@tylerl0706/ahpx 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,3397 @@
1
+ import { EventEmitter } from 'node:events';
2
+
3
+ /**
4
+ * State Types — Source of truth for all AHP state type definitions.
5
+ *
6
+ * @module state
7
+ * @description Complete reference for all state types in the Agent Host Protocol.
8
+ */
9
+ /** A URI string (e.g. `agenthost:/root` or `copilot:/<uuid>`). */
10
+ type URI = string;
11
+ /**
12
+ * A string that may optionally be rendered as Markdown.
13
+ *
14
+ * - A plain `string` is rendered as-is (no Markdown processing).
15
+ * - An object with `{ markdown: string }` is rendered with Markdown formatting.
16
+ */
17
+ type StringOrMarkdown = string | {
18
+ markdown: string;
19
+ };
20
+ /**
21
+ * An optionally-sized icon that can be displayed in a user interface.
22
+ *
23
+ * @category Common Types
24
+ */
25
+ interface Icon {
26
+ /**
27
+ * A standard URI pointing to an icon resource. May be an HTTP/HTTPS URL or a
28
+ * `data:` URI with Base64-encoded image data.
29
+ *
30
+ * Consumers SHOULD take steps to ensure URLs serving icons are from the
31
+ * same domain as the client/server or a trusted domain.
32
+ *
33
+ * Consumers SHOULD take appropriate precautions when consuming SVGs as they can contain
34
+ * executable JavaScript.
35
+ */
36
+ src: URI;
37
+ /**
38
+ * Optional MIME type override if the source MIME type is missing or generic.
39
+ * For example: `"image/png"`, `"image/jpeg"`, or `"image/svg+xml"`.
40
+ */
41
+ contentType?: string;
42
+ /**
43
+ * Optional array of strings that specify sizes at which the icon can be used.
44
+ * Each string should be in WxH format (e.g., `"48x48"`, `"96x96"`) or `"any"` for scalable formats like SVG.
45
+ *
46
+ * If not provided, the client should assume that the icon can be used at any size.
47
+ */
48
+ sizes?: string[];
49
+ /**
50
+ * Optional specifier for the theme this icon is designed for. `"light"` indicates
51
+ * the icon is designed to be used with a light background, and `"dark"` indicates
52
+ * the icon is designed to be used with a dark background.
53
+ *
54
+ * If not provided, the client should assume the icon can be used with any theme.
55
+ */
56
+ theme?: 'light' | 'dark';
57
+ }
58
+ /**
59
+ * Describes a protected resource's authentication requirements using
60
+ * [RFC 9728](https://datatracker.ietf.org/doc/html/rfc9728) (OAuth 2.0
61
+ * Protected Resource Metadata) semantics.
62
+ *
63
+ * Field names use snake_case to match the RFC 9728 JSON format.
64
+ *
65
+ * @category Authentication
66
+ * @see {@link https://datatracker.ietf.org/doc/html/rfc9728 | RFC 9728}
67
+ */
68
+ interface IProtectedResourceMetadata {
69
+ /**
70
+ * REQUIRED. The protected resource's resource identifier, a URL using the
71
+ * `https` scheme with no fragment component (e.g. `"https://api.github.com"`).
72
+ */
73
+ resource: string;
74
+ /** OPTIONAL. Human-readable name of the protected resource. */
75
+ resource_name?: string;
76
+ /** OPTIONAL. JSON array of OAuth authorization server identifier URLs. */
77
+ authorization_servers?: string[];
78
+ /** OPTIONAL. URL of the protected resource's JWK Set document. */
79
+ jwks_uri?: string;
80
+ /** RECOMMENDED. JSON array of OAuth 2.0 scope values used in authorization requests. */
81
+ scopes_supported?: string[];
82
+ /** OPTIONAL. JSON array of Bearer Token presentation methods supported. */
83
+ bearer_methods_supported?: string[];
84
+ /** OPTIONAL. JSON array of JWS signing algorithms supported. */
85
+ resource_signing_alg_values_supported?: string[];
86
+ /** OPTIONAL. JSON array of JWE encryption algorithms (alg) supported. */
87
+ resource_encryption_alg_values_supported?: string[];
88
+ /** OPTIONAL. JSON array of JWE encryption algorithms (enc) supported. */
89
+ resource_encryption_enc_values_supported?: string[];
90
+ /** OPTIONAL. URL of human-readable documentation for the resource. */
91
+ resource_documentation?: string;
92
+ /** OPTIONAL. URL of the resource's data-usage policy. */
93
+ resource_policy_uri?: string;
94
+ /** OPTIONAL. URL of the resource's terms of service. */
95
+ resource_tos_uri?: string;
96
+ /**
97
+ * AHP extension. Whether authentication is required for this resource.
98
+ *
99
+ * - `true` (default) — the agent cannot be used without a valid token.
100
+ * The server SHOULD return `AuthRequired` (`-32007`) if the client
101
+ * attempts to use the agent without authenticating.
102
+ * - `false` — the agent works without authentication but MAY offer
103
+ * enhanced capabilities when a token is provided.
104
+ *
105
+ * Clients SHOULD treat an absent field the same as `true`.
106
+ */
107
+ required?: boolean;
108
+ }
109
+ /**
110
+ * Policy configuration state for a model.
111
+ *
112
+ * @category Root State
113
+ */
114
+ declare const enum PolicyState {
115
+ Enabled = "enabled",
116
+ Disabled = "disabled",
117
+ Unconfigured = "unconfigured"
118
+ }
119
+ /**
120
+ * Global state shared with every client subscribed to `agenthost:/root`.
121
+ *
122
+ * @category Root State
123
+ */
124
+ interface IRootState {
125
+ /** Available agent backends and their models */
126
+ agents: IAgentInfo[];
127
+ /** Number of active (non-disposed) sessions on the server */
128
+ activeSessions?: number;
129
+ }
130
+ /**
131
+ * @category Root State
132
+ */
133
+ interface IAgentInfo {
134
+ /** Agent provider ID (e.g. `'copilot'`) */
135
+ provider: string;
136
+ /** Human-readable name */
137
+ displayName: string;
138
+ /** Description string */
139
+ description: string;
140
+ /** Available models for this agent */
141
+ models: ISessionModelInfo[];
142
+ /**
143
+ * Protected resources this agent requires authentication for.
144
+ *
145
+ * Each entry describes an OAuth 2.0 protected resource using
146
+ * [RFC 9728](https://datatracker.ietf.org/doc/html/rfc9728) semantics.
147
+ * Clients should obtain tokens from the declared `authorization_servers`
148
+ * and push them via the `authenticate` command before creating sessions
149
+ * with this agent.
150
+ *
151
+ * @see {@link /specification/authentication | Authentication}
152
+ */
153
+ protectedResources?: IProtectedResourceMetadata[];
154
+ /**
155
+ * Customizations (Open Plugins) associated with this agent.
156
+ *
157
+ * Each entry is a reference to an [Open Plugins](https://open-plugins.com/)
158
+ * plugin that the agent host can activate for sessions using this agent.
159
+ */
160
+ customizations?: ICustomizationRef[];
161
+ }
162
+ /**
163
+ * @category Root State
164
+ */
165
+ interface ISessionModelInfo {
166
+ /** Model identifier */
167
+ id: string;
168
+ /** Provider this model belongs to */
169
+ provider: string;
170
+ /** Human-readable model name */
171
+ name: string;
172
+ /** Maximum context window size */
173
+ maxContextWindow?: number;
174
+ /** Whether the model supports vision */
175
+ supportsVision?: boolean;
176
+ /** Policy configuration state */
177
+ policyState?: PolicyState;
178
+ }
179
+ /**
180
+ * Discriminant for pending message kinds.
181
+ *
182
+ * @category Pending Message Types
183
+ */
184
+ declare const enum PendingMessageKind {
185
+ /** Injected into the current turn at a convenient point */
186
+ Steering = "steering",
187
+ /** Sent automatically as a new turn after the current turn finishes */
188
+ Queued = "queued"
189
+ }
190
+ /**
191
+ * A message queued for future delivery to the agent.
192
+ *
193
+ * Steering messages are injected into the current turn mid-flight.
194
+ * Queued messages are automatically started as new turns after the
195
+ * current turn naturally finishes.
196
+ *
197
+ * @category Pending Message Types
198
+ */
199
+ interface IPendingMessage {
200
+ /** Unique identifier for this pending message */
201
+ id: string;
202
+ /** The message content */
203
+ userMessage: IUserMessage;
204
+ }
205
+ /**
206
+ * Session initialization state.
207
+ *
208
+ * @category Session State
209
+ */
210
+ declare const enum SessionLifecycle {
211
+ Creating = "creating",
212
+ Ready = "ready",
213
+ CreationFailed = "creationFailed"
214
+ }
215
+ /**
216
+ * Current session status.
217
+ *
218
+ * @category Session State
219
+ */
220
+ declare const enum SessionStatus {
221
+ Idle = "idle",
222
+ InProgress = "in-progress",
223
+ Error = "error"
224
+ }
225
+ /**
226
+ * Full state for a single session, loaded when a client subscribes to the session's URI.
227
+ *
228
+ * @category Session State
229
+ */
230
+ interface ISessionState {
231
+ /** Lightweight session metadata */
232
+ summary: ISessionSummary;
233
+ /** Session initialization state */
234
+ lifecycle: SessionLifecycle;
235
+ /** Error details if creation failed */
236
+ creationError?: IErrorInfo;
237
+ /** Tools provided by the server (agent host) for this session */
238
+ serverTools?: IToolDefinition[];
239
+ /** The client currently providing tools and interactive capabilities to this session */
240
+ activeClient?: ISessionActiveClient;
241
+ /** The working directory URI for this session */
242
+ workingDirectory?: URI;
243
+ /** Completed turns */
244
+ turns: ITurn[];
245
+ /** Currently in-progress turn */
246
+ activeTurn?: IActiveTurn;
247
+ /** Message to inject into the current turn at a convenient point */
248
+ steeringMessage?: IPendingMessage;
249
+ /** Messages to send automatically as new turns after the current turn finishes */
250
+ queuedMessages?: IPendingMessage[];
251
+ /**
252
+ * Server-provided customizations active in this session.
253
+ *
254
+ * Client-provided customizations are available on
255
+ * {@link ISessionActiveClient.customizations | activeClient.customizations}.
256
+ */
257
+ customizations?: ISessionCustomization[];
258
+ }
259
+ /**
260
+ * The client currently providing tools and interactive capabilities to a session.
261
+ *
262
+ * Only one client may be active per session at a time. The server SHOULD
263
+ * automatically unset the active client if that client disconnects.
264
+ *
265
+ * @category Session State
266
+ */
267
+ interface ISessionActiveClient {
268
+ /** Client identifier (matches `clientId` from `initialize`) */
269
+ clientId: string;
270
+ /** Human-readable client name (e.g. `"VS Code"`) */
271
+ displayName?: string;
272
+ /** Tools this client provides to the session */
273
+ tools: IToolDefinition[];
274
+ /** Customizations this client contributes to the session */
275
+ customizations?: ICustomizationRef[];
276
+ }
277
+ /**
278
+ * @category Session State
279
+ */
280
+ interface ISessionSummary {
281
+ /** Session URI */
282
+ resource: URI;
283
+ /** Agent provider ID */
284
+ provider: string;
285
+ /** Session title */
286
+ title: string;
287
+ /** Current session status */
288
+ status: SessionStatus;
289
+ /** Creation timestamp */
290
+ createdAt: number;
291
+ /** Last modification timestamp */
292
+ modifiedAt: number;
293
+ /** Currently selected model */
294
+ model?: string;
295
+ /** The working directory URI for this session */
296
+ workingDirectory?: URI;
297
+ }
298
+ /**
299
+ * How a turn ended.
300
+ *
301
+ * @category Turn Types
302
+ */
303
+ declare const enum TurnState {
304
+ Complete = "complete",
305
+ Cancelled = "cancelled",
306
+ Error = "error"
307
+ }
308
+ /**
309
+ * Type of a message attachment.
310
+ *
311
+ * @category Turn Types
312
+ */
313
+ declare const enum AttachmentType {
314
+ File = "file",
315
+ Directory = "directory",
316
+ Selection = "selection"
317
+ }
318
+ /**
319
+ * A completed request/response cycle.
320
+ *
321
+ * @category Turn Types
322
+ */
323
+ interface ITurn {
324
+ /** Turn identifier */
325
+ id: string;
326
+ /** The user's input */
327
+ userMessage: IUserMessage;
328
+ /**
329
+ * All response content in stream order: text, tool calls, reasoning, and content refs.
330
+ *
331
+ * Consumers should derive display text by concatenating markdown parts,
332
+ * and find tool calls by filtering for `ToolCall` parts.
333
+ */
334
+ responseParts: IResponsePart[];
335
+ /** Token usage info */
336
+ usage: IUsageInfo | undefined;
337
+ /** How the turn ended */
338
+ state: TurnState;
339
+ /** Error details if state is `'error'` */
340
+ error?: IErrorInfo;
341
+ }
342
+ /**
343
+ * An in-progress turn — the assistant is actively streaming.
344
+ *
345
+ * @category Turn Types
346
+ */
347
+ interface IActiveTurn {
348
+ /** Turn identifier */
349
+ id: string;
350
+ /** The user's input */
351
+ userMessage: IUserMessage;
352
+ /**
353
+ * All response content in stream order: text, tool calls, reasoning, and content refs.
354
+ *
355
+ * Tool call parts include `pendingPermissions` when permissions are awaiting user approval.
356
+ */
357
+ responseParts: IResponsePart[];
358
+ /** Token usage info */
359
+ usage: IUsageInfo | undefined;
360
+ }
361
+ /**
362
+ * @category Turn Types
363
+ */
364
+ interface IUserMessage {
365
+ /** Message text */
366
+ text: string;
367
+ /** File/selection attachments */
368
+ attachments?: IMessageAttachment[];
369
+ }
370
+ /**
371
+ * @category Turn Types
372
+ */
373
+ interface IMessageAttachment {
374
+ /** Attachment type */
375
+ type: AttachmentType;
376
+ /** File/directory path */
377
+ path: string;
378
+ /** Display name */
379
+ displayName?: string;
380
+ }
381
+ /**
382
+ * Discriminant for response part types.
383
+ *
384
+ * @category Response Parts
385
+ */
386
+ declare const enum ResponsePartKind {
387
+ Markdown = "markdown",
388
+ ContentRef = "contentRef",
389
+ ToolCall = "toolCall",
390
+ Reasoning = "reasoning"
391
+ }
392
+ /**
393
+ * @category Response Parts
394
+ */
395
+ interface IMarkdownResponsePart {
396
+ /** Discriminant */
397
+ kind: ResponsePartKind.Markdown;
398
+ /** Part identifier, used by `session/delta` to target this part for content appends */
399
+ id: string;
400
+ /** Markdown content */
401
+ content: string;
402
+ }
403
+ /**
404
+ * A reference to large content stored outside the state tree.
405
+ */
406
+ interface IContentRef {
407
+ /** Content URI */
408
+ uri: URI;
409
+ /** Approximate size in bytes */
410
+ sizeHint?: number;
411
+ /** Content MIME type */
412
+ contentType?: string;
413
+ }
414
+ /**
415
+ * A content part that's a reference to large content stored outside the state tree.
416
+ *
417
+ * @category Response Parts
418
+ */
419
+ interface IResourceReponsePart extends IContentRef {
420
+ /** Discriminant */
421
+ kind: ResponsePartKind.ContentRef;
422
+ }
423
+ /**
424
+ * A tool call represented as a response part.
425
+ *
426
+ * Tool calls are part of the response stream, interleaved with text and
427
+ * reasoning. The `toolCall.toolCallId` serves as the part identifier for
428
+ * actions that target this part.
429
+ *
430
+ * @category Response Parts
431
+ */
432
+ interface IToolCallResponsePart {
433
+ /** Discriminant */
434
+ kind: ResponsePartKind.ToolCall;
435
+ /** Full tool call lifecycle state */
436
+ toolCall: IToolCallState;
437
+ }
438
+ /**
439
+ * Reasoning/thinking content from the model.
440
+ *
441
+ * @category Response Parts
442
+ */
443
+ interface IReasoningResponsePart {
444
+ /** Discriminant */
445
+ kind: ResponsePartKind.Reasoning;
446
+ /** Part identifier, used by `session/reasoning` to target this part for content appends */
447
+ id: string;
448
+ /** Accumulated reasoning text */
449
+ content: string;
450
+ }
451
+ /**
452
+ * @category Response Parts
453
+ */
454
+ type IResponsePart = IMarkdownResponsePart | IResourceReponsePart | IToolCallResponsePart | IReasoningResponsePart;
455
+ /**
456
+ * Status of a tool call in the lifecycle state machine.
457
+ *
458
+ * @category Tool Call Types
459
+ */
460
+ declare const enum ToolCallStatus {
461
+ Streaming = "streaming",
462
+ PendingConfirmation = "pending-confirmation",
463
+ Running = "running",
464
+ PendingResultConfirmation = "pending-result-confirmation",
465
+ Completed = "completed",
466
+ Cancelled = "cancelled"
467
+ }
468
+ /**
469
+ * How a tool call was confirmed for execution.
470
+ *
471
+ * - `NotNeeded` — No confirmation required (auto-approved)
472
+ * - `UserAction` — User explicitly approved
473
+ * - `Setting` — Approved by a persistent user setting
474
+ *
475
+ * @category Tool Call Types
476
+ */
477
+ declare const enum ToolCallConfirmationReason {
478
+ NotNeeded = "not-needed",
479
+ UserAction = "user-action",
480
+ Setting = "setting"
481
+ }
482
+ /**
483
+ * Why a tool call was cancelled.
484
+ *
485
+ * @category Tool Call Types
486
+ */
487
+ declare const enum ToolCallCancellationReason {
488
+ Denied = "denied",
489
+ Skipped = "skipped",
490
+ ResultDenied = "result-denied"
491
+ }
492
+ /**
493
+ * Metadata common to all tool call states.
494
+ *
495
+ * @category Tool Call Types
496
+ * @remarks
497
+ * Fields like `toolName` carry agent-specific identifiers on the wire despite the
498
+ * agent-agnostic design principle. These exist for debugging and logging purposes.
499
+ * A future version may move these to a separate diagnostic channel or namespace them
500
+ * more clearly.
501
+ */
502
+ interface IToolCallBase {
503
+ /** Unique tool call identifier */
504
+ toolCallId: string;
505
+ /** Internal tool name (for debugging/logging) */
506
+ toolName: string;
507
+ /** Human-readable tool name */
508
+ displayName: string;
509
+ /**
510
+ * If this tool is provided by a client, the `clientId` of the owning client.
511
+ * Absent for server-side tools.
512
+ *
513
+ * When set, the identified client is responsible for executing the tool and
514
+ * dispatching `session/toolCallComplete` with the result.
515
+ */
516
+ toolClientId?: string;
517
+ /**
518
+ * Additional provider-specific metadata for this tool call.
519
+ *
520
+ * Clients MAY look for well-known keys here to provide enhanced UI.
521
+ * For example, a `ptyTerminal` key with `{ input: string; output: string }`
522
+ * indicates the tool operated on a terminal (both `input` and `output` may
523
+ * contain escape sequences).
524
+ */
525
+ _meta?: Record<string, unknown>;
526
+ }
527
+ /**
528
+ * Properties available once tool call parameters are fully received.
529
+ *
530
+ * @category Tool Call Types
531
+ */
532
+ interface IToolCallParameterFields {
533
+ /** Message describing what the tool will do */
534
+ invocationMessage: StringOrMarkdown;
535
+ /** Raw tool input */
536
+ toolInput?: string;
537
+ }
538
+ /**
539
+ * Tool execution result details, available after execution completes.
540
+ *
541
+ * @category Tool Call Types
542
+ */
543
+ interface IToolCallResult {
544
+ /** Whether the tool succeeded */
545
+ success: boolean;
546
+ /** Past-tense description of what the tool did */
547
+ pastTenseMessage: StringOrMarkdown;
548
+ /**
549
+ * Unstructured result content blocks.
550
+ *
551
+ * This mirrors the `content` field of MCP `CallToolResult`.
552
+ */
553
+ content?: IToolResultContent[];
554
+ /**
555
+ * Optional structured result object.
556
+ *
557
+ * This mirrors the `structuredContent` field of MCP `CallToolResult`.
558
+ */
559
+ structuredContent?: Record<string, unknown>;
560
+ /** Error details if the tool failed */
561
+ error?: {
562
+ message: string;
563
+ code?: string;
564
+ };
565
+ }
566
+ /**
567
+ * LM is streaming the tool call parameters.
568
+ *
569
+ * @category Tool Call Types
570
+ */
571
+ interface IToolCallStreamingState extends IToolCallBase {
572
+ status: ToolCallStatus.Streaming;
573
+ /** Partial parameters accumulated so far */
574
+ partialInput?: string;
575
+ /** Progress message shown while parameters are streaming */
576
+ invocationMessage?: StringOrMarkdown;
577
+ }
578
+ /**
579
+ * Parameters are complete, or a running tool requires re-confirmation
580
+ * (e.g. a mid-execution permission check).
581
+ *
582
+ * @category Tool Call Types
583
+ */
584
+ interface IToolCallPendingConfirmationState extends IToolCallBase, IToolCallParameterFields {
585
+ status: ToolCallStatus.PendingConfirmation;
586
+ /** Short title for the confirmation prompt (e.g. `"Run in terminal"`, `"Write file"`) */
587
+ confirmationTitle?: StringOrMarkdown;
588
+ }
589
+ /**
590
+ * Tool is actively executing.
591
+ *
592
+ * @category Tool Call Types
593
+ */
594
+ interface IToolCallRunningState extends IToolCallBase, IToolCallParameterFields {
595
+ status: ToolCallStatus.Running;
596
+ /** How the tool was confirmed for execution */
597
+ confirmed: ToolCallConfirmationReason;
598
+ }
599
+ /**
600
+ * Tool finished executing, waiting for client to approve the result.
601
+ *
602
+ * @category Tool Call Types
603
+ */
604
+ interface IToolCallPendingResultConfirmationState extends IToolCallBase, IToolCallParameterFields, IToolCallResult {
605
+ status: ToolCallStatus.PendingResultConfirmation;
606
+ /** How the tool was confirmed for execution */
607
+ confirmed: ToolCallConfirmationReason;
608
+ }
609
+ /**
610
+ * Tool completed successfully or with an error.
611
+ *
612
+ * @category Tool Call Types
613
+ */
614
+ interface IToolCallCompletedState extends IToolCallBase, IToolCallParameterFields, IToolCallResult {
615
+ status: ToolCallStatus.Completed;
616
+ /** How the tool was confirmed for execution */
617
+ confirmed: ToolCallConfirmationReason;
618
+ }
619
+ /**
620
+ * Tool call was cancelled before execution.
621
+ *
622
+ * @category Tool Call Types
623
+ */
624
+ interface IToolCallCancelledState extends IToolCallBase, IToolCallParameterFields {
625
+ status: ToolCallStatus.Cancelled;
626
+ /** Why the tool was cancelled */
627
+ reason: ToolCallCancellationReason;
628
+ /** Optional message explaining the cancellation */
629
+ reasonMessage?: StringOrMarkdown;
630
+ /** What the user suggested doing instead */
631
+ userSuggestion?: IUserMessage;
632
+ }
633
+ /**
634
+ * Discriminated union of all tool call lifecycle states.
635
+ *
636
+ * See the [state model guide](/guide/state-model.html#tool-call-lifecycle)
637
+ * for the full state machine diagram.
638
+ *
639
+ * @category Tool Call Types
640
+ */
641
+ type IToolCallState = IToolCallStreamingState | IToolCallPendingConfirmationState | IToolCallRunningState | IToolCallPendingResultConfirmationState | IToolCallCompletedState | IToolCallCancelledState;
642
+ /**
643
+ * Describes a tool available in a session, provided by either the server or the active client.
644
+ *
645
+ * This type mirrors the MCP `Tool` type from the Model Context Protocol specification
646
+ * (2025-11-25 draft) and will continue to track it.
647
+ *
648
+ * @category Tool Definition Types
649
+ */
650
+ interface IToolDefinition {
651
+ /** Unique tool identifier */
652
+ name: string;
653
+ /** Human-readable display name */
654
+ title?: string;
655
+ /** Description of what the tool does */
656
+ description?: string;
657
+ /**
658
+ * JSON Schema defining the expected input parameters.
659
+ *
660
+ * Optional because client-provided tools may not have formal schemas.
661
+ * Mirrors MCP `Tool.inputSchema`.
662
+ */
663
+ inputSchema?: {
664
+ type: 'object';
665
+ properties?: Record<string, object>;
666
+ required?: string[];
667
+ };
668
+ /**
669
+ * JSON Schema defining the structure of the tool's output.
670
+ *
671
+ * Mirrors MCP `Tool.outputSchema`.
672
+ */
673
+ outputSchema?: {
674
+ type: 'object';
675
+ properties?: Record<string, object>;
676
+ required?: string[];
677
+ };
678
+ /** Behavioral hints about the tool. All properties are advisory. */
679
+ annotations?: IToolAnnotations;
680
+ /**
681
+ * Additional provider-specific metadata.
682
+ *
683
+ * Mirrors the MCP `_meta` convention.
684
+ */
685
+ _meta?: Record<string, unknown>;
686
+ }
687
+ /**
688
+ * Behavioral hints about a tool. All properties are advisory and not
689
+ * guaranteed to faithfully describe tool behavior.
690
+ *
691
+ * Mirrors MCP `ToolAnnotations` from the Model Context Protocol specification.
692
+ *
693
+ * @category Tool Definition Types
694
+ */
695
+ interface IToolAnnotations {
696
+ /** Alternate human-readable title */
697
+ title?: string;
698
+ /** Tool does not modify its environment (default: false) */
699
+ readOnlyHint?: boolean;
700
+ /** Tool may perform destructive updates (default: true) */
701
+ destructiveHint?: boolean;
702
+ /** Repeated calls with the same arguments have no additional effect (default: false) */
703
+ idempotentHint?: boolean;
704
+ /** Tool may interact with external entities (default: true) */
705
+ openWorldHint?: boolean;
706
+ }
707
+ /**
708
+ * Discriminant for tool result content types.
709
+ *
710
+ * @category Tool Result Content
711
+ */
712
+ declare const enum ToolResultContentType {
713
+ Text = "text",
714
+ EmbeddedResource = "embeddedResource",
715
+ Resource = "resource",
716
+ FileEdit = "fileEdit"
717
+ }
718
+ /**
719
+ * Text content in a tool result.
720
+ *
721
+ * Mirrors MCP `TextContent`.
722
+ *
723
+ * @category Tool Result Content
724
+ */
725
+ interface IToolResultTextContent {
726
+ type: ToolResultContentType.Text;
727
+ /** The text content */
728
+ text: string;
729
+ }
730
+ /**
731
+ * Base64-encoded binary content embedded in a tool result.
732
+ *
733
+ * Mirrors MCP `EmbeddedResource` for inline binary data.
734
+ *
735
+ * @category Tool Result Content
736
+ */
737
+ interface IToolResultEmbeddedResourceContent {
738
+ type: ToolResultContentType.EmbeddedResource;
739
+ /** Base64-encoded data */
740
+ data: string;
741
+ /** Content type (e.g. `"image/png"`, `"application/pdf"`) */
742
+ contentType: string;
743
+ }
744
+ /**
745
+ * A reference to a resource stored outside the tool result.
746
+ *
747
+ * Wraps {@link IContentRef} for lazy-loading large results.
748
+ *
749
+ * @category Tool Result Content
750
+ */
751
+ interface IToolResultResourceContent extends IContentRef {
752
+ type: ToolResultContentType.Resource;
753
+ }
754
+ /**
755
+ * Describes a file modification performed by a tool.
756
+ *
757
+ * Supports creates (only `after`), deletes (only `before`), renames/moves
758
+ * (different `uri` in `before` and `after`), and edits (same `uri`, different content).
759
+ *
760
+ * @category Tool Result Content
761
+ */
762
+ interface IToolResultFileEditContent {
763
+ type: ToolResultContentType.FileEdit;
764
+ /** The file state before the edit. Absent for file creations or for in-place file edits. */
765
+ before?: {
766
+ /** URI of the file before the edit */
767
+ uri: URI;
768
+ /** Reference to the file content before the edit */
769
+ content: IContentRef;
770
+ };
771
+ /** The file state after the edit. Absent for file deletions. */
772
+ after?: {
773
+ /** URI of the file after the edit */
774
+ uri: URI;
775
+ /** Reference to the file content after the edit */
776
+ content: IContentRef;
777
+ };
778
+ /** Optional diff display metadata */
779
+ diff?: {
780
+ /** Number of items added (e.g., lines for text files, cells for notebooks) */
781
+ added?: number;
782
+ /** Number of items removed (e.g., lines for text files, cells for notebooks) */
783
+ removed?: number;
784
+ };
785
+ }
786
+ /**
787
+ * Content block in a tool result.
788
+ *
789
+ * Mirrors the content blocks in MCP `CallToolResult.content`, plus
790
+ * `IToolResultResourceContent` for lazy-loading large results and
791
+ * `IToolResultFileEditContent` for file edit diffs (AHP extensions).
792
+ *
793
+ * @category Tool Result Content
794
+ */
795
+ type IToolResultContent = IToolResultTextContent | IToolResultEmbeddedResourceContent | IToolResultResourceContent | IToolResultFileEditContent;
796
+ /**
797
+ * A reference to an [Open Plugins](https://open-plugins.com/) plugin.
798
+ *
799
+ * This is intentionally thin — AHP specifies plugin identity and metadata
800
+ * but not implementation details, which are defined by the Open Plugins spec.
801
+ *
802
+ * @category Customization Types
803
+ */
804
+ interface ICustomizationRef {
805
+ /** Plugin URI (e.g. an HTTPS URL or marketplace identifier) */
806
+ uri: URI;
807
+ /** Human-readable name */
808
+ displayName: string;
809
+ /** Description of what the plugin provides */
810
+ description?: string;
811
+ /** Icons for the plugin */
812
+ icons?: Icon[];
813
+ /**
814
+ * Opaque version token for this customization.
815
+ *
816
+ * Clients SHOULD include a nonce with every customization they provide.
817
+ * Consumers can compare nonces to detect whether a customization has
818
+ * changed since it was last seen, avoiding redundant reloads or copies.
819
+ */
820
+ nonce?: string;
821
+ }
822
+ /**
823
+ * Loading status for a server-managed customization.
824
+ *
825
+ * @category Customization Types
826
+ */
827
+ declare const enum CustomizationStatus {
828
+ /** Plugin is being loaded */
829
+ Loading = "loading",
830
+ /** Plugin is fully operational */
831
+ Loaded = "loaded",
832
+ /** Plugin partially loaded but has warnings */
833
+ Degraded = "degraded",
834
+ /** Plugin was unable to load */
835
+ Error = "error"
836
+ }
837
+ /**
838
+ * A customization active in a session.
839
+ *
840
+ * Entries without a `clientId` are server-provided; entries with a `clientId`
841
+ * originate from that client.
842
+ *
843
+ * @category Customization Types
844
+ */
845
+ interface ISessionCustomization {
846
+ /** The plugin this customization refers to */
847
+ customization: ICustomizationRef;
848
+ /** Whether this customization is currently enabled */
849
+ enabled: boolean;
850
+ /** Server-reported loading status */
851
+ status?: CustomizationStatus;
852
+ /**
853
+ * Human-readable status detail (e.g. error message or degradation warning).
854
+ */
855
+ statusMessage?: string;
856
+ }
857
+ /**
858
+ * @category Common Types
859
+ */
860
+ interface IUsageInfo {
861
+ /** Input tokens consumed */
862
+ inputTokens?: number;
863
+ /** Output tokens generated */
864
+ outputTokens?: number;
865
+ /** Model used */
866
+ model?: string;
867
+ /** Tokens read from cache */
868
+ cacheReadTokens?: number;
869
+ }
870
+ /**
871
+ * @category Common Types
872
+ */
873
+ interface IErrorInfo {
874
+ /** Error type identifier */
875
+ errorType: string;
876
+ /** Human-readable error message */
877
+ message: string;
878
+ /** Stack trace */
879
+ stack?: string;
880
+ }
881
+ /**
882
+ * A point-in-time snapshot of a subscribed resource's state, returned by
883
+ * `initialize`, `reconnect`, and `subscribe`.
884
+ *
885
+ * @category Common Types
886
+ */
887
+ interface ISnapshot {
888
+ /** The subscribed resource URI (e.g. `agenthost:/root` or `copilot:/<uuid>`) */
889
+ resource: URI;
890
+ /** The current state of the resource */
891
+ state: IRootState | ISessionState;
892
+ /** The `serverSeq` at which this snapshot was taken. Subsequent actions will have `serverSeq > fromSeq`. */
893
+ fromSeq: number;
894
+ }
895
+
896
+ /**
897
+ * Action Types — Source of truth for all AHP action type definitions.
898
+ *
899
+ * @module actions
900
+ * @description Complete reference for all action types in the Agent Host Protocol.
901
+ * Actions are the sole mutation mechanism for subscribable state.
902
+ */
903
+
904
+ /**
905
+ * Discriminant values for all state actions.
906
+ *
907
+ * @category Actions
908
+ */
909
+ declare const enum ActionType {
910
+ RootAgentsChanged = "root/agentsChanged",
911
+ RootActiveSessionsChanged = "root/activeSessionsChanged",
912
+ SessionReady = "session/ready",
913
+ SessionCreationFailed = "session/creationFailed",
914
+ SessionTurnStarted = "session/turnStarted",
915
+ SessionDelta = "session/delta",
916
+ SessionResponsePart = "session/responsePart",
917
+ SessionToolCallStart = "session/toolCallStart",
918
+ SessionToolCallDelta = "session/toolCallDelta",
919
+ SessionToolCallReady = "session/toolCallReady",
920
+ SessionToolCallConfirmed = "session/toolCallConfirmed",
921
+ SessionToolCallComplete = "session/toolCallComplete",
922
+ SessionToolCallResultConfirmed = "session/toolCallResultConfirmed",
923
+ SessionTurnComplete = "session/turnComplete",
924
+ SessionTurnCancelled = "session/turnCancelled",
925
+ SessionError = "session/error",
926
+ SessionTitleChanged = "session/titleChanged",
927
+ SessionUsage = "session/usage",
928
+ SessionReasoning = "session/reasoning",
929
+ SessionModelChanged = "session/modelChanged",
930
+ SessionServerToolsChanged = "session/serverToolsChanged",
931
+ SessionActiveClientChanged = "session/activeClientChanged",
932
+ SessionActiveClientToolsChanged = "session/activeClientToolsChanged",
933
+ SessionPendingMessageSet = "session/pendingMessageSet",
934
+ SessionPendingMessageRemoved = "session/pendingMessageRemoved",
935
+ SessionQueuedMessagesReordered = "session/queuedMessagesReordered",
936
+ SessionCustomizationsChanged = "session/customizationsChanged",
937
+ SessionCustomizationToggled = "session/customizationToggled",
938
+ SessionTruncated = "session/truncated"
939
+ }
940
+ /**
941
+ * Identifies the client that originally dispatched an action.
942
+ */
943
+ interface IActionOrigin {
944
+ clientId: string;
945
+ clientSeq: number;
946
+ }
947
+ /**
948
+ * Every action is wrapped in an `ActionEnvelope`.
949
+ */
950
+ interface IActionEnvelope {
951
+ readonly action: IStateAction;
952
+ readonly serverSeq: number;
953
+ readonly origin: IActionOrigin | undefined;
954
+ readonly rejectionReason?: string;
955
+ }
956
+ /**
957
+ * Base interface for all tool-call-scoped actions, carrying the common
958
+ * session, turn, and tool call identifiers.
959
+ *
960
+ * @category Session Actions
961
+ */
962
+ interface IToolCallActionBase {
963
+ /** Session URI */
964
+ session: URI;
965
+ /** Turn identifier */
966
+ turnId: string;
967
+ /** Tool call identifier */
968
+ toolCallId: string;
969
+ /**
970
+ * Additional provider-specific metadata for this tool call.
971
+ *
972
+ * Clients MAY look for well-known keys here to provide enhanced UI.
973
+ * For example, a `ptyTerminal` key with `{ input: string; output: string }`
974
+ * indicates the tool operated on a terminal (both `input` and `output` may
975
+ * contain escape sequences).
976
+ */
977
+ _meta?: Record<string, unknown>;
978
+ }
979
+ /**
980
+ * Fired when available agent backends or their models change.
981
+ *
982
+ * @category Root Actions
983
+ * @version 1
984
+ */
985
+ interface IRootAgentsChangedAction {
986
+ type: ActionType.RootAgentsChanged;
987
+ /** Updated agent list */
988
+ agents: IAgentInfo[];
989
+ }
990
+ /**
991
+ * Fired when the number of active sessions changes.
992
+ *
993
+ * @category Root Actions
994
+ * @version 1
995
+ */
996
+ interface IRootActiveSessionsChangedAction {
997
+ type: ActionType.RootActiveSessionsChanged;
998
+ /** Current count of active sessions */
999
+ activeSessions: number;
1000
+ }
1001
+ /**
1002
+ * Session backend initialized successfully.
1003
+ *
1004
+ * @category Session Actions
1005
+ * @version 1
1006
+ */
1007
+ interface ISessionReadyAction {
1008
+ type: ActionType.SessionReady;
1009
+ /** Session URI */
1010
+ session: URI;
1011
+ }
1012
+ /**
1013
+ * Session backend failed to initialize.
1014
+ *
1015
+ * @category Session Actions
1016
+ * @version 1
1017
+ */
1018
+ interface ISessionCreationFailedAction {
1019
+ type: ActionType.SessionCreationFailed;
1020
+ /** Session URI */
1021
+ session: URI;
1022
+ /** Error details */
1023
+ error: IErrorInfo;
1024
+ }
1025
+ /**
1026
+ * User sent a message; server starts agent processing.
1027
+ *
1028
+ * @category Session Actions
1029
+ * @version 1
1030
+ * @clientDispatchable
1031
+ */
1032
+ interface ISessionTurnStartedAction {
1033
+ type: ActionType.SessionTurnStarted;
1034
+ /** Session URI */
1035
+ session: URI;
1036
+ /** Turn identifier */
1037
+ turnId: string;
1038
+ /** User's message */
1039
+ userMessage: IUserMessage;
1040
+ /** If this turn was auto-started from a queued message, the ID of that message */
1041
+ queuedMessageId?: string;
1042
+ }
1043
+ /**
1044
+ * Streaming text chunk from the assistant, appended to a specific response part.
1045
+ *
1046
+ * The server MUST first emit a `session/responsePart` to create the target
1047
+ * part (markdown or reasoning), then use this action to append text to it.
1048
+ *
1049
+ * @category Session Actions
1050
+ * @version 1
1051
+ */
1052
+ interface ISessionDeltaAction {
1053
+ type: ActionType.SessionDelta;
1054
+ /** Session URI */
1055
+ session: URI;
1056
+ /** Turn identifier */
1057
+ turnId: string;
1058
+ /** Identifier of the response part to append to */
1059
+ partId: string;
1060
+ /** Text chunk */
1061
+ content: string;
1062
+ }
1063
+ /**
1064
+ * Structured content appended to the response.
1065
+ *
1066
+ * @category Session Actions
1067
+ * @version 1
1068
+ */
1069
+ interface ISessionResponsePartAction {
1070
+ type: ActionType.SessionResponsePart;
1071
+ /** Session URI */
1072
+ session: URI;
1073
+ /** Turn identifier */
1074
+ turnId: string;
1075
+ /** Response part (markdown or content ref) */
1076
+ part: IResponsePart;
1077
+ }
1078
+ /**
1079
+ * A tool call begins — parameters are streaming from the LM.
1080
+ *
1081
+ * For client-provided tools, the server sets `toolClientId` to identify the
1082
+ * owning client. That client is responsible for executing the tool once it
1083
+ * reaches the `running` state and dispatching `session/toolCallComplete`.
1084
+ *
1085
+ * @category Session Actions
1086
+ * @version 1
1087
+ */
1088
+ interface ISessionToolCallStartAction extends IToolCallActionBase {
1089
+ type: ActionType.SessionToolCallStart;
1090
+ /** Internal tool name (for debugging/logging) */
1091
+ toolName: string;
1092
+ /** Human-readable tool name */
1093
+ displayName: string;
1094
+ /**
1095
+ * If this tool is provided by a client, the `clientId` of the owning client.
1096
+ * Absent for server-side tools.
1097
+ */
1098
+ toolClientId?: string;
1099
+ }
1100
+ /**
1101
+ * Streaming partial parameters for a tool call.
1102
+ *
1103
+ * @category Session Actions
1104
+ * @version 1
1105
+ */
1106
+ interface ISessionToolCallDeltaAction extends IToolCallActionBase {
1107
+ type: ActionType.SessionToolCallDelta;
1108
+ /** Partial parameter content to append */
1109
+ content: string;
1110
+ /** Updated progress message */
1111
+ invocationMessage?: StringOrMarkdown;
1112
+ }
1113
+ /**
1114
+ * Tool call parameters are complete, or a running tool requires re-confirmation.
1115
+ *
1116
+ * When dispatched for a `streaming` tool call, transitions to `pending-confirmation`
1117
+ * or directly to `running` if `confirmed` is set.
1118
+ *
1119
+ * When dispatched for a `running` tool call (e.g. mid-execution permission needed),
1120
+ * transitions back to `pending-confirmation`. The `invocationMessage` and `_meta`
1121
+ * SHOULD be updated to describe the specific confirmation needed. Clients use the
1122
+ * standard `session/toolCallConfirmed` flow to approve or deny.
1123
+ *
1124
+ * For client-provided tools, the server typically sets `confirmed` to
1125
+ * `'not-needed'` so the tool transitions directly to `running`, where the
1126
+ * owning client can begin execution immediately.
1127
+ *
1128
+ * @category Session Actions
1129
+ * @version 1
1130
+ */
1131
+ interface ISessionToolCallReadyAction extends IToolCallActionBase {
1132
+ type: ActionType.SessionToolCallReady;
1133
+ /** Message describing what the tool will do or what confirmation is needed */
1134
+ invocationMessage: StringOrMarkdown;
1135
+ /** Raw tool input */
1136
+ toolInput?: string;
1137
+ /** Short title for the confirmation prompt (e.g. `"Run in terminal"`, `"Write file"`) */
1138
+ confirmationTitle?: StringOrMarkdown;
1139
+ /** If set, the tool was auto-confirmed and transitions directly to `running` */
1140
+ confirmed?: ToolCallConfirmationReason;
1141
+ }
1142
+ /**
1143
+ * Client approves a pending tool call. The tool transitions to `running`.
1144
+ *
1145
+ * @category Session Actions
1146
+ * @version 1
1147
+ * @clientDispatchable
1148
+ */
1149
+ interface ISessionToolCallApprovedAction extends IToolCallActionBase {
1150
+ type: ActionType.SessionToolCallConfirmed;
1151
+ /** The tool call was approved */
1152
+ approved: true;
1153
+ /** How the tool was confirmed */
1154
+ confirmed: ToolCallConfirmationReason;
1155
+ }
1156
+ /**
1157
+ * Client denies a pending tool call. The tool transitions to `cancelled`.
1158
+ *
1159
+ * For client-provided tools, the owning client MUST dispatch this if it does
1160
+ * not recognize the tool or cannot execute it.
1161
+ *
1162
+ * @category Session Actions
1163
+ * @version 1
1164
+ * @clientDispatchable
1165
+ */
1166
+ interface ISessionToolCallDeniedAction extends IToolCallActionBase {
1167
+ type: ActionType.SessionToolCallConfirmed;
1168
+ /** The tool call was denied */
1169
+ approved: false;
1170
+ /** Why the tool was cancelled */
1171
+ reason: ToolCallCancellationReason.Denied | ToolCallCancellationReason.Skipped;
1172
+ /** What the user suggested doing instead */
1173
+ userSuggestion?: IUserMessage;
1174
+ /** Optional explanation for the denial */
1175
+ reasonMessage?: StringOrMarkdown;
1176
+ }
1177
+ /**
1178
+ * Client confirms or denies a pending tool call.
1179
+ *
1180
+ * @category Session Actions
1181
+ * @version 1
1182
+ * @clientDispatchable
1183
+ */
1184
+ type ISessionToolCallConfirmedAction = ISessionToolCallApprovedAction | ISessionToolCallDeniedAction;
1185
+ /**
1186
+ * Tool execution finished. Transitions to `completed` or `pending-result-confirmation`
1187
+ * if `requiresResultConfirmation` is `true`.
1188
+ *
1189
+ * For client-provided tools (where `toolClientId` is set on the tool call state),
1190
+ * the owning client dispatches this action with the execution result. The server
1191
+ * SHOULD reject this action if the dispatching client does not match `toolClientId`.
1192
+ *
1193
+ * Servers waiting on a client tool call MAY time out after a reasonable duration
1194
+ * if the implementing client disconnects or becomes unresponsive, and dispatch
1195
+ * this action with `result.success = false` and an appropriate error.
1196
+ *
1197
+ * @category Session Actions
1198
+ * @version 1
1199
+ * @clientDispatchable
1200
+ */
1201
+ interface ISessionToolCallCompleteAction extends IToolCallActionBase {
1202
+ type: ActionType.SessionToolCallComplete;
1203
+ /** Execution result */
1204
+ result: IToolCallResult;
1205
+ /** If true, the result requires client approval before finalizing */
1206
+ requiresResultConfirmation?: boolean;
1207
+ }
1208
+ /**
1209
+ * Client approves or denies a tool's result.
1210
+ *
1211
+ * If `approved` is `false`, the tool transitions to `cancelled` with reason `result-denied`.
1212
+ *
1213
+ * @category Session Actions
1214
+ * @version 1
1215
+ * @clientDispatchable
1216
+ */
1217
+ interface ISessionToolCallResultConfirmedAction extends IToolCallActionBase {
1218
+ type: ActionType.SessionToolCallResultConfirmed;
1219
+ /** Whether the result was approved */
1220
+ approved: boolean;
1221
+ }
1222
+ /**
1223
+ * Turn finished — the assistant is idle.
1224
+ *
1225
+ * @category Session Actions
1226
+ * @version 1
1227
+ */
1228
+ interface ISessionTurnCompleteAction {
1229
+ type: ActionType.SessionTurnComplete;
1230
+ /** Session URI */
1231
+ session: URI;
1232
+ /** Turn identifier */
1233
+ turnId: string;
1234
+ }
1235
+ /**
1236
+ * Turn was aborted; server stops processing.
1237
+ *
1238
+ * @category Session Actions
1239
+ * @version 1
1240
+ * @clientDispatchable
1241
+ */
1242
+ interface ISessionTurnCancelledAction {
1243
+ type: ActionType.SessionTurnCancelled;
1244
+ /** Session URI */
1245
+ session: URI;
1246
+ /** Turn identifier */
1247
+ turnId: string;
1248
+ }
1249
+ /**
1250
+ * Error during turn processing.
1251
+ *
1252
+ * @category Session Actions
1253
+ * @version 1
1254
+ */
1255
+ interface ISessionErrorAction {
1256
+ type: ActionType.SessionError;
1257
+ /** Session URI */
1258
+ session: URI;
1259
+ /** Turn identifier */
1260
+ turnId: string;
1261
+ /** Error details */
1262
+ error: IErrorInfo;
1263
+ }
1264
+ /**
1265
+ * Session title updated. Fired by the server when the title is auto-generated
1266
+ * from conversation, or dispatched by a client to rename a session.
1267
+ *
1268
+ * @category Session Actions
1269
+ * @clientDispatchable
1270
+ * @version 1
1271
+ */
1272
+ interface ISessionTitleChangedAction {
1273
+ type: ActionType.SessionTitleChanged;
1274
+ /** Session URI */
1275
+ session: URI;
1276
+ /** New title */
1277
+ title: string;
1278
+ }
1279
+ /**
1280
+ * Token usage report for a turn.
1281
+ *
1282
+ * @category Session Actions
1283
+ * @version 1
1284
+ */
1285
+ interface ISessionUsageAction {
1286
+ type: ActionType.SessionUsage;
1287
+ /** Session URI */
1288
+ session: URI;
1289
+ /** Turn identifier */
1290
+ turnId: string;
1291
+ /** Token usage data */
1292
+ usage: IUsageInfo;
1293
+ }
1294
+ /**
1295
+ * Reasoning/thinking text from the model, appended to a specific reasoning response part.
1296
+ *
1297
+ * The server MUST first emit a `session/responsePart` to create the target
1298
+ * reasoning part, then use this action to append text to it.
1299
+ *
1300
+ * @category Session Actions
1301
+ * @version 1
1302
+ */
1303
+ interface ISessionReasoningAction {
1304
+ type: ActionType.SessionReasoning;
1305
+ /** Session URI */
1306
+ session: URI;
1307
+ /** Turn identifier */
1308
+ turnId: string;
1309
+ /** Identifier of the reasoning response part to append to */
1310
+ partId: string;
1311
+ /** Reasoning text chunk */
1312
+ content: string;
1313
+ }
1314
+ /**
1315
+ * Model changed for this session.
1316
+ *
1317
+ * @category Session Actions
1318
+ * @version 1
1319
+ * @clientDispatchable
1320
+ */
1321
+ interface ISessionModelChangedAction {
1322
+ type: ActionType.SessionModelChanged;
1323
+ /** Session URI */
1324
+ session: URI;
1325
+ /** New model ID */
1326
+ model: string;
1327
+ }
1328
+ /**
1329
+ * Server tools for this session have changed.
1330
+ *
1331
+ * Full-replacement semantics: the `tools` array replaces the previous `serverTools` entirely.
1332
+ *
1333
+ * @category Session Actions
1334
+ * @version 1
1335
+ */
1336
+ interface ISessionServerToolsChangedAction {
1337
+ type: ActionType.SessionServerToolsChanged;
1338
+ /** Session URI */
1339
+ session: URI;
1340
+ /** Updated server tools list (full replacement) */
1341
+ tools: IToolDefinition[];
1342
+ }
1343
+ /**
1344
+ * The active client for this session has changed.
1345
+ *
1346
+ * A client dispatches this action with its own `ISessionActiveClient` to claim
1347
+ * the active role, or with `null` to release it. The server SHOULD reject if
1348
+ * another client is already active. The server SHOULD automatically dispatch
1349
+ * this action with `activeClient: null` when the active client disconnects.
1350
+ *
1351
+ * @category Session Actions
1352
+ * @version 1
1353
+ * @clientDispatchable
1354
+ */
1355
+ interface ISessionActiveClientChangedAction {
1356
+ type: ActionType.SessionActiveClientChanged;
1357
+ /** Session URI */
1358
+ session: URI;
1359
+ /** The new active client, or `null` to unset */
1360
+ activeClient: ISessionActiveClient | null;
1361
+ }
1362
+ /**
1363
+ * The active client's tool list has changed.
1364
+ *
1365
+ * Full-replacement semantics: the `tools` array replaces the active client's
1366
+ * previous tools entirely. The server SHOULD reject if the dispatching client
1367
+ * is not the current active client.
1368
+ *
1369
+ * @category Session Actions
1370
+ * @version 1
1371
+ * @clientDispatchable
1372
+ */
1373
+ interface ISessionActiveClientToolsChangedAction {
1374
+ type: ActionType.SessionActiveClientToolsChanged;
1375
+ /** Session URI */
1376
+ session: URI;
1377
+ /** Updated client tools list (full replacement) */
1378
+ tools: IToolDefinition[];
1379
+ }
1380
+ /**
1381
+ * The session's customizations have changed.
1382
+ *
1383
+ * Full-replacement semantics: the `customizations` array replaces the
1384
+ * previous `customizations` entirely.
1385
+ *
1386
+ * @category Session Actions
1387
+ * @version 1
1388
+ */
1389
+ interface ISessionCustomizationsChangedAction {
1390
+ type: ActionType.SessionCustomizationsChanged;
1391
+ /** Session URI */
1392
+ session: URI;
1393
+ /** Updated customization list (full replacement) */
1394
+ customizations: ISessionCustomization[];
1395
+ }
1396
+ /**
1397
+ * A client toggled a customization on or off.
1398
+ *
1399
+ * The server locates the customization by `uri` in the session's
1400
+ * customization list and sets its `enabled` flag.
1401
+ *
1402
+ * @category Session Actions
1403
+ * @version 1
1404
+ * @clientDispatchable
1405
+ */
1406
+ interface ISessionCustomizationToggledAction {
1407
+ type: ActionType.SessionCustomizationToggled;
1408
+ /** Session URI */
1409
+ session: URI;
1410
+ /** The URI of the customization to toggle */
1411
+ uri: URI;
1412
+ /** Whether to enable or disable the customization */
1413
+ enabled: boolean;
1414
+ }
1415
+ /**
1416
+ * Truncates a session's history. If `turnId` is provided, all turns after that
1417
+ * turn are removed and the specified turn is kept. If `turnId` is omitted, all
1418
+ * turns are removed.
1419
+ *
1420
+ * If there is an active turn it is silently dropped and the session status
1421
+ * returns to `idle`.
1422
+ *
1423
+ * Common use-case: truncate old data then dispatch a new
1424
+ * `session/turnStarted` with an edited message.
1425
+ *
1426
+ * @category Session Actions
1427
+ * @version 1
1428
+ * @clientDispatchable
1429
+ */
1430
+ interface ISessionTruncatedAction {
1431
+ type: ActionType.SessionTruncated;
1432
+ /** Session URI */
1433
+ session: URI;
1434
+ /** Keep turns up to and including this turn. Omit to clear all turns. */
1435
+ turnId?: string;
1436
+ }
1437
+ /**
1438
+ * A pending message was set (upsert semantics: creates or replaces).
1439
+ *
1440
+ * For steering messages, this always replaces the single steering message.
1441
+ * For queued messages, if a message with the given `id` already exists it is
1442
+ * updated in place; otherwise it is appended to the queue. If the session is
1443
+ * idle when a queued message is set, the server SHOULD immediately consume it
1444
+ * and start a new turn.
1445
+ *
1446
+ * @category Session Actions
1447
+ * @version 1
1448
+ * @clientDispatchable
1449
+ */
1450
+ interface ISessionPendingMessageSetAction {
1451
+ type: ActionType.SessionPendingMessageSet;
1452
+ /** Session URI */
1453
+ session: URI;
1454
+ /** Whether this is a steering or queued message */
1455
+ kind: PendingMessageKind;
1456
+ /** Unique identifier for this pending message */
1457
+ id: string;
1458
+ /** The message content */
1459
+ userMessage: IUserMessage;
1460
+ }
1461
+ /**
1462
+ * A pending message was removed (steering or queued).
1463
+ *
1464
+ * Dispatched by clients to cancel a pending message, or by the server when
1465
+ * it consumes a message (e.g. starting a turn from a queued message or
1466
+ * injecting a steering message into the current turn).
1467
+ *
1468
+ * @category Session Actions
1469
+ * @version 1
1470
+ * @clientDispatchable
1471
+ */
1472
+ interface ISessionPendingMessageRemovedAction {
1473
+ type: ActionType.SessionPendingMessageRemoved;
1474
+ /** Session URI */
1475
+ session: URI;
1476
+ /** Whether this is a steering or queued message */
1477
+ kind: PendingMessageKind;
1478
+ /** Identifier of the pending message to remove */
1479
+ id: string;
1480
+ }
1481
+ /**
1482
+ * Reorder the queued messages.
1483
+ *
1484
+ * The `order` array contains the IDs of queued messages in their new
1485
+ * desired order. IDs not present in the current queue are ignored.
1486
+ * Queued messages whose IDs are absent from `order` are appended at
1487
+ * the end in their original relative order (so a client with a stale
1488
+ * view of the queue never silently drops messages).
1489
+ *
1490
+ * @category Session Actions
1491
+ * @version 1
1492
+ * @clientDispatchable
1493
+ */
1494
+ interface ISessionQueuedMessagesReorderedAction {
1495
+ type: ActionType.SessionQueuedMessagesReordered;
1496
+ /** Session URI */
1497
+ session: URI;
1498
+ /** Queued message IDs in the desired order */
1499
+ order: string[];
1500
+ }
1501
+ /**
1502
+ * Discriminated union of all state actions.
1503
+ */
1504
+ type IStateAction = IRootAgentsChangedAction | IRootActiveSessionsChangedAction | ISessionReadyAction | ISessionCreationFailedAction | ISessionTurnStartedAction | ISessionDeltaAction | ISessionResponsePartAction | ISessionToolCallStartAction | ISessionToolCallDeltaAction | ISessionToolCallReadyAction | ISessionToolCallConfirmedAction | ISessionToolCallCompleteAction | ISessionToolCallResultConfirmedAction | ISessionTurnCompleteAction | ISessionTurnCancelledAction | ISessionErrorAction | ISessionTitleChangedAction | ISessionUsageAction | ISessionReasoningAction | ISessionModelChangedAction | ISessionServerToolsChangedAction | ISessionActiveClientChangedAction | ISessionActiveClientToolsChangedAction | ISessionPendingMessageSetAction | ISessionPendingMessageRemovedAction | ISessionQueuedMessagesReorderedAction | ISessionCustomizationsChangedAction | ISessionCustomizationToggledAction | ISessionTruncatedAction;
1505
+
1506
+ /**
1507
+ * Command Types — Source of truth for all AHP command (JSON-RPC request) definitions.
1508
+ *
1509
+ * @module commands
1510
+ * @description Commands are JSON-RPC requests from the client to the server.
1511
+ * They return a result or a JSON-RPC error.
1512
+ */
1513
+
1514
+ /**
1515
+ * Establishes a new connection and negotiates the protocol version.
1516
+ * This MUST be the first message sent by the client.
1517
+ *
1518
+ * @category Commands
1519
+ * @method initialize
1520
+ * @direction Client → Server
1521
+ * @messageType Request
1522
+ * @version 1
1523
+ * @see {@link /specification/lifecycle | Lifecycle} for the full handshake flow.
1524
+ */
1525
+ interface IInitializeParams {
1526
+ /** Protocol version the client speaks */
1527
+ protocolVersion: number;
1528
+ /** Unique client identifier */
1529
+ clientId: string;
1530
+ /** URIs to subscribe to during handshake */
1531
+ initialSubscriptions?: URI[];
1532
+ }
1533
+ /**
1534
+ * Result of the `initialize` command.
1535
+ *
1536
+ * If the server does not support the client's protocol version, it MUST return
1537
+ * error code `-32005` (`UnsupportedProtocolVersion`).
1538
+ */
1539
+ interface IInitializeResult {
1540
+ /** Protocol version the server speaks */
1541
+ protocolVersion: number;
1542
+ /** Current server sequence number */
1543
+ serverSeq: number;
1544
+ /** Snapshots for each `initialSubscriptions` URI */
1545
+ snapshots: ISnapshot[];
1546
+ /** Suggested default directory for remote filesystem browsing */
1547
+ defaultDirectory?: URI;
1548
+ }
1549
+ /**
1550
+ * Discriminant for reconnect result types.
1551
+ *
1552
+ * @category Commands
1553
+ */
1554
+ declare const enum ReconnectResultType {
1555
+ Replay = "replay",
1556
+ Snapshot = "snapshot"
1557
+ }
1558
+ /**
1559
+ * Re-establishes a dropped connection. The server replays missed actions or
1560
+ * provides fresh snapshots.
1561
+ *
1562
+ * @category Commands
1563
+ * @method reconnect
1564
+ * @direction Client → Server
1565
+ * @messageType Request
1566
+ * @version 1
1567
+ * @see {@link /specification/lifecycle | Lifecycle} for details.
1568
+ */
1569
+ interface IReconnectParams {
1570
+ /** Client identifier from the original connection */
1571
+ clientId: string;
1572
+ /** Last `serverSeq` the client received */
1573
+ lastSeenServerSeq: number;
1574
+ /** URIs the client was subscribed to */
1575
+ subscriptions: URI[];
1576
+ }
1577
+ /**
1578
+ * Reconnect result when the server can replay from the requested sequence.
1579
+ *
1580
+ * The server MUST include all replayed data in the response.
1581
+ */
1582
+ interface IReconnectReplayResult {
1583
+ /** Discriminant */
1584
+ type: ReconnectResultType.Replay;
1585
+ /** Missed action envelopes since `lastSeenServerSeq` */
1586
+ actions: IActionEnvelope[];
1587
+ }
1588
+ /**
1589
+ * Reconnect result when the gap exceeds the replay buffer.
1590
+ */
1591
+ interface IReconnectSnapshotResult {
1592
+ /** Discriminant */
1593
+ type: ReconnectResultType.Snapshot;
1594
+ /** Fresh snapshots for each subscription */
1595
+ snapshots: ISnapshot[];
1596
+ }
1597
+ /** Result of the `reconnect` command. */
1598
+ type IReconnectResult = IReconnectReplayResult | IReconnectSnapshotResult;
1599
+ /**
1600
+ * Subscribe to a URI-identified state resource.
1601
+ *
1602
+ * @category Commands
1603
+ * @method subscribe
1604
+ * @direction Client → Server
1605
+ * @messageType Request
1606
+ * @version 1
1607
+ * @see {@link /specification/subscriptions | Subscriptions}
1608
+ */
1609
+ interface ISubscribeParams {
1610
+ /** URI to subscribe to */
1611
+ resource: URI;
1612
+ }
1613
+ /**
1614
+ * Result of the `subscribe` command.
1615
+ */
1616
+ interface ISubscribeResult {
1617
+ /** Snapshot of the subscribed resource */
1618
+ snapshot: ISnapshot;
1619
+ }
1620
+ /**
1621
+ * Creates a new session with the specified agent provider.
1622
+ *
1623
+ * If the session URI already exists, the server MUST return an error with code
1624
+ * `-32003` (`SessionAlreadyExists`).
1625
+ *
1626
+ * After creation, the client should subscribe to the session URI to receive state
1627
+ * updates. The server also broadcasts a `notify/sessionAdded` notification to all
1628
+ * clients.
1629
+ *
1630
+ * @category Commands
1631
+ * @method createSession
1632
+ * @direction Client → Server
1633
+ * @messageType Request
1634
+ * @version 1
1635
+ * @example
1636
+ * ```jsonc
1637
+ * // Client → Server
1638
+ * { "jsonrpc": "2.0", "id": 2, "method": "createSession",
1639
+ * "params": { "session": "copilot:/<uuid>", "provider": "copilot", "model": "gpt-4o" } }
1640
+ *
1641
+ * // Server → Client (success)
1642
+ * { "jsonrpc": "2.0", "id": 2, "result": null }
1643
+ *
1644
+ * // Server → Client (failure — provider not found)
1645
+ * { "jsonrpc": "2.0", "id": 2, "error": { "code": -32002, "message": "No agent for provider" } }
1646
+ *
1647
+ * // Server → Client (failure — session already exists)
1648
+ * { "jsonrpc": "2.0", "id": 2, "error": { "code": -32003, "message": "Session already exists" } }
1649
+ * ```
1650
+ */
1651
+ /**
1652
+ * Identifies a source session and turn to fork from.
1653
+ *
1654
+ * When provided in `createSession`, the server populates the new session with
1655
+ * content from the source session up to and including the response of the
1656
+ * specified turn.
1657
+ */
1658
+ interface ISessionForkSource {
1659
+ /** URI of the existing session to fork from */
1660
+ session: URI;
1661
+ /** Turn ID in the source session; content up to and including this turn's response is copied */
1662
+ turnId: string;
1663
+ }
1664
+ interface ICreateSessionParams {
1665
+ /** Session URI (client-chosen, e.g. `copilot:/<uuid>`) */
1666
+ session: URI;
1667
+ /** Agent provider ID */
1668
+ provider?: string;
1669
+ /** Model ID to use */
1670
+ model?: string;
1671
+ /** Working directory for the session */
1672
+ workingDirectory?: URI;
1673
+ /**
1674
+ * Fork from an existing session. The new session is populated with content
1675
+ * from the source session up to and including the specified turn's response.
1676
+ */
1677
+ fork?: ISessionForkSource;
1678
+ }
1679
+ /**
1680
+ * Disposes a session and cleans up server-side resources.
1681
+ *
1682
+ * The server broadcasts a `notify/sessionRemoved` notification to all clients.
1683
+ *
1684
+ * @category Commands
1685
+ * @method disposeSession
1686
+ * @direction Client → Server
1687
+ * @messageType Request
1688
+ * @version 1
1689
+ */
1690
+ interface IDisposeSessionParams {
1691
+ /** Session URI to dispose */
1692
+ session: URI;
1693
+ }
1694
+ /**
1695
+ * Returns a list of session summaries. Used to populate session lists and sidebars.
1696
+ *
1697
+ * The session list is **not** part of the state tree because it can be arbitrarily
1698
+ * large. Clients fetch it imperatively and maintain a local cache updated by
1699
+ * `notify/sessionAdded` and `notify/sessionRemoved` notifications.
1700
+ *
1701
+ * @category Commands
1702
+ * @method listSessions
1703
+ * @direction Client → Server
1704
+ * @messageType Request
1705
+ * @version 1
1706
+ */
1707
+ interface IListSessionsParams {
1708
+ /** Optional filter criteria */
1709
+ filter?: object;
1710
+ }
1711
+ /** Result of the `listSessions` command. */
1712
+ interface IListSessionsResult {
1713
+ /** The list of session summaries. */
1714
+ items: ISessionSummary[];
1715
+ }
1716
+ /**
1717
+ * Encoding of fetched content data.
1718
+ *
1719
+ * @category Commands
1720
+ */
1721
+ declare const enum ContentEncoding {
1722
+ Base64 = "base64",
1723
+ Utf8 = "utf-8"
1724
+ }
1725
+ /**
1726
+ * Reads the content of a resource by URI.
1727
+ *
1728
+ * Content references keep the state tree small by storing large data (images,
1729
+ * long tool outputs) by reference rather than inline.
1730
+ *
1731
+ * Binary content (images, etc.) MUST use `base64` encoding. Text content MAY
1732
+ * use `utf-8` encoding.
1733
+ *
1734
+ * @category Commands
1735
+ * @method resourceRead
1736
+ * @direction Client → Server
1737
+ * @messageType Request
1738
+ * @version 1
1739
+ * @throws `NotFound` (`-32008`) if the URI does not exist.
1740
+ * @throws `PermissionDenied` (`-32009`) if the client is not permitted to read the URI.
1741
+ * @example
1742
+ * ```jsonc
1743
+ * // Client → Server
1744
+ * { "jsonrpc": "2.0", "id": 10, "method": "resourceRead",
1745
+ * "params": { "uri": "copilot:/<uuid>/content/img-1" } }
1746
+ *
1747
+ * // Server → Client
1748
+ * { "jsonrpc": "2.0", "id": 10, "result": {
1749
+ * "data": "iVBORw0KGgo...",
1750
+ * "encoding": "base64",
1751
+ * "contentType": "image/png"
1752
+ * }}
1753
+ * ```
1754
+ */
1755
+ interface IResourceReadParams {
1756
+ /** Content URI from a `ContentRef` */
1757
+ uri: string;
1758
+ /** Preferred encoding for the returned data (default: server-chosen) */
1759
+ encoding?: ContentEncoding;
1760
+ }
1761
+ /**
1762
+ * Result of the `resourceRead` command.
1763
+ *
1764
+ * The server SHOULD honor the `encoding` requested in the params. If the
1765
+ * server cannot provide the requested encoding, it MUST fall back to either
1766
+ * `base64` or `utf-8`.
1767
+ */
1768
+ interface IResourceReadResult {
1769
+ /** Content encoded as a string */
1770
+ data: string;
1771
+ /** How `data` is encoded */
1772
+ encoding: ContentEncoding;
1773
+ /** Content type (e.g. `"image/png"`, `"text/plain"`) */
1774
+ contentType?: string;
1775
+ }
1776
+ /**
1777
+ * Writes content to a file on the server's filesystem.
1778
+ *
1779
+ * Binary content (images, etc.) MUST use `base64` encoding. Text content MAY
1780
+ * use `utf-8` encoding.
1781
+ *
1782
+ * If the file does not exist, it is created. If the file already exists, it is
1783
+ * overwritten unless `createOnly` is set.
1784
+ *
1785
+ * @category Commands
1786
+ * @method resourceWrite
1787
+ * @direction Client → Server
1788
+ * @messageType Request
1789
+ * @version 1
1790
+ * @throws `NotFound` (`-32008`) if the parent directory does not exist.
1791
+ * @throws `PermissionDenied` (`-32009`) if the client is not permitted to write to the path.
1792
+ * @throws `AlreadyExists` (`-32010`) if `createOnly` is set and the file already exists.
1793
+ * @example
1794
+ * ```jsonc
1795
+ * // Client → Server
1796
+ * { "jsonrpc": "2.0", "id": 11, "method": "resourceWrite",
1797
+ * "params": { "uri": "file:///workspace/hello.txt", "data": "SGVsbG8=",
1798
+ * "encoding": "base64", "contentType": "text/plain" } }
1799
+ *
1800
+ * // Server → Client
1801
+ * { "jsonrpc": "2.0", "id": 11, "result": {} }
1802
+ * ```
1803
+ */
1804
+ interface IResourceWriteParams {
1805
+ /** Target file URI on the server filesystem */
1806
+ uri: URI;
1807
+ /** Content encoded as a string */
1808
+ data: string;
1809
+ /** How `data` is encoded */
1810
+ encoding: ContentEncoding;
1811
+ /** Content type (e.g. `"text/plain"`, `"image/png"`) */
1812
+ contentType?: string;
1813
+ /**
1814
+ * If `true`, the server MUST fail if the file already exists instead of
1815
+ * overwriting it. Useful for safe creation of new files.
1816
+ */
1817
+ createOnly?: boolean;
1818
+ }
1819
+ /**
1820
+ * Result of the `resourceWrite` command.
1821
+ *
1822
+ * An empty object on success.
1823
+ */
1824
+ interface IResourceWriteResult {
1825
+ }
1826
+ /**
1827
+ * Lists directory entries at a file URI on the server's filesystem.
1828
+ *
1829
+ * This is intended for remote folder pickers and similar UI that needs to let
1830
+ * users navigate the server's local filesystem.
1831
+ *
1832
+ * The server MUST return success only if the target exists and is a directory.
1833
+ * If the target does not exist, is not a directory, or cannot be accessed, the
1834
+ * server MUST return a JSON-RPC error.
1835
+ *
1836
+ * @category Commands
1837
+ * @method resourceList
1838
+ * @direction Client → Server
1839
+ * @messageType Request
1840
+ * @version 1
1841
+ * @throws `NotFound` (`-32008`) if the directory does not exist.
1842
+ * @throws `PermissionDenied` (`-32009`) if the client is not permitted to browse the directory.
1843
+ */
1844
+ interface IResourceListParams {
1845
+ /** Directory URI on the server filesystem */
1846
+ uri: URI;
1847
+ }
1848
+ /**
1849
+ * Directory entry returned by `resourceList`.
1850
+ */
1851
+ interface IDirectoryEntry {
1852
+ /** Base name of the entry */
1853
+ name: string;
1854
+ /** Whether the entry is a file or directory */
1855
+ type: 'file' | 'directory';
1856
+ }
1857
+ /**
1858
+ * Result of the `resourceList` command.
1859
+ */
1860
+ interface IResourceListResult {
1861
+ /** Entries directly contained in the requested directory */
1862
+ entries: IDirectoryEntry[];
1863
+ }
1864
+ /**
1865
+ * Fetches historical turns for a session. Used for lazy loading of conversation
1866
+ * history.
1867
+ *
1868
+ * @category Commands
1869
+ * @method fetchTurns
1870
+ * @direction Client → Server
1871
+ * @messageType Request
1872
+ * @version 1
1873
+ * @example
1874
+ * ```jsonc
1875
+ * // Client → Server (fetch the 20 most recent turns)
1876
+ * { "jsonrpc": "2.0", "id": 8, "method": "fetchTurns",
1877
+ * "params": { "session": "copilot:/<uuid>", "limit": 20 } }
1878
+ *
1879
+ * // Server → Client
1880
+ * { "jsonrpc": "2.0", "id": 8, "result": {
1881
+ * "turns": [ { "id": "t1", ... }, { "id": "t2", ... } ],
1882
+ * "hasMore": true
1883
+ * }}
1884
+ *
1885
+ * // Client → Server (fetch 20 turns before t1)
1886
+ * { "jsonrpc": "2.0", "id": 9, "method": "fetchTurns",
1887
+ * "params": { "session": "copilot:/<uuid>", "before": "t1", "limit": 20 } }
1888
+ * ```
1889
+ */
1890
+ interface IFetchTurnsParams {
1891
+ /** Session URI */
1892
+ session: URI;
1893
+ /** Turn ID to fetch before (exclusive). Omit to fetch from the most recent turn. */
1894
+ before?: string;
1895
+ /** Maximum number of turns to return. Server MAY impose its own upper bound. */
1896
+ limit?: number;
1897
+ }
1898
+ /**
1899
+ * Result of the `fetchTurns` command.
1900
+ */
1901
+ interface IFetchTurnsResult {
1902
+ /** The requested turns, ordered oldest-first */
1903
+ turns: ITurn[];
1904
+ /** Whether more turns exist before the returned range */
1905
+ hasMore: boolean;
1906
+ }
1907
+ /**
1908
+ * Copies a resource from one URI to another on the server's filesystem.
1909
+ *
1910
+ * If the destination already exists, it is overwritten unless `failIfExists`
1911
+ * is set.
1912
+ *
1913
+ * @category Commands
1914
+ * @method resourceCopy
1915
+ * @direction Client → Server
1916
+ * @messageType Request
1917
+ * @version 1
1918
+ * @throws `NotFound` (`-32008`) if the source does not exist.
1919
+ * @throws `PermissionDenied` (`-32009`) if the client is not permitted to read the source or write to the destination.
1920
+ * @throws `AlreadyExists` (`-32010`) if `failIfExists` is set and the destination already exists.
1921
+ */
1922
+ interface IResourceCopyParams {
1923
+ /** Source URI to copy from */
1924
+ source: URI;
1925
+ /** Destination URI to copy to */
1926
+ destination: URI;
1927
+ /**
1928
+ * If `true`, the server MUST fail if the destination already exists instead
1929
+ * of overwriting it.
1930
+ */
1931
+ failIfExists?: boolean;
1932
+ }
1933
+ /**
1934
+ * Result of the `resourceCopy` command.
1935
+ *
1936
+ * An empty object on success.
1937
+ */
1938
+ interface IResourceCopyResult {
1939
+ }
1940
+ /**
1941
+ * Deletes a resource at a URI on the server's filesystem.
1942
+ *
1943
+ * @category Commands
1944
+ * @method resourceDelete
1945
+ * @direction Client → Server
1946
+ * @messageType Request
1947
+ * @version 1
1948
+ * @throws `NotFound` (`-32008`) if the resource does not exist.
1949
+ * @throws `PermissionDenied` (`-32009`) if the client is not permitted to delete the resource.
1950
+ */
1951
+ interface IResourceDeleteParams {
1952
+ /** URI of the resource to delete */
1953
+ uri: URI;
1954
+ /**
1955
+ * If `true` and the target is a directory, delete it and all its contents
1956
+ * recursively. If `false` (default), deleting a non-empty directory MUST fail.
1957
+ */
1958
+ recursive?: boolean;
1959
+ }
1960
+ /**
1961
+ * Result of the `resourceDelete` command.
1962
+ *
1963
+ * An empty object on success.
1964
+ */
1965
+ interface IResourceDeleteResult {
1966
+ }
1967
+ /**
1968
+ * Moves (renames) a resource from one URI to another on the server's filesystem.
1969
+ *
1970
+ * If the destination already exists, it is overwritten unless `failIfExists`
1971
+ * is set.
1972
+ *
1973
+ * @category Commands
1974
+ * @method resourceMove
1975
+ * @direction Client → Server
1976
+ * @messageType Request
1977
+ * @version 1
1978
+ * @throws `NotFound` (`-32008`) if the source does not exist.
1979
+ * @throws `PermissionDenied` (`-32009`) if the client is not permitted to move the resource.
1980
+ * @throws `AlreadyExists` (`-32010`) if `failIfExists` is set and the destination already exists.
1981
+ */
1982
+ interface IResourceMoveParams {
1983
+ /** Source URI to move from */
1984
+ source: URI;
1985
+ /** Destination URI to move to */
1986
+ destination: URI;
1987
+ /**
1988
+ * If `true`, the server MUST fail if the destination already exists instead
1989
+ * of overwriting it.
1990
+ */
1991
+ failIfExists?: boolean;
1992
+ }
1993
+ /**
1994
+ * Result of the `resourceMove` command.
1995
+ *
1996
+ * An empty object on success.
1997
+ */
1998
+ interface IResourceMoveResult {
1999
+ }
2000
+ /**
2001
+ * Pushes a Bearer token for a protected resource. The `resource` field MUST
2002
+ * match an `IProtectedResourceMetadata.resource` value declared by an agent
2003
+ * in `IAgentInfo.protectedResources`.
2004
+ *
2005
+ * Tokens are delivered using [RFC 6750](https://datatracker.ietf.org/doc/html/rfc6750)
2006
+ * (Bearer Token Usage) semantics. The client obtains the token from the
2007
+ * authorization server(s) listed in the resource's metadata and pushes it
2008
+ * to the server via this command.
2009
+ *
2010
+ * @category Commands
2011
+ * @method authenticate
2012
+ * @direction Client → Server
2013
+ * @messageType Request
2014
+ * @version 1
2015
+ * @see {@link /specification/authentication | Authentication}
2016
+ * @example
2017
+ * ```jsonc
2018
+ * // Client → Server
2019
+ * { "jsonrpc": "2.0", "id": 3, "method": "authenticate",
2020
+ * "params": { "resource": "https://api.github.com", "token": "gho_xxxx" } }
2021
+ *
2022
+ * // Server → Client (success)
2023
+ * { "jsonrpc": "2.0", "id": 3, "result": {} }
2024
+ *
2025
+ * // Server → Client (failure — invalid token)
2026
+ * { "jsonrpc": "2.0", "id": 3, "error": { "code": -32007, "message": "Invalid token" } }
2027
+ * ```
2028
+ */
2029
+ interface IAuthenticateParams {
2030
+ /**
2031
+ * The protected resource identifier. MUST match a `resource` value from
2032
+ * `IProtectedResourceMetadata` declared in `IAgentInfo.protectedResources`.
2033
+ */
2034
+ resource: string;
2035
+ /** Bearer token obtained from the resource's authorization server */
2036
+ token: string;
2037
+ }
2038
+ /**
2039
+ * Result of the `authenticate` command.
2040
+ *
2041
+ * An empty object on success. If the token is invalid or the resource is
2042
+ * unrecognized, the server MUST return a JSON-RPC error (e.g. `AuthRequired`
2043
+ * `-32007` or `InvalidParams` `-32602`).
2044
+ */
2045
+ interface IAuthenticateResult {
2046
+ }
2047
+
2048
+ /**
2049
+ * Notification Types — Source of truth for all AHP notification definitions.
2050
+ *
2051
+ * @module notifications
2052
+ * @description Notifications are ephemeral broadcasts that are **not** part of the
2053
+ * state tree. They are not processed by reducers and are not replayed on reconnection.
2054
+ */
2055
+
2056
+ /**
2057
+ * Reason why authentication is required.
2058
+ *
2059
+ * @category Protocol Notifications
2060
+ */
2061
+ declare const enum AuthRequiredReason {
2062
+ /** The client has not yet authenticated for the resource */
2063
+ Required = "required",
2064
+ /** A previously valid token has expired or been revoked */
2065
+ Expired = "expired"
2066
+ }
2067
+ /**
2068
+ * Discriminant values for all protocol notifications.
2069
+ *
2070
+ * @category Protocol Notifications
2071
+ */
2072
+ declare const enum NotificationType {
2073
+ SessionAdded = "notify/sessionAdded",
2074
+ SessionRemoved = "notify/sessionRemoved",
2075
+ AuthRequired = "notify/authRequired"
2076
+ }
2077
+ /**
2078
+ * Broadcast to all connected clients when a new session is created.
2079
+ *
2080
+ * @category Protocol Notifications
2081
+ * @version 1
2082
+ * @example
2083
+ * ```json
2084
+ * {
2085
+ * "jsonrpc": "2.0",
2086
+ * "method": "notification",
2087
+ * "params": {
2088
+ * "notification": {
2089
+ * "type": "notify/sessionAdded",
2090
+ * "summary": {
2091
+ * "resource": "copilot:/<uuid>",
2092
+ * "provider": "copilot",
2093
+ * "title": "New Session",
2094
+ * "status": "idle",
2095
+ * "createdAt": 1710000000000,
2096
+ * "modifiedAt": 1710000000000
2097
+ * }
2098
+ * }
2099
+ * }
2100
+ * }
2101
+ * ```
2102
+ */
2103
+ interface ISessionAddedNotification {
2104
+ type: NotificationType.SessionAdded;
2105
+ /** Summary of the new session */
2106
+ summary: ISessionSummary;
2107
+ }
2108
+ /**
2109
+ * Broadcast to all connected clients when a session is disposed.
2110
+ *
2111
+ * @category Protocol Notifications
2112
+ * @version 1
2113
+ * @example
2114
+ * ```json
2115
+ * {
2116
+ * "jsonrpc": "2.0",
2117
+ * "method": "notification",
2118
+ * "params": {
2119
+ * "notification": {
2120
+ * "type": "notify/sessionRemoved",
2121
+ * "session": "copilot:/<uuid>"
2122
+ * }
2123
+ * }
2124
+ * }
2125
+ * ```
2126
+ */
2127
+ interface ISessionRemovedNotification {
2128
+ type: NotificationType.SessionRemoved;
2129
+ /** URI of the removed session */
2130
+ session: URI;
2131
+ }
2132
+ /**
2133
+ * Sent by the server when a protected resource requires (re-)authentication.
2134
+ *
2135
+ * This notification is sent when a previously valid token expires or is
2136
+ * revoked, or when the server discovers a new authentication requirement.
2137
+ * Clients should obtain a fresh token and push it via the `authenticate`
2138
+ * command.
2139
+ *
2140
+ * @category Protocol Notifications
2141
+ * @version 1
2142
+ * @see {@link /specification/authentication | Authentication}
2143
+ * @example
2144
+ * ```json
2145
+ * {
2146
+ * "jsonrpc": "2.0",
2147
+ * "method": "notification",
2148
+ * "params": {
2149
+ * "notification": {
2150
+ * "type": "notify/authRequired",
2151
+ * "resource": "https://api.github.com",
2152
+ * "reason": "expired"
2153
+ * }
2154
+ * }
2155
+ * }
2156
+ * ```
2157
+ */
2158
+ interface IAuthRequiredNotification {
2159
+ type: NotificationType.AuthRequired;
2160
+ /** The protected resource identifier that requires authentication */
2161
+ resource: string;
2162
+ /** Why authentication is required */
2163
+ reason?: AuthRequiredReason;
2164
+ }
2165
+ /**
2166
+ * Discriminated union of all protocol notifications.
2167
+ */
2168
+ type IProtocolNotification = ISessionAddedNotification | ISessionRemovedNotification | IAuthRequiredNotification;
2169
+
2170
+ /**
2171
+ * Message Types — Fully typed JSON-RPC message definitions for the AHP wire protocol.
2172
+ *
2173
+ * @module messages
2174
+ * @description Typed JSON-RPC request, response, and notification types for all
2175
+ * AHP methods. Narrowing on the `method` field gives fully typed `params` and
2176
+ * result types.
2177
+ */
2178
+
2179
+ /**
2180
+ * Registry mapping each command method name to its params and result types.
2181
+ *
2182
+ * @category Commands
2183
+ */
2184
+ interface ICommandMap {
2185
+ 'initialize': {
2186
+ params: IInitializeParams;
2187
+ result: IInitializeResult;
2188
+ };
2189
+ 'reconnect': {
2190
+ params: IReconnectParams;
2191
+ result: IReconnectResult;
2192
+ };
2193
+ 'subscribe': {
2194
+ params: ISubscribeParams;
2195
+ result: ISubscribeResult;
2196
+ };
2197
+ 'createSession': {
2198
+ params: ICreateSessionParams;
2199
+ result: null;
2200
+ };
2201
+ 'disposeSession': {
2202
+ params: IDisposeSessionParams;
2203
+ result: null;
2204
+ };
2205
+ 'listSessions': {
2206
+ params: IListSessionsParams;
2207
+ result: IListSessionsResult;
2208
+ };
2209
+ 'resourceRead': {
2210
+ params: IResourceReadParams;
2211
+ result: IResourceReadResult;
2212
+ };
2213
+ 'resourceWrite': {
2214
+ params: IResourceWriteParams;
2215
+ result: IResourceWriteResult;
2216
+ };
2217
+ 'resourceList': {
2218
+ params: IResourceListParams;
2219
+ result: IResourceListResult;
2220
+ };
2221
+ 'resourceCopy': {
2222
+ params: IResourceCopyParams;
2223
+ result: IResourceCopyResult;
2224
+ };
2225
+ 'resourceDelete': {
2226
+ params: IResourceDeleteParams;
2227
+ result: IResourceDeleteResult;
2228
+ };
2229
+ 'resourceMove': {
2230
+ params: IResourceMoveParams;
2231
+ result: IResourceMoveResult;
2232
+ };
2233
+ 'fetchTurns': {
2234
+ params: IFetchTurnsParams;
2235
+ result: IFetchTurnsResult;
2236
+ };
2237
+ 'authenticate': {
2238
+ params: IAuthenticateParams;
2239
+ result: IAuthenticateResult;
2240
+ };
2241
+ }
2242
+
2243
+ /**
2244
+ * WebSocket transport layer for AHP protocol communication.
2245
+ *
2246
+ * Handles connection lifecycle, reconnection, and raw message framing.
2247
+ */
2248
+
2249
+ interface TransportOptions {
2250
+ /** Connection timeout in ms (default: 10_000) */
2251
+ connectTimeout?: number;
2252
+ /** Headers to include in the WebSocket handshake */
2253
+ headers?: Record<string, string>;
2254
+ }
2255
+ interface TransportEvents {
2256
+ open: [];
2257
+ close: [code: number, reason: string];
2258
+ error: [error: Error];
2259
+ message: [data: unknown];
2260
+ }
2261
+ /**
2262
+ * Low-level WebSocket transport. Sends and receives JSON text frames.
2263
+ */
2264
+ declare class Transport extends EventEmitter<TransportEvents> {
2265
+ private ws;
2266
+ private _connected;
2267
+ get connected(): boolean;
2268
+ /**
2269
+ * Open a WebSocket connection to the given URL.
2270
+ */
2271
+ connect(url: string, options?: TransportOptions): Promise<void>;
2272
+ /**
2273
+ * Send a JSON-serializable value over the WebSocket.
2274
+ */
2275
+ send(data: unknown): void;
2276
+ /**
2277
+ * Gracefully close the connection.
2278
+ */
2279
+ close(): void;
2280
+ private attachListeners;
2281
+ }
2282
+
2283
+ /**
2284
+ * JSON-RPC 2.0 message routing layer for AHP protocol.
2285
+ *
2286
+ * Handles request/response correlation, notification dispatch,
2287
+ * and incoming action/notification routing.
2288
+ */
2289
+
2290
+ /** Error thrown when a JSON-RPC request receives an error response. */
2291
+ declare class RpcError extends Error {
2292
+ readonly code: number;
2293
+ readonly data?: unknown | undefined;
2294
+ constructor(code: number, message: string, data?: unknown | undefined);
2295
+ }
2296
+ /** Error thrown when a request times out. */
2297
+ declare class RpcTimeoutError extends Error {
2298
+ readonly method: string;
2299
+ readonly timeoutMs: number;
2300
+ constructor(method: string, timeoutMs: number);
2301
+ }
2302
+ interface ProtocolLayerOptions {
2303
+ /** Default request timeout in ms (default: 30_000) */
2304
+ requestTimeout?: number;
2305
+ }
2306
+ interface ProtocolLayerEvents {
2307
+ action: [envelope: IActionEnvelope];
2308
+ notification: [notification: IProtocolNotification];
2309
+ }
2310
+ /**
2311
+ * JSON-RPC 2.0 protocol layer over a Transport.
2312
+ *
2313
+ * - Sends requests with auto-incrementing IDs and returns Promises
2314
+ * - Sends notifications (fire-and-forget, no ID)
2315
+ * - Routes incoming messages to pending request resolvers or event emitters
2316
+ */
2317
+ declare class ProtocolLayer extends EventEmitter<ProtocolLayerEvents> {
2318
+ private readonly transport;
2319
+ private nextId;
2320
+ private pending;
2321
+ private readonly requestTimeout;
2322
+ constructor(transport: Transport, options?: ProtocolLayerOptions);
2323
+ /**
2324
+ * Send a typed JSON-RPC request and await the response.
2325
+ */
2326
+ request<M extends keyof ICommandMap>(method: M, params: ICommandMap[M]["params"], timeoutMs?: number): Promise<ICommandMap[M]["result"]>;
2327
+ /**
2328
+ * Send a JSON-RPC notification (no response expected).
2329
+ */
2330
+ notify(method: string, params: unknown): void;
2331
+ /**
2332
+ * Cancel all pending requests (e.g. on disconnect).
2333
+ */
2334
+ cancelAll(reason: string): void;
2335
+ private handleMessage;
2336
+ }
2337
+
2338
+ /**
2339
+ * SessionHandle — Convenience wrapper for a single session on an AhpClient.
2340
+ *
2341
+ * Filters events by session URI, provides a cleaner API for sending prompts,
2342
+ * cancelling turns, and accessing session state. Library consumers work with
2343
+ * SessionHandle instead of raw `client.dispatchAction()` calls.
2344
+ */
2345
+
2346
+ /** Options for sending a prompt via SessionHandle. */
2347
+ interface PromptOptions {
2348
+ /** File or directory attachments to include with the message. */
2349
+ attachments?: IMessageAttachment[];
2350
+ /** Timeout in ms for the entire turn (default: none). */
2351
+ timeout?: number;
2352
+ }
2353
+ /** Result of a completed turn. */
2354
+ interface TurnResult {
2355
+ turnId: string;
2356
+ responseText: string;
2357
+ toolCalls: number;
2358
+ usage?: {
2359
+ inputTokens: number;
2360
+ outputTokens: number;
2361
+ model?: string;
2362
+ };
2363
+ state: "complete" | "cancelled" | "error";
2364
+ error?: string;
2365
+ }
2366
+ /** Events emitted by SessionHandle, scoped to a single session. */
2367
+ interface SessionHandleEvents {
2368
+ /** Any action for this session. */
2369
+ action: [envelope: IActionEnvelope];
2370
+ /** A turn completed successfully. */
2371
+ turnComplete: [turn: ITurn];
2372
+ /** An error occurred on this session. */
2373
+ error: [error: Error];
2374
+ /** Session was disposed. */
2375
+ disposed: [];
2376
+ }
2377
+ /**
2378
+ * A handle to a single session on an AhpClient.
2379
+ *
2380
+ * Provides a session-scoped view: events are filtered to only this session,
2381
+ * state accessors read from the client's state mirror, and action dispatch
2382
+ * auto-injects the session URI.
2383
+ */
2384
+ declare class SessionHandle extends EventEmitter<SessionHandleEvents> {
2385
+ private readonly client;
2386
+ readonly uri: URI;
2387
+ readonly provider: string;
2388
+ readonly model?: string;
2389
+ private _disposed;
2390
+ private _activeTurnId;
2391
+ private readonly _onAction;
2392
+ private readonly _onDisconnect;
2393
+ constructor(client: AhpClient, uri: URI, provider: string, model?: string);
2394
+ /** Current session state from the state mirror. */
2395
+ get state(): ISessionState | undefined;
2396
+ /** Whether the session is ready for prompts. */
2397
+ get isReady(): boolean;
2398
+ /** The currently active turn, if any. */
2399
+ get activeTurn(): IActiveTurn | undefined;
2400
+ /** Whether this handle has been disposed. */
2401
+ get disposed(): boolean;
2402
+ /**
2403
+ * Wait for the session to reach the "ready" lifecycle state.
2404
+ *
2405
+ * Resolves immediately if already ready. Rejects on creation failure
2406
+ * or timeout.
2407
+ */
2408
+ waitForReady(timeout?: number): Promise<void>;
2409
+ /**
2410
+ * Dispose this session handle and clean up server-side resources.
2411
+ */
2412
+ dispose(): Promise<void>;
2413
+ /**
2414
+ * Send a prompt and wait for the turn to complete.
2415
+ *
2416
+ * Returns a `TurnResult` when the turn finishes (complete, error, or cancelled).
2417
+ * Tool call confirmations and permissions are NOT handled automatically —
2418
+ * library consumers should listen to `handle.on('action', ...)` and use
2419
+ * `handle.dispatchAction()` for tool/permission responses.
2420
+ */
2421
+ sendPrompt(text: string, options?: PromptOptions): Promise<TurnResult>;
2422
+ /**
2423
+ * Cancel the currently active turn.
2424
+ */
2425
+ cancelTurn(): Promise<void>;
2426
+ /**
2427
+ * Dispatch a client action for this session.
2428
+ *
2429
+ * Automatically injects the session URI into the action. Use this for
2430
+ * tool call confirmations, permission responses, model changes, etc.
2431
+ */
2432
+ dispatchAction(action: Record<string, unknown> & {
2433
+ type: string;
2434
+ }): void;
2435
+ private ensureNotDisposed;
2436
+ }
2437
+
2438
+ /**
2439
+ * Local state mirror — applies incoming actions through the AHP reducers.
2440
+ *
2441
+ * Maintains a client-side copy of root state and session states,
2442
+ * kept in sync by applying action envelopes from the server.
2443
+ */
2444
+
2445
+ /**
2446
+ * Client-side state mirror that tracks root and session states
2447
+ * by applying incoming action envelopes through the protocol reducers.
2448
+ */
2449
+ declare class StateMirror {
2450
+ private rootState;
2451
+ private sessions;
2452
+ private serverSeq;
2453
+ /** Current root state (agents, active session count). */
2454
+ get root(): IRootState;
2455
+ /** Current server sequence number. */
2456
+ get seq(): number;
2457
+ /** Get a session state by URI. */
2458
+ getSession(uri: URI): ISessionState | undefined;
2459
+ /** All tracked session URIs. */
2460
+ get sessionUris(): URI[];
2461
+ /**
2462
+ * Load a snapshot (from initialize, reconnect, or subscribe).
2463
+ */
2464
+ applySnapshot(snapshot: ISnapshot): void;
2465
+ /**
2466
+ * Apply an incoming action envelope from the server.
2467
+ */
2468
+ applyAction(envelope: IActionEnvelope): void;
2469
+ /**
2470
+ * Remove a session from tracking (e.g. after dispose or unsubscribe).
2471
+ */
2472
+ removeSession(uri: URI): void;
2473
+ }
2474
+
2475
+ /**
2476
+ * ActiveClientManager — Manages active client status for AHP sessions.
2477
+ *
2478
+ * AHP sessions have an "active client" concept — only one client at a time
2479
+ * provides tools to the session. This manager handles claiming/releasing
2480
+ * active status and registering tools.
2481
+ */
2482
+
2483
+ /**
2484
+ * Manages active client status and tool registration for AHP sessions.
2485
+ */
2486
+ declare class ActiveClientManager {
2487
+ private readonly client;
2488
+ private readonly clientId;
2489
+ /** Sessions where this client is the active client. */
2490
+ private readonly activeSessions;
2491
+ constructor(client: AhpClient, clientId: string);
2492
+ /**
2493
+ * Claim active client status for a session.
2494
+ * Dispatches `session/activeClientChanged` with this client's info.
2495
+ */
2496
+ claimActiveClient(sessionUri: URI, displayName?: string, tools?: IToolDefinition[]): Promise<void>;
2497
+ /**
2498
+ * Release active client status for a session.
2499
+ * Dispatches `session/activeClientChanged` with `null`.
2500
+ */
2501
+ releaseActiveClient(sessionUri: URI): Promise<void>;
2502
+ /**
2503
+ * Check if this client is the active client for a session.
2504
+ * Uses the local state mirror for the check.
2505
+ */
2506
+ isActiveClient(sessionUri: URI): boolean;
2507
+ /**
2508
+ * Register (or update) the tools this client provides to a session.
2509
+ * Dispatches `session/activeClientToolsChanged`.
2510
+ * Only valid when this client is the active client.
2511
+ */
2512
+ registerTools(sessionUri: URI, tools: IToolDefinition[]): Promise<void>;
2513
+ /**
2514
+ * Handle a tool call directed at this client.
2515
+ * Dispatches `session/toolCallComplete` with the result.
2516
+ */
2517
+ completeToolCall(sessionUri: URI, turnId: string, toolCallId: string, result: {
2518
+ success: boolean;
2519
+ pastTenseMessage: string;
2520
+ content?: Array<{
2521
+ type: "text";
2522
+ text: string;
2523
+ }>;
2524
+ }): void;
2525
+ /**
2526
+ * Get the set of sessions where this client is active.
2527
+ */
2528
+ get sessions(): ReadonlySet<URI>;
2529
+ }
2530
+
2531
+ /**
2532
+ * ReconnectManager — Handles automatic reconnection with exponential backoff.
2533
+ *
2534
+ * When the WebSocket connection drops, attempts to reconnect using the
2535
+ * AHP `reconnect` command. Supports both `replay` (apply missed actions)
2536
+ * and `snapshot` (reset state) recovery modes.
2537
+ */
2538
+
2539
+ interface ReconnectOptions {
2540
+ /** Maximum number of reconnect attempts (default: 5) */
2541
+ maxRetries?: number;
2542
+ /** Initial backoff in milliseconds (default: 1000) */
2543
+ backoffMs?: number;
2544
+ /** Maximum backoff in milliseconds (default: 30000) */
2545
+ maxBackoffMs?: number;
2546
+ /** Stream for status messages (default: process.stderr) */
2547
+ statusOut?: {
2548
+ write(data: string): void;
2549
+ };
2550
+ }
2551
+ type ReconnectOutcome = "replay" | "snapshot" | "failed";
2552
+ /**
2553
+ * Manages reconnection to an AHP server with exponential backoff.
2554
+ */
2555
+ declare class ReconnectManager {
2556
+ private readonly serverUrl;
2557
+ private readonly clientId;
2558
+ private readonly maxRetries;
2559
+ private readonly backoffMs;
2560
+ private readonly maxBackoffMs;
2561
+ private readonly statusOut;
2562
+ private aborted;
2563
+ constructor(serverUrl: string, clientId: string, options?: ReconnectOptions);
2564
+ /**
2565
+ * Attempt to reconnect to the AHP server.
2566
+ *
2567
+ * @param client - The AhpClient to reconnect
2568
+ * @param lastSeenServerSeq - Last server sequence number received
2569
+ * @param subscriptions - URIs the client was subscribed to
2570
+ * @returns The reconnect outcome (replay, snapshot, or failed)
2571
+ */
2572
+ reconnect(client: AhpClient, _lastSeenServerSeq: number, subscriptions: URI[]): Promise<ReconnectOutcome>;
2573
+ /**
2574
+ * Abort any in-progress reconnection attempt.
2575
+ */
2576
+ abort(): void;
2577
+ /**
2578
+ * Sleep for a given number of milliseconds. Can be aborted.
2579
+ */
2580
+ private sleep;
2581
+ }
2582
+
2583
+ /**
2584
+ * AhpClient — High-level AHP protocol client.
2585
+ *
2586
+ * Composes Transport + ProtocolLayer + StateMirror into a single
2587
+ * interface for connecting to AHP servers, managing sessions, and
2588
+ * dispatching actions.
2589
+ */
2590
+
2591
+ interface AhpClientOptions extends TransportOptions, ProtocolLayerOptions {
2592
+ /** Unique client identifier (default: random UUID) */
2593
+ clientId?: string;
2594
+ /** URIs to subscribe to during initialization */
2595
+ initialSubscriptions?: URI[];
2596
+ }
2597
+ interface AhpClientEvents {
2598
+ action: [envelope: IActionEnvelope];
2599
+ notification: [notification: IProtocolNotification];
2600
+ connected: [result: IInitializeResult];
2601
+ disconnected: [code: number, reason: string];
2602
+ error: [error: Error];
2603
+ }
2604
+ /** Options for opening a session via `AhpClient.openSession()`. */
2605
+ interface OpenSessionOptions {
2606
+ /** Agent provider (e.g. "copilot"). If omitted, uses the first available. */
2607
+ provider?: string;
2608
+ /** Model to use for the session. */
2609
+ model?: string;
2610
+ /** Working directory for the session. */
2611
+ workingDirectory?: string;
2612
+ /** Whether to wait for the session to be ready (default: true). */
2613
+ waitForReady?: boolean;
2614
+ /** Timeout in ms for waiting for ready state (default: 30000). */
2615
+ readyTimeout?: number;
2616
+ }
2617
+ /**
2618
+ * High-level AHP client.
2619
+ *
2620
+ * Usage:
2621
+ * ```ts
2622
+ * const client = new AhpClient();
2623
+ * const result = await client.connect("ws://localhost:3000");
2624
+ * console.log(result.snapshots[0].state);
2625
+ * await client.disconnect();
2626
+ * ```
2627
+ */
2628
+ declare class AhpClient extends EventEmitter<AhpClientEvents> {
2629
+ private readonly options;
2630
+ private transport;
2631
+ private protocol;
2632
+ private readonly _state;
2633
+ private readonly _sessions;
2634
+ private _clientId;
2635
+ private _clientSeq;
2636
+ private _connected;
2637
+ constructor(options?: AhpClientOptions);
2638
+ /** Whether the client is currently connected. */
2639
+ get connected(): boolean;
2640
+ /** The local state mirror. */
2641
+ get state(): StateMirror;
2642
+ /** The client identifier. */
2643
+ get clientId(): string;
2644
+ /** All active session handles. */
2645
+ get sessions(): ReadonlyMap<string, SessionHandle>;
2646
+ /**
2647
+ * Connect to an AHP server and perform the initialization handshake.
2648
+ */
2649
+ connect(url: string): Promise<IInitializeResult>;
2650
+ /**
2651
+ * Gracefully disconnect from the server.
2652
+ */
2653
+ disconnect(): Promise<void>;
2654
+ /**
2655
+ * Create a session and return a handle for interacting with it.
2656
+ *
2657
+ * Creates the session on the server, subscribes to its state, and
2658
+ * (by default) waits for it to reach the "ready" lifecycle state.
2659
+ */
2660
+ openSession(options?: OpenSessionOptions): Promise<SessionHandle>;
2661
+ /**
2662
+ * Create a new session with the specified agent provider.
2663
+ */
2664
+ createSession(sessionUri: URI, provider?: string, model?: string, workingDirectory?: string): Promise<null>;
2665
+ /**
2666
+ * Dispose a session and clean up server-side resources.
2667
+ */
2668
+ disposeSession(sessionUri: URI): Promise<null>;
2669
+ /**
2670
+ * List all sessions on the server.
2671
+ */
2672
+ listSessions(): Promise<IListSessionsResult>;
2673
+ /**
2674
+ * Subscribe to a state resource URI.
2675
+ */
2676
+ subscribe(resourceUri: URI): Promise<ISubscribeResult>;
2677
+ /**
2678
+ * Unsubscribe from a state resource URI.
2679
+ */
2680
+ unsubscribe(resourceUri: URI): void;
2681
+ /**
2682
+ * Fetch historical turns for a session.
2683
+ */
2684
+ fetchTurns(sessionUri: URI, before?: string, limit?: number): Promise<IFetchTurnsResult>;
2685
+ /**
2686
+ * Read content by URI (files, tool outputs, etc.).
2687
+ */
2688
+ resourceRead(uri: string, encoding?: ContentEncoding): Promise<IResourceReadResult>;
2689
+ /**
2690
+ * Write content to a file on the server's filesystem.
2691
+ */
2692
+ resourceWrite(params: IResourceWriteParams): Promise<IResourceWriteResult>;
2693
+ /**
2694
+ * List directory entries on the server's filesystem.
2695
+ */
2696
+ resourceList(uri: URI): Promise<IResourceListResult>;
2697
+ /**
2698
+ * Copy a resource from one URI to another.
2699
+ */
2700
+ resourceCopy(params: IResourceCopyParams): Promise<IResourceCopyResult>;
2701
+ /**
2702
+ * Delete a resource at a URI.
2703
+ */
2704
+ resourceDelete(params: IResourceDeleteParams): Promise<IResourceDeleteResult>;
2705
+ /**
2706
+ * Move (rename) a resource from one URI to another.
2707
+ */
2708
+ resourceMove(params: IResourceMoveParams): Promise<IResourceMoveResult>;
2709
+ /**
2710
+ * Dispatch a client-originated action to the server.
2711
+ */
2712
+ dispatchAction(action: IStateAction): void;
2713
+ /**
2714
+ * Push an authentication token for a protected resource.
2715
+ */
2716
+ authenticate(resource: string, token: string): Promise<void>;
2717
+ private ensureConnected;
2718
+ }
2719
+
2720
+ /**
2721
+ * ConnectionPool — Manages reusable AhpClient connections to multiple servers.
2722
+ *
2723
+ * For library consumers managing multiple servers, the pool ensures
2724
+ * that only one WebSocket connection exists per server URL, and provides
2725
+ * aggregate stats across all connections and sessions.
2726
+ */
2727
+
2728
+ /** Options for the ConnectionPool. */
2729
+ interface ConnectionPoolOptions {
2730
+ /** Maximum concurrent connections per server URL (default: 1). */
2731
+ maxConnectionsPerServer?: number;
2732
+ }
2733
+ /**
2734
+ * Pool of AhpClient connections, keyed by server URL.
2735
+ *
2736
+ * Reuses existing connections to the same server URL. Each connection
2737
+ * is an `AhpClient` that can host multiple concurrent sessions.
2738
+ *
2739
+ * @example
2740
+ * ```ts
2741
+ * const pool = new ConnectionPool();
2742
+ * const client = await pool.getClient("ws://localhost:8082");
2743
+ * const session = await client.openSession({ provider: "copilot" });
2744
+ * // ... use session ...
2745
+ * await pool.closeAll();
2746
+ * ```
2747
+ */
2748
+ declare class ConnectionPool {
2749
+ private readonly _clients;
2750
+ private readonly _maxPerServer;
2751
+ constructor(options?: ConnectionPoolOptions);
2752
+ /**
2753
+ * Get or create a connected client for the given server URL.
2754
+ *
2755
+ * If a connected client already exists for this URL, it is returned.
2756
+ * Otherwise a new client is created, connected, and cached.
2757
+ */
2758
+ getClient(url: string, options?: AhpClientOptions): Promise<AhpClient>;
2759
+ /**
2760
+ * Close all connections in the pool.
2761
+ */
2762
+ closeAll(): Promise<void>;
2763
+ /** Number of active connections in the pool. */
2764
+ get activeConnections(): number;
2765
+ /** Total number of active sessions across all connections. */
2766
+ get activeSessions(): number;
2767
+ private normalizeUrl;
2768
+ }
2769
+
2770
+ /**
2771
+ * PromptRenderer — Streaming terminal renderer for AHP turn output.
2772
+ *
2773
+ * Renders deltas, reasoning blocks, tool calls, permissions, usage,
2774
+ * and turn lifecycle events to stdout with color formatting via picocolors.
2775
+ */
2776
+
2777
+ /** Minimal info about a tool call ready for display. */
2778
+ interface ToolCallInfo {
2779
+ toolCallId: string;
2780
+ toolName: string;
2781
+ displayName: string;
2782
+ invocationMessage: StringOrMarkdown;
2783
+ toolInput?: string;
2784
+ }
2785
+
2786
+ /**
2787
+ * OutputFormatter — Abstraction layer for CLI output formatting.
2788
+ *
2789
+ * Three modes:
2790
+ * - text: Colored terminal output via PromptRenderer
2791
+ * - json: NDJSON (one JSON object per line)
2792
+ * - quiet: Accumulates silently, prints only the final response
2793
+ */
2794
+
2795
+ /**
2796
+ * Interface implemented by all output formatters.
2797
+ *
2798
+ * The TurnController calls these methods as actions arrive from the server.
2799
+ * Each formatter decides how (or whether) to render them.
2800
+ */
2801
+ interface OutputFormatter {
2802
+ onDelta(text: string): void;
2803
+ onReasoning(text: string): void;
2804
+ onToolCallStart(id: string, name: string): void;
2805
+ onToolCallDelta(id: string, paramsDelta: string): void;
2806
+ onToolCallReady(id: string, call: ToolCallInfo): void;
2807
+ onToolCallComplete(id: string, result: IToolCallResult): void;
2808
+ onToolCallCancelled(id: string, reason: string): void;
2809
+ onUsage(usage: IUsageInfo): void;
2810
+ onTurnComplete(responseText: string): void;
2811
+ onTurnError(error: IErrorInfo): void;
2812
+ onTurnCancelled(): void;
2813
+ onTitleChanged(title: string): void;
2814
+ }
2815
+
2816
+ /**
2817
+ * JSON Formatter — NDJSON output (one JSON object per line).
2818
+ *
2819
+ * Each event has a stable envelope:
2820
+ * ```json
2821
+ * { "type": "delta", "timestamp": "<ISO>", "data": { ... } }
2822
+ * ```
2823
+ *
2824
+ * Raw protocol data goes in `data` — no renaming or reshaping.
2825
+ *
2826
+ * When `strict` mode is enabled, non-JSON stderr output is suppressed.
2827
+ */
2828
+
2829
+ type JsonEventType = "delta" | "reasoning" | "tool_call_start" | "tool_call_delta" | "tool_call_ready" | "tool_call_complete" | "tool_call_cancelled" | "usage" | "turn_complete" | "turn_error" | "turn_cancelled" | "title_changed";
2830
+
2831
+ /**
2832
+ * Event Forwarder — Pluggable event forwarding system.
2833
+ *
2834
+ * Defines the `AhpxEvent` shape and the `EventForwarder` interface.
2835
+ * Implementations (WebhookForwarder, WebSocketForwarder) forward events
2836
+ * to external consumers: dashboards, log aggregators, monitoring systems.
2837
+ *
2838
+ * Events match the JsonEnvelope shape from the NDJSON formatter, extended
2839
+ * with `sessionUri` for multi-session disambiguation.
2840
+ */
2841
+
2842
+ /**
2843
+ * An event emitted by ahpx, suitable for forwarding to external consumers.
2844
+ *
2845
+ * Intentionally compatible with `JsonEnvelope` from the NDJSON formatter,
2846
+ * but with an additional `sessionUri` field for multi-session support.
2847
+ */
2848
+ interface AhpxEvent {
2849
+ /** Event type (e.g. "delta", "tool_call_complete", "turn_complete"). */
2850
+ type: JsonEventType | (string & {});
2851
+ /** ISO 8601 timestamp of when the event was generated. */
2852
+ timestamp: string;
2853
+ /** Optional metadata tags (e.g. jobId, project, environment). */
2854
+ tags?: Record<string, string>;
2855
+ /** Event payload — raw protocol data, no renaming or reshaping. */
2856
+ data: Record<string, unknown>;
2857
+ /** Session URI this event belongs to (for multi-session disambiguation). */
2858
+ sessionUri?: string;
2859
+ }
2860
+ /**
2861
+ * Interface for forwarding events to external consumers.
2862
+ *
2863
+ * Implementations handle transport, batching, retry, and filtering.
2864
+ * The `forward()` method may buffer events internally — call `close()`
2865
+ * to flush any remaining events and release resources.
2866
+ */
2867
+ interface EventForwarder {
2868
+ /** Forward an event to the external consumer. May buffer internally. */
2869
+ forward(event: AhpxEvent): Promise<void>;
2870
+ /** Flush buffered events and release resources. */
2871
+ close(): Promise<void>;
2872
+ }
2873
+
2874
+ /**
2875
+ * Webhook Forwarder — POST events to an HTTP endpoint.
2876
+ *
2877
+ * Batches events to reduce HTTP requests, retries with exponential backoff
2878
+ * on failure, supports event type filtering, and buffers events if the
2879
+ * endpoint is temporarily down. Flushes remaining events on `close()`.
2880
+ */
2881
+
2882
+ interface WebhookForwarderOptions {
2883
+ /** URL to POST events to. */
2884
+ url: string;
2885
+ /** Custom HTTP headers to include in requests. */
2886
+ headers?: Record<string, string>;
2887
+ /** Number of events to batch before sending (default: 10). */
2888
+ batchSize?: number;
2889
+ /** Max milliseconds to wait before flushing a partial batch (default: 1000). */
2890
+ batchIntervalMs?: number;
2891
+ /** Number of retry attempts on failure (default: 3). */
2892
+ retries?: number;
2893
+ /** Event types to forward. If empty/undefined, forwards all. */
2894
+ filter?: string[];
2895
+ }
2896
+ declare class WebhookForwarder implements EventForwarder {
2897
+ private readonly url;
2898
+ private readonly headers;
2899
+ private readonly batchSize;
2900
+ private readonly batchIntervalMs;
2901
+ private readonly retries;
2902
+ private readonly filter;
2903
+ private batch;
2904
+ private flushTimer;
2905
+ private closed;
2906
+ private flushPromise;
2907
+ constructor(options: WebhookForwarderOptions);
2908
+ forward(event: AhpxEvent): Promise<void>;
2909
+ close(): Promise<void>;
2910
+ private startFlushTimer;
2911
+ private clearFlushTimer;
2912
+ private flush;
2913
+ private sendWithRetry;
2914
+ private send;
2915
+ }
2916
+
2917
+ /**
2918
+ * WebSocket Forwarder — Stream events over a WebSocket connection.
2919
+ *
2920
+ * Connects to a WebSocket endpoint and streams events in real-time.
2921
+ * Auto-reconnects on disconnect, supports event type filtering,
2922
+ * and handles backpressure by buffering when the WebSocket buffer is full.
2923
+ */
2924
+
2925
+ interface WebSocketForwarderOptions {
2926
+ /** WebSocket URL to connect to (ws:// or wss://). */
2927
+ url: string;
2928
+ /** Custom headers for the WebSocket handshake. */
2929
+ headers?: Record<string, string>;
2930
+ /** Auto-reconnect on disconnect (default: true). */
2931
+ reconnect?: boolean;
2932
+ /** Event types to forward. If empty/undefined, forwards all. */
2933
+ filter?: string[];
2934
+ }
2935
+ declare class WebSocketForwarder implements EventForwarder {
2936
+ private readonly url;
2937
+ private readonly headers;
2938
+ private readonly reconnect;
2939
+ private readonly filter;
2940
+ private ws;
2941
+ private buffer;
2942
+ private closed;
2943
+ private reconnecting;
2944
+ private reconnectTimer;
2945
+ private reconnectAttempt;
2946
+ private connectPromise;
2947
+ constructor(options: WebSocketForwarderOptions);
2948
+ forward(event: AhpxEvent): Promise<void>;
2949
+ close(): Promise<void>;
2950
+ private connect;
2951
+ private scheduleReconnect;
2952
+ private isConnected;
2953
+ private sendOrBuffer;
2954
+ private addToBuffer;
2955
+ private drainBuffer;
2956
+ }
2957
+
2958
+ /**
2959
+ * Forwarding Formatter — Decorator that wraps an OutputFormatter and
2960
+ * forwards events to one or more EventForwarder instances.
2961
+ *
2962
+ * Each OutputFormatter method is delegated to the inner formatter AND
2963
+ * converted to an AhpxEvent that is forwarded to all registered forwarders.
2964
+ *
2965
+ * Forwarding is fire-and-forget — errors are logged but never propagate
2966
+ * to the formatter or TurnController. This ensures that a flaky endpoint
2967
+ * never disrupts the primary output pipeline.
2968
+ */
2969
+
2970
+ interface ForwardingFormatterOptions {
2971
+ /** The inner formatter to delegate rendering to. */
2972
+ inner: OutputFormatter;
2973
+ /** One or more forwarders to send events to. */
2974
+ forwarders: EventForwarder[];
2975
+ /** Session URI to attach to forwarded events. */
2976
+ sessionUri?: string;
2977
+ /** Metadata tags to attach to forwarded events. */
2978
+ tags?: Record<string, string>;
2979
+ }
2980
+ declare class ForwardingFormatter implements OutputFormatter {
2981
+ private readonly inner;
2982
+ private readonly forwarders;
2983
+ private readonly tags?;
2984
+ /** Session URI to attach to forwarded events. Can be set after construction. */
2985
+ sessionUri?: string;
2986
+ constructor(options: ForwardingFormatterOptions);
2987
+ onDelta(text: string): void;
2988
+ onReasoning(text: string): void;
2989
+ onToolCallStart(id: string, name: string): void;
2990
+ onToolCallDelta(id: string, paramsDelta: string): void;
2991
+ onToolCallReady(id: string, call: ToolCallInfo): void;
2992
+ onToolCallComplete(id: string, result: IToolCallResult): void;
2993
+ onToolCallCancelled(id: string, reason: string): void;
2994
+ onUsage(usage: IUsageInfo): void;
2995
+ onTurnComplete(responseText: string): void;
2996
+ onTurnError(error: IErrorInfo): void;
2997
+ onTurnCancelled(): void;
2998
+ onTitleChanged(title: string): void;
2999
+ /**
3000
+ * Close all forwarders, flushing any buffered events.
3001
+ *
3002
+ * Call this when the session/turn is done to ensure all events
3003
+ * have been delivered.
3004
+ */
3005
+ close(): Promise<void>;
3006
+ private emit;
3007
+ }
3008
+
3009
+ /**
3010
+ * AuthHandler — Handles AHP authentication flow.
3011
+ *
3012
+ * When a server sends an `authRequired` notification, the handler:
3013
+ * 1. Checks for a stored token (from ~/.ahpx/auth.json)
3014
+ * 2. Checks environment variable (AHPX_TOKEN)
3015
+ * 3. Uses a CLI-provided token (--token flag)
3016
+ * 4. Prompts the user interactively (if TTY available)
3017
+ * 5. Stores successful tokens for future use
3018
+ *
3019
+ * Tokens are stored with restrictive file permissions (0600).
3020
+ */
3021
+
3022
+ interface AuthHandlerOptions {
3023
+ /** Explicit token (from --token flag) */
3024
+ token?: string;
3025
+ /** Config directory override (for testing) */
3026
+ configDir?: string;
3027
+ /** Whether interactive prompting is allowed */
3028
+ interactive?: boolean;
3029
+ }
3030
+ /**
3031
+ * Handles AHP authentication: token storage, lookup, and delivery.
3032
+ */
3033
+ declare class AuthHandler {
3034
+ private readonly client;
3035
+ private readonly configDir;
3036
+ private readonly explicitToken;
3037
+ private readonly interactive;
3038
+ constructor(client: AhpClient, options?: AuthHandlerOptions);
3039
+ /**
3040
+ * Handle an authRequired notification — find a token and authenticate.
3041
+ * Returns true if authentication succeeded, false otherwise.
3042
+ */
3043
+ handleAuthRequired(resource: IProtectedResourceMetadata): Promise<boolean>;
3044
+ /**
3045
+ * Store a token for a resource in ~/.ahpx/auth.json.
3046
+ * File is created with 0600 permissions.
3047
+ */
3048
+ storeToken(resourceUri: string, token: string): Promise<void>;
3049
+ /**
3050
+ * Load a stored token for a resource.
3051
+ */
3052
+ loadToken(resourceUri: string): Promise<string | undefined>;
3053
+ /**
3054
+ * Try to authenticate with the server.
3055
+ */
3056
+ private tryAuthenticate;
3057
+ /**
3058
+ * Prompt the user for a token interactively.
3059
+ */
3060
+ private promptForToken;
3061
+ }
3062
+
3063
+ /**
3064
+ * Server Health Checker — probes AHP servers for health status.
3065
+ *
3066
+ * Each health check connects, initializes, reads root state, and disconnects.
3067
+ * Stateless per-check — no long-lived connections.
3068
+ */
3069
+ interface ServerHealth {
3070
+ name: string;
3071
+ url: string;
3072
+ status: "healthy" | "degraded" | "unreachable";
3073
+ latencyMs: number;
3074
+ protocolVersion?: number;
3075
+ agents: {
3076
+ provider: string;
3077
+ models: string[];
3078
+ }[];
3079
+ activeSessions: number;
3080
+ checkedAt: string;
3081
+ error?: string;
3082
+ }
3083
+ declare class HealthChecker {
3084
+ private readonly _defaultTimeout;
3085
+ constructor(options?: {
3086
+ timeout?: number;
3087
+ });
3088
+ /** Check a single server's health. */
3089
+ check(url: string, name: string, options?: {
3090
+ timeout?: number;
3091
+ token?: string;
3092
+ }): Promise<ServerHealth>;
3093
+ /** Check all servers concurrently. */
3094
+ checkAll(connections: Array<{
3095
+ name: string;
3096
+ url: string;
3097
+ token?: string;
3098
+ }>): Promise<ServerHealth[]>;
3099
+ }
3100
+
3101
+ /**
3102
+ * Connection Store — Manages named AHP server connection profiles.
3103
+ *
3104
+ * Profiles are stored in `~/.ahpx/connections.json` with atomic writes
3105
+ * (write to temp + rename) to prevent corruption.
3106
+ */
3107
+ interface ConnectionProfile {
3108
+ /** Unique display name for this connection */
3109
+ name: string;
3110
+ /** WebSocket URL (ws:// or wss://) */
3111
+ url: string;
3112
+ /** Optional authentication token */
3113
+ token?: string;
3114
+ /** Whether this is the default connection */
3115
+ default?: boolean;
3116
+ /** Optional tags for server grouping (e.g., ['gpu', 'cloud']) */
3117
+ tags?: string[];
3118
+ }
3119
+
3120
+ /**
3121
+ * Fleet Manager — manages multiple AHP servers with health-aware routing.
3122
+ *
3123
+ * Provides server selection strategies (least-sessions, round-robin, random,
3124
+ * preferred) and filters by provider, model, or tag. Caches health data and
3125
+ * refreshes on demand.
3126
+ */
3127
+
3128
+ type RoutingStrategy = "least-sessions" | "round-robin" | "random" | "preferred";
3129
+ interface FleetManagerOptions {
3130
+ connections: ConnectionProfile[];
3131
+ strategy?: RoutingStrategy;
3132
+ preferredServer?: string;
3133
+ /** Tag-to-server-name mapping, e.g. { gpu: ['cloud-1'], local: ['laptop'] } */
3134
+ tags?: Record<string, string[]>;
3135
+ healthCheckTimeout?: number;
3136
+ }
3137
+ interface ServerRequirements {
3138
+ provider?: string;
3139
+ model?: string;
3140
+ tag?: string;
3141
+ }
3142
+ declare class FleetManager {
3143
+ private readonly _connections;
3144
+ private readonly _strategy;
3145
+ private readonly _preferredServer;
3146
+ private readonly _tags;
3147
+ private readonly _checker;
3148
+ private _healthCache;
3149
+ private _roundRobinIndex;
3150
+ constructor(options: FleetManagerOptions);
3151
+ /** Pick the best server for a dispatch based on strategy and requirements. */
3152
+ selectServer(requirements?: ServerRequirements): Promise<{
3153
+ name: string;
3154
+ url: string;
3155
+ }>;
3156
+ /** Get health for all servers (cached). */
3157
+ getHealth(): Promise<ServerHealth[]>;
3158
+ /** Refresh health cache by checking all servers. */
3159
+ refresh(): Promise<void>;
3160
+ private _applyStrategy;
3161
+ private _leastSessions;
3162
+ }
3163
+
3164
+ /**
3165
+ * Session Store — Persists local session metadata as individual JSON files.
3166
+ *
3167
+ * Each session is stored as `~/.ahpx/sessions/<id>.json`, using atomic
3168
+ * writes (temp file + rename) to prevent corruption.
3169
+ */
3170
+ /** Lightweight summary of a single turn, stored locally for offline history. */
3171
+ interface TurnSummary {
3172
+ /** Turn identifier (UUID from the AHP action). */
3173
+ turnId: string;
3174
+ /** First 200 characters of the user's message. */
3175
+ userMessage: string;
3176
+ /** First 200 characters of the agent's response. */
3177
+ responsePreview: string;
3178
+ /** Number of tool calls made during this turn. */
3179
+ toolCallCount: number;
3180
+ /** Token usage, if reported by the server. */
3181
+ tokenUsage?: {
3182
+ input: number;
3183
+ output: number;
3184
+ model?: string;
3185
+ };
3186
+ /** Final state of the turn. */
3187
+ state: "complete" | "cancelled" | "error";
3188
+ /** ISO 8601 timestamp when the turn completed. */
3189
+ timestamp: string;
3190
+ }
3191
+ interface SessionRecord {
3192
+ /** Unique identifier (UUID) */
3193
+ id: string;
3194
+ /** AHP session URI (e.g. "copilot:/<uuid>") */
3195
+ sessionUri: string;
3196
+ /** Name of the saved connection this session belongs to */
3197
+ serverName: string;
3198
+ /** WebSocket URL (preserved in case the connection profile is removed) */
3199
+ serverUrl: string;
3200
+ /** Agent provider (e.g. "copilot") */
3201
+ provider: string;
3202
+ /** Model used for this session */
3203
+ model?: string;
3204
+ /** User-given name for named sessions */
3205
+ name?: string;
3206
+ /** Working directory when the session was created */
3207
+ workingDirectory?: string;
3208
+ /** Nearest git root directory (for directory-walk scoping) */
3209
+ gitRoot?: string;
3210
+ /** Server-generated session title */
3211
+ title?: string;
3212
+ /** Session lifecycle status */
3213
+ status: "active" | "closed";
3214
+ /** ISO 8601 timestamp of creation */
3215
+ createdAt: string;
3216
+ /** ISO 8601 timestamp when session was closed */
3217
+ closedAt?: string;
3218
+ /** ISO 8601 timestamp of the last prompt sent */
3219
+ lastPromptAt?: string;
3220
+ /** Local turn history (lightweight summaries, capped at MAX_LOCAL_TURNS). */
3221
+ turns?: TurnSummary[];
3222
+ }
3223
+ interface SessionFilter {
3224
+ /** Filter by status */
3225
+ status?: "active" | "closed";
3226
+ /** Filter by server name */
3227
+ serverName?: string;
3228
+ /** Filter by working directory (exact match) */
3229
+ workingDirectory?: string;
3230
+ /** Filter by user-given session name */
3231
+ name?: string;
3232
+ }
3233
+ /** Truncate a string to the preview limit, appending ellipsis if needed. */
3234
+ declare function truncatePreview(str: string, maxLen?: number): string;
3235
+ /** Build a TurnSummary from a completed turn result. */
3236
+ declare function buildTurnSummary(result: {
3237
+ turnId: string;
3238
+ responseText: string;
3239
+ toolCalls: number;
3240
+ usage?: {
3241
+ inputTokens: number;
3242
+ outputTokens: number;
3243
+ model?: string;
3244
+ };
3245
+ state: "complete" | "cancelled" | "error";
3246
+ userMessage: string;
3247
+ }): TurnSummary;
3248
+ declare class SessionStore {
3249
+ private readonly sessionsDir;
3250
+ constructor(configDir?: string);
3251
+ /** Ensure the sessions directory exists. */
3252
+ private ensureDir;
3253
+ /** Path to a session record file. Validates ID to prevent path traversal. */
3254
+ private filePath;
3255
+ /** Validate that a session ID is safe for use in file paths (no traversal). */
3256
+ private validateId;
3257
+ /**
3258
+ * Save a session record to disk. Creates a new file or overwrites an existing one.
3259
+ * Uses atomic writes (temp file + rename).
3260
+ */
3261
+ save(record: SessionRecord): Promise<void>;
3262
+ /** Get a session record by ID, or undefined if not found. */
3263
+ get(id: string): Promise<SessionRecord | undefined>;
3264
+ /**
3265
+ * List session records, optionally filtered.
3266
+ * Returns records sorted by createdAt descending (newest first).
3267
+ */
3268
+ list(filter?: SessionFilter): Promise<SessionRecord[]>;
3269
+ /**
3270
+ * Update specific fields on an existing session record.
3271
+ * Returns the updated record, or undefined if not found.
3272
+ */
3273
+ update(id: string, updates: Partial<Omit<SessionRecord, "id">>): Promise<SessionRecord | undefined>;
3274
+ /**
3275
+ * Soft-close a session: set status='closed' and record the timestamp.
3276
+ * The record is preserved for history.
3277
+ * Returns the updated record, or undefined if not found.
3278
+ */
3279
+ close(id: string): Promise<SessionRecord | undefined>;
3280
+ /**
3281
+ * Append a turn summary to a session record's local history.
3282
+ * Caps the history at MAX_LOCAL_TURNS entries (oldest removed first).
3283
+ * Returns the updated record, or undefined if not found.
3284
+ */
3285
+ appendTurn(id: string, turn: TurnSummary): Promise<SessionRecord | undefined>;
3286
+ /**
3287
+ * Find a session by scope: matching serverName, workingDirectory, and optional name.
3288
+ * Only returns active sessions.
3289
+ */
3290
+ getByScope(options: {
3291
+ serverName: string;
3292
+ workingDirectory: string;
3293
+ name?: string;
3294
+ }): Promise<SessionRecord | undefined>;
3295
+ }
3296
+
3297
+ /**
3298
+ * Session Persistence — Bridge between local SessionStore and live AHP server.
3299
+ *
3300
+ * Handles resuming sessions from local records, saving turn summaries after
3301
+ * each prompt, and syncing local state with server-side session lists.
3302
+ */
3303
+
3304
+ /** Outcome of attempting to resume a session on a server. */
3305
+ type ResumeOutcome = {
3306
+ status: "resumed";
3307
+ } | {
3308
+ status: "not_found";
3309
+ } | {
3310
+ status: "error";
3311
+ message: string;
3312
+ };
3313
+ /** Result of syncing local records with a server. */
3314
+ interface SyncResult {
3315
+ /** Session URIs found on server but not in local store. */
3316
+ added: string[];
3317
+ /** Session IDs in local store whose sessions no longer exist on server. */
3318
+ removed: string[];
3319
+ /** Session IDs where title or status diverged. */
3320
+ updated: string[];
3321
+ }
3322
+ declare class SessionPersistence {
3323
+ private readonly store;
3324
+ constructor(store: SessionStore);
3325
+ /**
3326
+ * Resume a locally-stored session on a connected server.
3327
+ *
3328
+ * Subscribes to the session URI and verifies it is still alive. Returns
3329
+ * a ResumeOutcome indicating whether the session was found.
3330
+ */
3331
+ resume(record: SessionRecord, client: AhpClient): Promise<ResumeOutcome>;
3332
+ /**
3333
+ * Save a turn summary to the local session record after a prompt completes.
3334
+ */
3335
+ saveTurn(recordId: string, result: {
3336
+ turnId: string;
3337
+ responseText: string;
3338
+ toolCalls: number;
3339
+ usage?: {
3340
+ inputTokens: number;
3341
+ outputTokens: number;
3342
+ model?: string;
3343
+ };
3344
+ state: "complete" | "cancelled" | "error";
3345
+ userMessage: string;
3346
+ }): Promise<SessionRecord | undefined>;
3347
+ /**
3348
+ * Sync local session records for a server with the server's actual state.
3349
+ *
3350
+ * Compares locally-active records against the server's session list to
3351
+ * find sessions that were added remotely, disposed remotely, or updated.
3352
+ */
3353
+ sync(client: AhpClient, serverName: string): Promise<SyncResult>;
3354
+ }
3355
+
3356
+ /**
3357
+ * URI utility functions for converting between file URIs and filesystem paths.
3358
+ *
3359
+ * These functions handle both Unix and Windows paths correctly regardless of
3360
+ * the platform they run on — critical for ahpx which may run on macOS/Linux
3361
+ * while targeting remote Windows servers via `--cwd`.
3362
+ *
3363
+ * @see https://datatracker.ietf.org/doc/html/rfc8089 — The "file" URI Scheme
3364
+ */
3365
+ /**
3366
+ * Ensure a filesystem path or URI string is a proper `file://` URI.
3367
+ *
3368
+ * | Input | Output |
3369
+ * |-----------------------------|-------------------------------------|
3370
+ * | `C:\Users\tyler\Code` | `file:///C:/Users/tyler/Code` |
3371
+ * | `C:/Users/tyler/Code` | `file:///C:/Users/tyler/Code` |
3372
+ * | `/Users/tyler/Code` | `file:///Users/tyler/Code` |
3373
+ * | `file:///C:/Users/tyler` | `file:///C:/Users/tyler` (unchanged)|
3374
+ * | `copilot:/session-1` | `copilot:/session-1` (unchanged) |
3375
+ * | `""` (empty) | `""` (unchanged) |
3376
+ *
3377
+ * Backslashes are normalized to forward slashes. Spaces and other reserved
3378
+ * characters in path components are percent-encoded.
3379
+ */
3380
+ declare function ensureFileUri(pathOrUri: string): string;
3381
+ /**
3382
+ * Convert a `file://` URI to a display-friendly filesystem path.
3383
+ *
3384
+ * | Input | Output |
3385
+ * |---------------------------------|---------------------------|
3386
+ * | `file:///C:/Users/tyler/Code` | `C:/Users/tyler/Code` |
3387
+ * | `file:///Users/tyler/Code` | `/Users/tyler/Code` |
3388
+ * | `file:///C%3A/Users/tyler` | `C:/Users/tyler` |
3389
+ * | `copilot:/session-1` | `copilot:/session-1` |
3390
+ * | `/plain/path` | `/plain/path` |
3391
+ *
3392
+ * Percent-encoded characters are decoded. Windows drive letters are detected
3393
+ * and the leading slash is stripped so the path starts with `C:`.
3394
+ */
3395
+ declare function fileUriToDisplayPath(uri: string): string;
3396
+
3397
+ export { ActionType, ActiveClientManager, AhpClient, type AhpClientEvents, type AhpClientOptions, type AhpxEvent, AuthHandler, type AuthHandlerOptions, ConnectionPool, type ConnectionPoolOptions, type ConnectionProfile, ContentEncoding, type EventForwarder, FleetManager, type FleetManagerOptions, ForwardingFormatter, type ForwardingFormatterOptions, HealthChecker, type IActionEnvelope, type IActiveTurn, type IAgentInfo, type ICreateSessionParams, type ICustomizationRef, type IErrorInfo, type IFetchTurnsResult, type IInitializeResult, type IListSessionsResult, type IMarkdownResponsePart, type IPendingMessage, type IProtocolNotification, type IReasoningResponsePart, type IResourceCopyParams, type IResourceCopyResult, type IResourceDeleteParams, type IResourceDeleteResult, type IResourceListResult, type IResourceMoveParams, type IResourceMoveResult, type IResourceReadResult, type IResourceWriteParams, type IResourceWriteResult, type IResponsePart, type IRootState, type ISessionCustomization, type ISessionForkSource, type ISessionState, type ISessionSummary, type ISnapshot, type IStateAction, type ISubscribeResult, type IToolAnnotations, type IToolCallResponsePart, type IToolCallState, type IToolDefinition, type ITurn, type IUsageInfo, type IUserMessage, type Icon, type OpenSessionOptions, PendingMessageKind, type PromptOptions, ProtocolLayer, type ProtocolLayerOptions, ReconnectManager, type ReconnectOptions, type ReconnectOutcome, ResponsePartKind, type ResumeOutcome, type RoutingStrategy, RpcError, RpcTimeoutError, type ServerHealth, type ServerRequirements, type SessionFilter, SessionHandle, type SessionHandleEvents, SessionLifecycle, SessionPersistence, type SessionRecord, SessionStatus, SessionStore, type TurnResult as SessionTurnResult, StateMirror, type SyncResult, ToolCallStatus, Transport, type TransportOptions, type TurnSummary, type URI, WebSocketForwarder, type WebSocketForwarderOptions, WebhookForwarder, type WebhookForwarderOptions, buildTurnSummary, ensureFileUri, fileUriToDisplayPath, truncatePreview };