molecule-core/workspace
Hongming Wang e1628c4d56 fix(a2a): route terminal Message via TaskUpdater.complete/failed in task mode
PR #2558 enqueued a Task at the start of new requests so the v1 SDK
would accept TaskUpdater.start_work() — fix #1 of the v0→v1 migration
gap (PR #2170). But after Task is enqueued, the executor enters
"task mode" and the SDK rejects raw Message enqueues at the terminal
step:

  {"code":-32603,"message":"Received Message object in task mode.
  Use TaskStatusUpdateEvent or TaskArtifactUpdateEvent instead."}

Synth-E2E 2026-05-03T11:00:34Z surfaced this on the very first run
after the prior fix cascaded. Validation site is the same
a2a/server/agent_execution/active_task.py — the framework's job is
to enforce the v1 invariant; we're catching up to it.

The fix routes both terminal events through TaskUpdater helpers:
- success: updater.complete(message=msg) wraps in
  TaskStatusUpdateEvent(state=COMPLETED, final=True)
- error: updater.failed(message=...) wraps in
  TaskStatusUpdateEvent(state=FAILED, final=True)

Both helpers exist in a2a-sdk ≥ 1.0; verified via
TaskUpdater.complete signature.

Tests:
- conftest TaskUpdater stub now records complete/failed calls AND
  routes the message back through event_queue.enqueue_event so the
  ~20 legacy tests asserting on enqueue_event keep working
- 2 new regression tests pin the contract:
  * test_terminal_success_routes_via_updater_complete
  * test_terminal_error_routes_via_updater_failed
- Both NEW tests verified to FAIL on staging-baseline (without this
  fix) and PASS with it — they'd catch the regression before staging
  if the wheel-smoke gate covered task-mode terminal events too
  (separate yak-shave for #131 follow-up)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 04:06:45 -07:00
..
adapters fix: comprehensive a2a-sdk 1.x migration sweep across workspace/ 2026-04-27 09:42:57 -07:00
builtin_tools feat(harness): coordinator phase-boundary instrumentation for RFC #2251 2026-04-28 20:11:46 -07:00
lib feat(workspace): pre-stop serialization for pause/resume (closes #1386) 2026-04-21 12:40:44 +00:00
molecule_audit chore: open-source restructure — rename dirs, remove internal files, scrub secrets 2026-04-18 00:24:44 -07:00
platform_tools feat(a2a-mcp): add chat_history tool for prior turns with a peer 2026-05-01 17:54:23 -07:00
plugins_registry feat(plugin): implement MCPServerAdaptor (issue #847) 2026-04-24 01:42:13 +00:00
policies feat(platform): single-source-of-truth tool registry — adapters consume, no drift 2026-04-28 17:11:36 -07:00
scripts fix(git-token-helper): close TOCTOU window + stop swallowing chmod errors (closes #1552) 2026-04-26 08:22:29 -07:00
skill_loader feat(skills): per-skill runtime compatibility (#119, hermes pattern) 2026-04-27 01:57:43 -07:00
tests fix(a2a): route terminal Message via TaskUpdater.complete/failed in task mode 2026-05-03 04:06:45 -07:00
.coveragerc test(workspace): centralize pytest-cov config + 92% floor (closes #1817) 2026-04-26 06:21:22 -07:00
a2a_cli.py fix(runtime): use lowercase wire role for v0.3 JSON-RPC compat layer 2026-04-27 12:40:11 -07:00
a2a_client.py fix(channel): validate peer_id at envelope build — close path-traversal foothold 2026-05-01 18:43:49 -07:00
a2a_executor.py fix(a2a): route terminal Message via TaskUpdater.complete/failed in task mode 2026-05-03 04:06:45 -07:00
a2a_mcp_server.py Merge pull request #2479 from Molecule-AI/fix/molecule-mcp-non-pipe-stdout 2026-05-02 02:20:51 +00:00
a2a_tools.py docs(a2a-tools): drop stale comment — before_ts is now server-supported 2026-05-01 18:13:51 -07:00
adapter_base.py feat(workspace): wire EventLog into adapter base (#119 PR-3b) 2026-05-03 01:18:19 -07:00
agent.py chore: open-source restructure — rename dirs, remove internal files, scrub secrets 2026-04-18 00:24:44 -07:00
agents_md.py chore: open-source restructure — rename dirs, remove internal files, scrub secrets 2026-04-18 00:24:44 -07:00
build-all.sh fix: update workspace script comments for workspace-template → workspace rename 2026-04-18 01:48:05 -07:00
config.py feat(workspace): event_log module + EventLogConfig (#119 PR-2) 2026-05-03 00:17:12 -07:00
configs_dir.py fix(runtime): auto-fallback CONFIGS_DIR for non-container hosts (closes #2458) 2026-05-01 13:07:55 -07:00
consolidation.py fix: apply #1124 env-var defaults + scrub F1088 credentials from INCIDENT_LOG.md (#1347) 2026-04-21 08:11:44 +00:00
coordinator.py feat(harness): coordinator phase-boundary instrumentation for RFC #2251 2026-04-28 20:11:46 -07:00
Dockerfile feat(workspace): 45-min gh-token refresh daemon + credential helper cache 2026-04-22 19:52:46 -07:00
entrypoint.sh fix(workspace): credential helper security hardening (#1797) 2026-04-23 18:14:55 +00:00
event_log.py feat(workspace): event_log module + EventLogConfig (#119 PR-2) 2026-05-03 00:17:12 -07:00
events.py chore: open-source restructure — rename dirs, remove internal files, scrub secrets 2026-04-18 00:24:44 -07:00
executor_helpers.py docs(a2a): correct misleading v1-tolerance comments 2026-05-02 02:33:00 -07:00
heartbeat.py feat(workspace): wire observability config into heartbeat + uvicorn (#119 PR-3a) 2026-05-03 01:01:57 -07:00
inbox.py fix(inbox): skip self-notify rows in poller to break echo loop 2026-05-01 17:35:49 -07:00
initial_prompt.py chore: open-source restructure — rename dirs, remove internal files, scrub secrets 2026-04-18 00:24:44 -07:00
internal_chat_uploads.py fix(workspace): surface errno + path on chat-upload mkdir failure 2026-05-01 11:47:53 -07:00
internal_file_read.py feat(chat_files): rewrite Download as HTTP-forward (RFC #2312, PR-D) 2026-04-29 15:19:02 -07:00
main.py feat(workspace): wire EventLog into adapter base (#119 PR-3b) 2026-05-03 01:18:19 -07:00
mcp_cli.py fix(runtime): register configs_dir in TOP_LEVEL_MODULES + drop alias 2026-05-01 13:13:57 -07:00
molecule_ai_status.py fix(runtime): replace remaining /app/ legacy paths in agent prompts + docstrings 2026-04-27 11:22:00 -07:00
platform_auth.py fix(runtime): auto-fallback CONFIGS_DIR for non-container hosts (closes #2458) 2026-05-01 13:07:55 -07:00
platform_inbound_auth.py fix(runtime): auto-fallback CONFIGS_DIR for non-container hosts (closes #2458) 2026-05-01 13:07:55 -07:00
plugins.py chore: open-source restructure — rename dirs, remove internal files, scrub secrets 2026-04-18 00:24:44 -07:00
preflight.py fix(preflight): skip required_env check in MOLECULE_SMOKE_MODE 2026-05-03 03:44:05 -07:00
prompt.py feat(prompt): Platform Capabilities preamble at top of system prompt 2026-04-29 21:31:13 -07:00
pytest.ini feat(preflight): replace SUPPORTED_RUNTIMES static list with adapter discovery 2026-04-27 00:44:51 -07:00
rebuild-runtime-images.sh fix: update workspace script comments for workspace-template → workspace rename 2026-04-18 01:48:05 -07:00
requirements.txt chore(deps)(deps): update starlette requirement in /workspace 2026-05-03 01:36:45 +00:00
runtime_wedge.py chore(workspace): drop claude_sdk_executor — Phase 2 of #87 2026-04-27 00:52:55 -07:00
shared_runtime.py feat(platform): single-source-of-truth tool registry — adapters consume, no drift 2026-04-28 17:11:36 -07:00
smoke_mode.py chore(smoke): runtime_wedge follow-ups from PR #2473 review 2026-05-01 18:01:51 -07:00
transcript_auth.py chore: open-source restructure — rename dirs, remove internal files, scrub secrets 2026-04-18 00:24:44 -07:00
watcher.py chore: open-source restructure — rename dirs, remove internal files, scrub secrets 2026-04-18 00:24:44 -07:00