assistant-stream 0.2.42 → 0.2.44

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.
Files changed (36) hide show
  1. package/dist/core/object/ObjectStreamAccumulator.js +1 -1
  2. package/dist/core/object/ObjectStreamAccumulator.js.map +1 -1
  3. package/dist/core/serialization/data-stream/DataStream.js +3 -3
  4. package/dist/core/serialization/data-stream/DataStream.js.map +1 -1
  5. package/dist/core/tool/ToolExecutionStream.d.ts +2 -0
  6. package/dist/core/tool/ToolExecutionStream.d.ts.map +1 -1
  7. package/dist/core/tool/ToolExecutionStream.js +13 -1
  8. package/dist/core/tool/ToolExecutionStream.js.map +1 -1
  9. package/dist/core/tool/ToolResponse.js +1 -1
  10. package/dist/core/tool/ToolResponse.js.map +1 -1
  11. package/dist/core/tool/index.d.ts +1 -1
  12. package/dist/core/tool/index.d.ts.map +1 -1
  13. package/dist/core/tool/index.js.map +1 -1
  14. package/dist/core/tool/toolResultStream.d.ts +5 -1
  15. package/dist/core/tool/toolResultStream.d.ts.map +1 -1
  16. package/dist/core/tool/toolResultStream.js +44 -12
  17. package/dist/core/tool/toolResultStream.js.map +1 -1
  18. package/dist/utils/index.d.ts +1 -1
  19. package/dist/utils/index.d.ts.map +1 -1
  20. package/dist/utils/index.js.map +1 -1
  21. package/dist/utils/json/fix-json.d.ts.map +1 -1
  22. package/dist/utils/json/fix-json.js +59 -61
  23. package/dist/utils/json/fix-json.js.map +1 -1
  24. package/dist/utils/json/index.d.ts +1 -1
  25. package/dist/utils/json/index.d.ts.map +1 -1
  26. package/dist/utils/json/parse-partial-json-object.js +1 -1
  27. package/package.json +4 -5
  28. package/src/core/object/ObjectStreamAccumulator.ts +1 -1
  29. package/src/core/serialization/data-stream/DataStream.ts +3 -3
  30. package/src/core/tool/ToolExecutionStream.ts +22 -1
  31. package/src/core/tool/index.ts +1 -0
  32. package/src/core/tool/toolResultStream.ts +50 -6
  33. package/src/utils/index.ts +1 -1
  34. package/src/utils/json/fix-json.ts +59 -61
  35. package/src/utils/json/index.ts +1 -1
  36. package/src/utils/json/parse-partial-json-object.test.ts +1 -1
@@ -43,7 +43,7 @@ var ObjectStreamAccumulator = class _ObjectStreamAccumulator {
43
43
  const [key, ...rest] = path;
44
44
  if (Array.isArray(state)) {
45
45
  const idx = Number(key);
46
- if (isNaN(idx))
46
+ if (Number.isNaN(idx))
47
47
  throw new Error(`Expected array index at [${path.join(", ")}]`);
48
48
  if (idx > state.length || idx < 0)
49
49
  throw new Error(`Insert array index out of bounds`);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/core/object/ObjectStreamAccumulator.ts"],"sourcesContent":["import { ReadonlyJSONValue, ReadonlyJSONObject } from \"../../utils\";\nimport { ObjectStreamOperation } from \"./types\";\n\nexport class ObjectStreamAccumulator {\n private _state: ReadonlyJSONValue;\n\n constructor(initialValue: ReadonlyJSONValue = null) {\n this._state = initialValue;\n }\n\n get state() {\n return this._state;\n }\n\n append(ops: readonly ObjectStreamOperation[]) {\n this._state = ops.reduce(\n (state, op) => ObjectStreamAccumulator.apply(state, op),\n this._state,\n );\n }\n\n private static apply(state: ReadonlyJSONValue, op: ObjectStreamOperation) {\n const type = op.type;\n switch (type) {\n case \"set\":\n return ObjectStreamAccumulator.updatePath(\n state,\n op.path,\n () => op.value,\n );\n case \"append-text\":\n return ObjectStreamAccumulator.updatePath(state, op.path, (current) => {\n if (typeof current !== \"string\")\n throw new Error(`Expected string at path [${op.path.join(\", \")}]`);\n return current + op.value;\n });\n\n default: {\n const _exhaustiveCheck: never = type;\n throw new Error(`Invalid operation type: ${_exhaustiveCheck}`);\n }\n }\n }\n\n private static updatePath(\n state: ReadonlyJSONValue | undefined,\n path: readonly string[],\n updater: (current: ReadonlyJSONValue | undefined) => ReadonlyJSONValue,\n ): ReadonlyJSONValue {\n if (path.length === 0) return updater(state);\n\n // Initialize state as empty object if it's null and we're trying to set a property\n state ??= {};\n\n if (typeof state !== \"object\") {\n throw new Error(`Invalid path: [${path.join(\", \")}]`);\n }\n\n const [key, ...rest] = path as [string, ...(readonly string[])];\n if (Array.isArray(state)) {\n const idx = Number(key);\n if (isNaN(idx))\n throw new Error(`Expected array index at [${path.join(\", \")}]`);\n if (idx > state.length || idx < 0)\n throw new Error(`Insert array index out of bounds`);\n\n const nextState = [...state];\n nextState[idx] = this.updatePath(nextState[idx], rest, updater);\n\n return nextState;\n }\n\n const nextState = { ...(state as ReadonlyJSONObject) };\n nextState[key] = this.updatePath(nextState[key], rest, updater);\n\n return nextState;\n }\n}\n"],"mappings":";AAGO,IAAM,0BAAN,MAAM,yBAAwB;AAAA,EAC3B;AAAA,EAER,YAAY,eAAkC,MAAM;AAClD,SAAK,SAAS;AAAA,EAChB;AAAA,EAEA,IAAI,QAAQ;AACV,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,OAAO,KAAuC;AAC5C,SAAK,SAAS,IAAI;AAAA,MAChB,CAAC,OAAO,OAAO,yBAAwB,MAAM,OAAO,EAAE;AAAA,MACtD,KAAK;AAAA,IACP;AAAA,EACF;AAAA,EAEA,OAAe,MAAM,OAA0B,IAA2B;AACxE,UAAM,OAAO,GAAG;AAChB,YAAQ,MAAM;AAAA,MACZ,KAAK;AACH,eAAO,yBAAwB;AAAA,UAC7B;AAAA,UACA,GAAG;AAAA,UACH,MAAM,GAAG;AAAA,QACX;AAAA,MACF,KAAK;AACH,eAAO,yBAAwB,WAAW,OAAO,GAAG,MAAM,CAAC,YAAY;AACrE,cAAI,OAAO,YAAY;AACrB,kBAAM,IAAI,MAAM,4BAA4B,GAAG,KAAK,KAAK,IAAI,CAAC,GAAG;AACnE,iBAAO,UAAU,GAAG;AAAA,QACtB,CAAC;AAAA,MAEH,SAAS;AACP,cAAM,mBAA0B;AAChC,cAAM,IAAI,MAAM,2BAA2B,gBAAgB,EAAE;AAAA,MAC/D;AAAA,IACF;AAAA,EACF;AAAA,EAEA,OAAe,WACb,OACA,MACA,SACmB;AACnB,QAAI,KAAK,WAAW,EAAG,QAAO,QAAQ,KAAK;AAG3C,cAAU,CAAC;AAEX,QAAI,OAAO,UAAU,UAAU;AAC7B,YAAM,IAAI,MAAM,kBAAkB,KAAK,KAAK,IAAI,CAAC,GAAG;AAAA,IACtD;AAEA,UAAM,CAAC,KAAK,GAAG,IAAI,IAAI;AACvB,QAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,YAAM,MAAM,OAAO,GAAG;AACtB,UAAI,MAAM,GAAG;AACX,cAAM,IAAI,MAAM,4BAA4B,KAAK,KAAK,IAAI,CAAC,GAAG;AAChE,UAAI,MAAM,MAAM,UAAU,MAAM;AAC9B,cAAM,IAAI,MAAM,kCAAkC;AAEpD,YAAMA,aAAY,CAAC,GAAG,KAAK;AAC3B,MAAAA,WAAU,GAAG,IAAI,KAAK,WAAWA,WAAU,GAAG,GAAG,MAAM,OAAO;AAE9D,aAAOA;AAAA,IACT;AAEA,UAAM,YAAY,EAAE,GAAI,MAA6B;AACrD,cAAU,GAAG,IAAI,KAAK,WAAW,UAAU,GAAG,GAAG,MAAM,OAAO;AAE9D,WAAO;AAAA,EACT;AACF;","names":["nextState"]}
