assistant-stream 0.2.12 → 0.2.14

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;AAuUxB,qBAAa,2BAA4B,SAAQ,eAAe,CAC9D,oBAAoB,EACpB,gBAAgB,CACjB;gBACa,EACV,cAAc,GACf,GAAE;QACD,cAAc,CAAC,EAAE,gBAAgB,CAAC;KAC9B;CAsEP"}
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;AAyUxB,qBAAa,2BAA4B,SAAQ,eAAe,CAC9D,oBAAoB,EACpB,gBAAgB,CACjB;gBACa,EACV,cAAc,GACf,GAAE;QACD,cAAc,CAAC,EAAE,gBAAgB,CAAC;KAC9B;CAsEP"}
@@ -106,8 +106,7 @@ var handleToolCallArgsTextFinish = (message, chunk) => {
106
106
  if (part.type !== "tool-call") {
107
107
  throw new Error("Last is not a tool call");
108
108
  }
109
- if (part.state !== "partial-call")
110
- throw new Error("Last is not a partial call");
109
+ if (part.state !== "partial-call") return part;
111
110
  return {
112
111
  ...part,
113
112
  state: "call"
@@ -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\";\n\nconst createInitialMessage = (): AssistantMessage => ({\n role: \"assistant\",\n status: { type: \"running\" },\n parts: [],\n get content() {\n return this.parts;\n },\n metadata: {\n unstable_state: null,\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 };\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 };\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 };\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 if (part.state !== \"partial-call\")\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 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 // TODO this test isn't sound\n const requiresAction = message.parts?.at(-1)?.type === \"tool-call\";\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\";\n\nconst createInitialMessage = (): AssistantMessage => ({\n role: \"assistant\",\n status: { type: \"running\" },\n parts: [],\n get content() {\n return this.parts;\n },\n metadata: {\n unstable_state: null,\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 };\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 };\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 };\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 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 // TODO this test isn't sound\n const requiresAction = message.parts?.at(-1)?.type === \"tool-call\";\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":[]}
@@ -4,13 +4,13 @@ import { TextStreamController } from "./text";
4
4
  import { ToolCallStreamController } from "./tool-call";
5
5
  import { FilePart, SourcePart } from "../utils/types";
6
6
  import { ReadonlyJSONObject, ReadonlyJSONValue } from "../../utils/json/json-value";
7
- import { ToolResponseInit } from "../tool/ToolResponse";
7
+ import { ToolResponseLike } from "../tool/ToolResponse";
8
8
  type ToolCallPartInit = {
9
9
  toolCallId?: string;
10
10
  toolName: string;
11
11
  argsText?: string;
12
12
  args?: ReadonlyJSONObject;
13
- response?: ToolResponseInit<ReadonlyJSONValue>;
13
+ response?: ToolResponseLike<ReadonlyJSONValue>;
14
14
  };
15
15
  export type AssistantStreamController = {
16
16
  appendText(textDelta: string): void;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/core/modules/assistant-stream.ts"],"sourcesContent":["import { AssistantStream } from \"../AssistantStream\";\nimport { AssistantStreamChunk, PartInit } from \"../AssistantStreamChunk\";\nimport { createMergeStream } from \"../utils/stream/merge\";\nimport { createTextStreamController, TextStreamController } from \"./text\";\nimport {\n createToolCallStreamController,\n ToolCallStreamController,\n} from \"./tool-call\";\nimport { Counter } from \"../utils/Counter\";\nimport {\n PathAppendEncoder,\n PathMergeEncoder,\n} from \"../utils/stream/path-utils\";\nimport { DataStreamEncoder } from \"../serialization/data-stream/DataStream\";\nimport { FilePart, SourcePart } from \"../utils/types\";\nimport { generateId } from \"../utils/generateId\";\nimport {\n ReadonlyJSONObject,\n ReadonlyJSONValue,\n} from \"../../utils/json/json-value\";\nimport { ToolResponseInit } from \"../tool/ToolResponse\";\nimport { promiseWithResolvers } from \"../../utils/promiseWithResolvers\";\n\ntype ToolCallPartInit = {\n toolCallId?: string;\n toolName: string;\n argsText?: string;\n args?: ReadonlyJSONObject;\n response?: ToolResponseInit<ReadonlyJSONValue>;\n};\n\nexport type AssistantStreamController = {\n appendText(textDelta: string): void;\n appendReasoning(reasoningDelta: string): void;\n appendSource(options: SourcePart): void;\n appendFile(options: FilePart): void;\n addTextPart(): TextStreamController;\n addToolCallPart(options: string): ToolCallStreamController;\n addToolCallPart(options: ToolCallPartInit): ToolCallStreamController;\n enqueue(chunk: AssistantStreamChunk): void;\n merge(stream: AssistantStream): void;\n close(): void;\n};\n\nclass AssistantStreamControllerImpl implements AssistantStreamController {\n private _merger = createMergeStream();\n private _append:\n | {\n controller: TextStreamController;\n kind: \"text\" | \"reasoning\";\n }\n | undefined;\n private _contentCounter = new Counter();\n\n get __internal_isClosed() {\n return this._merger.isSealed();\n }\n\n __internal_getReadable() {\n return this._merger.readable;\n }\n\n private _closeSubscriber: undefined | (() => void);\n __internal_subscribeToClose(callback: () => void) {\n this._closeSubscriber = callback;\n }\n\n private _addPart(part: PartInit, stream: AssistantStream) {\n if (this._append) {\n this._append.controller.close();\n this._append = undefined;\n }\n\n this.enqueue({\n type: \"part-start\",\n part,\n path: [],\n });\n this._merger.addStream(\n stream.pipeThrough(new PathAppendEncoder(this._contentCounter.value)),\n );\n }\n\n merge(stream: AssistantStream) {\n this._merger.addStream(\n stream.pipeThrough(new PathMergeEncoder(this._contentCounter)),\n );\n }\n\n appendText(textDelta: string) {\n if (this._append?.kind !== \"text\") {\n this._append = {\n kind: \"text\",\n controller: this.addTextPart(),\n };\n }\n this._append.controller.append(textDelta);\n }\n\n appendReasoning(textDelta: string) {\n if (this._append?.kind !== \"reasoning\") {\n this._append = {\n kind: \"reasoning\",\n controller: this.addReasoningPart(),\n };\n }\n this._append.controller.append(textDelta);\n }\n\n addTextPart() {\n const [stream, controller] = createTextStreamController();\n this._addPart({ type: \"text\" }, stream);\n return controller;\n }\n\n addReasoningPart() {\n const [stream, controller] = createTextStreamController();\n this._addPart({ type: \"reasoning\" }, stream);\n return controller;\n }\n\n addToolCallPart(\n options: string | ToolCallPartInit,\n ): ToolCallStreamController {\n const opt = typeof options === \"string\" ? { toolName: options } : options;\n const toolName = opt.toolName;\n const toolCallId = opt.toolCallId ?? generateId();\n\n const [stream, controller] = createToolCallStreamController();\n this._addPart({ type: \"tool-call\", toolName, toolCallId }, stream);\n\n if (opt.argsText !== undefined) {\n controller.argsText.append(opt.argsText);\n controller.argsText.close();\n }\n if (opt.args !== undefined) {\n controller.argsText.append(JSON.stringify(opt.args));\n controller.argsText.close();\n }\n if (opt.response !== undefined) {\n controller.setResponse(opt.response);\n }\n\n return controller;\n }\n\n appendSource(options: SourcePart) {\n this._addPart(\n options,\n new ReadableStream({\n start(controller) {\n controller.enqueue({\n type: \"part-finish\",\n path: [],\n });\n controller.close();\n },\n }),\n );\n }\n\n appendFile(options: FilePart) {\n this._addPart(\n options,\n new ReadableStream({\n start(controller) {\n controller.enqueue({\n type: \"part-finish\",\n path: [],\n });\n controller.close();\n },\n }),\n );\n }\n\n enqueue(chunk: AssistantStreamChunk) {\n this._merger.enqueue(chunk);\n\n if (chunk.type === \"part-start\" && chunk.path.length === 0) {\n this._contentCounter.up();\n }\n }\n\n close() {\n this._merger.seal();\n this._append?.controller?.close();\n\n this._closeSubscriber?.();\n }\n}\n\nexport function createAssistantStream(\n callback: (controller: AssistantStreamController) => PromiseLike<void> | void,\n): AssistantStream {\n const controller = new AssistantStreamControllerImpl();\n\n let promiseOrVoid: PromiseLike<void> | void;\n try {\n promiseOrVoid = callback(controller);\n } catch (e) {\n if (!controller.__internal_isClosed) {\n controller.enqueue({\n type: \"error\",\n path: [],\n error: String(e),\n });\n controller.close();\n }\n throw e;\n }\n\n if (promiseOrVoid instanceof Promise) {\n const runTask = async () => {\n try {\n await promiseOrVoid;\n } catch (e) {\n if (!controller.__internal_isClosed) {\n controller.enqueue({\n type: \"error\",\n path: [],\n error: String(e),\n });\n }\n throw e;\n } finally {\n if (!controller.__internal_isClosed) {\n controller.close();\n }\n }\n };\n runTask();\n } else {\n if (!controller.__internal_isClosed) {\n controller.close();\n }\n }\n\n return controller.__internal_getReadable();\n}\n\nexport function createAssistantStreamController() {\n const { resolve, promise } = promiseWithResolvers<void>();\n let controller!: AssistantStreamController;\n const stream = createAssistantStream((c) => {\n controller = c;\n\n (controller as AssistantStreamControllerImpl).__internal_subscribeToClose(\n resolve,\n );\n\n return promise;\n });\n return [stream, controller] as const;\n}\n\nexport function createAssistantStreamResponse(\n callback: (controller: AssistantStreamController) => PromiseLike<void> | void,\n) {\n return AssistantStream.toResponse(\n createAssistantStream(callback),\n new DataStreamEncoder(),\n );\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../src/core/modules/assistant-stream.ts"],"sourcesContent":["import { AssistantStream } from \"../AssistantStream\";\nimport { AssistantStreamChunk, PartInit } from \"../AssistantStreamChunk\";\nimport { createMergeStream } from \"../utils/stream/merge\";\nimport { createTextStreamController, TextStreamController } from \"./text\";\nimport {\n createToolCallStreamController,\n ToolCallStreamController,\n} from \"./tool-call\";\nimport { Counter } from \"../utils/Counter\";\nimport {\n PathAppendEncoder,\n PathMergeEncoder,\n} from \"../utils/stream/path-utils\";\nimport { DataStreamEncoder } from \"../serialization/data-stream/DataStream\";\nimport { FilePart, SourcePart } from \"../utils/types\";\nimport { generateId } from \"../utils/generateId\";\nimport {\n ReadonlyJSONObject,\n ReadonlyJSONValue,\n} from \"../../utils/json/json-value\";\nimport { ToolResponseLike } from \"../tool/ToolResponse\";\nimport { promiseWithResolvers } from \"../../utils/promiseWithResolvers\";\n\ntype ToolCallPartInit = {\n toolCallId?: string;\n toolName: string;\n argsText?: string;\n args?: ReadonlyJSONObject;\n response?: ToolResponseLike<ReadonlyJSONValue>;\n};\n\nexport type AssistantStreamController = {\n appendText(textDelta: string): void;\n appendReasoning(reasoningDelta: string): void;\n appendSource(options: SourcePart): void;\n appendFile(options: FilePart): void;\n addTextPart(): TextStreamController;\n addToolCallPart(options: string): ToolCallStreamController;\n addToolCallPart(options: ToolCallPartInit): ToolCallStreamController;\n enqueue(chunk: AssistantStreamChunk): void;\n merge(stream: AssistantStream): void;\n close(): void;\n};\n\nclass AssistantStreamControllerImpl implements AssistantStreamController {\n private _merger = createMergeStream();\n private _append:\n | {\n controller: TextStreamController;\n kind: \"text\" | \"reasoning\";\n }\n | undefined;\n private _contentCounter = new Counter();\n\n get __internal_isClosed() {\n return this._merger.isSealed();\n }\n\n __internal_getReadable() {\n return this._merger.readable;\n }\n\n private _closeSubscriber: undefined | (() => void);\n __internal_subscribeToClose(callback: () => void) {\n this._closeSubscriber = callback;\n }\n\n private _addPart(part: PartInit, stream: AssistantStream) {\n if (this._append) {\n this._append.controller.close();\n this._append = undefined;\n }\n\n this.enqueue({\n type: \"part-start\",\n part,\n path: [],\n });\n this._merger.addStream(\n stream.pipeThrough(new PathAppendEncoder(this._contentCounter.value)),\n );\n }\n\n merge(stream: AssistantStream) {\n this._merger.addStream(\n stream.pipeThrough(new PathMergeEncoder(this._contentCounter)),\n );\n }\n\n appendText(textDelta: string) {\n if (this._append?.kind !== \"text\") {\n this._append = {\n kind: \"text\",\n controller: this.addTextPart(),\n };\n }\n this._append.controller.append(textDelta);\n }\n\n appendReasoning(textDelta: string) {\n if (this._append?.kind !== \"reasoning\") {\n this._append = {\n kind: \"reasoning\",\n controller: this.addReasoningPart(),\n };\n }\n this._append.controller.append(textDelta);\n }\n\n addTextPart() {\n const [stream, controller] = createTextStreamController();\n this._addPart({ type: \"text\" }, stream);\n return controller;\n }\n\n addReasoningPart() {\n const [stream, controller] = createTextStreamController();\n this._addPart({ type: \"reasoning\" }, stream);\n return controller;\n }\n\n addToolCallPart(\n options: string | ToolCallPartInit,\n ): ToolCallStreamController {\n const opt = typeof options === \"string\" ? { toolName: options } : options;\n const toolName = opt.toolName;\n const toolCallId = opt.toolCallId ?? generateId();\n\n const [stream, controller] = createToolCallStreamController();\n this._addPart({ type: \"tool-call\", toolName, toolCallId }, stream);\n\n if (opt.argsText !== undefined) {\n controller.argsText.append(opt.argsText);\n controller.argsText.close();\n }\n if (opt.args !== undefined) {\n controller.argsText.append(JSON.stringify(opt.args));\n controller.argsText.close();\n }\n if (opt.response !== undefined) {\n controller.setResponse(opt.response);\n }\n\n return controller;\n }\n\n appendSource(options: SourcePart) {\n this._addPart(\n options,\n new ReadableStream({\n start(controller) {\n controller.enqueue({\n type: \"part-finish\",\n path: [],\n });\n controller.close();\n },\n }),\n );\n }\n\n appendFile(options: FilePart) {\n this._addPart(\n options,\n new ReadableStream({\n start(controller) {\n controller.enqueue({\n type: \"part-finish\",\n path: [],\n });\n controller.close();\n },\n }),\n );\n }\n\n enqueue(chunk: AssistantStreamChunk) {\n this._merger.enqueue(chunk);\n\n if (chunk.type === \"part-start\" && chunk.path.length === 0) {\n this._contentCounter.up();\n }\n }\n\n close() {\n this._merger.seal();\n this._append?.controller?.close();\n\n this._closeSubscriber?.();\n }\n}\n\nexport function createAssistantStream(\n callback: (controller: AssistantStreamController) => PromiseLike<void> | void,\n): AssistantStream {\n const controller = new AssistantStreamControllerImpl();\n\n let promiseOrVoid: PromiseLike<void> | void;\n try {\n promiseOrVoid = callback(controller);\n } catch (e) {\n if (!controller.__internal_isClosed) {\n controller.enqueue({\n type: \"error\",\n path: [],\n error: String(e),\n });\n controller.close();\n }\n throw e;\n }\n\n if (promiseOrVoid instanceof Promise) {\n const runTask = async () => {\n try {\n await promiseOrVoid;\n } catch (e) {\n if (!controller.__internal_isClosed) {\n controller.enqueue({\n type: \"error\",\n path: [],\n error: String(e),\n });\n }\n throw e;\n } finally {\n if (!controller.__internal_isClosed) {\n controller.close();\n }\n }\n };\n runTask();\n } else {\n if (!controller.__internal_isClosed) {\n controller.close();\n }\n }\n\n return controller.__internal_getReadable();\n}\n\nexport function createAssistantStreamController() {\n const { resolve, promise } = promiseWithResolvers<void>();\n let controller!: AssistantStreamController;\n const stream = createAssistantStream((c) => {\n controller = c;\n\n (controller as AssistantStreamControllerImpl).__internal_subscribeToClose(\n resolve,\n );\n\n return promise;\n });\n return [stream, controller] as const;\n}\n\nexport function createAssistantStreamResponse(\n callback: (controller: AssistantStreamController) => PromiseLike<void> | void,\n) {\n return AssistantStream.toResponse(\n createAssistantStream(callback),\n new DataStreamEncoder(),\n );\n}\n"],"mappings":"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","names":[]}
