Path: blob/main/src/vs/platform/agentHost/common/state/protocol/commands.ts
13405 views
/*---------------------------------------------------------------------------------------------1* Copyright (c) Microsoft Corporation. All rights reserved.2* Licensed under the MIT License. See License.txt in the project root for license information.3*--------------------------------------------------------------------------------------------*/45// allow-any-unicode-comment-file6// DO NOT EDIT -- auto-generated by scripts/sync-agent-host-protocol.ts78import type { URI, Snapshot, SessionConfigSchema, SessionSummary, ModelSelection, Turn, TerminalClaim, SessionActiveClient } from './state.js';9import type { ActionEnvelope, StateAction } from './actions.js';1011export type { ConfigPropertySchema, ConfigSchema, SessionConfigPropertySchema, SessionConfigSchema } from './state.js';1213// ─── initialize ──────────────────────────────────────────────────────────────1415/**16* Establishes a new connection and negotiates the protocol version.17* This MUST be the first message sent by the client.18*19* @category Commands20* @method initialize21* @direction Client → Server22* @messageType Request23* @version 124* @see {@link /specification/lifecycle | Lifecycle} for the full handshake flow.25*/26export interface InitializeParams {27/** Protocol version the client speaks */28protocolVersion: number;29/** Unique client identifier */30clientId: string;31/** URIs to subscribe to during handshake */32initialSubscriptions?: URI[];33/**34* IETF BCP 47 language tag indicating the client's preferred locale35* (e.g. `"en-US"`, `"ja"`). The server SHOULD use this to localise36* user-facing strings such as confirmation option labels.37*/38locale?: string;39}4041/**42* Result of the `initialize` command.43*44* If the server does not support the client's protocol version, it MUST return45* error code `-32005` (`UnsupportedProtocolVersion`).46*/47export interface InitializeResult {48/** Protocol version the server speaks */49protocolVersion: number;50/** Current server sequence number */51serverSeq: number;52/** Snapshots for each `initialSubscriptions` URI */53snapshots: Snapshot[];54/** Suggested default directory for remote filesystem browsing */55defaultDirectory?: URI;56}5758// ─── reconnect ───────────────────────────────────────────────────────────────5960/**61* Discriminant for reconnect result types.62*63* @category Commands64*/65export const enum ReconnectResultType {66Replay = 'replay',67Snapshot = 'snapshot',68}6970/**71* Re-establishes a dropped connection. The server replays missed actions or72* provides fresh snapshots.73*74* @category Commands75* @method reconnect76* @direction Client → Server77* @messageType Request78* @version 179* @see {@link /specification/lifecycle | Lifecycle} for details.80*/81export interface ReconnectParams {82/** Client identifier from the original connection */83clientId: string;84/** Last `serverSeq` the client received */85lastSeenServerSeq: number;86/** URIs the client was subscribed to */87subscriptions: URI[];88}8990/**91* Reconnect result when the server can replay from the requested sequence.92*93* The server MUST include all replayed data in the response.94*/95export interface ReconnectReplayResult {96/** Discriminant */97type: ReconnectResultType.Replay;98/** Missed action envelopes since `lastSeenServerSeq` */99actions: ActionEnvelope[];100}101102/**103* Reconnect result when the gap exceeds the replay buffer.104*/105export interface ReconnectSnapshotResult {106/** Discriminant */107type: ReconnectResultType.Snapshot;108/** Fresh snapshots for each subscription */109snapshots: Snapshot[];110}111112/** Result of the `reconnect` command. */113export type ReconnectResult = ReconnectReplayResult | ReconnectSnapshotResult;114115// ─── subscribe ───────────────────────────────────────────────────────────────116117/**118* Subscribe to a URI-identified state resource.119*120* @category Commands121* @method subscribe122* @direction Client → Server123* @messageType Request124* @version 1125* @see {@link /specification/subscriptions | Subscriptions}126*/127export interface SubscribeParams {128/** URI to subscribe to */129resource: URI;130}131132/**133* Result of the `subscribe` command.134*/135export interface SubscribeResult {136/** Snapshot of the subscribed resource */137snapshot: Snapshot;138}139140// ─── createSession ───────────────────────────────────────────────────────────141142/**143* Creates a new session with the specified agent provider.144*145* If the session URI already exists, the server MUST return an error with code146* `-32003` (`SessionAlreadyExists`).147*148* After creation, the client should subscribe to the session URI to receive state149* updates. The server also broadcasts a `notify/sessionAdded` notification to all150* clients.151*152* @category Commands153* @method createSession154* @direction Client → Server155* @messageType Request156* @version 1157* @example158* ```jsonc159* // Client → Server160* { "jsonrpc": "2.0", "id": 2, "method": "createSession",161* "params": { "session": "copilot:/<uuid>", "provider": "copilot", "model": "gpt-4o" } }162*163* // Server → Client (success)164* { "jsonrpc": "2.0", "id": 2, "result": null }165*166* // Server → Client (failure — provider not found)167* { "jsonrpc": "2.0", "id": 2, "error": { "code": -32002, "message": "No agent for provider" } }168*169* // Server → Client (failure — session already exists)170* { "jsonrpc": "2.0", "id": 2, "error": { "code": -32003, "message": "Session already exists" } }171* ```172*/173/**174* Identifies a source session and turn to fork from.175*176* When provided in `createSession`, the server populates the new session with177* content from the source session up to and including the response of the178* specified turn.179*/180export interface SessionForkSource {181/** URI of the existing session to fork from */182session: URI;183/** Turn ID in the source session; content up to and including this turn's response is copied */184turnId: string;185}186187export interface CreateSessionParams {188/** Session URI (client-chosen, e.g. `copilot:/<uuid>`) */189session: URI;190/** Agent provider ID */191provider?: string;192/** Model selection (ID and optional model-specific configuration) */193model?: ModelSelection;194/** Working directory for the session */195workingDirectory?: URI;196/**197* Fork from an existing session. The new session is populated with content198* from the source session up to and including the specified turn's response.199*/200fork?: SessionForkSource;201/**202* Agent-specific configuration values collected via `resolveSessionConfig`.203* Keys and values correspond to the schema returned by the server.204*/205config?: Record<string, unknown>;206/**207* Eagerly claim the active client role for the new session.208*209* When provided, the server initializes the session with this client as the210* active client, equivalent to dispatching a `session/activeClientChanged`211* action immediately after creation. The `clientId` MUST match the212* `clientId` the creating client supplied in `initialize`.213*/214activeClient?: SessionActiveClient;215}216217// ─── disposeSession ──────────────────────────────────────────────────────────218219/**220* Disposes a session and cleans up server-side resources.221*222* The server broadcasts a `notify/sessionRemoved` notification to all clients.223*224* @category Commands225* @method disposeSession226* @direction Client → Server227* @messageType Request228* @version 1229*/230export interface DisposeSessionParams {231/** Session URI to dispose */232session: URI;233}234235// ─── createTerminal ──────────────────────────────────────────────────────────236237/**238* Creates a new terminal on the server.239*240* After creation, the client should subscribe to the terminal URI to receive241* state updates. The server dispatches `root/terminalsChanged` to update the242* root terminal list.243*244* @category Commands245* @method createTerminal246* @direction Client → Server247* @messageType Request248* @version 1249*/250export interface CreateTerminalParams {251/** Terminal URI (client-chosen) */252terminal: URI;253/** Initial owner of the terminal */254claim: TerminalClaim;255/** Human-readable terminal name */256name?: string;257/** Initial working directory URI */258cwd?: URI;259/** Initial terminal width in columns */260cols?: number;261/** Initial terminal height in rows */262rows?: number;263}264265// ─── disposeTerminal ─────────────────────────────────────────────────────────266267/**268* Disposes a terminal and kills its process if still running.269*270* The server dispatches `root/terminalsChanged` to remove the terminal from271* the root terminal list.272*273* @category Commands274* @method disposeTerminal275* @direction Client → Server276* @messageType Request277* @version 1278*/279export interface DisposeTerminalParams {280/** Terminal URI to dispose */281terminal: URI;282}283284// ─── listSessions ────────────────────────────────────────────────────────────285286/**287* Returns a list of session summaries. Used to populate session lists and sidebars.288*289* The session list is **not** part of the state tree because it can be arbitrarily290* large. Clients fetch it imperatively and maintain a local cache updated by291* `notify/sessionAdded` and `notify/sessionRemoved` notifications.292*293* @category Commands294* @method listSessions295* @direction Client → Server296* @messageType Request297* @version 1298*/299export interface ListSessionsParams {300/** Optional filter criteria */301filter?: object;302}303304/** Result of the `listSessions` command. */305export interface ListSessionsResult {306/** The list of session summaries. */307items: SessionSummary[];308}309310// ─── resourceRead ────────────────────────────────────────────────────────311312/**313* Encoding of fetched content data.314*315* @category Commands316*/317export const enum ContentEncoding {318Base64 = 'base64',319Utf8 = 'utf-8',320}321322/**323* Reads the content of a resource by URI.324*325* Content references keep the state tree small by storing large data (images,326* long tool outputs) by reference rather than inline.327*328* Binary content (images, etc.) MUST use `base64` encoding. Text content MAY329* use `utf-8` encoding.330*331* @category Commands332* @method resourceRead333* @direction Client → Server334* @messageType Request335* @version 1336* @throws `NotFound` (`-32008`) if the URI does not exist.337* @throws `PermissionDenied` (`-32009`) if the client is not permitted to read the URI.338* @example339* ```jsonc340* // Client → Server341* { "jsonrpc": "2.0", "id": 10, "method": "resourceRead",342* "params": { "uri": "copilot:/<uuid>/content/img-1" } }343*344* // Server → Client345* { "jsonrpc": "2.0", "id": 10, "result": {346* "data": "iVBORw0KGgo...",347* "encoding": "base64",348* "contentType": "image/png"349* }}350* ```351*/352export interface ResourceReadParams {353/** Content URI from a `ContentRef` */354uri: string;355/** Preferred encoding for the returned data (default: server-chosen) */356encoding?: ContentEncoding;357}358359/**360* Result of the `resourceRead` command.361*362* The server SHOULD honor the `encoding` requested in the params. If the363* server cannot provide the requested encoding, it MUST fall back to either364* `base64` or `utf-8`.365*/366export interface ResourceReadResult {367/** Content encoded as a string */368data: string;369/** How `data` is encoded */370encoding: ContentEncoding;371/** Content type (e.g. `"image/png"`, `"text/plain"`) */372contentType?: string;373}374375// ─── resourceWrite ───────────────────────────────────────────────────────────376377/**378* Writes content to a file on the server's filesystem.379*380* Binary content (images, etc.) MUST use `base64` encoding. Text content MAY381* use `utf-8` encoding.382*383* If the file does not exist, it is created. If the file already exists, it is384* overwritten unless `createOnly` is set.385*386* @category Commands387* @method resourceWrite388* @direction Client → Server389* @messageType Request390* @version 1391* @throws `NotFound` (`-32008`) if the parent directory does not exist.392* @throws `PermissionDenied` (`-32009`) if the client is not permitted to write to the path.393* @throws `AlreadyExists` (`-32010`) if `createOnly` is set and the file already exists.394* @example395* ```jsonc396* // Client → Server397* { "jsonrpc": "2.0", "id": 11, "method": "resourceWrite",398* "params": { "uri": "file:///workspace/hello.txt", "data": "SGVsbG8=",399* "encoding": "base64", "contentType": "text/plain" } }400*401* // Server → Client402* { "jsonrpc": "2.0", "id": 11, "result": {} }403* ```404*/405export interface ResourceWriteParams {406/** Target file URI on the server filesystem */407uri: URI;408/** Content encoded as a string */409data: string;410/** How `data` is encoded */411encoding: ContentEncoding;412/** Content type (e.g. `"text/plain"`, `"image/png"`) */413contentType?: string;414/**415* If `true`, the server MUST fail if the file already exists instead of416* overwriting it. Useful for safe creation of new files.417*/418createOnly?: boolean;419}420421/**422* Result of the `resourceWrite` command.423*424* An empty object on success.425*/426export interface ResourceWriteResult {427}428429// ─── resourceList ────────────────────────────────────────────────────────430431/**432* Lists directory entries at a file URI on the server's filesystem.433*434* This is intended for remote folder pickers and similar UI that needs to let435* users navigate the server's local filesystem.436*437* The server MUST return success only if the target exists and is a directory.438* If the target does not exist, is not a directory, or cannot be accessed, the439* server MUST return a JSON-RPC error.440*441* @category Commands442* @method resourceList443* @direction Client → Server444* @messageType Request445* @version 1446* @throws `NotFound` (`-32008`) if the directory does not exist.447* @throws `PermissionDenied` (`-32009`) if the client is not permitted to browse the directory.448*/449export interface ResourceListParams {450/** Directory URI on the server filesystem */451uri: URI;452}453454/**455* Directory entry returned by `resourceList`.456*/457export interface DirectoryEntry {458/** Base name of the entry */459name: string;460/** Whether the entry is a file or directory */461type: 'file' | 'directory';462}463464/**465* Result of the `resourceList` command.466*/467export interface ResourceListResult {468/** Entries directly contained in the requested directory */469entries: DirectoryEntry[];470}471472// ─── fetchTurns ──────────────────────────────────────────────────────────────473474/**475* Fetches historical turns for a session. Used for lazy loading of conversation476* history.477*478* @category Commands479* @method fetchTurns480* @direction Client → Server481* @messageType Request482* @version 1483* @example484* ```jsonc485* // Client → Server (fetch the 20 most recent turns)486* { "jsonrpc": "2.0", "id": 8, "method": "fetchTurns",487* "params": { "session": "copilot:/<uuid>", "limit": 20 } }488*489* // Server → Client490* { "jsonrpc": "2.0", "id": 8, "result": {491* "turns": [ { "id": "t1", ... }, { "id": "t2", ... } ],492* "hasMore": true493* }}494*495* // Client → Server (fetch 20 turns before t1)496* { "jsonrpc": "2.0", "id": 9, "method": "fetchTurns",497* "params": { "session": "copilot:/<uuid>", "before": "t1", "limit": 20 } }498* ```499*/500export interface FetchTurnsParams {501/** Session URI */502session: URI;503/** Turn ID to fetch before (exclusive). Omit to fetch from the most recent turn. */504before?: string;505/** Maximum number of turns to return. Server MAY impose its own upper bound. */506limit?: number;507}508509/**510* Result of the `fetchTurns` command.511*/512export interface FetchTurnsResult {513/** The requested turns, ordered oldest-first */514turns: Turn[];515/** Whether more turns exist before the returned range */516hasMore: boolean;517}518519// ─── unsubscribe ─────────────────────────────────────────────────────────────520521/**522* Stop receiving updates for a URI.523*524* @category Commands525* @method unsubscribe526* @direction Client → Server527* @messageType Notification528* @version 1529* @see {@link /specification/subscriptions | Subscriptions}530*/531export interface UnsubscribeParams {532/** URI to unsubscribe from */533resource: URI;534}535536// ─── dispatchAction ──────────────────────────────────────────────────────────537538/**539* Fire-and-forget action dispatch (write-ahead). The client applies actions540* optimistically to local state.541*542* @category Commands543* @method dispatchAction544* @direction Client → Server545* @messageType Notification546* @version 1547* @see {@link /guide/actions | Actions} for the full list of client-dispatchable actions.548*/549export interface DispatchActionParams {550/** Client sequence number */551clientSeq: number;552/** The action to dispatch */553action: StateAction;554}555556// ─── resourceCopy ────────────────────────────────────────────────────────────557558/**559* Copies a resource from one URI to another on the server's filesystem.560*561* If the destination already exists, it is overwritten unless `failIfExists`562* is set.563*564* @category Commands565* @method resourceCopy566* @direction Client → Server567* @messageType Request568* @version 1569* @throws `NotFound` (`-32008`) if the source does not exist.570* @throws `PermissionDenied` (`-32009`) if the client is not permitted to read the source or write to the destination.571* @throws `AlreadyExists` (`-32010`) if `failIfExists` is set and the destination already exists.572*/573export interface ResourceCopyParams {574/** Source URI to copy from */575source: URI;576/** Destination URI to copy to */577destination: URI;578/**579* If `true`, the server MUST fail if the destination already exists instead580* of overwriting it.581*/582failIfExists?: boolean;583}584585/**586* Result of the `resourceCopy` command.587*588* An empty object on success.589*/590export interface ResourceCopyResult {591}592593// ─── resourceDelete ──────────────────────────────────────────────────────────594595/**596* Deletes a resource at a URI on the server's filesystem.597*598* @category Commands599* @method resourceDelete600* @direction Client → Server601* @messageType Request602* @version 1603* @throws `NotFound` (`-32008`) if the resource does not exist.604* @throws `PermissionDenied` (`-32009`) if the client is not permitted to delete the resource.605*/606export interface ResourceDeleteParams {607/** URI of the resource to delete */608uri: URI;609/**610* If `true` and the target is a directory, delete it and all its contents611* recursively. If `false` (default), deleting a non-empty directory MUST fail.612*/613recursive?: boolean;614}615616/**617* Result of the `resourceDelete` command.618*619* An empty object on success.620*/621export interface ResourceDeleteResult {622}623624// ─── resourceMove ────────────────────────────────────────────────────────────625626/**627* Moves (renames) a resource from one URI to another on the server's filesystem.628*629* If the destination already exists, it is overwritten unless `failIfExists`630* is set.631*632* @category Commands633* @method resourceMove634* @direction Client → Server635* @messageType Request636* @version 1637* @throws `NotFound` (`-32008`) if the source does not exist.638* @throws `PermissionDenied` (`-32009`) if the client is not permitted to move the resource.639* @throws `AlreadyExists` (`-32010`) if `failIfExists` is set and the destination already exists.640*/641export interface ResourceMoveParams {642/** Source URI to move from */643source: URI;644/** Destination URI to move to */645destination: URI;646/**647* If `true`, the server MUST fail if the destination already exists instead648* of overwriting it.649*/650failIfExists?: boolean;651}652653/**654* Result of the `resourceMove` command.655*656* An empty object on success.657*/658export interface ResourceMoveResult {659}660661// ─── authenticate ────────────────────────────────────────────────────────────662663/**664* Pushes a Bearer token for a protected resource. The `resource` field MUST665* match a `ProtectedResourceMetadata.resource` value declared by an agent666* in `AgentInfo.protectedResources`.667*668* Tokens are delivered using [RFC 6750](https://datatracker.ietf.org/doc/html/rfc6750)669* (Bearer Token Usage) semantics. The client obtains the token from the670* authorization server(s) listed in the resource's metadata and pushes it671* to the server via this command.672*673* @category Commands674* @method authenticate675* @direction Client → Server676* @messageType Request677* @version 1678* @see {@link /specification/authentication | Authentication}679* @example680* ```jsonc681* // Client → Server682* { "jsonrpc": "2.0", "id": 3, "method": "authenticate",683* "params": { "resource": "https://api.github.com", "token": "gho_xxxx" } }684*685* // Server → Client (success)686* { "jsonrpc": "2.0", "id": 3, "result": {} }687*688* // Server → Client (failure — invalid token)689* { "jsonrpc": "2.0", "id": 3, "error": { "code": -32007, "message": "Invalid token" } }690* ```691*/692export interface AuthenticateParams {693/**694* The protected resource identifier. MUST match a `resource` value from695* `ProtectedResourceMetadata` declared in `AgentInfo.protectedResources`.696*/697resource: string;698/** Bearer token obtained from the resource's authorization server */699token: string;700}701702/**703* Result of the `authenticate` command.704*705* An empty object on success. If the token is invalid or the resource is706* unrecognized, the server MUST return a JSON-RPC error (e.g. `AuthRequired`707* `-32007` or `InvalidParams` `-32602`).708*/709export interface AuthenticateResult {710}711712// ─── resolveSessionConfig ────────────────────────────────────────────────────713714/**715* Iteratively resolves the session configuration schema. The client sends the716* current partial session config and any user-filled metadata values. The server717* returns a property schema describing what additional metadata is needed,718* contextual to the current selections.719*720* The client calls this command whenever the user changes a significant input721* (e.g. picks a working directory, toggles a property). Each response returns722* the full current property set (not a delta). The returned `values` contain723* server-resolved defaults to pass to `createSession`.724*725* @category Commands726* @method resolveSessionConfig727* @direction Client → Server728* @messageType Request729* @version 1730* @example731* ```jsonc732* // Step 1: Client picks a working directory733* // Client → Server734* { "jsonrpc": "2.0", "id": 5, "method": "resolveSessionConfig",735* "params": { "workingDirectory": "file:///home/user/my-project" } }736*737* // Server → Client (git repo detected, offers worktree option)738* { "jsonrpc": "2.0", "id": 5, "result": {739* "schema": {740* "type": "object",741* "properties": {742* "target": { "type": "string", "title": "Target", "enum": ["workspace", "worktree"] }743* }744* },745* "values": {}746* }}747*748* // Step 2: User enables worktree749* // Client → Server750* { "jsonrpc": "2.0", "id": 6, "method": "resolveSessionConfig",751* "params": { "workingDirectory": "file:///home/user/my-project",752* "config": { "target": "worktree" } } }753*754* // Server → Client (now requires branch selection)755* { "jsonrpc": "2.0", "id": 6, "result": {756* "schema": {757* "type": "object",758* "properties": {759* "target": { "type": "string", "title": "Target", "enum": ["workspace", "worktree"] },760* "baseBranch": { "type": "string", "title": "Base Branch",761* "enum": ["main", "develop"],762* "enumLabels": ["main", "develop"] }763* },764* "required": ["baseBranch"]765* },766* "values": { "target": "worktree" }767* }}768* ```769*/770export interface ResolveSessionConfigParams {771/** Agent provider ID */772provider?: string;773/** Working directory for the session */774workingDirectory?: URI;775/** Current user-filled configuration values */776config?: Record<string, unknown>;777}778779/**780* Result of the `resolveSessionConfig` command.781*/782export interface ResolveSessionConfigResult {783/** JSON Schema describing available configuration properties given the current context */784schema: SessionConfigSchema;785/** Current configuration values (echoed back with server-resolved defaults applied) */786values: Record<string, unknown>;787}788789// ─── sessionConfigCompletions ────────────────────────────────────────────────790791/**792* A single value item returned by `sessionConfigCompletions`.793*794* @category Commands795*/796export interface SessionConfigValueItem {797/** The value to store in config */798value: string;799/** Human-readable display label */800label: string;801/** Optional secondary description */802description?: string;803}804805/**806* Queries the server for allowed values of a dynamic session config property.807*808* Used when a property in the schema returned by `resolveSessionConfig` has809* `enumDynamic: true`. The client sends a search query and receives matching810* values with display metadata.811*812* @category Commands813* @method sessionConfigCompletions814* @direction Client → Server815* @messageType Request816* @version 1817* @example818* ```jsonc819* // Client → Server (user types "ma" in branch picker)820* { "jsonrpc": "2.0", "id": 7, "method": "sessionConfigCompletions",821* "params": { "workingDirectory": "file:///home/user/my-project",822* "config": { "target": "worktree" },823* "property": "baseBranch", "query": "ma" } }824*825* // Server → Client826* { "jsonrpc": "2.0", "id": 7, "result": {827* "items": [828* { "value": "main", "label": "main", "icon": "git-branch" },829* { "value": "main-v2", "label": "main-v2", "icon": "git-branch" }830* ]831* }}832* ```833*/834export interface SessionConfigCompletionsParams {835/** Agent provider ID */836provider?: string;837/** Working directory for the session */838workingDirectory?: URI;839/** Current user-filled configuration values (provides context for the query) */840config?: Record<string, unknown>;841/** Property id from the schema to query values for */842property: string;843/** Search filter text (empty or omitted returns default/recent values) */844query?: string;845}846847/**848* Result of the `sessionConfigCompletions` command.849*/850export interface SessionConfigCompletionsResult {851/** Matching value items */852items: SessionConfigValueItem[];853}854855856