@github/copilot-sdk 1.0.0-beta.1 → 1.0.0-beta.10
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.
- package/README.md +52 -43
- package/dist/canvas.d.ts +126 -0
- package/dist/canvas.js +49 -0
- package/dist/cjs/canvas.js +75 -0
- package/dist/cjs/client.js +536 -299
- package/dist/cjs/extension.js +9 -2
- package/dist/cjs/generated/rpc.js +1319 -14
- package/dist/cjs/index.js +22 -7
- package/dist/cjs/session.js +179 -93
- package/dist/cjs/sessionFsProvider.js +34 -0
- package/dist/cjs/toolSet.js +107 -0
- package/dist/cjs/types.js +38 -4
- package/dist/client.d.ts +63 -73
- package/dist/client.js +537 -300
- package/dist/extension.d.ts +3 -1
- package/dist/extension.js +10 -2
- package/dist/generated/rpc.d.ts +10187 -1028
- package/dist/generated/rpc.js +1319 -14
- package/dist/generated/session-events.d.ts +1982 -195
- package/dist/index.d.ts +6 -2
- package/dist/index.js +15 -2
- package/dist/session.d.ts +18 -186
- package/dist/session.js +179 -92
- package/dist/sessionFsProvider.d.ts +29 -2
- package/dist/sessionFsProvider.js +34 -0
- package/dist/toolSet.d.ts +75 -0
- package/dist/toolSet.js +82 -0
- package/dist/types.d.ts +730 -123
- package/dist/types.js +36 -3
- package/docs/agent-author.md +31 -7
- package/docs/examples.md +23 -16
- package/package.json +3 -3
package/dist/cjs/index.js
CHANGED
|
@@ -18,25 +18,40 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
18
18
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
19
|
var index_exports = {};
|
|
20
20
|
__export(index_exports, {
|
|
21
|
+
BuiltInTools: () => import_toolSet.BuiltInTools,
|
|
22
|
+
Canvas: () => import_canvas.Canvas,
|
|
23
|
+
CanvasError: () => import_canvas.CanvasError,
|
|
21
24
|
CopilotClient: () => import_client.CopilotClient,
|
|
22
25
|
CopilotSession: () => import_session.CopilotSession,
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
RuntimeConnection: () => import_types.RuntimeConnection,
|
|
27
|
+
SYSTEM_MESSAGE_SECTIONS: () => import_types2.SYSTEM_MESSAGE_SECTIONS,
|
|
28
|
+
ToolSet: () => import_toolSet.ToolSet,
|
|
29
|
+
approveAll: () => import_types2.approveAll,
|
|
30
|
+
convertMcpCallToolResult: () => import_types2.convertMcpCallToolResult,
|
|
31
|
+
createCanvas: () => import_canvas.createCanvas,
|
|
32
|
+
createSessionFsAdapter: () => import_types2.createSessionFsAdapter,
|
|
33
|
+
defineTool: () => import_types2.defineTool
|
|
28
34
|
});
|
|
29
35
|
module.exports = __toCommonJS(index_exports);
|
|
30
36
|
var import_client = require("./client.js");
|
|
31
|
-
var import_session = require("./session.js");
|
|
32
37
|
var import_types = require("./types.js");
|
|
38
|
+
var import_toolSet = require("./toolSet.js");
|
|
39
|
+
var import_session = require("./session.js");
|
|
40
|
+
var import_canvas = require("./canvas.js");
|
|
41
|
+
var import_types2 = require("./types.js");
|
|
33
42
|
// Annotate the CommonJS export names for ESM import in node:
|
|
34
43
|
0 && (module.exports = {
|
|
44
|
+
BuiltInTools,
|
|
45
|
+
Canvas,
|
|
46
|
+
CanvasError,
|
|
35
47
|
CopilotClient,
|
|
36
48
|
CopilotSession,
|
|
37
|
-
|
|
49
|
+
RuntimeConnection,
|
|
50
|
+
SYSTEM_MESSAGE_SECTIONS,
|
|
51
|
+
ToolSet,
|
|
38
52
|
approveAll,
|
|
39
53
|
convertMcpCallToolResult,
|
|
54
|
+
createCanvas,
|
|
40
55
|
createSessionFsAdapter,
|
|
41
56
|
defineTool
|
|
42
57
|
});
|
package/dist/cjs/session.js
CHANGED
|
@@ -18,14 +18,28 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
18
18
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
19
|
var session_exports = {};
|
|
20
20
|
__export(session_exports, {
|
|
21
|
-
CopilotSession: () => CopilotSession
|
|
22
|
-
NO_RESULT_PERMISSION_V2_ERROR: () => NO_RESULT_PERMISSION_V2_ERROR
|
|
21
|
+
CopilotSession: () => CopilotSession
|
|
23
22
|
});
|
|
24
23
|
module.exports = __toCommonJS(session_exports);
|
|
25
24
|
var import_node = require("vscode-jsonrpc/node.js");
|
|
26
25
|
var import_rpc = require("./generated/rpc.js");
|
|
26
|
+
var import_canvas = require("./canvas.js");
|
|
27
27
|
var import_telemetry = require("./telemetry.js");
|
|
28
|
-
|
|
28
|
+
function deserializeHookInput(raw) {
|
|
29
|
+
if (!raw || typeof raw !== "object" || typeof raw.timestamp !== "number") {
|
|
30
|
+
return raw;
|
|
31
|
+
}
|
|
32
|
+
const obj = raw;
|
|
33
|
+
const { cwd, ...rest } = obj;
|
|
34
|
+
return { ...rest, timestamp: new Date(obj.timestamp), workingDirectory: cwd };
|
|
35
|
+
}
|
|
36
|
+
function isOpenCanvasInstance(value) {
|
|
37
|
+
if (!value || typeof value !== "object") {
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
const instance = value;
|
|
41
|
+
return typeof instance.instanceId === "string" && instance.instanceId.length > 0 && typeof instance.extensionId === "string" && instance.extensionId.length > 0 && typeof instance.canvasId === "string" && instance.canvasId.length > 0 && typeof instance.reopen === "boolean" && (instance.availability === "ready" || instance.availability === "stale");
|
|
42
|
+
}
|
|
29
43
|
class CopilotSession {
|
|
30
44
|
/**
|
|
31
45
|
* Creates a new CopilotSession instance.
|
|
@@ -45,15 +59,19 @@ class CopilotSession {
|
|
|
45
59
|
eventHandlers = /* @__PURE__ */ new Set();
|
|
46
60
|
typedEventHandlers = /* @__PURE__ */ new Map();
|
|
47
61
|
toolHandlers = /* @__PURE__ */ new Map();
|
|
62
|
+
canvases = /* @__PURE__ */ new Map();
|
|
48
63
|
commandHandlers = /* @__PURE__ */ new Map();
|
|
49
64
|
permissionHandler;
|
|
50
65
|
userInputHandler;
|
|
51
66
|
elicitationHandler;
|
|
67
|
+
exitPlanModeHandler;
|
|
68
|
+
autoModeSwitchHandler;
|
|
52
69
|
hooks;
|
|
53
70
|
transformCallbacks;
|
|
54
71
|
_rpc = null;
|
|
55
72
|
traceContextProvider;
|
|
56
73
|
_capabilities = {};
|
|
74
|
+
openCanvasInstances = [];
|
|
57
75
|
/** @internal Client session API handlers, populated by CopilotClient during create/resume. */
|
|
58
76
|
clientSessionApis = {};
|
|
59
77
|
/**
|
|
@@ -100,59 +118,22 @@ class CopilotSession {
|
|
|
100
118
|
input: (message, options) => this._input(message, options)
|
|
101
119
|
};
|
|
102
120
|
}
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
*
|
|
106
|
-
* The message is processed asynchronously. Subscribe to events via {@link on}
|
|
107
|
-
* to receive streaming responses and other session events.
|
|
108
|
-
*
|
|
109
|
-
* @param options - The message options including the prompt and optional attachments
|
|
110
|
-
* @returns A promise that resolves with the message ID of the response
|
|
111
|
-
* @throws Error if the session has been disconnected or the connection fails
|
|
112
|
-
*
|
|
113
|
-
* @example
|
|
114
|
-
* ```typescript
|
|
115
|
-
* const messageId = await session.send({
|
|
116
|
-
* prompt: "Explain this code",
|
|
117
|
-
* attachments: [{ type: "file", path: "./src/index.ts" }]
|
|
118
|
-
* });
|
|
119
|
-
* ```
|
|
120
|
-
*/
|
|
121
|
-
async send(options) {
|
|
121
|
+
async send(optionsOrPrompt) {
|
|
122
|
+
const options = typeof optionsOrPrompt === "string" ? { prompt: optionsOrPrompt } : optionsOrPrompt;
|
|
122
123
|
const response = await this.connection.sendRequest("session.send", {
|
|
123
124
|
...await (0, import_telemetry.getTraceContext)(this.traceContextProvider),
|
|
124
125
|
sessionId: this.sessionId,
|
|
125
126
|
prompt: options.prompt,
|
|
127
|
+
displayPrompt: options.displayPrompt,
|
|
126
128
|
attachments: options.attachments,
|
|
127
129
|
mode: options.mode,
|
|
130
|
+
agentMode: options.agentMode,
|
|
128
131
|
requestHeaders: options.requestHeaders
|
|
129
132
|
});
|
|
130
133
|
return response.messageId;
|
|
131
134
|
}
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
*
|
|
135
|
-
* This is a convenience method that combines {@link send} with waiting for
|
|
136
|
-
* the `session.idle` event. Use this when you want to block until the
|
|
137
|
-
* assistant has finished processing the message.
|
|
138
|
-
*
|
|
139
|
-
* Events are still delivered to handlers registered via {@link on} while waiting.
|
|
140
|
-
*
|
|
141
|
-
* @param options - The message options including the prompt and optional attachments
|
|
142
|
-
* @param timeout - Timeout in milliseconds (default: 60000). Controls how long to wait; does not abort in-flight agent work.
|
|
143
|
-
* @returns A promise that resolves with the final assistant message when the session becomes idle,
|
|
144
|
-
* or undefined if no assistant message was received
|
|
145
|
-
* @throws Error if the timeout is reached before the session becomes idle
|
|
146
|
-
* @throws Error if the session has been disconnected or the connection fails
|
|
147
|
-
*
|
|
148
|
-
* @example
|
|
149
|
-
* ```typescript
|
|
150
|
-
* // Send and wait for completion with default 60s timeout
|
|
151
|
-
* const response = await session.sendAndWait({ prompt: "What is 2+2?" });
|
|
152
|
-
* console.log(response?.data.content); // "4"
|
|
153
|
-
* ```
|
|
154
|
-
*/
|
|
155
|
-
async sendAndWait(options, timeout) {
|
|
135
|
+
async sendAndWait(optionsOrPrompt, timeout) {
|
|
136
|
+
const options = typeof optionsOrPrompt === "string" ? { prompt: optionsOrPrompt } : optionsOrPrompt;
|
|
156
137
|
const effectiveTimeout = timeout ?? 6e4;
|
|
157
138
|
let resolveIdle;
|
|
158
139
|
let rejectWithError;
|
|
@@ -293,6 +274,25 @@ class CopilotSession {
|
|
|
293
274
|
}
|
|
294
275
|
} else if (event.type === "capabilities.changed") {
|
|
295
276
|
this._capabilities = { ...this._capabilities, ...event.data };
|
|
277
|
+
} else if (event.type === "session.canvas.opened") {
|
|
278
|
+
this.upsertOpenCanvasFromEvent(event.data);
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
upsertOpenCanvasFromEvent(data) {
|
|
282
|
+
if (!isOpenCanvasInstance(data)) {
|
|
283
|
+
console.warn("failed to deserialize session.canvas.opened payload");
|
|
284
|
+
return;
|
|
285
|
+
}
|
|
286
|
+
this.upsertOpenCanvas(data);
|
|
287
|
+
}
|
|
288
|
+
upsertOpenCanvas(instance) {
|
|
289
|
+
const index = this.openCanvasInstances.findIndex(
|
|
290
|
+
(open) => open.instanceId === instance.instanceId
|
|
291
|
+
);
|
|
292
|
+
if (index >= 0) {
|
|
293
|
+
this.openCanvasInstances[index] = instance;
|
|
294
|
+
} else {
|
|
295
|
+
this.openCanvasInstances.push(instance);
|
|
296
296
|
}
|
|
297
297
|
}
|
|
298
298
|
/**
|
|
@@ -395,8 +395,8 @@ class CopilotSession {
|
|
|
395
395
|
/**
|
|
396
396
|
* Registers custom tool handlers for this session.
|
|
397
397
|
*
|
|
398
|
-
* Tools allow the assistant to execute custom functions.
|
|
399
|
-
*
|
|
398
|
+
* Tools with handlers allow the assistant to execute custom functions automatically.
|
|
399
|
+
* Declaration-only tools are surfaced as events and left pending for the consumer.
|
|
400
400
|
*
|
|
401
401
|
* @param tools - An array of tool definitions with their handlers, or undefined to clear all tools
|
|
402
402
|
* @internal This method is typically called internally when creating a session with tools.
|
|
@@ -407,7 +407,9 @@ class CopilotSession {
|
|
|
407
407
|
return;
|
|
408
408
|
}
|
|
409
409
|
for (const tool of tools) {
|
|
410
|
-
|
|
410
|
+
if (tool.handler) {
|
|
411
|
+
this.toolHandlers.set(tool.name, tool.handler);
|
|
412
|
+
}
|
|
411
413
|
}
|
|
412
414
|
}
|
|
413
415
|
/**
|
|
@@ -420,6 +422,61 @@ class CopilotSession {
|
|
|
420
422
|
getToolHandler(name) {
|
|
421
423
|
return this.toolHandlers.get(name);
|
|
422
424
|
}
|
|
425
|
+
/**
|
|
426
|
+
* Registers canvas declarations and handlers for this session.
|
|
427
|
+
*
|
|
428
|
+
* @param canvases - Canvases created via `createCanvas`, or undefined to clear all canvases
|
|
429
|
+
* @internal Called by the SDK when creating/resuming a session with `canvases`.
|
|
430
|
+
*/
|
|
431
|
+
registerCanvases(canvases) {
|
|
432
|
+
this.canvases.clear();
|
|
433
|
+
if (!canvases || canvases.length === 0) {
|
|
434
|
+
delete this.clientSessionApis.canvas;
|
|
435
|
+
return;
|
|
436
|
+
}
|
|
437
|
+
for (const canvas of canvases) {
|
|
438
|
+
this.canvases.set(canvas.declaration.id, canvas);
|
|
439
|
+
}
|
|
440
|
+
const self = this;
|
|
441
|
+
this.clientSessionApis.canvas = {
|
|
442
|
+
async open(params) {
|
|
443
|
+
const canvas = self.canvases.get(params.canvasId);
|
|
444
|
+
if (!canvas) throw new Error(`No canvas registered with id "${params.canvasId}"`);
|
|
445
|
+
try {
|
|
446
|
+
return await canvas.open(params) ?? {};
|
|
447
|
+
} catch (error) {
|
|
448
|
+
throw toCanvasRpcError(error);
|
|
449
|
+
}
|
|
450
|
+
},
|
|
451
|
+
async close(params) {
|
|
452
|
+
const canvas = self.canvases.get(params.canvasId);
|
|
453
|
+
if (!canvas) throw new Error(`No canvas registered with id "${params.canvasId}"`);
|
|
454
|
+
try {
|
|
455
|
+
if (canvas.onClose) {
|
|
456
|
+
await canvas.onClose(params);
|
|
457
|
+
}
|
|
458
|
+
} catch (error) {
|
|
459
|
+
throw toCanvasRpcError(error);
|
|
460
|
+
}
|
|
461
|
+
},
|
|
462
|
+
async invoke(params) {
|
|
463
|
+
const canvas = self.canvases.get(params.canvasId);
|
|
464
|
+
if (!canvas) throw new Error(`No canvas registered with id "${params.canvasId}"`);
|
|
465
|
+
const handler = canvas.actionHandlers.get(params.actionName);
|
|
466
|
+
if (!handler) {
|
|
467
|
+
throw new import_canvas.CanvasError(
|
|
468
|
+
"canvas_action_no_handler",
|
|
469
|
+
"No handler implemented for this canvas action"
|
|
470
|
+
);
|
|
471
|
+
}
|
|
472
|
+
try {
|
|
473
|
+
return await handler(params);
|
|
474
|
+
} catch (error) {
|
|
475
|
+
throw toCanvasRpcError(error);
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
};
|
|
479
|
+
}
|
|
423
480
|
/**
|
|
424
481
|
* Registers command handlers for this session.
|
|
425
482
|
*
|
|
@@ -444,6 +501,24 @@ class CopilotSession {
|
|
|
444
501
|
registerElicitationHandler(handler) {
|
|
445
502
|
this.elicitationHandler = handler;
|
|
446
503
|
}
|
|
504
|
+
/**
|
|
505
|
+
* Registers the exit-plan-mode handler for this session.
|
|
506
|
+
*
|
|
507
|
+
* @param handler - The handler to invoke when the server dispatches an exit-plan-mode request
|
|
508
|
+
* @internal This method is typically called internally when creating/resuming a session.
|
|
509
|
+
*/
|
|
510
|
+
registerExitPlanModeHandler(handler) {
|
|
511
|
+
this.exitPlanModeHandler = handler;
|
|
512
|
+
}
|
|
513
|
+
/**
|
|
514
|
+
* Registers the auto-mode-switch handler for this session.
|
|
515
|
+
*
|
|
516
|
+
* @param handler - The handler to invoke when the server dispatches an auto-mode-switch request
|
|
517
|
+
* @internal This method is typically called internally when creating/resuming a session.
|
|
518
|
+
*/
|
|
519
|
+
registerAutoModeSwitchHandler(handler) {
|
|
520
|
+
this.autoModeSwitchHandler = handler;
|
|
521
|
+
}
|
|
447
522
|
/**
|
|
448
523
|
* Handles an elicitation.requested broadcast event.
|
|
449
524
|
* Invokes the registered handler and responds via handlePendingElicitation RPC.
|
|
@@ -469,6 +544,26 @@ class CopilotSession {
|
|
|
469
544
|
}
|
|
470
545
|
}
|
|
471
546
|
}
|
|
547
|
+
/**
|
|
548
|
+
* Handles an exitPlanMode.request callback from the runtime.
|
|
549
|
+
* @internal
|
|
550
|
+
*/
|
|
551
|
+
async _handleExitPlanModeRequest(request) {
|
|
552
|
+
if (!this.exitPlanModeHandler) {
|
|
553
|
+
return { approved: true };
|
|
554
|
+
}
|
|
555
|
+
return await this.exitPlanModeHandler(request, { sessionId: this.sessionId });
|
|
556
|
+
}
|
|
557
|
+
/**
|
|
558
|
+
* Handles an autoModeSwitch.request callback from the runtime.
|
|
559
|
+
* @internal
|
|
560
|
+
*/
|
|
561
|
+
async _handleAutoModeSwitchRequest(request) {
|
|
562
|
+
if (!this.autoModeSwitchHandler) {
|
|
563
|
+
return "no";
|
|
564
|
+
}
|
|
565
|
+
return await this.autoModeSwitchHandler(request, { sessionId: this.sessionId });
|
|
566
|
+
}
|
|
472
567
|
/**
|
|
473
568
|
* Sets the host capabilities for this session.
|
|
474
569
|
*
|
|
@@ -478,6 +573,24 @@ class CopilotSession {
|
|
|
478
573
|
setCapabilities(capabilities) {
|
|
479
574
|
this._capabilities = capabilities ?? {};
|
|
480
575
|
}
|
|
576
|
+
/**
|
|
577
|
+
* Snapshot of canvas instances currently known to be open for this session.
|
|
578
|
+
* Populated from the `session.resume` response and live `session.canvas.opened`
|
|
579
|
+
* events. Returns a defensive copy — mutating the returned array has no effect
|
|
580
|
+
* on the session.
|
|
581
|
+
*/
|
|
582
|
+
get openCanvases() {
|
|
583
|
+
return [...this.openCanvasInstances];
|
|
584
|
+
}
|
|
585
|
+
/**
|
|
586
|
+
* Sets the open-canvas snapshot for this session.
|
|
587
|
+
*
|
|
588
|
+
* @param instances - The `openCanvases` array from the `session.resume` response.
|
|
589
|
+
* @internal This method is typically called internally when resuming a session.
|
|
590
|
+
*/
|
|
591
|
+
setOpenCanvases(instances) {
|
|
592
|
+
this.openCanvasInstances = [...instances];
|
|
593
|
+
}
|
|
481
594
|
assertElicitation() {
|
|
482
595
|
if (!this._capabilities.ui?.elicitation) {
|
|
483
596
|
throw new Error(
|
|
@@ -617,33 +730,6 @@ class CopilotSession {
|
|
|
617
730
|
}
|
|
618
731
|
return { sections: result };
|
|
619
732
|
}
|
|
620
|
-
/**
|
|
621
|
-
* Handles a permission request in the v2 protocol format (synchronous RPC).
|
|
622
|
-
* Used as a back-compat adapter when connected to a v2 server.
|
|
623
|
-
*
|
|
624
|
-
* @param request - The permission request data from the CLI
|
|
625
|
-
* @returns A promise that resolves with the permission decision
|
|
626
|
-
* @internal This method is for internal use by the SDK.
|
|
627
|
-
*/
|
|
628
|
-
async _handlePermissionRequestV2(request) {
|
|
629
|
-
if (!this.permissionHandler) {
|
|
630
|
-
return { kind: "user-not-available" };
|
|
631
|
-
}
|
|
632
|
-
try {
|
|
633
|
-
const result = await this.permissionHandler(request, {
|
|
634
|
-
sessionId: this.sessionId
|
|
635
|
-
});
|
|
636
|
-
if (result.kind === "no-result") {
|
|
637
|
-
throw new Error(NO_RESULT_PERMISSION_V2_ERROR);
|
|
638
|
-
}
|
|
639
|
-
return result;
|
|
640
|
-
} catch (error) {
|
|
641
|
-
if (error instanceof Error && error.message === NO_RESULT_PERMISSION_V2_ERROR) {
|
|
642
|
-
throw error;
|
|
643
|
-
}
|
|
644
|
-
return { kind: "user-not-available" };
|
|
645
|
-
}
|
|
646
|
-
}
|
|
647
733
|
/**
|
|
648
734
|
* Handles a user input request from the Copilot CLI.
|
|
649
735
|
*
|
|
@@ -676,9 +762,12 @@ class CopilotSession {
|
|
|
676
762
|
if (!this.hooks) {
|
|
677
763
|
return void 0;
|
|
678
764
|
}
|
|
765
|
+
const normalized = deserializeHookInput(input);
|
|
679
766
|
const handlerMap = {
|
|
680
767
|
preToolUse: this.hooks.onPreToolUse,
|
|
768
|
+
preMcpToolCall: this.hooks.onPreMcpToolCall,
|
|
681
769
|
postToolUse: this.hooks.onPostToolUse,
|
|
770
|
+
postToolUseFailure: this.hooks.onPostToolUseFailure,
|
|
682
771
|
userPromptSubmitted: this.hooks.onUserPromptSubmitted,
|
|
683
772
|
sessionStart: this.hooks.onSessionStart,
|
|
684
773
|
sessionEnd: this.hooks.onSessionEnd,
|
|
@@ -689,7 +778,7 @@ class CopilotSession {
|
|
|
689
778
|
return void 0;
|
|
690
779
|
}
|
|
691
780
|
try {
|
|
692
|
-
const result = await handler(
|
|
781
|
+
const result = await handler(normalized, { sessionId: this.sessionId });
|
|
693
782
|
return result;
|
|
694
783
|
} catch (_error) {
|
|
695
784
|
return void 0;
|
|
@@ -706,7 +795,7 @@ class CopilotSession {
|
|
|
706
795
|
*
|
|
707
796
|
* @example
|
|
708
797
|
* ```typescript
|
|
709
|
-
* const events = await session.
|
|
798
|
+
* const events = await session.getEvents();
|
|
710
799
|
* for (const event of events) {
|
|
711
800
|
* if (event.type === "assistant.message") {
|
|
712
801
|
* console.log("Assistant:", event.data.content);
|
|
@@ -714,7 +803,7 @@ class CopilotSession {
|
|
|
714
803
|
* }
|
|
715
804
|
* ```
|
|
716
805
|
*/
|
|
717
|
-
async
|
|
806
|
+
async getEvents() {
|
|
718
807
|
const response = await this.connection.sendRequest("session.getMessages", {
|
|
719
808
|
sessionId: this.sessionId
|
|
720
809
|
});
|
|
@@ -749,18 +838,10 @@ class CopilotSession {
|
|
|
749
838
|
this.typedEventHandlers.clear();
|
|
750
839
|
this.toolHandlers.clear();
|
|
751
840
|
this.permissionHandler = void 0;
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
* Disconnects this session and releases all in-memory resources.
|
|
757
|
-
* Session data on disk is preserved for later resumption.
|
|
758
|
-
*
|
|
759
|
-
* @returns A promise that resolves when the session is disconnected
|
|
760
|
-
* @throws Error if the connection fails
|
|
761
|
-
*/
|
|
762
|
-
async destroy() {
|
|
763
|
-
return this.disconnect();
|
|
841
|
+
this.userInputHandler = void 0;
|
|
842
|
+
this.elicitationHandler = void 0;
|
|
843
|
+
this.exitPlanModeHandler = void 0;
|
|
844
|
+
this.autoModeSwitchHandler = void 0;
|
|
764
845
|
}
|
|
765
846
|
/** Enables `await using session = ...` syntax for automatic cleanup. */
|
|
766
847
|
async [Symbol.asyncDispose]() {
|
|
@@ -846,8 +927,13 @@ function isToolResultObject(value) {
|
|
|
846
927
|
];
|
|
847
928
|
return allowedResultTypes.includes(value.resultType);
|
|
848
929
|
}
|
|
930
|
+
function toCanvasRpcError(error) {
|
|
931
|
+
if (error instanceof import_node.ResponseError) return error;
|
|
932
|
+
const code = error instanceof import_canvas.CanvasError ? error.code : "canvas_handler_error";
|
|
933
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
934
|
+
return new import_node.ResponseError(import_node.ErrorCodes.InternalError, message, { code, message });
|
|
935
|
+
}
|
|
849
936
|
// Annotate the CommonJS export names for ESM import in node:
|
|
850
937
|
0 && (module.exports = {
|
|
851
|
-
CopilotSession
|
|
852
|
-
NO_RESULT_PERMISSION_V2_ERROR
|
|
938
|
+
CopilotSession
|
|
853
939
|
});
|
|
@@ -21,6 +21,18 @@ __export(sessionFsProvider_exports, {
|
|
|
21
21
|
createSessionFsAdapter: () => createSessionFsAdapter
|
|
22
22
|
});
|
|
23
23
|
module.exports = __toCommonJS(sessionFsProvider_exports);
|
|
24
|
+
function normalizeSqliteParams(params) {
|
|
25
|
+
if (!params) {
|
|
26
|
+
return void 0;
|
|
27
|
+
}
|
|
28
|
+
const normalized = {};
|
|
29
|
+
for (const [key, value] of Object.entries(params)) {
|
|
30
|
+
if (value !== void 0) {
|
|
31
|
+
normalized[key] = value;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return normalized;
|
|
35
|
+
}
|
|
24
36
|
function createSessionFsAdapter(provider) {
|
|
25
37
|
return {
|
|
26
38
|
readFile: async ({ path }) => {
|
|
@@ -107,6 +119,28 @@ function createSessionFsAdapter(provider) {
|
|
|
107
119
|
} catch (err) {
|
|
108
120
|
return toSessionFsError(err);
|
|
109
121
|
}
|
|
122
|
+
},
|
|
123
|
+
// Unlike the FS methods above, SQLite methods let errors propagate to the JSON-RPC layer
|
|
124
|
+
// rather than catching and mapping via toSessionFsError. The FS error mapping is specifically
|
|
125
|
+
// for translating Node.js errno codes (e.g., ENOENT) into SessionFsError, which isn't
|
|
126
|
+
// meaningful for SQL errors. Letting exceptions propagate preserves the original error
|
|
127
|
+
// message in the JSON-RPC error response.
|
|
128
|
+
sqliteQuery: async ({ queryType, query, params: bindParams }) => {
|
|
129
|
+
if (!provider.sqlite) {
|
|
130
|
+
throw new Error("SQLite is not supported by this provider");
|
|
131
|
+
}
|
|
132
|
+
const result = await provider.sqlite.query(
|
|
133
|
+
queryType,
|
|
134
|
+
query,
|
|
135
|
+
normalizeSqliteParams(bindParams)
|
|
136
|
+
);
|
|
137
|
+
return result ?? { rows: [], columns: [], rowsAffected: 0 };
|
|
138
|
+
},
|
|
139
|
+
sqliteExists: async () => {
|
|
140
|
+
if (!provider.sqlite) {
|
|
141
|
+
throw new Error("SQLite is not supported by this provider");
|
|
142
|
+
}
|
|
143
|
+
return { exists: await provider.sqlite.exists() };
|
|
110
144
|
}
|
|
111
145
|
};
|
|
112
146
|
}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var toolSet_exports = {};
|
|
20
|
+
__export(toolSet_exports, {
|
|
21
|
+
BuiltInTools: () => BuiltInTools,
|
|
22
|
+
ToolSet: () => ToolSet
|
|
23
|
+
});
|
|
24
|
+
module.exports = __toCommonJS(toolSet_exports);
|
|
25
|
+
const VALID_TOOL_NAME = /^[a-zA-Z0-9_-]+$/;
|
|
26
|
+
function validateName(kind, name) {
|
|
27
|
+
if (name === "*") {
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
if (!VALID_TOOL_NAME.test(name)) {
|
|
31
|
+
throw new Error(
|
|
32
|
+
`Invalid ${kind} tool name '${name}': tool names must match /^[a-zA-Z0-9_-]+$/ or be the wildcard '*'.`
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
class ToolSet {
|
|
37
|
+
items = [];
|
|
38
|
+
addBuiltIn(nameOrNames) {
|
|
39
|
+
const names = typeof nameOrNames === "string" ? [nameOrNames] : nameOrNames;
|
|
40
|
+
for (const name of names) {
|
|
41
|
+
validateName("builtin", name);
|
|
42
|
+
this.items.push(`builtin:${name}`);
|
|
43
|
+
}
|
|
44
|
+
return this;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Adds a custom tool pattern. Matches tools registered via the SDK's
|
|
48
|
+
* `tools` option or via custom agents.
|
|
49
|
+
*
|
|
50
|
+
* @param name A specific custom tool name or `"*"` to match all custom tools.
|
|
51
|
+
*/
|
|
52
|
+
addCustom(name) {
|
|
53
|
+
validateName("custom", name);
|
|
54
|
+
this.items.push(`custom:${name}`);
|
|
55
|
+
return this;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Adds an MCP tool pattern. Matches tools advertised by any configured
|
|
59
|
+
* MCP server.
|
|
60
|
+
*
|
|
61
|
+
* @param toolName The runtime's canonical wire name for the MCP tool
|
|
62
|
+
* (e.g. `"github-list_issues"`), or `"*"` to match all MCP tools from
|
|
63
|
+
* any server.
|
|
64
|
+
*/
|
|
65
|
+
addMcp(toolName) {
|
|
66
|
+
validateName("mcp", toolName);
|
|
67
|
+
this.items.push(`mcp:${toolName}`);
|
|
68
|
+
return this;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Returns a defensive copy of the accumulated filter strings, suitable for
|
|
72
|
+
* passing as {@link SessionConfigBase.availableTools}.
|
|
73
|
+
*/
|
|
74
|
+
toArray() {
|
|
75
|
+
return [...this.items];
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
const BuiltInTools = {
|
|
79
|
+
/**
|
|
80
|
+
* Built-in tools that operate only within the bounds of a single session —
|
|
81
|
+
* no host filesystem access outside the session, no cross-session state,
|
|
82
|
+
* no host environment access, no network. Safe to enable in `Mode = "empty"`
|
|
83
|
+
* scenarios (e.g. multi-tenant servers) without leaking host capabilities.
|
|
84
|
+
*
|
|
85
|
+
* **Contract:** tools in this set MUST NOT be extended (even behind options
|
|
86
|
+
* or args) to read or write state outside the session boundary. Adding
|
|
87
|
+
* cross-session or host-state behavior to one of these tools is a
|
|
88
|
+
* breaking change that requires removing it from this set.
|
|
89
|
+
*/
|
|
90
|
+
Isolated: [
|
|
91
|
+
"ask_user",
|
|
92
|
+
"task_complete",
|
|
93
|
+
"exit_plan_mode",
|
|
94
|
+
"task",
|
|
95
|
+
"read_agent",
|
|
96
|
+
"write_agent",
|
|
97
|
+
"list_agents",
|
|
98
|
+
"send_inbox",
|
|
99
|
+
"context_board",
|
|
100
|
+
"skill"
|
|
101
|
+
]
|
|
102
|
+
};
|
|
103
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
104
|
+
0 && (module.exports = {
|
|
105
|
+
BuiltInTools,
|
|
106
|
+
ToolSet
|
|
107
|
+
});
|