@@ -1,11 +1,11 @@
1
1
  import { AssistantStream } from "../AssistantStream";
2
- import { ToolResponseInit } from "../tool/ToolResponse";
2
+ import { ToolResponseLike } from "../tool/ToolResponse";
3
3
  import { ReadonlyJSONValue } from "../../utils/json/json-value";
4
4
  import { UnderlyingReadable } from "../utils/stream/UnderlyingReadable";
5
5
  import { TextStreamController } from "./text";
6
6
  export type ToolCallStreamController = {
7
7
  argsText: TextStreamController;
8
- setResponse(response: ToolResponseInit<ReadonlyJSONValue>): void;
8
+ setResponse(response: ToolResponseLike<ReadonlyJSONValue>): void;
9
9
  close(): void;
10
10
  };
11
11
  export declare const createToolCallStream: (readable: UnderlyingReadable<ToolCallStreamController>) => AssistantStream;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/core/modules/tool-call.ts"],"sourcesContent":["import { AssistantStream } from \"../AssistantStream\";\nimport { AssistantStreamChunk } from \"../AssistantStreamChunk\";\nimport { ToolResponseInit } from \"../tool/ToolResponse\";\nimport { ReadonlyJSONValue } from \"../../utils/json/json-value\";\nimport { UnderlyingReadable } from \"../utils/stream/UnderlyingReadable\";\nimport { createTextStream, TextStreamController } from \"./text\";\n\nexport type ToolCallStreamController = {\n argsText: TextStreamController;\n\n setResponse(response: ToolResponseInit<ReadonlyJSONValue>): void;\n close(): void;\n};\n\nclass ToolCallStreamControllerImpl implements ToolCallStreamController {\n private _isClosed = false;\n\n private _mergeTask: Promise<void>;\n constructor(\n private _controller: ReadableStreamDefaultController<AssistantStreamChunk>,\n ) {\n const stream = createTextStream({\n start: (c) => {\n this._argsTextController = c;\n },\n });\n this._mergeTask = stream.pipeTo(\n new WritableStream({\n write: (chunk) => {\n switch (chunk.type) {\n case \"text-delta\":\n this._controller.enqueue(chunk);\n break;\n\n case \"part-finish\":\n this._controller.enqueue({\n type: \"tool-call-args-text-finish\",\n path: [],\n });\n break;\n\n default:\n throw new Error(`Unexpected chunk type: ${chunk.type}`);\n }\n },\n }),\n );\n }\n\n get argsText() {\n return this._argsTextController;\n }\n\n private _argsTextController!: TextStreamController;\n\n async setResponse(response: ToolResponseInit<ReadonlyJSONValue>) {\n this._argsTextController.close();\n await Promise.resolve(); // flush microtask queue\n // TODO switch argsTextController to be something that doesn'#t require this\n this._controller.enqueue({\n type: \"result\",\n path: [],\n ...(response.artifact !== undefined\n ? { artifact: response.artifact }\n : {}),\n result: response.result,\n isError: response.isError ?? false,\n });\n }\n\n async close() {\n if (this._isClosed) return;\n\n this._isClosed = true;\n this._argsTextController.close();\n await this._mergeTask;\n\n this._controller.enqueue({\n type: \"part-finish\",\n path: [],\n });\n this._controller.close();\n }\n}\n\nexport const createToolCallStream = (\n readable: UnderlyingReadable<ToolCallStreamController>,\n): AssistantStream => {\n return new ReadableStream({\n start(c) {\n return readable.start?.(new ToolCallStreamControllerImpl(c));\n },\n pull(c) {\n return readable.pull?.(new ToolCallStreamControllerImpl(c));\n },\n cancel(c) {\n return readable.cancel?.(c);\n },\n });\n};\n\nexport const createToolCallStreamController = () => {\n let controller!: ToolCallStreamController;\n const stream = createToolCallStream({\n start(c) {\n controller = c;\n },\n });\n return [stream, controller] as const;\n};\n"],"mappings":";AAKA,SAAS,wBAA8C;AASvD,IAAM,+BAAN,MAAuE;AAAA,EAIrE,YACU,aACR;AADQ;AAER,UAAM,SAAS,iBAAiB;AAAA,MAC9B,OAAO,CAAC,MAAM;AACZ,aAAK,sBAAsB;AAAA,MAC7B;AAAA,IACF,CAAC;AACD,SAAK,aAAa,OAAO;AAAA,MACvB,IAAI,eAAe;AAAA,QACjB,OAAO,CAAC,UAAU;AAChB,kBAAQ,MAAM,MAAM;AAAA,YAClB,KAAK;AACH,mBAAK,YAAY,QAAQ,KAAK;AAC9B;AAAA,YAEF,KAAK;AACH,mBAAK,YAAY,QAAQ;AAAA,gBACvB,MAAM;AAAA,gBACN,MAAM,CAAC;AAAA,cACT,CAAC;AACD;AAAA,YAEF;AACE,oBAAM,IAAI,MAAM,0BAA0B,MAAM,IAAI,EAAE;AAAA,UAC1D;AAAA,QACF;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EAhCQ,YAAY;AAAA,EAEZ;AAAA,EAgCR,IAAI,WAAW;AACb,WAAO,KAAK;AAAA,EACd;AAAA,EAEQ;AAAA,EAER,MAAM,YAAY,UAA+C;AAC/D,SAAK,oBAAoB,MAAM;AAC/B,UAAM,QAAQ,QAAQ;AAEtB,SAAK,YAAY,QAAQ;AAAA,MACvB,MAAM;AAAA,MACN,MAAM,CAAC;AAAA,MACP,GAAI,SAAS,aAAa,SACtB,EAAE,UAAU,SAAS,SAAS,IAC9B,CAAC;AAAA,MACL,QAAQ,SAAS;AAAA,MACjB,SAAS,SAAS,WAAW;AAAA,IAC/B,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,QAAQ;AACZ,QAAI,KAAK,UAAW;AAEpB,SAAK,YAAY;AACjB,SAAK,oBAAoB,MAAM;AAC/B,UAAM,KAAK;AAEX,SAAK,YAAY,QAAQ;AAAA,MACvB,MAAM;AAAA,MACN,MAAM,CAAC;AAAA,IACT,CAAC;AACD,SAAK,YAAY,MAAM;AAAA,EACzB;AACF;AAEO,IAAM,uBAAuB,CAClC,aACoB;AACpB,SAAO,IAAI,eAAe;AAAA,IACxB,MAAM,GAAG;AACP,aAAO,SAAS,QAAQ,IAAI,6BAA6B,CAAC,CAAC;AAAA,IAC7D;AAAA,IACA,KAAK,GAAG;AACN,aAAO,SAAS,OAAO,IAAI,6BAA6B,CAAC,CAAC;AAAA,IAC5D;AAAA,IACA,OAAO,GAAG;AACR,aAAO,SAAS,SAAS,CAAC;AAAA,IAC5B;AAAA,EACF,CAAC;AACH;AAEO,IAAM,iCAAiC,MAAM;AAClD,MAAI;AACJ,QAAM,SAAS,qBAAqB;AAAA,IAClC,MAAM,GAAG;AACP,mBAAa;AAAA,IACf;AAAA,EACF,CAAC;AACD,SAAO,CAAC,QAAQ,UAAU;AAC5B;","names":[]}
