assistant-stream 0.3.21 → 0.3.23

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","names":[],"sources":["../../../src/core/accumulators/assistant-message-accumulator.ts"],"mappings":";;;;;cAmBa,oBAAA;EAAwB;AAAA;EAGnC,cAAA,GAAiB,iBAAA;AAAA,MACV,gBAAA;AAAA,cAwYI,2BAAA,SAAoC,eAAA,CAC/C,oBAAA,EACA,gBAAA;;IAGE,cAAA;IACA,QAAA;IACA;EAAA;IAEA,cAAA,GAAiB,gBAAA;IACjB,QAAA;IACA,OAAA,IAAW,KAAA;EAAA;AAAA"}
1
+ {"version":3,"file":"assistant-message-accumulator.d.ts","names":[],"sources":["../../../src/core/accumulators/assistant-message-accumulator.ts"],"mappings":";;;;;cAmBa,oBAAA;EAAwB;AAAA;EAGnC,cAAA,GAAiB,iBAAA;AAAA,MACV,gBAAA;AAAA,cAiZI,2BAAA,SAAoC,eAAA,CAC/C,oBAAA,EACA,gBAAA;;IAGE,cAAA;IACA,QAAA;IACA;EAAA;IAEA,cAAA,GAAiB,gBAAA;IACjB,QAAA;IACA,OAAA,IAAW,KAAA;EAAA;AAAA"}
@@ -63,6 +63,7 @@ const handlePartStart = (message, chunk) => {
63
63
  toolName: partInit.toolName,
64
64
  argsText: "",
65
65
  args: {},
66
+ timing: { startedAt: Date.now() },
66
67
  ...partInit.parentId && { parentId: partInit.parentId }
67
68
  };
