Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/src/vs/platform/agentHost/common/agentService.ts
13394 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
import { Event } from '../../../base/common/event.js';
7
import { IReference } from '../../../base/common/lifecycle.js';
8
import { IAuthorizationProtectedResourceMetadata } from '../../../base/common/oauth.js';
9
import type { IObservable } from '../../../base/common/observable.js';
10
import { URI } from '../../../base/common/uri.js';
11
import { createDecorator } from '../../instantiation/common/instantiation.js';
12
import type { ISyncedCustomization } from './agentPluginManager.js';
13
import type { IAgentSubscription } from './state/agentSubscription.js';
14
import type { CreateTerminalParams, ResolveSessionConfigResult, SessionConfigCompletionsResult } from './state/protocol/commands.js';
15
import { ProtectedResourceMetadata, type ConfigSchema, type FileEdit, type ModelSelection, type SessionActiveClient, type ToolCallPendingConfirmationState, type ToolDefinition } from './state/protocol/state.js';
16
import type { ActionEnvelope, INotification, IRootConfigChangedAction, SessionAction, TerminalAction } from './state/sessionActions.js';
17
import type { ResourceCopyParams, ResourceCopyResult, ResourceDeleteParams, ResourceDeleteResult, ResourceListResult, ResourceMoveParams, ResourceMoveResult, ResourceReadResult, ResourceWriteParams, ResourceWriteResult, IStateSnapshot } from './state/sessionProtocol.js';
18
import { AttachmentType, ComponentToState, SessionInputResponseKind, SessionStatus, StateComponents, type CustomizationRef, type PendingMessage, type RootState, type SessionCustomization, type SessionInputAnswer, type SessionMeta, type ToolCallResult, type Turn, type PolicyState } from './state/sessionState.js';
19
20
// IPC contract between the renderer and the agent host utility process.
21
// Defines all serializable event types, the IAgent provider interface,
22
// and the IAgentService / IAgentHostService service decorators.
23
24
export const enum AgentHostIpcChannels {
25
/** Channel for the agent host service on the main-process side */
26
AgentHost = 'agentHost',
27
/** Channel for log forwarding from the agent host process */
28
Logger = 'agentHostLogger',
29
/** Channel for WebSocket client connection count (server process management only) */
30
ConnectionTracker = 'agentHostConnectionTracker',
31
}
32
33
/** Configuration key that controls whether the local agent host process is spawned. */
34
export const AgentHostEnabledSettingId = 'chat.agentHost.enabled';
35
36
/** Configuration key that controls whether per-host IPC traffic output channels are created. */
37
export const AgentHostIpcLoggingSettingId = 'chat.agentHost.ipcLoggingEnabled';
38
39
/** Result of starting the agent host WebSocket server on-demand. */
40
export interface IAgentHostSocketInfo {
41
readonly socketPath: string;
42
}
43
44
/** Inspector listener information for the agent host process. */
45
export interface IAgentHostInspectInfo {
46
readonly host: string;
47
readonly port: number;
48
/** A `devtools://` URL that can be opened with `INativeHostService.openDevToolsWindow`. */
49
readonly devtoolsUrl: string;
50
}
51
52
/**
53
* IPC service exposed on the {@link AgentHostIpcChannels.ConnectionTracker}
54
* channel. Used by the server process for lifetime management and by the
55
* shared process to request a local WebSocket listener on-demand.
56
*/
57
export interface IConnectionTrackerService {
58
readonly onDidChangeConnectionCount: Event<number>;
59
60
/**
61
* Request the agent host to start a WebSocket server on a local
62
* pipe/socket. Returns the socket path.
63
* If a server is already running, returns the existing info.
64
*/
65
startWebSocketServer(): Promise<IAgentHostSocketInfo>;
66
67
/**
68
* Get inspector listener info for the agent host process. If the inspector
69
* is not currently active and `tryEnable` is true, opens the inspector on
70
* a random local port. Returns `undefined` if the inspector cannot be
71
* enabled (e.g. running in an environment without `node:inspector`).
72
*/
73
getInspectInfo(tryEnable: boolean): Promise<IAgentHostInspectInfo | undefined>;
74
}
75
76
// ---- IPC data types (serializable across MessagePort) -----------------------
77
78
export interface IAgentSessionMetadata {
79
readonly session: URI;
80
readonly startTime: number;
81
readonly modifiedTime: number;
82
readonly project?: IAgentSessionProjectInfo;
83
readonly summary?: string;
84
readonly status?: SessionStatus;
85
/** Human-readable description of what the session is currently doing. */
86
readonly activity?: string;
87
readonly model?: ModelSelection;
88
readonly workingDirectory?: URI;
89
readonly customizationDirectory?: URI;
90
readonly isRead?: boolean;
91
readonly isArchived?: boolean;
92
readonly diffs?: readonly FileEdit[];
93
/**
94
* Side-channel metadata mirroring {@link SessionState._meta}, propagated
95
* to clients via per-session state subscriptions.
96
* Producers SHOULD use namespaced keys; consumers MUST ignore unknown
97
* keys. Use the typed accessors in `sessionState.ts` (e.g.
98
* `readSessionGitState`) for well-known slots.
99
*/
100
readonly _meta?: SessionMeta;
101
}
102
103
export interface IAgentSessionProjectInfo {
104
readonly uri: URI;
105
readonly displayName: string;
106
}
107
108
export interface IAgentCreateSessionResult {
109
readonly session: URI;
110
readonly project?: IAgentSessionProjectInfo;
111
/** The resolved working directory, which may differ from the requested one (e.g. worktree). */
112
readonly workingDirectory?: URI;
113
}
114
115
export type AgentProvider = string;
116
117
/** Metadata describing an agent backend, discovered over IPC. */
118
export interface IAgentDescriptor {
119
readonly provider: AgentProvider;
120
readonly displayName: string;
121
readonly description: string;
122
}
123
124
// ---- Auth types (RFC 9728 / RFC 6750 inspired) -----------------------------
125
126
/**
127
* Parameters for the `authenticate` command.
128
* Analogous to sending `Authorization: Bearer <token>` (RFC 6750 section 2.1).
129
*/
130
export interface AuthenticateParams {
131
/**
132
* The `resource` identifier from the server's
133
* {@link IAuthorizationProtectedResourceMetadata} that this token targets.
134
*/
135
readonly resource: string;
136
137
/** The bearer token value (RFC 6750). */
138
readonly token: string;
139
}
140
141
/**
142
* Result of the `authenticate` command.
143
*/
144
export interface AuthenticateResult {
145
/** Whether the token was accepted. */
146
readonly authenticated: boolean;
147
}
148
149
export interface IAgentCreateSessionConfig {
150
readonly provider?: AgentProvider;
151
readonly model?: ModelSelection;
152
readonly session?: URI;
153
readonly workingDirectory?: URI;
154
readonly config?: Record<string, unknown>;
155
/**
156
* Eagerly claim the active client role for the new session. When provided,
157
* the server initializes the session with this client as the active
158
* client, equivalent to dispatching a `session/activeClientChanged`
159
* action immediately after creation. The `clientId` MUST match the
160
* connection's own `clientId`.
161
*/
162
readonly activeClient?: SessionActiveClient;
163
/** Fork from an existing session at a specific turn. */
164
readonly fork?: {
165
readonly session: URI;
166
readonly turnIndex: number;
167
readonly turnId: string;
168
/**
169
* Maps old protocol turn IDs to new protocol turn IDs.
170
* Populated by the service layer after generating fresh UUIDs
171
* for the forked session's turns. Used by the agent to remap
172
* per-turn data (e.g. SDK event ID mappings) in the session database.
173
*/
174
readonly turnIdMapping?: ReadonlyMap<string, string>;
175
};
176
}
177
178
export interface IAgentResolveSessionConfigParams {
179
readonly provider?: AgentProvider;
180
readonly workingDirectory?: URI;
181
readonly config?: Record<string, unknown>;
182
}
183
184
export interface IAgentSessionConfigCompletionsParams extends IAgentResolveSessionConfigParams {
185
readonly property: string;
186
readonly query?: string;
187
}
188
189
/** Serializable attachment passed alongside a message to the agent host. */
190
export interface IAgentAttachment {
191
readonly type: AttachmentType;
192
readonly uri: URI;
193
readonly displayName?: string;
194
/** For selections: the selected text. */
195
readonly text?: string;
196
/** For selections: line/character range. */
197
readonly selection?: {
198
readonly start: { readonly line: number; readonly character: number };
199
readonly end: { readonly line: number; readonly character: number };
200
};
201
}
202
203
/** Serializable model information from the agent host. */
204
export interface IAgentModelInfo {
205
readonly provider: AgentProvider;
206
readonly id: string;
207
readonly name: string;
208
readonly maxContextWindow?: number;
209
readonly supportsVision: boolean;
210
readonly configSchema?: ConfigSchema;
211
readonly policyState?: PolicyState;
212
}
213
214
// ---- Agent signals (sent via IAgent.onDidSessionProgress) -------------------
215
216
/**
217
* A signal emitted by an agent during session execution.
218
*
219
* Most signals carry a protocol {@link SessionAction} directly via the
220
* `kind: 'action'` shape, eliminating a parallel event ontology. A small
221
* number of cases that have no clean protocol action (permission
222
* auto-approval, subagent session creation, steering message
223
* acknowledgment) remain as discriminated non-action signals so the host
224
* can perform side effects before — or instead of — dispatching an action.
225
*/
226
export type AgentSignal =
227
| IAgentActionSignal
228
| IAgentToolPendingConfirmationSignal
229
| IAgentSubagentStartedSignal
230
| IAgentSteeringConsumedSignal;
231
232
/**
233
* Carries a protocol {@link SessionAction} produced by an agent. The host
234
* dispatches the action through the state manager after routing via
235
* {@link IAgentActionSignal.parentToolCallId} (if set).
236
*
237
* Agents are responsible for populating `session` and any `turnId` /
238
* `partId` fields on the action.
239
*/
240
export interface IAgentActionSignal {
241
readonly kind: 'action';
242
/** Top-level session URI. For inner subagent events this is the parent session — see {@link parentToolCallId}. */
243
readonly session: URI;
244
/** Protocol action to dispatch. */
245
readonly action: SessionAction;
246
/** If set, route the action to the subagent session belonging to this tool call. */
247
readonly parentToolCallId?: string;
248
}
249
250
/**
251
* A tool has finished collecting parameters and needs the host to decide
252
* whether it should run (or, mid-execution, re-confirm). The host applies
253
* auto-approval logic over {@link permissionKind} / {@link permissionPath}
254
* (see `SessionPermissionManager.getAutoApproval`) and then dispatches the
255
* appropriate `SessionToolCallReady` action — with confirmation options
256
* baked in when the user must approve, or with `confirmed: NotNeeded` when
257
* the host auto-approved.
258
*
259
* Kept as a non-action signal because the host owns this approval policy;
260
* the agent only describes the tool call and the kind of permission being
261
* requested. The {@link state} field carries the protocol-shaped tool-call
262
* state and is dispatched verbatim into the action.
263
*/
264
export interface IAgentToolPendingConfirmationSignal {
265
readonly kind: 'pending_confirmation';
266
readonly session: URI;
267
/** Protocol-shaped pending-confirmation state, dispatched verbatim into `SessionToolCallReady`. */
268
readonly state: ToolCallPendingConfirmationState;
269
/** Host-only auto-approval kind (not part of the dispatched action). */
270
readonly permissionKind?: 'shell' | 'write' | 'mcp' | 'read' | 'url' | 'custom-tool' | 'hook' | 'memory';
271
/** Host-only auto-approval path target (not part of the dispatched action). */
272
readonly permissionPath?: string;
273
/**
274
* If set, the tool call belongs to the subagent rooted at this
275
* parent tool call. Used by the host to route the resulting
276
* `SessionToolCallReady` to the subagent session — otherwise the
277
* action would land on the parent session, where there is no
278
* matching `SessionToolCallStart`.
279
*/
280
readonly parentToolCallId?: string;
281
}
282
283
/**
284
* A subagent was spawned by a tool call. The host creates a child session
285
* silently and routes subsequent inner-tool events to it.
286
*
287
* Kept as a non-action signal because subagent session creation has no
288
* protocol action — it's a host-side composition primitive.
289
*/
290
export interface IAgentSubagentStartedSignal {
291
readonly kind: 'subagent_started';
292
readonly session: URI;
293
readonly toolCallId: string;
294
readonly agentName: string;
295
readonly agentDisplayName: string;
296
readonly agentDescription?: string;
297
}
298
299
/** A steering message was consumed (sent to the model). */
300
export interface IAgentSteeringConsumedSignal {
301
readonly kind: 'steering_consumed';
302
readonly session: URI;
303
readonly id: string;
304
}
305
306
// ---- Session URI helpers ----------------------------------------------------
307
308
export namespace AgentSession {
309
310
/**
311
* Creates a session URI from a provider name and raw session ID.
312
* The URI scheme is the provider name (e.g., `copilot:/<rawId>`).
313
*/
314
export function uri(provider: AgentProvider, rawSessionId: string): URI {
315
return URI.from({ scheme: provider, path: `/${rawSessionId}` });
316
}
317
318
/**
319
* Extracts the raw session ID from a session URI (the path without leading slash).
320
* Accepts both a URI object and a URI string.
321
*/
322
export function id(session: URI | string): string {
323
const parsed = typeof session === 'string' ? URI.parse(session) : session;
324
return parsed.path.substring(1);
325
}
326
327
/**
328
* Extracts the provider name from a session URI scheme.
329
* Accepts both a URI object and a URI string.
330
*/
331
export function provider(session: URI | string): AgentProvider | undefined {
332
const parsed = typeof session === 'string' ? URI.parse(session) : session;
333
return parsed.scheme || undefined;
334
}
335
}
336
337
// ---- Agent provider interface -----------------------------------------------
338
339
/**
340
* Implemented by each agent backend (e.g. Copilot SDK).
341
* The {@link IAgentService} dispatches to the appropriate agent based on
342
* the agent id.
343
*/
344
export interface IAgent {
345
/** Unique identifier for this provider (e.g. `'copilot'`). */
346
readonly id: AgentProvider;
347
348
/** Fires when the provider streams progress for a session. */
349
readonly onDidSessionProgress: Event<AgentSignal>;
350
351
/** Create a new session. Returns server-owned session metadata. */
352
createSession(config?: IAgentCreateSessionConfig): Promise<IAgentCreateSessionResult>;
353
354
/** Resolve the dynamic configuration schema for creating a session. */
355
resolveSessionConfig(params: IAgentResolveSessionConfigParams): Promise<ResolveSessionConfigResult>;
356
357
/** Return dynamic completions for a session configuration property. */
358
sessionConfigCompletions(params: IAgentSessionConfigCompletionsParams): Promise<SessionConfigCompletionsResult>;
359
360
/** Send a user message into an existing session. */
361
sendMessage(session: URI, prompt: string, attachments?: IAgentAttachment[], turnId?: string): Promise<void>;
362
363
/**
364
* Called when the session's pending (steering) message changes.
365
* The agent harness decides how to react — e.g. inject steering
366
* mid-turn via `mode: 'immediate'`.
367
*
368
* Queued messages are consumed on the server side and are not
369
* forwarded to the agent; `queuedMessages` will always be empty.
370
*/
371
setPendingMessages?(session: URI, steeringMessage: PendingMessage | undefined, queuedMessages: readonly PendingMessage[]): void;
372
373
/**
374
* Retrieve the reconstructed turns for a session, used when restoring
375
* sessions from persistent storage. Each agent owns the conversion from
376
* its SDK-specific event log to protocol {@link Turn}s, including
377
* subagent sessions (callers pass the subagent URI to retrieve the
378
* child session's turns).
379
*/
380
getSessionMessages(session: URI): Promise<readonly Turn[]>;
381
382
/** Dispose a session, freeing resources. */
383
disposeSession(session: URI): Promise<void>;
384
385
/** Abort the current turn, stopping any in-flight processing. */
386
abortSession(session: URI): Promise<void>;
387
388
/** Change the model for an existing session. */
389
changeModel(session: URI, model: ModelSelection): Promise<void>;
390
391
/** Respond to a pending permission request from the SDK. */
392
respondToPermissionRequest(requestId: string, approved: boolean): void;
393
394
/** Respond to a pending user input request from the SDK's ask_user tool. */
395
respondToUserInputRequest(requestId: string, response: SessionInputResponseKind, answers?: Record<string, SessionInputAnswer>): void;
396
397
/** Return the descriptor for this agent. */
398
getDescriptor(): IAgentDescriptor;
399
400
/** Available models from this provider. */
401
readonly models: IObservable<readonly IAgentModelInfo[]>;
402
403
/** List persisted sessions from this provider. */
404
listSessions(): Promise<IAgentSessionMetadata[]>;
405
406
/** Declare protected resources this agent requires auth for (RFC 9728). */
407
getProtectedResources(): ProtectedResourceMetadata[];
408
409
/**
410
* Fires when the agent's host-owned customizations change
411
* (loading state, resolution results, etc.), so infrastructure
412
* can republish {@link AgentInfo} and session customization state.
413
*/
414
readonly onDidCustomizationsChange?: Event<void>;
415
416
/**
417
* Returns the host-owned customization refs this agent currently exposes.
418
*
419
* Used to publish baseline customization metadata on {@link AgentInfo}.
420
*/
421
getCustomizations?(): readonly CustomizationRef[];
422
423
/**
424
* Returns the effective customization list for a session, including
425
* source, enablement, and loading/error status.
426
*/
427
getSessionCustomizations?(session: URI): Promise<readonly SessionCustomization[]>;
428
429
/**
430
* Authenticate for a specific resource. Returns true if accepted.
431
* The `resource` matches {@link IAuthorizationProtectedResourceMetadata.resource}.
432
*/
433
authenticate(resource: string, token: string): Promise<boolean>;
434
435
/**
436
* Truncate a session's history. If `turnId` is provided, keeps turns up to
437
* and including that turn. If omitted, all turns are removed.
438
* Optional — not all providers support truncation.
439
*/
440
truncateSession?(session: URI, turnId?: string): Promise<void>;
441
442
/**
443
* Notifies the provider that a session's archived state has changed.
444
* Providers may use this to clean up or restore per-session resources
445
* (for example, removing a session-owned worktree on archive and
446
* recreating it on unarchive). Optional.
447
*/
448
onArchivedChanged?(session: URI, isArchived: boolean): Promise<void>;
449
450
/**
451
* Receives client-provided customization refs and syncs them (e.g. copies
452
* plugin files to local storage). Returns per-customization status with
453
* local plugin directories.
454
*
455
* The agent MAY defer a client restart until all active sessions are idle.
456
*/
457
setClientCustomizations(clientId: string, customizations: CustomizationRef[], progress?: (results: ISyncedCustomization[]) => void): Promise<ISyncedCustomization[]>;
458
459
/**
460
* Receives client-provided tool definitions to make available in a
461
* specific session. The agent registers these as custom tools so the
462
* LLM can call them; execution is routed back to the owning client.
463
*
464
* Always called on `activeClientChanged`, even with an empty array,
465
* to clear a previous client's tools.
466
*
467
* @param session The session URI this tool set applies to.
468
* @param clientId The client that owns these tools.
469
* @param tools The tool definitions (full replacement).
470
*/
471
setClientTools(session: URI, clientId: string, tools: ToolDefinition[]): void;
472
473
/**
474
* Called when a client completes a client-provided tool call.
475
* Resolves the tool handler's deferred promise so the SDK can continue.
476
*
477
* @param session The session the tool call belongs to.
478
*/
479
onClientToolCallComplete(session: URI, toolCallId: string, result: ToolCallResult): void;
480
481
/**
482
* Notifies the agent that a customization has been toggled on or off.
483
* The agent MAY restart its client before the next message is sent.
484
*/
485
setCustomizationEnabled(uri: string, enabled: boolean): void;
486
487
/** Gracefully shut down all sessions. */
488
shutdown(): Promise<void>;
489
490
/** Dispose this provider and all its resources. */
491
dispose(): void;
492
}
493
494
// ---- Service interfaces -----------------------------------------------------
495
496
export const IAgentService = createDecorator<IAgentService>('agentService');
497
498
/**
499
* Service contract for communicating with the agent host process. Methods here
500
* are proxied across MessagePort via `ProxyChannel`.
501
*
502
* State is synchronized via the subscribe/unsubscribe/dispatchAction protocol.
503
* Clients observe root state (agents, models) and session state via subscriptions,
504
* and mutate state by dispatching actions (e.g. session/turnStarted, session/turnCancelled).
505
*/
506
export interface IAgentService {
507
readonly _serviceBrand: undefined;
508
509
/**
510
* Authenticate for a protected resource on the server.
511
* The {@link AuthenticateParams.resource} must match a resource from
512
* the agent's protectedResources in root state. Analogous to RFC 6750
513
* bearer token delivery.
514
*/
515
authenticate(params: AuthenticateParams): Promise<AuthenticateResult>;
516
517
/** List all available sessions from the Copilot CLI. */
518
listSessions(): Promise<IAgentSessionMetadata[]>;
519
520
/** Create a new session. Returns the session URI. */
521
createSession(config?: IAgentCreateSessionConfig): Promise<URI>;
522
523
/** Resolve the dynamic configuration schema for creating a session. */
524
resolveSessionConfig(params: IAgentResolveSessionConfigParams): Promise<ResolveSessionConfigResult>;
525
526
/** Return dynamic completions for a session configuration property. */
527
sessionConfigCompletions(params: IAgentSessionConfigCompletionsParams): Promise<SessionConfigCompletionsResult>;
528
529
/** Dispose a session in the agent host, freeing SDK resources. */
530
disposeSession(session: URI): Promise<void>;
531
532
/** Create a new terminal on the agent host. */
533
createTerminal(params: CreateTerminalParams): Promise<void>;
534
535
/** Dispose a terminal and kill its process if still running. */
536
disposeTerminal(terminal: URI): Promise<void>;
537
538
/** Gracefully shut down all sessions and the underlying client. */
539
shutdown(): Promise<void>;
540
541
// ---- Protocol methods (sessions process protocol) ----------------------
542
543
/**
544
* Subscribe to state at the given URI. Returns a snapshot of the current
545
* state and the serverSeq at snapshot time. Subsequent actions for this
546
* resource arrive via {@link onDidAction}.
547
*/
548
subscribe(resource: URI): Promise<IStateSnapshot>;
549
550
/** Unsubscribe from state updates for the given URI. */
551
unsubscribe(resource: URI): void;
552
553
/**
554
* Fires when the server applies an action to subscribable state.
555
* Clients use this alongside {@link subscribe} to keep their local
556
* state in sync.
557
*/
558
readonly onDidAction: Event<ActionEnvelope>;
559
560
/**
561
* Fires when the server broadcasts an ephemeral notification
562
* (e.g. sessionAdded, sessionRemoved).
563
*/
564
readonly onDidNotification: Event<INotification>;
565
566
/**
567
* Dispatch a client-originated action to the server. The server applies
568
* it to state, triggers side effects, and echoes it back via
569
* {@link onDidAction} with the client's origin for reconciliation.
570
*/
571
dispatchAction(action: SessionAction | TerminalAction | IRootConfigChangedAction, clientId: string, clientSeq: number): void;
572
573
/**
574
* List the contents of a directory on the agent host's filesystem.
575
* Used by the client to drive a remote folder picker before session creation.
576
*/
577
resourceList(uri: URI): Promise<ResourceListResult>;
578
579
/**
580
* Read stored content by URI from the agent host (e.g. file edit snapshots,
581
* or reading files from the remote filesystem).
582
*/
583
resourceRead(uri: URI): Promise<ResourceReadResult>;
584
585
/**
586
* Write content to a file on the agent host's filesystem.
587
* Used for undo/redo operations on file edits.
588
*/
589
resourceWrite(params: ResourceWriteParams): Promise<ResourceWriteResult>;
590
591
/**
592
* Copy a resource from one URI to another on the agent host's filesystem.
593
*/
594
resourceCopy(params: ResourceCopyParams): Promise<ResourceCopyResult>;
595
596
/**
597
* Delete a resource at a URI on the agent host's filesystem.
598
*/
599
resourceDelete(params: ResourceDeleteParams): Promise<ResourceDeleteResult>;
600
601
/**
602
* Move (rename) a resource from one URI to another on the agent host's filesystem.
603
*/
604
resourceMove(params: ResourceMoveParams): Promise<ResourceMoveResult>;
605
}
606
607
/**
608
* Consumer-facing connection to an agent host. Session handlers, terminal
609
* contributions, and other features program against this interface.
610
*
611
* Implementations wrap an {@link IAgentService} and layer subscription
612
* management and optimistic write-ahead on top.
613
*/
614
export interface IAgentConnection {
615
readonly _serviceBrand: undefined;
616
readonly clientId: string;
617
618
// ---- State subscriptions ------------------------------------------------
619
readonly rootState: IAgentSubscription<RootState>;
620
getSubscription<T extends StateComponents>(kind: T, resource: URI): IReference<IAgentSubscription<ComponentToState[T]>>;
621
getSubscriptionUnmanaged<T extends StateComponents>(kind: T, resource: URI): IAgentSubscription<ComponentToState[T]> | undefined;
622
623
// ---- Action dispatch ----------------------------------------------------
624
dispatch(action: SessionAction | TerminalAction | IRootConfigChangedAction): void;
625
626
// ---- Events (connection-level) ------------------------------------------
627
readonly onDidNotification: Event<INotification>;
628
readonly onDidAction: Event<ActionEnvelope>;
629
630
// ---- Session lifecycle --------------------------------------------------
631
authenticate(params: AuthenticateParams): Promise<AuthenticateResult>;
632
listSessions(): Promise<IAgentSessionMetadata[]>;
633
createSession(config?: IAgentCreateSessionConfig): Promise<URI>;
634
resolveSessionConfig(params: IAgentResolveSessionConfigParams): Promise<ResolveSessionConfigResult>;
635
sessionConfigCompletions(params: IAgentSessionConfigCompletionsParams): Promise<SessionConfigCompletionsResult>;
636
disposeSession(session: URI): Promise<void>;
637
638
// ---- Terminal lifecycle -------------------------------------------------
639
createTerminal(params: CreateTerminalParams): Promise<void>;
640
disposeTerminal(terminal: URI): Promise<void>;
641
642
// ---- Filesystem operations ----------------------------------------------
643
resourceList(uri: URI): Promise<ResourceListResult>;
644
resourceRead(uri: URI): Promise<ResourceReadResult>;
645
resourceWrite(params: ResourceWriteParams): Promise<ResourceWriteResult>;
646
resourceCopy(params: ResourceCopyParams): Promise<ResourceCopyResult>;
647
resourceDelete(params: ResourceDeleteParams): Promise<ResourceDeleteResult>;
648
resourceMove(params: ResourceMoveParams): Promise<ResourceMoveResult>;
649
}
650
651
export const IAgentHostService = createDecorator<IAgentHostService>('agentHostService');
652
653
/**
654
* The local wrapper around the agent host process (manages lifecycle, restart,
655
* exposes the proxied service). Consumed by the main process and workbench.
656
*/
657
export interface IAgentHostService extends IAgentConnection {
658
659
readonly onAgentHostExit: Event<number>;
660
readonly onAgentHostStart: Event<void>;
661
662
/**
663
* `true` while we are in the middle of authenticating against the local
664
* agent host (resolving tokens for any advertised `protectedResources` and
665
* pushing them via {@link authenticate}). Defaults to `true` at startup so
666
* that the period before the first auth pass is also covered.
667
*
668
* Producers (the workbench `AgentHostContribution`) flip this around their
669
* auth pass; consumers (e.g. the local sessions provider) read it to mark
670
* sessions as still loading.
671
*/
672
readonly authenticationPending: IObservable<boolean>;
673
674
/** Update {@link authenticationPending}. Internal — only the auth driver should call this. */
675
setAuthenticationPending(pending: boolean): void;
676
677
restartAgentHost(): Promise<void>;
678
679
startWebSocketServer(): Promise<IAgentHostSocketInfo>;
680
681
/**
682
* Get inspector listener info for the agent host process. If the inspector
683
* is not currently active and `tryEnable` is true, opens the inspector on
684
* a random local port. Returns `undefined` if the inspector cannot be
685
* enabled.
686
*/
687
getInspectInfo(tryEnable: boolean): Promise<IAgentHostInspectInfo | undefined>;
688
}
689
690