@github/copilot-sdk 1.0.0-beta.6 → 1.0.0-beta.7

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 CHANGED
@@ -131,10 +131,6 @@ Resume an existing session. Returns the session with `workspacePath` populated i
131
131
 
132
132
  Ping the server to check connectivity.
133
133
 
134
- ##### `getState(): ConnectionState`
135
-
136
- Get current connection state.
137
-
138
134
  ##### `listSessions(filter?: SessionListFilter): Promise<SessionMetadata[]>`
139
135
 
140
136
  List all available sessions. Optionally filter by working directory context.
@@ -573,8 +569,8 @@ The SDK auto-injects environment context, tool instructions, and security guardr
573
569
  Use `mode: "customize"` to selectively override individual sections of the prompt while preserving the rest:
574
570
 
575
571
  ```typescript
576
- import { SYSTEM_PROMPT_SECTIONS } from "@github/copilot-sdk";
577
- import type { SectionOverride, SystemPromptSection } from "@github/copilot-sdk";
572
+ import { SYSTEM_MESSAGE_SECTIONS } from "@github/copilot-sdk";
573
+ import type { SectionOverride, SystemMessageSection } from "@github/copilot-sdk";
578
574
 
579
575
  const session = await client.createSession({
580
576
  model: "gpt-5",
@@ -597,7 +593,7 @@ const session = await client.createSession({
597
593
  });
598
594
  ```
599
595
 
600
- Available section IDs: `identity`, `tone`, `tool_efficiency`, `environment_context`, `code_change_rules`, `guidelines`, `safety`, `tool_instructions`, `custom_instructions`, `last_instructions`. Use the `SYSTEM_PROMPT_SECTIONS` constant for descriptions of each section.
596
+ Available section IDs: `identity`, `tone`, `tool_efficiency`, `environment_context`, `code_change_rules`, `guidelines`, `safety`, `tool_instructions`, `custom_instructions`, `runtime_instructions`, `last_instructions`. Use the `SYSTEM_MESSAGE_SECTIONS` constant for descriptions of each section.
601
597
 
602
598
  Each section override supports four actions:
603
599
 
