Skip to content

ACP: session/load does not replay conversation history per spec #12285

@saltbo

Description

@saltbo

Summary

hermes acp's session/load handler returns immediately after refreshing cwd and registering MCP servers. It does not replay the session's past session_update notifications, which the ACP specification says the agent should do.

Repro

With any external ACP client (I'm using a TypeScript client built with @agentclientprotocol/sdk v0.19.0):

  1. Start a session with newSession, run a prompt, collect the agent's tool-use + message notifications.
  2. Record the resulting sessionId.
  3. Start a fresh ACP connection to a new hermes acp subprocess.
  4. Call loadSession({ sessionId, cwd, mcpServers: [] }).
  5. Observe the Client.sessionUpdate callback.

Expected: a stream of session_update notifications replaying agent_message_chunk, tool_call, tool_call_update, etc. for the prior turns, then loadSession resolves.

Actual: exactly one available_commands_update notification (from _schedule_available_commands_update), then loadSession resolves. No conversation history is streamed.

Where in the code

acp_adapter/server.py:375-389 (hermes-agent v0.10):

async def load_session(self, cwd, session_id, mcp_servers, **kwargs):
    state = self.session_manager.update_cwd(session_id, cwd)
    if state is None:
        logger.warning("load_session: session %s not found", session_id)
        return None
    await self._register_session_mcp_servers(state, mcp_servers)
    logger.info("Loaded session %s", session_id)
    self._schedule_available_commands_update(session_id)
    return LoadSessionResponse(models=self._build_model_state(state))

The transcript itself is preserved on disk (~/.hermes/sessions/session_<session_id>.json) — it just isn't sent back over the protocol.

Spec reference

From Session Setup → Loading Sessions:

The agent should:

  • Restore the session context and conversation history
  • Connect to the specified MCP servers
  • Stream the entire conversation history back to the client via notifications

Suggested fix

After the current body and before return, iterate the stored messages for this session and emit each as a session_update notification with the matching sessionUpdate kind (user_message_chunk, agent_message_chunk, tool_call, tool_call_update), then return LoadSessionResponse. The mapping from hermes's internal message format to ACP notifications already exists in the live prompt path — it just isn't invoked during load.

Why this matters

External ACP clients (editors, orchestrators) that reconnect to an existing session have no way to reconstruct the conversation. In our case, an agent dashboard that shows task history gets an empty panel whenever a hermes-backed session is re-opened, even though the data is intact on disk. Parsing ~/.hermes/sessions/*.json directly works as a workaround but defeats the point of the protocol boundary.

Environment

  • hermes-agent v0.9.0 (Apr 13, 2026)
  • @agentclientprotocol/sdk v0.19.0
  • macOS 14.6, Python 3.11.14

Happy to submit a PR if the fix shape above looks right.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Medium — degraded but workaround existscomp/acpAgent Communication Protocol adaptertype/bugSomething isn't working

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions