Skip to content

Commit 7655d0b

Browse files
jmoseleyCopilot
andcommitted
Fix Node SDK host extension envelope shape
handleHostExtensionInvoke was returning JSON-RPC-style {id, result} / {id, error}, but runtime expects HostedExtensionResponse envelope {ok: true, result} / {ok: false, error} per protocol/types.ts. This caused all extension-provided canvases to fail with canvas_invoke_malformed_response after the runtime added its defensive guard. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 098b6c9 commit 7655d0b

1 file changed

Lines changed: 8 additions & 5 deletions

File tree

nodejs/src/client.ts

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2061,15 +2061,15 @@ export class CopilotClient {
20612061
private async handleHostExtensionInvoke(params: {
20622062
sessionId: string;
20632063
request: { id?: string; method: string; params?: unknown };
2064-
}): Promise<{ id?: string; result?: unknown; error?: CanvasError }> {
2064+
}): Promise<{ ok: true; result: unknown } | { ok: false; error: CanvasError }> {
20652065
if (!params || typeof params.sessionId !== "string" || !params.request) {
20662066
throw new Error("Invalid hostExtension.invoke payload");
20672067
}
20682068
const session = this.sessions.get(params.sessionId);
20692069
if (!session) {
20702070
throw new Error(`Session not found: ${params.sessionId}`);
20712071
}
2072-
const { id, method, params: inner } = params.request;
2072+
const { method, params: inner } = params.request;
20732073
// Canvas V1.1: only `canvas.action.invoke` is in use. Other inner methods
20742074
// are dead in the V1.1 cutover; reject explicitly so misrouted calls
20752075
// don't silently no-op.
@@ -2083,7 +2083,7 @@ export class CopilotClient {
20832083
const canvas = session.getCanvas(actionParams.canvasId);
20842084
if (!canvas) {
20852085
return {
2086-
id,
2086+
ok: false,
20872087
error: {
20882088
code: "canvas_not_found",
20892089
message: `No canvas registered with id "${actionParams.canvasId}"`,
@@ -2093,11 +2093,14 @@ export class CopilotClient {
20932093
}
20942094
try {
20952095
const result = await dispatchCanvasAction(canvas, params.sessionId, actionParams);
2096-
return { id, result };
2096+
return { ok: true, result };
20972097
} catch (e) {
20982098
if (e && typeof e === "object" && "code" in e && "message" in e) {
20992099
const ce = e as CanvasError;
2100-
return { id, error: { code: ce.code, message: ce.message, name: ce.name } };
2100+
return {
2101+
ok: false,
2102+
error: { code: ce.code, message: ce.message, name: ce.name } as CanvasError,
2103+
};
21012104
}
21022105
throw e;
21032106
}

0 commit comments

Comments
 (0)