@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.
@@ -69,7 +69,7 @@ var init_kit = __esm({
69
69
  });
70
70
 
71
71
  // src/durable/agent-run.workflow.ts
72
- import { AGENT_DEPS_FACTORY as AGENT_DEPS_FACTORY2, AGENT_STORE, RUN_ENDED_BEFORE_TOOL_CALL, RunCancelledError, agentFailureCode, agentRunContext, encodeStreamEvent as encodeStreamEvent2, isReplayIntegrityError as isReplayIntegrityError2, publishAgentRunFailed, releaseThreadRun, runAgentLoop, runDurationMs, settleAll, settleDeadRun, settleUnsettledDelegation, streamFailure } from "@dudousxd/nestjs-agent-core";
72
+ import { AGENT_DEPS_FACTORY as AGENT_DEPS_FACTORY2, AGENT_STORE, RUN_ENDED_BEFORE_TOOL_CALL, RunCancelledError, agentFailureCode, agentRunContext, encodeStreamEvent as encodeStreamEvent2, isReplayIntegrityError as isReplayIntegrityError2, publishAgentRunFailed, releaseThreadRun, runAgentLoop, runDurationMs, runEndTimings, settleAll, settleDeadRun, settleUnsettledDelegation, streamFailure } from "@dudousxd/nestjs-agent-core";
73
73
  import { RUN_GATEWAY, Workflow, WorkflowService } from "@dudousxd/nestjs-durable";
74
74
  import { isWorkflowControlFlowSignal } from "@dudousxd/nestjs-durable-core";
75
75
  import { Inject as Inject2, Injectable as Injectable2, Logger, Optional } from "@nestjs/common";
@@ -613,6 +613,18 @@ var AgentRunWorkflow = class _AgentRunWorkflow {
613
613
  ];