@@ -0,0 +1,163 @@
1
+ /**
2
+ * Extension-owned canvases declared via
3
+ * `joinSession({ canvases: [createCanvas({...})] })`.
4
+ *
5
+ * The runtime sends provider callbacks directly as `canvas.open`,
6
+ * `canvas.close`, and `canvas.action.invoke` JSON-RPC requests. The SDK
7
+ * routes those requests by `canvasId` to the in-process handlers bound by
8
+ * `createCanvas`. Re-opening with an existing `instanceId` is how the host
9
+ * focuses an existing panel; reload is a renderer-only concern.
10
+ */
11
+ /** JSON Schema object used for canvas inputs. */
12
+ export type CanvasJsonSchema = Record<string, unknown>;
13
+ /**
14
+ * A single agent-callable action contributed by a canvas. The metadata
15
+ * (`name`, `description`, `inputSchema`) is serialized over the wire on
16
+ * `session.create` / `session.resume`; the `handler` closure is stripped
17
+ * before the declaration is sent and dispatched in-process by the SDK.
18
+ *
19
+ * Names MUST NOT start with `canvas.` — that prefix is reserved for
20
+ * lifecycle verbs.
21
+ */
22
+ export interface CanvasAction {
23
+ /** Action identifier, unique within the canvas. */
24
+ name: string;
25
+ /** Description shown to the model when picking an action. */
26
+ description?: string;
27
+ /** Optional JSON Schema for the action's `input` payload. */
28
+ inputSchema?: CanvasJsonSchema;
29
+ /** Required per-action dispatch handler. */
30
+ handler: (ctx: CanvasActionContext) => Promise<unknown> | unknown;
31
+ }
32
+ /**
33
+ * Declarative metadata for a single canvas, serialized over the wire on
34
+ * `session.create` / `session.resume`.
35
+ */
36
+ export interface CanvasDeclaration {
37
+ /** Canvas id, unique within the declaring connection. */
38
+ id: string;
39
+ /** Human-readable label shown in discovery and host UI chrome. */
40
+ displayName: string;
41
+ /** Short, single-sentence description shown to the agent in canvas catalogs. */
42
+ description: string;
43
+ /** Optional JSON Schema for the `input` payload accepted by `canvas.open`. */
44
+ inputSchema?: CanvasJsonSchema;
45
+ /** Agent-invocable actions exposed via `invoke_canvas_action`. */
46
+ actions?: Omit<CanvasAction, "handler">[];
47
+ }
48
+ /** Response returned from `open`. */
49
+ export interface CanvasOpenResponse {
50
+ /** URL the host should render. Optional for native canvases. */
51
+ url?: string;
52
+ /** Provider-supplied title shown in host chrome. */
53
+ title?: string;
54
+ /** Provider-supplied status text shown in host chrome. */
55
+ status?: string;
56
+ }
57
+ /** Host capabilities passed to canvas callbacks. */
58
+ export interface CanvasHostContext {
59
+ capabilities?: {
60
+ canvases?: boolean;
61
+ };
62
+ }
63
+ /** Context handed to a canvas's `open` handler. */
64
+ export interface CanvasOpenContext {
65
+ /** Session that requested the canvas. */
66
+ sessionId: string;
67
+ /** Extension id that owns the canvas. */
68
+ extensionId: string;
69
+ /** Canvas id (matches the declaring `CanvasDeclaration.id`). */
70
+ canvasId: string;
71
+ /** Stable instance id supplied by the runtime. */
72
+ instanceId: string;
73
+ /** Validated `input` payload, shaped by `CanvasDeclaration.inputSchema`. */
74
+ input: unknown;
75
+ /** Host capabilities supplied by the runtime. */
76
+ host?: CanvasHostContext;
77
+ }
78
+ /** Context handed to a canvas action handler. */
79
+ export interface CanvasActionContext {
80
+ /** Session that invoked the action. */
81
+ sessionId: string;
82
+ /** Extension id that owns the canvas. */
83
+ extensionId: string;
84
+ /** Canvas id targeted by the action. */
85
+ canvasId: string;
86
+ /** Instance id targeted by the action. */
87
+ instanceId: string;
88
+ /** Action name from `CanvasAction.name`. */
89
+ actionName: string;
90
+ /** Validated `input` payload, shaped by the action's `inputSchema`. */
91
+ input: unknown;
92
+ /** Host capabilities supplied by the runtime. */
93
+ host?: CanvasHostContext;
94
+ }
95
+ /** Context handed to a canvas's `onClose` handler. */
96
+ export interface CanvasLifecycleContext {
97
+ /** Session owning the canvas instance. */
98
+ sessionId: string;
99
+ /** Extension id that owns the canvas. */
100
+ extensionId: string;
101
+ /** Canvas id (matches the declaring `CanvasDeclaration.id`). */
102
+ canvasId: string;
103
+ /** Instance id this lifecycle event applies to. */
104
+ instanceId: string;
105
+ /** Host capabilities supplied by the runtime. */
106
+ host?: CanvasHostContext;
107
+ }
108
+ /** Structured error returned from canvas handlers. */
109
+ export declare class CanvasError extends Error {
110
+ readonly code: string;
111
+ constructor(code: string, message: string);
112
+ /** Default error when an action is declared but no `handler` is wired. */
113
+ static noHandler(): CanvasError;
114
+ }
115
+ /**
116
+ * Options accepted by {@link createCanvas}. Combines the declarative
117
+ * {@link CanvasDeclaration} fields with the in-process handler closures.
118
+ */
119
+ export interface CanvasOptions {
120
+ /** @see CanvasDeclaration.id */
121
+ id: string;
122
+ /** @see CanvasDeclaration.displayName */
123
+ displayName: string;
124
+ /** @see CanvasDeclaration.description */
125
+ description: string;
126
+ /** @see CanvasDeclaration.inputSchema */
127
+ inputSchema?: CanvasJsonSchema;
128
+ /**
129
+ * Agent-invocable actions exposed via `invoke_canvas_action`. Each action
130
+ * carries its own required `handler`; the action's wire metadata
131
+ * (`name`, `description`, `inputSchema`) is what reaches the runtime.
132
+ */
133
+ actions?: CanvasAction[];
134
+ /** Required. Open a new canvas instance. */
135
+ open: (ctx: CanvasOpenContext) => Promise<CanvasOpenResponse> | CanvasOpenResponse;
136
+ /**
137
+ * Optional. Notified when a canvas instance is closed by the user, the
138
+ * agent, or the host. Fire-and-forget: the return value is ignored and
139
+ * errors are logged but not surfaced to the runtime.
140
+ */
141
+ onClose?: (ctx: CanvasLifecycleContext) => Promise<void> | void;
142
+ }
143
+ /** A registered canvas: declarative metadata + in-process handler closures.
144
+ *
145
+ * Node intentionally uses a per-canvas factory pattern (mirroring
146
+ * {@link https://github.com/github/copilot-sdk | `DefineTool`}'s co-location
147
+ * ergonomics) where other SDKs (Rust, Python, Go, .NET) expose a single
148
+ * `CanvasHandler` per session that switches on `canvasId`. Both shapes target
149
+ * the same JSON-RPC wire protocol; the divergence is API ergonomics only.
150
+ */
151
+ export declare class Canvas {
152
+ readonly declaration: CanvasDeclaration;
153
+ readonly open: NonNullable<CanvasOptions["open"]>;
154
+ readonly onClose?: CanvasOptions["onClose"];
155
+ }
156
+ /** Create a canvas declaration with bound in-process handlers.
157
+ *
158
+ * Node intentionally uses this per-canvas factory pattern (mirroring
159
+ * `DefineTool`'s co-location ergonomics) where other SDKs (Rust, Python, Go,
160
+ * .NET) expose a single `CanvasHandler` per session that switches on
161
+ * `canvasId`. Both shapes target the same JSON-RPC wire protocol.
162
+ */
163
+ export declare function createCanvas(options: CanvasOptions): Canvas;
package/dist/canvas.js ADDED
@@ -0,0 +1,92 @@
1
+ class CanvasError extends Error {
2
+ constructor(code, message) {
3
+ super(message);
4
+ this.code = code;
5
+ this.name = "CanvasError";
6
+ }
7
+ /** Default error when an action is declared but no `handler` is wired. */
8
+ static noHandler() {
9
+ return new CanvasError(
10
+ "canvas_action_no_handler",
11
+ "No handler implemented for this canvas action"
12
+ );
13
+ }
14
+ }
15
+ class Canvas {
16
+ declaration;
17
+ open;
18
+ onClose;
19
+ /** @internal */
20
+ actionHandlers;
21
+ /** @internal */
22
+ constructor(options) {
23
+ const actionHandlers = /* @__PURE__ */ new Map();
24
+ const wireActions = options.actions?.map(
25
+ ({ handler, ...wire }) => {
26
+ actionHandlers.set(wire.name, handler);
27
+ return wire;
28
+ }
29
+ );
30
+ this.declaration = {
31
+ id: options.id,
32
+ displayName: options.displayName,
33
+ description: options.description,
34
+ inputSchema: options.inputSchema,
35
+ actions: wireActions
36
+ };
37
+ this.open = options.open;
38
+ this.onClose = options.onClose;
39
+ this.actionHandlers = actionHandlers;
40
+ }
41
+ }
42
+ function createCanvas(options) {
43
+ return new Canvas(options);
44
+ }
45
+ async function dispatchCanvasProviderRequest(canvas, actionName, params) {
46
+ switch (actionName) {
47
+ case "canvas.open": {
48
+ const result = await canvas.open({
49
+ sessionId: params.sessionId,
50
+ extensionId: params.extensionId,
51
+ canvasId: params.canvasId,
52
+ instanceId: params.instanceId,
53
+ input: params.input,
54
+ host: params.host
55
+ });
56
+ return result ?? {};
57
+ }
58
+ case "canvas.close": {
59
+ if (canvas.onClose) {
60
+ await canvas.onClose({
61
+ sessionId: params.sessionId,
62
+ extensionId: params.extensionId,
63
+ canvasId: params.canvasId,
64
+ instanceId: params.instanceId,
65
+ host: params.host
66
+ });
67
+ }
68
+ return void 0;
69
+ }
70
+ default: {
71
+ const perAction = canvas.actionHandlers.get(actionName);
72
+ if (!perAction) {
73
+ throw CanvasError.noHandler();
74
+ }
75
+ return perAction({
76
+ sessionId: params.sessionId,
77
+ extensionId: params.extensionId,
78
+ canvasId: params.canvasId,
79
+ instanceId: params.instanceId,
80
+ actionName,
81
+ input: params.input,
82
+ host: params.host
83
+ });
84
+ }
85
+ }
86
+ }
87
+ export {
88
+ Canvas,
89
+ CanvasError,
90
+ createCanvas,
91
+ dispatchCanvasProviderRequest
92
+ };
@@ -0,0 +1,119 @@
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 canvas_exports = {};
20
+ __export(canvas_exports, {
21
+ Canvas: () => Canvas,
22
+ CanvasError: () => CanvasError,
23
+ createCanvas: () => createCanvas,
24
+ dispatchCanvasProviderRequest: () => dispatchCanvasProviderRequest
25
+ });
26
+ module.exports = __toCommonJS(canvas_exports);
27
+ class CanvasError extends Error {
28
+ constructor(code, message) {
29
+ super(message);
30
+ this.code = code;
31
+ this.name = "CanvasError";
32
+ }
33
+ /** Default error when an action is declared but no `handler` is wired. */
34
+ static noHandler() {
35
+ return new CanvasError(
36
+ "canvas_action_no_handler",
37
+ "No handler implemented for this canvas action"
38
+ );
39
+ }
40
+ }
41
+ class Canvas {
42
+ declaration;
43
+ open;
44
+ onClose;
45
+ /** @internal */
46
+ actionHandlers;
47
+ /** @internal */
48
+ constructor(options) {
49
+ const actionHandlers = /* @__PURE__ */ new Map();
50
+ const wireActions = options.actions?.map(
51
+ ({ handler, ...wire }) => {
52
+ actionHandlers.set(wire.name, handler);
53
+ return wire;
54
+ }
55
+ );
56
+ this.declaration = {
57
+ id: options.id,
58
+ displayName: options.displayName,
59
+ description: options.description,
60
+ inputSchema: options.inputSchema,
61
+ actions: wireActions
62
+ };
63
+ this.open = options.open;
64
+ this.onClose = options.onClose;
65
+ this.actionHandlers = actionHandlers;
66
+ }
67
+ }
68
+ function createCanvas(options) {
69
+ return new Canvas(options);
70
+ }
71
+ async function dispatchCanvasProviderRequest(canvas, actionName, params) {
72
+ switch (actionName) {
73
+ case "canvas.open": {
74
+ const result = await canvas.open({
75
+ sessionId: params.sessionId,
76
+ extensionId: params.extensionId,
77
+ canvasId: params.canvasId,
78
+ instanceId: params.instanceId,
79
+ input: params.input,
80
+ host: params.host
81
+ });
82
+ return result ?? {};
83
+ }
84
+ case "canvas.close": {
85
+ if (canvas.onClose) {
86
+ await canvas.onClose({
87
+ sessionId: params.sessionId,
88
+ extensionId: params.extensionId,
89
+ canvasId: params.canvasId,
90
+ instanceId: params.instanceId,
91
+ host: params.host
92
+ });
93
+ }
94
+ return void 0;
95
+ }
96
+ default: {
97
+ const perAction = canvas.actionHandlers.get(actionName);
98
+ if (!perAction) {
99
+ throw CanvasError.noHandler();
100
+ }
101
+ return perAction({
102
+ sessionId: params.sessionId,
103
+ extensionId: params.extensionId,
104
+ canvasId: params.canvasId,
105
+ instanceId: params.instanceId,
106
+ actionName,
107
+ input: params.input,
108
+ host: params.host
109
+ });
110
+ }
111
+ }
112
+ }
113
+ // Annotate the CommonJS export names for ESM import in node:
114
+ 0 && (module.exports = {
115
+ Canvas,
116
+ CanvasError,
117
+ createCanvas,
118
+ dispatchCanvasProviderRequest
119
+ });
@@ -30,13 +30,14 @@ var import_node_path = require("node:path");
30
30
  var import_node_url = require("node:url");
