Summary
In docs/integrations/microsoft-agent-framework.md, the "Node.js / TypeScript (standalone SDK)" example under Streaming responses registers an assistant.message_delta handler that reads event.data.delta:
session.on("assistant.message_delta", (event) => {
process.stdout.write(event.data.delta ?? "");
});
The payload type for that event declares deltaContent, not delta. AssistantMessageDeltaData in nodejs/src/generated/session-events.ts has exactly three members:
export interface AssistantMessageDeltaData {
deltaContent: string;
messageId: string;
parentToolCallId?: string;
}
So event.data.delta evaluates to undefined, the ?? "" fallback turns that into an empty string, and the handler writes nothing for each delta event. Someone copying this example sees no streamed output.
Reproduction
Against the published package (@github/copilot-sdk@1.0.8), in an ESM project. This is an instrumented version of the documented handler, not the doc block verbatim: it accumulates both the documented accessor and deltaContent side by side so the difference is visible, and it uses a deny-all permission handler and a one-word prompt.
import { CopilotClient } from "@github/copilot-sdk";
const client = new CopilotClient();
const session = await client.createSession({
streaming: true,
onPermissionRequest: async () => ({ kind: "reject" }),
});
let asDocumented = "";
let actual = "";
let keys = null;
session.on("assistant.message_delta", (event) => {
keys ??= Object.keys(event.data);
asDocumented += event.data.delta ?? "";
actual += event.data.deltaContent ?? "";
});
await session.sendAndWait({ prompt: "Reply with exactly one word: pong" });
console.log("payload keys: ", JSON.stringify(keys));
console.log("event.data.delta: ", JSON.stringify(asDocumented));
console.log("event.data.deltaContent:", JSON.stringify(actual));
await client.stop();
process.exit(0);
Output:
payload keys: ["messageId","deltaContent"]
event.data.delta: ""
event.data.deltaContent: "pong"
The behaviour is not model-specific; model is omitted here so the session uses the default.
Expected
The example writes the streamed text, as the equivalent examples elsewhere in the docs do.
Notes
deltaContent is the accessor used consistently everywhere else:
- The Java example in the same "Streaming responses" section of the same guide calls
event.getData().deltaContent().
docs/features/streaming-events.md and docs/getting-started.md use event.data.deltaContent in their TypeScript snippets, event.data.delta_content in Python, and deltaContent in Rust and Java.
- The event reference table in
docs/features/streaming-events.md lists messageId and deltaContent as the fields of assistant.message_delta.
- The generated types agree across bindings:
deltaContent in Node.js, DeltaContent/deltaContent in Go, .NET and Java, and delta_content (deserialised from deltaContent) in Python.
event.data.delta appears exactly once in the repository, on this line.
The fix is a one-token change on that line.
Summary
In
docs/integrations/microsoft-agent-framework.md, the "Node.js / TypeScript (standalone SDK)" example under Streaming responses registers anassistant.message_deltahandler that readsevent.data.delta:The payload type for that event declares
deltaContent, notdelta.AssistantMessageDeltaDatainnodejs/src/generated/session-events.tshas exactly three members:So
event.data.deltaevaluates toundefined, the?? ""fallback turns that into an empty string, and the handler writes nothing for each delta event. Someone copying this example sees no streamed output.Reproduction
Against the published package (
@github/copilot-sdk@1.0.8), in an ESM project. This is an instrumented version of the documented handler, not the doc block verbatim: it accumulates both the documented accessor anddeltaContentside by side so the difference is visible, and it uses a deny-all permission handler and a one-word prompt.Output:
The behaviour is not model-specific;
modelis omitted here so the session uses the default.Expected
The example writes the streamed text, as the equivalent examples elsewhere in the docs do.
Notes
deltaContentis the accessor used consistently everywhere else:event.getData().deltaContent().docs/features/streaming-events.mdanddocs/getting-started.mduseevent.data.deltaContentin their TypeScript snippets,event.data.delta_contentin Python, anddeltaContentin Rust and Java.docs/features/streaming-events.mdlistsmessageIdanddeltaContentas the fields ofassistant.message_delta.deltaContentin Node.js,DeltaContent/deltaContentin Go, .NET and Java, anddelta_content(deserialised fromdeltaContent) in Python.event.data.deltaappears exactly once in the repository, on this line.The fix is a one-token change on that line.