@flutchai/flutch-sdk 0.7.14 → 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 +86 -21
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +15 -1
- package/dist/index.d.ts +15 -1
- package/dist/index.js +84 -22
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -5203,6 +5203,29 @@ function sanitizeTraceError(error, options) {
|
|
|
5203
5203
|
}
|
|
5204
5204
|
__name(sanitizeTraceError, "sanitizeTraceError");
|
|
5205
5205
|
|
|
5206
|
+
// src/tools/tool-usage.ts
|
|
5207
|
+
function toolUsageOf(value) {
|
|
5208
|
+
const cost = value?.total_cost;
|
|
5209
|
+
return typeof cost === "number" && Number.isFinite(cost) && cost >= 0 ? {
|
|
5210
|
+
total_cost: cost
|
|
5211
|
+
} : void 0;
|
|
5212
|
+
}
|
|
5213
|
+
__name(toolUsageOf, "toolUsageOf");
|
|
5214
|
+
function toolEndOutput(content, usage) {
|
|
5215
|
+
return usage ? {
|
|
5216
|
+
content,
|
|
5217
|
+
usage_metadata: usage
|
|
5218
|
+
} : content;
|
|
5219
|
+
}
|
|
5220
|
+
__name(toolEndOutput, "toolEndOutput");
|
|
5221
|
+
function toolEndContent(output) {
|
|
5222
|
+
if (!output || typeof output !== "object") return void 0;
|
|
5223
|
+
const o = output;
|
|
5224
|
+
if (typeof o.content !== "string") return void 0;
|
|
5225
|
+
return toolUsageOf(o.usage_metadata) || toolUsageOf(o.artifact?.usage_metadata) ? o.content : void 0;
|
|
5226
|
+
}
|
|
5227
|
+
__name(toolEndContent, "toolEndContent");
|
|
5228
|
+
|
|
5206
5229
|
// src/engines/langgraph/stream-thinking.ts
|
|
5207
5230
|
function splitThinking(blocks) {
|
|
5208
5231
|
const thoughts = [];
|
|
@@ -5268,6 +5291,7 @@ function joinTextSteps(parts) {
|
|
|
5268
5291
|
__name(joinTextSteps, "joinTextSteps");
|
|
5269
5292
|
var MIN_DUPLICATE_WORDS = 8;
|
|
5270
5293
|
var DUPLICATE_SIMILARITY = 0.75;
|
|
5294
|
+
var NO_TOOL_END = "No result: the call's end was not received.";
|
|
5271
5295
|
function paragraphsOf(text) {
|
|
5272
5296
|
return text.split(/\n\s*\n/).map((p) => p.trim()).filter(Boolean);
|
|
5273
5297
|
}
|
|
@@ -5688,25 +5712,11 @@ exports.EventProcessor = class _EventProcessor {
|
|
|
5688
5712
|
const output = event.data?.output;
|
|
5689
5713
|
let outputString;
|
|
5690
5714
|
try {
|
|
5691
|
-
outputString = typeof output === "string" ? output : JSON.stringify(output, null, 2);
|
|
5715
|
+
outputString = typeof output === "string" ? output : toolEndContent(output) ?? JSON.stringify(output, null, 2);
|
|
5692
5716
|
} catch {
|
|
5693
5717
|
outputString = typeof output?.content === "string" ? output.content : "[Output too large to display]";
|
|
5694
5718
|
}
|
|
5695
|
-
|
|
5696
|
-
if (outputString.length > MAX_TOOL_OUTPUT_LENGTH) {
|
|
5697
|
-
let cutAt = outputString.lastIndexOf("\n", MAX_TOOL_OUTPUT_LENGTH);
|
|
5698
|
-
if (cutAt < MAX_TOOL_OUTPUT_LENGTH * 0.8) {
|
|
5699
|
-
cutAt = MAX_TOOL_OUTPUT_LENGTH;
|
|
5700
|
-
}
|
|
5701
|
-
outputString = outputString.slice(0, cutAt) + `
|
|
5702
|
-
... [truncated: ${outputString.length - cutAt} chars]`;
|
|
5703
|
-
}
|
|
5704
|
-
toolBlock.output = outputString;
|
|
5705
|
-
this.sendDelta(channel, {
|
|
5706
|
-
type: "tool_output_chunk",
|
|
5707
|
-
stepId: toolBlock.id,
|
|
5708
|
-
chunk: outputString
|
|
5709
|
-
}, onPartial);
|
|
5719
|
+
this.closeToolBlock(channel, toolBlock, outputString, onPartial);
|
|
5710
5720
|
this.logger.log("\u2705 Tool completed", {
|
|
5711
5721
|
toolName: event.name,
|
|
5712
5722
|
toolBlockId: toolBlock.id,
|
|
@@ -5723,8 +5733,18 @@ exports.EventProcessor = class _EventProcessor {
|
|
|
5723
5733
|
if (event.event === "on_tool_error") {
|
|
5724
5734
|
const channel = event.metadata?.stream_channel ?? StreamChannel.TEXT;
|
|
5725
5735
|
const state = acc.channels.get(channel);
|
|
5726
|
-
|
|
5736
|
+
let toolBlock;
|
|
5737
|
+
if (state && event.run_id && state.toolBlocksByRunId.has(event.run_id)) {
|
|
5738
|
+
toolBlock = state.toolBlocksByRunId.get(event.run_id);
|
|
5727
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);
|
|
5728
5748
|
}
|
|
5729
5749
|
this.logger.error("\u274C Tool failed", {
|
|
5730
5750
|
toolName: event.name,
|
|
@@ -5765,6 +5785,28 @@ exports.EventProcessor = class _EventProcessor {
|
|
|
5765
5785
|
}
|
|
5766
5786
|
}
|
|
5767
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
|
+
/**
|
|
5768
5810
|
* Build final result from accumulator
|
|
5769
5811
|
* Returns unified content chains from all channels
|
|
5770
5812
|
*/
|
|
@@ -5777,6 +5819,12 @@ exports.EventProcessor = class _EventProcessor {
|
|
|
5777
5819
|
pendingCount: state.pendingToolBlocks.length,
|
|
5778
5820
|
mappedCount: state.toolBlocksByRunId.size
|
|
5779
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();
|
|
5780
5828
|
}
|
|
5781
5829
|
if (state.currentBlock) {
|
|
5782
5830
|
state.contentChain.push(state.currentBlock);
|
|
@@ -6957,6 +7005,9 @@ ${paramDescriptions.join("\n")}`;
|
|
|
6957
7005
|
name: mcpTool.name,
|
|
6958
7006
|
description: enhancedDescription,
|
|
6959
7007
|
schema,
|
|
7008
|
+
// The call's cost rides on the ToolMessage's artifact, which the model
|
|
7009
|
+
// never sees and the trace keeps (see tool-usage.ts).
|
|
7010
|
+
responseFormat: "content_and_artifact",
|
|
6960
7011
|
func: /* @__PURE__ */ __name(async (input, _runManager, config) => {
|
|
6961
7012
|
logger3.log(`\u{1F527} [${mcpTool.name}] LLM INPUT: ${JSON.stringify(input)}`);
|
|
6962
7013
|
const configurable = config?.configurable;
|
|
@@ -6985,7 +7036,13 @@ ${paramDescriptions.join("\n")}`;
|
|
|
6985
7036
|
}
|
|
6986
7037
|
const output = typeof result.result === "string" ? result.result : JSON.stringify(result.result, null, 2);
|
|
6987
7038
|
logger3.log(`\u{1F527} [${mcpTool.name}] TOOL OUTPUT: ${output.length > 200 ? output.substring(0, 200) + "..." : output}`);
|
|
6988
|
-
|
|
7039
|
+
const usage = toolUsageOf(result.usage_metadata);
|
|
7040
|
+
return [
|
|
7041
|
+
output,
|
|
7042
|
+
usage ? {
|
|
7043
|
+
usage_metadata: usage
|
|
7044
|
+
} : void 0
|
|
7045
|
+
];
|
|
6989
7046
|
} catch (error) {
|
|
6990
7047
|
logger3.error(`\u{1F527} [${mcpTool.name}] Exception during execution`, error);
|
|
6991
7048
|
if (axios2__default.default.isAxiosError(error)) {
|
|
@@ -7305,12 +7362,17 @@ exports.McpRuntimeHttpClient = class _McpRuntimeHttpClient {
|
|
|
7305
7362
|
]
|
|
7306
7363
|
}, JSON.stringify(enrichedArgs), parsedConfig.runId, void 0, parsedConfig.tags, parsedConfig.metadata, toolName);
|
|
7307
7364
|
const result = await this.executeTool(toolName, enrichedArgs, executionContext, mcpServers, config?.signal);
|
|
7308
|
-
const
|
|
7309
|
-
|
|
7365
|
+
const { usage_metadata: rawUsage, ...shown } = result;
|
|
7366
|
+
const usageMetadata = toolUsageOf(rawUsage);
|
|
7367
|
+
const content = shown.success ? JSON.stringify(shown) : shown.error || JSON.stringify(shown);
|
|
7368
|
+
await runManager?.handleToolEnd(toolEndOutput(content, usageMetadata));
|
|
7310
7369
|
return {
|
|
7311
7370
|
content,
|
|
7312
7371
|
success: result.success,
|
|
7313
|
-
rawResult: result.success ? result.result : void 0
|
|
7372
|
+
rawResult: result.success ? result.result : void 0,
|
|
7373
|
+
...usageMetadata && {
|
|
7374
|
+
usageMetadata
|
|
7375
|
+
}
|
|
7314
7376
|
};
|
|
7315
7377
|
} catch (error) {
|
|
7316
7378
|
this.logger.error(`Error executing tool ${toolName}:`, error);
|
|
@@ -9491,8 +9553,11 @@ exports.splitTools = splitTools;
|
|
|
9491
9553
|
exports.storeAttachmentData = storeAttachmentData;
|
|
9492
9554
|
exports.toOpenAIEffort = toOpenAIEffort;
|
|
9493
9555
|
exports.toOptionalNumber = toOptionalNumber;
|
|
9556
|
+
exports.toolEndContent = toolEndContent;
|
|
9557
|
+
exports.toolEndOutput = toolEndOutput;
|
|
9494
9558
|
exports.toolSearchApplies = toolSearchApplies;
|
|
9495
9559
|
exports.toolSearchTerms = toolSearchTerms;
|
|
9560
|
+
exports.toolUsageOf = toolUsageOf;
|
|
9496
9561
|
exports.traceApiCall = traceApiCall;
|
|
9497
9562
|
exports.withFlutchContext = withFlutchContext;
|
|
9498
9563
|
exports.withToolReferences = withToolReferences;
|