614
614
  const hooks = {
615
615
  runId: ctx.runId,
616
+ // The runtime's own enqueue stamp: the run row's `createdAt` is written when the run is
617
+ // started (a send, a parent's `ctx.child`, the queue's `ctx.startChild`), so now − createdAt,
618
+ // read on the body's first execution (inside `persist:run:start`), is how long it waited for a
619
+ // worker. The clocks are the enqueuing process's and the worker's.
620
+ queueMs: /* @__PURE__ */ __name(async () => {
621
+ const runs = this.runs;
622
+ const run = typeof runs?.getRun === "function" ? await runs.getRun(ctx.runId) : (await runs?.getRunDetail(ctx.runId))?.run;
623
+ const createdAt = run?.createdAt;
624
+ if (createdAt === void 0) return void 0;
625
+ const at = new Date(createdAt).getTime();
626
+ return Number.isFinite(at) ? Date.now() - at : void 0;
627
+ }, "queueMs"),
616
628
  // A child forwards into the top-level sink but must not end/fail it (the top-level run owns it).
617
629
  // A thread's own turn hands the thread to its queue just before the loop ends the stream, so
618
630
  // the reader learns what runs next from the `queue` frame, before the end.
@@ -783,6 +795,7 @@ var AgentRunWorkflow = class _AgentRunWorkflow {
783
795
  const timed = durationMs !== void 0 ? {
784
796
  durationMs
785
797
  } : {};
798
+ const measured = runEndTimings(error);
786
799
  if (isReplayIntegrityError2(error)) {
787
800
  const detail = error.message;
788
801
  const code2 = agentFailureCode(error);
@@ -793,6 +806,7 @@ var AgentRunWorkflow = class _AgentRunWorkflow {
793
806
  code: code2,
794
807
  message: detail,
795
808
  ...timed,
809
+ ...measured,
796
810
  context: agentRunContext(input)
797
811
  });
798
812
  await settleDeadRun(this.store, {
@@ -816,6 +830,7 @@ var AgentRunWorkflow = class _AgentRunWorkflow {
816
830
  code,
817
831
  message,
818
832
  ...timed,
833
+ ...measured,
819
834
  context: agentRunContext(input)
820
835
  });
821
836
  await stepOf(ctx)("persist:run:fail", async () => {
@@ -1458,7 +1473,7 @@ AgentDurableModule = _ts_decorate4([
1458
1473
 
1459
1474
  // src/agent.module.ts
1460
1475
  import { AGENT_ACTOR_RESOLVER as AGENT_ACTOR_RESOLVER14, AGENT_APPROVAL_PORT, AGENT_DEPS_FACTORY as AGENT_DEPS_FACTORY9, AGENT_DURABLE_RUNNER as AGENT_DURABLE_RUNNER2, AGENT_MEMORY as AGENT_MEMORY3, AGENT_MODEL as AGENT_MODEL3, AGENT_MODEL_CATALOG as AGENT_MODEL_CATALOG3, AGENT_OPTIONS as AGENT_OPTIONS10, AGENT_PROMPT_CONTRIBUTORS as AGENT_PROMPT_CONTRIBUTORS3, AGENT_QUOTA_PROVIDER as AGENT_QUOTA_PROVIDER3, AGENT_REGISTRY as AGENT_REGISTRY6, AGENT_ROLES_POLICY as AGENT_ROLES_POLICY2, AGENT_RUNNER as AGENT_RUNNER2, AGENT_SINK as AGENT_SINK4, AGENT_SKILLS as AGENT_SKILLS3, AGENT_SKILL_SOURCES as AGENT_SKILL_SOURCES2, AGENT_STORE as AGENT_STORE9, AGENT_TOOL_REGISTRY as AGENT_TOOL_REGISTRY3, AgentRegistry as AgentRegistry6, ClosedRolesPolicy, DefaultRolesPolicy, InMemoryAgentStore, ToolRegistry as ToolRegistry3, personalAgentGate, personalAgentScopes } from "@dudousxd/nestjs-agent-core";
1461
- import { Global as Global2, Logger as Logger10, Module as Module3 } from "@nestjs/common";
1476
+ import { Global as Global2, Logger as Logger11, Module as Module3 } from "@nestjs/common";
1462
1477
  import { DiscoveryModule, ModulesContainer, RouterModule } from "@nestjs/core";
1463
1478
 
1464
1479
  // src/agent-deps.factory.ts
@@ -2179,8 +2194,8 @@ AgentDepsFactory2 = _ts_decorate6([
2179
2194
  var AGENT_SERVICE = /* @__PURE__ */ Symbol.for("@dudousxd/nestjs-agent:agent-service");
2180
2195
 
2181
2196
  // src/agent.service.ts
2182
- import { AGENT_ATTACHMENT_STAGING as AGENT_ATTACHMENT_STAGING2, AGENT_DEPS_FACTORY as AGENT_DEPS_FACTORY4, AGENT_MODEL_CATALOG, AGENT_OPTIONS as AGENT_OPTIONS4, AGENT_QUOTA_PROVIDER as AGENT_QUOTA_PROVIDER2, AGENT_RUNNER, AGENT_STORE as AGENT_STORE6, DEFAULT_TEXT_ACTION_PROPOSAL_VOCABULARY as DEFAULT_TEXT_ACTION_PROPOSAL_VOCABULARY2, REQUESTER_APPROVER, findCatalogModel, mayDecideApproval as mayDecideApproval2, readElicitationQuestions, settleDeadRun as settleDeadRun2, textActionProposalReply as textActionProposalReply2, validateElicitationAnswer } from "@dudousxd/nestjs-agent-core";
2183
- import { BadRequestException as BadRequestException2, ConflictException as ConflictException2, ForbiddenException as ForbiddenException2, GoneException, HttpException, HttpStatus, Inject as Inject8, Injectable as Injectable7, NotFoundException as NotFoundException2, NotImplementedException as NotImplementedException3, Optional as Optional5, PayloadTooLargeException, UnsupportedMediaTypeException } from "@nestjs/common";
2197
+ import { AGENT_ATTACHMENT_STAGING as AGENT_ATTACHMENT_STAGING2, AGENT_DEPS_FACTORY as AGENT_DEPS_FACTORY4, AGENT_MODEL_CATALOG, AGENT_OPTIONS as AGENT_OPTIONS4, AGENT_QUOTA_PROVIDER as AGENT_QUOTA_PROVIDER2, AGENT_RUNNER, AGENT_STORE as AGENT_STORE6, DEFAULT_TEXT_ACTION_PROPOSAL_VOCABULARY as DEFAULT_TEXT_ACTION_PROPOSAL_VOCABULARY2, REQUESTER_APPROVER, findCatalogModel, mayDecideApproval as mayDecideApproval2, readElicitationQuestions, recordAiUsage, settleDeadRun as settleDeadRun2, textActionProposalReply as textActionProposalReply2, validateElicitationAnswer } from "@dudousxd/nestjs-agent-core";
2198
+ import { BadRequestException as BadRequestException2, ConflictException as ConflictException2, ForbiddenException as ForbiddenException2, GoneException, HttpException, HttpStatus, Inject as Inject8, Injectable as Injectable7, Logger as Logger4, NotFoundException as NotFoundException2, NotImplementedException as NotImplementedException3, Optional as Optional5, PayloadTooLargeException, UnsupportedMediaTypeException } from "@nestjs/common";
2184
2199
 
2185
2200
  // src/attachment-limits.ts
2186
2201
  var DEFAULT_MAX_ATTACHMENT_BYTES = 20 * 1024 * 1024;
@@ -2981,6 +2996,7 @@ function _ts_param7(paramIndex, decorator) {
2981
2996
  };
2982
2997
  }
2983
2998
  __name(_ts_param7, "_ts_param");
2999
+ var usageLogger = new Logger4("AgentService");
2984
3000
  var NO_USER_MESSAGE_CODE = "no_user_message";
2985
3001
  function sendableParams(params) {
2986
3002
  const message = params.message;
@@ -3808,9 +3824,28 @@ var AgentService = class {
3808
3824
  await this.assertOwnsThread(actor, threadId);
3809
3825
  return this.store.softDeleteThread(threadId);
3810
3826
  }
3811
- async forkThread(actor, threadId, fromMessageId) {
3812
- await this.assertOwnsThread(actor, threadId);
3813
- return this.store.forkThread(threadId, fromMessageId);
3827
+ /**
3828
+ * Copy a thread up to `fromMessageId` (inclusive) into a new one. By default only the thread's
3829
+ * owner may, and the copy is theirs. With `params.authorized`, the host has vouched for `actor`
3830
+ * (a share link it checked) and the copy is `actor`'s — see {@link ForkThreadParams}.
3831
+ */
3832
+ async forkThread(actor, threadId, fromMessageId, params = {}) {
3833
+ if (params.authorized === true) {
3834
+ if (await this.store.ownerOfThread(threadId) === null) {
3835
+ throw new NotFoundException2(`thread ${threadId} not found`);
3836
+ }
3837
+ } else {
3838
+ await this.assertOwnsThread(actor, threadId);
3839
+ }
3840
+ const options = {
3841
+ ...params.authorized === true ? {
3842
+ actorRef: actor.id
3843
+ } : {},
3844
+ ...params.tenantRef !== void 0 ? {
3845
+ tenantRef: params.tenantRef
3846
+ } : {}
3847
+ };
3848
+ return this.store.forkThread(threadId, fromMessageId, options);
3814
3849
  }
3815
3850
  /** Kept for source compatibility — a thin wrapper over the more general `updateThread`. */
3816
3851
  async renameThread(actor, threadId, title) {
@@ -4205,6 +4240,31 @@ var AgentService = class {
4205
4240
  throw new ForbiddenException2("run belongs to another actor");
4206
4241
  }
4207
4242
  }
4243
+ /**
4244
+ * Record AI spend that did not come from an agent turn — a transcription, a TTS render, a batch of
4245
+ * embeddings, a direct OpenAI/OpenRouter SDK call — on the same ledger the agent's turns write, so
4246
+ * cost, quota and the dashboard see one figure.
4247
+ *
4248
+ * Never throws into the caller's flow by default: a failed write or an invalid input is logged and
4249
+ * answered with `{ recorded: false, error }`. Pass `{ throwOnError: true }` where losing the row
4250
+ * must fail the caller.
4251
+ *
4252
+ * Counted against `actorRef` like an agent turn: the ledger is the budget (`LedgerQuotaProvider`),
4253
+ * so its tokens count in the token windows (a row with no tokens adds 0 there) and its `costUsd` in
4254
+ * the USD windows. A `QuotaStore` counter is bumped only where loop deps carry one (`AgentModule`
4255
+ * wires none). `actorRef: null` is platform cost, recorded under `PLATFORM_ACTOR_REF` and counted
4256
+ * against nobody.
4257
+ */
4258
+ recordUsage(input, options = {}) {
4259
+ return recordAiUsage({
4260
+ store: this.store,
4261
+ quota: this.deps.forAgent().quota,
4262
+ day: utcDay(),
4263
+ input,
4264
+ options,
4265
+ warn: /* @__PURE__ */ __name((message) => usageLogger.warn(message), "warn")
4266
+ });
4267
+ }
4208
4268
  };
4209
4269
  AgentService = _ts_decorate9([
4210
4270
  Injectable7(),
@@ -6111,7 +6171,7 @@ ToolsController = _ts_decorate23([
6111
6171
 
6112
6172
  // src/discovery/agent-discovery.service.ts
6113
6173
  import { AGENT_PROMPT_CONTRIBUTORS as AGENT_PROMPT_CONTRIBUTORS2, AGENT_REGISTRY as AGENT_REGISTRY4, AgentRegistry as AgentRegistry5 } from "@dudousxd/nestjs-agent-core";
6114
- import { Inject as Inject22, Injectable as Injectable9, Logger as Logger4 } from "@nestjs/common";
6174
+ import { Inject as Inject22, Injectable as Injectable9, Logger as Logger5 } from "@nestjs/common";
6115
6175
  import { DiscoveryService, MetadataScanner } from "@nestjs/core";
6116
6176
 
6117
6177
  // src/decorator/agent.decorator.ts
@@ -6162,7 +6222,7 @@ var AgentDiscoveryService = class _AgentDiscoveryService {
6162
6222
  scanner;
6163
6223
  registry;
6164
6224
  contributors;
6165
- logger = new Logger4(_AgentDiscoveryService.name);
6225
+ logger = new Logger5(_AgentDiscoveryService.name);
6166
6226
  constructor(discovery, scanner, registry, contributors) {
6167
6227
  this.discovery = discovery;
6168
6228
  this.scanner = scanner;
@@ -6344,7 +6404,7 @@ AgentDiscoveryService = _ts_decorate24([
6344
6404
 
6345
6405
  // src/discovery/ai-tool-discovery.service.ts
6346
6406
  import { AGENT_OPTIONS as AGENT_OPTIONS7, AGENT_REGISTRY as AGENT_REGISTRY5, AGENT_TOOL_REGISTRY as AGENT_TOOL_REGISTRY2, normalizeDelegation as normalizeDelegation2 } from "@dudousxd/nestjs-agent-core";
6347
- import { Inject as Inject23, Injectable as Injectable10, Logger as Logger5 } from "@nestjs/common";
6407
+ import { Inject as Inject23, Injectable as Injectable10, Logger as Logger6 } from "@nestjs/common";
6348
6408
  import { DiscoveryService as DiscoveryService2 } from "@nestjs/core";
6349
6409
  import { z } from "zod";
6350
6410
 
@@ -6391,7 +6451,7 @@ var AiToolDiscoveryService = class _AiToolDiscoveryService {
6391
6451
  registry;
6392
6452
  agents;
6393
6453
  options;
6394
- logger = new Logger5(_AiToolDiscoveryService.name);
6454
+ logger = new Logger6(_AiToolDiscoveryService.name);
6395
6455
  constructor(discovery, registry, agents, options) {
6396
6456
  this.discovery = discovery;
6397
6457
  this.registry = registry;
@@ -6557,7 +6617,7 @@ AiToolDiscoveryService = _ts_decorate25([
6557
6617
 
6558
6618
  // src/discovery/skill-discovery.service.ts
6559
6619
  import { AGENT_SKILL_SOURCES } from "@dudousxd/nestjs-agent-core";
6560
- import { Inject as Inject24, Injectable as Injectable11, Logger as Logger6 } from "@nestjs/common";
6620
+ import { Inject as Inject24, Injectable as Injectable11, Logger as Logger7 } from "@nestjs/common";
6561
6621
  import { DiscoveryService as DiscoveryService3 } from "@nestjs/core";
6562
6622
 
6563
6623
  // src/decorator/skill.decorator.ts
@@ -6606,7 +6666,7 @@ var SkillDiscoveryService = class _SkillDiscoveryService {
6606
6666
  }
6607
6667
  discovery;
6608
6668
  declared;
6609
- logger = new Logger6(_SkillDiscoveryService.name);
6669
+ logger = new Logger7(_SkillDiscoveryService.name);
6610
6670
  constructor(discovery, declared) {
6611
6671
  this.discovery = discovery;
6612
6672
  this.declared = declared;
@@ -6731,7 +6791,7 @@ var LedgerQuotaProvider = class {
6731
6791
 
6732
6792
  // src/pricing-boot.service.ts
6733
6793
  import { AGENT_MODEL as AGENT_MODEL2, AGENT_OPTIONS as AGENT_OPTIONS8, AGENT_PRICING_STORE as AGENT_PRICING_STORE2, ensureModelPricing } from "@dudousxd/nestjs-agent-core";
6734
- import { Inject as Inject25, Injectable as Injectable12, Logger as Logger7, Optional as Optional11 } from "@nestjs/common";
6794
+ import { Inject as Inject25, Injectable as Injectable12, Logger as Logger8, Optional as Optional11 } from "@nestjs/common";
6735
6795
  function _ts_decorate27(decorators, target, key, desc) {
6736
6796
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
6737
6797
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") {
@@ -6758,7 +6818,7 @@ function _ts_param25(paramIndex, decorator) {
6758
6818
  };
6759
6819
  }
6760
6820
  __name(_ts_param25, "_ts_param");
6761
- var logger = new Logger7("AgentPricing");
6821
+ var logger = new Logger8("AgentPricing");
6762
6822
  var PricingBootService = class {
6763
6823
  static {
6764
6824
  __name(this, "PricingBootService");
@@ -6821,7 +6881,7 @@ PricingBootService = _ts_decorate27([
6821
6881
  // src/proposals/action-proposal-worker.service.ts
6822
6882
  import { randomUUID as randomUUID2 } from "crypto";
6823
6883
  import { AGENT_DEPS_FACTORY as AGENT_DEPS_FACTORY7, AGENT_OPTIONS as AGENT_OPTIONS9, AGENT_STORE as AGENT_STORE7, ActionProposalExecutor, ActionProposalWorker, assertIndependentActionCapabilities as assertIndependentActionCapabilities2 } from "@dudousxd/nestjs-agent-core";
6824
- import { Inject as Inject26, Injectable as Injectable13, Logger as Logger8 } from "@nestjs/common";
6884
+ import { Inject as Inject26, Injectable as Injectable13, Logger as Logger9 } from "@nestjs/common";
6825
6885
  function _ts_decorate28(decorators, target, key, desc) {
6826
6886
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
6827
6887
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") {
@@ -6856,7 +6916,7 @@ var ActionProposalWorkerService = class _ActionProposalWorkerService {
6856
6916
  options;
6857
6917
  deps;
6858
6918
  worker;
6859
- logger = new Logger8(_ActionProposalWorkerService.name);
6919
+ logger = new Logger9(_ActionProposalWorkerService.name);
6860
6920
  settledListeners = /* @__PURE__ */ new Set();
6861
6921
  admittedListeners = /* @__PURE__ */ new Set();
6862
6922
  /**
@@ -7113,8 +7173,8 @@ ActionProposalController = _ts_decorate29([
7113
7173
  ], ActionProposalController);
7114
7174
 
7115
7175
  // src/runner/inline-agent-runner.ts
7116
- import { AGENT_DEPS_FACTORY as AGENT_DEPS_FACTORY8, AGENT_STORE as AGENT_STORE8, RUN_ENDED_BEFORE_TOOL_CALL as RUN_ENDED_BEFORE_TOOL_CALL2, RunCancelledError as RunCancelledError2, agentFailureCode as agentFailureCode2, agentRunContext as agentRunContext2, encodeStreamEvent as encodeStreamEvent5, publishAgentRunCancelled as publishAgentRunCancelled2, publishAgentRunFailed as publishAgentRunFailed2, releaseThreadRun as releaseThreadRun3, runAgentLoop as runAgentLoop2, runDurationMs as runDurationMs2, settleAll as settleAll2, settleUnsettledDelegation as settleUnsettledDelegation3, streamFailure as streamFailure3 } from "@dudousxd/nestjs-agent-core";
7117
- import { Inject as Inject28, Injectable as Injectable14, Logger as Logger9, Optional as Optional12 } from "@nestjs/common";
7176
+ import { AGENT_DEPS_FACTORY as AGENT_DEPS_FACTORY8, AGENT_STORE as AGENT_STORE8, RUN_ENDED_BEFORE_TOOL_CALL as RUN_ENDED_BEFORE_TOOL_CALL2, RunCancelledError as RunCancelledError2, agentFailureCode as agentFailureCode2, agentRunContext as agentRunContext2, encodeStreamEvent as encodeStreamEvent5, publishAgentRunCancelled as publishAgentRunCancelled2, publishAgentRunFailed as publishAgentRunFailed2, releaseThreadRun as releaseThreadRun3, runAgentLoop as runAgentLoop2, runDurationMs as runDurationMs2, runEndTimings as runEndTimings2, settleAll as settleAll2, settleUnsettledDelegation as settleUnsettledDelegation3, streamFailure as streamFailure3 } from "@dudousxd/nestjs-agent-core";
7177
+ import { Inject as Inject28, Injectable as Injectable14, Logger as Logger10, Optional as Optional12 } from "@nestjs/common";
7118
7178
  function _ts_decorate30(decorators, target, key, desc) {
7119
7179
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
7120
7180
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") {
@@ -7148,7 +7208,7 @@ var InlineAgentRunner = class _InlineAgentRunner {
7148
7208
  factory;
7149
7209
  store;
7150
7210
  queue;
7151
- logger = new Logger9(_InlineAgentRunner.name);
7211
+ logger = new Logger10(_InlineAgentRunner.name);
7152
7212
  pending = /* @__PURE__ */ new Map();
7153
7213
  /**
7154
7214
  * Runs someone has asked to stop. In-process, like `pending`, and for the same reason: this runner
@@ -7185,10 +7245,12 @@ var InlineAgentRunner = class _InlineAgentRunner {
7185
7245
  }
7186
7246
  async start(input, options = {}) {
7187
7247
  const runId = options.runId ?? crypto.randomUUID();
7248
+ const acceptedAt = Date.now();
7188
7249
  const day = input.day ?? utcDay();
7189
7250
  const deps = this.factory.forAgent(input.agentName);
7190
7251
  this.live.add(runId);
7191
7252
  const hooks = this.topLevelHooks({
7253
+ acceptedAt,
7192
7254
  runId,
7193
7255
  deps,
7194
7256
  actor: input.actor,
@@ -7210,8 +7272,9 @@ var InlineAgentRunner = class _InlineAgentRunner {
7210
7272
  const timed = durationMs !== void 0 ? {
7211
7273
  durationMs
7212
7274
  } : {};
7275
+ const measured = runEndTimings2(error);
7213
7276
  if (error instanceof RunCancelledError2) {
7214
- await this.settleCancelled(runId, input, deps, durationMs);
7277
+ await this.settleCancelled(runId, input, deps, durationMs, measured);
7215
7278
  return;
7216
7279
  }
7217
7280
  const message = error instanceof Error ? error.message : String(error);
@@ -7223,6 +7286,7 @@ var InlineAgentRunner = class _InlineAgentRunner {
7223
7286
  code,
7224
7287
  message,
7225
7288
  ...timed,
7289
+ ...measured,
7226
7290
  context: agentRunContext2(input)
7227
7291
  });
7228
7292
  await this.store.recordRunEnd?.({
@@ -7300,7 +7364,7 @@ var InlineAgentRunner = class _InlineAgentRunner {
7300
7364
  * the stream ENDED after a `cancelled` frame rather than failed, so a client that retries failed
7301
7365
  * streams does not retry this one.
7302
7366
  */
7303
- async settleCancelled(runId, input, deps, durationMs) {
7367
+ async settleCancelled(runId, input, deps, durationMs, measured = {}) {
7304
7368
  this.logger.log(`agent run ${runId} cancelled`);
7305
7369
  const timed = durationMs !== void 0 ? {
7306
7370
  durationMs
@@ -7309,6 +7373,7 @@ var InlineAgentRunner = class _InlineAgentRunner {
7309
7373
  runId,
7310
7374
  threadId: input.threadId,
7311
7375
  ...timed,
7376
+ ...measured,
7312
7377
  context: agentRunContext2(input)
7313
7378
  });
7314
7379
  const writer = await deps.sink.open(runId);
@@ -7401,9 +7466,10 @@ var InlineAgentRunner = class _InlineAgentRunner {
7401
7466
  });
7402
7467
  }
7403
7468
  topLevelHooks(args) {
7404
- const { runId, deps, actor, day, threadId, chainBelow, input } = args;
7469
+ const { runId, deps, actor, day, threadId, chainBelow, input, acceptedAt } = args;
7405
7470
  return {
7406
7471
  runId,
7472
+ queueMs: /* @__PURE__ */ __name(() => Date.now() - acceptedAt, "queueMs"),
7407
7473
  // The loop ends the stream when the turn completes. Just before, the thread passes to the next
7408
7474
  // queued message (or is released), and the reader is told which — so by the time a client
7409
7475
  // sees the run end, the thread is already free or already running what it queued.
@@ -7528,10 +7594,12 @@ var InlineAgentRunner = class _InlineAgentRunner {
7528
7594
  const timed = durationMs !== void 0 ? {
7529
7595
  durationMs
7530
7596
  } : {};
7597
+ const measured = runEndTimings2(error);
7531
7598
  const settled = {
7532
7599
  runId,
7533
7600
  threadId: subThread.id,
7534
7601
  ...timed,
7602
+ ...measured,
7535
7603
  context: agentRunContext2(childInput)
7536
7604
  };
7537
7605
  if (cancelled) {
@@ -7720,7 +7788,7 @@ function _ts_decorate31(decorators, target, key, desc) {
7720
7788
  }
7721
7789
  __name(_ts_decorate31, "_ts_decorate");
7722
7790
  var DEFAULT_PATH = "agent";
7723
- var logger2 = new Logger10("AgentModule");
7791
+ var logger2 = new Logger11("AgentModule");
7724
7792
  function externalWrapper(modules, token) {
7725
7793
  for (const module of modules.values()) {
7726
7794
  if (module.metatype === AgentModule) continue;