hermes-agent/tests/acp
kshitij 3034eee38e
fix(acp): replay session history before responding to session/load (#12285 follow-up) (#26957)
Switches `_replay_session_history` from `loop.call_soon`-deferred (after the
`LoadSessionResponse` is written) to `await`-inline (before the response is
constructed) for both `session/load` and `session/resume`. Adds defensive
try/except around the awaited call so a replay helper crash still yields a
successful load response — partial transcripts are acceptable, total
load failure is not.

The deferral was added on May 2 in commit 19854c7cd with the rationale "Zed
only attaches streamed transcript/tool updates once the load/resume response
has completed." That justification was incorrect:

- Zed's current ACP integration (zed-industries/zed
  crates/agent_servers/src/acp.rs) explicitly registers the session-update
  routing entry BEFORE awaiting the loadSession RPC, with the comment:
  "so that any session/update notifications that arrive during the call
  (e.g. history replay during session/load) can find the thread."
- Every other reference ACP server (Codex, Claude Code, OpenCode, Pi, agentao)
  replays history BEFORE responding to the load request.
- The ACP spec wording ("Stream the entire conversation history back to the
  client via notifications") and the natural JSON-RPC reading both mean
  "during the request's lifetime", not "after the response resolves".

Empirical reproduction (reported by Biraj on @agentclientprotocol/sdk
v0.21.1): the same custom ACP client works correctly against Codex /
Claude Code / OpenCode / Pi but receives 0 notifications from Hermes
because it measures the per-call notification count at the moment
`loadSession` resolves — which on Hermes was before the `call_soon`-
scheduled replay coroutine had a chance to run.

Changes:
- `acp_adapter/server.py`: remove `_schedule_history_replay`; both
  `load_session` and `resume_session` now `await self._replay_session_history`
  before returning, wrapped in try/except that logs and continues on
  helper exceptions.
- `tests/acp/test_server.py`: replace the single
  `test_load_session_schedules_history_replay_after_response`
  (which encoded the now-incorrect post-response ordering) with two tests
  asserting `events == ["replay", "returned"]` for load and resume.
  Add two regression tests confirming that a replay helper raising still
  yields a `LoadSessionResponse` / `ResumeSessionResponse` rather than
  propagating the exception out as a JSON-RPC error.

Result: 240 ACP tests pass (was 238), ruff clean. Verified end-to-end:
biraj's synchronous notification-counter pattern now sees 6 notifications
during `loadSession` for a 5-message session, matching all other reference
ACP servers.

The `_fenced_text` change in `acp_adapter/tools.py` from the same May 2
commit is orthogonal and intentionally left intact — it's a separate,
still-valid fix for Zed's pipe-as-table rendering.

Refs #12285. Follows up #26943 (which added thought-chunk replay but kept
the deferral).
2026-05-16 07:41:34 -07:00
..
__init__.py feat: restore ACP server implementation from PR #949 (#1254) 2026-03-14 00:09:05 -07:00
test_approval_isolation.py fix(acp): wire HERMES_SESSION_KEY per session so sudo cache scope activates 2026-04-28 01:34:16 -07:00
test_auth.py feat: add ACP registry metadata for Zed 2026-05-14 20:26:02 -07:00
test_entry.py feat(acp): hermes acp --setup-browser bootstraps browser tools for registry installs 2026-05-15 01:38:24 -07:00
test_events.py fix(acp): replay native todo plans 2026-05-15 14:07:53 -07:00
test_mcp_e2e.py fix(acp): polish Zed context and tool rendering 2026-05-03 01:44:23 -07:00
test_permissions.py fix(async): close unscheduled coroutines in all threadsafe bridges (#26584) 2026-05-15 14:00:01 -07:00
test_ping_suppression.py fix(acp): silence 'Background task failed' noise on liveness-probe requests (#12855) 2026-04-20 00:10:27 -07:00
test_registry_manifest.py feat(acp-registry): switch to uvx distribution, drop npm launcher 2026-05-14 22:27:09 -07:00
test_server.py fix(acp): replay session history before responding to session/load (#12285 follow-up) (#26957) 2026-05-16 07:41:34 -07:00
test_session.py fix(acp): preserve assistant reasoning metadata in session persistence 2026-05-05 10:18:28 -07:00
test_tools.py fix(acp): compact Zed tool replay rendering 2026-05-03 01:44:23 -07:00