@dudousxd/nestjs-agent 1.36.2 → 1.38.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/dist/a2ui/index.d.cts +1 -1
- package/dist/a2ui/index.d.ts +1 -1
- package/dist/durable/index.cjs +74 -6
- package/dist/durable/index.cjs.map +1 -1
- package/dist/durable/index.js +92 -24
- package/dist/durable/index.js.map +1 -1
- package/dist/{index-CJdTomOT.d.cts → index-BJFM1tG8.d.cts} +40 -3
- package/dist/{index-D1xRrnCq.d.ts → index-De98CGXa.d.ts} +40 -3
- package/dist/index.cjs +59 -6
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +76 -23
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/a2ui/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export * from '@dudousxd/nestjs-agent-core/a2ui';
|
|
2
|
-
export { b as A2uiAdapterOptions, c as A2uiRunHandler, i as a2uiAdapter } from '../index-
|
|
2
|
+
export { b as A2uiAdapterOptions, c as A2uiRunHandler, i as a2uiAdapter } from '../index-BJFM1tG8.cjs';
|
|
3
3
|
import '@dudousxd/nestjs-agent-core';
|
|
4
4
|
import 'express';
|
|
5
5
|
import '@dudousxd/nestjs-agent-core/genui';
|
package/dist/a2ui/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export * from '@dudousxd/nestjs-agent-core/a2ui';
|
|
2
|
-
export { b as A2uiAdapterOptions, c as A2uiRunHandler, i as a2uiAdapter } from '../index-
|
|
2
|
+
export { b as A2uiAdapterOptions, c as A2uiRunHandler, i as a2uiAdapter } from '../index-De98CGXa.js';
|
|
3
3
|
import '@dudousxd/nestjs-agent-core';
|
|
4
4
|
import 'express';
|
|
5
5
|
import '@dudousxd/nestjs-agent-core/genui';
|
package/dist/durable/index.cjs
CHANGED
|
@@ -646,6 +646,18 @@ var AgentRunWorkflow = class _AgentRunWorkflow {
|
|
|
646
646
|
];
|
|
647
647
|
const hooks = {
|
|
648
648
|
runId: ctx.runId,
|
|
649
|
+
// The runtime's own enqueue stamp: the run row's `createdAt` is written when the run is
|
|
650
|
+
// started (a send, a parent's `ctx.child`, the queue's `ctx.startChild`), so now − createdAt,
|
|
651
|
+
// read on the body's first execution (inside `persist:run:start`), is how long it waited for a
|
|
652
|
+
// worker. The clocks are the enqueuing process's and the worker's.
|
|
653
|
+
queueMs: /* @__PURE__ */ __name(async () => {
|
|
654
|
+
const runs = this.runs;
|
|
655
|
+
const run = typeof runs?.getRun === "function" ? await runs.getRun(ctx.runId) : (await runs?.getRunDetail(ctx.runId))?.run;
|
|
656
|
+
const createdAt = run?.createdAt;
|
|
657
|
+
if (createdAt === void 0) return void 0;
|
|
658
|
+
const at = new Date(createdAt).getTime();
|
|
659
|
+
return Number.isFinite(at) ? Date.now() - at : void 0;
|
|
660
|
+
}, "queueMs"),
|
|
649
661
|
// A child forwards into the top-level sink but must not end/fail it (the top-level run owns it).
|
|
650
662
|
// A thread's own turn hands the thread to its queue just before the loop ends the stream, so
|
|
651
663
|
// the reader learns what runs next from the `queue` frame, before the end.
|
|
@@ -816,6 +828,7 @@ var AgentRunWorkflow = class _AgentRunWorkflow {
|
|
|
816
828
|
const timed = durationMs !== void 0 ? {
|
|
817
829
|
durationMs
|
|
818
830
|
} : {};
|
|
831
|
+
const measured = (0, import_nestjs_agent_core4.runEndTimings)(error);
|
|
819
832
|
if ((0, import_nestjs_agent_core4.isReplayIntegrityError)(error)) {
|
|
820
833
|
const detail = error.message;
|
|
821
834
|
const code2 = (0, import_nestjs_agent_core4.agentFailureCode)(error);
|
|
@@ -826,6 +839,7 @@ var AgentRunWorkflow = class _AgentRunWorkflow {
|
|
|
826
839
|
code: code2,
|
|
827
840
|
message: detail,
|
|
828
841
|
...timed,
|
|
842
|
+
...measured,
|
|
829
843
|
context: (0, import_nestjs_agent_core4.agentRunContext)(input)
|
|
830
844
|
});
|
|
831
845
|
await (0, import_nestjs_agent_core4.settleDeadRun)(this.store, {
|
|
@@ -849,6 +863,7 @@ var AgentRunWorkflow = class _AgentRunWorkflow {
|
|
|
849
863
|
code,
|
|
850
864
|
message,
|
|
851
865
|
...timed,
|
|
866
|
+
...measured,
|
|
852
867
|
context: (0, import_nestjs_agent_core4.agentRunContext)(input)
|
|
853
868
|
});
|
|
854
869
|
await stepOf(ctx)("persist:run:fail", async () => {
|
|
@@ -3014,6 +3029,7 @@ function _ts_param7(paramIndex, decorator) {
|
|
|
3014
3029
|
};
|
|
3015
3030
|
}
|
|
3016
3031
|
__name(_ts_param7, "_ts_param");
|
|
3032
|
+
var usageLogger = new import_common10.Logger("AgentService");
|
|
3017
3033
|
var NO_USER_MESSAGE_CODE = "no_user_message";
|
|
3018
3034
|
function sendableParams(params) {
|
|
3019
3035
|
const message = params.message;
|
|
@@ -3841,9 +3857,28 @@ var AgentService = class {
|
|
|
3841
3857
|
await this.assertOwnsThread(actor, threadId);
|
|
3842
3858
|
return this.store.softDeleteThread(threadId);
|
|
3843
3859
|
}
|
|
3844
|
-
|
|
3845
|
-
|
|
3846
|
-
|
|
3860
|
+
/**
|
|
3861
|
+
* Copy a thread up to `fromMessageId` (inclusive) into a new one. By default only the thread's
|
|
3862
|
+
* owner may, and the copy is theirs. With `params.authorized`, the host has vouched for `actor`
|
|
3863
|
+
* (a share link it checked) and the copy is `actor`'s — see {@link ForkThreadParams}.
|
|
3864
|
+
*/
|
|
3865
|
+
async forkThread(actor, threadId, fromMessageId, params = {}) {
|
|
3866
|
+
if (params.authorized === true) {
|
|
3867
|
+
if (await this.store.ownerOfThread(threadId) === null) {
|
|
3868
|
+
throw new import_common10.NotFoundException(`thread ${threadId} not found`);
|
|
3869
|
+
}
|
|
3870
|
+
} else {
|
|
3871
|
+
await this.assertOwnsThread(actor, threadId);
|
|
3872
|
+
}
|
|
3873
|
+
const options = {
|
|
3874
|
+
...params.authorized === true ? {
|
|
3875
|
+
actorRef: actor.id
|
|
3876
|
+
} : {},
|
|
3877
|
+
...params.tenantRef !== void 0 ? {
|
|
3878
|
+
tenantRef: params.tenantRef
|
|
3879
|
+
} : {}
|
|
3880
|
+
};
|
|
3881
|
+
return this.store.forkThread(threadId, fromMessageId, options);
|
|
3847
3882
|
}
|
|
3848
3883
|
/** Kept for source compatibility — a thin wrapper over the more general `updateThread`. */
|
|
3849
3884
|
async renameThread(actor, threadId, title) {
|
|
@@ -4238,6 +4273,31 @@ var AgentService = class {
|
|
|
4238
4273
|
throw new import_common10.ForbiddenException("run belongs to another actor");
|
|
4239
4274
|
}
|
|
4240
4275
|
}
|
|
4276
|
+
/**
|
|
4277
|
+
* Record AI spend that did not come from an agent turn — a transcription, a TTS render, a batch of
|
|
4278
|
+
* embeddings, a direct OpenAI/OpenRouter SDK call — on the same ledger the agent's turns write, so
|
|
4279
|
+
* cost, quota and the dashboard see one figure.
|
|
4280
|
+
*
|
|
4281
|
+
* Never throws into the caller's flow by default: a failed write or an invalid input is logged and
|
|
4282
|
+
* answered with `{ recorded: false, error }`. Pass `{ throwOnError: true }` where losing the row
|
|
4283
|
+
* must fail the caller.
|
|
4284
|
+
*
|
|
4285
|
+
* Counted against `actorRef` like an agent turn: the ledger is the budget (`LedgerQuotaProvider`),
|
|
4286
|
+
* so its tokens count in the token windows (a row with no tokens adds 0 there) and its `costUsd` in
|
|
4287
|
+
* the USD windows. A `QuotaStore` counter is bumped only where loop deps carry one (`AgentModule`
|
|
4288
|
+
* wires none). `actorRef: null` is platform cost, recorded under `PLATFORM_ACTOR_REF` and counted
|
|
4289
|
+
* against nobody.
|
|
4290
|
+
*/
|
|
4291
|
+
recordUsage(input, options = {}) {
|
|
4292
|
+
return (0, import_nestjs_agent_core16.recordAiUsage)({
|
|
4293
|
+
store: this.store,
|
|
4294
|
+
quota: this.deps.forAgent().quota,
|
|
4295
|
+
day: utcDay(),
|
|
4296
|
+
input,
|
|
4297
|
+
options,
|
|
4298
|
+
warn: /* @__PURE__ */ __name((message) => usageLogger.warn(message), "warn")
|
|
4299
|
+
});
|
|
4300
|
+
}
|
|
4241
4301
|
};
|
|
4242
4302
|
AgentService = _ts_decorate9([
|
|
4243
4303
|
(0, import_common10.Injectable)(),
|
|
@@ -7218,10 +7278,12 @@ var InlineAgentRunner = class _InlineAgentRunner {
|
|
|
7218
7278
|
}
|
|
7219
7279
|
async start(input, options = {}) {
|
|
7220
7280
|
const runId = options.runId ?? crypto.randomUUID();
|
|
7281
|
+
const acceptedAt = Date.now();
|
|
7221
7282
|
const day = input.day ?? utcDay();
|
|
7222
7283
|
const deps = this.factory.forAgent(input.agentName);
|
|
7223
7284
|
this.live.add(runId);
|
|
7224
7285
|
const hooks = this.topLevelHooks({
|
|
7286
|
+
acceptedAt,
|
|
7225
7287
|
runId,
|
|
7226
7288
|
deps,
|
|
7227
7289
|
actor: input.actor,
|
|
@@ -7243,8 +7305,9 @@ var InlineAgentRunner = class _InlineAgentRunner {
|
|
|
7243
7305
|
const timed = durationMs !== void 0 ? {
|
|
7244
7306
|
durationMs
|
|
7245
7307
|
} : {};
|
|
7308
|
+
const measured = (0, import_nestjs_agent_core38.runEndTimings)(error);
|
|
7246
7309
|
if (error instanceof import_nestjs_agent_core38.RunCancelledError) {
|
|
7247
|
-
await this.settleCancelled(runId, input, deps, durationMs);
|
|
7310
|
+
await this.settleCancelled(runId, input, deps, durationMs, measured);
|
|
7248
7311
|
return;
|
|
7249
7312
|
}
|
|
7250
7313
|
const message = error instanceof Error ? error.message : String(error);
|
|
@@ -7256,6 +7319,7 @@ var InlineAgentRunner = class _InlineAgentRunner {
|
|
|
7256
7319
|
code,
|
|
7257
7320
|
message,
|
|
7258
7321
|
...timed,
|
|
7322
|
+
...measured,
|
|
7259
7323
|
context: (0, import_nestjs_agent_core38.agentRunContext)(input)
|
|
7260
7324
|
});
|
|
7261
7325
|
await this.store.recordRunEnd?.({
|
|
@@ -7333,7 +7397,7 @@ var InlineAgentRunner = class _InlineAgentRunner {
|
|
|
7333
7397
|
* the stream ENDED after a `cancelled` frame rather than failed, so a client that retries failed
|
|
7334
7398
|
* streams does not retry this one.
|
|
7335
7399
|
*/
|
|
7336
|
-
async settleCancelled(runId, input, deps, durationMs) {
|
|
7400
|
+
async settleCancelled(runId, input, deps, durationMs, measured = {}) {
|
|
7337
7401
|
this.logger.log(`agent run ${runId} cancelled`);
|
|
7338
7402
|
const timed = durationMs !== void 0 ? {
|
|
7339
7403
|
durationMs
|
|
@@ -7342,6 +7406,7 @@ var InlineAgentRunner = class _InlineAgentRunner {
|
|
|
7342
7406
|
runId,
|
|
7343
7407
|
threadId: input.threadId,
|
|
7344
7408
|
...timed,
|
|
7409
|
+
...measured,
|
|
7345
7410
|
context: (0, import_nestjs_agent_core38.agentRunContext)(input)
|
|
7346
7411
|
});
|
|
7347
7412
|
const writer = await deps.sink.open(runId);
|
|
@@ -7434,9 +7499,10 @@ var InlineAgentRunner = class _InlineAgentRunner {
|
|
|
7434
7499
|
});
|
|
7435
7500
|
}
|
|
7436
7501
|
topLevelHooks(args) {
|
|
7437
|
-
const { runId, deps, actor, day, threadId, chainBelow, input } = args;
|
|
7502
|
+
const { runId, deps, actor, day, threadId, chainBelow, input, acceptedAt } = args;
|
|
7438
7503
|
return {
|
|
7439
7504
|
runId,
|
|
7505
|
+
queueMs: /* @__PURE__ */ __name(() => Date.now() - acceptedAt, "queueMs"),
|
|
7440
7506
|
// The loop ends the stream when the turn completes. Just before, the thread passes to the next
|
|
7441
7507
|
// queued message (or is released), and the reader is told which — so by the time a client
|
|
7442
7508
|
// sees the run end, the thread is already free or already running what it queued.
|
|
@@ -7561,10 +7627,12 @@ var InlineAgentRunner = class _InlineAgentRunner {
|
|
|
7561
7627
|
const timed = durationMs !== void 0 ? {
|
|
7562
7628
|
durationMs
|
|
7563
7629
|
} : {};
|
|
7630
|
+
const measured = (0, import_nestjs_agent_core38.runEndTimings)(error);
|
|
7564
7631
|
const settled = {
|
|
7565
7632
|
runId,
|
|
7566
7633
|
threadId: subThread.id,
|
|
7567
7634
|
...timed,
|
|
7635
|
+
...measured,
|
|
7568
7636
|
context: (0, import_nestjs_agent_core38.agentRunContext)(childInput)
|
|
7569
7637
|
};
|
|
7570
7638
|
if (cancelled) {
|