@tanstack/ai 0.61.0 → 0.63.0
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/README.md +1 -0
- package/dist/esm/activities/chat/agents/define-agent.d.ts +17 -5
- package/dist/esm/activities/chat/agents/define-agent.js.map +1 -1
- package/dist/esm/activities/chat/agents/spawn.d.ts +2 -0
- package/dist/esm/activities/chat/agents/spawn.js +8 -5
- package/dist/esm/activities/chat/agents/spawn.js.map +1 -1
- package/dist/esm/activities/chat/index.js +156 -57
- package/dist/esm/activities/chat/index.js.map +1 -1
- package/dist/esm/activities/chat/messages.js +30 -18
- package/dist/esm/activities/chat/messages.js.map +1 -1
- package/dist/esm/activities/chat/middleware/types.d.ts +1 -0
- package/dist/esm/activities/chat/middleware/types.js.map +1 -1
- package/dist/esm/activities/chat/stream/message-updaters.d.ts +2 -2
- package/dist/esm/activities/chat/stream/message-updaters.js +2 -1
- package/dist/esm/activities/chat/stream/message-updaters.js.map +1 -1
- package/dist/esm/activities/chat/stream/processor.d.ts +11 -9
- package/dist/esm/activities/chat/stream/processor.js +38 -18
- package/dist/esm/activities/chat/stream/processor.js.map +1 -1
- package/dist/esm/activities/chat/tools/tool-calls.d.ts +16 -2
- package/dist/esm/activities/chat/tools/tool-calls.js +55 -16
- package/dist/esm/activities/chat/tools/tool-calls.js.map +1 -1
- package/dist/esm/activities/chat/tools/tool-definition.d.ts +4 -0
- package/dist/esm/activities/chat/tools/tool-definition.js +4 -0
- package/dist/esm/activities/chat/tools/tool-definition.js.map +1 -1
- package/dist/esm/activities/evaluate/adapter.d.ts +4 -0
- package/dist/esm/activities/evaluate/adapter.js.map +1 -1
- package/dist/esm/activities/evaluate/index.d.ts +4 -0
- package/dist/esm/activities/evaluate/index.js +3 -1
- package/dist/esm/activities/evaluate/index.js.map +1 -1
- package/dist/esm/client.d.ts +1 -1
- package/dist/esm/client.js.map +1 -1
- package/dist/esm/index.d.ts +1 -1
- package/dist/esm/index.js +2 -2
- package/dist/esm/interrupt-resume.js +29 -4
- package/dist/esm/interrupt-resume.js.map +1 -1
- package/dist/esm/middlewares/otel.d.ts +5 -2
- package/dist/esm/middlewares/otel.js +114 -0
- package/dist/esm/middlewares/otel.js.map +1 -1
- package/dist/esm/types.d.ts +42 -1
- package/dist/esm/utilities/ag-ui-wire.js +5 -3
- package/dist/esm/utilities/ag-ui-wire.js.map +1 -1
- package/dist/esm/utilities/tool-result.d.ts +2 -1
- package/dist/esm/utilities/tool-result.js +4 -1
- package/dist/esm/utilities/tool-result.js.map +1 -1
- package/package.json +3 -3
- package/skills/ai-core/chat-experience/SKILL.md +120 -0
- package/skills/ai-core/tool-calling/SKILL.md +103 -0
- package/src/activities/chat/agents/define-agent.ts +20 -3
- package/src/activities/chat/agents/spawn.ts +20 -12
- package/src/activities/chat/index.ts +235 -62
- package/src/activities/chat/messages.ts +40 -5
- package/src/activities/chat/middleware/types.ts +1 -0
- package/src/activities/chat/stream/message-updaters.ts +3 -0
- package/src/activities/chat/stream/processor.ts +57 -27
- package/src/activities/chat/tools/tool-calls.ts +98 -9
- package/src/activities/chat/tools/tool-definition.ts +8 -0
- package/src/activities/evaluate/adapter.ts +4 -0
- package/src/activities/evaluate/index.ts +6 -0
- package/src/client.ts +1 -0
- package/src/index.ts +1 -0
- package/src/interrupt-resume.ts +55 -4
- package/src/middlewares/otel.ts +161 -3
- package/src/types.ts +38 -1
- package/src/utilities/ag-ui-wire.ts +12 -1
- package/src/utilities/tool-result.ts +7 -1
|
@@ -163,8 +163,10 @@ var TextEngine = class {
|
|
|
163
163
|
initialClientToolResults;
|
|
164
164
|
resumeApprovals = /* @__PURE__ */ new Map();
|
|
165
165
|
resumeClientToolResults = /* @__PURE__ */ new Map();
|
|
166
|
+
resumeClientToolErrors = /* @__PURE__ */ new Map();
|
|
166
167
|
resumeDeniedToolResults = /* @__PURE__ */ new Map();
|
|
167
168
|
resumeCancelledToolCallIds = /* @__PURE__ */ new Set();
|
|
169
|
+
resumeInputResponses = /* @__PURE__ */ new Map();
|
|
168
170
|
resumeGenericInterrupts = /* @__PURE__ */ new Map();
|
|
169
171
|
resumeGenericInterruptRequests = /* @__PURE__ */ new Map();
|
|
170
172
|
threadId;
|
|
@@ -330,6 +332,33 @@ var TextEngine = class {
|
|
|
330
332
|
getFinalizationError() {
|
|
331
333
|
return this.finalizationError;
|
|
332
334
|
}
|
|
335
|
+
async runTerminalHook() {
|
|
336
|
+
if (this.terminalHookCalled || this.isCancelled()) return;
|
|
337
|
+
this.terminalHookCalled = true;
|
|
338
|
+
if (this.finalizationError) {
|
|
339
|
+
const errForHook = new Error(this.finalizationError.message, this.finalizationError.cause !== void 0 ? { cause: this.finalizationError.cause } : void 0);
|
|
340
|
+
if (this.finalizationError.code !== void 0) Object.defineProperty(errForHook, "code", {
|
|
341
|
+
value: this.finalizationError.code,
|
|
342
|
+
enumerable: true
|
|
343
|
+
});
|
|
344
|
+
if (this.finalizationError.rawText !== void 0) Object.defineProperty(errForHook, "rawText", {
|
|
345
|
+
value: this.finalizationError.rawText,
|
|
346
|
+
enumerable: true
|
|
347
|
+
});
|
|
348
|
+
await this.middlewareRunner.runOnError(this.middlewareCtx, {
|
|
349
|
+
error: errForHook,
|
|
350
|
+
duration: Date.now() - this.streamStartTime
|
|
351
|
+
});
|
|
352
|
+
return;
|
|
353
|
+
}
|
|
354
|
+
this.addTerminalAssistantMessages();
|
|
355
|
+
await this.middlewareRunner.runOnFinish(this.middlewareCtx, {
|
|
356
|
+
finishReason: this.lastFinishReason,
|
|
357
|
+
duration: Date.now() - this.streamStartTime,
|
|
358
|
+
content: this.accumulatedContent,
|
|
359
|
+
usage: rebuildTokenUsage(this.finishedEvent?.usage, tanstackMetadata(this.finishedEvent ?? void 0)?.usage)
|
|
360
|
+
});
|
|
361
|
+
}
|
|
333
362
|
async *run() {
|
|
334
363
|
this.beforeRun();
|
|
335
364
|
this.logger.agentLoop("run started", { threadId: this.middlewareCtx.threadId });
|
|
@@ -355,7 +384,11 @@ var TextEngine = class {
|
|
|
355
384
|
}
|
|
356
385
|
return;
|
|
357
386
|
}
|
|
358
|
-
|
|
387
|
+
const pendingPhase = yield* this.checkForPendingToolCalls();
|
|
388
|
+
if (pendingPhase === "stop" || pendingPhase === "wait") {
|
|
389
|
+
await this.runTerminalHook();
|
|
390
|
+
return;
|
|
391
|
+
}
|
|
359
392
|
if (!(!!this.finalStructuredOutput && this.tools.length === 0 && this.finalStructuredOutput.nativeCombined !== true)) do {
|
|
360
393
|
if (this.earlyTermination) break;
|
|
361
394
|
if (this.isCancelled()) return;
|
|
@@ -391,29 +424,7 @@ var TextEngine = class {
|
|
|
391
424
|
if (!this.finalizationError && !this.isCancelled()) yield* this.flushDeferredModelRunFinishedChunks();
|
|
392
425
|
} else yield* this.runStructuredFinalization();
|
|
393
426
|
}
|
|
394
|
-
|
|
395
|
-
if (this.finalizationError) {
|
|
396
|
-
this.terminalHookCalled = true;
|
|
397
|
-
const errForHook = new Error(this.finalizationError.message, this.finalizationError.cause !== void 0 ? { cause: this.finalizationError.cause } : void 0);
|
|
398
|
-
if (this.finalizationError.code !== void 0) Object.defineProperty(errForHook, "code", {
|
|
399
|
-
value: this.finalizationError.code,
|
|
400
|
-
enumerable: true
|
|
401
|
-
});
|
|
402
|
-
await this.middlewareRunner.runOnError(this.middlewareCtx, {
|
|
403
|
-
error: errForHook,
|
|
404
|
-
duration: Date.now() - this.streamStartTime
|
|
405
|
-
});
|
|
406
|
-
} else {
|
|
407
|
-
this.addTerminalAssistantMessages();
|
|
408
|
-
this.terminalHookCalled = true;
|
|
409
|
-
await this.middlewareRunner.runOnFinish(this.middlewareCtx, {
|
|
410
|
-
finishReason: this.lastFinishReason,
|
|
411
|
-
duration: Date.now() - this.streamStartTime,
|
|
412
|
-
content: this.accumulatedContent,
|
|
413
|
-
usage: rebuildTokenUsage(this.finishedEvent?.usage, tanstackMetadata(this.finishedEvent ?? void 0)?.usage)
|
|
414
|
-
});
|
|
415
|
-
}
|
|
416
|
-
}
|
|
427
|
+
await this.runTerminalHook();
|
|
417
428
|
} catch (error) {
|
|
418
429
|
if (error instanceof Error && error.name === "InterruptReplaySignal" && "continuationRunId" in error && typeof error.continuationRunId === "string") {
|
|
419
430
|
this.terminalHookCalled = true;
|
|
@@ -885,8 +896,10 @@ var TextEngine = class {
|
|
|
885
896
|
await this.middlewareRunner.runOnAfterToolCall(this.middlewareCtx, info);
|
|
886
897
|
}
|
|
887
898
|
}, this.middlewareCtx.context, this.toolAbortSignal, {
|
|
899
|
+
clientToolErrors: this.resumeClientToolErrors,
|
|
888
900
|
deniedToolResults: this.resumeDeniedToolResults,
|
|
889
|
-
cancelledToolCallIds: this.resumeCancelledToolCallIds
|
|
901
|
+
cancelledToolCallIds: this.resumeCancelledToolCallIds,
|
|
902
|
+
inputResponses: this.resumeInputResponses
|
|
890
903
|
});
|
|
891
904
|
const executionResult = yield* this.drainToolCallGenerator(generator);
|
|
892
905
|
if (this.isMiddlewareAborted()) {
|
|
@@ -900,10 +913,10 @@ var TextEngine = class {
|
|
|
900
913
|
needsApproval: executionResult.needsApproval,
|
|
901
914
|
needsClientExecution: executionResult.needsClientExecution
|
|
902
915
|
}));
|
|
903
|
-
if (executionResult.needsApproval.length > 0 || executionResult.needsClientExecution.length > 0 || executionResult.subagentInterrupts.length > 0) {
|
|
916
|
+
if (executionResult.needsApproval.length > 0 || executionResult.needsClientExecution.length > 0 || executionResult.inputRequired.length > 0 || executionResult.subagentInterrupts.length > 0) {
|
|
904
917
|
this.discardDeferredToolCallRunFinishedChunks();
|
|
905
918
|
if (allResults.length > 0) for (const chunk of this.buildToolResultChunks(allResults, finishEvent)) yield* this.pipeThroughMiddleware(chunk);
|
|
906
|
-
const emitted = yield* this.emitActionableInterruptBoundary(finishEvent, executionResult.needsApproval, executionResult.needsClientExecution, [], executionResult.subagentInterrupts);
|
|
919
|
+
const emitted = yield* this.emitActionableInterruptBoundary(finishEvent, executionResult.needsApproval, executionResult.needsClientExecution, [], executionResult.inputRequired, executionResult.subagentInterrupts);
|
|
907
920
|
this.setToolPhase(emitted ? "wait" : "stop");
|
|
908
921
|
return emitted ? "wait" : "stop";
|
|
909
922
|
}
|
|
@@ -977,8 +990,10 @@ var TextEngine = class {
|
|
|
977
990
|
await this.middlewareRunner.runOnAfterToolCall(this.middlewareCtx, info);
|
|
978
991
|
}
|
|
979
992
|
}, this.middlewareCtx.context, this.toolAbortSignal, {
|
|
993
|
+
clientToolErrors: this.resumeClientToolErrors,
|
|
980
994
|
deniedToolResults: this.resumeDeniedToolResults,
|
|
981
|
-
cancelledToolCallIds: this.resumeCancelledToolCallIds
|
|
995
|
+
cancelledToolCallIds: this.resumeCancelledToolCallIds,
|
|
996
|
+
inputResponses: this.resumeInputResponses
|
|
982
997
|
});
|
|
983
998
|
const executionResult = yield* this.drainToolCallGenerator(generator);
|
|
984
999
|
this.middlewareCtx.phase = "afterTools";
|
|
@@ -997,13 +1012,13 @@ var TextEngine = class {
|
|
|
997
1012
|
const afterToolRequests = yield* this.runWhileYielding(this.middlewareRunner.runOnInterruptBoundary(this.middlewareCtx));
|
|
998
1013
|
if (afterToolRequests.length > 0) {
|
|
999
1014
|
for (const chunk of afterToolBoundaryChunks) yield* this.pipeThroughMiddleware(chunk);
|
|
1000
|
-
yield* this.emitBoundaryInterrupts("afterTools", finishEvent, toolCalls, afterToolRequests);
|
|
1015
|
+
yield* this.emitBoundaryInterrupts("afterTools", finishEvent, toolCalls, afterToolRequests, executionResult.inputRequired);
|
|
1001
1016
|
this.setToolPhase("wait");
|
|
1002
1017
|
return;
|
|
1003
1018
|
}
|
|
1004
|
-
if (executionResult.needsApproval.length > 0 || executionResult.needsClientExecution.length > 0 || executionResult.subagentInterrupts.length > 0) {
|
|
1019
|
+
if (executionResult.needsApproval.length > 0 || executionResult.needsClientExecution.length > 0 || executionResult.inputRequired.length > 0 || executionResult.subagentInterrupts.length > 0) {
|
|
1005
1020
|
if (allResults.length > 0) for (const chunk of afterToolBoundaryChunks) yield* this.pipeThroughMiddleware(chunk);
|
|
1006
|
-
const emitted = yield* this.emitActionableInterruptBoundary(finishEvent, executionResult.needsApproval, executionResult.needsClientExecution, [], executionResult.subagentInterrupts);
|
|
1021
|
+
const emitted = yield* this.emitActionableInterruptBoundary(finishEvent, executionResult.needsApproval, executionResult.needsClientExecution, [], executionResult.inputRequired, executionResult.subagentInterrupts);
|
|
1007
1022
|
this.setToolPhase(emitted ? "wait" : "stop");
|
|
1008
1023
|
return;
|
|
1009
1024
|
}
|
|
@@ -1230,7 +1245,7 @@ var TextEngine = class {
|
|
|
1230
1245
|
genericInterruptId() {
|
|
1231
1246
|
return this.createId("interrupt");
|
|
1232
1247
|
}
|
|
1233
|
-
buildActionableInterrupts(approvals, clientRequests, genericRequests = [], genericInterruptIds = [], childInterrupts = []) {
|
|
1248
|
+
buildActionableInterrupts(approvals, clientRequests, genericRequests = [], genericInterruptIds = [], inputRequired = [], childInterrupts = []) {
|
|
1234
1249
|
const interrupts = [];
|
|
1235
1250
|
for (const approval of approvals) {
|
|
1236
1251
|
const tool = this.tools.find((candidate) => candidate.name === approval.toolName);
|
|
@@ -1311,6 +1326,27 @@ var TextEngine = class {
|
|
|
1311
1326
|
}
|
|
1312
1327
|
});
|
|
1313
1328
|
}
|
|
1329
|
+
for (const pendingInput of inputRequired) {
|
|
1330
|
+
const id = `mcp_input_${pendingInput.toolCallId}`;
|
|
1331
|
+
interrupts.push({
|
|
1332
|
+
id,
|
|
1333
|
+
reason: "mcp_input",
|
|
1334
|
+
message: `Input required to run ${pendingInput.toolName}`,
|
|
1335
|
+
toolCallId: pendingInput.toolCallId,
|
|
1336
|
+
metadata: {
|
|
1337
|
+
toolName: pendingInput.toolName,
|
|
1338
|
+
[interruptBindingMetadataKey]: {
|
|
1339
|
+
v: 1,
|
|
1340
|
+
kind: "generic",
|
|
1341
|
+
interruptId: id
|
|
1342
|
+
},
|
|
1343
|
+
[INTERRUPT_PAYLOAD_METADATA_KEY]: {
|
|
1344
|
+
kind: pendingInput.kind,
|
|
1345
|
+
request: pendingInput.request
|
|
1346
|
+
}
|
|
1347
|
+
}
|
|
1348
|
+
});
|
|
1349
|
+
}
|
|
1314
1350
|
interrupts.push(...childInterrupts);
|
|
1315
1351
|
const ids = /* @__PURE__ */ new Set();
|
|
1316
1352
|
for (const interrupt of interrupts) {
|
|
@@ -1319,13 +1355,13 @@ var TextEngine = class {
|
|
|
1319
1355
|
}
|
|
1320
1356
|
return interrupts;
|
|
1321
1357
|
}
|
|
1322
|
-
buildInterruptFinishedChunk(finishEvent, approvals, clientRequests, genericRequests = [], genericInterruptIds, childInterrupts) {
|
|
1358
|
+
buildInterruptFinishedChunk(finishEvent, approvals, clientRequests, genericRequests = [], genericInterruptIds, inputRequired = [], childInterrupts) {
|
|
1323
1359
|
return {
|
|
1324
1360
|
...finishEvent,
|
|
1325
1361
|
timestamp: Date.now(),
|
|
1326
1362
|
outcome: {
|
|
1327
1363
|
type: "interrupt",
|
|
1328
|
-
interrupts: this.buildActionableInterrupts(approvals, clientRequests, genericRequests, genericInterruptIds, childInterrupts)
|
|
1364
|
+
interrupts: this.buildActionableInterrupts(approvals, clientRequests, genericRequests, genericInterruptIds, inputRequired, childInterrupts)
|
|
1329
1365
|
}
|
|
1330
1366
|
};
|
|
1331
1367
|
}
|
|
@@ -1419,10 +1455,10 @@ var TextEngine = class {
|
|
|
1419
1455
|
};
|
|
1420
1456
|
yield* this.pipeThroughMiddleware(this.buildInterruptRunErrorChunk(error));
|
|
1421
1457
|
}
|
|
1422
|
-
async *emitActionableInterruptBoundary(finishEvent, approvals, clientRequests, genericRequests = [], childInterrupts = []) {
|
|
1458
|
+
async *emitActionableInterruptBoundary(finishEvent, approvals, clientRequests, genericRequests = [], inputRequired = [], childInterrupts = []) {
|
|
1423
1459
|
yield* this.emitSyntheticRunStarted(finishEvent);
|
|
1424
1460
|
const genericInterruptIds = genericRequests.map(() => this.genericInterruptId());
|
|
1425
|
-
const terminal = this.completeEphemeralInterruptBindings(this.buildInterruptFinishedChunk(finishEvent, approvals, clientRequests, genericRequests, genericInterruptIds, childInterrupts));
|
|
1461
|
+
const terminal = this.completeEphemeralInterruptBindings(this.buildInterruptFinishedChunk(finishEvent, approvals, clientRequests, genericRequests, genericInterruptIds, inputRequired, childInterrupts));
|
|
1426
1462
|
let terminalOutputs;
|
|
1427
1463
|
try {
|
|
1428
1464
|
terminalOutputs = [...this.emitPublicChunks(await this.middlewareRunner.runOnChunk(this.middlewareCtx, terminal))];
|
|
@@ -1439,7 +1475,7 @@ var TextEngine = class {
|
|
|
1439
1475
|
for (const output of terminalOutputs) yield this.publicInterruptTerminal(output);
|
|
1440
1476
|
return true;
|
|
1441
1477
|
}
|
|
1442
|
-
async *emitBoundaryInterrupts(phase, finishEvent, toolCalls = [], requests) {
|
|
1478
|
+
async *emitBoundaryInterrupts(phase, finishEvent, toolCalls = [], requests, inputRequired = []) {
|
|
1443
1479
|
this.middlewareCtx.phase = phase;
|
|
1444
1480
|
const boundaryRequests = requests ?? (yield* this.runWhileYielding(this.middlewareRunner.runOnInterruptBoundary(this.middlewareCtx)));
|
|
1445
1481
|
if (boundaryRequests.length === 0) return false;
|
|
@@ -1449,7 +1485,7 @@ var TextEngine = class {
|
|
|
1449
1485
|
else this.addAssistantTextMessageForInterrupt();
|
|
1450
1486
|
}
|
|
1451
1487
|
const actionable = this.getBoundaryActionableToolRequests(toolCalls);
|
|
1452
|
-
yield* this.emitActionableInterruptBoundary(finishEvent, actionable.approvals, actionable.clientRequests, boundaryRequests);
|
|
1488
|
+
yield* this.emitActionableInterruptBoundary(finishEvent, actionable.approvals, actionable.clientRequests, boundaryRequests, inputRequired);
|
|
1453
1489
|
return true;
|
|
1454
1490
|
}
|
|
1455
1491
|
addAssistantTextMessageForInterrupt() {
|
|
@@ -1482,7 +1518,7 @@ var TextEngine = class {
|
|
|
1482
1518
|
input,
|
|
1483
1519
|
approvalId
|
|
1484
1520
|
});
|
|
1485
|
-
else if (!tool.execute && !clientToolResults.has(toolCall.id) && !this.resumeCancelledToolCallIds.has(toolCall.id)) clientRequests.push({
|
|
1521
|
+
else if (!tool.execute && !clientToolResults.has(toolCall.id) && !this.resumeClientToolErrors.has(toolCall.id) && !this.resumeCancelledToolCallIds.has(toolCall.id)) clientRequests.push({
|
|
1486
1522
|
toolCallId: toolCall.id,
|
|
1487
1523
|
toolName: toolCall.function.name,
|
|
1488
1524
|
input
|
|
@@ -1553,7 +1589,10 @@ var TextEngine = class {
|
|
|
1553
1589
|
content: wireContent,
|
|
1554
1590
|
role: "tool"
|
|
1555
1591
|
};
|
|
1556
|
-
chunks.push(result.state === "output-error" ? withTanstackMetadata(resultChunk, {
|
|
1592
|
+
chunks.push(result.state === "output-error" ? withTanstackMetadata(resultChunk, {
|
|
1593
|
+
state: result.state,
|
|
1594
|
+
...result.outcome !== void 0 && { toolResultOutcome: result.outcome }
|
|
1595
|
+
}) : resultChunk);
|
|
1557
1596
|
const placeholderIdx = this.messages.findIndex((m) => {
|
|
1558
1597
|
if (m.role !== "tool" || m.toolCallId !== result.toolCallId) return false;
|
|
1559
1598
|
if (typeof m.content !== "string") return false;
|
|
@@ -1563,18 +1602,31 @@ var TextEngine = class {
|
|
|
1563
1602
|
return false;
|
|
1564
1603
|
}
|
|
1565
1604
|
});
|
|
1566
|
-
const
|
|
1605
|
+
const isDeniedResult = result.outcome === "denied";
|
|
1606
|
+
const existingToolResultIdx = isDeniedResult ? this.messages.findIndex((message) => message.role === "tool" && message.toolCallId === result.toolCallId) : -1;
|
|
1607
|
+
const resultMessageIdx = existingToolResultIdx >= 0 ? existingToolResultIdx : placeholderIdx;
|
|
1608
|
+
const existingToolMessage = existingToolResultIdx >= 0 ? this.messages[existingToolResultIdx] : void 0;
|
|
1609
|
+
const errorField = result.state === "output-error" && { error: toolResultErrorText(parseToolOutput(wireContent)) };
|
|
1610
|
+
const replacementMessage = existingToolMessage?.role === "tool" ? {
|
|
1611
|
+
...existingToolMessage,
|
|
1612
|
+
content,
|
|
1613
|
+
toolCallId: result.toolCallId,
|
|
1614
|
+
...errorField
|
|
1615
|
+
} : {
|
|
1567
1616
|
role: "tool",
|
|
1568
1617
|
content,
|
|
1569
1618
|
toolCallId: result.toolCallId,
|
|
1570
|
-
...
|
|
1619
|
+
...errorField
|
|
1571
1620
|
};
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1621
|
+
const newToolMessage = result.outcome !== void 0 ? withTanstackMetadata(replacementMessage, { toolResultOutcome: result.outcome }) : replacementMessage;
|
|
1622
|
+
if (resultMessageIdx >= 0) {
|
|
1623
|
+
const replacedMessages = [
|
|
1624
|
+
...this.messages.slice(0, resultMessageIdx),
|
|
1625
|
+
newToolMessage,
|
|
1626
|
+
...this.messages.slice(resultMessageIdx + 1)
|
|
1627
|
+
];
|
|
1628
|
+
this.messages = isDeniedResult ? replacedMessages.filter((message, index) => index === resultMessageIdx || !(message.role === "tool" && message.toolCallId === result.toolCallId)) : replacedMessages;
|
|
1629
|
+
} else this.messages = [...this.messages, newToolMessage];
|
|
1578
1630
|
this.middlewareCtx.messages = this.messages;
|
|
1579
1631
|
}
|
|
1580
1632
|
return chunks;
|
|
@@ -1586,7 +1638,7 @@ var TextEngine = class {
|
|
|
1586
1638
|
if (typeof message.content === "string") try {
|
|
1587
1639
|
if (JSON.parse(message.content).pendingExecution === true) hasPendingExecution = true;
|
|
1588
1640
|
} catch {}
|
|
1589
|
-
if (!hasPendingExecution) completedToolIds.add(message.toolCallId);
|
|
1641
|
+
if (!hasPendingExecution && !this.resumeDeniedToolResults.has(message.toolCallId)) completedToolIds.add(message.toolCallId);
|
|
1590
1642
|
}
|
|
1591
1643
|
const pending = [];
|
|
1592
1644
|
for (const message of this.messages) if (message.role === "assistant" && message.toolCalls) for (const toolCall of message.toolCalls) {
|
|
@@ -1828,6 +1880,7 @@ var TextEngine = class {
|
|
|
1828
1880
|
};
|
|
1829
1881
|
const runChunkMiddleware = (synthChunk) => this.middlewareRunner.runOnChunk(this.middlewareCtx, synthChunk);
|
|
1830
1882
|
let runErrorYielded = false;
|
|
1883
|
+
let rawText = "";
|
|
1831
1884
|
for await (const raw of providerStream) {
|
|
1832
1885
|
if (this.isCancelled()) break;
|
|
1833
1886
|
{
|
|
@@ -1873,11 +1926,16 @@ var TextEngine = class {
|
|
|
1873
1926
|
}
|
|
1874
1927
|
}
|
|
1875
1928
|
if (chunk.type === EventType.RUN_FINISHED) await this.runOnUsageFromChunk(chunk);
|
|
1876
|
-
if (chunk.type === EventType.
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
|
|
1929
|
+
if (chunk.type === EventType.TEXT_MESSAGE_CONTENT) rawText += chunk.delta;
|
|
1930
|
+
if (chunk.type === EventType.RUN_ERROR) {
|
|
1931
|
+
const cause = fallbackAdapterError ?? chunk.rawEvent;
|
|
1932
|
+
this.finalizationError = {
|
|
1933
|
+
message: chunk.message,
|
|
1934
|
+
...chunk.code ? { code: chunk.code } : {},
|
|
1935
|
+
...cause !== void 0 ? { cause } : {},
|
|
1936
|
+
...rawText ? { rawText } : {}
|
|
1937
|
+
};
|
|
1938
|
+
}
|
|
1881
1939
|
const outputChunks = await this.middlewareRunner.runOnChunk(this.middlewareCtx, outboundChunk);
|
|
1882
1940
|
if (this.finalStructuredOutput.yieldChunks) for (const spec of this.emitPublicChunks(outputChunks)) {
|
|
1883
1941
|
if (spec.type === EventType.RUN_ERROR) runErrorYielded = true;
|
|
@@ -1967,7 +2025,8 @@ var TextEngine = class {
|
|
|
1967
2025
|
this.finalizationError = {
|
|
1968
2026
|
message: `Failed to parse structured output as JSON. Content: ${detail}`,
|
|
1969
2027
|
code: "structured-output-parse-failed",
|
|
1970
|
-
cause: err
|
|
2028
|
+
cause: err,
|
|
2029
|
+
rawText
|
|
1971
2030
|
};
|
|
1972
2031
|
}
|
|
1973
2032
|
}
|
|
@@ -2029,6 +2088,7 @@ var TextEngine = class {
|
|
|
2029
2088
|
resumeToolState: {
|
|
2030
2089
|
approvals: this.resumeApprovals,
|
|
2031
2090
|
clientToolResults: this.resumeClientToolResults,
|
|
2091
|
+
clientToolErrors: this.resumeClientToolErrors,
|
|
2032
2092
|
deniedToolResults: this.resumeDeniedToolResults,
|
|
2033
2093
|
cancelledToolCallIds: this.resumeCancelledToolCallIds
|
|
2034
2094
|
},
|
|
@@ -2108,6 +2168,24 @@ var TextEngine = class {
|
|
|
2108
2168
|
}] : [];
|
|
2109
2169
|
});
|
|
2110
2170
|
pending.push(...genericPending);
|
|
2171
|
+
const mcpInputCallIds = /* @__PURE__ */ new Map();
|
|
2172
|
+
for (const toolCall of pendingToolCalls) {
|
|
2173
|
+
const interruptId = `mcp_input_${toolCall.id}`;
|
|
2174
|
+
if (!resumeInterruptIds.has(interruptId)) continue;
|
|
2175
|
+
if (!toolsByCallId.get(toolCall.id)?.execute) continue;
|
|
2176
|
+
mcpInputCallIds.set(interruptId, toolCall.id);
|
|
2177
|
+
pending.push({
|
|
2178
|
+
interruptId,
|
|
2179
|
+
payload: { id: interruptId },
|
|
2180
|
+
binding: {
|
|
2181
|
+
v: 1,
|
|
2182
|
+
kind: "generic",
|
|
2183
|
+
interruptId,
|
|
2184
|
+
interruptedRunId,
|
|
2185
|
+
generation: 0
|
|
2186
|
+
}
|
|
2187
|
+
});
|
|
2188
|
+
}
|
|
2111
2189
|
const validated = await validateInterruptResumeBatch({
|
|
2112
2190
|
threadId: this.threadId,
|
|
2113
2191
|
interruptedRunId,
|
|
@@ -2124,6 +2202,14 @@ var TextEngine = class {
|
|
|
2124
2202
|
approvals
|
|
2125
2203
|
});
|
|
2126
2204
|
const genericResolutions = validated.resumeToolState.genericInterrupts;
|
|
2205
|
+
for (const [interruptId, toolCallId] of mcpInputCallIds) {
|
|
2206
|
+
const resolution = genericResolutions?.get(interruptId);
|
|
2207
|
+
if (!resolution) continue;
|
|
2208
|
+
this.resumeInputResponses.set(toolCallId, resolution.status === "resolved" ? {
|
|
2209
|
+
status: "resolved",
|
|
2210
|
+
payload: resolution.payload
|
|
2211
|
+
} : { status: "cancelled" });
|
|
2212
|
+
}
|
|
2127
2213
|
if (genericPending.length > 0 && genericResolutions) {
|
|
2128
2214
|
const resolutions = genericPending.sort((left, right) => {
|
|
2129
2215
|
return (left.binding.kind === "generic" ? left.binding.batchIndex ?? 0 : 0) - (right.binding.kind === "generic" ? right.binding.batchIndex ?? 0 : 0);
|
|
@@ -2144,7 +2230,10 @@ var TextEngine = class {
|
|
|
2144
2230
|
all: (...definitions) => definitions.length === 0 ? resolutions : resolutions.filter((resolution) => definitions.includes(resolution.request.definition))
|
|
2145
2231
|
});
|
|
2146
2232
|
if (policy.toolResume === "stop") this.earlyTermination = true;
|
|
2147
|
-
else if (policy.toolResume === "cancel") for (const request of pendingToolCalls)
|
|
2233
|
+
else if (policy.toolResume === "cancel") for (const request of pendingToolCalls) {
|
|
2234
|
+
if (this.resumeDeniedToolResults.has(request.id)) continue;
|
|
2235
|
+
this.resumeCancelledToolCallIds.add(request.id);
|
|
2236
|
+
}
|
|
2148
2237
|
}
|
|
2149
2238
|
}
|
|
2150
2239
|
getGenericContinuationPending(interruptedRunId) {
|
|
@@ -2216,6 +2305,7 @@ var TextEngine = class {
|
|
|
2216
2305
|
applyResumeToolState(state) {
|
|
2217
2306
|
if (state?.approvals) for (const [approvalId, resolution] of state.approvals) this.resumeApprovals.set(approvalId, resolution);
|
|
2218
2307
|
if (state?.clientToolResults) for (const [toolCallId, result] of state.clientToolResults) this.resumeClientToolResults.set(toolCallId, result);
|
|
2308
|
+
if (state?.clientToolErrors) for (const [toolCallId, errorText] of state.clientToolErrors) this.resumeClientToolErrors.set(toolCallId, errorText);
|
|
2219
2309
|
if (state?.deniedToolResults) for (const [toolCallId, result] of state.deniedToolResults) this.resumeDeniedToolResults.set(toolCallId, result);
|
|
2220
2310
|
if (state?.cancelledToolCallIds) for (const toolCallId of state.cancelledToolCallIds) this.resumeCancelledToolCallIds.add(toolCallId);
|
|
2221
2311
|
if (state?.genericInterrupts) for (const [interruptId, resolution] of state.genericInterrupts) this.resumeGenericInterrupts.set(interruptId, resolution);
|
|
@@ -2240,7 +2330,10 @@ var TextEngine = class {
|
|
|
2240
2330
|
all: (...definitions) => definitions.length === 0 ? resolutions : resolutions.filter((resolution) => definitions.includes(resolution.request.definition))
|
|
2241
2331
|
});
|
|
2242
2332
|
if (policy.toolResume === "stop") this.earlyTermination = true;
|
|
2243
|
-
else if (policy.toolResume === "cancel") for (const toolCall of this.getPendingToolCallsFromMessages())
|
|
2333
|
+
else if (policy.toolResume === "cancel") for (const toolCall of this.getPendingToolCallsFromMessages()) {
|
|
2334
|
+
if (this.resumeDeniedToolResults.has(toolCall.id)) continue;
|
|
2335
|
+
this.resumeCancelledToolCallIds.add(toolCall.id);
|
|
2336
|
+
}
|
|
2244
2337
|
}
|
|
2245
2338
|
applyMiddlewareConfig(config) {
|
|
2246
2339
|
this.applyResumeToolState(config.resumeToolState);
|
|
@@ -2577,6 +2670,8 @@ async function* runRoutedSubagents(options, engineRef) {
|
|
|
2577
2670
|
yield* runChatEngine(options, engineRef);
|
|
2578
2671
|
return;
|
|
2579
2672
|
}
|
|
2673
|
+
const withInput = bag.agents.find((agent) => agent.inputSchema !== void 0);
|
|
2674
|
+
if (withInput) throw new Error(`Subagent "${withInput.name}" has an inputSchema. inputSchema needs tool mode: remove subagents.router so the model writes the input.`);
|
|
2580
2675
|
const threadId = options.threadId ?? `thread-${Date.now()}`;
|
|
2581
2676
|
const runId = options.runId ?? `run-${Date.now()}`;
|
|
2582
2677
|
const messages = options.messages ?? [];
|
|
@@ -2889,6 +2984,10 @@ async function runAgenticStructuredOutput(options) {
|
|
|
2889
2984
|
value: finalizationError.code,
|
|
2890
2985
|
enumerable: true
|
|
2891
2986
|
});
|
|
2987
|
+
if (finalizationError.rawText !== void 0) Object.defineProperty(err, "rawText", {
|
|
2988
|
+
value: finalizationError.rawText,
|
|
2989
|
+
enumerable: true
|
|
2990
|
+
});
|
|
2892
2991
|
throw err;
|
|
2893
2992
|
}
|
|
2894
2993
|
const validated = engine.getValidatedStructuredOutput();
|