refactor: remove _read_fw helper, add ChatSummary TypedDict to dispatcher
linuztx committed
Mar 17, 2026 at 02:58 UTC
489a8634f13781aff20a2b4dd8cdd52eb651e922
3 files changed
+16
-13
plugins/_email_integration/extensions/python/process_chain_end/_55_email_reply.py
+1
-2
@@ -70,8 +70,7 @@ def _extract_last_response(context: AgentContext) -> str:
70
def _notify_agent_of_failure(
71
context: AgentContext, error: str, attempt: int,
72
):
73
- from plugins._email_integration.helpers.handler import _read_fw
74
- msg = _read_fw(
73
+ msg = context.agent0.read_prompt(
74
"fw.email.send_failed.md", error=error, attempt=str(attempt),
75
max_retries=str(MAX_SEND_RETRIES),
76
)
plugins/_email_integration/helpers/dispatcher.py
+13
-3
@@ -6,7 +6,7 @@ No agent deps in pure helpers.
6
7
import re
8
from dataclasses import dataclass
9
-from typing import Literal
9
+from typing import Literal, TypedDict
10
11
# Pattern for extracting chat thread ID from email subject
12
# Matches: [a0-xxxxxxxx] at end of subject
@@ -46,13 +46,23 @@ def build_reply_subject(original_subject: str, thread_id: str) -> str:
46
return f"{clean} [a0-{thread_id}]"
47
48
49
-def build_chat_summary(context_id: str, data: dict) -> dict:
49
+class ChatSummary(TypedDict):
50
+ context_id: str
51
+ thread_id: str
52
+ sender: str
53
+ subject: str
54
+ handler: str
55
+ history_preview: str
56
+
57
+
58
+def build_chat_summary(context_id: str, data: dict) -> ChatSummary:
59
return {
60
"context_id": context_id,
61
"thread_id": data.get(CTX_EMAIL_THREAD_ID, ""),
62
"sender": data.get(CTX_EMAIL_SENDER, ""),
63
"subject": data.get(CTX_EMAIL_SUBJECT, ""),
64
"handler": data.get(CTX_EMAIL_HANDLER, ""),
65
+ "history_preview": "",
66
}
67
68
@@ -66,7 +76,7 @@ def truncate_body(body: str) -> str:
76
return body[:BODY_PREVIEW_MAX_CHARS] + "... (truncated)"
77
78
69
-def format_chats_list(existing_chats: list[dict]) -> str:
79
+def format_chats_list(existing_chats: list[ChatSummary]) -> str:
80
if not existing_chats:
81
return "No existing chats for this handler."
82
sections = []
plugins/_email_integration/helpers/handler.py
+2
-8
@@ -36,12 +36,6 @@ PLUGIN_NAME = "_email_integration"
36
DOWNLOAD_FOLDER = "usr/email/attachments"
37
STATE_FILE = "usr/email/state.json"
38
39
-_PROMPTS_DIR = os.path.join(os.path.dirname(os.path.dirname(__file__)), "prompts")
40
-
41
-
42
-def _read_fw(filename: str, **kwargs: str) -> str:
43
- return files.read_prompt_file(filename, _directories=[_PROMPTS_DIR], **kwargs)
44
-
39
40
# ------------------------------------------------------------------
41
# UID state persistence
@@ -217,7 +211,7 @@ async def _call_dispatcher(
211
agent: Agent,
212
handler_cfg: dict,
213
msg: InboundMessage,
220
- existing_chats: list[dict],
214
+ existing_chats: list[disp.ChatSummary],
215
) -> disp.DispatchDecision:
216
body_preview = disp.truncate_body(msg.body)
217
chats_text = disp.format_chats_list(existing_chats)
@@ -318,7 +312,7 @@ async def _route_to_chat(
312
HISTORY_PREVIEW_MAX_CHARS: int = 500
313
314
321
-def _find_handler_chats(handler_name: str, sender: str) -> list[dict]:
315
+def _find_handler_chats(handler_name: str, sender: str) -> list[disp.ChatSummary]:
316
results = []
317
for ctx_id, ctx in AgentContext._contexts.items():
318
if not isinstance(ctx, AgentContext):