Skip to content

Commit e29d399

Browse files
committed
Document terminals
1 parent 1becb48 commit e29d399

10 files changed

Lines changed: 303 additions & 56 deletions

File tree

docs/protocol/schema.mdx

Lines changed: 201 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -523,6 +523,189 @@ See protocol docs: [Agent Reports Output](https://agentclientprotocol.com/protoc
523523
The actual update content.
524524
</ResponseField>
525525

526+
<a id="terminal-create"></a>
527+
### <span class="font-mono">terminal/create</span>
528+
529+
Executes a command in a new terminal
530+
531+
Only available if the `terminal` Client capability is set to `true`.
532+
533+
Returns a `TerminalId` that can be used with other terminal methods
534+
to get the current output, wait for exit, and kill the command.
535+
536+
The `TerminalId` can also be used to embed the terminal in a tool call
537+
by using the `ToolCallContent::Terminal` variant.
538+
539+
The Agent is responsible for releasing the terminal by using the `terminal/release`
540+
method.
541+
542+
See protocol docs: [Terminals](https://agentclientprotocol.com/protocol/terminals)
543+
544+
#### <span class="font-mono">CreateTerminalRequest</span>
545+
546+
**Type:** Object
547+
548+
**Properties:**
549+
550+
<ResponseField name="args" type={<><span>"string"</span><span>[]</span></>} >
551+
</ResponseField>
552+
<ResponseField name="command" type={"string"} required>
553+
</ResponseField>
554+
<ResponseField name="cwd" type={"string | null"} >
555+
</ResponseField>
556+
<ResponseField name="env" type={<><span><a href="#envvariable">EnvVariable</a></span><span>[]</span></>} >
557+
</ResponseField>
558+
<ResponseField name="outputByteLimit" type={"integer | null"} >
559+
560+
- Minimum: `0`
561+
562+
</ResponseField>
563+
<ResponseField name="sessionId" type={<a href="#sessionid">SessionId</a>} required>
564+
</ResponseField>
565+
566+
#### <span class="font-mono">CreateTerminalResponse</span>
567+
568+
**Type:** Object
569+
570+
**Properties:**
571+
572+
<ResponseField name="terminalId" type={"string"} required></ResponseField>
573+
574+
<a id="terminal-kill"></a>
575+
### <span class="font-mono">terminal/kill</span>
576+
577+
Kills the terminal command without releasing the terminal
578+
579+
While `terminal/release` will also kill the command, this method will keep
580+
the `TerminalId` valid so it can be used with other methods.
581+
582+
This method can be helpful when implementing command timeouts which terminate
583+
the command as soon as elapsed, and then get the final output so it can be sent
584+
to the model.
585+
586+
Note: `terminal/release` when `TerminalId` is no longer needed.
587+
588+
See protocol docs: [Terminals](https://agentclientprotocol.com/protocol/terminals)
589+
590+
#### <span class="font-mono">KillTerminalCommandRequest</span>
591+
592+
**Type:** Object
593+
594+
**Properties:**
595+
596+
<ResponseField
597+
name="sessionId"
598+
type={<a href="#sessionid">SessionId</a>}
599+
required
600+
></ResponseField>
601+
<ResponseField name="terminalId" type={"string"} required></ResponseField>
602+
603+
<a id="terminal-output"></a>
604+
### <span class="font-mono">terminal/output</span>
605+
606+
Gets the terminal ouput and exit status
607+
608+
Returns the current content in the terminal without waiting for the command to exit.
609+
If the command has already exited, the exit status is included.
610+
611+
See protocol docs: [Terminals](https://agentclientprotocol.com/protocol/terminals)
612+
613+
#### <span class="font-mono">TerminalOutputRequest</span>
614+
615+
**Type:** Object
616+
617+
**Properties:**
618+
619+
<ResponseField
620+
name="sessionId"
621+
type={<a href="#sessionid">SessionId</a>}
622+
required
623+
></ResponseField>
624+
<ResponseField name="terminalId" type={"string"} required></ResponseField>
625+
626+
#### <span class="font-mono">TerminalOutputResponse</span>
627+
628+
**Type:** Object
629+
630+
**Properties:**
631+
632+
<ResponseField
633+
name="exitStatus"
634+
type={
635+
<>
636+
<span>
637+
<a href="#terminalexitstatus">TerminalExitStatus</a>
638+
</span>
639+
<span> | null</span>
640+
</>
641+
}
642+
></ResponseField>
643+
<ResponseField name="output" type={"string"} required></ResponseField>
644+
<ResponseField name="truncated" type={"boolean"} required></ResponseField>
645+
646+
<a id="terminal-release"></a>
647+
### <span class="font-mono">terminal/release</span>
648+
649+
Releases a terminal
650+
651+
The command is killed if it hasn't exited yet. Use `terminal/wait_for_exit`
652+
to wait for the command to exit before releasing the terminal.
653+
654+
After release, the `TerminalId` can no longer be used with other `terminal/*` methods,
655+
but tool calls that already contain it, continue to display its output.
656+
657+
The `terminal/kill` method can be used to terminate the command without releasing
658+
the terminal, allowing the Agent to call `terminal/output` and other methods.
659+
660+
See protocol docs: [Terminals](https://agentclientprotocol.com/protocol/terminals)
661+
662+
#### <span class="font-mono">ReleaseTerminalRequest</span>
663+
664+
**Type:** Object
665+
666+
**Properties:**
667+
668+
<ResponseField
669+
name="sessionId"
670+
type={<a href="#sessionid">SessionId</a>}
671+
required
672+
></ResponseField>
673+
<ResponseField name="terminalId" type={"string"} required></ResponseField>
674+
675+
<a id="terminal-wait_for_exit"></a>
676+
### <span class="font-mono">terminal/wait_for_exit</span>
677+
678+
Waits for the terminal command to exit and return its exit status
679+
680+
See protocol docs: [Terminals](https://agentclientprotocol.com/protocol/terminals)
681+
682+
#### <span class="font-mono">WaitForTerminalExitRequest</span>
683+
684+
**Type:** Object
685+
686+
**Properties:**
687+
688+
<ResponseField
689+
name="sessionId"
690+
type={<a href="#sessionid">SessionId</a>}
691+
required
692+
></ResponseField>
693+
<ResponseField name="terminalId" type={"string"} required></ResponseField>
694+
695+
#### <span class="font-mono">WaitForTerminalExitResponse</span>
696+
697+
**Type:** Object
698+
699+
**Properties:**
700+
701+
<ResponseField name="exitCode" type={"integer | null"} >
702+
703+
- Minimum: `0`
704+
705+
</ResponseField>
706+
<ResponseField name="signal" type={"string | null"} >
707+
</ResponseField>
708+
526709
## <span class="font-mono">AgentCapabilities</span>
527710

528711
Capabilities supported by the agent.
@@ -694,9 +877,7 @@ Determines which file operations the agent can request.
694877

695878
</ResponseField>
696879
<ResponseField name="terminal" type={"boolean"} >
697-
**UNSTABLE**
698-
699-
This capability is not part of the spec yet, and may be removed or changed at any point.
880+
Whether the Client support all `terminal/*` methods.
700881

701882
- Default: `false`
702883

@@ -1781,6 +1962,20 @@ response to confirm successful cancellation.
17811962

17821963
</ResponseField>
17831964

1965+
## <span class="font-mono">TerminalExitStatus</span>
1966+
1967+
**Type:** Object
1968+
1969+
**Properties:**
1970+
1971+
<ResponseField name="exitCode" type={"integer | null"} >
1972+
1973+
- Minimum: `0`
1974+
1975+
</ResponseField>
1976+
<ResponseField name="signal" type={"string | null"} >
1977+
</ResponseField>
1978+
17841979
## <span class="font-mono">TextContent</span>
17851980

17861981
Text provided to or from an LLM.
@@ -1929,7 +2124,9 @@ File modification shown as a diff.
19292124
</ResponseField>
19302125

19312126
<ResponseField name="terminal">
1932-
{""}
2127+
Embed a terminal created with `terminal/create`
2128+
2129+
The terminal must be added to the tool call before calling `terminal/release`.
19332130

19342131
<Expandable title="Properties">
19352132

rust/acp.rs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,7 @@ impl Side for ClientSide {
268268
.map(AgentRequest::TerminalOutputRequest)
269269
.map_err(Into::into),
270270
TERMINAL_KILL_METHOD_NAME => serde_json::from_str(params.get())
271-
.map(AgentRequest::KillTerminalRequest)
271+
.map(AgentRequest::KillTerminalCommandRequest)
272272
.map_err(Into::into),
273273
TERMINAL_RELEASE_METHOD_NAME => serde_json::from_str(params.get())
274274
.map(AgentRequest::ReleaseTerminalRequest)
@@ -326,8 +326,8 @@ impl<T: Client> MessageHandler<ClientSide> for T {
326326
let response = self.wait_for_terminal_exit(args).await?;
327327
Ok(ClientResponse::WaitForTerminalExitResponse(response))
328328
}
329-
AgentRequest::KillTerminalRequest(args) => {
330-
self.kill_terminal(args).await?;
329+
AgentRequest::KillTerminalCommandRequest(args) => {
330+
self.kill_terminal_command(args).await?;
331331
Ok(ClientResponse::KillTerminalResponse)
332332
}
333333
}
@@ -479,11 +479,14 @@ impl Client for AgentSideConnection {
479479
.await
480480
}
481481

482-
async fn kill_terminal(&self, arguments: KillTerminalRequest) -> Result<(), Error> {
482+
async fn kill_terminal_command(
483+
&self,
484+
arguments: KillTerminalCommandRequest,
485+
) -> Result<(), Error> {
483486
self.conn
484487
.request(
485488
TERMINAL_KILL_METHOD_NAME,
486-
Some(AgentRequest::KillTerminalRequest(arguments)),
489+
Some(AgentRequest::KillTerminalCommandRequest(arguments)),
487490
)
488491
.await
489492
}

0 commit comments

Comments
 (0)