improve(email): extract body preview func and remove thread_id from dispatcher prompt
linuztx committed
Mar 15, 2026 at 22:22 UTC
1aa1190de12e0fb863669661b72da7ced047a2d2
3 files changed
+16
-8
plugins/_email_integration/helpers/dispatcher.py
+10
-2
@@ -22,6 +22,8 @@ CTX_EMAIL_REFERENCES = "email_references"
22
# Transient — consumed per-reply, not persisted
23
CTX_EMAIL_ATTACHMENTS = "_email_response_attachments"
24
25
+BODY_PREVIEW_MAX_CHARS: int = 2000
26
+
27
DispatchAction = Literal["new_chat", "continue_chat", "intervene_soft", "intervene_hard"]
28
29
@@ -58,14 +60,20 @@ def build_chat_summary(context_id: str, data: dict) -> dict:
60
# Dispatcher prompt builders
61
# ------------------------------------------------------------------
62
63
+def truncate_body(body: str) -> str:
64
+ if len(body) <= BODY_PREVIEW_MAX_CHARS:
65
+ return body
66
+ return body[:BODY_PREVIEW_MAX_CHARS] + "... (truncated)"
67
+
68
+
69
def format_chats_list(existing_chats: list[dict]) -> str:
70
if not existing_chats:
71
return "No existing chats for this handler."
72
sections = []
73
for c in existing_chats[:20]:
74
header = (
67
- f"- context_id={c['context_id']} thread_id={c.get('thread_id', '')} "
68
- f"sender={c.get('sender', '')} subject={c.get('subject', '')}"
75
+ f"- context_id={c['context_id']}"
76
+ f" sender={c.get('sender', '')} subject={c.get('subject', '')}"
77
)
78
preview = c.get("history_preview", "")
79
if preview:
plugins/_email_integration/helpers/handler.py
+1
-1
@@ -182,7 +182,7 @@ async def _call_dispatcher(
182
msg: InboundMessage,
183
existing_chats: list[dict],
184
) -> disp.DispatchDecision:
185
- body_preview = msg.body[:2000] if len(msg.body) > 2000 else msg.body
185
+ body_preview = disp.truncate_body(msg.body)
186
chats_text = disp.format_chats_list(existing_chats)
187
188
prompt = agent.read_prompt(
plugins/_email_integration/prompts/fw.email.dispatcher_system.md
+5
-5
@@ -1,19 +1,19 @@
1
You route inbound emails to agent chats.
2
-You receive: the new email (sender, subject, body) and a list of existing chats for this email handler.
2
+You receive: the new email (sender, subject, body) and a list of existing chats with conversation history.
3
4
Rules:
5
-- If the email subject contains a thread ID marker [a0-XXXX] AND a matching chat exists, reply with CONTINUE and that chat's context_id
6
-- If no thread ID but the email content clearly relates to an existing chat (same topic, same sender), reply with CONTINUE and the best matching context_id
5
+- If the email content clearly relates to an existing chat (same topic, same sender), reply with CONTINUE and that chat's context_id
6
- If the email is a status question or low-priority follow-up on a running chat, reply with INTERVENE_SOFT and the context_id — the agent will receive it after current step
7
- If the email is urgent and requires immediate attention on a running chat, reply with INTERVENE_HARD and the context_id
8
- Otherwise reply with NEW_CHAT
9
10
+Use conversation history to determine topic relevance when matching emails to chats.
11
+
12
Respond with EXACTLY one line in this format:
13
ACTION context_id reason
14
15
Examples:
16
NEW_CHAT _ new request from user
16
-CONTINUE ctx_abc123 thread ID matches
17
-CONTINUE ctx_def456 same sender discussing AWS deployment
17
+CONTINUE ctx_abc123 same sender discussing AWS deployment
18
INTERVENE_SOFT ctx_abc123 user asking for status update
19
INTERVENE_HARD ctx_abc123 urgent correction needed