assistant-stream 0.2.25 → 0.2.27

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.
@@ -1 +1 @@
1
- {"version":3,"file":"assistant-message-accumulator.d.ts","sourceRoot":"","sources":["../../../src/core/accumulators/assistant-message-accumulator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAG/D,OAAO,EACL,gBAAgB,EAQjB,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAEhD,eAAO,MAAM,oBAAoB,GAAI,sBAElC;IACD,cAAc,CAAC,EAAE,iBAAiB,CAAC;CAC/B,KAAG,gBAcP,CAAC;AAmUH,qBAAa,2BAA4B,SAAQ,eAAe,CAC9D,oBAAoB,EACpB,gBAAgB,CACjB;gBACa,EACV,cAAc,GACf,GAAE;QACD,cAAc,CAAC,EAAE,gBAAgB,CAAC;KAC9B;CA4EP"}
1
+ {"version":3,"file":"assistant-message-accumulator.d.ts","sourceRoot":"","sources":["../../../src/core/accumulators/assistant-message-accumulator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAG/D,OAAO,EACL,gBAAgB,EAQjB,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAEhD,eAAO,MAAM,oBAAoB,GAAI,sBAElC;IACD,cAAc,CAAC,EAAE,iBAAiB,CAAC;CAC/B,KAAG,gBAcP,CAAC;AA+UH,qBAAa,2BAA4B,SAAQ,eAAe,CAC9D,oBAAoB,EACpB,gBAAgB,CACjB;gBACa,EACV,cAAc,GACf,GAAE;QACD,cAAc,CAAC,EAAE,gBAAgB,CAAC;KAC9B;CAqFP"}
@@ -258,13 +258,31 @@ var handleUpdateState = (message, chunk) => {
258
258
  }
259
259
  };
260
260
  };
