@flutchai/flutch-sdk 0.7.15 → 0.7.16

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.
package/dist/index.cjs CHANGED
@@ -5291,6 +5291,7 @@ function joinTextSteps(parts) {
5291
5291
  __name(joinTextSteps, "joinTextSteps");
5292
5292
  var MIN_DUPLICATE_WORDS = 8;
5293
5293
  var DUPLICATE_SIMILARITY = 0.75;
5294
+ var NO_TOOL_END = "No result: the call's end was not received.";
5294
5295
  function paragraphsOf(text) {
5295
5296
  return text.split(/\n\s*\n/).map((p) => p.trim()).filter(Boolean);
5296
5297
  }
@@ -5715,21 +5716,7 @@ exports.EventProcessor = class _EventProcessor {
5715
5716
  } catch {
5716
5717
  outputString = typeof output?.content === "string" ? output.content : "[Output too large to display]";
5717
5718
  }
5718
- const MAX_TOOL_OUTPUT_LENGTH = 5e4;
5719
- if (outputString.length > MAX_TOOL_OUTPUT_LENGTH) {
5720
- let cutAt = outputString.lastIndexOf("\n", MAX_TOOL_OUTPUT_LENGTH);
5721
- if (cutAt < MAX_TOOL_OUTPUT_LENGTH * 0.8) {
5722
- cutAt = MAX_TOOL_OUTPUT_LENGTH;
5723
- }
5724
- outputString = outputString.slice(0, cutAt) + `
5725
- ... [truncated: ${outputString.length - cutAt} chars]`;
5726
- }
5727
- toolBlock.output = outputString;
5728
- this.sendDelta(channel, {
5729
- type: "tool_output_chunk",
5730
- stepId: toolBlock.id,
5731
- chunk: outputString
5732
- }, onPartial);
5719
+ this.closeToolBlock(channel, toolBlock, outputString, onPartial);
5733
5720
  this.logger.log("\u2705 Tool completed", {
5734
5721
  toolName: event.name,
5735
5722
  toolBlockId: toolBlock.id,
@@ -5746,8 +5733,18 @@ exports.EventProcessor = class _EventProcessor {
5746
5733
  if (event.event === "on_tool_error") {
5747
5734
  const channel = event.metadata?.stream_channel ?? StreamChannel.TEXT;
5748
5735
  const state = acc.channels.get(channel);
5749
- if (state && event.run_id) {
5736
+ let toolBlock;
5737
+ if (state && event.run_id && state.toolBlocksByRunId.has(event.run_id)) {
5738
+ toolBlock = state.toolBlocksByRunId.get(event.run_id);
5750
5739
  state.toolBlocksByRunId.delete(event.run_id);
5740
+ } else if (state) {
5741
+ const idx = state.pendingToolBlocks.findIndex((b) => b.name === event.name);
5742
+ if (idx !== -1) toolBlock = state.pendingToolBlocks.splice(idx, 1)[0];
5743
+ }
5744
+ if (toolBlock && toolBlock.type === "tool_use") {
5745
+ const error = event.data?.error;
5746
+ const message = error instanceof Error ? error.message : String(error ?? "failed");
5747
+ this.closeToolBlock(channel, toolBlock, `Error: ${message}`, onPartial);
5751
5748
  }
5752
5749
  this.logger.error("\u274C Tool failed", {
5753
5750
  toolName: event.name,
@@ -5788,6 +5785,28 @@ exports.EventProcessor = class _EventProcessor {
5788
5785
  }
5789
5786
  }
5790
5787
  /**
5788
+ * A call's result on its block and to the client: the client closes the
5789
+ * step on it. Cut to keep the message document under MongoDB's 16MB.
5790
+ */
5791
+ closeToolBlock(channel, toolBlock, output, onPartial) {
5792
+ const MAX_TOOL_OUTPUT_LENGTH = 5e4;
5793
+ let outputString = output;
5794
+ if (outputString.length > MAX_TOOL_OUTPUT_LENGTH) {
5795
+ let cutAt = outputString.lastIndexOf("\n", MAX_TOOL_OUTPUT_LENGTH);
5796
+ if (cutAt < MAX_TOOL_OUTPUT_LENGTH * 0.8) {
5797
+ cutAt = MAX_TOOL_OUTPUT_LENGTH;
5798
+ }
5799
+ outputString = outputString.slice(0, cutAt) + `
5800
+ ... [truncated: ${outputString.length - cutAt} chars]`;
5801
+ }
5802
+ toolBlock.output = outputString;
5803
+ this.sendDelta(channel, {
5804
+ type: "tool_output_chunk",
5805
+ stepId: toolBlock.id,
5806
+ chunk: outputString
5807
+ }, onPartial);
5808
+ }
5809
+ /**
5791
5810
  * Build final result from accumulator
5792
5811
  * Returns unified content chains from all channels
5793
5812
  */
@@ -5800,6 +5819,12 @@ exports.EventProcessor = class _EventProcessor {
5800
5819
  pendingCount: state.pendingToolBlocks.length,
5801
5820
  mappedCount: state.toolBlocksByRunId.size
5802
5821
  });
5822
+ for (const block of [
5823
+ ...state.pendingToolBlocks,
5824
+ ...state.toolBlocksByRunId.values()
5825
+ ]) if (block.type === "tool_use" && !block.output) block.output = NO_TOOL_END;
5826
+ state.pendingToolBlocks = [];
5827
+ state.toolBlocksByRunId.clear();
5803
5828
  }
5804
5829
  if (state.currentBlock) {
5805
5830
  state.contentChain.push(state.currentBlock);