1
+ {"version":3,"sources":["../../../src/core/modules/tool-call.ts"],"sourcesContent":["import { AssistantStream } from \"../AssistantStream\";\nimport { AssistantStreamChunk } from \"../AssistantStreamChunk\";\nimport { ToolResponseLike } from \"../tool/ToolResponse\";\nimport { ReadonlyJSONValue } from \"../../utils/json/json-value\";\nimport { UnderlyingReadable } from \"../utils/stream/UnderlyingReadable\";\nimport { createTextStream, TextStreamController } from \"./text\";\n\nexport type ToolCallStreamController = {\n argsText: TextStreamController;\n\n setResponse(response: ToolResponseLike<ReadonlyJSONValue>): void;\n close(): void;\n};\n\nclass ToolCallStreamControllerImpl implements ToolCallStreamController {\n private _isClosed = false;\n\n private _mergeTask: Promise<void>;\n constructor(\n private _controller: ReadableStreamDefaultController<AssistantStreamChunk>,\n ) {\n const stream = createTextStream({\n start: (c) => {\n this._argsTextController = c;\n },\n });\n this._mergeTask = stream.pipeTo(\n new WritableStream({\n write: (chunk) => {\n switch (chunk.type) {\n case \"text-delta\":\n this._controller.enqueue(chunk);\n break;\n\n case \"part-finish\":\n this._controller.enqueue({\n type: \"tool-call-args-text-finish\",\n path: [],\n });\n break;\n\n default:\n throw new Error(`Unexpected chunk type: ${chunk.type}`);\n }\n },\n }),\n );\n }\n\n get argsText() {\n return this._argsTextController;\n }\n\n private _argsTextController!: TextStreamController;\n\n async setResponse(response: ToolResponseLike<ReadonlyJSONValue>) {\n this._argsTextController.close();\n await Promise.resolve(); // flush microtask queue\n // TODO switch argsTextController to be something that doesn'#t require this\n this._controller.enqueue({\n type: \"result\",\n path: [],\n ...(response.artifact !== undefined\n ? { artifact: response.artifact }\n : {}),\n result: response.result,\n isError: response.isError ?? false,\n });\n }\n\n async close() {\n if (this._isClosed) return;\n\n this._isClosed = true;\n this._argsTextController.close();\n await this._mergeTask;\n\n this._controller.enqueue({\n type: \"part-finish\",\n path: [],\n });\n this._controller.close();\n }\n}\n\nexport const createToolCallStream = (\n readable: UnderlyingReadable<ToolCallStreamController>,\n): AssistantStream => {\n return new ReadableStream({\n start(c) {\n return readable.start?.(new ToolCallStreamControllerImpl(c));\n },\n pull(c) {\n return readable.pull?.(new ToolCallStreamControllerImpl(c));\n },\n cancel(c) {\n return readable.cancel?.(c);\n },\n });\n};\n\nexport const createToolCallStreamController = () => {\n let controller!: ToolCallStreamController;\n const stream = createToolCallStream({\n start(c) {\n controller = c;\n },\n });\n return [stream, controller] as const;\n};\n"],"mappings":";AAKA,SAAS,wBAA8C;AASvD,IAAM,+BAAN,MAAuE;AAAA,EAIrE,YACU,aACR;AADQ;AAER,UAAM,SAAS,iBAAiB;AAAA,MAC9B,OAAO,CAAC,MAAM;AACZ,aAAK,sBAAsB;AAAA,MAC7B;AAAA,IACF,CAAC;AACD,SAAK,aAAa,OAAO;AAAA,MACvB,IAAI,eAAe;AAAA,QACjB,OAAO,CAAC,UAAU;AAChB,kBAAQ,MAAM,MAAM;AAAA,YAClB,KAAK;AACH,mBAAK,YAAY,QAAQ,KAAK;AAC9B;AAAA,YAEF,KAAK;AACH,mBAAK,YAAY,QAAQ;AAAA,gBACvB,MAAM;AAAA,gBACN,MAAM,CAAC;AAAA,cACT,CAAC;AACD;AAAA,YAEF;AACE,oBAAM,IAAI,MAAM,0BAA0B,MAAM,IAAI,EAAE;AAAA,UAC1D;AAAA,QACF;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EAhCQ,YAAY;AAAA,EAEZ;AAAA,EAgCR,IAAI,WAAW;AACb,WAAO,KAAK;AAAA,EACd;AAAA,EAEQ;AAAA,EAER,MAAM,YAAY,UAA+C;AAC/D,SAAK,oBAAoB,MAAM;AAC/B,UAAM,QAAQ,QAAQ;AAEtB,SAAK,YAAY,QAAQ;AAAA,MACvB,MAAM;AAAA,MACN,MAAM,CAAC;AAAA,MACP,GAAI,SAAS,aAAa,SACtB,EAAE,UAAU,SAAS,SAAS,IAC9B,CAAC;AAAA,MACL,QAAQ,SAAS;AAAA,MACjB,SAAS,SAAS,WAAW;AAAA,IAC/B,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,QAAQ;AACZ,QAAI,KAAK,UAAW;AAEpB,SAAK,YAAY;AACjB,SAAK,oBAAoB,MAAM;AAC/B,UAAM,KAAK;AAEX,SAAK,YAAY,QAAQ;AAAA,MACvB,MAAM;AAAA,MACN,MAAM,CAAC;AAAA,IACT,CAAC;AACD,SAAK,YAAY,MAAM;AAAA,EACzB;AACF;AAEO,IAAM,uBAAuB,CAClC,aACoB;AACpB,SAAO,IAAI,eAAe;AAAA,IACxB,MAAM,GAAG;AACP,aAAO,SAAS,QAAQ,IAAI,6BAA6B,CAAC,CAAC;AAAA,IAC7D;AAAA,IACA,KAAK,GAAG;AACN,aAAO,SAAS,OAAO,IAAI,6BAA6B,CAAC,CAAC;AAAA,IAC5D;AAAA,IACA,OAAO,GAAG;AACR,aAAO,SAAS,SAAS,CAAC;AAAA,IAC5B;AAAA,EACF,CAAC;AACH;AAEO,IAAM,iCAAiC,MAAM;AAClD,MAAI;AACJ,QAAM,SAAS,qBAAqB;AAAA,IAClC,MAAM,GAAG;AACP,mBAAa;AAAA,IACf;AAAA,EACF,CAAC;AACD,SAAO,CAAC,QAAQ,UAAU;AAC5B;","names":[]}
@@ -1,6 +1,6 @@
1
1
  import { ReadonlyJSONValue } from "../../utils/json/json-value";
