@dudousxd/nestjs-agent 1.12.1 → 1.13.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/index.cjs CHANGED
@@ -483,8 +483,22 @@ var AgentService = class {
483
483
  }
484
484
  return entry.id;
485
485
  }
486
- /** The model a turn runs on: the send's own, else the thread's pinned one, else none. */
486
+ /**
487
+ * The model a turn runs on: the send's own (that turn only — it is never stored on the thread),
488
+ * else the thread's pinned one, else none. An agent the catalog locks to one model runs on it
489
+ * whatever was sent or pinned, and a send naming another model is refused.
490
+ */
487
491
  async resolveModel(actor, agent, requested, threadId) {
492
+ const locked = this.models !== void 0 ? (await this.models.list({
493
+ actor,
494
+ agent
495
+ })).locked : void 0;
496
+ if (locked !== void 0) {
497
+ if (requested !== void 0 && requested !== locked.model) {
498
+ throw new import_common2.BadRequestException(`model "${requested}" cannot be selected: ${locked.reason ?? `this agent always uses "${locked.model}"`}`);
499
+ }
500
+ return locked.model;
501
+ }
488
502
  const model = requested ?? (threadId !== void 0 ? await this.threadModel(threadId) : null);
489
503
  if (model === null || model === void 0) {
490
504
  return void 0;
@@ -633,12 +647,15 @@ var AgentService = class {
633
647
  * "the user picked exactly the defaults" persist as the same answers, and no client has to
634
648
  * re-send what it was shown.
635
649
  */
636
- async answer(actor, toolCallId2, answers2 = {}) {
650
+ async answer(actor, toolCallId2, answers2 = {}, opts = {}) {
637
651
  await this.assertOwnsToolCall(actor, toolCallId2);
638
652
  await this.assertAnswersFit(toolCallId2, answers2);
639
653
  const reply = {
640
654
  answers: answers2,
641
- answeredByRef: actor.id
655
+ answeredByRef: actor.id,
656
+ ...opts.via !== void 0 ? {
657
+ answeredVia: opts.via
658
+ } : {}
642
659
  };
643
660
  return this.signalToolCall(toolCallId2, reply);
644
661
  }
@@ -647,12 +664,15 @@ var AgentService = class {
647
664
  * them: the run records this as a rejection, so a reader auditing what the agent was told can
648
665
  * tell a choice the user made from one they refused to make.
649
666
  */
650
- async skip(actor, toolCallId2) {
667
+ async skip(actor, toolCallId2, opts = {}) {
651
668
  await this.assertOwnsToolCall(actor, toolCallId2);
652
669
  const reply = {
653
670
  answers: {},
654
671
  skipped: true,
655
- answeredByRef: actor.id
672
+ answeredByRef: actor.id,
673
+ ...opts.via !== void 0 ? {
674
+ answeredVia: opts.via
675
+ } : {}
656
676
  };
657
677
  return this.signalToolCall(toolCallId2, reply);
658
678
  }
@@ -2514,7 +2534,9 @@ var ToolCallController = class {
2514
2534
  */
2515
2535
  async answer(req, body) {
2516
2536
  const actor = await this.actorResolver.resolve(req);
2517
- await this.agent.answer(actor, toolCallId(body.toolCallId), answers(body.answers));
2537
+ await this.agent.answer(actor, toolCallId(body.toolCallId), answers(body.answers), {
2538
+ via: via(body.via)
2539
+ });
2518
2540
  return {
2519
2541
  ok: true
2520
2542
  };
@@ -2522,7 +2544,9 @@ var ToolCallController = class {
2522
2544
  /** Decline to answer and let the agent proceed on the answers it pre-picked. */
2523
2545
  async skip(req, body) {
2524
2546
  const actor = await this.actorResolver.resolve(req);
2525
- await this.agent.skip(actor, toolCallId(body.toolCallId));
2547
+ await this.agent.skip(actor, toolCallId(body.toolCallId), {
2548
+ via: via(body.via)
2549
+ });
2526
2550
  return {
2527
2551
  ok: true
2528
2552
  };
@@ -3301,9 +3325,11 @@ var LedgerQuotaProvider = class {
3301
3325
  }
3302
3326
  store;
3303
3327
  limits;
3304
- constructor(store, limits = {}) {
3328
+ options;
3329
+ constructor(store, limits = {}, options = {}) {
3305
3330
  this.store = store;
3306
3331
  this.limits = limits;
3332
+ this.options = options;
3307
3333
  }
3308
3334
  async report(query) {
3309
3335
  const now = query.now ?? /* @__PURE__ */ new Date();
@@ -3317,10 +3343,14 @@ var LedgerQuotaProvider = class {
3317
3343
  windows.push(this.window("month", used.usedTokens, used.costUsd, range.resetsAt));
3318
3344
  }
3319
3345
  const blocked = (0, import_nestjs_agent_core21.exhaustedWindow)(windows);
3346
+ const warning = (0, import_nestjs_agent_core21.quotaWarning)(windows);
3320
3347
  return {
3321
3348
  windows,
3322
3349
  ...blocked !== void 0 ? {
3323
3350
  blocked
3351
+ } : {},
3352
+ ...warning !== void 0 ? {
3353
+ warning
3324
3354
  } : {}
3325
3355
  };
3326
3356
  }
@@ -3341,7 +3371,10 @@ var LedgerQuotaProvider = class {
3341
3371
  ...limits.usd !== void 0 ? {
3342
3372
  limitUsd: limits.usd
3343
3373
  } : {},
3344
- resetsAt
3374
+ resetsAt,
3375
+ ...this.options.warnAt !== void 0 && (limits.tokens !== void 0 || limits.usd !== void 0) ? {
3376
+ warnAt: this.options.warnAt
3377
+ } : {}
3345
3378
  };
3346
3379
  }
3347
3380
  };
@@ -3946,7 +3979,9 @@ function sharedProviders(durable) {
3946
3979
  // `quota` is either a provider of the host's own or ceilings for the built-in ledger one;
3947
3980
  // omitted, the ledger provider still reports usage, with no ceiling to block on.
3948
3981
  provide: import_nestjs_agent_core24.AGENT_QUOTA_PROVIDER,
3949
- useFactory: /* @__PURE__ */ __name((o, store) => isQuotaProvider(o.quota) ? o.quota : new LedgerQuotaProvider(store, o.quota?.limits), "useFactory"),
3982
+ useFactory: /* @__PURE__ */ __name((o, store) => isQuotaProvider(o.quota) ? o.quota : new LedgerQuotaProvider(store, o.quota?.limits, o.quota?.warnAt !== void 0 ? {
3983
+ warnAt: o.quota.warnAt
3984
+ } : {}), "useFactory"),
3950
3985
  inject: [
3951
3986
  import_nestjs_agent_core24.AGENT_OPTIONS,
3952
3987
  import_nestjs_agent_core24.AGENT_STORE