261
+ var throttleCallback = (callback) => {
262
+ let hasScheduled = false;
263
+ return () => {
264
+ if (hasScheduled) return;
265
+ hasScheduled = true;
266
+ queueMicrotask(() => {
267
+ hasScheduled = false;
268
+ callback();
269
+ });
270
+ };
271
+ };
261
272
  var AssistantMessageAccumulator = class extends TransformStream {
262
273
  constructor({
263
274
  initialMessage
264
275
  } = {}) {
265
276
  let message = initialMessage ?? createInitialMessage();
277
+ let controller;
278
+ const emitChunk = throttleCallback(() => {
279
+ controller?.enqueue(message);
280
+ });
266
281
  super({
267
- transform(chunk, controller) {
282
+ start(c) {
283
+ controller = c;
284
+ },
285
+ transform(chunk) {
268
286
  const type = chunk.type;
269
287
  switch (type) {
270
288
  case "part-start":
@@ -308,9 +326,9 @@ var AssistantMessageAccumulator = class extends TransformStream {
308
326
  throw new Error(`Unsupported chunk type: ${unhandledType}`);
309
327
  }
310
328
  }
311
- controller.enqueue(message);
329
+ emitChunk();
312
330
  },
313
- flush(controller) {
331
+ flush(controller2) {
314
332
  if (message.status?.type === "running") {
315
333
  const requiresAction = message.parts?.some(
316
334
  (part) => part.type === "tool-call" && (part.state === "call" || part.state === "partial-call") && part.result === void 0
@@ -324,7 +342,7 @@ var AssistantMessageAccumulator = class extends TransformStream {
324
342
  completionTokens: 0
325
343
  }
326
344
  });
327
- controller.enqueue(message);
345
+ controller2.enqueue(message);
328
346
  }
329
347
  }
330
348
  });
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/core/accumulators/assistant-message-accumulator.ts"],"sourcesContent":["import { AssistantStreamChunk } from \"../AssistantStreamChunk\";\nimport { generateId } from \"../utils/generateId\";\nimport { parsePartialJsonObject } from \"../../utils/json/parse-partial-json-object\";\nimport {\n AssistantMessage,\n AssistantMessageStatus,\n TextPart,\n ToolCallPart,\n SourcePart,\n AssistantMessagePart,\n ReasoningPart,\n FilePart,\n} from \"../utils/types\";\nimport { ObjectStreamAccumulator } from \"../object/ObjectStreamAccumulator\";\nimport { ReadonlyJSONValue } from \"../../utils\";\n\nexport const createInitialMessage = ({\n unstable_state = null,\n}: {\n unstable_state?: ReadonlyJSONValue;\n} = {}): AssistantMessage => ({\n role: \"assistant\",\n status: { type: \"running\" },\n parts: [],\n get content() {\n return this.parts;\n },\n metadata: {\n unstable_state,\n unstable_data: [],\n unstable_annotations: [],\n steps: [],\n custom: {},\n },\n});\n\nconst updatePartForPath = (\n message: AssistantMessage,\n chunk: AssistantStreamChunk,\n updater: (part: AssistantMessagePart) => AssistantMessagePart,\n): AssistantMessage => {\n if (message.parts.length === 0) {\n throw new Error(\"No parts available to update.\");\n }\n\n if (chunk.path.length !== 1)\n throw new Error(\"Nested paths are not supported yet.\");\n\n const partIndex = chunk.path[0]!;\n const updatedPart = updater(message.parts[partIndex]!);\n return {\n ...message,\n parts: [\n ...message.parts.slice(0, partIndex),\n updatedPart,\n ...message.parts.slice(partIndex + 1),\n ],\n get content() {\n return this.parts;\n },\n };\n};\n\nconst handlePartStart = (\n message: AssistantMessage,\n chunk: AssistantStreamChunk & { readonly type: \"part-start\" },\n): AssistantMessage => {\n const partInit = chunk.part;\n if (partInit.type === \"text\" || partInit.type === \"reasoning\") {\n const newTextPart: TextPart | ReasoningPart = {\n type: partInit.type,\n text: \"\",\n status: { type: \"running\" },\n ...(partInit.parentId && { parentId: partInit.parentId }),\n };\n return {\n ...message,\n parts: [...message.parts, newTextPart],\n get content() {\n return this.parts;\n },\n };\n } else if (partInit.type === \"tool-call\") {\n const newToolCallPart: ToolCallPart = {\n type: \"tool-call\",\n state: \"partial-call\",\n status: { type: \"running\", isArgsComplete: false },\n toolCallId: partInit.toolCallId,\n toolName: partInit.toolName,\n argsText: \"\",\n args: {},\n ...(partInit.parentId && { parentId: partInit.parentId }),\n };\n return {\n ...message,\n parts: [...message.parts, newToolCallPart],\n get content() {\n return this.parts;\n },\n };\n } else if (partInit.type === \"source\") {\n const newSourcePart: SourcePart = {\n type: \"source\",\n sourceType: partInit.sourceType,\n id: partInit.id,\n url: partInit.url,\n ...(partInit.title ? { title: partInit.title } : undefined),\n ...(partInit.parentId && { parentId: partInit.parentId }),\n };\n return {\n ...message,\n parts: [...message.parts, newSourcePart],\n get content() {\n return this.parts;\n },\n };\n } else if (partInit.type === \"file\") {\n const newFilePart: FilePart = {\n type: \"file\",\n mimeType: partInit.mimeType,\n data: partInit.data,\n };\n return {\n ...message,\n parts: [...message.parts, newFilePart],\n get content() {\n return this.parts;\n },\n };\n } else {\n throw new Error(`Unsupported part type: ${partInit.type}`);\n }\n};\n\nconst handleToolCallArgsTextFinish = (\n message: AssistantMessage,\n chunk: AssistantStreamChunk & {\n readonly type: \"tool-call-args-text-finish\";\n },\n): AssistantMessage => {\n return updatePartForPath(message, chunk, (part) => {\n if (part.type !== \"tool-call\") {\n throw new Error(\"Last is not a tool call\");\n }\n\n // TODO this should never be hit; this happens if args-text-finish is emitted after resutl\n if (part.state !== \"partial-call\") return part;\n // throw new Error(\"Last is not a partial call\");\n\n return {\n ...part,\n state: \"call\",\n };\n });\n};\n\nconst handlePartFinish = (\n message: AssistantMessage,\n chunk: AssistantStreamChunk & { readonly type: \"part-finish\" },\n): AssistantMessage => {\n return updatePartForPath(message, chunk, (part) => ({\n ...part,\n status: { type: \"complete\", reason: \"unknown\" },\n }));\n};\n\nconst handleTextDelta = (\n message: AssistantMessage,\n chunk: AssistantStreamChunk & { type: \"text-delta\" },\n): AssistantMessage => {\n return updatePartForPath(message, chunk, (part) => {\n if (part.type === \"text\" || part.type === \"reasoning\") {\n return { ...part, text: part.text + chunk.textDelta };\n } else if (part.type === \"tool-call\") {\n const newArgsText = part.argsText + chunk.textDelta;\n\n // Fall back to existing args if parsing fails\n const newArgs = parsePartialJsonObject(newArgsText) ?? part.args;\n\n return { ...part, argsText: newArgsText, args: newArgs };\n } else {\n throw new Error(\n \"text-delta received but part is neither text nor tool-call\",\n );\n }\n });\n};\n\nconst handleResult = (\n message: AssistantMessage,\n chunk: AssistantStreamChunk & { type: \"result\" },\n): AssistantMessage => {\n return updatePartForPath(message, chunk, (part) => {\n if (part.type === \"tool-call\") {\n return {\n ...part,\n state: \"result\",\n ...(chunk.artifact !== undefined ? { artifact: chunk.artifact } : {}),\n result: chunk.result,\n isError: chunk.isError ?? false,\n status: { type: \"complete\", reason: \"stop\" },\n };\n } else {\n throw new Error(\"Result chunk received but part is not a tool-call\");\n }\n });\n};\n\nconst handleMessageFinish = (\n message: AssistantMessage,\n chunk: AssistantStreamChunk & { type: \"message-finish\" },\n): AssistantMessage => {\n // avoid edge case where providers send finish chunks that overwrite message error status (issue #2181)\n if (\n message.status?.type === \"incomplete\" &&\n message.status?.reason === \"error\"\n ) {\n return message;\n }\n\n const newStatus = getStatus(chunk);\n return { ...message, status: newStatus };\n};\n\nconst getStatus = (\n chunk:\n | (AssistantStreamChunk & { type: \"message-finish\" })\n | (AssistantStreamChunk & { type: \"step-finish\" }),\n): AssistantMessageStatus => {\n if (chunk.finishReason === \"tool-calls\") {\n return {\n type: \"requires-action\",\n reason: \"tool-calls\",\n };\n } else if (\n chunk.finishReason === \"stop\" ||\n chunk.finishReason === \"unknown\"\n ) {\n return {\n type: \"complete\",\n reason: chunk.finishReason,\n };\n } else {\n return {\n type: \"incomplete\",\n reason: chunk.finishReason,\n };\n }\n};\n\nconst handleAnnotations = (\n message: AssistantMessage,\n chunk: AssistantStreamChunk & { type: \"annotations\" },\n): AssistantMessage => {\n return {\n ...message,\n metadata: {\n ...message.metadata,\n unstable_annotations: [\n ...message.metadata.unstable_annotations,\n ...chunk.annotations,\n ],\n },\n };\n};\n\nconst handleData = (\n message: AssistantMessage,\n chunk: AssistantStreamChunk & { type: \"data\" },\n): AssistantMessage => {\n return {\n ...message,\n metadata: {\n ...message.metadata,\n unstable_data: [...message.metadata.unstable_data, ...chunk.data],\n },\n };\n};\n\nconst handleStepStart = (\n message: AssistantMessage,\n chunk: AssistantStreamChunk & { type: \"step-start\" },\n): AssistantMessage => {\n return {\n ...message,\n metadata: {\n ...message.metadata,\n steps: [\n ...message.metadata.steps,\n { state: \"started\", messageId: chunk.messageId },\n ],\n },\n };\n};\n\nconst handleStepFinish = (\n message: AssistantMessage,\n chunk: AssistantStreamChunk & { type: \"step-finish\" },\n): AssistantMessage => {\n const steps = message.metadata.steps.slice();\n const lastIndex = steps.length - 1;\n\n // Check if the previous step is a step-start (has state \"started\")\n if (steps.length > 0 && steps[lastIndex]?.state === \"started\") {\n steps[lastIndex] = {\n ...steps[lastIndex],\n state: \"finished\",\n finishReason: chunk.finishReason,\n usage: chunk.usage,\n isContinued: chunk.isContinued,\n };\n } else {\n // If no previous step-start exists, append a finished step\n steps.push({\n state: \"finished\",\n messageId: generateId(),\n finishReason: chunk.finishReason,\n usage: chunk.usage,\n isContinued: chunk.isContinued,\n });\n }\n\n return {\n ...message,\n metadata: {\n ...message.metadata,\n steps,\n },\n };\n};\n\nconst handleErrorChunk = (\n message: AssistantMessage,\n chunk: AssistantStreamChunk & { type: \"error\" },\n): AssistantMessage => {\n return {\n ...message,\n status: { type: \"incomplete\", reason: \"error\", error: chunk.error },\n };\n};\n\nconst handleUpdateState = (\n message: AssistantMessage,\n chunk: AssistantStreamChunk & { type: \"update-state\" },\n): AssistantMessage => {\n const acc = new ObjectStreamAccumulator(message.metadata.unstable_state);\n acc.append(chunk.operations);\n\n return {\n ...message,\n metadata: {\n ...message.metadata,\n unstable_state: acc.state,\n },\n };\n};\n\nexport class AssistantMessageAccumulator extends TransformStream<\n AssistantStreamChunk,\n AssistantMessage\n> {\n constructor({\n initialMessage,\n }: {\n initialMessage?: AssistantMessage;\n } = {}) {\n let message = initialMessage ?? createInitialMessage();\n super({\n transform(chunk, controller) {\n const type = chunk.type;\n switch (type) {\n case \"part-start\":\n message = handlePartStart(message, chunk);\n break;\n\n case \"tool-call-args-text-finish\":\n message = handleToolCallArgsTextFinish(message, chunk);\n break;\n\n case \"part-finish\":\n message = handlePartFinish(message, chunk);\n break;\n\n case \"text-delta\":\n message = handleTextDelta(message, chunk);\n break;\n case \"result\":\n message = handleResult(message, chunk);\n break;\n case \"message-finish\":\n message = handleMessageFinish(message, chunk);\n break;\n case \"annotations\":\n message = handleAnnotations(message, chunk);\n break;\n case \"data\":\n message = handleData(message, chunk);\n break;\n case \"step-start\":\n message = handleStepStart(message, chunk);\n break;\n case \"step-finish\":\n message = handleStepFinish(message, chunk);\n break;\n case \"error\":\n message = handleErrorChunk(message, chunk);\n break;\n case \"update-state\":\n message = handleUpdateState(message, chunk);\n break;\n default: {\n const unhandledType: never = type;\n throw new Error(`Unsupported chunk type: ${unhandledType}`);\n }\n }\n controller.enqueue(message);\n },\n flush(controller) {\n if (message.status?.type === \"running\") {\n // Check if there are any tool calls that require action\n const requiresAction =\n message.parts?.some(\n (part) =>\n part.type === \"tool-call\" &&\n (part.state === \"call\" || part.state === \"partial-call\") &&\n part.result === undefined,\n ) ?? false;\n message = handleMessageFinish(message, {\n type: \"message-finish\",\n path: [],\n finishReason: requiresAction ? \"tool-calls\" : \"unknown\",\n usage: {\n promptTokens: 0,\n completionTokens: 0,\n },\n });\n controller.enqueue(message);\n }\n },\n });\n }\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../src/core/accumulators/assistant-message-accumulator.ts"],"sourcesContent":["import { AssistantStreamChunk } from \"../AssistantStreamChunk\";\nimport { generateId } from \"../utils/generateId\";\nimport { parsePartialJsonObject } from \"../../utils/json/parse-partial-json-object\";\nimport {\n AssistantMessage,\n AssistantMessageStatus,\n TextPart,\n ToolCallPart,\n SourcePart,\n AssistantMessagePart,\n ReasoningPart,\n FilePart,\n} from \"../utils/types\";\nimport { ObjectStreamAccumulator } from \"../object/ObjectStreamAccumulator\";\nimport { ReadonlyJSONValue } from \"../../utils\";\n\nexport const createInitialMessage = ({\n unstable_state = null,\n}: {\n unstable_state?: ReadonlyJSONValue;\n} = {}): AssistantMessage => ({\n role: \"assistant\",\n status: { type: \"running\" },\n parts: [],\n get content() {\n return this.parts;\n },\n metadata: {\n unstable_state,\n unstable_data: [],\n unstable_annotations: [],\n steps: [],\n custom: {},\n },\n});\n\nconst updatePartForPath = (\n message: AssistantMessage,\n chunk: AssistantStreamChunk,\n updater: (part: AssistantMessagePart) => AssistantMessagePart,\n): AssistantMessage => {\n if (message.parts.length === 0) {\n throw new Error(\"No parts available to update.\");\n }\n\n if (chunk.path.length !== 1)\n throw new Error(\"Nested paths are not supported yet.\");\n\n const partIndex = chunk.path[0]!;\n const updatedPart = updater(message.parts[partIndex]!);\n return {\n ...message,\n parts: [\n ...message.parts.slice(0, partIndex),\n updatedPart,\n ...message.parts.slice(partIndex + 1),\n ],\n get content() {\n return this.parts;\n },\n };\n};\n\nconst handlePartStart = (\n message: AssistantMessage,\n chunk: AssistantStreamChunk & { readonly type: \"part-start\" },\n): AssistantMessage => {\n const partInit = chunk.part;\n if (partInit.type === \"text\" || partInit.type === \"reasoning\") {\n const newTextPart: TextPart | ReasoningPart = {\n type: partInit.type,\n text: \"\",\n status: { type: \"running\" },\n ...(partInit.parentId && { parentId: partInit.parentId }),\n };\n return {\n ...message,\n parts: [...message.parts, newTextPart],\n get content() {\n return this.parts;\n },\n };\n } else if (partInit.type === \"tool-call\") {\n const newToolCallPart: ToolCallPart = {\n type: \"tool-call\",\n state: \"partial-call\",\n status: { type: \"running\", isArgsComplete: false },\n toolCallId: partInit.toolCallId,\n toolName: partInit.toolName,\n argsText: \"\",\n args: {},\n ...(partInit.parentId && { parentId: partInit.parentId }),\n };\n return {\n ...message,\n parts: [...message.parts, newToolCallPart],\n get content() {\n return this.parts;\n },\n };\n } else if (partInit.type === \"source\") {\n const newSourcePart: SourcePart = {\n type: \"source\",\n sourceType: partInit.sourceType,\n id: partInit.id,\n url: partInit.url,\n ...(partInit.title ? { title: partInit.title } : undefined),\n ...(partInit.parentId && { parentId: partInit.parentId }),\n };\n return {\n ...message,\n parts: [...message.parts, newSourcePart],\n get content() {\n return this.parts;\n },\n };\n } else if (partInit.type === \"file\") {\n const newFilePart: FilePart = {\n type: \"file\",\n mimeType: partInit.mimeType,\n data: partInit.data,\n };\n return {\n ...message,\n parts: [...message.parts, newFilePart],\n get content() {\n return this.parts;\n },\n };\n } else {\n throw new Error(`Unsupported part type: ${partInit.type}`);\n }\n};\n\nconst handleToolCallArgsTextFinish = (\n message: AssistantMessage,\n chunk: AssistantStreamChunk & {\n readonly type: \"tool-call-args-text-finish\";\n },\n): AssistantMessage => {\n return updatePartForPath(message, chunk, (part) => {\n if (part.type !== \"tool-call\") {\n throw new Error(\"Last is not a tool call\");\n }\n\n // TODO this should never be hit; this happens if args-text-finish is emitted after resutl\n if (part.state !== \"partial-call\") return part;\n // throw new Error(\"Last is not a partial call\");\n\n return {\n ...part,\n state: \"call\",\n };\n });\n};\n\nconst handlePartFinish = (\n message: AssistantMessage,\n chunk: AssistantStreamChunk & { readonly type: \"part-finish\" },\n): AssistantMessage => {\n return updatePartForPath(message, chunk, (part) => ({\n ...part,\n status: { type: \"complete\", reason: \"unknown\" },\n }));\n};\n\nconst handleTextDelta = (\n message: AssistantMessage,\n chunk: AssistantStreamChunk & { type: \"text-delta\" },\n): AssistantMessage => {\n return updatePartForPath(message, chunk, (part) => {\n if (part.type === \"text\" || part.type === \"reasoning\") {\n return { ...part, text: part.text + chunk.textDelta };\n } else if (part.type === \"tool-call\") {\n const newArgsText = part.argsText + chunk.textDelta;\n\n // Fall back to existing args if parsing fails\n const newArgs = parsePartialJsonObject(newArgsText) ?? part.args;\n\n return { ...part, argsText: newArgsText, args: newArgs };\n } else {\n throw new Error(\n \"text-delta received but part is neither text nor tool-call\",\n );\n }\n });\n};\n\nconst handleResult = (\n message: AssistantMessage,\n chunk: AssistantStreamChunk & { type: \"result\" },\n): AssistantMessage => {\n return updatePartForPath(message, chunk, (part) => {\n if (part.type === \"tool-call\") {\n return {\n ...part,\n state: \"result\",\n ...(chunk.artifact !== undefined ? { artifact: chunk.artifact } : {}),\n result: chunk.result,\n isError: chunk.isError ?? false,\n status: { type: \"complete\", reason: \"stop\" },\n };\n } else {\n throw new Error(\"Result chunk received but part is not a tool-call\");\n }\n });\n};\n\nconst handleMessageFinish = (\n message: AssistantMessage,\n chunk: AssistantStreamChunk & { type: \"message-finish\" },\n): AssistantMessage => {\n // avoid edge case where providers send finish chunks that overwrite message error status (issue #2181)\n if (\n message.status?.type === \"incomplete\" &&\n message.status?.reason === \"error\"\n ) {\n return message;\n }\n\n const newStatus = getStatus(chunk);\n return { ...message, status: newStatus };\n};\n\nconst getStatus = (\n chunk:\n | (AssistantStreamChunk & { type: \"message-finish\" })\n | (AssistantStreamChunk & { type: \"step-finish\" }),\n): AssistantMessageStatus => {\n if (chunk.finishReason === \"tool-calls\") {\n return {\n type: \"requires-action\",\n reason: \"tool-calls\",\n };\n } else if (\n chunk.finishReason === \"stop\" ||\n chunk.finishReason === \"unknown\"\n ) {\n return {\n type: \"complete\",\n reason: chunk.finishReason,\n };\n } else {\n return {\n type: \"incomplete\",\n reason: chunk.finishReason,\n };\n }\n};\n\nconst handleAnnotations = (\n message: AssistantMessage,\n chunk: AssistantStreamChunk & { type: \"annotations\" },\n): AssistantMessage => {\n return {\n ...message,\n metadata: {\n ...message.metadata,\n unstable_annotations: [\n ...message.metadata.unstable_annotations,\n ...chunk.annotations,\n ],\n },\n };\n};\n\nconst handleData = (\n message: AssistantMessage,\n chunk: AssistantStreamChunk & { type: \"data\" },\n): AssistantMessage => {\n return {\n ...message,\n metadata: {\n ...message.metadata,\n unstable_data: [...message.metadata.unstable_data, ...chunk.data],\n },\n };\n};\n\nconst handleStepStart = (\n message: AssistantMessage,\n chunk: AssistantStreamChunk & { type: \"step-start\" },\n): AssistantMessage => {\n return {\n ...message,\n metadata: {\n ...message.metadata,\n steps: [\n ...message.metadata.steps,\n { state: \"started\", messageId: chunk.messageId },\n ],\n },\n };\n};\n\nconst handleStepFinish = (\n message: AssistantMessage,\n chunk: AssistantStreamChunk & { type: \"step-finish\" },\n): AssistantMessage => {\n const steps = message.metadata.steps.slice();\n const lastIndex = steps.length - 1;\n\n // Check if the previous step is a step-start (has state \"started\")\n if (steps.length > 0 && steps[lastIndex]?.state === \"started\") {\n steps[lastIndex] = {\n ...steps[lastIndex],\n state: \"finished\",\n finishReason: chunk.finishReason,\n usage: chunk.usage,\n isContinued: chunk.isContinued,\n };\n } else {\n // If no previous step-start exists, append a finished step\n steps.push({\n state: \"finished\",\n messageId: generateId(),\n finishReason: chunk.finishReason,\n usage: chunk.usage,\n isContinued: chunk.isContinued,\n });\n }\n\n return {\n ...message,\n metadata: {\n ...message.metadata,\n steps,\n },\n };\n};\n\nconst handleErrorChunk = (\n message: AssistantMessage,\n chunk: AssistantStreamChunk & { type: \"error\" },\n): AssistantMessage => {\n return {\n ...message,\n status: { type: \"incomplete\", reason: \"error\", error: chunk.error },\n };\n};\n\nconst handleUpdateState = (\n message: AssistantMessage,\n chunk: AssistantStreamChunk & { type: \"update-state\" },\n): AssistantMessage => {\n const acc = new ObjectStreamAccumulator(message.metadata.unstable_state);\n acc.append(chunk.operations);\n\n return {\n ...message,\n metadata: {\n ...message.metadata,\n unstable_state: acc.state,\n },\n };\n};\n\nconst throttleCallback = (callback: () => void) => {\n let hasScheduled = false;\n return () => {\n if (hasScheduled) return;\n hasScheduled = true;\n queueMicrotask(() => {\n hasScheduled = false;\n callback();\n });\n };\n};\n\nexport class AssistantMessageAccumulator extends TransformStream<\n AssistantStreamChunk,\n AssistantMessage\n> {\n constructor({\n initialMessage,\n }: {\n initialMessage?: AssistantMessage;\n } = {}) {\n let message = initialMessage ?? createInitialMessage();\n let controller:\n | TransformStreamDefaultController<AssistantMessage>\n | undefined;\n const emitChunk = throttleCallback(() => {\n controller?.enqueue(message);\n });\n super({\n start(c) {\n controller = c;\n },\n transform(chunk) {\n const type = chunk.type;\n switch (type) {\n case \"part-start\":\n message = handlePartStart(message, chunk);\n break;\n\n case \"tool-call-args-text-finish\":\n message = handleToolCallArgsTextFinish(message, chunk);\n break;\n\n case \"part-finish\":\n message = handlePartFinish(message, chunk);\n break;\n\n case \"text-delta\":\n message = handleTextDelta(message, chunk);\n break;\n case \"result\":\n message = handleResult(message, chunk);\n break;\n case \"message-finish\":\n message = handleMessageFinish(message, chunk);\n break;\n case \"annotations\":\n message = handleAnnotations(message, chunk);\n break;\n case \"data\":\n message = handleData(message, chunk);\n break;\n case \"step-start\":\n message = handleStepStart(message, chunk);\n break;\n case \"step-finish\":\n message = handleStepFinish(message, chunk);\n break;\n case \"error\":\n message = handleErrorChunk(message, chunk);\n break;\n case \"update-state\":\n message = handleUpdateState(message, chunk);\n break;\n default: {\n const unhandledType: never = type;\n throw new Error(`Unsupported chunk type: ${unhandledType}`);\n }\n }\n emitChunk();\n },\n flush(controller) {\n if (message.status?.type === \"running\") {\n // Check if there are any tool calls that require action\n const requiresAction =\n message.parts?.some(\n (part) =>\n part.type === \"tool-call\" &&\n (part.state === \"call\" || part.state === \"partial-call\") &&\n part.result === undefined,\n ) ?? false;\n message = handleMessageFinish(message, {\n type: \"message-finish\",\n path: [],\n finishReason: requiresAction ? \"tool-calls\" : \"unknown\",\n usage: {\n promptTokens: 0,\n completionTokens: 0,\n },\n });\n controller.enqueue(message);\n }\n },\n });\n }\n}\n"],"mappings":"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","names":["controller"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "assistant-stream",
3
- "version": "0.2.25",
3
+ "version": "0.2.27",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "exports": {
@@ -355,6 +355,18 @@ const handleUpdateState = (
355
355
  };
356
356
  };
357
357
 
358
+ const throttleCallback = (callback: () => void) => {
359
+ let hasScheduled = false;
360
+ return () => {
361
+ if (hasScheduled) return;
362
+ hasScheduled = true;
363
+ queueMicrotask(() => {
364
+ hasScheduled = false;
365
+ callback();
366
+ });
367
+ };
368
+ };
369
+
358
370
  export class AssistantMessageAccumulator extends TransformStream<
359
371
  AssistantStreamChunk,
360
372
  AssistantMessage
@@ -365,8 +377,17 @@ export class AssistantMessageAccumulator extends TransformStream<
365
377
  initialMessage?: AssistantMessage;
366
378
  } = {}) {
367
379
  let message = initialMessage ?? createInitialMessage();
380
+ let controller:
381
+ | TransformStreamDefaultController<AssistantMessage>
382
+ | undefined;
383
+ const emitChunk = throttleCallback(() => {
384
+ controller?.enqueue(message);
385
+ });
368
386
  super({
369
- transform(chunk, controller) {
387
+ start(c) {
388
+ controller = c;
389
+ },
390
+ transform(chunk) {
370
391
  const type = chunk.type;
371
392
  switch (type) {
372
393
  case "part-start":
@@ -413,7 +434,7 @@ export class AssistantMessageAccumulator extends TransformStream<
413
434
  throw new Error(`Unsupported chunk type: ${unhandledType}`);
414
435
  }
415
436
  }
416
- controller.enqueue(message);
437
+ emitChunk();
417
438
  },
418
439
  flush(controller) {
419
440
  if (message.status?.type === "running") {