@dudousxd/nestjs-agent 1.22.0 → 1.23.1

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
@@ -1175,6 +1175,9 @@ var ChatQueueService = class _ChatQueueService {
1175
1175
  } : {},
1176
1176
  ...input.uiCapabilities !== void 0 ? {
1177
1177
  uiCapabilities: input.uiCapabilities
1178
+ } : {},
1179
+ ...input.hostContext !== void 0 ? {
1180
+ hostContext: input.hostContext
1178
1181
  } : {}
1179
1182
  });
1180
1183
  await store.setQueuePause(threadId, {
@@ -1260,6 +1263,9 @@ var ChatQueueService = class _ChatQueueService {
1260
1263
  ...message.uiCapabilities !== void 0 ? {
1261
1264
  uiCapabilities: message.uiCapabilities
1262
1265
  } : {},
1266
+ ...message.hostContext !== void 0 ? {
1267
+ hostContext: message.hostContext
1268
+ } : {},
1263
1269
  ...message.model !== void 0 ? {
1264
1270
  model: message.model
1265
1271
  } : {}
@@ -1630,6 +1636,9 @@ var AgentService = class {
1630
1636
  }
1631
1637
  const created = await this.store.createThread({
1632
1638
  actor: params.actor,
1639
+ ...agentName !== void 0 ? {
1640
+ agentName
1641
+ } : {},
1633
1642
  ...params.transient === true ? {
1634
1643
  transient: true
1635
1644
  } : {},
@@ -1642,7 +1651,7 @@ var AgentService = class {
1642
1651
  });
1643
1652
  threadId = created.id;
1644
1653
  } else {
1645
- await this.assertOwnsThread(params.actor, threadId);
1654
+ if (params.authorized !== true) await this.assertOwnsThread(params.actor, threadId);
1646
1655
  if (params.personaId !== void 0) {
1647
1656
  await this.pinThreadPersona(threadId, params.personaId);
1648
1657
  }
@@ -1668,6 +1677,9 @@ var AgentService = class {
1668
1677
  ...params.uiCapabilities !== void 0 ? {
1669
1678
  uiCapabilities: params.uiCapabilities
1670
1679
  } : {},
1680
+ ...params.hostContext !== void 0 ? {
1681
+ hostContext: params.hostContext
1682
+ } : {},
1671
1683
  ...model !== void 0 ? {
1672
1684
  model
1673
1685
  } : {}
@@ -1690,7 +1702,7 @@ var AgentService = class {
1690
1702
  });
1691
1703
  }
1692
1704
  if (live === null && mode !== "queue") {
1693
- const runId = crypto.randomUUID();
1705
+ const runId = this.runner.runIdFor?.(input) ?? crypto.randomUUID();
1694
1706
  if (await queue.queueStore().claimActiveStream(threadId, runId, stale !== null ? {
1695
1707
  replacing: stale
1696
1708
  } : {})) {
@@ -1758,6 +1770,9 @@ var AgentService = class {
1758
1770
  ...input.uiCapabilities !== void 0 ? {
1759
1771
  uiCapabilities: input.uiCapabilities
1760
1772
  } : {},
1773
+ ...input.hostContext !== void 0 ? {
1774
+ hostContext: input.hostContext
1775
+ } : {},
1761
1776
  ...interrupting !== void 0 ? {
1762
1777
  interrupt: true,
1763
1778
  at: "head"
@@ -5969,11 +5984,11 @@ function isQuotaProvider(quota) {
5969
5984
  __name(isQuotaProvider, "isQuotaProvider");
5970
5985
  function resolveCatalog(options) {
5971
5986
  if (options.models !== void 0) return options.models;
5972
- const carried = options.model.catalog;
5987
+ const carried = options.model?.catalog;
5973
5988
  return carried !== void 0 && typeof carried.list === "function" ? carried : void 0;
5974
5989
  }
5975
5990
  __name(resolveCatalog, "resolveCatalog");
5976
- function sharedProviders(durable) {
5991
+ function sharedProviders(durable, engine) {
5977
5992
  const providers = [
5978
5993
  {
5979
5994
  provide: import_nestjs_agent_core33.AGENT_TOOL_REGISTRY,
@@ -6104,7 +6119,12 @@ function sharedProviders(durable) {
6104
6119
  import_core4.ModulesContainer
6105
6120
  ]
6106
6121
  });
6107
- if (durable) {
6122
+ if (engine !== void 0) {
6123
+ providers.push(...engine.providers, {
6124
+ provide: import_nestjs_agent_core33.AGENT_RUNNER,
6125
+ useExisting: engine.runner
6126
+ });
6127
+ } else if (durable) {
6108
6128
  providers.push({
6109
6129
  provide: import_nestjs_agent_core33.AGENT_RUNNER,
6110
6130
  useFactory: /* @__PURE__ */ __name((durableRunner) => {
@@ -6129,8 +6149,9 @@ function sharedProviders(durable) {
6129
6149
  return providers;
6130
6150
  }
6131
6151
  __name(sharedProviders, "sharedProviders");
6132
- function exportsFor() {
6152
+ function exportsFor(engine) {
6133
6153
  return [
6154
+ ...engine?.exports ?? [],
6134
6155
  import_nestjs_agent_core33.AGENT_OPTIONS,
6135
6156
  import_nestjs_agent_core33.AGENT_TOOL_REGISTRY,
6136
6157
  import_nestjs_agent_core33.AGENT_REGISTRY,
@@ -6180,10 +6201,11 @@ function adapterProviders(adapters) {
6180
6201
  return (adapters ?? []).flatMap((adapter) => adapter.providers ?? []);
6181
6202
  }
6182
6203
  __name(adapterProviders, "adapterProviders");
6183
- function controllersForSurface(surface, adapters) {
6204
+ function controllersForSurface(surface, adapters, engine) {
6184
6205
  return surface === "engine" ? [] : [
6185
6206
  ...BASE_CONTROLLERS,
6186
- ...adapterControllers(adapters)
6207
+ ...adapterControllers(adapters),
6208
+ ...engine?.controllers ?? []
6187
6209
  ];
6188
6210
  }
6189
6211
  __name(controllersForSurface, "controllersForSurface");
@@ -6213,12 +6235,22 @@ function routerFor(path) {
6213
6235
  ]);
6214
6236
  }
6215
6237
  __name(routerFor, "routerFor");
6238
+ function assertRunnable(options) {
6239
+ if (options.engine !== void 0 && options.durable === true) {
6240
+ throw new Error(`AgentModule: \`durable: true\` runs turns on the library's loop, but the \`${options.engine.name}\` engine runs them instead. Drop \`durable\` (the engine decides how its turns survive a restart).`);
6241
+ }
6242
+ if (options.engine === void 0 && options.model === void 0) {
6243
+ throw new Error("AgentModule: set `model` (the loop runs the turns) or `engine` (something else does).");
6244
+ }
6245
+ }
6246
+ __name(assertRunnable, "assertRunnable");
6216
6247
  var AgentModule = class _AgentModule {
6217
6248
  static {
6218
6249
  __name(this, "AgentModule");
6219
6250
  }
6220
6251
  static forRoot(options) {
6221
6252
  const path = options.path ?? DEFAULT_PATH;
6253
+ assertRunnable(options);
6222
6254
  applyGuards(options.guards, options.adapters);
6223
6255
  return {
6224
6256
  module: _AgentModule,
@@ -6227,21 +6259,27 @@ var AgentModule = class _AgentModule {
6227
6259
  import_core4.DiscoveryModule,
6228
6260
  routerFor(path)
6229
6261
  ],
6230
- controllers: controllersForSurface(options.surface, options.adapters),
6262
+ controllers: controllersForSurface(options.surface, options.adapters, options.engine),
6231
6263
  providers: [
6232
6264
  {
6233
6265
  provide: import_nestjs_agent_core33.AGENT_OPTIONS,
6234
6266
  useValue: options
6235
6267
  },
6236
- ...sharedProviders(options.durable ?? false),
6268
+ ...sharedProviders(options.durable ?? false, options.engine),
6237
6269
  ...guardProviders(options.guards),
6238
6270
  ...adapterProviders(options.adapters)
6239
6271
  ],
6240
- exports: exportsFor()
6272
+ exports: exportsFor(options.engine)
6241
6273
  };
6242
6274
  }
6243
6275
  static forRootAsync(options) {
6244
6276
  const path = options.path ?? DEFAULT_PATH;
6277
+ if (options.engine !== void 0) {
6278
+ assertRunnable({
6279
+ engine: options.engine,
6280
+ durable: options.durable ?? false
6281
+ });
6282
+ }
6245
6283
  applyGuards(options.guards, options.adapters);
6246
6284
  return {
6247
6285
  module: _AgentModule,
@@ -6251,7 +6289,7 @@ var AgentModule = class _AgentModule {
6251
6289
  routerFor(path),
6252
6290
  ...options.imports ?? []
6253
6291
  ],
6254
- controllers: controllersForSurface(options.surface, options.adapters),
6292
+ controllers: controllersForSurface(options.surface, options.adapters, options.engine),
6255
6293
  providers: [
6256
6294
  {
6257
6295
  provide: import_nestjs_agent_core33.AGENT_OPTIONS,
@@ -6261,18 +6299,25 @@ var AgentModule = class _AgentModule {
6261
6299
  // anything today (AgentDurableModule takes its own mirror option — see its doc for why),
6262
6300
  // but it's stamped here too so the EFFECTIVE value is always observable off
6263
6301
  // AGENT_OPTIONS, sync or async alike.
6264
- useFactory: /* @__PURE__ */ __name(async (...args) => ({
6265
- ...await options.useFactory(...args),
6266
- durable: options.durable ?? false,
6267
- surface: options.surface ?? "both"
6268
- }), "useFactory"),
6302
+ useFactory: /* @__PURE__ */ __name(async (...args) => {
6303
+ const resolved = {
6304
+ ...await options.useFactory(...args),
6305
+ durable: options.durable ?? false,
6306
+ surface: options.surface ?? "both",
6307
+ ...options.engine !== void 0 ? {
6308
+ engine: options.engine
6309
+ } : {}
6310
+ };
6311
+ assertRunnable(resolved);
6312
+ return resolved;
6313
+ }, "useFactory"),
6269
6314
  inject: options.inject ?? []
6270
6315
  },
6271
- ...sharedProviders(options.durable ?? false),
6316
+ ...sharedProviders(options.durable ?? false, options.engine),
6272
6317
  ...guardProviders(options.guards),
6273
6318
  ...adapterProviders(options.adapters)
6274
6319
  ],
6275
- exports: exportsFor()
6320
+ exports: exportsFor(options.engine)
6276
6321
  };
6277
6322
  }
6278
6323
  };
@@ -6407,7 +6452,10 @@ var AgUiRunHandler = class {
6407
6452
  if (owner !== null && owner !== actor.id) {
6408
6453
  throw new import_common28.ForbiddenException("thread belongs to another actor");
6409
6454
  }
6410
- if (owner !== null && turn.media.length === 0) {
6455
+ if (forwarded.regenerate === true && owner === null) {
6456
+ throw invalid("invalid_input", "regenerate needs a thread that already has an exchange");
6457
+ }
6458
+ if (owner !== null && forwarded.regenerate !== true && turn.media.length === 0 && turn.staged.length === 0) {
6411
6459
  const decision = await this.agent.handleTextDecision(input.threadId, actor, turn.text);
6412
6460
  if ("proposalDecision" in decision) {
6413
6461
  this.writeEvents(res, [
@@ -6422,7 +6470,7 @@ var AgUiRunHandler = class {
6422
6470
  return;
6423
6471
  }
6424
6472
  }
6425
- const refs = await this.stage(actor, turn.media, warnings);
6473
+ const refs = await this.stage(actor, turn.media, warnings, turn.staged);
6426
6474
  if (turn.text.trim().length === 0 && refs.length === 0) {
6427
6475
  throw invalid("no_user_message", "the user message to answer is empty");
6428
6476
  }
@@ -6458,6 +6506,9 @@ var AgUiRunHandler = class {
6458
6506
  } : {},
6459
6507
  ...refs.length > 0 ? {
6460
6508
  attachments: refs
6509
+ } : {},
6510
+ ...forwarded.regenerate === true ? {
6511
+ regenerate: true
6461
6512
  } : {}
6462
6513
  });
6463
6514
  await this.pipe(res, started.runId, {
@@ -6469,10 +6520,25 @@ var AgUiRunHandler = class {
6469
6520
  preamble: warningEvents(warnings)
6470
6521
  });
6471
6522
  }
6472
- /** Stage the turn's inline media through the bound store, within its limits; say what was not used. */
6473
- async stage(actor, media, warnings) {
6523
+ /**
6524
+ * The turn's attachments: the ones already staged (by mediaId), then its inline media staged
6525
+ * through the bound store — all within the store's limits; say what was not used.
6526
+ */
6527
+ async stage(actor, media, warnings, staged = []) {
6474
6528
  const refs = [];
6475
6529
  const limits = attachmentLimits(this.options, this.staging);
6530
+ for (const ref of staged) {
6531
+ const label = `The attachment ${ref.mediaId} was not used`;
6532
+ if (this.staging === void 0) {
6533
+ warnings.push(`${label}: attachments are not enabled on this agent.`);
6534
+ } else if (refs.length >= limits.maxPerMessage) {
6535
+ warnings.push(`${label}: a message carries at most ${limits.maxPerMessage} attachments.`);
6536
+ } else {
6537
+ refs.push({
6538
+ mediaId: ref.mediaId
6539
+ });
6540
+ }
6541
+ }
6476
6542
  for (const item of media) {
6477
6543
  const label = `The ${item.kind} "${item.filename}" was not used`;
6478
6544
  if (this.staging === void 0) {
@@ -6485,7 +6551,7 @@ var AgUiRunHandler = class {
6485
6551
  warnings.push(`${label}: it is larger than ${limits.maxBytes} bytes.`);
6486
6552
  } else {
6487
6553
  try {
6488
- const staged = await this.staging.stage({
6554
+ const staged2 = await this.staging.stage({
6489
6555
  data: item.data,
6490
6556
  filename: item.filename,
6491
6557
  contentType: item.contentType,
@@ -6493,7 +6559,7 @@ var AgUiRunHandler = class {
6493
6559
  actor
6494
6560
  });
6495
6561
  refs.push({
6496
- mediaId: staged.mediaId
6562
+ mediaId: staged2.mediaId
6497
6563
  });
6498
6564
  } catch {
6499
6565
  warnings.push(`${label}: it could not be stored.`);
@@ -6611,11 +6677,17 @@ var AgUiRunHandler = class {
6611
6677
  res.setHeader("X-Agent-Run-Id", runId);
6612
6678
  res.flushHeaders();
6613
6679
  let terminal = false;
6680
+ const cursor = {
6681
+ seq: 0
6682
+ };
6614
6683
  try {
6615
6684
  const frames = (0, import_ag_ui.agUiFramesFromNdjson)(this.agent.subscribe(runId));
6616
- for await (const event of (0, import_ag_ui.agUiEvents)(frames, options)) {
6685
+ for await (const event of (0, import_ag_ui.agUiEvents)(frames, {
6686
+ ...options,
6687
+ cursor
6688
+ })) {
6617
6689
  if (event.type === "RUN_FINISHED" || event.type === "RUN_ERROR") terminal = true;
6618
- res.write((0, import_ag_ui.agUiSse)(event));
6690
+ res.write((0, import_ag_ui.agUiSse)(event, cursor.seq));
6619
6691
  }
6620
6692
  } catch {
6621
6693
  if (!terminal) {