1
+ {"version":3,"sources":["../../../src/core/object/ObjectStreamAccumulator.ts"],"sourcesContent":["import { ReadonlyJSONValue, ReadonlyJSONObject } from \"../../utils\";\nimport { ObjectStreamOperation } from \"./types\";\n\nexport class ObjectStreamAccumulator {\n private _state: ReadonlyJSONValue;\n\n constructor(initialValue: ReadonlyJSONValue = null) {\n this._state = initialValue;\n }\n\n get state() {\n return this._state;\n }\n\n append(ops: readonly ObjectStreamOperation[]) {\n this._state = ops.reduce(\n (state, op) => ObjectStreamAccumulator.apply(state, op),\n this._state,\n );\n }\n\n private static apply(state: ReadonlyJSONValue, op: ObjectStreamOperation) {\n const type = op.type;\n switch (type) {\n case \"set\":\n return ObjectStreamAccumulator.updatePath(\n state,\n op.path,\n () => op.value,\n );\n case \"append-text\":\n return ObjectStreamAccumulator.updatePath(state, op.path, (current) => {\n if (typeof current !== \"string\")\n throw new Error(`Expected string at path [${op.path.join(\", \")}]`);\n return current + op.value;\n });\n\n default: {\n const _exhaustiveCheck: never = type;\n throw new Error(`Invalid operation type: ${_exhaustiveCheck}`);\n }\n }\n }\n\n private static updatePath(\n state: ReadonlyJSONValue | undefined,\n path: readonly string[],\n updater: (current: ReadonlyJSONValue | undefined) => ReadonlyJSONValue,\n ): ReadonlyJSONValue {\n if (path.length === 0) return updater(state);\n\n // Initialize state as empty object if it's null and we're trying to set a property\n state ??= {};\n\n if (typeof state !== \"object\") {\n throw new Error(`Invalid path: [${path.join(\", \")}]`);\n }\n\n const [key, ...rest] = path as [string, ...(readonly string[])];\n if (Array.isArray(state)) {\n const idx = Number(key);\n if (Number.isNaN(idx))\n throw new Error(`Expected array index at [${path.join(\", \")}]`);\n if (idx > state.length || idx < 0)\n throw new Error(`Insert array index out of bounds`);\n\n const nextState = [...state];\n nextState[idx] = this.updatePath(nextState[idx], rest, updater);\n\n return nextState;\n }\n\n const nextState = { ...(state as ReadonlyJSONObject) };\n nextState[key] = this.updatePath(nextState[key], rest, updater);\n\n return nextState;\n }\n}\n"],"mappings":";AAGO,IAAM,0BAAN,MAAM,yBAAwB;AAAA,EAC3B;AAAA,EAER,YAAY,eAAkC,MAAM;AAClD,SAAK,SAAS;AAAA,EAChB;AAAA,EAEA,IAAI,QAAQ;AACV,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,OAAO,KAAuC;AAC5C,SAAK,SAAS,IAAI;AAAA,MAChB,CAAC,OAAO,OAAO,yBAAwB,MAAM,OAAO,EAAE;AAAA,MACtD,KAAK;AAAA,IACP;AAAA,EACF;AAAA,EAEA,OAAe,MAAM,OAA0B,IAA2B;AACxE,UAAM,OAAO,GAAG;AAChB,YAAQ,MAAM;AAAA,MACZ,KAAK;AACH,eAAO,yBAAwB;AAAA,UAC7B;AAAA,UACA,GAAG;AAAA,UACH,MAAM,GAAG;AAAA,QACX;AAAA,MACF,KAAK;AACH,eAAO,yBAAwB,WAAW,OAAO,GAAG,MAAM,CAAC,YAAY;AACrE,cAAI,OAAO,YAAY;AACrB,kBAAM,IAAI,MAAM,4BAA4B,GAAG,KAAK,KAAK,IAAI,CAAC,GAAG;AACnE,iBAAO,UAAU,GAAG;AAAA,QACtB,CAAC;AAAA,MAEH,SAAS;AACP,cAAM,mBAA0B;AAChC,cAAM,IAAI,MAAM,2BAA2B,gBAAgB,EAAE;AAAA,MAC/D;AAAA,IACF;AAAA,EACF;AAAA,EAEA,OAAe,WACb,OACA,MACA,SACmB;AACnB,QAAI,KAAK,WAAW,EAAG,QAAO,QAAQ,KAAK;AAG3C,cAAU,CAAC;AAEX,QAAI,OAAO,UAAU,UAAU;AAC7B,YAAM,IAAI,MAAM,kBAAkB,KAAK,KAAK,IAAI,CAAC,GAAG;AAAA,IACtD;AAEA,UAAM,CAAC,KAAK,GAAG,IAAI,IAAI;AACvB,QAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,YAAM,MAAM,OAAO,GAAG;AACtB,UAAI,OAAO,MAAM,GAAG;AAClB,cAAM,IAAI,MAAM,4BAA4B,KAAK,KAAK,IAAI,CAAC,GAAG;AAChE,UAAI,MAAM,MAAM,UAAU,MAAM;AAC9B,cAAM,IAAI,MAAM,kCAAkC;AAEpD,YAAMA,aAAY,CAAC,GAAG,KAAK;AAC3B,MAAAA,WAAU,GAAG,IAAI,KAAK,WAAWA,WAAU,GAAG,GAAG,MAAM,OAAO;AAE9D,aAAOA;AAAA,IACT;AAEA,UAAM,YAAY,EAAE,GAAI,MAA6B;AACrD,cAAU,GAAG,IAAI,KAAK,WAAW,UAAU,GAAG,GAAG,MAAM,OAAO;AAE9D,WAAO;AAAA,EACT;AACF;","names":["nextState"]}
@@ -221,7 +221,7 @@ var DataStreamDecoder = class extends PipeableTransformStream {
221
221
  const ctrl = parentId ? controller.withParentId(parentId) : controller;
222
222
  if (toolCallControllers.has(toolCallId))
223
223
  throw new Error(
224
- "Encountered duplicate tool call id: " + toolCallId
224
+ `Encountered duplicate tool call id: ${toolCallId}`
225
225
  );
226
226
  const toolCallController = ctrl.addToolCallPart({
227
227
  toolCallId,
@@ -236,7 +236,7 @@ var DataStreamDecoder = class extends PipeableTransformStream {
236
236
  const toolCallController = toolCallControllers.get(toolCallId);
237
237
  if (!toolCallController)
238
238
  throw new Error(
239
- "Encountered tool call with unknown id: " + toolCallId
239
+ `Encountered tool call with unknown id: ${toolCallId}`
240
240
  );
241
241
  toolCallController.argsText.append(argsTextDelta);
242
242
  break;
@@ -246,7 +246,7 @@ var DataStreamDecoder = class extends PipeableTransformStream {
246
246
  const toolCallController = toolCallControllers.get(toolCallId);
247
247
  if (!toolCallController)
248
248
  throw new Error(
249
- "Encountered tool call result with unknown id: " + toolCallId
249
+ `Encountered tool call result with unknown id: ${toolCallId}`
250
250
  );
251
251
  toolCallController.setResponse({
252
252
  artifact,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/core/serialization/data-stream/DataStream.ts"],"sourcesContent":["import { AssistantStreamChunk } from \"../../AssistantStreamChunk\";\nimport { ToolCallStreamController } from \"../../modules/tool-call\";\nimport { AssistantTransformStream } from \"../../utils/stream/AssistantTransformStream\";\nimport { PipeableTransformStream } from \"../../utils/stream/PipeableTransformStream\";\nimport { DataStreamChunk, DataStreamStreamChunkType } from \"./chunk-types\";\nimport { LineDecoderStream } from \"../../utils/stream/LineDecoderStream\";\nimport {\n DataStreamChunkDecoder,\n DataStreamChunkEncoder,\n} from \"./serialization\";\nimport {\n AssistantMetaStreamChunk,\n AssistantMetaTransformStream,\n} from \"../../utils/stream/AssistantMetaTransformStream\";\nimport { TextStreamController } from \"../../modules/text\";\nimport { AssistantStreamEncoder } from \"../../AssistantStream\";\n\nexport class DataStreamEncoder\n extends PipeableTransformStream<AssistantStreamChunk, Uint8Array<ArrayBuffer>>\n implements AssistantStreamEncoder\n{\n headers = new Headers({\n \"Content-Type\": \"text/plain; charset=utf-8\",\n \"x-vercel-ai-data-stream\": \"v1\",\n });\n\n constructor() {\n super((readable) => {\n const transform = new TransformStream<\n AssistantMetaStreamChunk,\n DataStreamChunk\n >({\n transform(chunk, controller) {\n const type = chunk.type;\n switch (type) {\n case \"part-start\": {\n const part = chunk.part;\n if (part.type === \"tool-call\") {\n const { type, ...value } = part;\n controller.enqueue({\n type: DataStreamStreamChunkType.StartToolCall,\n value,\n });\n }\n if (part.type === \"source\") {\n const { type, ...value } = part;\n controller.enqueue({\n type: DataStreamStreamChunkType.Source,\n value,\n });\n }\n break;\n }\n case \"text-delta\": {\n const part = chunk.meta;\n switch (part.type) {\n case \"text\": {\n if (part.parentId) {\n controller.enqueue({\n type: DataStreamStreamChunkType.AuiTextDelta,\n value: {\n textDelta: chunk.textDelta,\n parentId: part.parentId,\n },\n });\n } else {\n controller.enqueue({\n type: DataStreamStreamChunkType.TextDelta,\n value: chunk.textDelta,\n });\n }\n break;\n }\n case \"reasoning\": {\n if (part.parentId) {\n controller.enqueue({\n type: DataStreamStreamChunkType.AuiReasoningDelta,\n value: {\n reasoningDelta: chunk.textDelta,\n parentId: part.parentId,\n },\n });\n } else {\n controller.enqueue({\n type: DataStreamStreamChunkType.ReasoningDelta,\n value: chunk.textDelta,\n });\n }\n break;\n }\n case \"tool-call\": {\n controller.enqueue({\n type: DataStreamStreamChunkType.ToolCallArgsTextDelta,\n value: {\n toolCallId: part.toolCallId,\n argsTextDelta: chunk.textDelta,\n },\n });\n break;\n }\n default:\n throw new Error(\n `Unsupported part type for text-delta: ${part.type}`,\n );\n }\n break;\n }\n case \"result\": {\n // Only tool-call parts can have results.\n const part = chunk.meta;\n if (part.type !== \"tool-call\") {\n throw new Error(\n `Result chunk on non-tool-call part not supported: ${part.type}`,\n );\n }\n controller.enqueue({\n type: DataStreamStreamChunkType.ToolCallResult,\n value: {\n toolCallId: part.toolCallId,\n result: chunk.result,\n artifact: chunk.artifact,\n ...(chunk.isError ? { isError: chunk.isError } : {}),\n },\n });\n break;\n }\n case \"step-start\": {\n const { type, ...value } = chunk;\n controller.enqueue({\n type: DataStreamStreamChunkType.StartStep,\n value,\n });\n break;\n }\n case \"step-finish\": {\n const { type, ...value } = chunk;\n controller.enqueue({\n type: DataStreamStreamChunkType.FinishStep,\n value,\n });\n break;\n }\n case \"message-finish\": {\n const { type, ...value } = chunk;\n controller.enqueue({\n type: DataStreamStreamChunkType.FinishMessage,\n value,\n });\n break;\n }\n case \"error\": {\n controller.enqueue({\n type: DataStreamStreamChunkType.Error,\n value: chunk.error,\n });\n break;\n }\n case \"annotations\": {\n controller.enqueue({\n type: DataStreamStreamChunkType.Annotation,\n value: chunk.annotations,\n });\n break;\n }\n case \"data\": {\n controller.enqueue({\n type: DataStreamStreamChunkType.Data,\n value: chunk.data,\n });\n break;\n }\n\n case \"update-state\": {\n controller.enqueue({\n type: DataStreamStreamChunkType.AuiUpdateStateOperations,\n value: chunk.operations,\n });\n break;\n }\n\n // TODO ignore for now\n // in the future, we should create a handler that waits for text parts to finish before continuing\n case \"tool-call-args-text-finish\":\n case \"part-finish\":\n break;\n\n default: {\n const exhaustiveCheck: never = type;\n throw new Error(`Unsupported chunk type: ${exhaustiveCheck}`);\n }\n }\n },\n });\n\n return readable\n .pipeThrough(new AssistantMetaTransformStream())\n .pipeThrough(transform)\n .pipeThrough(new DataStreamChunkEncoder())\n .pipeThrough(new TextEncoderStream());\n });\n }\n}\n\nconst TOOL_CALL_ARGS_CLOSING_CHUNKS = [\n DataStreamStreamChunkType.StartToolCall,\n DataStreamStreamChunkType.ToolCall,\n DataStreamStreamChunkType.TextDelta,\n DataStreamStreamChunkType.ReasoningDelta,\n DataStreamStreamChunkType.Source,\n DataStreamStreamChunkType.Error,\n DataStreamStreamChunkType.FinishStep,\n DataStreamStreamChunkType.FinishMessage,\n DataStreamStreamChunkType.AuiTextDelta,\n DataStreamStreamChunkType.AuiReasoningDelta,\n];\n\nexport class DataStreamDecoder extends PipeableTransformStream<\n Uint8Array<ArrayBuffer>,\n AssistantStreamChunk\n> {\n constructor() {\n super((readable) => {\n const toolCallControllers = new Map<string, ToolCallStreamController>();\n let activeToolCallArgsText: TextStreamController | undefined;\n const transform = new AssistantTransformStream<DataStreamChunk>({\n transform(chunk, controller) {\n const { type, value } = chunk;\n\n if (TOOL_CALL_ARGS_CLOSING_CHUNKS.includes(type)) {\n activeToolCallArgsText?.close();\n activeToolCallArgsText = undefined;\n }\n\n switch (type) {\n case DataStreamStreamChunkType.ReasoningDelta:\n controller.appendReasoning(value);\n break;\n\n case DataStreamStreamChunkType.TextDelta:\n controller.appendText(value);\n break;\n\n case DataStreamStreamChunkType.AuiTextDelta:\n controller\n .withParentId(value.parentId)\n .appendText(value.textDelta);\n break;\n\n case DataStreamStreamChunkType.AuiReasoningDelta:\n controller\n .withParentId(value.parentId)\n .appendReasoning(value.reasoningDelta);\n break;\n\n case DataStreamStreamChunkType.StartToolCall: {\n const { toolCallId, toolName, parentId } = value;\n const ctrl = parentId\n ? controller.withParentId(parentId)\n : controller;\n\n if (toolCallControllers.has(toolCallId))\n throw new Error(\n \"Encountered duplicate tool call id: \" + toolCallId,\n );\n\n const toolCallController = ctrl.addToolCallPart({\n toolCallId,\n toolName,\n });\n toolCallControllers.set(toolCallId, toolCallController);\n\n activeToolCallArgsText = toolCallController.argsText;\n break;\n }\n\n case DataStreamStreamChunkType.ToolCallArgsTextDelta: {\n const { toolCallId, argsTextDelta } = value;\n const toolCallController = toolCallControllers.get(toolCallId);\n if (!toolCallController)\n throw new Error(\n \"Encountered tool call with unknown id: \" + toolCallId,\n );\n toolCallController.argsText.append(argsTextDelta);\n break;\n }\n\n case DataStreamStreamChunkType.ToolCallResult: {\n const { toolCallId, artifact, result, isError } = value;\n const toolCallController = toolCallControllers.get(toolCallId);\n if (!toolCallController)\n throw new Error(\n \"Encountered tool call result with unknown id: \" + toolCallId,\n );\n toolCallController.setResponse({\n artifact,\n result,\n isError,\n });\n break;\n }\n\n case DataStreamStreamChunkType.ToolCall: {\n const { toolCallId, toolName, args } = value;\n\n let toolCallController = toolCallControllers.get(toolCallId);\n if (toolCallController) {\n toolCallController.argsText.close();\n } else {\n toolCallController = controller.addToolCallPart({\n toolCallId,\n toolName,\n args,\n });\n toolCallControllers.set(toolCallId, toolCallController);\n }\n break;\n }\n\n case DataStreamStreamChunkType.FinishMessage:\n controller.enqueue({\n type: \"message-finish\",\n path: [],\n ...value,\n });\n break;\n\n case DataStreamStreamChunkType.StartStep:\n controller.enqueue({\n type: \"step-start\",\n path: [],\n ...value,\n });\n break;\n\n case DataStreamStreamChunkType.FinishStep:\n controller.enqueue({\n type: \"step-finish\",\n path: [],\n ...value,\n });\n break;\n case DataStreamStreamChunkType.Data:\n controller.enqueue({\n type: \"data\",\n path: [],\n data: value,\n });\n break;\n\n case DataStreamStreamChunkType.Annotation:\n controller.enqueue({\n type: \"annotations\",\n path: [],\n annotations: value,\n });\n break;\n\n case DataStreamStreamChunkType.Source: {\n const { parentId, ...sourceData } = value;\n const ctrl = parentId\n ? controller.withParentId(parentId)\n : controller;\n ctrl.appendSource({\n type: \"source\",\n ...sourceData,\n });\n break;\n }\n\n case DataStreamStreamChunkType.Error:\n controller.enqueue({\n type: \"error\",\n path: [],\n error: value,\n });\n break;\n\n case DataStreamStreamChunkType.File:\n controller.appendFile({\n type: \"file\",\n ...value,\n });\n break;\n\n case DataStreamStreamChunkType.AuiUpdateStateOperations:\n controller.enqueue({\n type: \"update-state\",\n path: [],\n operations: value,\n });\n break;\n\n case DataStreamStreamChunkType.ReasoningSignature:\n case DataStreamStreamChunkType.RedactedReasoning:\n // ignore these for now\n break;\n\n default: {\n const exhaustiveCheck: never = type;\n throw new Error(`unsupported chunk type: ${exhaustiveCheck}`);\n }\n }\n },\n flush() {\n activeToolCallArgsText?.close();\n activeToolCallArgsText = undefined;\n toolCallControllers.forEach((controller) => controller.close());\n toolCallControllers.clear();\n },\n });\n\n return readable\n .pipeThrough(new TextDecoderStream())\n .pipeThrough(new LineDecoderStream())\n .pipeThrough(new DataStreamChunkDecoder())\n .pipeThrough(transform);\n });\n }\n}\n"],"mappings":"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","names":["type"]}
1
+ {"version":3,"sources":["../../../../src/core/serialization/data-stream/DataStream.ts"],"sourcesContent":["import { AssistantStreamChunk } from \"../../AssistantStreamChunk\";\nimport { ToolCallStreamController } from \"../../modules/tool-call\";\nimport { AssistantTransformStream } from \"../../utils/stream/AssistantTransformStream\";\nimport { PipeableTransformStream } from \"../../utils/stream/PipeableTransformStream\";\nimport { DataStreamChunk, DataStreamStreamChunkType } from \"./chunk-types\";\nimport { LineDecoderStream } from \"../../utils/stream/LineDecoderStream\";\nimport {\n DataStreamChunkDecoder,\n DataStreamChunkEncoder,\n} from \"./serialization\";\nimport {\n AssistantMetaStreamChunk,\n AssistantMetaTransformStream,\n} from \"../../utils/stream/AssistantMetaTransformStream\";\nimport { TextStreamController } from \"../../modules/text\";\nimport { AssistantStreamEncoder } from \"../../AssistantStream\";\n\nexport class DataStreamEncoder\n extends PipeableTransformStream<AssistantStreamChunk, Uint8Array<ArrayBuffer>>\n implements AssistantStreamEncoder\n{\n headers = new Headers({\n \"Content-Type\": \"text/plain; charset=utf-8\",\n \"x-vercel-ai-data-stream\": \"v1\",\n });\n\n constructor() {\n super((readable) => {\n const transform = new TransformStream<\n AssistantMetaStreamChunk,\n DataStreamChunk\n >({\n transform(chunk, controller) {\n const type = chunk.type;\n switch (type) {\n case \"part-start\": {\n const part = chunk.part;\n if (part.type === \"tool-call\") {\n const { type, ...value } = part;\n controller.enqueue({\n type: DataStreamStreamChunkType.StartToolCall,\n value,\n });\n }\n if (part.type === \"source\") {\n const { type, ...value } = part;\n controller.enqueue({\n type: DataStreamStreamChunkType.Source,\n value,\n });\n }\n break;\n }\n case \"text-delta\": {\n const part = chunk.meta;\n switch (part.type) {\n case \"text\": {\n if (part.parentId) {\n controller.enqueue({\n type: DataStreamStreamChunkType.AuiTextDelta,\n value: {\n textDelta: chunk.textDelta,\n parentId: part.parentId,\n },\n });\n } else {\n controller.enqueue({\n type: DataStreamStreamChunkType.TextDelta,\n value: chunk.textDelta,\n });\n }\n break;\n }\n case \"reasoning\": {\n if (part.parentId) {\n controller.enqueue({\n type: DataStreamStreamChunkType.AuiReasoningDelta,\n value: {\n reasoningDelta: chunk.textDelta,\n parentId: part.parentId,\n },\n });\n } else {\n controller.enqueue({\n type: DataStreamStreamChunkType.ReasoningDelta,\n value: chunk.textDelta,\n });\n }\n break;\n }\n case \"tool-call\": {\n controller.enqueue({\n type: DataStreamStreamChunkType.ToolCallArgsTextDelta,\n value: {\n toolCallId: part.toolCallId,\n argsTextDelta: chunk.textDelta,\n },\n });\n break;\n }\n default:\n throw new Error(\n `Unsupported part type for text-delta: ${part.type}`,\n );\n }\n break;\n }\n case \"result\": {\n // Only tool-call parts can have results.\n const part = chunk.meta;\n if (part.type !== \"tool-call\") {\n throw new Error(\n `Result chunk on non-tool-call part not supported: ${part.type}`,\n );\n }\n controller.enqueue({\n type: DataStreamStreamChunkType.ToolCallResult,\n value: {\n toolCallId: part.toolCallId,\n result: chunk.result,\n artifact: chunk.artifact,\n ...(chunk.isError ? { isError: chunk.isError } : {}),\n },\n });\n break;\n }\n case \"step-start\": {\n const { type, ...value } = chunk;\n controller.enqueue({\n type: DataStreamStreamChunkType.StartStep,\n value,\n });\n break;\n }\n case \"step-finish\": {\n const { type, ...value } = chunk;\n controller.enqueue({\n type: DataStreamStreamChunkType.FinishStep,\n value,\n });\n break;\n }\n case \"message-finish\": {\n const { type, ...value } = chunk;\n controller.enqueue({\n type: DataStreamStreamChunkType.FinishMessage,\n value,\n });\n break;\n }\n case \"error\": {\n controller.enqueue({\n type: DataStreamStreamChunkType.Error,\n value: chunk.error,\n });\n break;\n }\n case \"annotations\": {\n controller.enqueue({\n type: DataStreamStreamChunkType.Annotation,\n value: chunk.annotations,\n });\n break;\n }\n case \"data\": {\n controller.enqueue({\n type: DataStreamStreamChunkType.Data,\n value: chunk.data,\n });\n break;\n }\n\n case \"update-state\": {\n controller.enqueue({\n type: DataStreamStreamChunkType.AuiUpdateStateOperations,\n value: chunk.operations,\n });\n break;\n }\n\n // TODO ignore for now\n // in the future, we should create a handler that waits for text parts to finish before continuing\n case \"tool-call-args-text-finish\":\n case \"part-finish\":\n break;\n\n default: {\n const exhaustiveCheck: never = type;\n throw new Error(`Unsupported chunk type: ${exhaustiveCheck}`);\n }\n }\n },\n });\n\n return readable\n .pipeThrough(new AssistantMetaTransformStream())\n .pipeThrough(transform)\n .pipeThrough(new DataStreamChunkEncoder())\n .pipeThrough(new TextEncoderStream());\n });\n }\n}\n\nconst TOOL_CALL_ARGS_CLOSING_CHUNKS = [\n DataStreamStreamChunkType.StartToolCall,\n DataStreamStreamChunkType.ToolCall,\n DataStreamStreamChunkType.TextDelta,\n DataStreamStreamChunkType.ReasoningDelta,\n DataStreamStreamChunkType.Source,\n DataStreamStreamChunkType.Error,\n DataStreamStreamChunkType.FinishStep,\n DataStreamStreamChunkType.FinishMessage,\n DataStreamStreamChunkType.AuiTextDelta,\n DataStreamStreamChunkType.AuiReasoningDelta,\n];\n\nexport class DataStreamDecoder extends PipeableTransformStream<\n Uint8Array<ArrayBuffer>,\n AssistantStreamChunk\n> {\n constructor() {\n super((readable) => {\n const toolCallControllers = new Map<string, ToolCallStreamController>();\n let activeToolCallArgsText: TextStreamController | undefined;\n const transform = new AssistantTransformStream<DataStreamChunk>({\n transform(chunk, controller) {\n const { type, value } = chunk;\n\n if (TOOL_CALL_ARGS_CLOSING_CHUNKS.includes(type)) {\n activeToolCallArgsText?.close();\n activeToolCallArgsText = undefined;\n }\n\n switch (type) {\n case DataStreamStreamChunkType.ReasoningDelta:\n controller.appendReasoning(value);\n break;\n\n case DataStreamStreamChunkType.TextDelta:\n controller.appendText(value);\n break;\n\n case DataStreamStreamChunkType.AuiTextDelta:\n controller\n .withParentId(value.parentId)\n .appendText(value.textDelta);\n break;\n\n case DataStreamStreamChunkType.AuiReasoningDelta:\n controller\n .withParentId(value.parentId)\n .appendReasoning(value.reasoningDelta);\n break;\n\n case DataStreamStreamChunkType.StartToolCall: {\n const { toolCallId, toolName, parentId } = value;\n const ctrl = parentId\n ? controller.withParentId(parentId)\n : controller;\n\n if (toolCallControllers.has(toolCallId))\n throw new Error(\n `Encountered duplicate tool call id: ${toolCallId}`,\n );\n\n const toolCallController = ctrl.addToolCallPart({\n toolCallId,\n toolName,\n });\n toolCallControllers.set(toolCallId, toolCallController);\n\n activeToolCallArgsText = toolCallController.argsText;\n break;\n }\n\n case DataStreamStreamChunkType.ToolCallArgsTextDelta: {\n const { toolCallId, argsTextDelta } = value;\n const toolCallController = toolCallControllers.get(toolCallId);\n if (!toolCallController)\n throw new Error(\n `Encountered tool call with unknown id: ${toolCallId}`,\n );\n toolCallController.argsText.append(argsTextDelta);\n break;\n }\n\n case DataStreamStreamChunkType.ToolCallResult: {\n const { toolCallId, artifact, result, isError } = value;\n const toolCallController = toolCallControllers.get(toolCallId);\n if (!toolCallController)\n throw new Error(\n `Encountered tool call result with unknown id: ${toolCallId}`,\n );\n toolCallController.setResponse({\n artifact,\n result,\n isError,\n });\n break;\n }\n\n case DataStreamStreamChunkType.ToolCall: {\n const { toolCallId, toolName, args } = value;\n\n let toolCallController = toolCallControllers.get(toolCallId);\n if (toolCallController) {\n toolCallController.argsText.close();\n } else {\n toolCallController = controller.addToolCallPart({\n toolCallId,\n toolName,\n args,\n });\n toolCallControllers.set(toolCallId, toolCallController);\n }\n break;\n }\n\n case DataStreamStreamChunkType.FinishMessage:\n controller.enqueue({\n type: \"message-finish\",\n path: [],\n ...value,\n });\n break;\n\n case DataStreamStreamChunkType.StartStep:\n controller.enqueue({\n type: \"step-start\",\n path: [],\n ...value,\n });\n break;\n\n case DataStreamStreamChunkType.FinishStep:\n controller.enqueue({\n type: \"step-finish\",\n path: [],\n ...value,\n });\n break;\n case DataStreamStreamChunkType.Data:\n controller.enqueue({\n type: \"data\",\n path: [],\n data: value,\n });\n break;\n\n case DataStreamStreamChunkType.Annotation:\n controller.enqueue({\n type: \"annotations\",\n path: [],\n annotations: value,\n });\n break;\n\n case DataStreamStreamChunkType.Source: {\n const { parentId, ...sourceData } = value;\n const ctrl = parentId\n ? controller.withParentId(parentId)\n : controller;\n ctrl.appendSource({\n type: \"source\",\n ...sourceData,\n });\n break;\n }\n\n case DataStreamStreamChunkType.Error:\n controller.enqueue({\n type: \"error\",\n path: [],\n error: value,\n });\n break;\n\n case DataStreamStreamChunkType.File:\n controller.appendFile({\n type: \"file\",\n ...value,\n });\n break;\n\n case DataStreamStreamChunkType.AuiUpdateStateOperations:\n controller.enqueue({\n type: \"update-state\",\n path: [],\n operations: value,\n });\n break;\n\n case DataStreamStreamChunkType.ReasoningSignature:\n case DataStreamStreamChunkType.RedactedReasoning:\n // ignore these for now\n break;\n\n default: {\n const exhaustiveCheck: never = type;\n throw new Error(`unsupported chunk type: ${exhaustiveCheck}`);\n }\n }\n },\n flush() {\n activeToolCallArgsText?.close();\n activeToolCallArgsText = undefined;\n toolCallControllers.forEach((controller) => controller.close());\n toolCallControllers.clear();\n },\n });\n\n return readable\n .pipeThrough(new TextDecoderStream())\n .pipeThrough(new LineDecoderStream())\n .pipeThrough(new DataStreamChunkDecoder())\n .pipeThrough(transform);\n });\n }\n}\n"],"mappings":"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","names":["type"]}
@@ -16,6 +16,8 @@ type ToolStreamCallback = <TArgs extends ReadonlyJSONObject = ReadonlyJSONObject
16
16
  type ToolExecutionOptions = {
17
17
  execute: ToolCallback;
18
18
  streamCall: ToolStreamCallback;
19
+ onExecutionStart?: ((toolCallId: string, toolName: string) => void) | undefined;
20
+ onExecutionEnd?: ((toolCallId: string, toolName: string) => void) | undefined;
19
21
  };
20
22
  export declare class ToolExecutionStream extends PipeableTransformStream<AssistantStreamChunk, AssistantStreamChunk> {
21
23
  constructor(options: ToolExecutionOptions);
@@ -1 +1 @@
1
- {"version":3,"file":"ToolExecutionStream.d.ts","sourceRoot":"","sources":["../../../src/core/tool/ToolExecutionStream.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAK/D,OAAO,EAAE,uBAAuB,EAAE,MAAM,yCAAyC,CAAC;AAClF,OAAO,EACL,kBAAkB,EAClB,iBAAiB,EAClB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAG9C,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAE9C,KAAK,YAAY,GAAG,CAAC,QAAQ,EAAE;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,kBAAkB,CAAC;CAC1B,KACG,OAAO,CAAC,YAAY,CAAC,iBAAiB,CAAC,CAAC,GACxC,YAAY,CAAC,iBAAiB,CAAC,GAC/B,SAAS,CAAC;AAEd,KAAK,kBAAkB,GAAG,CACxB,KAAK,SAAS,kBAAkB,GAAG,kBAAkB,EACrD,OAAO,SAAS,iBAAiB,GAAG,iBAAiB,EACrD,QAAQ,EAAE;IACV,MAAM,EAAE,cAAc,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IACvC,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;CAClB,KAAK,IAAI,CAAC;AAEX,KAAK,oBAAoB,GAAG;IAC1B,OAAO,EAAE,YAAY,CAAC;IACtB,UAAU,EAAE,kBAAkB,CAAC;CAChC,CAAC;AAEF,qBAAa,mBAAoB,SAAQ,uBAAuB,CAC9D,oBAAoB,EACpB,oBAAoB,CACrB;gBACa,OAAO,EAAE,oBAAoB;CAwJ1C"}
1
+ {"version":3,"file":"ToolExecutionStream.d.ts","sourceRoot":"","sources":["../../../src/core/tool/ToolExecutionStream.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAK/D,OAAO,EAAE,uBAAuB,EAAE,MAAM,yCAAyC,CAAC;AAClF,OAAO,EACL,kBAAkB,EAClB,iBAAiB,EAClB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAG9C,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAE9C,KAAK,YAAY,GAAG,CAAC,QAAQ,EAAE;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,kBAAkB,CAAC;CAC1B,KACG,OAAO,CAAC,YAAY,CAAC,iBAAiB,CAAC,CAAC,GACxC,YAAY,CAAC,iBAAiB,CAAC,GAC/B,SAAS,CAAC;AAEd,KAAK,kBAAkB,GAAG,CACxB,KAAK,SAAS,kBAAkB,GAAG,kBAAkB,EACrD,OAAO,SAAS,iBAAiB,GAAG,iBAAiB,EACrD,QAAQ,EAAE;IACV,MAAM,EAAE,cAAc,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IACvC,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;CAClB,KAAK,IAAI,CAAC;AAEX,KAAK,oBAAoB,GAAG;IAC1B,OAAO,EAAE,YAAY,CAAC;IACtB,UAAU,EAAE,kBAAkB,CAAC;IAC/B,gBAAgB,CAAC,EACb,CAAC,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC,GAChD,SAAS,CAAC;IACd,cAAc,CAAC,EAAE,CAAC,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;CAC/E,CAAC;AAEF,qBAAa,mBAAoB,SAAQ,uBAAuB,CAC9D,oBAAoB,EACpB,oBAAoB,CACrB;gBACa,OAAO,EAAE,oBAAoB;CAyK1C"}
@@ -61,6 +61,7 @@ var ToolExecutionStream = class extends PipeableTransformStream {
61
61
  const streamController = toolCallControllers.get(toolCallId);
62
62
  if (!streamController)
63
63
  throw new Error("No controller found for tool call");
64
+ let isExecuting = false;
64
65
  const promise = withPromiseOrValue(
65
66
  () => {
66
67
  let args;
@@ -71,13 +72,21 @@ var ToolExecutionStream = class extends PipeableTransformStream {
71
72
  `Function parameter parsing failed. ${JSON.stringify(e.message)}`
72
73
  );
73
74
  }
74
- return options.execute({
75
+ const executeResult = options.execute({
75
76
  toolCallId,
76
77
  toolName,
77
78
  args
78
79
  });
80
+ if (executeResult !== void 0) {
81
+ isExecuting = true;
82
+ options.onExecutionStart?.(toolCallId, toolName);
83
+ }
84
+ return executeResult;
79
85
  },
80
86
  (c) => {
87
+ if (isExecuting) {
88
+ options.onExecutionEnd?.(toolCallId, toolName);
89
+ }
81
90
  if (c === void 0) return;
82
91
  const result = new ToolResponse({
83
92
  artifact: c.artifact,
@@ -92,6 +101,9 @@ var ToolExecutionStream = class extends PipeableTransformStream {
92
101
  });
93
102
  },
94
103
  (e) => {
104
+ if (isExecuting) {
105
+ options.onExecutionEnd?.(toolCallId, toolName);
106
+ }
95
107
  const result = new ToolResponse({
96
108
  result: String(e),
97
109
  isError: true
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/core/tool/ToolExecutionStream.ts"],"sourcesContent":["import sjson from \"secure-json-parse\";\nimport { AssistantStreamChunk } from \"../AssistantStreamChunk\";\nimport {\n AssistantMetaStreamChunk,\n AssistantMetaTransformStream,\n} from \"../utils/stream/AssistantMetaTransformStream\";\nimport { PipeableTransformStream } from \"../utils/stream/PipeableTransformStream\";\nimport {\n ReadonlyJSONObject,\n ReadonlyJSONValue,\n} from \"../../utils/json/json-value\";\nimport { ToolResponse } from \"./ToolResponse\";\nimport { withPromiseOrValue } from \"../utils/withPromiseOrValue\";\nimport { ToolCallReaderImpl } from \"./ToolCallReader\";\nimport { ToolCallReader } from \"./tool-types\";\n\ntype ToolCallback = (toolCall: {\n toolCallId: string;\n toolName: string;\n args: ReadonlyJSONObject;\n}) =>\n | Promise<ToolResponse<ReadonlyJSONValue>>\n | ToolResponse<ReadonlyJSONValue>\n | undefined;\n\ntype ToolStreamCallback = <\n TArgs extends ReadonlyJSONObject = ReadonlyJSONObject,\n TResult extends ReadonlyJSONValue = ReadonlyJSONValue,\n>(toolCall: {\n reader: ToolCallReader<TArgs, TResult>;\n toolCallId: string;\n toolName: string;\n}) => void;\n\ntype ToolExecutionOptions = {\n execute: ToolCallback;\n streamCall: ToolStreamCallback;\n};\n\nexport class ToolExecutionStream extends PipeableTransformStream<\n AssistantStreamChunk,\n AssistantStreamChunk\n> {\n constructor(options: ToolExecutionOptions) {\n const toolCallPromises = new Map<string, PromiseLike<void>>();\n const toolCallControllers = new Map<\n string,\n ToolCallReaderImpl<ReadonlyJSONObject, ReadonlyJSONValue>\n >();\n\n super((readable) => {\n const transform = new TransformStream<\n AssistantMetaStreamChunk,\n AssistantStreamChunk\n >({\n transform(chunk, controller) {\n // forward everything\n if (chunk.type !== \"part-finish\" || chunk.meta.type !== \"tool-call\") {\n controller.enqueue(chunk);\n }\n\n const type = chunk.type;\n\n switch (type) {\n case \"part-start\":\n if (chunk.part.type === \"tool-call\") {\n const reader = new ToolCallReaderImpl<\n ReadonlyJSONObject,\n ReadonlyJSONValue\n >();\n toolCallControllers.set(chunk.part.toolCallId, reader);\n\n options.streamCall({\n reader,\n toolCallId: chunk.part.toolCallId,\n toolName: chunk.part.toolName,\n });\n }\n break;\n case \"text-delta\": {\n if (chunk.meta.type === \"tool-call\") {\n const toolCallId = chunk.meta.toolCallId;\n\n const controller = toolCallControllers.get(toolCallId);\n if (!controller)\n throw new Error(\"No controller found for tool call\");\n controller.appendArgsTextDelta(chunk.textDelta);\n }\n break;\n }\n case \"result\": {\n if (chunk.meta.type !== \"tool-call\") break;\n\n const { toolCallId } = chunk.meta;\n const controller = toolCallControllers.get(toolCallId);\n if (!controller)\n throw new Error(\"No controller found for tool call\");\n controller.setResponse(\n new ToolResponse({\n result: chunk.result,\n artifact: chunk.artifact,\n isError: chunk.isError,\n }),\n );\n break;\n }\n case \"tool-call-args-text-finish\": {\n if (chunk.meta.type !== \"tool-call\") break;\n\n const { toolCallId, toolName } = chunk.meta;\n const streamController = toolCallControllers.get(toolCallId)!;\n if (!streamController)\n throw new Error(\"No controller found for tool call\");\n\n const promise = withPromiseOrValue(\n () => {\n let args;\n try {\n args = sjson.parse(streamController.argsText);\n } catch (e) {\n throw new Error(\n `Function parameter parsing failed. ${JSON.stringify((e as Error).message)}`,\n );\n }\n\n return options.execute({\n toolCallId,\n toolName,\n args,\n });\n },\n (c) => {\n if (c === undefined) return;\n\n // TODO how to handle new ToolResult({ result: undefined })?\n const result = new ToolResponse({\n artifact: c.artifact,\n result: c.result,\n isError: c.isError,\n });\n streamController.setResponse(result);\n controller.enqueue({\n type: \"result\",\n path: chunk.path,\n ...result,\n });\n },\n (e) => {\n const result = new ToolResponse({\n result: String(e),\n isError: true,\n });\n\n streamController.setResponse(result);\n controller.enqueue({\n type: \"result\",\n path: chunk.path,\n ...result,\n });\n },\n );\n if (promise) {\n toolCallPromises.set(toolCallId, promise);\n }\n break;\n }\n\n case \"part-finish\": {\n if (chunk.meta.type !== \"tool-call\") break;\n\n const { toolCallId } = chunk.meta;\n const toolCallPromise = toolCallPromises.get(toolCallId);\n if (toolCallPromise) {\n toolCallPromise.then(() => {\n toolCallPromises.delete(toolCallId);\n toolCallControllers.delete(toolCallId);\n\n controller.enqueue(chunk);\n });\n } else {\n controller.enqueue(chunk);\n }\n }\n }\n },\n async flush() {\n await Promise.all(toolCallPromises.values());\n },\n });\n\n return readable\n .pipeThrough(new AssistantMetaTransformStream())\n .pipeThrough(transform);\n });\n }\n}\n"],"mappings":";AAAA,OAAO,WAAW;AAElB;AAAA,EAEE;AAAA,OACK;AACP,SAAS,+BAA+B;AAKxC,SAAS,oBAAoB;AAC7B,SAAS,0BAA0B;AACnC,SAAS,0BAA0B;AA0B5B,IAAM,sBAAN,cAAkC,wBAGvC;AAAA,EACA,YAAY,SAA+B;AACzC,UAAM,mBAAmB,oBAAI,IAA+B;AAC5D,UAAM,sBAAsB,oBAAI,IAG9B;AAEF,UAAM,CAAC,aAAa;AAClB,YAAM,YAAY,IAAI,gBAGpB;AAAA,QACA,UAAU,OAAO,YAAY;AAE3B,cAAI,MAAM,SAAS,iBAAiB,MAAM,KAAK,SAAS,aAAa;AACnE,uBAAW,QAAQ,KAAK;AAAA,UAC1B;AAEA,gBAAM,OAAO,MAAM;AAEnB,kBAAQ,MAAM;AAAA,YACZ,KAAK;AACH,kBAAI,MAAM,KAAK,SAAS,aAAa;AACnC,sBAAM,SAAS,IAAI,mBAGjB;AACF,oCAAoB,IAAI,MAAM,KAAK,YAAY,MAAM;AAErD,wBAAQ,WAAW;AAAA,kBACjB;AAAA,kBACA,YAAY,MAAM,KAAK;AAAA,kBACvB,UAAU,MAAM,KAAK;AAAA,gBACvB,CAAC;AAAA,cACH;AACA;AAAA,YACF,KAAK,cAAc;AACjB,kBAAI,MAAM,KAAK,SAAS,aAAa;AACnC,sBAAM,aAAa,MAAM,KAAK;AAE9B,sBAAMA,cAAa,oBAAoB,IAAI,UAAU;AACrD,oBAAI,CAACA;AACH,wBAAM,IAAI,MAAM,mCAAmC;AACrD,gBAAAA,YAAW,oBAAoB,MAAM,SAAS;AAAA,cAChD;AACA;AAAA,YACF;AAAA,YACA,KAAK,UAAU;AACb,kBAAI,MAAM,KAAK,SAAS,YAAa;AAErC,oBAAM,EAAE,WAAW,IAAI,MAAM;AAC7B,oBAAMA,cAAa,oBAAoB,IAAI,UAAU;AACrD,kBAAI,CAACA;AACH,sBAAM,IAAI,MAAM,mCAAmC;AACrD,cAAAA,YAAW;AAAA,gBACT,IAAI,aAAa;AAAA,kBACf,QAAQ,MAAM;AAAA,kBACd,UAAU,MAAM;AAAA,kBAChB,SAAS,MAAM;AAAA,gBACjB,CAAC;AAAA,cACH;AACA;AAAA,YACF;AAAA,YACA,KAAK,8BAA8B;AACjC,kBAAI,MAAM,KAAK,SAAS,YAAa;AAErC,oBAAM,EAAE,YAAY,SAAS,IAAI,MAAM;AACvC,oBAAM,mBAAmB,oBAAoB,IAAI,UAAU;AAC3D,kBAAI,CAAC;AACH,sBAAM,IAAI,MAAM,mCAAmC;AAErD,oBAAM,UAAU;AAAA,gBACd,MAAM;AACJ,sBAAI;AACJ,sBAAI;AACF,2BAAO,MAAM,MAAM,iBAAiB,QAAQ;AAAA,kBAC9C,SAAS,GAAG;AACV,0BAAM,IAAI;AAAA,sBACR,sCAAsC,KAAK,UAAW,EAAY,OAAO,CAAC;AAAA,oBAC5E;AAAA,kBACF;AAEA,yBAAO,QAAQ,QAAQ;AAAA,oBACrB;AAAA,oBACA;AAAA,oBACA;AAAA,kBACF,CAAC;AAAA,gBACH;AAAA,gBACA,CAAC,MAAM;AACL,sBAAI,MAAM,OAAW;AAGrB,wBAAM,SAAS,IAAI,aAAa;AAAA,oBAC9B,UAAU,EAAE;AAAA,oBACZ,QAAQ,EAAE;AAAA,oBACV,SAAS,EAAE;AAAA,kBACb,CAAC;AACD,mCAAiB,YAAY,MAAM;AACnC,6BAAW,QAAQ;AAAA,oBACjB,MAAM;AAAA,oBACN,MAAM,MAAM;AAAA,oBACZ,GAAG;AAAA,kBACL,CAAC;AAAA,gBACH;AAAA,gBACA,CAAC,MAAM;AACL,wBAAM,SAAS,IAAI,aAAa;AAAA,oBAC9B,QAAQ,OAAO,CAAC;AAAA,oBAChB,SAAS;AAAA,kBACX,CAAC;AAED,mCAAiB,YAAY,MAAM;AACnC,6BAAW,QAAQ;AAAA,oBACjB,MAAM;AAAA,oBACN,MAAM,MAAM;AAAA,oBACZ,GAAG;AAAA,kBACL,CAAC;AAAA,gBACH;AAAA,cACF;AACA,kBAAI,SAAS;AACX,iCAAiB,IAAI,YAAY,OAAO;AAAA,cAC1C;AACA;AAAA,YACF;AAAA,YAEA,KAAK,eAAe;AAClB,kBAAI,MAAM,KAAK,SAAS,YAAa;AAErC,oBAAM,EAAE,WAAW,IAAI,MAAM;AAC7B,oBAAM,kBAAkB,iBAAiB,IAAI,UAAU;AACvD,kBAAI,iBAAiB;AACnB,gCAAgB,KAAK,MAAM;AACzB,mCAAiB,OAAO,UAAU;AAClC,sCAAoB,OAAO,UAAU;AAErC,6BAAW,QAAQ,KAAK;AAAA,gBAC1B,CAAC;AAAA,cACH,OAAO;AACL,2BAAW,QAAQ,KAAK;AAAA,cAC1B;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,QACA,MAAM,QAAQ;AACZ,gBAAM,QAAQ,IAAI,iBAAiB,OAAO,CAAC;AAAA,QAC7C;AAAA,MACF,CAAC;AAED,aAAO,SACJ,YAAY,IAAI,6BAA6B,CAAC,EAC9C,YAAY,SAAS;AAAA,IAC1B,CAAC;AAAA,EACH;AACF;","names":["controller"]}
1
+ {"version":3,"sources":["../../../src/core/tool/ToolExecutionStream.ts"],"sourcesContent":["import sjson from \"secure-json-parse\";\nimport { AssistantStreamChunk } from \"../AssistantStreamChunk\";\nimport {\n AssistantMetaStreamChunk,\n AssistantMetaTransformStream,\n} from \"../utils/stream/AssistantMetaTransformStream\";\nimport { PipeableTransformStream } from \"../utils/stream/PipeableTransformStream\";\nimport {\n ReadonlyJSONObject,\n ReadonlyJSONValue,\n} from \"../../utils/json/json-value\";\nimport { ToolResponse } from \"./ToolResponse\";\nimport { withPromiseOrValue } from \"../utils/withPromiseOrValue\";\nimport { ToolCallReaderImpl } from \"./ToolCallReader\";\nimport { ToolCallReader } from \"./tool-types\";\n\ntype ToolCallback = (toolCall: {\n toolCallId: string;\n toolName: string;\n args: ReadonlyJSONObject;\n}) =>\n | Promise<ToolResponse<ReadonlyJSONValue>>\n | ToolResponse<ReadonlyJSONValue>\n | undefined;\n\ntype ToolStreamCallback = <\n TArgs extends ReadonlyJSONObject = ReadonlyJSONObject,\n TResult extends ReadonlyJSONValue = ReadonlyJSONValue,\n>(toolCall: {\n reader: ToolCallReader<TArgs, TResult>;\n toolCallId: string;\n toolName: string;\n}) => void;\n\ntype ToolExecutionOptions = {\n execute: ToolCallback;\n streamCall: ToolStreamCallback;\n onExecutionStart?:\n | ((toolCallId: string, toolName: string) => void)\n | undefined;\n onExecutionEnd?: ((toolCallId: string, toolName: string) => void) | undefined;\n};\n\nexport class ToolExecutionStream extends PipeableTransformStream<\n AssistantStreamChunk,\n AssistantStreamChunk\n> {\n constructor(options: ToolExecutionOptions) {\n const toolCallPromises = new Map<string, PromiseLike<void>>();\n const toolCallControllers = new Map<\n string,\n ToolCallReaderImpl<ReadonlyJSONObject, ReadonlyJSONValue>\n >();\n\n super((readable) => {\n const transform = new TransformStream<\n AssistantMetaStreamChunk,\n AssistantStreamChunk\n >({\n transform(chunk, controller) {\n // forward everything\n if (chunk.type !== \"part-finish\" || chunk.meta.type !== \"tool-call\") {\n controller.enqueue(chunk);\n }\n\n const type = chunk.type;\n\n switch (type) {\n case \"part-start\":\n if (chunk.part.type === \"tool-call\") {\n const reader = new ToolCallReaderImpl<\n ReadonlyJSONObject,\n ReadonlyJSONValue\n >();\n toolCallControllers.set(chunk.part.toolCallId, reader);\n\n options.streamCall({\n reader,\n toolCallId: chunk.part.toolCallId,\n toolName: chunk.part.toolName,\n });\n }\n break;\n case \"text-delta\": {\n if (chunk.meta.type === \"tool-call\") {\n const toolCallId = chunk.meta.toolCallId;\n\n const controller = toolCallControllers.get(toolCallId);\n if (!controller)\n throw new Error(\"No controller found for tool call\");\n controller.appendArgsTextDelta(chunk.textDelta);\n }\n break;\n }\n case \"result\": {\n if (chunk.meta.type !== \"tool-call\") break;\n\n const { toolCallId } = chunk.meta;\n const controller = toolCallControllers.get(toolCallId);\n if (!controller)\n throw new Error(\"No controller found for tool call\");\n controller.setResponse(\n new ToolResponse({\n result: chunk.result,\n artifact: chunk.artifact,\n isError: chunk.isError,\n }),\n );\n break;\n }\n case \"tool-call-args-text-finish\": {\n if (chunk.meta.type !== \"tool-call\") break;\n\n const { toolCallId, toolName } = chunk.meta;\n const streamController = toolCallControllers.get(toolCallId)!;\n if (!streamController)\n throw new Error(\"No controller found for tool call\");\n\n let isExecuting = false;\n const promise = withPromiseOrValue(\n () => {\n let args;\n try {\n args = sjson.parse(streamController.argsText);\n } catch (e) {\n throw new Error(\n `Function parameter parsing failed. ${JSON.stringify((e as Error).message)}`,\n );\n }\n\n const executeResult = options.execute({\n toolCallId,\n toolName,\n args,\n });\n\n // Only mark as executing if the tool has frontend execution\n if (executeResult !== undefined) {\n isExecuting = true;\n options.onExecutionStart?.(toolCallId, toolName);\n }\n\n return executeResult;\n },\n (c) => {\n if (isExecuting) {\n options.onExecutionEnd?.(toolCallId, toolName);\n }\n\n if (c === undefined) return;\n\n // TODO how to handle new ToolResult({ result: undefined })?\n const result = new ToolResponse({\n artifact: c.artifact,\n result: c.result,\n isError: c.isError,\n });\n streamController.setResponse(result);\n controller.enqueue({\n type: \"result\",\n path: chunk.path,\n ...result,\n });\n },\n (e) => {\n if (isExecuting) {\n options.onExecutionEnd?.(toolCallId, toolName);\n }\n\n const result = new ToolResponse({\n result: String(e),\n isError: true,\n });\n\n streamController.setResponse(result);\n controller.enqueue({\n type: \"result\",\n path: chunk.path,\n ...result,\n });\n },\n );\n if (promise) {\n toolCallPromises.set(toolCallId, promise);\n }\n break;\n }\n\n case \"part-finish\": {\n if (chunk.meta.type !== \"tool-call\") break;\n\n const { toolCallId } = chunk.meta;\n const toolCallPromise = toolCallPromises.get(toolCallId);\n if (toolCallPromise) {\n toolCallPromise.then(() => {\n toolCallPromises.delete(toolCallId);\n toolCallControllers.delete(toolCallId);\n\n controller.enqueue(chunk);\n });\n } else {\n controller.enqueue(chunk);\n }\n }\n }\n },\n async flush() {\n await Promise.all(toolCallPromises.values());\n },\n });\n\n return readable\n .pipeThrough(new AssistantMetaTransformStream())\n .pipeThrough(transform);\n });\n }\n}\n"],"mappings":";AAAA,OAAO,WAAW;AAElB;AAAA,EAEE;AAAA,OACK;AACP,SAAS,+BAA+B;AAKxC,SAAS,oBAAoB;AAC7B,SAAS,0BAA0B;AACnC,SAAS,0BAA0B;AA8B5B,IAAM,sBAAN,cAAkC,wBAGvC;AAAA,EACA,YAAY,SAA+B;AACzC,UAAM,mBAAmB,oBAAI,IAA+B;AAC5D,UAAM,sBAAsB,oBAAI,IAG9B;AAEF,UAAM,CAAC,aAAa;AAClB,YAAM,YAAY,IAAI,gBAGpB;AAAA,QACA,UAAU,OAAO,YAAY;AAE3B,cAAI,MAAM,SAAS,iBAAiB,MAAM,KAAK,SAAS,aAAa;AACnE,uBAAW,QAAQ,KAAK;AAAA,UAC1B;AAEA,gBAAM,OAAO,MAAM;AAEnB,kBAAQ,MAAM;AAAA,YACZ,KAAK;AACH,kBAAI,MAAM,KAAK,SAAS,aAAa;AACnC,sBAAM,SAAS,IAAI,mBAGjB;AACF,oCAAoB,IAAI,MAAM,KAAK,YAAY,MAAM;AAErD,wBAAQ,WAAW;AAAA,kBACjB;AAAA,kBACA,YAAY,MAAM,KAAK;AAAA,kBACvB,UAAU,MAAM,KAAK;AAAA,gBACvB,CAAC;AAAA,cACH;AACA;AAAA,YACF,KAAK,cAAc;AACjB,kBAAI,MAAM,KAAK,SAAS,aAAa;AACnC,sBAAM,aAAa,MAAM,KAAK;AAE9B,sBAAMA,cAAa,oBAAoB,IAAI,UAAU;AACrD,oBAAI,CAACA;AACH,wBAAM,IAAI,MAAM,mCAAmC;AACrD,gBAAAA,YAAW,oBAAoB,MAAM,SAAS;AAAA,cAChD;AACA;AAAA,YACF;AAAA,YACA,KAAK,UAAU;AACb,kBAAI,MAAM,KAAK,SAAS,YAAa;AAErC,oBAAM,EAAE,WAAW,IAAI,MAAM;AAC7B,oBAAMA,cAAa,oBAAoB,IAAI,UAAU;AACrD,kBAAI,CAACA;AACH,sBAAM,IAAI,MAAM,mCAAmC;AACrD,cAAAA,YAAW;AAAA,gBACT,IAAI,aAAa;AAAA,kBACf,QAAQ,MAAM;AAAA,kBACd,UAAU,MAAM;AAAA,kBAChB,SAAS,MAAM;AAAA,gBACjB,CAAC;AAAA,cACH;AACA;AAAA,YACF;AAAA,YACA,KAAK,8BAA8B;AACjC,kBAAI,MAAM,KAAK,SAAS,YAAa;AAErC,oBAAM,EAAE,YAAY,SAAS,IAAI,MAAM;AACvC,oBAAM,mBAAmB,oBAAoB,IAAI,UAAU;AAC3D,kBAAI,CAAC;AACH,sBAAM,IAAI,MAAM,mCAAmC;AAErD,kBAAI,cAAc;AAClB,oBAAM,UAAU;AAAA,gBACd,MAAM;AACJ,sBAAI;AACJ,sBAAI;AACF,2BAAO,MAAM,MAAM,iBAAiB,QAAQ;AAAA,kBAC9C,SAAS,GAAG;AACV,0BAAM,IAAI;AAAA,sBACR,sCAAsC,KAAK,UAAW,EAAY,OAAO,CAAC;AAAA,oBAC5E;AAAA,kBACF;AAEA,wBAAM,gBAAgB,QAAQ,QAAQ;AAAA,oBACpC;AAAA,oBACA;AAAA,oBACA;AAAA,kBACF,CAAC;AAGD,sBAAI,kBAAkB,QAAW;AAC/B,kCAAc;AACd,4BAAQ,mBAAmB,YAAY,QAAQ;AAAA,kBACjD;AAEA,yBAAO;AAAA,gBACT;AAAA,gBACA,CAAC,MAAM;AACL,sBAAI,aAAa;AACf,4BAAQ,iBAAiB,YAAY,QAAQ;AAAA,kBAC/C;AAEA,sBAAI,MAAM,OAAW;AAGrB,wBAAM,SAAS,IAAI,aAAa;AAAA,oBAC9B,UAAU,EAAE;AAAA,oBACZ,QAAQ,EAAE;AAAA,oBACV,SAAS,EAAE;AAAA,kBACb,CAAC;AACD,mCAAiB,YAAY,MAAM;AACnC,6BAAW,QAAQ;AAAA,oBACjB,MAAM;AAAA,oBACN,MAAM,MAAM;AAAA,oBACZ,GAAG;AAAA,kBACL,CAAC;AAAA,gBACH;AAAA,gBACA,CAAC,MAAM;AACL,sBAAI,aAAa;AACf,4BAAQ,iBAAiB,YAAY,QAAQ;AAAA,kBAC/C;AAEA,wBAAM,SAAS,IAAI,aAAa;AAAA,oBAC9B,QAAQ,OAAO,CAAC;AAAA,oBAChB,SAAS;AAAA,kBACX,CAAC;AAED,mCAAiB,YAAY,MAAM;AACnC,6BAAW,QAAQ;AAAA,oBACjB,MAAM;AAAA,oBACN,MAAM,MAAM;AAAA,oBACZ,GAAG;AAAA,kBACL,CAAC;AAAA,gBACH;AAAA,cACF;AACA,kBAAI,SAAS;AACX,iCAAiB,IAAI,YAAY,OAAO;AAAA,cAC1C;AACA;AAAA,YACF;AAAA,YAEA,KAAK,eAAe;AAClB,kBAAI,MAAM,KAAK,SAAS,YAAa;AAErC,oBAAM,EAAE,WAAW,IAAI,MAAM;AAC7B,oBAAM,kBAAkB,iBAAiB,IAAI,UAAU;AACvD,kBAAI,iBAAiB;AACnB,gCAAgB,KAAK,MAAM;AACzB,mCAAiB,OAAO,UAAU;AAClC,sCAAoB,OAAO,UAAU;AAErC,6BAAW,QAAQ,KAAK;AAAA,gBAC1B,CAAC;AAAA,cACH,OAAO;AACL,2BAAW,QAAQ,KAAK;AAAA,cAC1B;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,QACA,MAAM,QAAQ;AACZ,gBAAM,QAAQ,IAAI,iBAAiB,OAAO,CAAC;AAAA,QAC7C;AAAA,MACF,CAAC;AAED,aAAO,SACJ,YAAY,IAAI,6BAA6B,CAAC,EAC9C,YAAY,SAAS;AAAA,IAC1B,CAAC;AAAA,EACH;AACF;","names":["controller"]}
@@ -1,5 +1,5 @@
1
1
  // src/core/tool/ToolResponse.ts
2
- var TOOL_RESPONSE_SYMBOL = Symbol.for("aui.tool-response");
2
+ var TOOL_RESPONSE_SYMBOL = /* @__PURE__ */ Symbol.for("aui.tool-response");
3
3
  var ToolResponse = class _ToolResponse {
4
4
  get [TOOL_RESPONSE_SYMBOL]() {
5
5
  return true;
@@ -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 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
+ {"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,uBAAO,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":[]}
@@ -2,5 +2,5 @@ export type { Tool } from "./tool-types";
2
2
  export { ToolResponse, type ToolResponseLike } from "./ToolResponse";
3
3
  export { ToolExecutionStream } from "./ToolExecutionStream";
4
4
  export type { ToolCallReader } from "./tool-types";
5
- export { toolResultStream as unstable_toolResultStream, unstable_runPendingTools, } from "./toolResultStream";
5
+ export { toolResultStream as unstable_toolResultStream, unstable_runPendingTools, type ToolResultStreamOptions, } from "./toolResultStream";
6
6
  //# sourceMappingURL=index.d.ts.map
@@ -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,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
+ {"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,EACxB,KAAK,uBAAuB,GAC7B,MAAM,oBAAoB,CAAC"}
@@ -1 +1 @@
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
+ {"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 type ToolResultStreamOptions,\n} from \"./toolResultStream\";\n"],"mappings":";AACA,SAAS,oBAA2C;AACpD,SAAS,2BAA2B;AAEpC;AAAA,EACsB;AAAA,EACpB;AAAA,OAEK;","names":[]}
@@ -2,5 +2,9 @@ import { Tool } from "./tool-types";
2
2
  import { ToolExecutionStream } from "./ToolExecutionStream";
3
3
  import { AssistantMessage } from "../utils/types";
4
4
  export declare function unstable_runPendingTools(message: AssistantMessage, tools: Record<string, Tool> | undefined, abortSignal: AbortSignal, human: (toolCallId: string, payload: unknown) => Promise<unknown>): Promise<AssistantMessage>;
5
- export declare function toolResultStream(tools: Record<string, Tool> | (() => Record<string, Tool> | undefined) | undefined, abortSignal: AbortSignal | (() => AbortSignal), human: (toolCallId: string, payload: unknown) => Promise<unknown>): ToolExecutionStream;
5
+ export type ToolResultStreamOptions = {
6
+ onExecutionStart?: (toolCallId: string, toolName: string) => void;
7
+ onExecutionEnd?: (toolCallId: string, toolName: string) => void;
8
+ };
9
+ export declare function toolResultStream(tools: Record<string, Tool> | (() => Record<string, Tool> | undefined) | undefined, abortSignal: AbortSignal | (() => AbortSignal), human: (toolCallId: string, payload: unknown) => Promise<unknown>, options?: ToolResultStreamOptions): ToolExecutionStream;
6
10
  //# sourceMappingURL=toolResultStream.d.ts.map
@@ -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,EACxB,KAAK,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,OAAO,CAAC,6BAiElE;AAED,wBAAgB,gBAAgB,CAC9B,KAAK,EACD,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,GACpB,CAAC,MAAM,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,GAAG,SAAS,CAAC,GACxC,SAAS,EACb,WAAW,EAAE,WAAW,GAAG,CAAC,MAAM,WAAW,CAAC,EAC9C,KAAK,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,OAAO,CAAC,uBAWlE"}
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;AA+GlD,wBAAsB,wBAAwB,CAC5C,OAAO,EAAE,gBAAgB,EACzB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,GAAG,SAAS,EACvC,WAAW,EAAE,WAAW,EACxB,KAAK,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,OAAO,CAAC,6BAiElE;AAED,MAAM,MAAM,uBAAuB,GAAG;IACpC,gBAAgB,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IAClE,cAAc,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;CACjE,CAAC;AAEF,wBAAgB,gBAAgB,CAC9B,KAAK,EACD,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,GACpB,CAAC,MAAM,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,GAAG,SAAS,CAAC,GACxC,SAAS,EACb,WAAW,EAAE,WAAW,GAAG,CAAC,MAAM,WAAW,CAAC,EAC9C,KAAK,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,OAAO,CAAC,EACjE,OAAO,CAAC,EAAE,uBAAuB,uBAalC"}
@@ -8,24 +8,54 @@ function getToolResponse(tools, abortSignal, toolCall, human) {
8
8
  const tool = tools?.[toolCall.toolName];
9
9
  if (!tool || !tool.execute) return void 0;
10
10
  const getResult = async (toolExecute) => {
11
+ if (abortSignal.aborted) {
12
+ return new ToolResponse({
13
+ result: "Tool execution was cancelled.",
14
+ isError: true
15
+ });
16
+ }
11
17
  let executeFn = toolExecute;
12
18
  if (isStandardSchemaV1(tool.parameters)) {
13
- let result2 = tool.parameters["~standard"].validate(toolCall.args);
14
- if (result2 instanceof Promise) result2 = await result2;
15
- if (result2.issues) {
19
+ let result = tool.parameters["~standard"].validate(toolCall.args);
20
+ if (result instanceof Promise) result = await result;
21
+ if (result.issues) {
16
22
  executeFn = tool.experimental_onSchemaValidationError ?? (() => {
17
23
  throw new Error(
18
- `Function parameter validation failed. ${JSON.stringify(result2.issues)}`
24
+ `Function parameter validation failed. ${JSON.stringify(result.issues)}`
19
25
  );
20
26
  });
21
27
  }
22
28
  }
23
- const result = await executeFn(toolCall.args, {
24
- toolCallId: toolCall.toolCallId,
25
- abortSignal,
26
- human: (payload) => human(toolCall.toolCallId, payload)
27
- });
28
- return ToolResponse.toResponse(result);
29
+ const abortPromise = new Promise(
30
+ (resolve) => {
31
+ const onAbort = () => {
32
+ queueMicrotask(() => {
33
+ queueMicrotask(() => {
34
+ resolve(
35
+ new ToolResponse({
36
+ result: "Tool execution was cancelled.",
37
+ isError: true
38
+ })
39
+ );
40
+ });
41
+ });
42
+ };
43
+ if (abortSignal.aborted) {
44
+ onAbort();
45
+ } else {
46
+ abortSignal.addEventListener("abort", onAbort, { once: true });
47
+ }
48
+ }
49
+ );
50
+ const executePromise = (async () => {
51
+ const result = await executeFn(toolCall.args, {
52
+ toolCallId: toolCall.toolCallId,
53
+ abortSignal,
54
+ human: (payload) => human(toolCall.toolCallId, payload)
55
+ });
56
+ return ToolResponse.toResponse(result);
57
+ })();
58
+ return Promise.race([executePromise, abortPromise]);
29
59
  };
30
60
  return getResult(tool.execute);
31
61
  }
@@ -91,12 +121,14 @@ async function unstable_runPendingTools(message, tools, abortSignal, human) {
91
121
  content: updatedParts
92
122
  };
93
123
  }
94
- function toolResultStream(tools, abortSignal, human) {
124
+ function toolResultStream(tools, abortSignal, human, options) {
95
125
  const toolsFn = typeof tools === "function" ? tools : () => tools;
96
126
  const abortSignalFn = typeof abortSignal === "function" ? abortSignal : () => abortSignal;
97
127
  return new ToolExecutionStream({
98
128
  execute: (toolCall) => getToolResponse(toolsFn(), abortSignalFn(), toolCall, human),
99
- streamCall: ({ reader, ...context }) => getToolStreamResponse(toolsFn(), abortSignalFn(), reader, context, human)
129
+ streamCall: ({ reader, ...context }) => getToolStreamResponse(toolsFn(), abortSignalFn(), reader, context, human),
130
+ onExecutionStart: options?.onExecutionStart,
131
+ onExecutionEnd: options?.onExecutionEnd
100
132
  });
101
133
  }
102
134
  export {
@@ -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 human: (toolCallId: string, payload: unknown) => Promise<unknown>,\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 human: (payload: unknown) => human(toolCall.toolCallId, payload),\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 human: (toolCallId: string, payload: unknown) => Promise<unknown>,\n) {\n tools?.[context.toolName]?.streamCall?.(reader, {\n toolCallId: context.toolCallId,\n abortSignal,\n human: (payload: unknown) => human(context.toolCallId, payload),\n });\n}\n\nexport async function unstable_runPendingTools(\n message: AssistantMessage,\n tools: Record<string, Tool> | undefined,\n abortSignal: AbortSignal,\n human: (toolCallId: string, payload: unknown) => Promise<unknown>,\n) {\n const toolCallPromises = message.parts\n .filter((part) => part.type === \"tool-call\")\n .map(async (part) => {\n const promiseOrUndefined = getToolResponse(\n tools,\n abortSignal,\n part,\n human ??\n (async () => {\n throw new Error(\n \"Tool human input is not supported in this context\",\n );\n }),\n );\n if (promiseOrUndefined) {\n const result = await promiseOrUndefined;\n return {\n toolCallId: part.toolCallId,\n result,\n };\n }\n return null;\n });\n\n const toolCallResults = (await Promise.all(toolCallPromises)).filter(\n (result) => result !== null,\n ) as { toolCallId: string; result: ToolResponse<ReadonlyJSONValue> }[];\n\n if (toolCallResults.length === 0) {\n return message;\n }\n\n const toolCallResultsById = toolCallResults.reduce(\n (acc, { toolCallId, result }) => {\n acc[toolCallId] = result;\n return acc;\n },\n {} as Record<string, ToolResponse<ReadonlyJSONValue>>,\n );\n\n const updatedParts = message.parts.map((p) => {\n if (p.type === \"tool-call\") {\n const toolResponse = toolCallResultsById[p.toolCallId];\n if (toolResponse) {\n return {\n ...p,\n state: \"result\" as const,\n ...(toolResponse.artifact !== undefined\n ? { artifact: toolResponse.artifact }\n : {}),\n result: toolResponse.result as ReadonlyJSONValue,\n isError: toolResponse.isError,\n };\n }\n }\n return p;\n });\n\n return {\n ...message,\n parts: updatedParts,\n content: updatedParts,\n };\n}\n\nexport function toolResultStream(\n tools:\n | Record<string, Tool>\n | (() => Record<string, Tool> | undefined)\n | undefined,\n abortSignal: AbortSignal | (() => AbortSignal),\n human: (toolCallId: string, payload: unknown) => Promise<unknown>,\n) {\n const toolsFn = typeof tools === \"function\" ? tools : () => tools;\n const abortSignalFn =\n typeof abortSignal === \"function\" ? abortSignal : () => abortSignal;\n return new ToolExecutionStream({\n execute: (toolCall) =>\n getToolResponse(toolsFn(), abortSignalFn(), toolCall, human),\n streamCall: ({ reader, ...context }) =>\n getToolStreamResponse(toolsFn(), abortSignalFn(), reader, context, human),\n });\n}\n"],"mappings":"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","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 human: (toolCallId: string, payload: unknown) => Promise<unknown>,\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 // Check if already aborted before starting\n if (abortSignal.aborted) {\n return new ToolResponse({\n result: \"Tool execution was cancelled.\",\n isError: true,\n });\n }\n\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 // Create abort promise that resolves after 2 microtasks\n // This gives tools that handle abort a chance to win the race\n const abortPromise = new Promise<ToolResponse<ReadonlyJSONValue>>(\n (resolve) => {\n const onAbort = () => {\n queueMicrotask(() => {\n queueMicrotask(() => {\n resolve(\n new ToolResponse({\n result: \"Tool execution was cancelled.\",\n isError: true,\n }),\n );\n });\n });\n };\n if (abortSignal.aborted) {\n onAbort();\n } else {\n abortSignal.addEventListener(\"abort\", onAbort, { once: true });\n }\n },\n );\n\n const executePromise = (async () => {\n const result = (await executeFn(toolCall.args, {\n toolCallId: toolCall.toolCallId,\n abortSignal,\n human: (payload: unknown) => human(toolCall.toolCallId, payload),\n })) as unknown as ReadonlyJSONValue;\n return ToolResponse.toResponse(result);\n })();\n\n return Promise.race([executePromise, abortPromise]);\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 human: (toolCallId: string, payload: unknown) => Promise<unknown>,\n) {\n tools?.[context.toolName]?.streamCall?.(reader, {\n toolCallId: context.toolCallId,\n abortSignal,\n human: (payload: unknown) => human(context.toolCallId, payload),\n });\n}\n\nexport async function unstable_runPendingTools(\n message: AssistantMessage,\n tools: Record<string, Tool> | undefined,\n abortSignal: AbortSignal,\n human: (toolCallId: string, payload: unknown) => Promise<unknown>,\n) {\n const toolCallPromises = message.parts\n .filter((part) => part.type === \"tool-call\")\n .map(async (part) => {\n const promiseOrUndefined = getToolResponse(\n tools,\n abortSignal,\n part,\n human ??\n (async () => {\n throw new Error(\n \"Tool human input is not supported in this context\",\n );\n }),\n );\n if (promiseOrUndefined) {\n const result = await promiseOrUndefined;\n return {\n toolCallId: part.toolCallId,\n result,\n };\n }\n return null;\n });\n\n const toolCallResults = (await Promise.all(toolCallPromises)).filter(\n (result) => result !== null,\n ) as { toolCallId: string; result: ToolResponse<ReadonlyJSONValue> }[];\n\n if (toolCallResults.length === 0) {\n return message;\n }\n\n const toolCallResultsById = toolCallResults.reduce(\n (acc, { toolCallId, result }) => {\n acc[toolCallId] = result;\n return acc;\n },\n {} as Record<string, ToolResponse<ReadonlyJSONValue>>,\n );\n\n const updatedParts = message.parts.map((p) => {\n if (p.type === \"tool-call\") {\n const toolResponse = toolCallResultsById[p.toolCallId];\n if (toolResponse) {\n return {\n ...p,\n state: \"result\" as const,\n ...(toolResponse.artifact !== undefined\n ? { artifact: toolResponse.artifact }\n : {}),\n result: toolResponse.result as ReadonlyJSONValue,\n isError: toolResponse.isError,\n };\n }\n }\n return p;\n });\n\n return {\n ...message,\n parts: updatedParts,\n content: updatedParts,\n };\n}\n\nexport type ToolResultStreamOptions = {\n onExecutionStart?: (toolCallId: string, toolName: string) => void;\n onExecutionEnd?: (toolCallId: string, toolName: string) => void;\n};\n\nexport function toolResultStream(\n tools:\n | Record<string, Tool>\n | (() => Record<string, Tool> | undefined)\n | undefined,\n abortSignal: AbortSignal | (() => AbortSignal),\n human: (toolCallId: string, payload: unknown) => Promise<unknown>,\n options?: ToolResultStreamOptions,\n) {\n const toolsFn = typeof tools === \"function\" ? tools : () => tools;\n const abortSignalFn =\n typeof abortSignal === \"function\" ? abortSignal : () => abortSignal;\n return new ToolExecutionStream({\n execute: (toolCall) =>\n getToolResponse(toolsFn(), abortSignalFn(), toolCall, human),\n streamCall: ({ reader, ...context }) =>\n getToolStreamResponse(toolsFn(), abortSignalFn(), reader, context, human),\n onExecutionStart: options?.onExecutionStart,\n onExecutionEnd: options?.onExecutionEnd,\n });\n}\n"],"mappings":"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","names":[]}
@@ -1,3 +1,3 @@
1
1
  export { asAsyncIterableStream, type AsyncIterableStream, } from "./AsyncIterableStream";
2
- export { type ReadonlyJSONObject, type ReadonlyJSONValue } from "./json";
2
+ export type { ReadonlyJSONObject, ReadonlyJSONValue } from "./json";
3
3
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,qBAAqB,EACrB,KAAK,mBAAmB,GACzB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,KAAK,kBAAkB,EAAE,KAAK,iBAAiB,EAAE,MAAM,QAAQ,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,qBAAqB,EACrB,KAAK,mBAAmB,GACzB,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,QAAQ,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utils/index.ts"],"sourcesContent":["export {\n asAsyncIterableStream,\n type AsyncIterableStream,\n} from \"./AsyncIterableStream\";\nexport { type ReadonlyJSONObject, type ReadonlyJSONValue } from \"./json\";\n"],"mappings":";AAAA;AAAA,EACE;AAAA,OAEK;","names":[]}
1
+ {"version":3,"sources":["../../src/utils/index.ts"],"sourcesContent":["export {\n asAsyncIterableStream,\n type AsyncIterableStream,\n} from \"./AsyncIterableStream\";\nexport type { ReadonlyJSONObject, ReadonlyJSONValue } from \"./json\";\n"],"mappings":";AAAA;AAAA,EACE;AAAA,OAEK;","names":[]}
@@ -1 +1 @@
1
- {"version":3,"file":"fix-json.d.ts","sourceRoot":"","sources":["../../../src/utils/json/fix-json.ts"],"names":[],"mappings":"AA+DA,wBAAgB,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAwazD"}
1
+ {"version":3,"file":"fix-json.d.ts","sourceRoot":"","sources":["../../../src/utils/json/fix-json.ts"],"names":[],"mappings":"AA+DA,wBAAgB,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAsazD"}
@@ -7,71 +7,69 @@ function fixJson(input) {
7
7
  let currentKey;
8
8
  function pushCurrentKeyToPath() {
9
9
  if (currentKey !== void 0) {
10
- path.push(JSON.parse('"' + currentKey + '"'));
10
+ path.push(JSON.parse(`"${currentKey}"`));
11
11
  currentKey = void 0;
12
12
  }
13
13
  }
14
14
  function processValueStart(char, i, swapState) {
15
- {
16
- switch (char) {
17
- case '"': {
18
- lastValidIndex = i;
19
- stack.pop();
20
- stack.push(swapState);
21
- stack.push("INSIDE_STRING");
22
- pushCurrentKeyToPath();
23
- break;
24
- }
25
- case "f":
26
- case "t":
27
- case "n": {
28
- lastValidIndex = i;
29
- literalStart = i;
30
- stack.pop();
31
- stack.push(swapState);
32
- stack.push("INSIDE_LITERAL");
33
- break;
34
- }
35
- case "-": {
36
- stack.pop();
37
- stack.push(swapState);
38
- stack.push("INSIDE_NUMBER");
39
- pushCurrentKeyToPath();
40
- break;
41
- }
42
- case "0":
43
- case "1":
44
- case "2":
45
- case "3":
46
- case "4":
47
- case "5":
48
- case "6":
49
- case "7":
50
- case "8":
51
- case "9": {
52
- lastValidIndex = i;
53
- stack.pop();
54
- stack.push(swapState);
55
- stack.push("INSIDE_NUMBER");
56
- pushCurrentKeyToPath();
57
- break;
58
- }
59
- case "{": {
60
- lastValidIndex = i;
61
- stack.pop();
62
- stack.push(swapState);
63
- stack.push("INSIDE_OBJECT_START");
64
- pushCurrentKeyToPath();
65
- break;
66
- }
67
- case "[": {
68
- lastValidIndex = i;
69
- stack.pop();
70
- stack.push(swapState);
71
- stack.push("INSIDE_ARRAY_START");
72
- pushCurrentKeyToPath();
73
- break;
74
- }
15
+ switch (char) {
16
+ case '"': {
17
+ lastValidIndex = i;
18
+ stack.pop();
19
+ stack.push(swapState);
20
+ stack.push("INSIDE_STRING");
21
+ pushCurrentKeyToPath();
22
+ break;
23
+ }
24
+ case "f":
25
+ case "t":
26
+ case "n": {
27
+ lastValidIndex = i;
28
+ literalStart = i;
29
+ stack.pop();
30
+ stack.push(swapState);
31
+ stack.push("INSIDE_LITERAL");
32
+ break;
33
+ }
34
+ case "-": {
35
+ stack.pop();
36
+ stack.push(swapState);
37
+ stack.push("INSIDE_NUMBER");
38
+ pushCurrentKeyToPath();
39
+ break;
40
+ }
41
+ case "0":
42
+ case "1":
43
+ case "2":
44
+ case "3":
45
+ case "4":
46
+ case "5":
47
+ case "6":
48
+ case "7":
49
+ case "8":
50
+ case "9": {
51
+ lastValidIndex = i;
52
+ stack.pop();
53
+ stack.push(swapState);
54
+ stack.push("INSIDE_NUMBER");
55
+ pushCurrentKeyToPath();
56
+ break;
57
+ }
58
+ case "{": {
59
+ lastValidIndex = i;
60
+ stack.pop();
61
+ stack.push(swapState);
62
+ stack.push("INSIDE_OBJECT_START");
63
+ pushCurrentKeyToPath();
64
+ break;
65
+ }
66
+ case "[": {
67
+ lastValidIndex = i;
68
+ stack.pop();
69
+ stack.push(swapState);
70
+ stack.push("INSIDE_ARRAY_START");
71
+ pushCurrentKeyToPath();
72
+ break;
75
73
  }
76
74
  }
77
75
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/utils/json/fix-json.ts"],"sourcesContent":["// LICENSE for this file only\n\n// MIT License\n\n// Copyright (c) 2025 AgentbaseAI Inc.\n// Copyright (c) 2023 Lars Grammel\n\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\ntype State =\n | \"ROOT\"\n | \"FINISH\"\n | \"INSIDE_STRING\"\n | \"INSIDE_STRING_ESCAPE\"\n | \"INSIDE_LITERAL\"\n | \"INSIDE_NUMBER\"\n | \"INSIDE_OBJECT_START\"\n | \"INSIDE_OBJECT_KEY\"\n | \"INSIDE_OBJECT_AFTER_KEY\"\n | \"INSIDE_OBJECT_BEFORE_VALUE\"\n | \"INSIDE_OBJECT_AFTER_VALUE\"\n | \"INSIDE_OBJECT_AFTER_COMMA\"\n | \"INSIDE_ARRAY_START\"\n | \"INSIDE_ARRAY_AFTER_VALUE\"\n | \"INSIDE_ARRAY_AFTER_COMMA\";\n\n// Implemented as a scanner with additional fixing\n// that performs a single linear time scan pass over the partial JSON.\n//\n// The states should ideally match relevant states from the JSON spec:\n// https://www.json.org/json-en.html\n//\n// Please note that invalid JSON is not considered/covered, because it\n// is assumed that the resulting JSON will be processed by a standard\n// JSON parser that will detect any invalid JSON.\n\n// Returns a tuple of [fixedJson, partialPath]\n// partialPath is an array of object/array keys that represent\n// the currently partial values. An object is considered partial\n// if through appending extra characters to the JSON string, its\n// value could change.\n\n// Example input: '{\"foo\":[{\"a\":f'\n// Example output: ['{\"foo\":[{\"a\":false}]}', ['foo', '0']]\n// Example input: '{\"foo\":'\n// Example output: ['{}', []]\n\nexport function fixJson(input: string): [string, string[]] {\n const stack: State[] = [\"ROOT\"];\n let lastValidIndex = -1;\n let literalStart: number | null = null;\n const path: string[] = [];\n let currentKey: string | undefined;\n\n function pushCurrentKeyToPath(): void {\n if (currentKey !== undefined) {\n path.push(JSON.parse('\"' + currentKey + '\"'));\n currentKey = undefined;\n }\n }\n\n function processValueStart(char: string, i: number, swapState: State) {\n {\n switch (char) {\n case '\"': {\n lastValidIndex = i;\n stack.pop();\n stack.push(swapState);\n stack.push(\"INSIDE_STRING\");\n\n pushCurrentKeyToPath();\n break;\n }\n\n case \"f\":\n case \"t\":\n case \"n\": {\n lastValidIndex = i;\n literalStart = i;\n stack.pop();\n stack.push(swapState);\n stack.push(\"INSIDE_LITERAL\");\n break;\n }\n\n case \"-\": {\n stack.pop();\n stack.push(swapState);\n stack.push(\"INSIDE_NUMBER\");\n\n pushCurrentKeyToPath();\n break;\n }\n case \"0\":\n case \"1\":\n case \"2\":\n case \"3\":\n case \"4\":\n case \"5\":\n case \"6\":\n case \"7\":\n case \"8\":\n case \"9\": {\n lastValidIndex = i;\n stack.pop();\n stack.push(swapState);\n stack.push(\"INSIDE_NUMBER\");\n\n pushCurrentKeyToPath();\n break;\n }\n\n case \"{\": {\n lastValidIndex = i;\n stack.pop();\n stack.push(swapState);\n stack.push(\"INSIDE_OBJECT_START\");\n\n pushCurrentKeyToPath();\n break;\n }\n\n case \"[\": {\n lastValidIndex = i;\n stack.pop();\n stack.push(swapState);\n stack.push(\"INSIDE_ARRAY_START\");\n\n pushCurrentKeyToPath();\n break;\n }\n }\n }\n }\n\n function processAfterObjectValue(char: string, i: number) {\n switch (char) {\n case \",\": {\n stack.pop();\n stack.push(\"INSIDE_OBJECT_AFTER_COMMA\");\n break;\n }\n case \"}\": {\n lastValidIndex = i;\n stack.pop();\n currentKey = path.pop();\n break;\n }\n }\n }\n\n function processAfterArrayValue(char: string, i: number) {\n switch (char) {\n case \",\": {\n stack.pop();\n stack.push(\"INSIDE_ARRAY_AFTER_COMMA\");\n currentKey = (Number(currentKey) + 1).toString();\n break;\n }\n case \"]\": {\n lastValidIndex = i;\n stack.pop();\n currentKey = path.pop();\n break;\n }\n }\n }\n\n for (let i = 0; i < input.length; i++) {\n const char = input[i]!;\n const currentState = stack[stack.length - 1];\n\n switch (currentState) {\n case \"ROOT\":\n processValueStart(char, i, \"FINISH\");\n break;\n\n case \"INSIDE_OBJECT_START\": {\n switch (char) {\n case '\"': {\n stack.pop();\n stack.push(\"INSIDE_OBJECT_KEY\");\n currentKey = \"\";\n break;\n }\n case \"}\": {\n lastValidIndex = i;\n stack.pop();\n currentKey = path.pop();\n break;\n }\n }\n break;\n }\n\n case \"INSIDE_OBJECT_AFTER_COMMA\": {\n switch (char) {\n case '\"': {\n stack.pop();\n stack.push(\"INSIDE_OBJECT_KEY\");\n currentKey = \"\";\n break;\n }\n }\n break;\n }\n\n case \"INSIDE_OBJECT_KEY\": {\n switch (char) {\n case '\"': {\n stack.pop();\n stack.push(\"INSIDE_OBJECT_AFTER_KEY\");\n break;\n }\n case \"\\\\\": {\n stack.push(\"INSIDE_STRING_ESCAPE\");\n currentKey += char;\n break;\n }\n default: {\n currentKey += char;\n break;\n }\n }\n break;\n }\n\n case \"INSIDE_OBJECT_AFTER_KEY\": {\n switch (char) {\n case \":\": {\n stack.pop();\n stack.push(\"INSIDE_OBJECT_BEFORE_VALUE\");\n\n break;\n }\n }\n break;\n }\n\n case \"INSIDE_OBJECT_BEFORE_VALUE\": {\n processValueStart(char, i, \"INSIDE_OBJECT_AFTER_VALUE\");\n break;\n }\n\n case \"INSIDE_OBJECT_AFTER_VALUE\": {\n processAfterObjectValue(char, i);\n break;\n }\n\n case \"INSIDE_STRING\": {\n switch (char) {\n case '\"': {\n stack.pop();\n lastValidIndex = i;\n\n currentKey = path.pop();\n break;\n }\n\n case \"\\\\\": {\n stack.push(\"INSIDE_STRING_ESCAPE\");\n break;\n }\n\n default: {\n lastValidIndex = i;\n }\n }\n\n break;\n }\n\n case \"INSIDE_ARRAY_START\": {\n switch (char) {\n case \"]\": {\n lastValidIndex = i;\n stack.pop();\n currentKey = path.pop();\n break;\n }\n\n default: {\n lastValidIndex = i;\n currentKey = \"0\";\n processValueStart(char, i, \"INSIDE_ARRAY_AFTER_VALUE\");\n break;\n }\n }\n break;\n }\n\n case \"INSIDE_ARRAY_AFTER_VALUE\": {\n switch (char) {\n case \",\": {\n stack.pop();\n stack.push(\"INSIDE_ARRAY_AFTER_COMMA\");\n\n currentKey = (Number(currentKey) + 1).toString();\n break;\n }\n\n case \"]\": {\n lastValidIndex = i;\n stack.pop();\n currentKey = path.pop();\n break;\n }\n\n default: {\n lastValidIndex = i;\n break;\n }\n }\n\n break;\n }\n\n case \"INSIDE_ARRAY_AFTER_COMMA\": {\n processValueStart(char, i, \"INSIDE_ARRAY_AFTER_VALUE\");\n break;\n }\n\n case \"INSIDE_STRING_ESCAPE\": {\n stack.pop();\n\n if (stack[stack.length - 1] === \"INSIDE_STRING\") {\n lastValidIndex = i;\n } else if (stack[stack.length - 1] === \"INSIDE_OBJECT_KEY\") {\n currentKey += char;\n }\n\n break;\n }\n\n case \"INSIDE_NUMBER\": {\n switch (char) {\n case \"0\":\n case \"1\":\n case \"2\":\n case \"3\":\n case \"4\":\n case \"5\":\n case \"6\":\n case \"7\":\n case \"8\":\n case \"9\": {\n lastValidIndex = i;\n break;\n }\n\n case \"e\":\n case \"E\":\n case \"-\":\n case \".\": {\n break;\n }\n\n case \",\": {\n stack.pop();\n currentKey = path.pop();\n\n if (stack[stack.length - 1] === \"INSIDE_ARRAY_AFTER_VALUE\") {\n processAfterArrayValue(char, i);\n }\n\n if (stack[stack.length - 1] === \"INSIDE_OBJECT_AFTER_VALUE\") {\n processAfterObjectValue(char, i);\n }\n\n break;\n }\n\n case \"}\": {\n stack.pop();\n currentKey = path.pop();\n\n if (stack[stack.length - 1] === \"INSIDE_OBJECT_AFTER_VALUE\") {\n processAfterObjectValue(char, i);\n }\n\n break;\n }\n\n case \"]\": {\n stack.pop();\n currentKey = path.pop();\n\n if (stack[stack.length - 1] === \"INSIDE_ARRAY_AFTER_VALUE\") {\n processAfterArrayValue(char, i);\n }\n\n break;\n }\n\n default: {\n stack.pop();\n currentKey = path.pop();\n break;\n }\n }\n\n break;\n }\n\n case \"INSIDE_LITERAL\": {\n const partialLiteral = input.substring(literalStart!, i + 1);\n\n if (\n !\"false\".startsWith(partialLiteral) &&\n !\"true\".startsWith(partialLiteral) &&\n !\"null\".startsWith(partialLiteral)\n ) {\n stack.pop();\n\n if (stack[stack.length - 1] === \"INSIDE_OBJECT_AFTER_VALUE\") {\n processAfterObjectValue(char, i);\n } else if (stack[stack.length - 1] === \"INSIDE_ARRAY_AFTER_VALUE\") {\n processAfterArrayValue(char, i);\n }\n } else {\n lastValidIndex = i;\n }\n\n break;\n }\n }\n }\n\n let result = input.slice(0, lastValidIndex + 1);\n\n for (let i = stack.length - 1; i >= 0; i--) {\n const state = stack[i];\n\n switch (state) {\n case \"INSIDE_STRING\": {\n result += '\"';\n break;\n }\n\n case \"INSIDE_OBJECT_KEY\":\n case \"INSIDE_OBJECT_AFTER_KEY\":\n case \"INSIDE_OBJECT_AFTER_COMMA\":\n case \"INSIDE_OBJECT_START\":\n case \"INSIDE_OBJECT_BEFORE_VALUE\":\n case \"INSIDE_OBJECT_AFTER_VALUE\": {\n result += \"}\";\n break;\n }\n\n case \"INSIDE_ARRAY_START\":\n case \"INSIDE_ARRAY_AFTER_COMMA\":\n case \"INSIDE_ARRAY_AFTER_VALUE\": {\n result += \"]\";\n break;\n }\n\n case \"INSIDE_LITERAL\": {\n const partialLiteral = input.substring(literalStart!, input.length);\n\n if (\"true\".startsWith(partialLiteral)) {\n result += \"true\".slice(partialLiteral.length);\n } else if (\"false\".startsWith(partialLiteral)) {\n result += \"false\".slice(partialLiteral.length);\n } else if (\"null\".startsWith(partialLiteral)) {\n result += \"null\".slice(partialLiteral.length);\n }\n }\n }\n }\n\n return [result, path];\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../src/utils/json/fix-json.ts"],"sourcesContent":["// LICENSE for this file only\n\n// MIT License\n\n// Copyright (c) 2025 AgentbaseAI Inc.\n// Copyright (c) 2023 Lars Grammel\n\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\ntype State =\n | \"ROOT\"\n | \"FINISH\"\n | \"INSIDE_STRING\"\n | \"INSIDE_STRING_ESCAPE\"\n | \"INSIDE_LITERAL\"\n | \"INSIDE_NUMBER\"\n | \"INSIDE_OBJECT_START\"\n | \"INSIDE_OBJECT_KEY\"\n | \"INSIDE_OBJECT_AFTER_KEY\"\n | \"INSIDE_OBJECT_BEFORE_VALUE\"\n | \"INSIDE_OBJECT_AFTER_VALUE\"\n | \"INSIDE_OBJECT_AFTER_COMMA\"\n | \"INSIDE_ARRAY_START\"\n | \"INSIDE_ARRAY_AFTER_VALUE\"\n | \"INSIDE_ARRAY_AFTER_COMMA\";\n\n// Implemented as a scanner with additional fixing\n// that performs a single linear time scan pass over the partial JSON.\n//\n// The states should ideally match relevant states from the JSON spec:\n// https://www.json.org/json-en.html\n//\n// Please note that invalid JSON is not considered/covered, because it\n// is assumed that the resulting JSON will be processed by a standard\n// JSON parser that will detect any invalid JSON.\n\n// Returns a tuple of [fixedJson, partialPath]\n// partialPath is an array of object/array keys that represent\n// the currently partial values. An object is considered partial\n// if through appending extra characters to the JSON string, its\n// value could change.\n\n// Example input: '{\"foo\":[{\"a\":f'\n// Example output: ['{\"foo\":[{\"a\":false}]}', ['foo', '0']]\n// Example input: '{\"foo\":'\n// Example output: ['{}', []]\n\nexport function fixJson(input: string): [string, string[]] {\n const stack: State[] = [\"ROOT\"];\n let lastValidIndex = -1;\n let literalStart: number | null = null;\n const path: string[] = [];\n let currentKey: string | undefined;\n\n function pushCurrentKeyToPath(): void {\n if (currentKey !== undefined) {\n path.push(JSON.parse(`\"${currentKey}\"`));\n currentKey = undefined;\n }\n }\n\n function processValueStart(char: string, i: number, swapState: State) {\n switch (char) {\n case '\"': {\n lastValidIndex = i;\n stack.pop();\n stack.push(swapState);\n stack.push(\"INSIDE_STRING\");\n\n pushCurrentKeyToPath();\n break;\n }\n\n case \"f\":\n case \"t\":\n case \"n\": {\n lastValidIndex = i;\n literalStart = i;\n stack.pop();\n stack.push(swapState);\n stack.push(\"INSIDE_LITERAL\");\n break;\n }\n\n case \"-\": {\n stack.pop();\n stack.push(swapState);\n stack.push(\"INSIDE_NUMBER\");\n\n pushCurrentKeyToPath();\n break;\n }\n case \"0\":\n case \"1\":\n case \"2\":\n case \"3\":\n case \"4\":\n case \"5\":\n case \"6\":\n case \"7\":\n case \"8\":\n case \"9\": {\n lastValidIndex = i;\n stack.pop();\n stack.push(swapState);\n stack.push(\"INSIDE_NUMBER\");\n\n pushCurrentKeyToPath();\n break;\n }\n\n case \"{\": {\n lastValidIndex = i;\n stack.pop();\n stack.push(swapState);\n stack.push(\"INSIDE_OBJECT_START\");\n\n pushCurrentKeyToPath();\n break;\n }\n\n case \"[\": {\n lastValidIndex = i;\n stack.pop();\n stack.push(swapState);\n stack.push(\"INSIDE_ARRAY_START\");\n\n pushCurrentKeyToPath();\n break;\n }\n }\n }\n\n function processAfterObjectValue(char: string, i: number) {\n switch (char) {\n case \",\": {\n stack.pop();\n stack.push(\"INSIDE_OBJECT_AFTER_COMMA\");\n break;\n }\n case \"}\": {\n lastValidIndex = i;\n stack.pop();\n currentKey = path.pop();\n break;\n }\n }\n }\n\n function processAfterArrayValue(char: string, i: number) {\n switch (char) {\n case \",\": {\n stack.pop();\n stack.push(\"INSIDE_ARRAY_AFTER_COMMA\");\n currentKey = (Number(currentKey) + 1).toString();\n break;\n }\n case \"]\": {\n lastValidIndex = i;\n stack.pop();\n currentKey = path.pop();\n break;\n }\n }\n }\n\n for (let i = 0; i < input.length; i++) {\n const char = input[i]!;\n const currentState = stack[stack.length - 1];\n\n switch (currentState) {\n case \"ROOT\":\n processValueStart(char, i, \"FINISH\");\n break;\n\n case \"INSIDE_OBJECT_START\": {\n switch (char) {\n case '\"': {\n stack.pop();\n stack.push(\"INSIDE_OBJECT_KEY\");\n currentKey = \"\";\n break;\n }\n case \"}\": {\n lastValidIndex = i;\n stack.pop();\n currentKey = path.pop();\n break;\n }\n }\n break;\n }\n\n case \"INSIDE_OBJECT_AFTER_COMMA\": {\n switch (char) {\n case '\"': {\n stack.pop();\n stack.push(\"INSIDE_OBJECT_KEY\");\n currentKey = \"\";\n break;\n }\n }\n break;\n }\n\n case \"INSIDE_OBJECT_KEY\": {\n switch (char) {\n case '\"': {\n stack.pop();\n stack.push(\"INSIDE_OBJECT_AFTER_KEY\");\n break;\n }\n case \"\\\\\": {\n stack.push(\"INSIDE_STRING_ESCAPE\");\n currentKey += char;\n break;\n }\n default: {\n currentKey += char;\n break;\n }\n }\n break;\n }\n\n case \"INSIDE_OBJECT_AFTER_KEY\": {\n switch (char) {\n case \":\": {\n stack.pop();\n stack.push(\"INSIDE_OBJECT_BEFORE_VALUE\");\n\n break;\n }\n }\n break;\n }\n\n case \"INSIDE_OBJECT_BEFORE_VALUE\": {\n processValueStart(char, i, \"INSIDE_OBJECT_AFTER_VALUE\");\n break;\n }\n\n case \"INSIDE_OBJECT_AFTER_VALUE\": {\n processAfterObjectValue(char, i);\n break;\n }\n\n case \"INSIDE_STRING\": {\n switch (char) {\n case '\"': {\n stack.pop();\n lastValidIndex = i;\n\n currentKey = path.pop();\n break;\n }\n\n case \"\\\\\": {\n stack.push(\"INSIDE_STRING_ESCAPE\");\n break;\n }\n\n default: {\n lastValidIndex = i;\n }\n }\n\n break;\n }\n\n case \"INSIDE_ARRAY_START\": {\n switch (char) {\n case \"]\": {\n lastValidIndex = i;\n stack.pop();\n currentKey = path.pop();\n break;\n }\n\n default: {\n lastValidIndex = i;\n currentKey = \"0\";\n processValueStart(char, i, \"INSIDE_ARRAY_AFTER_VALUE\");\n break;\n }\n }\n break;\n }\n\n case \"INSIDE_ARRAY_AFTER_VALUE\": {\n switch (char) {\n case \",\": {\n stack.pop();\n stack.push(\"INSIDE_ARRAY_AFTER_COMMA\");\n\n currentKey = (Number(currentKey) + 1).toString();\n break;\n }\n\n case \"]\": {\n lastValidIndex = i;\n stack.pop();\n currentKey = path.pop();\n break;\n }\n\n default: {\n lastValidIndex = i;\n break;\n }\n }\n\n break;\n }\n\n case \"INSIDE_ARRAY_AFTER_COMMA\": {\n processValueStart(char, i, \"INSIDE_ARRAY_AFTER_VALUE\");\n break;\n }\n\n case \"INSIDE_STRING_ESCAPE\": {\n stack.pop();\n\n if (stack[stack.length - 1] === \"INSIDE_STRING\") {\n lastValidIndex = i;\n } else if (stack[stack.length - 1] === \"INSIDE_OBJECT_KEY\") {\n currentKey += char;\n }\n\n break;\n }\n\n case \"INSIDE_NUMBER\": {\n switch (char) {\n case \"0\":\n case \"1\":\n case \"2\":\n case \"3\":\n case \"4\":\n case \"5\":\n case \"6\":\n case \"7\":\n case \"8\":\n case \"9\": {\n lastValidIndex = i;\n break;\n }\n\n case \"e\":\n case \"E\":\n case \"-\":\n case \".\": {\n break;\n }\n\n case \",\": {\n stack.pop();\n currentKey = path.pop();\n\n if (stack[stack.length - 1] === \"INSIDE_ARRAY_AFTER_VALUE\") {\n processAfterArrayValue(char, i);\n }\n\n if (stack[stack.length - 1] === \"INSIDE_OBJECT_AFTER_VALUE\") {\n processAfterObjectValue(char, i);\n }\n\n break;\n }\n\n case \"}\": {\n stack.pop();\n currentKey = path.pop();\n\n if (stack[stack.length - 1] === \"INSIDE_OBJECT_AFTER_VALUE\") {\n processAfterObjectValue(char, i);\n }\n\n break;\n }\n\n case \"]\": {\n stack.pop();\n currentKey = path.pop();\n\n if (stack[stack.length - 1] === \"INSIDE_ARRAY_AFTER_VALUE\") {\n processAfterArrayValue(char, i);\n }\n\n break;\n }\n\n default: {\n stack.pop();\n currentKey = path.pop();\n break;\n }\n }\n\n break;\n }\n\n case \"INSIDE_LITERAL\": {\n const partialLiteral = input.substring(literalStart!, i + 1);\n\n if (\n !\"false\".startsWith(partialLiteral) &&\n !\"true\".startsWith(partialLiteral) &&\n !\"null\".startsWith(partialLiteral)\n ) {\n stack.pop();\n\n if (stack[stack.length - 1] === \"INSIDE_OBJECT_AFTER_VALUE\") {\n processAfterObjectValue(char, i);\n } else if (stack[stack.length - 1] === \"INSIDE_ARRAY_AFTER_VALUE\") {\n processAfterArrayValue(char, i);\n }\n } else {\n lastValidIndex = i;\n }\n\n break;\n }\n }\n }\n\n let result = input.slice(0, lastValidIndex + 1);\n\n for (let i = stack.length - 1; i >= 0; i--) {\n const state = stack[i];\n\n switch (state) {\n case \"INSIDE_STRING\": {\n result += '\"';\n break;\n }\n\n case \"INSIDE_OBJECT_KEY\":\n case \"INSIDE_OBJECT_AFTER_KEY\":\n case \"INSIDE_OBJECT_AFTER_COMMA\":\n case \"INSIDE_OBJECT_START\":\n case \"INSIDE_OBJECT_BEFORE_VALUE\":\n case \"INSIDE_OBJECT_AFTER_VALUE\": {\n result += \"}\";\n break;\n }\n\n case \"INSIDE_ARRAY_START\":\n case \"INSIDE_ARRAY_AFTER_COMMA\":\n case \"INSIDE_ARRAY_AFTER_VALUE\": {\n result += \"]\";\n break;\n }\n\n case \"INSIDE_LITERAL\": {\n const partialLiteral = input.substring(literalStart!, input.length);\n\n if (\"true\".startsWith(partialLiteral)) {\n result += \"true\".slice(partialLiteral.length);\n } else if (\"false\".startsWith(partialLiteral)) {\n result += \"false\".slice(partialLiteral.length);\n } else if (\"null\".startsWith(partialLiteral)) {\n result += \"null\".slice(partialLiteral.length);\n }\n }\n }\n }\n\n return [result, path];\n}\n"],"mappings":"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","names":[]}
@@ -1,2 +1,2 @@
1
- export { type ReadonlyJSONObject, type ReadonlyJSONValue } from "./json-value";
1
+ export type { ReadonlyJSONObject, ReadonlyJSONValue } from "./json-value";
2
2
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/utils/json/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,kBAAkB,EAAE,KAAK,iBAAiB,EAAE,MAAM,cAAc,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/utils/json/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC"}
@@ -1,7 +1,7 @@
1
1
  // src/utils/json/parse-partial-json-object.ts
2
2
  import sjson from "secure-json-parse";
3
3
  import { fixJson } from "./fix-json.js";
4
- var PARTIAL_JSON_OBJECT_META_SYMBOL = Symbol(
4
+ var PARTIAL_JSON_OBJECT_META_SYMBOL = /* @__PURE__ */ Symbol(
5
5
  "aui.parse-partial-json-object.meta"
6
6
  );
7
7
  var getPartialJsonObjectMeta = (obj) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "assistant-stream",
3
- "version": "0.2.42",
3
+ "version": "0.2.44",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "exports": {
@@ -26,8 +26,8 @@
26
26
  "devDependencies": {
27
27
  "@standard-schema/spec": "^1.0.0",
28
28
  "@types/node": "^24.10.1",
29
- "tsx": "^4.20.6",
30
- "vitest": "^4.0.14",
29
+ "tsx": "^4.21.0",
30
+ "vitest": "^4.0.15",
31
31
  "@assistant-ui/x-buildutils": "0.0.1"
32
32
  },
33
33
  "publishConfig": {
@@ -49,7 +49,6 @@
49
49
  "scripts": {
50
50
  "build": "tsx scripts/build.mts",
51
51
  "test": "vitest run",
52
- "test:watch": "vitest",
53
- "lint": "eslint ."
52
+ "test:watch": "vitest"
54
53
  }
55
54
  }
@@ -59,7 +59,7 @@ export class ObjectStreamAccumulator {
59
59
  const [key, ...rest] = path as [string, ...(readonly string[])];
60
60
  if (Array.isArray(state)) {
61
61
  const idx = Number(key);
62
- if (isNaN(idx))
62
+ if (Number.isNaN(idx))
63
63
  throw new Error(`Expected array index at [${path.join(", ")}]`);
64
64
  if (idx > state.length || idx < 0)
65
65
  throw new Error(`Insert array index out of bounds`);
@@ -260,7 +260,7 @@ export class DataStreamDecoder extends PipeableTransformStream<
260
260
 
261
261
  if (toolCallControllers.has(toolCallId))
262
262
  throw new Error(
263
- "Encountered duplicate tool call id: " + toolCallId,
263
+ `Encountered duplicate tool call id: ${toolCallId}`,
264
264
  );
265
265
 
266
266
  const toolCallController = ctrl.addToolCallPart({
@@ -278,7 +278,7 @@ export class DataStreamDecoder extends PipeableTransformStream<
278
278
  const toolCallController = toolCallControllers.get(toolCallId);
279
279
  if (!toolCallController)
280
280
  throw new Error(
281
- "Encountered tool call with unknown id: " + toolCallId,
281
+ `Encountered tool call with unknown id: ${toolCallId}`,
282
282
  );
283
283
  toolCallController.argsText.append(argsTextDelta);
284
284
  break;
@@ -289,7 +289,7 @@ export class DataStreamDecoder extends PipeableTransformStream<
289
289
  const toolCallController = toolCallControllers.get(toolCallId);
290
290
  if (!toolCallController)
291
291
  throw new Error(
292
- "Encountered tool call result with unknown id: " + toolCallId,
292
+ `Encountered tool call result with unknown id: ${toolCallId}`,
293
293
  );
294
294
  toolCallController.setResponse({
295
295
  artifact,
@@ -35,6 +35,10 @@ type ToolStreamCallback = <
35
35
  type ToolExecutionOptions = {
36
36
  execute: ToolCallback;
37
37
  streamCall: ToolStreamCallback;
38
+ onExecutionStart?:
39
+ | ((toolCallId: string, toolName: string) => void)
40
+ | undefined;
41
+ onExecutionEnd?: ((toolCallId: string, toolName: string) => void) | undefined;
38
42
  };
39
43
 
40
44
  export class ToolExecutionStream extends PipeableTransformStream<
@@ -112,6 +116,7 @@ export class ToolExecutionStream extends PipeableTransformStream<
112
116
  if (!streamController)
113
117
  throw new Error("No controller found for tool call");
114
118
 
119
+ let isExecuting = false;
115
120
  const promise = withPromiseOrValue(
116
121
  () => {
117
122
  let args;
@@ -123,13 +128,25 @@ export class ToolExecutionStream extends PipeableTransformStream<
123
128
  );
124
129
  }
125
130
 
126
- return options.execute({
131
+ const executeResult = options.execute({
127
132
  toolCallId,
128
133
  toolName,
129
134
  args,
130
135
  });
136
+
137
+ // Only mark as executing if the tool has frontend execution
138
+ if (executeResult !== undefined) {
139
+ isExecuting = true;
140
+ options.onExecutionStart?.(toolCallId, toolName);
141
+ }
142
+
143
+ return executeResult;
131
144
  },
132
145
  (c) => {
146
+ if (isExecuting) {
147
+ options.onExecutionEnd?.(toolCallId, toolName);
148
+ }
149
+
133
150
  if (c === undefined) return;
134
151
 
135
152
  // TODO how to handle new ToolResult({ result: undefined })?
@@ -146,6 +163,10 @@ export class ToolExecutionStream extends PipeableTransformStream<
146
163
  });
147
164
  },
148
165
  (e) => {
166
+ if (isExecuting) {
167
+ options.onExecutionEnd?.(toolCallId, toolName);
168
+ }
169
+
149
170
  const result = new ToolResponse({
150
171
  result: String(e),
151
172
  isError: true,
@@ -5,4 +5,5 @@ export type { ToolCallReader } from "./tool-types";
5
5
  export {
6
6
  toolResultStream as unstable_toolResultStream,
7
7
  unstable_runPendingTools,
8
+ type ToolResultStreamOptions,
8
9
  } from "./toolResultStream";
@@ -32,6 +32,14 @@ function getToolResponse(
32
32
  const getResult = async (
33
33
  toolExecute: ToolExecuteFunction<ReadonlyJSONObject, unknown>,
34
34
  ): Promise<ToolResponse<ReadonlyJSONValue>> => {
35
+ // Check if already aborted before starting
36
+ if (abortSignal.aborted) {
37
+ return new ToolResponse({
38
+ result: "Tool execution was cancelled.",
39
+ isError: true,
40
+ });
41
+ }
42
+
35
43
  let executeFn = toolExecute;
36
44
 
37
45
  if (isStandardSchemaV1(tool.parameters)) {
@@ -49,12 +57,40 @@ function getToolResponse(
49
57
  }
50
58
  }
51
59
 
52
- const result = (await executeFn(toolCall.args, {
53
- toolCallId: toolCall.toolCallId,
54
- abortSignal,
55
- human: (payload: unknown) => human(toolCall.toolCallId, payload),
56
- })) as unknown as ReadonlyJSONValue;
57
- return ToolResponse.toResponse(result);
60
+ // Create abort promise that resolves after 2 microtasks
61
+ // This gives tools that handle abort a chance to win the race
62
+ const abortPromise = new Promise<ToolResponse<ReadonlyJSONValue>>(
63
+ (resolve) => {
64
+ const onAbort = () => {
65
+ queueMicrotask(() => {
66
+ queueMicrotask(() => {
67
+ resolve(
68
+ new ToolResponse({
69
+ result: "Tool execution was cancelled.",
70
+ isError: true,
71
+ }),
72
+ );
73
+ });
74
+ });
75
+ };
76
+ if (abortSignal.aborted) {
77
+ onAbort();
78
+ } else {
79
+ abortSignal.addEventListener("abort", onAbort, { once: true });
80
+ }
81
+ },
82
+ );
83
+
84
+ const executePromise = (async () => {
85
+ const result = (await executeFn(toolCall.args, {
86
+ toolCallId: toolCall.toolCallId,
87
+ abortSignal,
88
+ human: (payload: unknown) => human(toolCall.toolCallId, payload),
89
+ })) as unknown as ReadonlyJSONValue;
90
+ return ToolResponse.toResponse(result);
91
+ })();
92
+
93
+ return Promise.race([executePromise, abortPromise]);
58
94
  };
59
95
 
60
96
  return getResult(tool.execute);
@@ -148,6 +184,11 @@ export async function unstable_runPendingTools(
148
184
  };
149
185
  }
150
186
 
187
+ export type ToolResultStreamOptions = {
188
+ onExecutionStart?: (toolCallId: string, toolName: string) => void;
189
+ onExecutionEnd?: (toolCallId: string, toolName: string) => void;
190
+ };
191
+
151
192
  export function toolResultStream(
152
193
  tools:
153
194
  | Record<string, Tool>
@@ -155,6 +196,7 @@ export function toolResultStream(
155
196
  | undefined,
156
197
  abortSignal: AbortSignal | (() => AbortSignal),
157
198
  human: (toolCallId: string, payload: unknown) => Promise<unknown>,
199
+ options?: ToolResultStreamOptions,
158
200
  ) {
159
201
  const toolsFn = typeof tools === "function" ? tools : () => tools;
160
202
  const abortSignalFn =
@@ -164,5 +206,7 @@ export function toolResultStream(
164
206
  getToolResponse(toolsFn(), abortSignalFn(), toolCall, human),
165
207
  streamCall: ({ reader, ...context }) =>
166
208
  getToolStreamResponse(toolsFn(), abortSignalFn(), reader, context, human),
209
+ onExecutionStart: options?.onExecutionStart,
210
+ onExecutionEnd: options?.onExecutionEnd,
167
211
  });
168
212
  }
@@ -2,4 +2,4 @@ export {
2
2
  asAsyncIterableStream,
3
3
  type AsyncIterableStream,
4
4
  } from "./AsyncIterableStream";
5
- export { type ReadonlyJSONObject, type ReadonlyJSONValue } from "./json";
5
+ export type { ReadonlyJSONObject, ReadonlyJSONValue } from "./json";
@@ -70,81 +70,79 @@ export function fixJson(input: string): [string, string[]] {
70
70
 
71
71
  function pushCurrentKeyToPath(): void {
72
72
  if (currentKey !== undefined) {
73
- path.push(JSON.parse('"' + currentKey + '"'));
73
+ path.push(JSON.parse(`"${currentKey}"`));
74
74
  currentKey = undefined;
75
75
  }
76
76
  }
77
77
 
78
78
  function processValueStart(char: string, i: number, swapState: State) {
79
- {
80
- switch (char) {
81
- case '"': {
82
- lastValidIndex = i;
83
- stack.pop();
84
- stack.push(swapState);
85
- stack.push("INSIDE_STRING");
79
+ switch (char) {
80
+ case '"': {
81
+ lastValidIndex = i;
82
+ stack.pop();
83
+ stack.push(swapState);
84
+ stack.push("INSIDE_STRING");
86
85
 
87
- pushCurrentKeyToPath();
88
- break;
89
- }
86
+ pushCurrentKeyToPath();
87
+ break;
88
+ }
90
89
 
91
- case "f":
92
- case "t":
93
- case "n": {
94
- lastValidIndex = i;
95
- literalStart = i;
96
- stack.pop();
97
- stack.push(swapState);
98
- stack.push("INSIDE_LITERAL");
99
- break;
100
- }
90
+ case "f":
91
+ case "t":
92
+ case "n": {
93
+ lastValidIndex = i;
94
+ literalStart = i;
95
+ stack.pop();
96
+ stack.push(swapState);
97
+ stack.push("INSIDE_LITERAL");
98
+ break;
99
+ }
101
100
 
102
- case "-": {
103
- stack.pop();
104
- stack.push(swapState);
105
- stack.push("INSIDE_NUMBER");
101
+ case "-": {
102
+ stack.pop();
103
+ stack.push(swapState);
104
+ stack.push("INSIDE_NUMBER");
106
105
 
107
- pushCurrentKeyToPath();
108
- break;
109
- }
110
- case "0":
111
- case "1":
112
- case "2":
113
- case "3":
114
- case "4":
115
- case "5":
116
- case "6":
117
- case "7":
118
- case "8":
119
- case "9": {
120
- lastValidIndex = i;
121
- stack.pop();
122
- stack.push(swapState);
123
- stack.push("INSIDE_NUMBER");
106
+ pushCurrentKeyToPath();
107
+ break;
108
+ }
109
+ case "0":
110
+ case "1":
111
+ case "2":
112
+ case "3":
113
+ case "4":
114
+ case "5":
115
+ case "6":
116
+ case "7":
117
+ case "8":
118
+ case "9": {
119
+ lastValidIndex = i;
120
+ stack.pop();
121
+ stack.push(swapState);
122
+ stack.push("INSIDE_NUMBER");
124
123
 
125
- pushCurrentKeyToPath();
126
- break;
127
- }
124
+ pushCurrentKeyToPath();
125
+ break;
126
+ }
128
127
 
129
- case "{": {
130
- lastValidIndex = i;
131
- stack.pop();
132
- stack.push(swapState);
133
- stack.push("INSIDE_OBJECT_START");
128
+ case "{": {
129
+ lastValidIndex = i;
130
+ stack.pop();
131
+ stack.push(swapState);
132
+ stack.push("INSIDE_OBJECT_START");
134
133
 
135
- pushCurrentKeyToPath();
136
- break;
137
- }
134
+ pushCurrentKeyToPath();
135
+ break;
136
+ }
138
137
 
139
- case "[": {
140
- lastValidIndex = i;
141
- stack.pop();
142
- stack.push(swapState);
143
- stack.push("INSIDE_ARRAY_START");
138
+ case "[": {
139
+ lastValidIndex = i;
140
+ stack.pop();
141
+ stack.push(swapState);
142
+ stack.push("INSIDE_ARRAY_START");
144
143
 
145
- pushCurrentKeyToPath();
146
- break;
147
- }
144
+ pushCurrentKeyToPath();
145
+ break;
148
146
  }
149
147
  }
150
148
  }
@@ -1 +1 @@
1
- export { type ReadonlyJSONObject, type ReadonlyJSONValue } from "./json-value";
1
+ export type { ReadonlyJSONObject, ReadonlyJSONValue } from "./json-value";
@@ -186,7 +186,7 @@ const tests: PartialJsonTest[] = [
186
186
  result: "complete",
187
187
  },
188
188
  {
189
- input: `{"foo": [1,"\",{"b":1},[],{},[1,[[2]]],{"1":1,"t":1`,
189
+ input: `{"foo": [1,"",{"b":1},[],{},[1,[[2]]],{"1":1,"t":1`,
190
190
  query: ["foo", 6, "t"],
191
191
  result: "partial",
192
192
  },