Skip to content

fix: serialize ACP requests to prevent session/prompt race condition (#499)#628

Open
MrRealORG wants to merge 1 commit into
XiaomiMiMo:mainfrom
MrRealORG:fix/auto-202606150158-acp-session-race
Open

fix: serialize ACP requests to prevent session/prompt race condition (#499)#628
MrRealORG wants to merge 1 commit into
XiaomiMiMo:mainfrom
MrRealORG:fix/auto-202606150158-acp-session-race

Conversation

@MrRealORG

Copy link
Copy Markdown

Summary

Fixes a race condition in mimo acp mode where session/prompt fails with "Session not found" even when using a valid sessionId just returned by session/new.

Root Cause

The @agentclientprotocol/sdk calls #processMessage() without await in its #receive() loop. This means rapid JSON-RPC requests are processed concurrently, not sequentially. When session/new yields at an async HTTP call (sdk.session.create()), the event loop is free to process the next message (session/prompt), which looks up the session in the in-memory Map — but the session hasn't been stored yet because the HTTP call hasn't completed.

t0: session/new  → starts async HTTP call (yields to event loop)
t1: session/prompt → looks up session in Map → NOT FOUND ❌
t2: session/new HTTP response arrives → session stored in Map ✓ (too late)

Fix

Add a lightweight promise-chain mutex (serialize()) to the Agent class that ensures all session-affecting ACP requests are processed sequentially. This is a minimal, non-invasive workaround for the SDK's fire-and-forget behavior.

Methods wrapped:

  • newSession / _newSession
  • loadSession / _loadSession
  • prompt / _prompt
  • cancel / _cancel
  • setSessionMode / _setSessionMode
  • setSessionConfigOption / _setSessionConfigOption
  • unstable_setSessionModel / _unstable_setSessionModel

Testing

The fix can be verified by sending rapid ACP requests via stdin:

echo -e '{"jsonrpc":"2.0","id":0,"method":"initialize","params":{...}}\n{"jsonrpc":"2.0","id":1,"method":"session/new","params":{...}}\n{"jsonrpc":"2.0","id":2,"method":"session/prompt","params":{"sessionId":"<from above>","prompt":[...]}}' | mimo acp

Fixes #499

…iaomiMiMo#499)

The @agentclientprotocol/sdk calls #processMessage without await,
causing rapid requests (e.g. session/new followed immediately by
session/prompt) to execute concurrently. Since session/new makes
an async HTTP call to create the session, session/prompt can fire
before the session is stored in the in-memory Map, resulting in
'Session not found' errors.

Add a lightweight promise-chain mutex (serialize()) that ensures
ACP requests are processed sequentially. Key session-affecting
methods (newSession, loadSession, prompt, cancel, setSessionMode,
setSessionConfigOption, unstable_setSessionModel) are wrapped.

This makes MiMo Code work correctly as an ACP agent backend with
clients like AgentClient/MoClaw that send requests in quick
succession via stdin/stdout JSON-RPC.

Fixes XiaomiMiMo#499
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ACP session/prompt returns 'Session not found' for valid session ID

1 participant