feat(agent): align with workflow@20261022 - turn_context messages and prompt tails

- merge main (b0ff2e0..c7ca781): workflow/20261022 moves dynamic context
  out of fixed prompts - collection/extraction prompts carry no inline vars;
  reference time and current form travel in the user message <turn_context>
  block; photo/confirm data kept at prompt tails
- prompts: all 8 files regenerated from 20261022 (byte-identity tests
  point at the new export)
- collect: user message = <turn_context>(本轮参考时间) + <user_input>;
  extraction message adds 当前表单; single trusted clock per turn threads
  through reply/extraction/repair
- photo: raw input only (20261022 photo nodes use system_text, no wrapper)
- workflow fake llm: unwraps <user_input> before event parsing
- fields: accident_time normalized to extraction format (YYYY年M月D日H点m分,
  strip zero padding) - fixes form assertion mismatch with padded output
- evals/run.py: trust_env=False - bypass Windows system proxy (registry
  proxy at 192.168.0.4:7897 was intercepting localhost and returning 503)
- verified: 172 unit tests; ALL golden suites pass on real model
  (46/46): collection_skip 12/12, photo_skip 4/4, no_false 2/2,
  button_guidance 12/12, non_motor_vehicle 14/14, time_confirmation 2/2
This commit is contained in:
Eric Wang
2026-10-22 12:28:24 +08:00
parent f9ec20cd81
commit e72d9c9bc0
15 changed files with 205 additions and 99 deletions
+8 -4
View File
@@ -185,9 +185,13 @@ def workflow_fake_responder(system_prompt: str, user_message: str, history=None)
current = stage_match.group(1) if stage_match else "1001"
mode = "browser_addon" if '"client_mode": "browser_addon"' in system_prompt else "direct"
event = parse_client_event(user_message)
# 20261022 起 user 消息为 <turn_context>+<user_input> 包装,取原始输入判断事件
input_match = re.search(r"<user_input>\n(.*?)\n?</user_input>", user_message, re.DOTALL)
raw_input = input_match.group(1) if input_match else user_message
event = parse_client_event(raw_input)
if event in (ClientEvent.SESSION_START, ClientEvent.CONTINUE) and current == "1001":
return f"<state>1002</state>已收到:{user_message}"
return f"<state>1002</state>已收到:{raw_input}"
if event is ClientEvent.PHOTO_DONE:
chain = {
"2000": "2001", "2001": "2002", "2002": "2003", "2003": "2005",
@@ -197,7 +201,7 @@ def workflow_fake_responder(system_prompt: str, user_message: str, history=None)
target = chain.get(current)
if target is None:
target = "0000" if mode == "browser_addon" else ("3001" if current == "2005" else "3002")
return f"<state>{target}</state>已收到:{user_message}"
return f"<state>{target}</state>已收到:{raw_input}"
if event is ClientEvent.PHOTO_FAILED_3X:
return "<state>0005</state>多次拍摄识别仍未成功,正在为您转接人工处理。"
if event is ClientEvent.NO_REPLY:
@@ -212,7 +216,7 @@ def workflow_fake_responder(system_prompt: str, user_message: str, history=None)
if trailing >= 1:
return "<state>0004</state>长时间未收到回应,为您转接人工。"
return f"<state>{current}</state>请问您还在吗?"
return f"<state>{current}</state>已收到:{user_message}"
return f"<state>{current}</state>已收到:{raw_input}"
def workflow_fake_llm() -> "FakeLLMService":