@dudousxd/nestjs-agent-core 0.32.0 → 0.34.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 +3 -1
- package/dist/genui/index.d.cts +1 -1
- package/dist/genui/index.d.ts +1 -1
- package/dist/guardrails/index.d.cts +2 -2
- package/dist/guardrails/index.d.ts +2 -2
- package/dist/index.cjs +241 -5
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +77 -5
- package/dist/index.d.ts +77 -5
- package/dist/index.js +229 -5
- package/dist/index.js.map +1 -1
- package/dist/{processors-DQJ5sWw7.d.cts → processors-Bm2DniQ8.d.cts} +1 -1
- package/dist/{processors-BIVqOR1Q.d.ts → processors-CtrfAA0B.d.ts} +1 -1
- package/dist/{tool-BhhzEI40.d.cts → tool-C128TFWw.d.cts} +91 -2
- package/dist/{tool-BhhzEI40.d.ts → tool-C128TFWw.d.ts} +91 -2
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -2348,6 +2348,123 @@ function isControlFlowSignal(error) {
|
|
|
2348
2348
|
}
|
|
2349
2349
|
__name(isControlFlowSignal, "isControlFlowSignal");
|
|
2350
2350
|
|
|
2351
|
+
// src/dangling-tool-calls.ts
|
|
2352
|
+
var UNFINISHED_TOOL_CALL = "This tool call was never completed: the turn it belonged to ended unexpectedly before it was settled. Do not assume it ran, and do not assume it did not \u2014 check the current state with a read tool if one exists, tell the person plainly what is and is not confirmed, and do it again only if they still want it.";
|
|
2353
|
+
var RUN_ENDED_BEFORE_TOOL_CALL = "the run ended before this tool call was settled";
|
|
2354
|
+
var DECLINED = "The person was asked to approve this action and declined it. Nothing ran and nothing changed.";
|
|
2355
|
+
var EXPIRED = "This action needed approval, and the request expired before anyone decided. Nothing ran.";
|
|
2356
|
+
function danglingToolCallIds(messages) {
|
|
2357
|
+
const ids = [];
|
|
2358
|
+
for (const message of messages) {
|
|
2359
|
+
const calls = message.toolCalls ?? [];
|
|
2360
|
+
if (message.role !== "assistant" || calls.length === 0) {
|
|
2361
|
+
continue;
|
|
2362
|
+
}
|
|
2363
|
+
const settled = new Set((message.toolResults ?? []).map((result) => result.id));
|
|
2364
|
+
for (const call of calls) {
|
|
2365
|
+
if (!settled.has(call.id)) {
|
|
2366
|
+
ids.push(call.id);
|
|
2367
|
+
}
|
|
2368
|
+
}
|
|
2369
|
+
}
|
|
2370
|
+
return ids;
|
|
2371
|
+
}
|
|
2372
|
+
__name(danglingToolCallIds, "danglingToolCallIds");
|
|
2373
|
+
function resultFor(call, outcome) {
|
|
2374
|
+
const base = {
|
|
2375
|
+
id: call.id,
|
|
2376
|
+
name: call.name
|
|
2377
|
+
};
|
|
2378
|
+
switch (outcome?.status) {
|
|
2379
|
+
case "executed":
|
|
2380
|
+
case "auto_executed":
|
|
2381
|
+
return {
|
|
2382
|
+
...base,
|
|
2383
|
+
output: outcome.output ?? null
|
|
2384
|
+
};
|
|
2385
|
+
case "failed":
|
|
2386
|
+
return {
|
|
2387
|
+
...base,
|
|
2388
|
+
output: null,
|
|
2389
|
+
error: outcome.error ?? UNFINISHED_TOOL_CALL
|
|
2390
|
+
};
|
|
2391
|
+
case "rejected":
|
|
2392
|
+
return {
|
|
2393
|
+
...base,
|
|
2394
|
+
output: {
|
|
2395
|
+
rejected: true
|
|
2396
|
+
},
|
|
2397
|
+
denied: true,
|
|
2398
|
+
error: DECLINED
|
|
2399
|
+
};
|
|
2400
|
+
case "expired":
|
|
2401
|
+
return {
|
|
2402
|
+
...base,
|
|
2403
|
+
output: {
|
|
2404
|
+
rejected: true,
|
|
2405
|
+
expired: true
|
|
2406
|
+
},
|
|
2407
|
+
denied: true,
|
|
2408
|
+
expired: true,
|
|
2409
|
+
error: EXPIRED
|
|
2410
|
+
};
|
|
2411
|
+
default:
|
|
2412
|
+
return {
|
|
2413
|
+
...base,
|
|
2414
|
+
output: null,
|
|
2415
|
+
error: UNFINISHED_TOOL_CALL
|
|
2416
|
+
};
|
|
2417
|
+
}
|
|
2418
|
+
}
|
|
2419
|
+
__name(resultFor, "resultFor");
|
|
2420
|
+
function settleDanglingToolCalls(messages, outcomes = []) {
|
|
2421
|
+
const known = new Map(outcomes.map((outcome) => [
|
|
2422
|
+
outcome.id,
|
|
2423
|
+
outcome
|
|
2424
|
+
]));
|
|
2425
|
+
return messages.map((message) => {
|
|
2426
|
+
const calls = message.toolCalls ?? [];
|
|
2427
|
+
if (message.role !== "assistant" || calls.length === 0) {
|
|
2428
|
+
return message;
|
|
2429
|
+
}
|
|
2430
|
+
const results = message.toolResults ?? [];
|
|
2431
|
+
const settled = new Set(results.map((result) => result.id));
|
|
2432
|
+
const missing = calls.filter((call) => !settled.has(call.id));
|
|
2433
|
+
if (missing.length === 0) {
|
|
2434
|
+
return message;
|
|
2435
|
+
}
|
|
2436
|
+
return {
|
|
2437
|
+
...message,
|
|
2438
|
+
toolResults: [
|
|
2439
|
+
...results,
|
|
2440
|
+
...missing.map((call) => resultFor(call, known.get(call.id)))
|
|
2441
|
+
]
|
|
2442
|
+
};
|
|
2443
|
+
});
|
|
2444
|
+
}
|
|
2445
|
+
__name(settleDanglingToolCalls, "settleDanglingToolCalls");
|
|
2446
|
+
|
|
2447
|
+
// src/dead-run.ts
|
|
2448
|
+
var RUN_NOT_ACTIVE_CODE = "run_not_active";
|
|
2449
|
+
var RUN_NOT_ACTIVE_MESSAGE = "This request is no longer waiting for an answer: the turn it belonged to has ended. Send the message again.";
|
|
2450
|
+
var RUN_NO_LONGER_RUNNING = "the run is no longer running";
|
|
2451
|
+
async function settleDeadRun(store, input) {
|
|
2452
|
+
const failure = input.failure;
|
|
2453
|
+
if (failure !== void 0) {
|
|
2454
|
+
await Promise.resolve(store.recordRunEnd?.({
|
|
2455
|
+
runId: input.runId,
|
|
2456
|
+
status: "failed",
|
|
2457
|
+
errorCode: failure.code,
|
|
2458
|
+
errorMessage: failure.message
|
|
2459
|
+
})).catch(() => void 0);
|
|
2460
|
+
}
|
|
2461
|
+
await Promise.resolve(store.failUnsettledToolCalls?.(input.runId, RUN_ENDED_BEFORE_TOOL_CALL)).catch(() => 0);
|
|
2462
|
+
if (input.threadId !== void 0) {
|
|
2463
|
+
await releaseThreadRun(store, input.threadId, input.runId).catch(() => void 0);
|
|
2464
|
+
}
|
|
2465
|
+
}
|
|
2466
|
+
__name(settleDeadRun, "settleDeadRun");
|
|
2467
|
+
|
|
2351
2468
|
// src/delegation.ts
|
|
2352
2469
|
function normalizeDelegation(entry) {
|
|
2353
2470
|
return typeof entry === "string" ? {
|
|
@@ -2812,9 +2929,46 @@ function agentFailureCode(error) {
|
|
|
2812
2929
|
if (error instanceof StructuredOutputError) {
|
|
2813
2930
|
return "structured_output_invalid";
|
|
2814
2931
|
}
|
|
2815
|
-
|
|
2932
|
+
if (isReplayIntegrityError(error)) {
|
|
2933
|
+
return "replay_diverged";
|
|
2934
|
+
}
|
|
2935
|
+
return isNoOutputError(error) ? "model_no_output" : "run_failed";
|
|
2816
2936
|
}
|
|
2817
2937
|
__name(agentFailureCode, "agentFailureCode");
|
|
2938
|
+
function isNoOutputError(error) {
|
|
2939
|
+
if (!(error instanceof Error)) {
|
|
2940
|
+
return false;
|
|
2941
|
+
}
|
|
2942
|
+
return error.name === "AI_NoOutputGeneratedError" || error.name === "NoOutputGeneratedError" || error.message.startsWith("No output generated");
|
|
2943
|
+
}
|
|
2944
|
+
__name(isNoOutputError, "isNoOutputError");
|
|
2945
|
+
var RUN_FAILED_MESSAGE = "The assistant could not finish this answer. Please try again.";
|
|
2946
|
+
var streamErrorDetails;
|
|
2947
|
+
function exposeStreamErrorDetails(expose) {
|
|
2948
|
+
streamErrorDetails = expose;
|
|
2949
|
+
}
|
|
2950
|
+
__name(exposeStreamErrorDetails, "exposeStreamErrorDetails");
|
|
2951
|
+
var WORDED_CODES = /* @__PURE__ */ new Set([
|
|
2952
|
+
"quota_exceeded",
|
|
2953
|
+
"output_rejected",
|
|
2954
|
+
"structured_output_invalid"
|
|
2955
|
+
]);
|
|
2956
|
+
function streamFailure(error) {
|
|
2957
|
+
const detail = error instanceof Error ? error.message : String(error);
|
|
2958
|
+
const code = agentFailureCode(error);
|
|
2959
|
+
if (WORDED_CODES.has(code)) {
|
|
2960
|
+
return {
|
|
2961
|
+
code,
|
|
2962
|
+
message: detail
|
|
2963
|
+
};
|
|
2964
|
+
}
|
|
2965
|
+
const exposed = streamErrorDetails ?? process.env.NODE_ENV !== "production";
|
|
2966
|
+
return {
|
|
2967
|
+
code,
|
|
2968
|
+
message: exposed ? detail : RUN_FAILED_MESSAGE
|
|
2969
|
+
};
|
|
2970
|
+
}
|
|
2971
|
+
__name(streamFailure, "streamFailure");
|
|
2818
2972
|
var MAX_DELEGATION_DEPTH = 5;
|
|
2819
2973
|
var DEFAULT_MAX_AGENT_APPEARANCES = 1;
|
|
2820
2974
|
function delegationRefusal(args) {
|
|
@@ -3006,9 +3160,9 @@ function splitHistory(policy, input, messages) {
|
|
|
3006
3160
|
}
|
|
3007
3161
|
__name(splitHistory, "splitHistory");
|
|
3008
3162
|
async function loadSelectedHistory(deps, input, hooks) {
|
|
3009
|
-
|
|
3163
|
+
const recorded = await hooks.step("load:thread", async () => {
|
|
3010
3164
|
const thread = await readThreadForTurn(deps, input.threadId);
|
|
3011
|
-
const { keep, drop } = splitHistory(deps.historyPolicy, input, toModelMessages(thread.messages));
|
|
3165
|
+
const { keep, drop } = splitHistory(deps.historyPolicy, input, await settleHistory(deps, toModelMessages(thread.messages)));
|
|
3012
3166
|
return {
|
|
3013
3167
|
messages: keep,
|
|
3014
3168
|
dropped: deps.historyPolicy?.summarize === void 0 ? [] : drop,
|
|
@@ -3016,8 +3170,21 @@ async function loadSelectedHistory(deps, input, hooks) {
|
|
|
3016
3170
|
hasAssistantMessage: thread.hasAssistantMessage
|
|
3017
3171
|
};
|
|
3018
3172
|
});
|
|
3173
|
+
return {
|
|
3174
|
+
...recorded,
|
|
3175
|
+
messages: settleDanglingToolCalls(recorded.messages)
|
|
3176
|
+
};
|
|
3019
3177
|
}
|
|
3020
3178
|
__name(loadSelectedHistory, "loadSelectedHistory");
|
|
3179
|
+
async function settleHistory(deps, messages) {
|
|
3180
|
+
const dangling = danglingToolCallIds(messages);
|
|
3181
|
+
if (dangling.length === 0) {
|
|
3182
|
+
return messages;
|
|
3183
|
+
}
|
|
3184
|
+
const outcomes = await Promise.resolve(deps.store.toolCallOutcomes?.(dangling) ?? []).catch(() => []);
|
|
3185
|
+
return settleDanglingToolCalls(messages, outcomes);
|
|
3186
|
+
}
|
|
3187
|
+
__name(settleHistory, "settleHistory");
|
|
3021
3188
|
async function readThreadForTurn(deps, threadId) {
|
|
3022
3189
|
const windowing = deps.store;
|
|
3023
3190
|
if (typeof windowing.loadThreadForTurn === "function") {
|
|
@@ -3057,7 +3224,7 @@ __name(turnMessageLimit, "turnMessageLimit");
|
|
|
3057
3224
|
async function loadWholeThread(deps, input, hooks) {
|
|
3058
3225
|
const thread = await hooks.step("load:thread", () => deps.store.getThread(input.threadId));
|
|
3059
3226
|
const stored = thread?.messages ?? [];
|
|
3060
|
-
const { keep, drop } = splitHistory(deps.historyPolicy, input, toModelMessages(stored));
|
|
3227
|
+
const { keep, drop } = splitHistory(deps.historyPolicy, input, settleDanglingToolCalls(toModelMessages(stored)));
|
|
3061
3228
|
return {
|
|
3062
3229
|
messages: keep,
|
|
3063
3230
|
dropped: drop,
|
|
@@ -3240,6 +3407,14 @@ async function awaitElicitation(hooks, request, ctx) {
|
|
|
3240
3407
|
}, ctx));
|
|
3241
3408
|
}
|
|
3242
3409
|
__name(awaitElicitation, "awaitElicitation");
|
|
3410
|
+
function toolCallContext(ctx, toolCallId) {
|
|
3411
|
+
return {
|
|
3412
|
+
...ctx,
|
|
3413
|
+
toolCallId,
|
|
3414
|
+
idempotencyKey: `${ctx.runId}:${toolCallId}`
|
|
3415
|
+
};
|
|
3416
|
+
}
|
|
3417
|
+
__name(toolCallContext, "toolCallContext");
|
|
3243
3418
|
function toolContext(deps, input, hooks) {
|
|
3244
3419
|
return {
|
|
3245
3420
|
actor: input.actor,
|
|
@@ -3679,7 +3854,7 @@ async function invokeClaimedTool(turn, claimed) {
|
|
|
3679
3854
|
}, () => invokeWithTransientRetry(() => {
|
|
3680
3855
|
ui2.restart();
|
|
3681
3856
|
return deps.registry.invoke(call.name, call.input, {
|
|
3682
|
-
...ctx,
|
|
3857
|
+
...toolCallContext(ctx, call.id),
|
|
3683
3858
|
emitUi: ui2.emit
|
|
3684
3859
|
}, deps.rolesPolicy);
|
|
3685
3860
|
}, deps.toolTransientRetry ?? {}, {
|
|
@@ -5074,6 +5249,13 @@ var InMemoryAgentStore = class {
|
|
|
5074
5249
|
message.attachments = patch.attachments;
|
|
5075
5250
|
}
|
|
5076
5251
|
}
|
|
5252
|
+
if (patch.interrupt !== void 0) {
|
|
5253
|
+
if (patch.interrupt) {
|
|
5254
|
+
message.interrupt = true;
|
|
5255
|
+
} else {
|
|
5256
|
+
delete message.interrupt;
|
|
5257
|
+
}
|
|
5258
|
+
}
|
|
5077
5259
|
message.updatedAt = this.now();
|
|
5078
5260
|
return {
|
|
5079
5261
|
...message
|
|
@@ -5270,6 +5452,36 @@ var InMemoryAgentStore = class {
|
|
|
5270
5452
|
} : {}
|
|
5271
5453
|
});
|
|
5272
5454
|
}
|
|
5455
|
+
async toolCallOutcomes(toolCallIds) {
|
|
5456
|
+
const outcomes = [];
|
|
5457
|
+
for (const id of toolCallIds) {
|
|
5458
|
+
const row = this.toolCalls.get(id);
|
|
5459
|
+
if (row !== void 0) {
|
|
5460
|
+
outcomes.push({
|
|
5461
|
+
id,
|
|
5462
|
+
status: row.status,
|
|
5463
|
+
...row.output !== void 0 ? {
|
|
5464
|
+
output: row.output
|
|
5465
|
+
} : {},
|
|
5466
|
+
...row.error !== void 0 ? {
|
|
5467
|
+
error: row.error
|
|
5468
|
+
} : {}
|
|
5469
|
+
});
|
|
5470
|
+
}
|
|
5471
|
+
}
|
|
5472
|
+
return outcomes;
|
|
5473
|
+
}
|
|
5474
|
+
async failUnsettledToolCalls(runId, error) {
|
|
5475
|
+
let settled = 0;
|
|
5476
|
+
for (const row of this.toolCalls.values()) {
|
|
5477
|
+
if (row.runId === runId && row.status === "pending_approval") {
|
|
5478
|
+
row.status = "failed";
|
|
5479
|
+
row.error = error;
|
|
5480
|
+
settled += 1;
|
|
5481
|
+
}
|
|
5482
|
+
}
|
|
5483
|
+
return settled;
|
|
5484
|
+
}
|
|
5273
5485
|
async updateToolCall(input) {
|
|
5274
5486
|
const row = this.toolCalls.get(input.toolCallId);
|
|
5275
5487
|
if (row === void 0) {
|
|
@@ -5596,6 +5808,11 @@ export {
|
|
|
5596
5808
|
REMEMBER_TOOL_DESCRIPTION,
|
|
5597
5809
|
REMEMBER_TOOL_NAME,
|
|
5598
5810
|
REQUESTER_APPROVER,
|
|
5811
|
+
RUN_ENDED_BEFORE_TOOL_CALL,
|
|
5812
|
+
RUN_FAILED_MESSAGE,
|
|
5813
|
+
RUN_NOT_ACTIVE_CODE,
|
|
5814
|
+
RUN_NOT_ACTIVE_MESSAGE,
|
|
5815
|
+
RUN_NO_LONGER_RUNNING,
|
|
5599
5816
|
RunCancelledError,
|
|
5600
5817
|
SKILL_TOOL_DESCRIPTION,
|
|
5601
5818
|
SKILL_TOOL_NAME,
|
|
@@ -5606,6 +5823,7 @@ export {
|
|
|
5606
5823
|
ToolInputInvalidError,
|
|
5607
5824
|
ToolNotFoundError,
|
|
5608
5825
|
ToolRegistry,
|
|
5826
|
+
UNFINISHED_TOOL_CALL,
|
|
5609
5827
|
actorScope,
|
|
5610
5828
|
agentDiagnosticKey,
|
|
5611
5829
|
agentFailureCode,
|
|
@@ -5623,6 +5841,7 @@ export {
|
|
|
5623
5841
|
createIncrementalGate,
|
|
5624
5842
|
createNoopEmitUi,
|
|
5625
5843
|
createUiCollector,
|
|
5844
|
+
danglingToolCallIds,
|
|
5626
5845
|
dayBoundsUtc,
|
|
5627
5846
|
decodeStreamEvent,
|
|
5628
5847
|
defaultCanDecide,
|
|
@@ -5634,6 +5853,7 @@ export {
|
|
|
5634
5853
|
estimateCost,
|
|
5635
5854
|
estimateMessageTokens,
|
|
5636
5855
|
exhaustedWindow,
|
|
5856
|
+
exposeStreamErrorDetails,
|
|
5637
5857
|
extractJson,
|
|
5638
5858
|
filterToolsByAllowList,
|
|
5639
5859
|
filterToolsByCanUse,
|
|
@@ -5696,6 +5916,8 @@ export {
|
|
|
5696
5916
|
runOutputProcessors,
|
|
5697
5917
|
seedModelPrices,
|
|
5698
5918
|
settleAll,
|
|
5919
|
+
settleDanglingToolCalls,
|
|
5920
|
+
settleDeadRun,
|
|
5699
5921
|
settleElicitation,
|
|
5700
5922
|
settleUnsettledDelegation,
|
|
5701
5923
|
skillInputSchema,
|
|
@@ -5704,9 +5926,11 @@ export {
|
|
|
5704
5926
|
stampToolKinds,
|
|
5705
5927
|
staticModelCatalog,
|
|
5706
5928
|
staticSkillProvider,
|
|
5929
|
+
streamFailure,
|
|
5707
5930
|
summarizeWithModel,
|
|
5708
5931
|
tenantScope,
|
|
5709
5932
|
toolCallApprovalFromRow,
|
|
5933
|
+
toolCallContext,
|
|
5710
5934
|
traceLlmTurn,
|
|
5711
5935
|
traceToolExecution,
|
|
5712
5936
|
truncateDetailContent,
|