31
31
  var import_node = require("vscode-jsonrpc/node.js");
32
32
  var import_rpc = require("./generated/rpc.js");
33
+ var import_canvas = require("./canvas.js");
33
34
  var import_sdkProtocolVersion = require("./sdkProtocolVersion.js");
34
35
  var import_session = require("./session.js");
35
36
  var import_sessionFsProvider = require("./sessionFsProvider.js");
36
37
  var import_telemetry = require("./telemetry.js");
37
38
  var import_types = require("./types.js");
38
39
  const import_meta = {};
39
- const MIN_PROTOCOL_VERSION = 2;
40
+ const MIN_PROTOCOL_VERSION = 3;
40
41
  function isZodSchema(value) {
41
42
  return value != null && typeof value === "object" && "toJSONSchema" in value && typeof value.toJSONSchema === "function";
42
43
  }
@@ -67,6 +68,16 @@ function toWireCustomAgents(agents) {
67
68
  return { ...rest, mcpServers: toWireMcpServers(mcpServers) };
68
69
  });
69
70
  }
71
+ function isCanvasProviderRequestParams(params) {
72
+ if (!params || typeof params !== "object") {
73
+ return false;
74
+ }
75
+ const request = params;
76
+ return typeof request.sessionId === "string" && typeof request.extensionId === "string" && typeof request.canvasId === "string" && typeof request.instanceId === "string";
77
+ }
78
+ function isCanvasActionInvokeParams(params) {
79
+ return isCanvasProviderRequestParams(params) && typeof params.actionName === "string";
80
+ }
70
81
  function extractTransformCallbacks(systemMessage) {
71
82
  if (!systemMessage || systemMessage.mode !== "customize" || !systemMessage.sections) {
72
83
  return { wirePayload: systemMessage, transformCallbacks: void 0 };
@@ -572,6 +583,7 @@ class CopilotClient {
572
583
  this.onGetTraceContext
573
584
  );
574
585
  session.registerTools(config.tools);
586
+ session.registerCanvases(config.canvases);
575
587
  session.registerCommands(config.commands);
576
588
  session.registerPermissionHandler(config.onPermissionRequest);
577
589
  if (config.onUserInputRequest) {
@@ -614,6 +626,10 @@ class CopilotClient {
614
626
  overridesBuiltInTool: tool.overridesBuiltInTool,
615
627
  skipPermission: tool.skipPermission
616
628
  })),
629
+ canvases: config.canvases?.map((canvas) => canvas.declaration),
630
+ requestCanvasRenderer: config.requestCanvasRenderer,
631
+ requestExtensions: config.requestExtensions,
632
+ extensionInfo: config.extensionInfo,
617
633
  commands: config.commands?.map((cmd) => ({
618
634
  name: cmd.name,
619
635
  description: cmd.description
@@ -624,7 +640,7 @@ class CopilotClient {
624
640
  provider: config.provider,
625
641
  enableSessionTelemetry: config.enableSessionTelemetry,
626
642
  modelCapabilities: config.modelCapabilities,
627
- requestPermission: true,
643
+ requestPermission: !!config.onPermissionRequest,
628
644
  requestUserInput: !!config.onUserInputRequest,
629
645
  requestElicitation: !!config.onElicitationRequest,
630
646
  requestExitPlanMode: !!config.onExitPlanModeRequest,
@@ -692,6 +708,7 @@ class CopilotClient {
692
708
  this.onGetTraceContext
693
709
  );
694
710
  session.registerTools(config.tools);
711
+ session.registerCanvases(config.canvases);
695
712
  session.registerCommands(config.commands);
696
713
  session.registerPermissionHandler(config.onPermissionRequest);
697
714
  if (config.onUserInputRequest) {
@@ -738,6 +755,10 @@ class CopilotClient {
738
755
  overridesBuiltInTool: tool.overridesBuiltInTool,
739
756
  skipPermission: tool.skipPermission
740
757
  })),
758
+ canvases: config.canvases?.map((canvas) => canvas.declaration),
759
+ requestCanvasRenderer: config.requestCanvasRenderer,
760
+ requestExtensions: config.requestExtensions,
761
+ extensionInfo: config.extensionInfo,
741
762
  commands: config.commands?.map((cmd) => ({
742
763
  name: cmd.name,
743
764
  description: cmd.description
@@ -767,32 +788,19 @@ class CopilotClient {
767
788
  suppressResumeEvent: config.suppressResumeEvent,
768
789
  continuePendingWork: config.continuePendingWork,
769
790
  gitHubToken: config.gitHubToken,
770
- remoteSession: config.remoteSession
791
+ remoteSession: config.remoteSession,
792
+ openCanvases: config.openCanvases
771
793
  });
772
- const { workspacePath, capabilities } = response;
794
+ const { workspacePath, capabilities, openCanvases } = response;
773
795
  session["_workspacePath"] = workspacePath;
774
796
  session.setCapabilities(capabilities);
797
+ session.setOpenCanvases(openCanvases ?? []);
775
798
  } catch (e) {
776
799
  this.sessions.delete(sessionId);
777
800
  throw e;
778
801
  }
779
802
  return session;
780
803
  }
781
- /**
782
- * Gets the current connection state of the client.
783
- *
784
- * @returns The current connection state: "disconnected", "connecting", "connected", or "error"
785
- *
786
- * @example
787
- * ```typescript
788
- * if (client.getState() === "connected") {
789
- * const session = await client.createSession({ onPermissionRequest: approveAll });
790
- * }
791
- * ```
792
- */
793
- getState() {
794
- return this.state;
795
- }
796
804
  /**
797
805
  * Sends a ping request to the server to verify connectivity.
798
806
  *
@@ -1381,14 +1389,6 @@ stderr: ${stderrOutput}`
1381
1389
  this.connection.onNotification("session.lifecycle", (notification) => {
1382
1390
  this.handleSessionLifecycleNotification(notification);
1383
1391
  });
1384
- this.connection.onRequest(
1385
- "tool.call",
1386
- async (params) => await this.handleToolCallRequestV2(params)
1387
- );
1388
- this.connection.onRequest(
1389
- "permission.request",
1390
- async (params) => await this.handlePermissionRequestV2(params)
1391
- );
1392
1392
  this.connection.onRequest(
1393
1393
  "userInput.request",
1394
1394
  async (params) => await this.handleUserInputRequest(params)
@@ -1409,6 +1409,18 @@ stderr: ${stderrOutput}`
1409
1409
  "systemMessage.transform",
1410
1410
  async (params) => await this.handleSystemMessageTransform(params)
1411
1411
  );
1412
+ this.connection.onRequest(
1413
+ "canvas.open",
1414
+ async (params) => this.handleCanvasProviderRequest("canvas.open", params)
1415
+ );
1416
+ this.connection.onRequest(
1417
+ "canvas.close",
1418
+ async (params) => this.handleCanvasProviderRequest("canvas.close", params)
1419
+ );
1420
+ this.connection.onRequest(
1421
+ "canvas.action.invoke",
1422
+ async (params) => this.handleCanvasActionInvokeRequest(params)
1423
+ );
1412
1424
  const sessions = this.sessions;
1413
1425
  (0, import_rpc.registerClientSessionApiHandlers)(this.connection, (sessionId) => {
1414
1426
  const session = sessions.get(sessionId);
@@ -1530,104 +1542,25 @@ stderr: ${stderrOutput}`
1530
1542
  }
1531
1543
  return await session._handleSystemMessageTransform(params.sections);
1532
1544
  }
1533
- // ========================================================================
1534
- // Protocol v2 backward-compatibility adapters
1535
- // ========================================================================
1536
- /**
1537
- * Handles a v2-style tool.call RPC request from the server.
1538
- * Looks up the session and tool handler, executes it, and returns the result
1539
- * in the v2 response format.
1540
- */
1541
- async handleToolCallRequestV2(params) {
1542
- if (!params || typeof params.sessionId !== "string" || typeof params.toolCallId !== "string" || typeof params.toolName !== "string") {
1543
- throw new Error("Invalid tool call payload");
1544
- }
1545
- const session = this.sessions.get(params.sessionId);
1546
- if (!session) {
1547
- throw new Error(`Unknown session ${params.sessionId}`);
1548
- }
1549
- const handler = session.getToolHandler(params.toolName);
1550
- if (!handler) {
1551
- return {
1552
- result: {
1553
- textResultForLlm: `Tool '${params.toolName}' is not supported by this client instance.`,
1554
- resultType: "failure",
1555
- error: `tool '${params.toolName}' not supported`,
1556
- toolTelemetry: {}
1557
- }
1558
- };
1559
- }
1560
- try {
1561
- const traceparent = params.traceparent;
1562
- const tracestate = params.tracestate;
1563
- const invocation = {
1564
- sessionId: params.sessionId,
1565
- toolCallId: params.toolCallId,
1566
- toolName: params.toolName,
1567
- arguments: params.arguments,
1568
- traceparent,
1569
- tracestate
1570
- };
1571
- const result = await handler(params.arguments, invocation);
1572
- return { result: this.normalizeToolResultV2(result) };
1573
- } catch (error) {
1574
- const message = error instanceof Error ? error.message : String(error);
1575
- return {
1576
- result: {
1577
- textResultForLlm: "Invoking this tool produced an error. Detailed information is not available.",
1578
- resultType: "failure",
1579
- error: message,
1580
- toolTelemetry: {}
1581
- }
1582
- };
1583
- }
1584
- }
1585
- /**
1586
- * Handles a v2-style permission.request RPC request from the server.
1587
- */
1588
- async handlePermissionRequestV2(params) {
1589
- if (!params || typeof params.sessionId !== "string" || !params.permissionRequest) {
1590
- throw new Error("Invalid permission request payload");
1545
+ async handleCanvasProviderRequest(actionName, params) {
1546
+ if (!isCanvasProviderRequestParams(params)) {
1547
+ throw new Error("Invalid canvas provider request payload");
1591
1548
  }
1592
1549
  const session = this.sessions.get(params.sessionId);
1593
1550
  if (!session) {
1594
1551
  throw new Error(`Session not found: ${params.sessionId}`);
1595
1552
  }
1596
- try {
1597
- const result = await session._handlePermissionRequestV2(params.permissionRequest);
1598
- return { result };
1599
- } catch (error) {
1600
- if (error instanceof Error && error.message === import_session.NO_RESULT_PERMISSION_V2_ERROR) {
1601
- throw error;
1602
- }
1603
- return {
1604
- result: {
1605
- kind: "user-not-available"
1606
- }
1607
- };
1553
+ const canvas = session.getCanvas(params.canvasId);
1554
+ if (!canvas) {
1555
+ throw new Error(`No canvas registered with id "${params.canvasId}"`);
1608
1556
  }
1557
+ return (0, import_canvas.dispatchCanvasProviderRequest)(canvas, actionName, params);
1609
1558
  }
1610
- normalizeToolResultV2(result) {
1611
- if (result === void 0 || result === null) {
1612
- return {
1613
- textResultForLlm: "Tool returned no result",
1614
- resultType: "failure",
1615
- error: "tool returned no result",
1616
- toolTelemetry: {}
1617
- };
1618
- }
1619
- if (this.isToolResultObject(result)) {
1620
- return result;
1559
+ async handleCanvasActionInvokeRequest(params) {
1560
+ if (!isCanvasActionInvokeParams(params)) {
1561
+ throw new Error("Invalid canvas provider request payload");
1621
1562
  }
1622
- const textResult = typeof result === "string" ? result : JSON.stringify(result);
1623
- return {
1624
- textResultForLlm: textResult,
1625
- resultType: "success",
1626
- toolTelemetry: {}
1627
- };
1628
- }
1629
- isToolResultObject(value) {
1630
- return typeof value === "object" && value !== null && "textResultForLlm" in value && typeof value.textResultForLlm === "string" && "resultType" in value;
1563
+ return this.handleCanvasProviderRequest(params.actionName, params);
1631
1564
  }
1632
1565
  }
1633
1566
  // Annotate the CommonJS export names for ESM import in node:
@@ -18,11 +18,15 @@ var __copyProps = (to, from, except, desc) => {
18
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
19
  var extension_exports = {};
20
20
  __export(extension_exports, {
21
+ Canvas: () => import_canvas.Canvas,
22
+ CanvasError: () => import_canvas.CanvasError,
23
+ createCanvas: () => import_canvas.createCanvas,
21
24
  joinSession: () => joinSession
22
25
  });
23
26
  module.exports = __toCommonJS(extension_exports);
24
27
  var import_client = require("./client.js");
25
28
  var import_types = require("./types.js");
29
+ var import_canvas = require("./canvas.js");
26
30
  async function joinSession(config = {}) {
27
31
  const sessionId = process.env.SESSION_ID;
28
32
  if (!sessionId) {
@@ -39,5 +43,8 @@ async function joinSession(config = {}) {
39
43
  }
40
44
  // Annotate the CommonJS export names for ESM import in node:
41
45
  0 && (module.exports = {
46
+ Canvas,
47
+ CanvasError,
48
+ createCanvas,
42
49
  joinSession
43
50
  });