lousho acp serves any Lousho agent this way, so you can chat with
it, watch its tool calls and approve them from the editor’s agent panel.
The command
<path> is loaded like lousho chat loads it, and
--model works the same way. The editor starts the process; it runs until
stdin closes. stdout carries nothing but protocol messages: errors, and
anything the agent’s code prints with console.log, go to stderr, which
editors show in their logs. A bad path or flag exits with code 1 and the coded
error (LOUSHO_CONFIG_INVALID, …) on stderr.
Zed
Add the agent to Zed’ssettings.json, then pick it in the agent panel:
@lousho/build-ai-agent installed (or use
an absolute path to node_modules/.bin/lousho as command). Provider keys
come from env or from the environment Zed was started in.
What is supported
Protocol version 1. The agent answers:
While a turn runs the agent sends
session/update notifications:
agent_message_chunkwith atextcontent block for each piece of text the model writes;agent_thought_chunkwith atextcontent block for each piece of the model’s reasoning;tool_call(status: 'in_progress',kind: 'other', the tool’s name astitle, its arguments asrawInput) when a tool call starts;tool_call_updatewithstatus: 'completed'(the result as text content and asrawOutput) or'failed'(the error) when it ends.
task tool are not forwarded; the task call
itself appears as one tool call.
Permissions. When a tool needs approval (needsApproval, permissions
rules that ask), the agent sends the editor a session/request_permission
request with the tool call and two options, allow (Allow, allow_once) and
reject (Reject, reject_once). The answer decides the approval with
agent.approvals.streamResolve() and the continued turn keeps streaming
updates; a rejection marks the tool call failed and the model carries on.
A turn may ask several times.
Questions. An ask_question pause (askQuestion: true) is not mapped to
a permission request, because the user’s answer can be free text. It ends the
turn (end_turn) with the question, and its numbered options, as the agent’s
message; the next prompt of the session is the answer
(agent.approvals.streamAnswer()).
Stop reasons. end_turn for a normal finish, max_turn_requests when
maxSteps ran out, max_tokens when a limits budget tripped or the model
stopped on its output limit, refusal when a guardrail blocked or the
provider’s content filter stopped the model, and cancelled after
session/cancel.
Errors. An unknown method answers JSON-RPC error -32601, a line that is
not JSON -32700, an unknown sessionId or an empty prompt -32602, and a
second prompt while one runs in the same session -32600. A run that fails
answers -32603 with the error’s message, and its SDK error code (for
example LOUSHO_PROVIDER_RATE_LIMITED) in error.data.code.
Not supported
session/load(loadSession: false) and session modes.- The client’s
fs/*andterminal/*methods: the agent reads files and runs commands with its own tools (Workspace tools), not through the editor. - Image, audio and embedded-resource prompt blocks (text prompts only).
planupdates, andallow_always/reject_alwayspermission options.- Authentication (
authMethodsis empty): provider keys come from the environment.
In code
The protocol core isserveAcp(agent, { input, write }): it reads JSON-RPC
lines from any async iterable and hands each outgoing line to write, so you
can serve it over another transport or drive it in tests without a process.
It resolves once input ends, after aborting any running turn.
store to keep the ACP sessions’ transcripts in an AgentStore (for
example a SqliteStore); by default they use the agent’s own store, or memory.