@dudousxd/nestjs-agent-core 0.33.0 → 0.35.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/ag-ui/index.cjs +1064 -0
- package/dist/ag-ui/index.cjs.map +1 -0
- package/dist/ag-ui/index.d.cts +479 -0
- package/dist/ag-ui/index.d.ts +479 -0
- package/dist/ag-ui/index.js +1025 -0
- package/dist/ag-ui/index.js.map +1 -0
- package/dist/genui/index.d.cts +2 -1
- package/dist/genui/index.d.ts +2 -1
- package/dist/guardrails/index.d.cts +3 -2
- package/dist/guardrails/index.d.ts +3 -2
- package/dist/index.cjs +245 -6
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +79 -5
- package/dist/index.d.ts +79 -5
- package/dist/index.js +233 -6
- package/dist/index.js.map +1 -1
- package/dist/{processors-DvZDW5zS.d.cts → processors-C0snQzZJ.d.cts} +1 -1
- package/dist/{processors-C1jir8eB.d.ts → processors-D5110pit.d.ts} +1 -1
- package/dist/{tool-CMTuoJ2v.d.cts → stream-events-CgWqAI-1.d.cts} +786 -806
- package/dist/{tool-CMTuoJ2v.d.ts → stream-events-CgWqAI-1.d.ts} +786 -806
- package/dist/tool-DklsS3JX.d.ts +119 -0
- package/dist/tool-DuJ-_qXM.d.cts +119 -0
- package/package.json +14 -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 ?? {}, {
|
|
@@ -4402,6 +4577,7 @@ ${block}`;
|
|
|
4402
4577
|
};
|
|
4403
4578
|
}
|
|
4404
4579
|
const resolvedModelId = turn.modelId ?? deps.modelId ?? "unknown";
|
|
4580
|
+
const stepModel = turn.modelId ?? deps.modelId;
|
|
4405
4581
|
const costUsd = resolveCostUsd(turn.usage, turn.costUsd, priceByModel.get(resolvedModelId));
|
|
4406
4582
|
const toolCallsWithKind = turn.toolCalls.map((call) => ({
|
|
4407
4583
|
...call,
|
|
@@ -4603,6 +4779,9 @@ ${block}`;
|
|
|
4603
4779
|
costUsd,
|
|
4604
4780
|
...turn.reasoningMs !== void 0 ? {
|
|
4605
4781
|
reasoningMs: turn.reasoningMs
|
|
4782
|
+
} : {},
|
|
4783
|
+
...stepModel !== void 0 ? {
|
|
4784
|
+
model: stepModel
|
|
4606
4785
|
} : {}
|
|
4607
4786
|
}));
|
|
4608
4787
|
});
|
|
@@ -4667,6 +4846,9 @@ ${block}`;
|
|
|
4667
4846
|
costUsd,
|
|
4668
4847
|
...turn.reasoningMs !== void 0 ? {
|
|
4669
4848
|
reasoningMs: turn.reasoningMs
|
|
4849
|
+
} : {},
|
|
4850
|
+
...stepModel !== void 0 ? {
|
|
4851
|
+
model: stepModel
|
|
4670
4852
|
} : {}
|
|
4671
4853
|
}));
|
|
4672
4854
|
});
|
|
@@ -4742,7 +4924,10 @@ var InMemoryAgentStore = class {
|
|
|
4742
4924
|
return (/* @__PURE__ */ new Date()).toISOString();
|
|
4743
4925
|
}
|
|
4744
4926
|
async createThread(input) {
|
|
4745
|
-
const id = crypto.randomUUID();
|
|
4927
|
+
const id = input.id ?? crypto.randomUUID();
|
|
4928
|
+
if (this.threads.has(id)) {
|
|
4929
|
+
throw new Error(`thread ${id} already exists`);
|
|
4930
|
+
}
|
|
4746
4931
|
const ts = this.now();
|
|
4747
4932
|
const row = {
|
|
4748
4933
|
id,
|
|
@@ -5277,6 +5462,36 @@ var InMemoryAgentStore = class {
|
|
|
5277
5462
|
} : {}
|
|
5278
5463
|
});
|
|
5279
5464
|
}
|
|
5465
|
+
async toolCallOutcomes(toolCallIds) {
|
|
5466
|
+
const outcomes = [];
|
|
5467
|
+
for (const id of toolCallIds) {
|
|
5468
|
+
const row = this.toolCalls.get(id);
|
|
5469
|
+
if (row !== void 0) {
|
|
5470
|
+
outcomes.push({
|
|
5471
|
+
id,
|
|
5472
|
+
status: row.status,
|
|
5473
|
+
...row.output !== void 0 ? {
|
|
5474
|
+
output: row.output
|
|
5475
|
+
} : {},
|
|
5476
|
+
...row.error !== void 0 ? {
|
|
5477
|
+
error: row.error
|
|
5478
|
+
} : {}
|
|
5479
|
+
});
|
|
5480
|
+
}
|
|
5481
|
+
}
|
|
5482
|
+
return outcomes;
|
|
5483
|
+
}
|
|
5484
|
+
async failUnsettledToolCalls(runId, error) {
|
|
5485
|
+
let settled = 0;
|
|
5486
|
+
for (const row of this.toolCalls.values()) {
|
|
5487
|
+
if (row.runId === runId && row.status === "pending_approval") {
|
|
5488
|
+
row.status = "failed";
|
|
5489
|
+
row.error = error;
|
|
5490
|
+
settled += 1;
|
|
5491
|
+
}
|
|
5492
|
+
}
|
|
5493
|
+
return settled;
|
|
5494
|
+
}
|
|
5280
5495
|
async updateToolCall(input) {
|
|
5281
5496
|
const row = this.toolCalls.get(input.toolCallId);
|
|
5282
5497
|
if (row === void 0) {
|
|
@@ -5603,6 +5818,11 @@ export {
|
|
|
5603
5818
|
REMEMBER_TOOL_DESCRIPTION,
|
|
5604
5819
|
REMEMBER_TOOL_NAME,
|
|
5605
5820
|
REQUESTER_APPROVER,
|
|
5821
|
+
RUN_ENDED_BEFORE_TOOL_CALL,
|
|
5822
|
+
RUN_FAILED_MESSAGE,
|
|
5823
|
+
RUN_NOT_ACTIVE_CODE,
|
|
5824
|
+
RUN_NOT_ACTIVE_MESSAGE,
|
|
5825
|
+
RUN_NO_LONGER_RUNNING,
|
|
5606
5826
|
RunCancelledError,
|
|
5607
5827
|
SKILL_TOOL_DESCRIPTION,
|
|
5608
5828
|
SKILL_TOOL_NAME,
|
|
@@ -5613,6 +5833,7 @@ export {
|
|
|
5613
5833
|
ToolInputInvalidError,
|
|
5614
5834
|
ToolNotFoundError,
|
|
5615
5835
|
ToolRegistry,
|
|
5836
|
+
UNFINISHED_TOOL_CALL,
|
|
5616
5837
|
actorScope,
|
|
5617
5838
|
agentDiagnosticKey,
|
|
5618
5839
|
agentFailureCode,
|
|
@@ -5630,6 +5851,7 @@ export {
|
|
|
5630
5851
|
createIncrementalGate,
|
|
5631
5852
|
createNoopEmitUi,
|
|
5632
5853
|
createUiCollector,
|
|
5854
|
+
danglingToolCallIds,
|
|
5633
5855
|
dayBoundsUtc,
|
|
5634
5856
|
decodeStreamEvent,
|
|
5635
5857
|
defaultCanDecide,
|
|
@@ -5641,6 +5863,7 @@ export {
|
|
|
5641
5863
|
estimateCost,
|
|
5642
5864
|
estimateMessageTokens,
|
|
5643
5865
|
exhaustedWindow,
|
|
5866
|
+
exposeStreamErrorDetails,
|
|
5644
5867
|
extractJson,
|
|
5645
5868
|
filterToolsByAllowList,
|
|
5646
5869
|
filterToolsByCanUse,
|
|
@@ -5703,6 +5926,8 @@ export {
|
|
|
5703
5926
|
runOutputProcessors,
|
|
5704
5927
|
seedModelPrices,
|
|
5705
5928
|
settleAll,
|
|
5929
|
+
settleDanglingToolCalls,
|
|
5930
|
+
settleDeadRun,
|
|
5706
5931
|
settleElicitation,
|
|
5707
5932
|
settleUnsettledDelegation,
|
|
5708
5933
|
skillInputSchema,
|
|
@@ -5711,9 +5936,11 @@ export {
|
|
|
5711
5936
|
stampToolKinds,
|
|
5712
5937
|
staticModelCatalog,
|
|
5713
5938
|
staticSkillProvider,
|
|
5939
|
+
streamFailure,
|
|
5714
5940
|
summarizeWithModel,
|
|
5715
5941
|
tenantScope,
|
|
5716
5942
|
toolCallApprovalFromRow,
|
|
5943
|
+
toolCallContext,
|
|
5717
5944
|
traceLlmTurn,
|
|
5718
5945
|
traceToolExecution,
|
|
5719
5946
|
truncateDetailContent,
|