@mindstudio-ai/agent 0.1.141 → 0.1.142
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/cli.js +66 -24
- package/dist/index.d.ts +26 -0
- package/dist/index.js +60 -18
- package/dist/index.js.map +1 -1
- package/dist/postinstall.js +66 -24
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -5169,9 +5169,11 @@ function logTaskResult(result) {
|
|
|
5169
5169
|
if (!isDevMode()) {
|
|
5170
5170
|
return;
|
|
5171
5171
|
}
|
|
5172
|
-
const toolSummary = result.toolCalls.map(
|
|
5172
|
+
const toolSummary = result.toolCalls.map(
|
|
5173
|
+
(tc) => `${tc.name} (${tc.durationMs}ms) ${tc.success ? "\u2713" : "\u2717"}` + (tc.truncated ? " \u26A0 result cut" : "")
|
|
5174
|
+
).join(", ");
|
|
5173
5175
|
console.log(
|
|
5174
|
-
`[task] ${result.turns} turn${result.turns === 1 ? "" : "s"}` + (toolSummary ? `: ${toolSummary}` : "") + ` | ${result.parsedSuccessfully ? "output OK" : "\u26A0 output not valid JSON"} | cost: ${result.usage.totalBillingCost} | trace: ${result.traceId}`
|
|
5176
|
+
`[task] ${result.turns} turn${result.turns === 1 ? "" : "s"}` + (toolSummary ? `: ${toolSummary}` : "") + (result.hitMaxTurns ? " | \u26A0 ran out of turns" : "") + (result.stopReason === "max_tokens" ? " | \u26A0 answer cut at the output limit" : "") + ` | ${result.parsedSuccessfully ? "output OK" : "\u26A0 output not valid JSON"} | cost: ${result.usage.totalBillingCost} | trace: ${result.traceId}`
|
|
5175
5177
|
);
|
|
5176
5178
|
}
|
|
5177
5179
|
var init_task = __esm({
|
|
@@ -5356,9 +5358,20 @@ function mergeToolInput(modelInput, defaults) {
|
|
|
5356
5358
|
}
|
|
5357
5359
|
return merged;
|
|
5358
5360
|
}
|
|
5359
|
-
function truncateToolOutput(output) {
|
|
5361
|
+
function truncateToolOutput(output, maxChars) {
|
|
5360
5362
|
const serialized = JSON.stringify(output);
|
|
5361
|
-
|
|
5363
|
+
if (!serialized || serialized.length <= maxChars) {
|
|
5364
|
+
return { output, truncated: false };
|
|
5365
|
+
}
|
|
5366
|
+
return {
|
|
5367
|
+
output: {
|
|
5368
|
+
truncated: true,
|
|
5369
|
+
totalChars: serialized.length,
|
|
5370
|
+
shownChars: maxChars,
|
|
5371
|
+
content: serialized.slice(0, maxChars)
|
|
5372
|
+
},
|
|
5373
|
+
truncated: true
|
|
5374
|
+
};
|
|
5362
5375
|
}
|
|
5363
5376
|
async function attemptTurn(httpConfig, body) {
|
|
5364
5377
|
const url = `${httpConfig.baseUrl}/developer/v2/task/turn`;
|
|
@@ -5569,6 +5582,7 @@ ${structuredOutputExample}
|
|
|
5569
5582
|
Math.max(options.maxTurns || DEFAULT_MAX_TURNS, 1),
|
|
5570
5583
|
MAX_TURNS_LIMIT
|
|
5571
5584
|
);
|
|
5585
|
+
const maxToolOutputChars = options.maxToolOutputChars ?? MAX_TOOL_OUTPUT_CHARS;
|
|
5572
5586
|
const traceId = randomUUID2();
|
|
5573
5587
|
const messages = [
|
|
5574
5588
|
{ role: "user", content: JSON.stringify(options.input) }
|
|
@@ -5583,11 +5597,13 @@ ${structuredOutputExample}
|
|
|
5583
5597
|
cacheReadTokens: 0,
|
|
5584
5598
|
totalBillingCost: 0
|
|
5585
5599
|
};
|
|
5586
|
-
const buildResult = (output2, outputRaw, parsedSuccessfully2, turns) => ({
|
|
5600
|
+
const buildResult = (output2, outputRaw, parsedSuccessfully2, turns, stopReason, hitMaxTurns = false) => ({
|
|
5587
5601
|
output: output2,
|
|
5588
5602
|
outputRaw,
|
|
5589
5603
|
parsedSuccessfully: parsedSuccessfully2,
|
|
5590
5604
|
turns,
|
|
5605
|
+
hitMaxTurns,
|
|
5606
|
+
stopReason,
|
|
5591
5607
|
usage: totalUsage,
|
|
5592
5608
|
toolCalls: toolCallLog,
|
|
5593
5609
|
traceId
|
|
@@ -5645,7 +5661,7 @@ ${structuredOutputExample}
|
|
|
5645
5661
|
}
|
|
5646
5662
|
);
|
|
5647
5663
|
}
|
|
5648
|
-
return finish(buildResult(null, "", false, loopCount));
|
|
5664
|
+
return finish(buildResult(null, "", false, loopCount, null));
|
|
5649
5665
|
}
|
|
5650
5666
|
if (err instanceof TurnError) {
|
|
5651
5667
|
throw new MindStudioError(
|
|
@@ -5692,11 +5708,11 @@ ${structuredOutputExample}
|
|
|
5692
5708
|
let result;
|
|
5693
5709
|
if (kind === "function") {
|
|
5694
5710
|
try {
|
|
5695
|
-
const
|
|
5711
|
+
const output4 = await functionTools.get(toolCall.name)(
|
|
5696
5712
|
mergedInput
|
|
5697
5713
|
);
|
|
5698
5714
|
result = {
|
|
5699
|
-
output:
|
|
5715
|
+
output: output4 ?? null,
|
|
5700
5716
|
billingCost: 0,
|
|
5701
5717
|
isError: false
|
|
5702
5718
|
};
|
|
@@ -5717,29 +5733,40 @@ ${structuredOutputExample}
|
|
|
5717
5733
|
} else {
|
|
5718
5734
|
result = await deps.executeStepTool(toolCall.name, mergedInput);
|
|
5719
5735
|
}
|
|
5736
|
+
const { output: output3, truncated } = truncateToolOutput(
|
|
5737
|
+
result.output,
|
|
5738
|
+
maxToolOutputChars
|
|
5739
|
+
);
|
|
5720
5740
|
toolCallLog.push({
|
|
5721
5741
|
name: toolCall.name,
|
|
5722
5742
|
success: !result.isError,
|
|
5723
|
-
durationMs: Date.now() - startTime
|
|
5743
|
+
durationMs: Date.now() - startTime,
|
|
5744
|
+
truncated
|
|
5724
5745
|
});
|
|
5725
|
-
return { toolCall, ...result };
|
|
5746
|
+
return { toolCall, ...result, output: output3, truncated };
|
|
5726
5747
|
})
|
|
5727
5748
|
);
|
|
5728
|
-
for (const {
|
|
5749
|
+
for (const {
|
|
5750
|
+
toolCall,
|
|
5751
|
+
output: output3,
|
|
5752
|
+
truncated,
|
|
5753
|
+
billingCost,
|
|
5754
|
+
isError
|
|
5755
|
+
} of results) {
|
|
5729
5756
|
if (billingCost) {
|
|
5730
5757
|
totalUsage.totalBillingCost += billingCost;
|
|
5731
5758
|
}
|
|
5732
|
-
const truncated = truncateToolOutput(output3);
|
|
5733
5759
|
messages.push({
|
|
5734
5760
|
role: "user",
|
|
5735
|
-
content: JSON.stringify(
|
|
5761
|
+
content: JSON.stringify(output3),
|
|
5736
5762
|
toolCallId: toolCall.id,
|
|
5737
5763
|
...isError && { isToolError: true }
|
|
5738
5764
|
});
|
|
5739
5765
|
onEvent?.({
|
|
5740
5766
|
type: "tool_call_result",
|
|
5741
5767
|
id: toolCall.id,
|
|
5742
|
-
output:
|
|
5768
|
+
output: output3,
|
|
5769
|
+
...truncated && { truncated: true }
|
|
5743
5770
|
});
|
|
5744
5771
|
}
|
|
5745
5772
|
if (isDevMode()) {
|
|
@@ -5759,11 +5786,15 @@ ${structuredOutputExample}
|
|
|
5759
5786
|
}
|
|
5760
5787
|
if (parseOk) {
|
|
5761
5788
|
if (!outputSchema) {
|
|
5762
|
-
return finish(
|
|
5789
|
+
return finish(
|
|
5790
|
+
buildResult(output2, turn.text, true, loopCount, turn.stopReason)
|
|
5791
|
+
);
|
|
5763
5792
|
}
|
|
5764
5793
|
const errors = validateAgainstSchema(output2, outputSchema);
|
|
5765
5794
|
if (errors.length === 0) {
|
|
5766
|
-
return finish(
|
|
5795
|
+
return finish(
|
|
5796
|
+
buildResult(output2, turn.text, true, loopCount, turn.stopReason)
|
|
5797
|
+
);
|
|
5767
5798
|
}
|
|
5768
5799
|
if (loopCount < maxTurns && schemaRepairCount < MAX_SCHEMA_REPAIR_ATTEMPTS) {
|
|
5769
5800
|
schemaRepairCount++;
|
|
@@ -5788,13 +5819,16 @@ ${formatValidationErrors(errors)}`
|
|
|
5788
5819
|
{ path: "$", message: "output was not valid JSON" }
|
|
5789
5820
|
]);
|
|
5790
5821
|
}
|
|
5791
|
-
return finish(
|
|
5822
|
+
return finish(
|
|
5823
|
+
buildResult(turn.text, turn.text, false, loopCount, turn.stopReason)
|
|
5824
|
+
);
|
|
5792
5825
|
}
|
|
5793
5826
|
messages.push({
|
|
5794
5827
|
role: "user",
|
|
5795
5828
|
content: "You have reached the maximum number of turns. Please provide your final output now as JSON."
|
|
5796
5829
|
});
|
|
5797
5830
|
let finalText = "";
|
|
5831
|
+
let finalStopReason = null;
|
|
5798
5832
|
try {
|
|
5799
5833
|
const turn = await runTurnWithRetry(httpConfig, {
|
|
5800
5834
|
model: options.model,
|
|
@@ -5805,6 +5839,7 @@ ${formatValidationErrors(errors)}`
|
|
|
5805
5839
|
});
|
|
5806
5840
|
accumulate(turn);
|
|
5807
5841
|
finalText = turn.text;
|
|
5842
|
+
finalStopReason = turn.stopReason;
|
|
5808
5843
|
} catch (err) {
|
|
5809
5844
|
if (err instanceof TurnError && err.phase === "model") {
|
|
5810
5845
|
if (isDevMode()) {
|
|
@@ -5834,7 +5869,14 @@ ${formatValidationErrors(errors)}`
|
|
|
5834
5869
|
}
|
|
5835
5870
|
}
|
|
5836
5871
|
return finish(
|
|
5837
|
-
buildResult(
|
|
5872
|
+
buildResult(
|
|
5873
|
+
output,
|
|
5874
|
+
finalText,
|
|
5875
|
+
parsedSuccessfully,
|
|
5876
|
+
loopCount + 1,
|
|
5877
|
+
finalStopReason,
|
|
5878
|
+
true
|
|
5879
|
+
)
|
|
5838
5880
|
);
|
|
5839
5881
|
}
|
|
5840
5882
|
var DEFAULT_MAX_TURNS, MAX_TURNS_LIMIT, MAX_SCHEMA_REPAIR_ATTEMPTS, MAX_TOOL_OUTPUT_CHARS, MAX_TURN_ATTEMPTS, INITIAL_BACKOFF_MS, STALL_TIMEOUT_MS, UNSAFE_KEYS, TurnError;
|
|
@@ -9156,7 +9198,7 @@ async function startMcpServer(options) {
|
|
|
9156
9198
|
capabilities: { tools: {} },
|
|
9157
9199
|
serverInfo: {
|
|
9158
9200
|
name: "mindstudio-agent",
|
|
9159
|
-
version: "0.1.
|
|
9201
|
+
version: "0.1.142"
|
|
9160
9202
|
},
|
|
9161
9203
|
instructions: 'Welcome to MindStudio \u2014 a platform with 200+ AI models, 850+ third-party integrations, and pre-built agents.\n\nGetting started:\n1. Call `ask` with any question about the SDK \u2014 it knows every action, model, and connector and returns working code with real model IDs and config options. Examples: ask("generate an image with FLUX"), ask("what models support vision?"), ask("how do I send a Slack message?").\n2. Call `changeName` to set your display name \u2014 use your name or whatever your user calls you. This is how you\'ll appear in MindStudio request logs.\n3. If you have a profile picture, pass its public image URL to `changeProfilePicture`.\n4. For manual browsing, call `listActions` to discover all available actions.\n\nThen use the tools to generate text, images, video, audio, search the web, work with data sources, run agents, and more.\n\nImportant:\n- AI-powered actions (text generation, image generation, video, audio, etc.) cost money. Before running these, call `estimateActionCost` and confirm with the user before proceeding \u2014 unless they\'ve explicitly told you to go ahead.\n- Not all agents from `listAgents` are configured for API use. Do not try to run an agent just because it appears in the list \u2014 it will likely fail. Only run agents the user specifically asks you to run.'
|
|
9162
9204
|
});
|
|
@@ -10168,7 +10210,7 @@ function isNewerVersion(current, latest) {
|
|
|
10168
10210
|
return false;
|
|
10169
10211
|
}
|
|
10170
10212
|
async function checkForUpdate() {
|
|
10171
|
-
const currentVersion = "0.1.
|
|
10213
|
+
const currentVersion = "0.1.142";
|
|
10172
10214
|
if (!currentVersion || process.env.MINDSTUDIO_NO_UPDATE_CHECK) {
|
|
10173
10215
|
return null;
|
|
10174
10216
|
}
|
|
@@ -10203,7 +10245,7 @@ async function checkForUpdate() {
|
|
|
10203
10245
|
}
|
|
10204
10246
|
}
|
|
10205
10247
|
function printUpdateNotice(latestVersion) {
|
|
10206
|
-
const currentVersion = "0.1.
|
|
10248
|
+
const currentVersion = "0.1.142";
|
|
10207
10249
|
process.stderr.write(
|
|
10208
10250
|
`
|
|
10209
10251
|
${ansi2.cyanBright("Update available")} ${ansi2.gray(currentVersion + " \u2192")} ${ansi2.cyanBold(latestVersion)}
|
|
@@ -10216,7 +10258,7 @@ function isStandaloneBinary() {
|
|
|
10216
10258
|
return !argv1.includes("node_modules");
|
|
10217
10259
|
}
|
|
10218
10260
|
async function cmdUpdate() {
|
|
10219
|
-
const currentVersion = "0.1.
|
|
10261
|
+
const currentVersion = "0.1.142";
|
|
10220
10262
|
process.stderr.write(
|
|
10221
10263
|
` ${ansi2.gray("Current version:")} ${currentVersion}
|
|
10222
10264
|
`
|
|
@@ -10357,7 +10399,7 @@ async function cmdLogin(options) {
|
|
|
10357
10399
|
process.stderr.write("\n");
|
|
10358
10400
|
printLogo();
|
|
10359
10401
|
process.stderr.write("\n");
|
|
10360
|
-
const ver = "0.1.
|
|
10402
|
+
const ver = "0.1.142";
|
|
10361
10403
|
process.stderr.write(
|
|
10362
10404
|
` ${ansi2.bold("MindStudio Agent")} ${ver ? " " + ansi2.gray("v" + ver) : ""}
|
|
10363
10405
|
`
|
|
@@ -10685,7 +10727,7 @@ async function main() {
|
|
|
10685
10727
|
const updatePromise = command !== "mcp" && command !== "login" && command !== "update" ? checkForUpdate() : Promise.resolve(null);
|
|
10686
10728
|
try {
|
|
10687
10729
|
if (command === "version" || command === "-v") {
|
|
10688
|
-
process.stdout.write("0.1.
|
|
10730
|
+
process.stdout.write("0.1.142\n");
|
|
10689
10731
|
return;
|
|
10690
10732
|
}
|
|
10691
10733
|
if (command === "login") {
|
package/dist/index.d.ts
CHANGED
|
@@ -4169,6 +4169,17 @@ interface RunTaskOptionsBase {
|
|
|
4169
4169
|
model: string;
|
|
4170
4170
|
/** Max loop iterations before forcing final output. Default 20, max 100. */
|
|
4171
4171
|
maxTurns?: number;
|
|
4172
|
+
/**
|
|
4173
|
+
* How much of each tool result reaches the model, in characters of its
|
|
4174
|
+
* JSON. Default 50,000. A larger result is cut to this, and the model gets
|
|
4175
|
+
* a record that says so instead: `{ truncated: true, totalChars, shownChars,
|
|
4176
|
+
* content }`, `content` being the beginning of the result's JSON. The call's
|
|
4177
|
+
* entry in `toolCalls` is marked `truncated` too. Every result stays in the
|
|
4178
|
+
* transcript, which is resent on every later turn, so raising this costs
|
|
4179
|
+
* tokens on every turn after a large result, and the whole transcript has to
|
|
4180
|
+
* fit the model's context window.
|
|
4181
|
+
*/
|
|
4182
|
+
maxToolOutputChars?: number;
|
|
4172
4183
|
/** App ID to execute within. */
|
|
4173
4184
|
appId?: string;
|
|
4174
4185
|
/** Thread ID for state persistence. */
|
|
@@ -4217,6 +4228,8 @@ interface TaskToolCall {
|
|
|
4217
4228
|
name: string;
|
|
4218
4229
|
success: boolean;
|
|
4219
4230
|
durationMs: number;
|
|
4231
|
+
/** The result was over `maxToolOutputChars`, so the model got only its beginning. */
|
|
4232
|
+
truncated?: boolean;
|
|
4220
4233
|
}
|
|
4221
4234
|
/** Usage stats from a task agent execution. */
|
|
4222
4235
|
interface TaskUsage {
|
|
@@ -4238,6 +4251,19 @@ interface RunTaskResult<T = unknown> {
|
|
|
4238
4251
|
parsedSuccessfully: boolean;
|
|
4239
4252
|
/** Number of loop iterations used. */
|
|
4240
4253
|
turns: number;
|
|
4254
|
+
/**
|
|
4255
|
+
* The task used every turn in `maxTurns` and was then asked, with its
|
|
4256
|
+
* tools taken away, for its final output: `output` is whatever it could
|
|
4257
|
+
* say from what it had gathered by then.
|
|
4258
|
+
*/
|
|
4259
|
+
hitMaxTurns: boolean;
|
|
4260
|
+
/**
|
|
4261
|
+
* Why the model stopped on the turn that produced `output`: `end_turn`, or
|
|
4262
|
+
* `max_tokens` when the answer was cut at the output limit (`repetition`
|
|
4263
|
+
* when the platform cut an answer that had begun repeating itself). Null
|
|
4264
|
+
* when that model call failed, and `output` is empty.
|
|
4265
|
+
*/
|
|
4266
|
+
stopReason: string | null;
|
|
4241
4267
|
/** Token and cost usage. */
|
|
4242
4268
|
usage: TaskUsage;
|
|
4243
4269
|
/** Summary of every tool call made during execution. */
|
package/dist/index.js
CHANGED
|
@@ -4975,9 +4975,11 @@ function logTaskResult(result) {
|
|
|
4975
4975
|
if (!isDevMode()) {
|
|
4976
4976
|
return;
|
|
4977
4977
|
}
|
|
4978
|
-
const toolSummary = result.toolCalls.map(
|
|
4978
|
+
const toolSummary = result.toolCalls.map(
|
|
4979
|
+
(tc) => `${tc.name} (${tc.durationMs}ms) ${tc.success ? "\u2713" : "\u2717"}` + (tc.truncated ? " \u26A0 result cut" : "")
|
|
4980
|
+
).join(", ");
|
|
4979
4981
|
console.log(
|
|
4980
|
-
`[task] ${result.turns} turn${result.turns === 1 ? "" : "s"}` + (toolSummary ? `: ${toolSummary}` : "") + ` | ${result.parsedSuccessfully ? "output OK" : "\u26A0 output not valid JSON"} | cost: ${result.usage.totalBillingCost} | trace: ${result.traceId}`
|
|
4982
|
+
`[task] ${result.turns} turn${result.turns === 1 ? "" : "s"}` + (toolSummary ? `: ${toolSummary}` : "") + (result.hitMaxTurns ? " | \u26A0 ran out of turns" : "") + (result.stopReason === "max_tokens" ? " | \u26A0 answer cut at the output limit" : "") + ` | ${result.parsedSuccessfully ? "output OK" : "\u26A0 output not valid JSON"} | cost: ${result.usage.totalBillingCost} | trace: ${result.traceId}`
|
|
4981
4983
|
);
|
|
4982
4984
|
}
|
|
4983
4985
|
|
|
@@ -5155,9 +5157,20 @@ function mergeToolInput(modelInput, defaults) {
|
|
|
5155
5157
|
}
|
|
5156
5158
|
return merged;
|
|
5157
5159
|
}
|
|
5158
|
-
function truncateToolOutput(output) {
|
|
5160
|
+
function truncateToolOutput(output, maxChars) {
|
|
5159
5161
|
const serialized = JSON.stringify(output);
|
|
5160
|
-
|
|
5162
|
+
if (!serialized || serialized.length <= maxChars) {
|
|
5163
|
+
return { output, truncated: false };
|
|
5164
|
+
}
|
|
5165
|
+
return {
|
|
5166
|
+
output: {
|
|
5167
|
+
truncated: true,
|
|
5168
|
+
totalChars: serialized.length,
|
|
5169
|
+
shownChars: maxChars,
|
|
5170
|
+
content: serialized.slice(0, maxChars)
|
|
5171
|
+
},
|
|
5172
|
+
truncated: true
|
|
5173
|
+
};
|
|
5161
5174
|
}
|
|
5162
5175
|
var TurnError = class extends Error {
|
|
5163
5176
|
constructor(message, retryable, phase, status, errorCode) {
|
|
@@ -5381,6 +5394,7 @@ ${structuredOutputExample}
|
|
|
5381
5394
|
Math.max(options.maxTurns || DEFAULT_MAX_TURNS, 1),
|
|
5382
5395
|
MAX_TURNS_LIMIT
|
|
5383
5396
|
);
|
|
5397
|
+
const maxToolOutputChars = options.maxToolOutputChars ?? MAX_TOOL_OUTPUT_CHARS;
|
|
5384
5398
|
const traceId = randomUUID2();
|
|
5385
5399
|
const messages = [
|
|
5386
5400
|
{ role: "user", content: JSON.stringify(options.input) }
|
|
@@ -5395,11 +5409,13 @@ ${structuredOutputExample}
|
|
|
5395
5409
|
cacheReadTokens: 0,
|
|
5396
5410
|
totalBillingCost: 0
|
|
5397
5411
|
};
|
|
5398
|
-
const buildResult = (output2, outputRaw, parsedSuccessfully2, turns) => ({
|
|
5412
|
+
const buildResult = (output2, outputRaw, parsedSuccessfully2, turns, stopReason, hitMaxTurns = false) => ({
|
|
5399
5413
|
output: output2,
|
|
5400
5414
|
outputRaw,
|
|
5401
5415
|
parsedSuccessfully: parsedSuccessfully2,
|
|
5402
5416
|
turns,
|
|
5417
|
+
hitMaxTurns,
|
|
5418
|
+
stopReason,
|
|
5403
5419
|
usage: totalUsage,
|
|
5404
5420
|
toolCalls: toolCallLog,
|
|
5405
5421
|
traceId
|
|
@@ -5457,7 +5473,7 @@ ${structuredOutputExample}
|
|
|
5457
5473
|
}
|
|
5458
5474
|
);
|
|
5459
5475
|
}
|
|
5460
|
-
return finish(buildResult(null, "", false, loopCount));
|
|
5476
|
+
return finish(buildResult(null, "", false, loopCount, null));
|
|
5461
5477
|
}
|
|
5462
5478
|
if (err instanceof TurnError) {
|
|
5463
5479
|
throw new MindStudioError(
|
|
@@ -5504,11 +5520,11 @@ ${structuredOutputExample}
|
|
|
5504
5520
|
let result;
|
|
5505
5521
|
if (kind === "function") {
|
|
5506
5522
|
try {
|
|
5507
|
-
const
|
|
5523
|
+
const output4 = await functionTools.get(toolCall.name)(
|
|
5508
5524
|
mergedInput
|
|
5509
5525
|
);
|
|
5510
5526
|
result = {
|
|
5511
|
-
output:
|
|
5527
|
+
output: output4 ?? null,
|
|
5512
5528
|
billingCost: 0,
|
|
5513
5529
|
isError: false
|
|
5514
5530
|
};
|
|
@@ -5529,29 +5545,40 @@ ${structuredOutputExample}
|
|
|
5529
5545
|
} else {
|
|
5530
5546
|
result = await deps.executeStepTool(toolCall.name, mergedInput);
|
|
5531
5547
|
}
|
|
5548
|
+
const { output: output3, truncated } = truncateToolOutput(
|
|
5549
|
+
result.output,
|
|
5550
|
+
maxToolOutputChars
|
|
5551
|
+
);
|
|
5532
5552
|
toolCallLog.push({
|
|
5533
5553
|
name: toolCall.name,
|
|
5534
5554
|
success: !result.isError,
|
|
5535
|
-
durationMs: Date.now() - startTime
|
|
5555
|
+
durationMs: Date.now() - startTime,
|
|
5556
|
+
truncated
|
|
5536
5557
|
});
|
|
5537
|
-
return { toolCall, ...result };
|
|
5558
|
+
return { toolCall, ...result, output: output3, truncated };
|
|
5538
5559
|
})
|
|
5539
5560
|
);
|
|
5540
|
-
for (const {
|
|
5561
|
+
for (const {
|
|
5562
|
+
toolCall,
|
|
5563
|
+
output: output3,
|
|
5564
|
+
truncated,
|
|
5565
|
+
billingCost,
|
|
5566
|
+
isError
|
|
5567
|
+
} of results) {
|
|
5541
5568
|
if (billingCost) {
|
|
5542
5569
|
totalUsage.totalBillingCost += billingCost;
|
|
5543
5570
|
}
|
|
5544
|
-
const truncated = truncateToolOutput(output3);
|
|
5545
5571
|
messages.push({
|
|
5546
5572
|
role: "user",
|
|
5547
|
-
content: JSON.stringify(
|
|
5573
|
+
content: JSON.stringify(output3),
|
|
5548
5574
|
toolCallId: toolCall.id,
|
|
5549
5575
|
...isError && { isToolError: true }
|
|
5550
5576
|
});
|
|
5551
5577
|
onEvent?.({
|
|
5552
5578
|
type: "tool_call_result",
|
|
5553
5579
|
id: toolCall.id,
|
|
5554
|
-
output:
|
|
5580
|
+
output: output3,
|
|
5581
|
+
...truncated && { truncated: true }
|
|
5555
5582
|
});
|
|
5556
5583
|
}
|
|
5557
5584
|
if (isDevMode()) {
|
|
@@ -5571,11 +5598,15 @@ ${structuredOutputExample}
|
|
|
5571
5598
|
}
|
|
5572
5599
|
if (parseOk) {
|
|
5573
5600
|
if (!outputSchema) {
|
|
5574
|
-
return finish(
|
|
5601
|
+
return finish(
|
|
5602
|
+
buildResult(output2, turn.text, true, loopCount, turn.stopReason)
|
|
5603
|
+
);
|
|
5575
5604
|
}
|
|
5576
5605
|
const errors = validateAgainstSchema(output2, outputSchema);
|
|
5577
5606
|
if (errors.length === 0) {
|
|
5578
|
-
return finish(
|
|
5607
|
+
return finish(
|
|
5608
|
+
buildResult(output2, turn.text, true, loopCount, turn.stopReason)
|
|
5609
|
+
);
|
|
5579
5610
|
}
|
|
5580
5611
|
if (loopCount < maxTurns && schemaRepairCount < MAX_SCHEMA_REPAIR_ATTEMPTS) {
|
|
5581
5612
|
schemaRepairCount++;
|
|
@@ -5600,13 +5631,16 @@ ${formatValidationErrors(errors)}`
|
|
|
5600
5631
|
{ path: "$", message: "output was not valid JSON" }
|
|
5601
5632
|
]);
|
|
5602
5633
|
}
|
|
5603
|
-
return finish(
|
|
5634
|
+
return finish(
|
|
5635
|
+
buildResult(turn.text, turn.text, false, loopCount, turn.stopReason)
|
|
5636
|
+
);
|
|
5604
5637
|
}
|
|
5605
5638
|
messages.push({
|
|
5606
5639
|
role: "user",
|
|
5607
5640
|
content: "You have reached the maximum number of turns. Please provide your final output now as JSON."
|
|
5608
5641
|
});
|
|
5609
5642
|
let finalText = "";
|
|
5643
|
+
let finalStopReason = null;
|
|
5610
5644
|
try {
|
|
5611
5645
|
const turn = await runTurnWithRetry(httpConfig, {
|
|
5612
5646
|
model: options.model,
|
|
@@ -5617,6 +5651,7 @@ ${formatValidationErrors(errors)}`
|
|
|
5617
5651
|
});
|
|
5618
5652
|
accumulate(turn);
|
|
5619
5653
|
finalText = turn.text;
|
|
5654
|
+
finalStopReason = turn.stopReason;
|
|
5620
5655
|
} catch (err) {
|
|
5621
5656
|
if (err instanceof TurnError && err.phase === "model") {
|
|
5622
5657
|
if (isDevMode()) {
|
|
@@ -5646,7 +5681,14 @@ ${formatValidationErrors(errors)}`
|
|
|
5646
5681
|
}
|
|
5647
5682
|
}
|
|
5648
5683
|
return finish(
|
|
5649
|
-
buildResult(
|
|
5684
|
+
buildResult(
|
|
5685
|
+
output,
|
|
5686
|
+
finalText,
|
|
5687
|
+
parsedSuccessfully,
|
|
5688
|
+
loopCount + 1,
|
|
5689
|
+
finalStopReason,
|
|
5690
|
+
true
|
|
5691
|
+
)
|
|
5650
5692
|
);
|
|
5651
5693
|
}
|
|
5652
5694
|
|