2
2
  declare const TOOL_RESPONSE_SYMBOL: unique symbol;
3
- export type ToolResponseInit<TResult> = {
3
+ export type ToolResponseLike<TResult> = {
4
4
  result: TResult;
5
5
  artifact?: ReadonlyJSONValue | undefined;
6
6
  isError?: boolean | undefined;
@@ -10,8 +10,9 @@ export declare class ToolResponse<TResult> {
10
10
  readonly artifact?: ReadonlyJSONValue;
11
11
  readonly result: TResult;
12
12
  readonly isError: boolean;
13
- constructor(options: ToolResponseInit<TResult>);
13
+ constructor(options: ToolResponseLike<TResult>);
14
14
  static [Symbol.hasInstance](obj: unknown): obj is ToolResponse<ReadonlyJSONValue>;
15
+ static toResponse(result: any | ToolResponse<any>): ToolResponse<any>;
15
16
  }
16
17
  export {};
17
18
  //# sourceMappingURL=ToolResponse.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ToolResponse.d.ts","sourceRoot":"","sources":["../../../src/core/tool/ToolResponse.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAEhE,QAAA,MAAM,oBAAoB,eAAkC,CAAC;AAE7D,MAAM,MAAM,gBAAgB,CAAC,OAAO,IAAI;IACtC,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,CAAC,EAAE,iBAAiB,GAAG,SAAS,CAAC;IACzC,OAAO,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CAC/B,CAAC;AAEF,qBAAa,YAAY,CAAC,OAAO;IAC/B,IAAI,CAAC,oBAAoB,CAAC,YAEzB;IAED,QAAQ,CAAC,QAAQ,CAAC,EAAE,iBAAiB,CAAC;IACtC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;gBAEd,OAAO,EAAE,gBAAgB,CAAC,OAAO,CAAC;IAQ9C,MAAM,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CACzB,GAAG,EAAE,OAAO,GACX,GAAG,IAAI,YAAY,CAAC,iBAAiB,CAAC;CAK1C"}
1
+ {"version":3,"file":"ToolResponse.d.ts","sourceRoot":"","sources":["../../../src/core/tool/ToolResponse.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAEhE,QAAA,MAAM,oBAAoB,eAAkC,CAAC;AAE7D,MAAM,MAAM,gBAAgB,CAAC,OAAO,IAAI;IACtC,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,CAAC,EAAE,iBAAiB,GAAG,SAAS,CAAC;IACzC,OAAO,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CAC/B,CAAC;AAEF,qBAAa,YAAY,CAAC,OAAO;IAC/B,IAAI,CAAC,oBAAoB,CAAC,YAEzB;IAED,QAAQ,CAAC,QAAQ,CAAC,EAAE,iBAAiB,CAAC;IACtC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;gBAEd,OAAO,EAAE,gBAAgB,CAAC,OAAO,CAAC;IAQ9C,MAAM,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CACzB,GAAG,EAAE,OAAO,GACX,GAAG,IAAI,YAAY,CAAC,iBAAiB,CAAC;IAMzC,MAAM,CAAC,UAAU,CAAC,MAAM,EAAE,GAAG,GAAG,YAAY,CAAC,GAAG,CAAC,GAAG,YAAY,CAAC,GAAG,CAAC;CAQtE"}
@@ -1,6 +1,6 @@
1
1
  // src/core/tool/ToolResponse.ts
2
2
  var TOOL_RESPONSE_SYMBOL = Symbol.for("aui.tool-response");
3
- var ToolResponse = class {
3
+ var ToolResponse = class _ToolResponse {
4
4
  get [TOOL_RESPONSE_SYMBOL]() {
5
5
  return true;
6
6
  }
@@ -17,6 +17,14 @@ var ToolResponse = class {
17
17
  static [Symbol.hasInstance](obj) {
18
18
  return typeof obj === "object" && obj !== null && TOOL_RESPONSE_SYMBOL in obj;
19
19
  }
20
+ static toResponse(result) {
21
+ if (result instanceof _ToolResponse) {
22
+ return result;
23
+ }
24
+ return new _ToolResponse({
25
+ result: result === void 0 ? "<no result>" : result
26
+ });
27
+ }
20
28
  };
21
29
  export {
22
30
  ToolResponse
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/core/tool/ToolResponse.ts"],"sourcesContent":["import { ReadonlyJSONValue } from \"../../utils/json/json-value\";\n\nconst TOOL_RESPONSE_SYMBOL = Symbol.for(\"aui.tool-response\");\n\nexport type ToolResponseInit<TResult> = {\n result: TResult;\n artifact?: ReadonlyJSONValue | undefined;\n isError?: boolean | undefined;\n};\n\nexport class ToolResponse<TResult> {\n get [TOOL_RESPONSE_SYMBOL]() {\n return true;\n }\n\n readonly artifact?: ReadonlyJSONValue;\n readonly result: TResult;\n readonly isError: boolean;\n\n constructor(options: ToolResponseInit<TResult>) {\n if (options.artifact !== undefined) {\n this.artifact = options.artifact;\n }\n this.result = options.result;\n this.isError = options.isError ?? false;\n }\n\n static [Symbol.hasInstance](\n obj: unknown,\n ): obj is ToolResponse<ReadonlyJSONValue> {\n return (\n typeof obj === \"object\" && obj !== null && TOOL_RESPONSE_SYMBOL in obj\n );\n }\n}\n"],"mappings":";AAEA,IAAM,uBAAuB,OAAO,IAAI,mBAAmB;AAQpD,IAAM,eAAN,MAA4B;AAAA,EACjC,KAAK,oBAAoB,IAAI;AAC3B,WAAO;AAAA,EACT;AAAA,EAES;AAAA,EACA;AAAA,EACA;AAAA,EAET,YAAY,SAAoC;AAC9C,QAAI,QAAQ,aAAa,QAAW;AAClC,WAAK,WAAW,QAAQ;AAAA,IAC1B;AACA,SAAK,SAAS,QAAQ;AACtB,SAAK,UAAU,QAAQ,WAAW;AAAA,EACpC;AAAA,EAEA,QAAQ,OAAO,WAAW,EACxB,KACwC;AACxC,WACE,OAAO,QAAQ,YAAY,QAAQ,QAAQ,wBAAwB;AAAA,EAEvE;AACF;","names":[]}
1
+ {"version":3,"sources":["../../../src/core/tool/ToolResponse.ts"],"sourcesContent":["import { ReadonlyJSONValue } from \"../../utils/json/json-value\";\n\nconst TOOL_RESPONSE_SYMBOL = Symbol.for(\"aui.tool-response\");\n\nexport type ToolResponseLike<TResult> = {\n result: TResult;\n artifact?: ReadonlyJSONValue | undefined;\n isError?: boolean | undefined;\n};\n\nexport class ToolResponse<TResult> {\n get [TOOL_RESPONSE_SYMBOL]() {\n return true;\n }\n\n readonly artifact?: ReadonlyJSONValue;\n readonly result: TResult;\n readonly isError: boolean;\n\n constructor(options: ToolResponseLike<TResult>) {\n if (options.artifact !== undefined) {\n this.artifact = options.artifact;\n }\n this.result = options.result;\n this.isError = options.isError ?? false;\n }\n\n static [Symbol.hasInstance](\n obj: unknown,\n ): obj is ToolResponse<ReadonlyJSONValue> {\n return (\n typeof obj === \"object\" && obj !== null && TOOL_RESPONSE_SYMBOL in obj\n );\n }\n\n static toResponse(result: any | ToolResponse<any>): ToolResponse<any> {\n if (result instanceof ToolResponse) {\n return result;\n }\n return new ToolResponse({\n result: result === undefined ? \"<no result>\" : result,\n });\n }\n}\n"],"mappings":";AAEA,IAAM,uBAAuB,OAAO,IAAI,mBAAmB;AAQpD,IAAM,eAAN,MAAM,cAAsB;AAAA,EACjC,KAAK,oBAAoB,IAAI;AAC3B,WAAO;AAAA,EACT;AAAA,EAES;AAAA,EACA;AAAA,EACA;AAAA,EAET,YAAY,SAAoC;AAC9C,QAAI,QAAQ,aAAa,QAAW;AAClC,WAAK,WAAW,QAAQ;AAAA,IAC1B;AACA,SAAK,SAAS,QAAQ;AACtB,SAAK,UAAU,QAAQ,WAAW;AAAA,EACpC;AAAA,EAEA,QAAQ,OAAO,WAAW,EACxB,KACwC;AACxC,WACE,OAAO,QAAQ,YAAY,QAAQ,QAAQ,wBAAwB;AAAA,EAEvE;AAAA,EAEA,OAAO,WAAW,QAAoD;AACpE,QAAI,kBAAkB,eAAc;AAClC,aAAO;AAAA,IACT;AACA,WAAO,IAAI,cAAa;AAAA,MACtB,QAAQ,WAAW,SAAY,gBAAgB;AAAA,IACjD,CAAC;AAAA,EACH;AACF;","names":[]}
@@ -1,5 +1,5 @@
1
1
  export type { Tool } from "./tool-types";
2
- export { ToolResponse } from "./ToolResponse";
2
+ export { ToolResponse, type ToolResponseLike } from "./ToolResponse";
3
3
  export { ToolExecutionStream } from "./ToolExecutionStream";
4
4
  export type { ToolCallReader } from "./tool-types";
5
5
  export { toolResultStream as unstable_toolResultStream, unstable_runPendingTools, } from "./toolResultStream";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/tool/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,YAAY,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EACL,gBAAgB,IAAI,yBAAyB,EAC7C,wBAAwB,GACzB,MAAM,oBAAoB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/tool/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,KAAK,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AACrE,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,YAAY,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EACL,gBAAgB,IAAI,yBAAyB,EAC7C,wBAAwB,GACzB,MAAM,oBAAoB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/core/tool/index.ts"],"sourcesContent":["export type { Tool } from \"./tool-types\";\nexport { ToolResponse } from \"./ToolResponse\";\nexport { ToolExecutionStream } from \"./ToolExecutionStream\";\nexport type { ToolCallReader } from \"./tool-types\";\nexport {\n toolResultStream as unstable_toolResultStream,\n unstable_runPendingTools,\n} from \"./toolResultStream\";\n"],"mappings":";AACA,SAAS,oBAAoB;AAC7B,SAAS,2BAA2B;AAEpC;AAAA,EACsB;AAAA,EACpB;AAAA,OACK;","names":[]}
1
+ {"version":3,"sources":["../../../src/core/tool/index.ts"],"sourcesContent":["export type { Tool } from \"./tool-types\";\nexport { ToolResponse, type ToolResponseLike } from \"./ToolResponse\";\nexport { ToolExecutionStream } from \"./ToolExecutionStream\";\nexport type { ToolCallReader } from \"./tool-types\";\nexport {\n toolResultStream as unstable_toolResultStream,\n unstable_runPendingTools,\n} from \"./toolResultStream\";\n"],"mappings":";AACA,SAAS,oBAA2C;AACpD,SAAS,2BAA2B;AAEpC;AAAA,EACsB;AAAA,EACpB;AAAA,OACK;","names":[]}
@@ -1 +1 @@
1
- {"version":3,"file":"toolResultStream.d.ts","sourceRoot":"","sources":["../../../src/core/tool/toolResultStream.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAuC,MAAM,cAAc,CAAC;AAGzE,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AA2ElD,wBAAsB,wBAAwB,CAC5C,OAAO,EAAE,gBAAgB,EACzB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,GAAG,SAAS,EACvC,WAAW,EAAE,WAAW,6BA+BzB;AAED,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,GAAG,SAAS,EACvC,WAAW,EAAE,WAAW,uBAOzB"}
1
+ {"version":3,"file":"toolResultStream.d.ts","sourceRoot":"","sources":["../../../src/core/tool/toolResultStream.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAuC,MAAM,cAAc,CAAC;AAGzE,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAuElD,wBAAsB,wBAAwB,CAC5C,OAAO,EAAE,gBAAgB,EACzB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,GAAG,SAAS,EACvC,WAAW,EAAE,WAAW,6BA+BzB;AAED,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,GAAG,SAAS,EACvC,WAAW,EAAE,WAAW,uBAOzB"}
@@ -24,11 +24,7 @@ function getToolResponse(tools, abortSignal, toolCall) {
24
24
  toolCallId: toolCall.toolCallId,
25
25
  abortSignal
26
26
  });
27
- if (result instanceof ToolResponse)
28
- return result;
29
- return new ToolResponse({
30
- result: result === void 0 ? "<no result>" : result
31
- });
27
+ return ToolResponse.toResponse(result);
32
28
  };
33
29
  return getResult(tool.execute);
34
30
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/core/tool/toolResultStream.ts"],"sourcesContent":["import { Tool, ToolCallReader, ToolExecuteFunction } from \"./tool-types\";\nimport { StandardSchemaV1 } from \"@standard-schema/spec\";\nimport { ToolResponse } from \"./ToolResponse\";\nimport { ToolExecutionStream } from \"./ToolExecutionStream\";\nimport { AssistantMessage } from \"../utils/types\";\nimport { ReadonlyJSONObject, ReadonlyJSONValue } from \"../../utils\";\n\nconst isStandardSchemaV1 = (\n schema: unknown,\n): schema is StandardSchemaV1<unknown> => {\n return (\n typeof schema === \"object\" &&\n schema !== null &&\n \"~standard\" in schema &&\n (schema as StandardSchemaV1<unknown>)[\"~standard\"].version === 1\n );\n};\n\nfunction getToolResponse(\n tools: Record<string, Tool> | undefined,\n abortSignal: AbortSignal,\n toolCall: {\n toolCallId: string;\n toolName: string;\n args: ReadonlyJSONObject;\n },\n) {\n const tool = tools?.[toolCall.toolName];\n if (!tool || !tool.execute) return undefined;\n\n const getResult = async (\n toolExecute: ToolExecuteFunction<ReadonlyJSONObject, unknown>,\n ): Promise<ToolResponse<ReadonlyJSONValue>> => {\n let executeFn = toolExecute;\n\n if (isStandardSchemaV1(tool.parameters)) {\n let result = tool.parameters[\"~standard\"].validate(toolCall.args);\n if (result instanceof Promise) result = await result;\n\n if (result.issues) {\n executeFn =\n tool.experimental_onSchemaValidationError ??\n (() => {\n throw new Error(\n `Function parameter validation failed. ${JSON.stringify(result.issues)}`,\n );\n });\n }\n }\n\n const result = (await executeFn(toolCall.args, {\n toolCallId: toolCall.toolCallId,\n abortSignal,\n })) as unknown as ReadonlyJSONValue;\n if (result instanceof ToolResponse)\n return result as ToolResponse<ReadonlyJSONValue>;\n return new ToolResponse({\n result: result === undefined ? \"<no result>\" : result,\n });\n };\n\n return getResult(tool.execute);\n}\n\nfunction getToolStreamResponse(\n tools: Record<string, Tool> | undefined,\n abortSignal: AbortSignal,\n reader: ToolCallReader<any, ReadonlyJSONValue>,\n context: {\n toolCallId: string;\n toolName: string;\n },\n) {\n tools?.[context.toolName]?.streamCall?.(reader, {\n toolCallId: context.toolCallId,\n abortSignal,\n });\n}\n\nexport async function unstable_runPendingTools(\n message: AssistantMessage,\n tools: Record<string, Tool> | undefined,\n abortSignal: AbortSignal,\n) {\n // TODO parallel tool calling\n for (const part of message.parts) {\n if (part.type === \"tool-call\") {\n const promiseOrUndefined = getToolResponse(tools, abortSignal, part);\n if (promiseOrUndefined) {\n const result = await promiseOrUndefined;\n const updatedParts = message.parts.map((p) => {\n if (p.type === \"tool-call\" && p.toolCallId === part.toolCallId) {\n return {\n ...p,\n state: \"result\" as const,\n ...(result.artifact !== undefined\n ? { artifact: result.artifact }\n : {}),\n result: result.result as ReadonlyJSONValue,\n isError: result.isError,\n };\n }\n return p;\n });\n message = {\n ...message,\n parts: updatedParts,\n content: updatedParts,\n };\n }\n }\n }\n return message;\n}\n\nexport function toolResultStream(\n tools: Record<string, Tool> | undefined,\n abortSignal: AbortSignal,\n) {\n return new ToolExecutionStream({\n execute: (toolCall) => getToolResponse(tools, abortSignal, toolCall),\n streamCall: ({ reader, ...context }) =>\n getToolStreamResponse(tools, abortSignal, reader, context),\n });\n}\n"],"mappings":";AAEA,SAAS,oBAAoB;AAC7B,SAAS,2BAA2B;AAIpC,IAAM,qBAAqB,CACzB,WACwC;AACxC,SACE,OAAO,WAAW,YAClB,WAAW,QACX,eAAe,UACd,OAAqC,WAAW,EAAE,YAAY;AAEnE;AAEA,SAAS,gBACP,OACA,aACA,UAKA;AACA,QAAM,OAAO,QAAQ,SAAS,QAAQ;AACtC,MAAI,CAAC,QAAQ,CAAC,KAAK,QAAS,QAAO;AAEnC,QAAM,YAAY,OAChB,gBAC6C;AAC7C,QAAI,YAAY;AAEhB,QAAI,mBAAmB,KAAK,UAAU,GAAG;AACvC,UAAIA,UAAS,KAAK,WAAW,WAAW,EAAE,SAAS,SAAS,IAAI;AAChE,UAAIA,mBAAkB,QAAS,CAAAA,UAAS,MAAMA;AAE9C,UAAIA,QAAO,QAAQ;AACjB,oBACE,KAAK,yCACJ,MAAM;AACL,gBAAM,IAAI;AAAA,YACR,yCAAyC,KAAK,UAAUA,QAAO,MAAM,CAAC;AAAA,UACxE;AAAA,QACF;AAAA,MACJ;AAAA,IACF;AAEA,UAAM,SAAU,MAAM,UAAU,SAAS,MAAM;AAAA,MAC7C,YAAY,SAAS;AAAA,MACrB;AAAA,IACF,CAAC;AACD,QAAI,kBAAkB;AACpB,aAAO;AACT,WAAO,IAAI,aAAa;AAAA,MACtB,QAAQ,WAAW,SAAY,gBAAgB;AAAA,IACjD,CAAC;AAAA,EACH;AAEA,SAAO,UAAU,KAAK,OAAO;AAC/B;AAEA,SAAS,sBACP,OACA,aACA,QACA,SAIA;AACA,UAAQ,QAAQ,QAAQ,GAAG,aAAa,QAAQ;AAAA,IAC9C,YAAY,QAAQ;AAAA,IACpB;AAAA,EACF,CAAC;AACH;AAEA,eAAsB,yBACpB,SACA,OACA,aACA;AAEA,aAAW,QAAQ,QAAQ,OAAO;AAChC,QAAI,KAAK,SAAS,aAAa;AAC7B,YAAM,qBAAqB,gBAAgB,OAAO,aAAa,IAAI;AACnE,UAAI,oBAAoB;AACtB,cAAM,SAAS,MAAM;AACrB,cAAM,eAAe,QAAQ,MAAM,IAAI,CAAC,MAAM;AAC5C,cAAI,EAAE,SAAS,eAAe,EAAE,eAAe,KAAK,YAAY;AAC9D,mBAAO;AAAA,cACL,GAAG;AAAA,cACH,OAAO;AAAA,cACP,GAAI,OAAO,aAAa,SACpB,EAAE,UAAU,OAAO,SAAS,IAC5B,CAAC;AAAA,cACL,QAAQ,OAAO;AAAA,cACf,SAAS,OAAO;AAAA,YAClB;AAAA,UACF;AACA,iBAAO;AAAA,QACT,CAAC;AACD,kBAAU;AAAA,UACR,GAAG;AAAA,UACH,OAAO;AAAA,UACP,SAAS;AAAA,QACX;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAEO,SAAS,iBACd,OACA,aACA;AACA,SAAO,IAAI,oBAAoB;AAAA,IAC7B,SAAS,CAAC,aAAa,gBAAgB,OAAO,aAAa,QAAQ;AAAA,IACnE,YAAY,CAAC,EAAE,QAAQ,GAAG,QAAQ,MAChC,sBAAsB,OAAO,aAAa,QAAQ,OAAO;AAAA,EAC7D,CAAC;AACH;","names":["result"]}
1
+ {"version":3,"sources":["../../../src/core/tool/toolResultStream.ts"],"sourcesContent":["import { Tool, ToolCallReader, ToolExecuteFunction } from \"./tool-types\";\nimport { StandardSchemaV1 } from \"@standard-schema/spec\";\nimport { ToolResponse } from \"./ToolResponse\";\nimport { ToolExecutionStream } from \"./ToolExecutionStream\";\nimport { AssistantMessage } from \"../utils/types\";\nimport { ReadonlyJSONObject, ReadonlyJSONValue } from \"../../utils\";\n\nconst isStandardSchemaV1 = (\n schema: unknown,\n): schema is StandardSchemaV1<unknown> => {\n return (\n typeof schema === \"object\" &&\n schema !== null &&\n \"~standard\" in schema &&\n (schema as StandardSchemaV1<unknown>)[\"~standard\"].version === 1\n );\n};\n\nfunction getToolResponse(\n tools: Record<string, Tool> | undefined,\n abortSignal: AbortSignal,\n toolCall: {\n toolCallId: string;\n toolName: string;\n args: ReadonlyJSONObject;\n },\n) {\n const tool = tools?.[toolCall.toolName];\n if (!tool || !tool.execute) return undefined;\n\n const getResult = async (\n toolExecute: ToolExecuteFunction<ReadonlyJSONObject, unknown>,\n ): Promise<ToolResponse<ReadonlyJSONValue>> => {\n let executeFn = toolExecute;\n\n if (isStandardSchemaV1(tool.parameters)) {\n let result = tool.parameters[\"~standard\"].validate(toolCall.args);\n if (result instanceof Promise) result = await result;\n\n if (result.issues) {\n executeFn =\n tool.experimental_onSchemaValidationError ??\n (() => {\n throw new Error(\n `Function parameter validation failed. ${JSON.stringify(result.issues)}`,\n );\n });\n }\n }\n\n const result = (await executeFn(toolCall.args, {\n toolCallId: toolCall.toolCallId,\n abortSignal,\n })) as unknown as ReadonlyJSONValue;\n return ToolResponse.toResponse(result);\n };\n\n return getResult(tool.execute);\n}\n\nfunction getToolStreamResponse(\n tools: Record<string, Tool> | undefined,\n abortSignal: AbortSignal,\n reader: ToolCallReader<any, ReadonlyJSONValue>,\n context: {\n toolCallId: string;\n toolName: string;\n },\n) {\n tools?.[context.toolName]?.streamCall?.(reader, {\n toolCallId: context.toolCallId,\n abortSignal,\n });\n}\n\nexport async function unstable_runPendingTools(\n message: AssistantMessage,\n tools: Record<string, Tool> | undefined,\n abortSignal: AbortSignal,\n) {\n // TODO parallel tool calling\n for (const part of message.parts) {\n if (part.type === \"tool-call\") {\n const promiseOrUndefined = getToolResponse(tools, abortSignal, part);\n if (promiseOrUndefined) {\n const result = await promiseOrUndefined;\n const updatedParts = message.parts.map((p) => {\n if (p.type === \"tool-call\" && p.toolCallId === part.toolCallId) {\n return {\n ...p,\n state: \"result\" as const,\n ...(result.artifact !== undefined\n ? { artifact: result.artifact }\n : {}),\n result: result.result as ReadonlyJSONValue,\n isError: result.isError,\n };\n }\n return p;\n });\n message = {\n ...message,\n parts: updatedParts,\n content: updatedParts,\n };\n }\n }\n }\n return message;\n}\n\nexport function toolResultStream(\n tools: Record<string, Tool> | undefined,\n abortSignal: AbortSignal,\n) {\n return new ToolExecutionStream({\n execute: (toolCall) => getToolResponse(tools, abortSignal, toolCall),\n streamCall: ({ reader, ...context }) =>\n getToolStreamResponse(tools, abortSignal, reader, context),\n });\n}\n"],"mappings":";AAEA,SAAS,oBAAoB;AAC7B,SAAS,2BAA2B;AAIpC,IAAM,qBAAqB,CACzB,WACwC;AACxC,SACE,OAAO,WAAW,YAClB,WAAW,QACX,eAAe,UACd,OAAqC,WAAW,EAAE,YAAY;AAEnE;AAEA,SAAS,gBACP,OACA,aACA,UAKA;AACA,QAAM,OAAO,QAAQ,SAAS,QAAQ;AACtC,MAAI,CAAC,QAAQ,CAAC,KAAK,QAAS,QAAO;AAEnC,QAAM,YAAY,OAChB,gBAC6C;AAC7C,QAAI,YAAY;AAEhB,QAAI,mBAAmB,KAAK,UAAU,GAAG;AACvC,UAAIA,UAAS,KAAK,WAAW,WAAW,EAAE,SAAS,SAAS,IAAI;AAChE,UAAIA,mBAAkB,QAAS,CAAAA,UAAS,MAAMA;AAE9C,UAAIA,QAAO,QAAQ;AACjB,oBACE,KAAK,yCACJ,MAAM;AACL,gBAAM,IAAI;AAAA,YACR,yCAAyC,KAAK,UAAUA,QAAO,MAAM,CAAC;AAAA,UACxE;AAAA,QACF;AAAA,MACJ;AAAA,IACF;AAEA,UAAM,SAAU,MAAM,UAAU,SAAS,MAAM;AAAA,MAC7C,YAAY,SAAS;AAAA,MACrB;AAAA,IACF,CAAC;AACD,WAAO,aAAa,WAAW,MAAM;AAAA,EACvC;AAEA,SAAO,UAAU,KAAK,OAAO;AAC/B;AAEA,SAAS,sBACP,OACA,aACA,QACA,SAIA;AACA,UAAQ,QAAQ,QAAQ,GAAG,aAAa,QAAQ;AAAA,IAC9C,YAAY,QAAQ;AAAA,IACpB;AAAA,EACF,CAAC;AACH;AAEA,eAAsB,yBACpB,SACA,OACA,aACA;AAEA,aAAW,QAAQ,QAAQ,OAAO;AAChC,QAAI,KAAK,SAAS,aAAa;AAC7B,YAAM,qBAAqB,gBAAgB,OAAO,aAAa,IAAI;AACnE,UAAI,oBAAoB;AACtB,cAAM,SAAS,MAAM;AACrB,cAAM,eAAe,QAAQ,MAAM,IAAI,CAAC,MAAM;AAC5C,cAAI,EAAE,SAAS,eAAe,EAAE,eAAe,KAAK,YAAY;AAC9D,mBAAO;AAAA,cACL,GAAG;AAAA,cACH,OAAO;AAAA,cACP,GAAI,OAAO,aAAa,SACpB,EAAE,UAAU,OAAO,SAAS,IAC5B,CAAC;AAAA,cACL,QAAQ,OAAO;AAAA,cACf,SAAS,OAAO;AAAA,YAClB;AAAA,UACF;AACA,iBAAO;AAAA,QACT,CAAC;AACD,kBAAU;AAAA,UACR,GAAG;AAAA,UACH,OAAO;AAAA,UACP,SAAS;AAAA,QACX;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAEO,SAAS,iBACd,OACA,aACA;AACA,SAAO,IAAI,oBAAoB;AAAA,IAC7B,SAAS,CAAC,aAAa,gBAAgB,OAAO,aAAa,QAAQ;AAAA,IACnE,YAAY,CAAC,EAAE,QAAQ,GAAG,QAAQ,MAChC,sBAAsB,OAAO,aAAa,QAAQ,OAAO;AAAA,EAC7D,CAAC;AACH;","names":["result"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "assistant-stream",
3
- "version": "0.2.12",
3
+ "version": "0.2.14",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "exports": {
@@ -134,8 +134,10 @@ const handleToolCallArgsTextFinish = (
134
134
  if (part.type !== "tool-call") {
135
135
  throw new Error("Last is not a tool call");
136
136
  }
137
- if (part.state !== "partial-call")
138
- throw new Error("Last is not a partial call");
137
+
138
+ // TODO this should never be hit; this happens if args-text-finish is emitted after resutl
139
+ if (part.state !== "partial-call") return part;
140
+ // throw new Error("Last is not a partial call");
139
141
 
140
142
  return {
141
143
  ...part,
@@ -18,7 +18,7 @@ import {
18
18
  ReadonlyJSONObject,
19
19
  ReadonlyJSONValue,
20
20
  } from "../../utils/json/json-value";
21
- import { ToolResponseInit } from "../tool/ToolResponse";
21
+ import { ToolResponseLike } from "../tool/ToolResponse";
22
22
  import { promiseWithResolvers } from "../../utils/promiseWithResolvers";
23
23
 
24
24
  type ToolCallPartInit = {
@@ -26,7 +26,7 @@ type ToolCallPartInit = {
26
26
  toolName: string;
27
27
  argsText?: string;
28
28
  args?: ReadonlyJSONObject;
29
- response?: ToolResponseInit<ReadonlyJSONValue>;
29
+ response?: ToolResponseLike<ReadonlyJSONValue>;
30
30
  };
31
31
 
32
32
  export type AssistantStreamController = {
@@ -1,6 +1,6 @@
1
1
  import { AssistantStream } from "../AssistantStream";
2
2
  import { AssistantStreamChunk } from "../AssistantStreamChunk";
3
- import { ToolResponseInit } from "../tool/ToolResponse";
3
+ import { ToolResponseLike } from "../tool/ToolResponse";
4
4
  import { ReadonlyJSONValue } from "../../utils/json/json-value";
5
5
  import { UnderlyingReadable } from "../utils/stream/UnderlyingReadable";
6
6
  import { createTextStream, TextStreamController } from "./text";
@@ -8,7 +8,7 @@ import { createTextStream, TextStreamController } from "./text";
8
8
  export type ToolCallStreamController = {
9
9
  argsText: TextStreamController;
10
10
 
11
- setResponse(response: ToolResponseInit<ReadonlyJSONValue>): void;
11
+ setResponse(response: ToolResponseLike<ReadonlyJSONValue>): void;
12
12
  close(): void;
13
13
  };
14
14
 
@@ -53,7 +53,7 @@ class ToolCallStreamControllerImpl implements ToolCallStreamController {
53
53
 
54
54
  private _argsTextController!: TextStreamController;
55
55
 
56
- async setResponse(response: ToolResponseInit<ReadonlyJSONValue>) {
56
+ async setResponse(response: ToolResponseLike<ReadonlyJSONValue>) {
57
57
  this._argsTextController.close();
58
58
  await Promise.resolve(); // flush microtask queue
59
59
  // TODO switch argsTextController to be something that doesn'#t require this
@@ -2,7 +2,7 @@ import { ReadonlyJSONValue } from "../../utils/json/json-value";
2
2
 
3
3
  const TOOL_RESPONSE_SYMBOL = Symbol.for("aui.tool-response");
4
4
 
5
- export type ToolResponseInit<TResult> = {
5
+ export type ToolResponseLike<TResult> = {
6
6
  result: TResult;
7
7
  artifact?: ReadonlyJSONValue | undefined;
8
8
  isError?: boolean | undefined;
@@ -17,7 +17,7 @@ export class ToolResponse<TResult> {
17
17
  readonly result: TResult;
18
18
  readonly isError: boolean;
19
19
 
20
- constructor(options: ToolResponseInit<TResult>) {
20
+ constructor(options: ToolResponseLike<TResult>) {
21
21
  if (options.artifact !== undefined) {
22
22
  this.artifact = options.artifact;
23
23
  }
@@ -32,4 +32,13 @@ export class ToolResponse<TResult> {
32
32
  typeof obj === "object" && obj !== null && TOOL_RESPONSE_SYMBOL in obj
33
33
  );
34
34
  }
35
+
36
+ static toResponse(result: any | ToolResponse<any>): ToolResponse<any> {
37
+ if (result instanceof ToolResponse) {
38
+ return result;
39
+ }
40
+ return new ToolResponse({
41
+ result: result === undefined ? "<no result>" : result,
42
+ });
43
+ }
35
44
  }
@@ -1,5 +1,5 @@
1
1
  export type { Tool } from "./tool-types";
2
- export { ToolResponse } from "./ToolResponse";
2
+ export { ToolResponse, type ToolResponseLike } from "./ToolResponse";
3
3
  export { ToolExecutionStream } from "./ToolExecutionStream";
4
4
  export type { ToolCallReader } from "./tool-types";
5
5
  export {
@@ -52,11 +52,7 @@ function getToolResponse(
52
52
  toolCallId: toolCall.toolCallId,
53
53
  abortSignal,
54
54
  })) as unknown as ReadonlyJSONValue;
55
- if (result instanceof ToolResponse)
56
- return result as ToolResponse<ReadonlyJSONValue>;
57
- return new ToolResponse({
58
- result: result === undefined ? "<no result>" : result,
59
- });
55
+ return ToolResponse.toResponse(result);
60
56
  };
61
57
 
62
58
  return getResult(tool.execute);