68
69
  return {
@@ -159,6 +160,10 @@ const handleResult = (message, chunk) => {
159
160
  if (part.type === "tool-call") return {
160
161
  ...part,
161
162
  state: "result",
163
+ ...part.timing !== void 0 ? { timing: {
164
+ ...part.timing,
165
+ completedAt: part.timing.completedAt ?? Date.now()
166
+ } } : {},
162
167
  ...chunk.artifact !== void 0 ? { artifact: chunk.artifact } : {},
163
168
  result: chunk.result,
164
169
  isError: chunk.isError ?? false,
@@ -1 +1 @@
1
- {"version":3,"file":"assistant-message-accumulator.js","names":["unhandledType"],"sources":["../../../src/core/accumulators/assistant-message-accumulator.ts"],"sourcesContent":["import type { AssistantStreamChunk } from \"../AssistantStreamChunk\";\nimport { generateId } from \"../utils/generateId\";\nimport { parsePartialJsonObject } from \"../../utils/json/parse-partial-json-object\";\nimport type {\n AssistantMessage,\n AssistantMessageStatus,\n AssistantMessageTiming,\n TextPart,\n ToolCallPart,\n SourcePart,\n AssistantMessagePart,\n ReasoningPart,\n FilePart,\n DataPart,\n} from \"../utils/types\";\nimport { ObjectStreamAccumulator } from \"../object/ObjectStreamAccumulator\";\nimport type { ReadonlyJSONValue } from \"../../utils\";\nimport { TimingTracker } from \"./TimingTracker\";\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 ...(partInit.parentId && { parentId: partInit.parentId }),\n };\n return {\n ...message,\n parts: [...message.parts, newFilePart],\n get content() {\n return this.parts;\n },\n };\n } else if (partInit.type === \"data\") {\n const newDataPart: DataPart = {\n type: \"data\",\n name: partInit.name,\n data: partInit.data,\n ...(partInit.parentId && { parentId: partInit.parentId }),\n };\n return {\n ...message,\n parts: [...message.parts, newDataPart],\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 result\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 ...(chunk.modelContent !== undefined\n ? { modelContent: chunk.modelContent }\n : {}),\n ...(chunk.messages !== undefined ? { messages: chunk.messages } : {}),\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 computeTiming = (\n tracker: TimingTracker,\n message: AssistantMessage,\n): AssistantMessageTiming => {\n let outputTokens = 0;\n for (const step of message.metadata.steps) {\n if (step.state === \"finished\" && step.usage) {\n outputTokens += step.usage.outputTokens;\n }\n }\n\n let totalText = \"\";\n for (const part of message.parts) {\n if (part.type === \"text\" || part.type === \"reasoning\") {\n totalText += part.text;\n }\n }\n\n return tracker.getTiming(\n outputTokens > 0 ? outputTokens : undefined,\n totalText || undefined,\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 throttle,\n onError,\n }: {\n initialMessage?: AssistantMessage;\n throttle?: boolean;\n onError?: (error: string) => void;\n } = {}) {\n let message = initialMessage ?? createInitialMessage();\n const tracker = new TimingTracker();\n let controller:\n | TransformStreamDefaultController<AssistantMessage>\n | undefined;\n const emitChunk = throttle\n ? throttleCallback(() => {\n controller?.enqueue(message);\n })\n : () => {\n controller?.enqueue(message);\n };\n super({\n start(c) {\n controller = c;\n },\n transform(chunk) {\n tracker.recordChunk();\n const type = chunk.type;\n switch (type) {\n case \"part-start\":\n message = handlePartStart(message, chunk);\n if (chunk.part.type === \"tool-call\") {\n tracker.recordToolCallStart(chunk.part.toolCallId);\n }\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 tracker.recordFirstToken();\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 onError?.(chunk.error);\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\n if (message.status.type !== \"running\") {\n message = {\n ...message,\n metadata: {\n ...message.metadata,\n timing: computeTiming(tracker, message),\n },\n };\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 inputTokens: 0,\n outputTokens: 0,\n },\n });\n\n message = {\n ...message,\n metadata: {\n ...message.metadata,\n timing: computeTiming(tracker, message),\n },\n };\n\n controller.enqueue(message);\n }\n },\n });\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"assistant-message-accumulator.js","names":["unhandledType"],"sources":["../../../src/core/accumulators/assistant-message-accumulator.ts"],"sourcesContent":["import type { AssistantStreamChunk } from \"../AssistantStreamChunk\";\nimport { generateId } from \"../utils/generateId\";\nimport { parsePartialJsonObject } from \"../../utils/json/parse-partial-json-object\";\nimport type {\n AssistantMessage,\n AssistantMessageStatus,\n AssistantMessageTiming,\n TextPart,\n ToolCallPart,\n SourcePart,\n AssistantMessagePart,\n ReasoningPart,\n FilePart,\n DataPart,\n} from \"../utils/types\";\nimport { ObjectStreamAccumulator } from \"../object/ObjectStreamAccumulator\";\nimport type { ReadonlyJSONValue } from \"../../utils\";\nimport { TimingTracker } from \"./TimingTracker\";\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 timing: { startedAt: Date.now() },\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 ...(partInit.parentId && { parentId: partInit.parentId }),\n };\n return {\n ...message,\n parts: [...message.parts, newFilePart],\n get content() {\n return this.parts;\n },\n };\n } else if (partInit.type === \"data\") {\n const newDataPart: DataPart = {\n type: \"data\",\n name: partInit.name,\n data: partInit.data,\n ...(partInit.parentId && { parentId: partInit.parentId }),\n };\n return {\n ...message,\n parts: [...message.parts, newDataPart],\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 result\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 ...(part.timing !== undefined\n ? {\n timing: {\n ...part.timing,\n completedAt: part.timing.completedAt ?? Date.now(),\n },\n }\n : {}),\n ...(chunk.artifact !== undefined ? { artifact: chunk.artifact } : {}),\n result: chunk.result,\n isError: chunk.isError ?? false,\n ...(chunk.modelContent !== undefined\n ? { modelContent: chunk.modelContent }\n : {}),\n ...(chunk.messages !== undefined ? { messages: chunk.messages } : {}),\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 computeTiming = (\n tracker: TimingTracker,\n message: AssistantMessage,\n): AssistantMessageTiming => {\n let outputTokens = 0;\n for (const step of message.metadata.steps) {\n if (step.state === \"finished\" && step.usage) {\n outputTokens += step.usage.outputTokens;\n }\n }\n\n let totalText = \"\";\n for (const part of message.parts) {\n if (part.type === \"text\" || part.type === \"reasoning\") {\n totalText += part.text;\n }\n }\n\n return tracker.getTiming(\n outputTokens > 0 ? outputTokens : undefined,\n totalText || undefined,\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 throttle,\n onError,\n }: {\n initialMessage?: AssistantMessage;\n throttle?: boolean;\n onError?: (error: string) => void;\n } = {}) {\n let message = initialMessage ?? createInitialMessage();\n const tracker = new TimingTracker();\n let controller:\n | TransformStreamDefaultController<AssistantMessage>\n | undefined;\n const emitChunk = throttle\n ? throttleCallback(() => {\n controller?.enqueue(message);\n })\n : () => {\n controller?.enqueue(message);\n };\n super({\n start(c) {\n controller = c;\n },\n transform(chunk) {\n tracker.recordChunk();\n const type = chunk.type;\n switch (type) {\n case \"part-start\":\n message = handlePartStart(message, chunk);\n if (chunk.part.type === \"tool-call\") {\n tracker.recordToolCallStart(chunk.part.toolCallId);\n }\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 tracker.recordFirstToken();\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 onError?.(chunk.error);\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\n if (message.status.type !== \"running\") {\n message = {\n ...message,\n metadata: {\n ...message.metadata,\n timing: computeTiming(tracker, message),\n },\n };\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 inputTokens: 0,\n outputTokens: 0,\n },\n });\n\n message = {\n ...message,\n metadata: {\n ...message.metadata,\n timing: computeTiming(tracker, message),\n },\n };\n\n controller.enqueue(message);\n }\n },\n });\n }\n}\n"],"mappings":"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"}
@@ -14,7 +14,7 @@ declare class ToolCallArgsReaderImpl<T extends ReadonlyJSONObject> implements To
14
14
  get<PathT extends TypePath<T>>(...fieldPath: PathT): Promise<TypeAtPath<T, PathT>>;
15
15
  streamValues<PathT extends TypePath<T>>(...fieldPath: PathT): AsyncIterableStream<DeepPartial<TypeAtPath<T, PathT>>>;
16
16
  streamText<PathT extends TypePath<T>>(...fieldPath: PathT): TypeAtPath<T, PathT> extends string & (infer U) ? AsyncIterableStream<U> : never;
17
- forEach<PathT extends TypePath<T>>(...fieldPath: PathT): TypeAtPath<T, PathT> extends Array<infer U> ? AsyncIterableStream<U> : never;
17
+ forEach<PathT extends TypePath<T>>(...fieldPath: PathT): NonNullable<TypeAtPath<T, PathT>> extends Array<infer U> ? AsyncIterableStream<U> : never;
18
18
  }
19
19
  declare class ToolCallResponseReaderImpl<TResult extends ReadonlyJSONValue> implements ToolCallResponseReader<TResult> {
20
20
  private readonly promise;
@@ -1 +1 @@
1
- {"version":3,"file":"ToolCallReader.d.ts","names":[],"sources":["../../../src/core/tool/ToolCallReader.ts"],"mappings":";;;;;;cA0Qa,sBAAA,WACD,kBAAA,aACC,kBAAA,CAAmB,CAAA;EAAA,QACtB,aAAA;EAAA,QACA,OAAA;EAAA,QACA,IAAA;EAAA,QACA,QAAA;cAEI,aAAA,EAAe,cAAA;EAAA,QAKb,aAAA;EA+Bd,GAAA,eAAkB,QAAA,CAAS,CAAA,MACtB,SAAA,EAAW,KAAA,GACb,OAAA,CAAQ,UAAA,CAAW,CAAA,EAAG,KAAA;EAiCzB,YAAA,eAA2B,QAAA,CAAS,CAAA,MAC/B,SAAA,EAAW,KAAA,GACb,mBAAA,CAAoB,WAAA,CAAY,UAAA,CAAW,CAAA,EAAG,KAAA;EA4BjD,UAAA,eAAyB,QAAA,CAAS,CAAA,MAC7B,SAAA,EAAW,KAAA,GACb,UAAA,CAAW,CAAA,EAAG,KAAA,+BACb,mBAAA,CAAoB,CAAA;EA6BxB,OAAA,eAAsB,QAAA,CAAS,CAAA,MAC1B,SAAA,EAAW,KAAA,GACb,UAAA,CAAW,CAAA,EAAG,KAAA,UAAe,KAAA,YAC5B,mBAAA,CAAoB,CAAA;AAAA;AAAA,cA8Bb,0BAAA,iBACK,iBAAA,aACL,sBAAA,CAAuB,OAAA;EAAA,iBACL,OAAA;cAAA,OAAA,EAAS,OAAA,CAAQ,YAAA,CAAa,OAAA;EAEpD,GAAA,IAAG,OAAA,CAAA,YAAA,CAAA,OAAA;AAAA;AAAA,cAKC,kBAAA,eACG,kBAAA,kBACE,iBAAA,aACL,cAAA,CAAe,KAAA,EAAO,OAAA;EAAA,SACjB,IAAA,EAAM,sBAAA,CAAuB,KAAA;EAAA,SAC7B,QAAA,EAAU,0BAAA,CAA2B,OAAA;EAAA,iBACpC,QAAA;EAAA,iBACA,OAAA;EAEV,QAAA;;EAYD,mBAAA,CAAoB,IAAA,WAAe,OAAA;EAanC,cAAA,IAAkB,OAAA;EAWxB,WAAA,CAAY,KAAA,EAAO,YAAA,CAAa,OAAA;EAIhC,MAAA"}
1
+ {"version":3,"file":"ToolCallReader.d.ts","names":[],"sources":["../../../src/core/tool/ToolCallReader.ts"],"mappings":";;;;;;cA0Qa,sBAAA,WACD,kBAAA,aACC,kBAAA,CAAmB,CAAA;EAAA,QACtB,aAAA;EAAA,QACA,OAAA;EAAA,QACA,IAAA;EAAA,QACA,QAAA;cAEI,aAAA,EAAe,cAAA;EAAA,QAKb,aAAA;EA+Bd,GAAA,eAAkB,QAAA,CAAS,CAAA,MACtB,SAAA,EAAW,KAAA,GACb,OAAA,CAAQ,UAAA,CAAW,CAAA,EAAG,KAAA;EAiCzB,YAAA,eAA2B,QAAA,CAAS,CAAA,MAC/B,SAAA,EAAW,KAAA,GACb,mBAAA,CAAoB,WAAA,CAAY,UAAA,CAAW,CAAA,EAAG,KAAA;EA4BjD,UAAA,eAAyB,QAAA,CAAS,CAAA,MAC7B,SAAA,EAAW,KAAA,GACb,UAAA,CAAW,CAAA,EAAG,KAAA,+BACb,mBAAA,CAAoB,CAAA;EA6BxB,OAAA,eAAsB,QAAA,CAAS,CAAA,MAC1B,SAAA,EAAW,KAAA,GACb,WAAA,CAAY,UAAA,CAAW,CAAA,EAAG,KAAA,WAAgB,KAAA,YACzC,mBAAA,CAAoB,CAAA;AAAA;AAAA,cA8Bb,0BAAA,iBACK,iBAAA,aACL,sBAAA,CAAuB,OAAA;EAAA,iBACL,OAAA;cAAA,OAAA,EAAS,OAAA,CAAQ,YAAA,CAAa,OAAA;EAEpD,GAAA,IAAG,OAAA,CAAA,YAAA,CAAA,OAAA;AAAA;AAAA,cAKC,kBAAA,eACG,kBAAA,kBACE,iBAAA,aACL,cAAA,CAAe,KAAA,EAAO,OAAA;EAAA,SACjB,IAAA,EAAM,sBAAA,CAAuB,KAAA;EAAA,SAC7B,QAAA,EAAU,0BAAA,CAA2B,OAAA;EAAA,iBACpC,QAAA;EAAA,iBACA,OAAA;EAEV,QAAA;;EAYD,mBAAA,CAAoB,IAAA,WAAe,OAAA;EAanC,cAAA,IAAkB,OAAA;EAWxB,WAAA,CAAY,KAAA,EAAO,YAAA,CAAa,OAAA;EAIhC,MAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"ToolCallReader.js","names":[],"sources":["../../../src/core/tool/ToolCallReader.ts"],"sourcesContent":["import { promiseWithResolvers } from \"../../utils/promiseWithResolvers\";\nimport {\n parsePartialJsonObject,\n getPartialJsonObjectFieldState,\n} from \"../../utils/json/parse-partial-json-object\";\nimport type {\n ToolCallArgsReader,\n ToolCallReader,\n ToolCallResponseReader,\n} from \"./tool-types\";\nimport type { DeepPartial, TypeAtPath, TypePath } from \"./type-path-utils\";\nimport type { ToolResponse } from \"./ToolResponse\";\nimport { asAsyncIterableStream } from \"../../utils/AsyncIterableStream\";\nimport type {\n AsyncIterableStream,\n ReadonlyJSONObject,\n ReadonlyJSONValue,\n} from \"../../utils\";\n\n// TODO: remove dispose\n\nfunction getField<T>(obj: T, fieldPath: (string | number)[]): unknown {\n let current: unknown = obj;\n for (const key of fieldPath) {\n if (current === undefined || current === null) {\n return undefined;\n }\n current = current[key as keyof typeof current];\n }\n return current;\n}\n\ninterface Handle {\n update(args: unknown): void;\n end(args: unknown): void;\n dispose(): void;\n}\n\nclass GetHandle<T, TValue> implements Handle {\n private resolve: (value: TValue) => void;\n private reject: (reason: unknown) => void;\n private disposed = false;\n private fieldPath: (string | number)[];\n\n constructor(\n resolve: (value: TValue) => void,\n reject: (reason: unknown) => void,\n fieldPath: (string | number)[],\n ) {\n this.resolve = resolve;\n this.reject = reject;\n this.fieldPath = fieldPath;\n }\n\n update(args: unknown): void {\n if (this.disposed) return;\n\n try {\n // Check if the field is complete\n if (\n getPartialJsonObjectFieldState(\n args as Record<string, unknown>,\n this.fieldPath,\n ) === \"complete\"\n ) {\n const value = getField(args as T, this.fieldPath);\n if (value !== undefined) {\n this.resolve(value as TValue);\n this.dispose();\n }\n }\n } catch (e) {\n this.reject(e);\n this.dispose();\n }\n }\n\n end(args: unknown): void {\n if (this.disposed) return;\n\n try {\n const value = getField(args as T, this.fieldPath);\n this.resolve(value as TValue);\n } catch (e) {\n this.reject(e);\n } finally {\n this.dispose();\n }\n }\n\n dispose(): void {\n this.disposed = true;\n }\n}\n\nclass StreamValuesHandle<T> implements Handle {\n private controller: ReadableStreamDefaultController<unknown>;\n private disposed = false;\n private fieldPath: (string | number)[];\n\n constructor(\n controller: ReadableStreamDefaultController<unknown>,\n fieldPath: (string | number)[],\n ) {\n this.controller = controller;\n this.fieldPath = fieldPath;\n }\n\n update(args: unknown): void {\n if (this.disposed) return;\n\n try {\n const value = getField(args as T, this.fieldPath);\n\n if (value !== undefined) {\n this.controller.enqueue(value);\n }\n\n // Check if the field is complete, if so close the stream\n if (\n getPartialJsonObjectFieldState(\n args as Record<string, unknown>,\n this.fieldPath,\n ) === \"complete\"\n ) {\n this.controller.close();\n this.dispose();\n }\n } catch (e) {\n this.controller.error(e);\n this.dispose();\n }\n }\n\n end(): void {\n if (this.disposed) return;\n this.controller.close();\n this.dispose();\n }\n\n dispose(): void {\n this.disposed = true;\n }\n}\n\nclass StreamTextHandle<T> implements Handle {\n private controller: ReadableStreamDefaultController<unknown>;\n private disposed = false;\n private fieldPath: (string | number)[];\n private lastValue: string | undefined = undefined;\n\n constructor(\n controller: ReadableStreamDefaultController<unknown>,\n fieldPath: (string | number)[],\n ) {\n this.controller = controller;\n this.fieldPath = fieldPath;\n }\n\n update(args: unknown): void {\n if (this.disposed) return;\n\n try {\n const value = getField(args as T, this.fieldPath);\n\n if (value !== undefined && typeof value === \"string\") {\n const delta = value.substring(this.lastValue?.length || 0);\n this.lastValue = value;\n this.controller.enqueue(delta);\n }\n\n // Check if the field is complete, if so close the stream\n if (\n getPartialJsonObjectFieldState(\n args as Record<string, unknown>,\n this.fieldPath,\n ) === \"complete\"\n ) {\n this.controller.close();\n this.dispose();\n }\n } catch (e) {\n this.controller.error(e);\n this.dispose();\n }\n }\n\n end(): void {\n if (this.disposed) return;\n this.controller.close();\n this.dispose();\n }\n\n dispose(): void {\n this.disposed = true;\n }\n}\n\nclass ForEachHandle<T> implements Handle {\n private controller: ReadableStreamDefaultController<unknown>;\n private disposed = false;\n private fieldPath: (string | number)[];\n private processedIndexes = new Set<number>();\n\n constructor(\n controller: ReadableStreamDefaultController<unknown>,\n fieldPath: (string | number)[],\n ) {\n this.controller = controller;\n this.fieldPath = fieldPath;\n }\n\n update(args: unknown): void {\n if (this.disposed) return;\n\n try {\n const array = getField(args as T, this.fieldPath);\n\n if (!Array.isArray(array)) {\n return;\n }\n\n // Check each array element and emit completed ones that haven't been processed\n for (let i = 0; i < array.length; i++) {\n if (!this.processedIndexes.has(i)) {\n const elementPath = [...this.fieldPath, i];\n if (\n getPartialJsonObjectFieldState(\n args as Record<string, unknown>,\n elementPath,\n ) === \"complete\"\n ) {\n this.controller.enqueue(array[i]);\n this.processedIndexes.add(i);\n }\n }\n }\n\n // Check if the entire array is complete\n if (\n getPartialJsonObjectFieldState(\n args as Record<string, unknown>,\n this.fieldPath,\n ) === \"complete\"\n ) {\n this.controller.close();\n this.dispose();\n }\n } catch (e) {\n this.controller.error(e);\n this.dispose();\n }\n }\n\n end(): void {\n if (this.disposed) return;\n this.controller.close();\n this.dispose();\n }\n\n dispose(): void {\n this.disposed = true;\n }\n}\n\n// Implementation of ToolCallReader that uses stream of partial JSON\nexport class ToolCallArgsReaderImpl<\n T extends ReadonlyJSONObject,\n> implements ToolCallArgsReader<T> {\n private argTextDeltas: ReadableStream<string>;\n private handles: Set<Handle> = new Set();\n private args: unknown = parsePartialJsonObject(\"\");\n private finished = false;\n\n constructor(argTextDeltas: ReadableStream<string>) {\n this.argTextDeltas = argTextDeltas;\n this.processStream();\n }\n\n private async processStream(): Promise<void> {\n try {\n let accumulatedText = \"\";\n const reader = this.argTextDeltas.getReader();\n\n while (true) {\n const { value, done } = await reader.read();\n if (done) break;\n\n accumulatedText += value;\n const parsedArgs = parsePartialJsonObject(accumulatedText);\n\n if (parsedArgs !== undefined) {\n this.args = parsedArgs;\n // Notify all handles of the updated args\n for (const handle of this.handles) {\n handle.update(parsedArgs);\n }\n }\n }\n } catch (error) {\n console.error(\"Error processing argument stream:\", error);\n } finally {\n this.finished = true;\n for (const handle of this.handles) {\n handle.end(this.args);\n }\n this.handles.clear();\n }\n }\n\n get<PathT extends TypePath<T>>(\n ...fieldPath: PathT\n ): Promise<TypeAtPath<T, PathT>> {\n return new Promise<TypeAtPath<T, PathT>>((resolve, reject) => {\n const handle = new GetHandle<T, TypeAtPath<T, PathT>>(\n resolve,\n reject,\n fieldPath,\n );\n\n // Check if the field is already complete in current args\n if (\n this.args &&\n getPartialJsonObjectFieldState(\n this.args as Record<string, unknown>,\n fieldPath,\n ) === \"complete\"\n ) {\n const value = getField(this.args as T, fieldPath);\n if (value !== undefined) {\n resolve(value as TypeAtPath<T, PathT>);\n return;\n }\n }\n\n if (this.finished) {\n handle.end(this.args);\n return;\n }\n\n this.handles.add(handle);\n handle.update(this.args);\n });\n }\n\n streamValues<PathT extends TypePath<T>>(\n ...fieldPath: PathT\n ): AsyncIterableStream<DeepPartial<TypeAtPath<T, PathT>>> {\n // Use a type assertion to convert the complex TypePath to a simple array\n const simplePath = fieldPath as unknown as (string | number)[];\n\n let handle: StreamValuesHandle<T> | undefined;\n const stream = new ReadableStream<DeepPartial<TypeAtPath<T, PathT>>>({\n start: (controller) => {\n handle = new StreamValuesHandle<T>(controller, simplePath);\n if (!this.finished) this.handles.add(handle);\n\n // Check current args immediately\n handle.update(this.args);\n\n if (this.finished) handle.end();\n },\n cancel: () => {\n // Dispose this stream's own handle (captured above) — scanning for the\n // first match would dispose a concurrent streamValues()'s handle.\n if (handle) {\n handle.dispose();\n this.handles.delete(handle);\n }\n },\n });\n\n return asAsyncIterableStream(stream) as any;\n }\n\n streamText<PathT extends TypePath<T>>(\n ...fieldPath: PathT\n ): TypeAtPath<T, PathT> extends string & (infer U)\n ? AsyncIterableStream<U>\n : never {\n // Use a type assertion to convert the complex TypePath to a simple array\n const simplePath = fieldPath as unknown as (string | number)[];\n\n let handle: StreamTextHandle<T> | undefined;\n const stream = new ReadableStream<unknown>({\n start: (controller) => {\n handle = new StreamTextHandle<T>(controller, simplePath);\n if (!this.finished) this.handles.add(handle);\n\n // Check current args immediately\n handle.update(this.args);\n\n if (this.finished) handle.end();\n },\n cancel: () => {\n // Dispose this stream's own handle (captured above) — scanning for the\n // first match would dispose a concurrent streamText()'s handle.\n if (handle) {\n handle.dispose();\n this.handles.delete(handle);\n }\n },\n });\n\n return asAsyncIterableStream(stream) as any;\n }\n\n forEach<PathT extends TypePath<T>>(\n ...fieldPath: PathT\n ): TypeAtPath<T, PathT> extends Array<infer U>\n ? AsyncIterableStream<U>\n : never {\n // Use a type assertion to convert the complex TypePath to a simple array\n const simplePath = fieldPath as unknown as (string | number)[];\n\n let handle: ForEachHandle<T> | undefined;\n const stream = new ReadableStream<unknown>({\n start: (controller) => {\n handle = new ForEachHandle<T>(controller, simplePath);\n if (!this.finished) this.handles.add(handle);\n\n // Check current args immediately\n handle.update(this.args);\n\n if (this.finished) handle.end();\n },\n cancel: () => {\n // Dispose this stream's own handle (captured above) — scanning for the\n // first match would dispose a concurrent forEach()'s handle.\n if (handle) {\n handle.dispose();\n this.handles.delete(handle);\n }\n },\n });\n\n return asAsyncIterableStream(stream) as any;\n }\n}\n\nexport class ToolCallResponseReaderImpl<\n TResult extends ReadonlyJSONValue,\n> implements ToolCallResponseReader<TResult> {\n constructor(private readonly promise: Promise<ToolResponse<TResult>>) {}\n\n public get() {\n return this.promise;\n }\n}\n\nexport class ToolCallReaderImpl<\n TArgs extends ReadonlyJSONObject,\n TResult extends ReadonlyJSONValue,\n> implements ToolCallReader<TArgs, TResult> {\n public readonly args: ToolCallArgsReaderImpl<TArgs>;\n public readonly response: ToolCallResponseReaderImpl<TResult>;\n private readonly writable: WritableStream<string>;\n private readonly resolve: (value: ToolResponse<TResult>) => void;\n\n public argsText: string = \"\";\n\n constructor() {\n const stream = new TransformStream<string, string>();\n this.writable = stream.writable;\n this.args = new ToolCallArgsReaderImpl<TArgs>(stream.readable);\n\n const { promise, resolve } = promiseWithResolvers<ToolResponse<TResult>>();\n this.resolve = resolve;\n this.response = new ToolCallResponseReaderImpl<TResult>(promise);\n }\n\n async appendArgsTextDelta(text: string): Promise<void> {\n const writer = this.writable.getWriter();\n try {\n await writer.write(text);\n } catch (err) {\n console.warn(err);\n } finally {\n writer.releaseLock();\n }\n\n this.argsText += text;\n }\n\n async finishArgsText(): Promise<void> {\n const writer = this.writable.getWriter();\n try {\n await writer.close();\n } catch (err) {\n console.warn(err);\n } finally {\n writer.releaseLock();\n }\n }\n\n setResponse(value: ToolResponse<TResult>): void {\n this.resolve(value);\n }\n\n result = {\n get: async () => {\n const response = await this.response.get();\n return response.result;\n },\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"ToolCallReader.js","names":[],"sources":["../../../src/core/tool/ToolCallReader.ts"],"sourcesContent":["import { promiseWithResolvers } from \"../../utils/promiseWithResolvers\";\nimport {\n parsePartialJsonObject,\n getPartialJsonObjectFieldState,\n} from \"../../utils/json/parse-partial-json-object\";\nimport type {\n ToolCallArgsReader,\n ToolCallReader,\n ToolCallResponseReader,\n} from \"./tool-types\";\nimport type { DeepPartial, TypeAtPath, TypePath } from \"./type-path-utils\";\nimport type { ToolResponse } from \"./ToolResponse\";\nimport { asAsyncIterableStream } from \"../../utils/AsyncIterableStream\";\nimport type {\n AsyncIterableStream,\n ReadonlyJSONObject,\n ReadonlyJSONValue,\n} from \"../../utils\";\n\n// TODO: remove dispose\n\nfunction getField<T>(obj: T, fieldPath: (string | number)[]): unknown {\n let current: unknown = obj;\n for (const key of fieldPath) {\n if (current === undefined || current === null) {\n return undefined;\n }\n current = current[key as keyof typeof current];\n }\n return current;\n}\n\ninterface Handle {\n update(args: unknown): void;\n end(args: unknown): void;\n dispose(): void;\n}\n\nclass GetHandle<T, TValue> implements Handle {\n private resolve: (value: TValue) => void;\n private reject: (reason: unknown) => void;\n private disposed = false;\n private fieldPath: (string | number)[];\n\n constructor(\n resolve: (value: TValue) => void,\n reject: (reason: unknown) => void,\n fieldPath: (string | number)[],\n ) {\n this.resolve = resolve;\n this.reject = reject;\n this.fieldPath = fieldPath;\n }\n\n update(args: unknown): void {\n if (this.disposed) return;\n\n try {\n // Check if the field is complete\n if (\n getPartialJsonObjectFieldState(\n args as Record<string, unknown>,\n this.fieldPath,\n ) === \"complete\"\n ) {\n const value = getField(args as T, this.fieldPath);\n if (value !== undefined) {\n this.resolve(value as TValue);\n this.dispose();\n }\n }\n } catch (e) {\n this.reject(e);\n this.dispose();\n }\n }\n\n end(args: unknown): void {\n if (this.disposed) return;\n\n try {\n const value = getField(args as T, this.fieldPath);\n this.resolve(value as TValue);\n } catch (e) {\n this.reject(e);\n } finally {\n this.dispose();\n }\n }\n\n dispose(): void {\n this.disposed = true;\n }\n}\n\nclass StreamValuesHandle<T> implements Handle {\n private controller: ReadableStreamDefaultController<unknown>;\n private disposed = false;\n private fieldPath: (string | number)[];\n\n constructor(\n controller: ReadableStreamDefaultController<unknown>,\n fieldPath: (string | number)[],\n ) {\n this.controller = controller;\n this.fieldPath = fieldPath;\n }\n\n update(args: unknown): void {\n if (this.disposed) return;\n\n try {\n const value = getField(args as T, this.fieldPath);\n\n if (value !== undefined) {\n this.controller.enqueue(value);\n }\n\n // Check if the field is complete, if so close the stream\n if (\n getPartialJsonObjectFieldState(\n args as Record<string, unknown>,\n this.fieldPath,\n ) === \"complete\"\n ) {\n this.controller.close();\n this.dispose();\n }\n } catch (e) {\n this.controller.error(e);\n this.dispose();\n }\n }\n\n end(): void {\n if (this.disposed) return;\n this.controller.close();\n this.dispose();\n }\n\n dispose(): void {\n this.disposed = true;\n }\n}\n\nclass StreamTextHandle<T> implements Handle {\n private controller: ReadableStreamDefaultController<unknown>;\n private disposed = false;\n private fieldPath: (string | number)[];\n private lastValue: string | undefined = undefined;\n\n constructor(\n controller: ReadableStreamDefaultController<unknown>,\n fieldPath: (string | number)[],\n ) {\n this.controller = controller;\n this.fieldPath = fieldPath;\n }\n\n update(args: unknown): void {\n if (this.disposed) return;\n\n try {\n const value = getField(args as T, this.fieldPath);\n\n if (value !== undefined && typeof value === \"string\") {\n const delta = value.substring(this.lastValue?.length || 0);\n this.lastValue = value;\n this.controller.enqueue(delta);\n }\n\n // Check if the field is complete, if so close the stream\n if (\n getPartialJsonObjectFieldState(\n args as Record<string, unknown>,\n this.fieldPath,\n ) === \"complete\"\n ) {\n this.controller.close();\n this.dispose();\n }\n } catch (e) {\n this.controller.error(e);\n this.dispose();\n }\n }\n\n end(): void {\n if (this.disposed) return;\n this.controller.close();\n this.dispose();\n }\n\n dispose(): void {\n this.disposed = true;\n }\n}\n\nclass ForEachHandle<T> implements Handle {\n private controller: ReadableStreamDefaultController<unknown>;\n private disposed = false;\n private fieldPath: (string | number)[];\n private processedIndexes = new Set<number>();\n\n constructor(\n controller: ReadableStreamDefaultController<unknown>,\n fieldPath: (string | number)[],\n ) {\n this.controller = controller;\n this.fieldPath = fieldPath;\n }\n\n update(args: unknown): void {\n if (this.disposed) return;\n\n try {\n const array = getField(args as T, this.fieldPath);\n\n if (!Array.isArray(array)) {\n return;\n }\n\n // Check each array element and emit completed ones that haven't been processed\n for (let i = 0; i < array.length; i++) {\n if (!this.processedIndexes.has(i)) {\n const elementPath = [...this.fieldPath, i];\n if (\n getPartialJsonObjectFieldState(\n args as Record<string, unknown>,\n elementPath,\n ) === \"complete\"\n ) {\n this.controller.enqueue(array[i]);\n this.processedIndexes.add(i);\n }\n }\n }\n\n // Check if the entire array is complete\n if (\n getPartialJsonObjectFieldState(\n args as Record<string, unknown>,\n this.fieldPath,\n ) === \"complete\"\n ) {\n this.controller.close();\n this.dispose();\n }\n } catch (e) {\n this.controller.error(e);\n this.dispose();\n }\n }\n\n end(): void {\n if (this.disposed) return;\n this.controller.close();\n this.dispose();\n }\n\n dispose(): void {\n this.disposed = true;\n }\n}\n\n// Implementation of ToolCallReader that uses stream of partial JSON\nexport class ToolCallArgsReaderImpl<\n T extends ReadonlyJSONObject,\n> implements ToolCallArgsReader<T> {\n private argTextDeltas: ReadableStream<string>;\n private handles: Set<Handle> = new Set();\n private args: unknown = parsePartialJsonObject(\"\");\n private finished = false;\n\n constructor(argTextDeltas: ReadableStream<string>) {\n this.argTextDeltas = argTextDeltas;\n this.processStream();\n }\n\n private async processStream(): Promise<void> {\n try {\n let accumulatedText = \"\";\n const reader = this.argTextDeltas.getReader();\n\n while (true) {\n const { value, done } = await reader.read();\n if (done) break;\n\n accumulatedText += value;\n const parsedArgs = parsePartialJsonObject(accumulatedText);\n\n if (parsedArgs !== undefined) {\n this.args = parsedArgs;\n // Notify all handles of the updated args\n for (const handle of this.handles) {\n handle.update(parsedArgs);\n }\n }\n }\n } catch (error) {\n console.error(\"Error processing argument stream:\", error);\n } finally {\n this.finished = true;\n for (const handle of this.handles) {\n handle.end(this.args);\n }\n this.handles.clear();\n }\n }\n\n get<PathT extends TypePath<T>>(\n ...fieldPath: PathT\n ): Promise<TypeAtPath<T, PathT>> {\n return new Promise<TypeAtPath<T, PathT>>((resolve, reject) => {\n const handle = new GetHandle<T, TypeAtPath<T, PathT>>(\n resolve,\n reject,\n fieldPath,\n );\n\n // Check if the field is already complete in current args\n if (\n this.args &&\n getPartialJsonObjectFieldState(\n this.args as Record<string, unknown>,\n fieldPath,\n ) === \"complete\"\n ) {\n const value = getField(this.args as T, fieldPath);\n if (value !== undefined) {\n resolve(value as TypeAtPath<T, PathT>);\n return;\n }\n }\n\n if (this.finished) {\n handle.end(this.args);\n return;\n }\n\n this.handles.add(handle);\n handle.update(this.args);\n });\n }\n\n streamValues<PathT extends TypePath<T>>(\n ...fieldPath: PathT\n ): AsyncIterableStream<DeepPartial<TypeAtPath<T, PathT>>> {\n // Use a type assertion to convert the complex TypePath to a simple array\n const simplePath = fieldPath as unknown as (string | number)[];\n\n let handle: StreamValuesHandle<T> | undefined;\n const stream = new ReadableStream<DeepPartial<TypeAtPath<T, PathT>>>({\n start: (controller) => {\n handle = new StreamValuesHandle<T>(controller, simplePath);\n if (!this.finished) this.handles.add(handle);\n\n // Check current args immediately\n handle.update(this.args);\n\n if (this.finished) handle.end();\n },\n cancel: () => {\n // Dispose this stream's own handle (captured above) — scanning for the\n // first match would dispose a concurrent streamValues()'s handle.\n if (handle) {\n handle.dispose();\n this.handles.delete(handle);\n }\n },\n });\n\n return asAsyncIterableStream(stream) as any;\n }\n\n streamText<PathT extends TypePath<T>>(\n ...fieldPath: PathT\n ): TypeAtPath<T, PathT> extends string & (infer U)\n ? AsyncIterableStream<U>\n : never {\n // Use a type assertion to convert the complex TypePath to a simple array\n const simplePath = fieldPath as unknown as (string | number)[];\n\n let handle: StreamTextHandle<T> | undefined;\n const stream = new ReadableStream<unknown>({\n start: (controller) => {\n handle = new StreamTextHandle<T>(controller, simplePath);\n if (!this.finished) this.handles.add(handle);\n\n // Check current args immediately\n handle.update(this.args);\n\n if (this.finished) handle.end();\n },\n cancel: () => {\n // Dispose this stream's own handle (captured above) — scanning for the\n // first match would dispose a concurrent streamText()'s handle.\n if (handle) {\n handle.dispose();\n this.handles.delete(handle);\n }\n },\n });\n\n return asAsyncIterableStream(stream) as any;\n }\n\n forEach<PathT extends TypePath<T>>(\n ...fieldPath: PathT\n ): NonNullable<TypeAtPath<T, PathT>> extends Array<infer U>\n ? AsyncIterableStream<U>\n : never {\n // Use a type assertion to convert the complex TypePath to a simple array\n const simplePath = fieldPath as unknown as (string | number)[];\n\n let handle: ForEachHandle<T> | undefined;\n const stream = new ReadableStream<unknown>({\n start: (controller) => {\n handle = new ForEachHandle<T>(controller, simplePath);\n if (!this.finished) this.handles.add(handle);\n\n // Check current args immediately\n handle.update(this.args);\n\n if (this.finished) handle.end();\n },\n cancel: () => {\n // Dispose this stream's own handle (captured above) — scanning for the\n // first match would dispose a concurrent forEach()'s handle.\n if (handle) {\n handle.dispose();\n this.handles.delete(handle);\n }\n },\n });\n\n return asAsyncIterableStream(stream) as any;\n }\n}\n\nexport class ToolCallResponseReaderImpl<\n TResult extends ReadonlyJSONValue,\n> implements ToolCallResponseReader<TResult> {\n constructor(private readonly promise: Promise<ToolResponse<TResult>>) {}\n\n public get() {\n return this.promise;\n }\n}\n\nexport class ToolCallReaderImpl<\n TArgs extends ReadonlyJSONObject,\n TResult extends ReadonlyJSONValue,\n> implements ToolCallReader<TArgs, TResult> {\n public readonly args: ToolCallArgsReaderImpl<TArgs>;\n public readonly response: ToolCallResponseReaderImpl<TResult>;\n private readonly writable: WritableStream<string>;\n private readonly resolve: (value: ToolResponse<TResult>) => void;\n\n public argsText: string = \"\";\n\n constructor() {\n const stream = new TransformStream<string, string>();\n this.writable = stream.writable;\n this.args = new ToolCallArgsReaderImpl<TArgs>(stream.readable);\n\n const { promise, resolve } = promiseWithResolvers<ToolResponse<TResult>>();\n this.resolve = resolve;\n this.response = new ToolCallResponseReaderImpl<TResult>(promise);\n }\n\n async appendArgsTextDelta(text: string): Promise<void> {\n const writer = this.writable.getWriter();\n try {\n await writer.write(text);\n } catch (err) {\n console.warn(err);\n } finally {\n writer.releaseLock();\n }\n\n this.argsText += text;\n }\n\n async finishArgsText(): Promise<void> {\n const writer = this.writable.getWriter();\n try {\n await writer.close();\n } catch (err) {\n console.warn(err);\n } finally {\n writer.releaseLock();\n }\n }\n\n setResponse(value: ToolResponse<TResult>): void {\n this.resolve(value);\n }\n\n result = {\n get: async () => {\n const response = await this.response.get();\n return response.result;\n },\n };\n}\n"],"mappings":"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"}
@@ -84,7 +84,7 @@ interface ToolCallArgsReader<TArgs extends Record<string, unknown>> {
84
84
  *
85
85
  * @param fieldPath An array of object keys or array indices.
86
86
  */
87
- forEach<PathT extends TypePath<TArgs>>(...fieldPath: PathT): TypeAtPath<TArgs, PathT> extends Array<infer U> ? AsyncIterableStream<U> : never;
87
+ forEach<PathT extends TypePath<TArgs>>(...fieldPath: PathT): NonNullable<TypeAtPath<TArgs, PathT>> extends Array<infer U> ? AsyncIterableStream<U> : never;
88
88
  }
89
89
  interface ToolCallResponseReader<TResult> {
90
90
  get: () => Promise<ToolResponse<TResult>>;
@@ -1 +1 @@
1
- {"version":3,"file":"tool-types.d.ts","names":[],"sources":["../../../src/core/tool/tool-types.ts"],"mappings":";;;;;;;KAMY,oBAAA;8EAGG,IAAA,UAHH;EAAA,SAKG,IAAA;AAAA;EALiB,4EASjB,IAAA;EAJA;;;;EAAA,SASA,IAAA,UAIQ;EAAA,SAFR,SAAA,UA8BH;EAAA,SA5BG,QAAA;AAAA;;;;;;;;;;;;;;;;;;;;AAqC0B;AAUzC;;;;;KAnBY,uBAAA,oBAA2C,OAAA;EA2BrC,2DAzBhB,UAAA,UA0B6B;EAxB7B,KAAA,EAAO,KAAA,EAwBJ;EAtBH,MAAA,EAAQ,OAAA;AAAA,eAEG,oBAAA,KACT,OAAA,UAAiB,oBAAA;;;;;;;;;UAUJ,kBAAA,eAAiC,MAAA;EA6BlC;;;;;;EAtBd,GAAA,eAAkB,QAAA,CAAS,KAAA,MACtB,SAAA,EAAW,KAAA,GACb,OAAA,CAAQ,UAAA,CAAW,KAAA,EAAO,KAAA;EA+Bb;;;;;;EAvBhB,YAAA,eAA2B,QAAA,CAAS,KAAA,MAC/B,SAAA,EAAW,KAAA,GACb,mBAAA,CAAoB,WAAA,CAAY,UAAA,CAAW,KAAA,EAAO,KAAA;EAuB9B;;;;;;EAfvB,UAAA,eAAyB,QAAA,CAAS,KAAA,MAC7B,SAAA,EAAW,KAAA,GACb,UAAA,CAAW,KAAA,EAAO,KAAA,+BACjB,mBAAA,CAAoB,CAAA;EAvBG;;;;;;EAgC3B,OAAA,eAAsB,QAAA,CAAS,KAAA,MAC1B,SAAA,EAAW,KAAA,GACb,UAAA,CAAW,KAAA,EAAO,KAAA,UAAe,KAAA,YAChC,mBAAA,CAAoB,CAAA;AAAA;AAAA,UAIT,sBAAA;EACf,GAAA,QAAW,OAAA,CAAQ,YAAA,CAAa,OAAA;AAAA;AAAA,UAGjB,cAAA,eACD,MAAA,oBAA0B,MAAA;EAGxC,IAAA,EAAM,kBAAA,CAAmB,KAAA;EACzB,QAAA,EAAU,sBAAA,CAAuB,OAAA;EApCV;;;;EA0CvB,MAAA;IACE,GAAA,QAAW,OAAA,CAAQ,OAAA;EAAA;AAAA;AAAA,KAIX,oBAAA;EAtCM,0DAwChB,UAAA,UAvCc;EAyCd,WAAA,EAAa,WAAA;EAzCuC;;;;EA8CpD,KAAA,GAAQ,OAAA,cAAqB,OAAO;AAAA;;;;KAM1B,mBAAA,oBACV,IAAA,EAAM,KAAA,EACN,OAAA,EAAS,oBAAA,KACN,OAAA,GAAU,OAAA,CAAQ,OAAA;AAAA,KAEX,sBAAA,eACI,MAAA,oBAA0B,MAAA,yCAGxC,MAAA,EAAQ,cAAA,CAAe,KAAA,EAAO,OAAA,GAC9B,OAAA,EAAS,oBAAA;AAAA,KAGN,+BAAA,YAA2C,mBAAmB,UAEjE,OAAA;;;;;;AAtDyB;AAI3B;;;;;;KAiEY,eAAA,GAAkB,MAAM,SAAS,MAAA;;;;;;;;AAhEJ;AAGzC;;;;;KA4EK,WAAA;AAAA,KAEA,QAAA,eACW,MAAA,oBAA0B,MAAA;EA1EP;;;EAgFjC,UAAA,GAAa,sBAAA,CAAuB,KAAA,EAAO,OAAA;EAzEvB;;;;;;;;;EAoFpB,OAAA,GAAU,WAAA;AAAA;AAAA,KAaP,WAAA,eACW,MAAA,oBAA0B,MAAA,wCAEtC,QAAA,CAAS,KAAA,EAAO,OAAA;EArGlB,uEAuGA,IAAA;EAEA,WAAA;EACA,UAAA;EACA,QAAA;EACA,OAAA;EACA,aAAA;EACA,oCAAA;EACA,eAAA;AAAA;;;;;;;;KAUG,sBAAA,eACW,MAAA,oBAA0B,MAAA,wCAEtC,QAAA,CAAS,KAAA,EAAO,OAAA;EAClB,IAAA,aAzG6B;EA4G7B,WAAA,uBA3GM;EA6GN,UAAA,GAAa,gBAAA,CAAiB,KAAA,IAAS,WAAA,cA3GpC;EA6GH,QAAA,YA7Ga;EA+Gb,OAAA,GAAU,mBAAA,CAAoB,KAAA,EAAO,OAAA,GA/GjB;EAiHpB,aAAA,GAAgB,uBAAA,CAAwB,KAAA,EAAO,OAAA,GApHV;EAsHrC,oCAAA,GAAuC,+BAAA,CAAgC,OAAA;EACvE,eAAA,GAAkB,eAAA;AAAA;AAAA,KAGf,YAAA,eACW,MAAA,oBAA0B,MAAA,wCAEtC,QAAA,CAAS,KAAA,EAAO,OAAA;EA1Hf,qDA4HH,IAAA,cA5HqB;EA+HrB,WAAA,uBA/H4B;EAiI5B,UAAA,EAAY,gBAAA,CAAiB,KAAA,IAAS,WAAA,EA/HN;EAiIhC,QAAA,YAhIc;EAkId,OAAA,GAAU,mBAAA,CAAoB,KAAA,EAAO,OAAA,GA/Hd;EAiIvB,aAAA,GAAgB,uBAAA,CAAwB,KAAA,EAAO,OAAA,GAjIvC;EAmIR,oCAAA,GAAuC,+BAAA,CAAgC,OAAA;EACvE,eAAA,GAAkB,eAAA;AAAA;AAAA,KAGf,SAAA,eACW,MAAA,oBAA0B,MAAA,wCAEtC,QAAA,CAAS,KAAA,EAAO,OAAA;EA7IJ,qEA+Id,IAAA,WA9IA;EAiJA,WAAA,uBA/IuB;EAiJvB,UAAA,EAAY,gBAAA,CAAiB,KAAA,IAAS,WAAA,EAjJtC;EAmJA,QAAA,YAlJA;EAoJA,OAAA;EACA,OAAA;EACA,aAAA;EACA,oCAAA;EACA,eAAA,GAAkB,eAAA;AAAA;AAAA,KAGf,YAAA,eACW,MAAA,oBAA0B,MAAA,wCAEtC,QAAA,CAAS,KAAA,EAAO,OAAA;EA3J4B,kEA6J9C,IAAA,cA3JO;EA8JP,UAAA,yBA/IU;EAiJV,UAAA,GAAa,gBAAA,CAAiB,KAAA,IAAS,WAAA;EAEvC,IAAA,EAAM,MAAA;EAnJ2C;AAAmB;;EAuJpE,uBAAA;EAEA,WAAA;EACA,QAAA;EACA,OAAA;EACA,aAAA;EACA,oCAAA;EACA,eAAA,GAAkB,eAAA;AAAA;AAAA,KAGR,eAAA;EAzIiC,2EA4IvC,IAAA;EACA,GAAA;EACA,OAAA,GAAU,MAAA;EACV,QAAA;AAAA;EArJU,0DAyJV,IAAA;EACA,OAAA;EACA,IAAA;EACA,GAAA,GAAM,MAAM;EACZ,GAAA;AAAA;AAAA,KAGD,OAAA,GAAU,QAAA,CAAS,MAAA;EA/IZ,2DAiJV,IAAA;EACA,MAAA,EAAQ,eAAA;EAER,WAAA;EACA,UAAA;EACA,QAAA;EACA,OAAA;EACA,aAAA;EACA,oCAAA;EACA,eAAA;AAAA;;;;;;;;;;;;;;;;;;;AAhIe;AAAA;;;;;;;;;;;;;;;;;;;;;;KA4KL,IAAA,eACI,MAAA,oBAA0B,MAAA,wCAGtC,YAAA,CAAa,KAAA,EAAO,OAAA,IACpB,WAAA,CAAY,KAAA,EAAO,OAAA,IACnB,SAAA,CAAU,KAAA,EAAO,OAAA,IACjB,YAAA,CAAa,KAAA,EAAO,OAAA,IACpB,OAAA,GACA,eAAA,CAAgB,KAAA,EAAO,OAAA;;;;;;;KAQf,eAAA,eACI,MAAA,oBAA0B,MAAA,wCAGtC,YAAA,CAAa,KAAA,EAAO,OAAA,IACpB,sBAAA,CAAuB,KAAA,EAAO,OAAA,IAC9B,SAAA,CAAU,KAAA,EAAO,OAAA,IACjB,YAAA,CAAa,KAAA,EAAO,OAAA,IACpB,OAAA,GACA,eAAA,CAAgB,KAAA,EAAO,OAAA;;;;KAKf,eAAA,eACI,MAAA,oBAA0B,MAAA,yCAGtC,IAAA,CAAK,YAAA,CAAa,KAAA,EAAO,OAAA,aACzB,IAAA,CAAK,WAAA,CAAY,KAAA,EAAO,OAAA,aACxB,IAAA,CAAK,SAAA,CAAU,KAAA,EAAO,OAAA,aACtB,IAAA,CAAK,YAAA,CAAa,KAAA,EAAO,OAAA;EACvB,IAAA;AAAA"}
1
+ {"version":3,"file":"tool-types.d.ts","names":[],"sources":["../../../src/core/tool/tool-types.ts"],"mappings":"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"}
@@ -36,6 +36,16 @@ type ToolCallStatus = {
36
36
  type: "incomplete";
37
37
  reason: "cancelled" | "length" | "content-filter" | "other";
38
38
  };
39
+ /**
40
+ * Wall-clock timing of a tool call. Accumulator-populated timings are
41
+ * measured by the consuming accumulator, so resumed or replayed streams
42
+ * re-measure them; hosts that need authoritative timings supply the field
43
+ * themselves.
44
+ */
45
+ type ToolCallTiming = {
46
+ /** Epoch milliseconds when the tool call started streaming or executing. */readonly startedAt: number; /** Epoch milliseconds when the result landed. Absent while the call runs. */
47
+ readonly completedAt?: number;
48
+ };
39
49
  type ToolCallPartBase = {
40
50
  type: "tool-call";
41
51
  status: ToolCallStatus;
@@ -43,6 +53,7 @@ type ToolCallPartBase = {
43
53
  toolName: string;
44
54
  argsText: string;
45
55
  args: ReadonlyJSONObject;
56
+ timing?: ToolCallTiming;
46
57
  artifact?: ReadonlyJSONValue;
47
58
  result?: ReadonlyJSONValue;
48
59
  modelContent?: readonly ToolModelContentPart[];
@@ -137,5 +148,5 @@ type AssistantMessage = {
137
148
  };
138
149
  };
139
150
  //#endregion
140
- export { AssistantMessage, AssistantMessagePart, AssistantMessageStatus, AssistantMessageTiming, DataPart, FilePart, ReasoningPart, SourcePart, TextPart, ToolCallPart };
151
+ export { AssistantMessage, AssistantMessagePart, AssistantMessageStatus, AssistantMessageTiming, DataPart, FilePart, ReasoningPart, SourcePart, TextPart, ToolCallPart, ToolCallTiming };
141
152
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","names":[],"sources":["../../../src/core/utils/types.ts"],"mappings":";;;;KAMK,UAAA;EAEC,IAAA;AAAA;EAGA,IAAA;EACA,MAAA;AAAA;EAGA,IAAA;EACA,MAAA;AAAA;AAAA,KAOM,QAAA;EACV,IAAA;EACA,IAAA;EACA,MAAA,EAAQ,UAAU;EAClB,QAAA;AAAA;AAAA,KAGU,aAAA;EACV,IAAA;EACA,IAAA;EACA,MAAA,EAAQ,UAAU;EAClB,QAAA;AAAA;AAAA,KAGG,cAAA;EAEC,IAAA;EACA,cAAA;AAAA;EAGA,IAAA;EACA,MAAA;AAAA;EAGA,IAAA;EACA,MAAA;AAAA;EAGA,IAAA;EACA,MAAA;AAAA;AAAA,KAGD,gBAAA;EACH,IAAA;EACA,MAAA,EAAQ,cAAA;EACR,UAAA;EACA,QAAA;EACA,QAAA;EACA,IAAA,EAAM,kBAAA;EACN,QAAA,GAAW,iBAAA;EACX,MAAA,GAAS,iBAAA;EACT,YAAA,YAAwB,oBAAA;EACxB,OAAA;EACA,QAAA;AAAA;AAAA,KAGG,yBAAA,GAA4B,gBAAgB;EAC/C,KAAA;EACA,MAAA;EACA,YAAA;AAAA;AAAA,KAGG,sBAAA,GAAyB,gBAAA;EAC5B,KAAA;EACA,MAAA,EAAQ,iBAAA;EACR,QAAA,GAAW,iBAAA;EACX,YAAA,YAAwB,oBAAA;EACxB,OAAA;AAAA;AAAA,KAGU,YAAA,GAAe,yBAAA,GAA4B,sBAAsB;AAAA,KAEjE,UAAA;EACV,IAAA;EACA,UAAA;EACA,EAAA;EACA,GAAA;EACA,KAAA;EACA,QAAA;AAAA;AAAA,KAGU,QAAA;EACV,IAAA;EACA,IAAA;EACA,QAAA;EACA,QAAA;AAAA;AAAA,KAGU,QAAA;EACV,IAAA;EACA,IAAA;EACA,IAAA,EAAM,iBAAiB;EACvB,QAAA;AAAA;AAAA,KAGU,oBAAA,GACR,QAAA,GACA,aAAA,GACA,YAAA,GACA,UAAA,GACA,QAAA,GACA,QAAA;AAAA,KAEC,yBAAA;EACH,WAAA;EACA,YAAY;AAAA;AAAA,KAGT,4BAAA;EAEC,KAAA;EACA,SAAA;AAAA;EAGA,KAAA;EACA,SAAA;EACA,YAAA;EAQA,KAAA,GAAQ,yBAAyB;EACjC,WAAA;AAAA;AAAA,KAGM,sBAAA;EAEN,IAAA;AAAA;EAGA,IAAA;EACA,MAAA;AAAA;EAGA,IAAA;EACA,MAAA;AAAA;EAGA,IAAA;EACA,MAAA;EAOA,KAAA,GAAQ,iBAAiB;AAAA;AAAA,KAGnB,sBAAA;2DAEV,eAAA,UApF2E;EAsF3E,cAAA,WApFoB;EAsFpB,eAAA,WAtFoB;EAwFpB,UAAA,WAtFA;EAwFA,eAAA,WAtFA;EAwFA,WAAA,UAtFA;EAwFA,aAAA;AAAA;AAAA,KAGU,gBAAA;EACV,IAAA;EACA,MAAA,EAAQ,sBAAA;EACR,KAAA,EAAO,oBAAA;EA1FP;;;EA8FA,OAAA,EAAS,oBAAA;EAET,QAAA;IACE,cAAA,EAAgB,iBAAA;IAChB,aAAA,EAAe,iBAAA;IACf,oBAAA,EAAsB,iBAAA;IACtB,KAAA,EAAO,4BAAA;IACP,MAAA,EAAQ,MAAA;IACR,MAAA,GAAS,sBAAA;EAAA;AAAA"}
1
+ {"version":3,"file":"types.d.ts","names":[],"sources":["../../../src/core/utils/types.ts"],"mappings":";;;;KAMK,UAAA;EAEC,IAAA;AAAA;EAGA,IAAA;EACA,MAAA;AAAA;EAGA,IAAA;EACA,MAAA;AAAA;AAAA,KAOM,QAAA;EACV,IAAA;EACA,IAAA;EACA,MAAA,EAAQ,UAAU;EAClB,QAAA;AAAA;AAAA,KAGU,aAAA;EACV,IAAA;EACA,IAAA;EACA,MAAA,EAAQ,UAAU;EAClB,QAAA;AAAA;AAAA,KAGG,cAAA;EAEC,IAAA;EACA,cAAA;AAAA;EAGA,IAAA;EACA,MAAA;AAAA;EAGA,IAAA;EACA,MAAA;AAAA;EAGA,IAAA;EACA,MAAA;AAAA;AAlBI;AACR;;;;;AADQ,KA2BE,cAAA;EAlBN,qFAoBK,SAAA,UAhBL;EAAA,SAkBK,WAAW;AAAA;AAAA,KAGjB,gBAAA;EACH,IAAA;EACA,MAAA,EAAQ,cAAA;EACR,UAAA;EACA,QAAA;EACA,QAAA;EACA,IAAA,EAAM,kBAAA;EACN,MAAA,GAAS,cAAA;EACT,QAAA,GAAW,iBAAA;EACX,MAAA,GAAS,iBAAA;EACT,YAAA,YAAwB,oBAAA;EACxB,OAAA;EACA,QAAA;AAAA;AAAA,KAGG,yBAAA,GAA4B,gBAAgB;EAC/C,KAAA;EACA,MAAA;EACA,YAAA;AAAA;AAAA,KAGG,sBAAA,GAAyB,gBAAA;EAC5B,KAAA;EACA,MAAA,EAAQ,iBAAA;EACR,QAAA,GAAW,iBAAA;EACX,YAAA,YAAwB,oBAAA;EACxB,OAAA;AAAA;AAAA,KAGU,YAAA,GAAe,yBAAA,GAA4B,sBAAsB;AAAA,KAEjE,UAAA;EACV,IAAA;EACA,UAAA;EACA,EAAA;EACA,GAAA;EACA,KAAA;EACA,QAAA;AAAA;AAAA,KAGU,QAAA;EACV,IAAA;EACA,IAAA;EACA,QAAA;EACA,QAAA;AAAA;AAAA,KAGU,QAAA;EACV,IAAA;EACA,IAAA;EACA,IAAA,EAAM,iBAAiB;EACvB,QAAA;AAAA;AAAA,KAGU,oBAAA,GACR,QAAA,GACA,aAAA,GACA,YAAA,GACA,UAAA,GACA,QAAA,GACA,QAAA;AAAA,KAEC,yBAAA;EACH,WAAA;EACA,YAAY;AAAA;AAAA,KAGT,4BAAA;EAEC,KAAA;EACA,SAAA;AAAA;EAGA,KAAA;EACA,SAAA;EACA,YAAA;EAQA,KAAA,GAAQ,yBAAyB;EACjC,WAAA;AAAA;AAAA,KAGM,sBAAA;EAEN,IAAA;AAAA;EAGA,IAAA;EACA,MAAA;AAAA;EAGA,IAAA;EACA,MAAA;AAAA;EAGA,IAAA;EACA,MAAA;EAOA,KAAA,GAAQ,iBAAiB;AAAA;AAAA,KAGnB,sBAAA;2DAEV,eAAA,UAjFA;EAmFA,cAAA,WAjFA;EAmFA,eAAA,WAjFA;EAmFA,UAAA,WAlFQ;EAoFR,eAAA,WAjFU;EAmFV,WAAA;EAEA,aAAA;AAAA;AAAA,KAGU,gBAAA;EACV,IAAA;EACA,MAAA,EAAQ,sBAAA;EACR,KAAA,EAAO,oBAAA;EAvFC;AAGV;;EAwFE,OAAA,EAAS,oBAAA;EAET,QAAA;IACE,cAAA,EAAgB,iBAAA;IAChB,aAAA,EAAe,iBAAA;IACf,oBAAA,EAAsB,iBAAA;IACtB,KAAA,EAAO,4BAAA;IACP,MAAA,EAAQ,MAAA;IACR,MAAA,GAAS,sBAAA;EAAA;AAAA"}
package/dist/index.d.ts CHANGED
@@ -2,7 +2,7 @@ import { TextStreamController } from "./core/modules/text.js";
2
2
  import { McpServerConfig, ProviderOptions, Tool, ToolCallReader, ToolDeclaration, ToolModelContentPart, ToolModelOutputFunction } from "./core/tool/tool-types.js";
3
3
  import { ToolResponse, ToolResponseLike } from "./core/tool/ToolResponse.js";
4
4
  import { ToolCallStreamController } from "./core/modules/tool-call.js";
5
- import { AssistantMessage, AssistantMessageTiming, DataPart } from "./core/utils/types.js";
5
+ import { AssistantMessage, AssistantMessageTiming, DataPart, ToolCallTiming } from "./core/utils/types.js";
6
6
  import { AssistantStreamController, createAssistantStream, createAssistantStreamController, createAssistantStreamResponse } from "./core/modules/assistant-stream.js";
7
7
  import { ObjectStreamChunk } from "./core/object/types.js";
8
8
  import { AssistantStreamChunk } from "./core/AssistantStreamChunk.js";
@@ -20,4 +20,4 @@ import { UIMessageStreamDecoder, UIMessageStreamDecoderOptions } from "./core/se
20
20
  import { ToolExecutionStream } from "./core/tool/ToolExecutionStream.js";
21
21
  import { ToToolsJSONSchemaOptions, ToolJSONSchema, toJSONSchema, toPartialJSONSchema, toToolsJSONSchema } from "./core/tool/schema-utils.js";
22
22
  import { ToolResultStreamOptions, toolResultStream, unstable_runPendingTools } from "./core/tool/toolResultStream.js";
23
- export { type AssistantMessage, AssistantMessageAccumulator, AssistantMessageStream, type AssistantMessageTiming, AssistantStream, type AssistantStreamChunk, type AssistantStreamController, AssistantTransportDecoder, AssistantTransportEncoder, type DataPart, DataStreamDecoder, DataStreamEncoder, type GenericAssistantMessage, type GenericFilePart, type GenericMessage, type GenericSystemMessage, type GenericTextPart, type GenericToolCallPart, type GenericToolMessage, type GenericToolResultPart, type GenericUserMessage, type McpServerConfig, type ObjectStreamChunk, ObjectStreamResponse, PlainTextDecoder, PlainTextEncoder, type ProviderOptions, type TextStreamController, type ToToolsJSONSchemaOptions, type Tool, type ToolCallReader, type ToolCallStreamController, type ToolDeclaration, ToolExecutionStream, type ToolJSONSchema, type ToolModelContentPart, type ToolModelOutputFunction, ToolResponse, type ToolResponseLike, type ToolResultStreamOptions, type UIMessageStreamChunk, type UIMessageStreamDataChunk, UIMessageStreamDecoder, type UIMessageStreamDecoderOptions, createAssistantStream, createAssistantStreamController, createAssistantStreamResponse, createObjectStream, fromObjectStreamResponse, toGenericMessages, toJSONSchema, toPartialJSONSchema, toToolsJSONSchema, createInitialMessage as unstable_createInitialMessage, unstable_runPendingTools, toolResultStream as unstable_toolResultStream };
23
+ export { type AssistantMessage, AssistantMessageAccumulator, AssistantMessageStream, type AssistantMessageTiming, AssistantStream, type AssistantStreamChunk, type AssistantStreamController, AssistantTransportDecoder, AssistantTransportEncoder, type DataPart, DataStreamDecoder, DataStreamEncoder, type GenericAssistantMessage, type GenericFilePart, type GenericMessage, type GenericSystemMessage, type GenericTextPart, type GenericToolCallPart, type GenericToolMessage, type GenericToolResultPart, type GenericUserMessage, type McpServerConfig, type ObjectStreamChunk, ObjectStreamResponse, PlainTextDecoder, PlainTextEncoder, type ProviderOptions, type TextStreamController, type ToToolsJSONSchemaOptions, type Tool, type ToolCallReader, type ToolCallStreamController, type ToolCallTiming, type ToolDeclaration, ToolExecutionStream, type ToolJSONSchema, type ToolModelContentPart, type ToolModelOutputFunction, ToolResponse, type ToolResponseLike, type ToolResultStreamOptions, type UIMessageStreamChunk, type UIMessageStreamDataChunk, UIMessageStreamDecoder, type UIMessageStreamDecoderOptions, createAssistantStream, createAssistantStreamController, createAssistantStreamResponse, createObjectStream, fromObjectStreamResponse, toGenericMessages, toJSONSchema, toPartialJSONSchema, toToolsJSONSchema, createInitialMessage as unstable_createInitialMessage, unstable_runPendingTools, toolResultStream as unstable_toolResultStream };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "assistant-stream",
3
- "version": "0.3.21",
3
+ "version": "0.3.23",
4
4
  "description": "Streaming utilities for AI assistants",
5
5
  "keywords": [
6
6
  "ai",
@@ -67,7 +67,7 @@
67
67
  "ioredis": "^5.11.1",
68
68
  "redis": "^6.0.0",
69
69
  "vitest": "^4.1.8",
70
- "@assistant-ui/x-buildutils": "0.0.12"
70
+ "@assistant-ui/x-buildutils": "0.0.14"
71
71
  },
72
72
  "publishConfig": {
73
73
  "access": "public",
@@ -101,6 +101,57 @@ describe("AssistantMessageAccumulator timing", () => {
101
101
  expect(last.metadata.timing!.toolCallCount).toBe(1);
102
102
  });
103
103
 
104
+ it("should record per-tool-call timing on the part", async () => {
105
+ const before = Date.now();
106
+ const chunks: AssistantStreamChunk[] = [
107
+ {
108
+ type: "part-start",
109
+ path: [0],
110
+ part: {
111
+ type: "tool-call",
112
+ toolCallId: "tc-1",
113
+ toolName: "search",
114
+ },
115
+ },
116
+ { type: "text-delta", path: [0], textDelta: '{"q":"test"}' },
117
+ { type: "tool-call-args-text-finish", path: [0] },
118
+ {
119
+ type: "result",
120
+ path: [0],
121
+ result: "found",
122
+ isError: false,
123
+ },
124
+ { type: "part-finish", path: [0] },
125
+ {
126
+ type: "message-finish",
127
+ path: [],
128
+ finishReason: "stop",
129
+ usage: { inputTokens: 0, outputTokens: 0 },
130
+ },
131
+ ];
132
+
133
+ const messages = await collectStream(chunks);
134
+ const after = Date.now();
135
+
136
+ const runningPart = messages
137
+ .find((m) =>
138
+ m.parts.some((p) => p.type === "tool-call" && p.state !== "result"),
139
+ )!
140
+ .parts.find((p) => p.type === "tool-call")!;
141
+ expect(runningPart.timing).toBeDefined();
142
+ expect(runningPart.timing!.startedAt).toBeGreaterThanOrEqual(before);
143
+ expect(runningPart.timing!.completedAt).toBeUndefined();
144
+
145
+ const settledPart = messages
146
+ .at(-1)!
147
+ .parts.find((p) => p.type === "tool-call")!;
148
+ expect(settledPart.timing).toBeDefined();
149
+ expect(settledPart.timing!.completedAt).toBeGreaterThanOrEqual(
150
+ settledPart.timing!.startedAt,
151
+ );
152
+ expect(settledPart.timing!.completedAt).toBeLessThanOrEqual(after);
153
+ });
154
+
104
155
  it("should include timing on flush when stream closes without message-finish", async () => {
105
156
  const chunks: AssistantStreamChunk[] = [
106
157
  { type: "part-start", path: [0], part: { type: "text" } },
@@ -92,6 +92,7 @@ const handlePartStart = (
92
92
  toolName: partInit.toolName,
93
93
  argsText: "",
94
94
  args: {},
95
+ timing: { startedAt: Date.now() },
95
96
  ...(partInit.parentId && { parentId: partInit.parentId }),
96
97
  };
97
98
  return {
@@ -213,6 +214,14 @@ const handleResult = (
213
214
  return {
214
215
  ...part,
215
216
  state: "result",
217
+ ...(part.timing !== undefined
218
+ ? {
219
+ timing: {
220
+ ...part.timing,
221
+ completedAt: part.timing.completedAt ?? Date.now(),
222
+ },
223
+ }
224
+ : {}),
216
225
  ...(chunk.artifact !== undefined ? { artifact: chunk.artifact } : {}),
217
226
  result: chunk.result,
218
227
  isError: chunk.isError ?? false,
@@ -407,7 +407,7 @@ export class ToolCallArgsReaderImpl<
407
407
 
408
408
  forEach<PathT extends TypePath<T>>(
409
409
  ...fieldPath: PathT
410
- ): TypeAtPath<T, PathT> extends Array<infer U>
410
+ ): NonNullable<TypeAtPath<T, PathT>> extends Array<infer U>
411
411
  ? AsyncIterableStream<U>
412
412
  : never {
413
413
  // Use a type assertion to convert the complex TypePath to a simple array
@@ -110,7 +110,7 @@ export interface ToolCallArgsReader<TArgs extends Record<string, unknown>> {
110
110
  */
111
111
  forEach<PathT extends TypePath<TArgs>>(
112
112
  ...fieldPath: PathT
113
- ): TypeAtPath<TArgs, PathT> extends Array<infer U>
113
+ ): NonNullable<TypeAtPath<TArgs, PathT>> extends Array<infer U>
114
114
  ? AsyncIterableStream<U>
115
115
  : never;
116
116
  }
@@ -53,6 +53,19 @@ type ToolCallStatus =
53
53
  reason: "cancelled" | "length" | "content-filter" | "other";
54
54
  };
55
55
 
56
+ /**
57
+ * Wall-clock timing of a tool call. Accumulator-populated timings are
58
+ * measured by the consuming accumulator, so resumed or replayed streams
59
+ * re-measure them; hosts that need authoritative timings supply the field
60
+ * themselves.
61
+ */
62
+ export type ToolCallTiming = {
63
+ /** Epoch milliseconds when the tool call started streaming or executing. */
64
+ readonly startedAt: number;
65
+ /** Epoch milliseconds when the result landed. Absent while the call runs. */
66
+ readonly completedAt?: number;
67
+ };
68
+
56
69
  type ToolCallPartBase = {
57
70
  type: "tool-call";
58
71
  status: ToolCallStatus;
@@ -60,6 +73,7 @@ type ToolCallPartBase = {
60
73
  toolName: string;
61
74
  argsText: string;
62
75
  args: ReadonlyJSONObject;
76
+ timing?: ToolCallTiming;
63
77
  artifact?: ReadonlyJSONValue;
64
78
  result?: ReadonlyJSONValue;
65
79
  modelContent?: readonly ToolModelContentPart[];
package/src/index.ts CHANGED
@@ -33,6 +33,7 @@ export type {
33
33
  AssistantMessage,
34
34
  AssistantMessageTiming,
35
35
  DataPart,
36
+ ToolCallTiming,
36
37
  } from "./core/utils/types";
37
38
 
38
39
  export type {
@@ -145,7 +145,17 @@ describe("resumable integration", () => {
145
145
  new AssistantTransportDecoder(),
146
146
  );
147
147
 
148
- expect(replayMessage.parts).toEqual(producerMessage.parts);
148
+ // Tool-call timing is measured by the consuming accumulator, so a replay
149
+ // re-measures it; compare parts modulo timing.
150
+ const withoutTiming = (parts: typeof replayMessage.parts) =>
151
+ parts.map((part) =>
152
+ part.type === "tool-call"
153
+ ? (({ timing: _timing, ...rest }) => rest)(part)
154
+ : part,
155
+ );
156
+ expect(withoutTiming(replayMessage.parts)).toEqual(
157
+ withoutTiming(producerMessage.parts),
158
+ );
149
159
  expect(replayMessage.status).toEqual(producerMessage.status);
150
160
  const toolPart = replayMessage.parts.find((p) => p.type === "tool-call");
151
161
  expect(toolPart).toBeDefined();
@@ -154,6 +164,7 @@ describe("resumable integration", () => {
154
164
  toolCallId: "tool-1",
155
165
  args: { query: "weather" },
156
166
  result: { temperature: 72 },
167
+ timing: { startedAt: expect.any(Number) },
157
168
  });
158
169
  });
159
170
  });