@dudousxd/nestjs-agent 1.27.1 → 1.29.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
@@ -22,8 +22,10 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
22
22
  // src/index.ts
23
23
  var index_exports = {};
24
24
  __export(index_exports, {
25
+ A2uiRunHandler: () => A2uiRunHandler,
25
26
  AGENT_CHAT_QUEUE: () => AGENT_CHAT_QUEUE,
26
27
  AGENT_METADATA: () => AGENT_METADATA,
28
+ AGENT_SERVICE: () => AGENT_SERVICE,
27
29
  AGENT_TOOL_BRAND: () => AGENT_TOOL_BRAND,
28
30
  AI_TOOL_METADATA: () => AI_TOOL_METADATA,
29
31
  ATTACHMENT_PAGE_SIZE: () => ATTACHMENT_PAGE_SIZE,
@@ -36,7 +38,7 @@ __export(index_exports, {
36
38
  AgentDepsFactory: () => AgentDepsFactory2,
37
39
  AgentDiscoveryService: () => AgentDiscoveryService,
38
40
  AgentModule: () => AgentModule,
39
- AgentService: () => AgentService,
41
+ AgentService: () => AgentService2,
40
42
  AiTool: () => AiTool,
41
43
  AiToolDiscoveryService: () => AiToolDiscoveryService,
42
44
  AnonymousActorResolver: () => AnonymousActorResolver,
@@ -65,6 +67,7 @@ __export(index_exports, {
65
67
  SystemPrompt: () => SystemPrompt,
66
68
  SystemPromptContributor: () => SystemPromptContributor,
67
69
  ToolsController: () => ToolsController,
70
+ a2uiAdapter: () => a2uiAdapter,
68
71
  agUiAdapter: () => agUiAdapter,
69
72
  attachmentLimits: () => attachmentLimits,
70
73
  declaredSkillProvider: () => declaredSkillProvider,
@@ -176,7 +179,7 @@ function resolverProviders(resolver) {
176
179
  }
177
180
  __name(resolverProviders, "resolverProviders");
178
181
  function toolOptions(options, resolver) {
179
- const { catalog: _catalog, ...rest } = options;
182
+ const { catalog: _catalog, sandbox: _sandbox, ...rest } = options;
180
183
  return {
181
184
  ...rest,
182
185
  ...resolver !== void 0 ? {
@@ -185,11 +188,19 @@ function toolOptions(options, resolver) {
185
188
  };
186
189
  }
187
190
  __name(toolOptions, "toolOptions");
191
+ function withSandbox(options) {
192
+ const base = options.catalog ?? (0, import_genui.defineCatalog)([]);
193
+ const { sandbox } = options;
194
+ return sandbox === void 0 || sandbox === false ? base : base.extend([
195
+ (0, import_genui.defineSandbox)(sandbox === true ? {} : sandbox)
196
+ ]);
197
+ }
198
+ __name(withSandbox, "withSandbox");
188
199
  function coreProviders(resolver) {
189
200
  return [
190
201
  {
191
202
  provide: GENUI_CATALOG,
192
- useFactory: /* @__PURE__ */ __name((options) => options.catalog ?? (0, import_genui.defineCatalog)([]), "useFactory"),
203
+ useFactory: /* @__PURE__ */ __name((options) => withSandbox(options), "useFactory"),
193
204
  inject: [
194
205
  GENUI_OPTIONS
195
206
  ]
@@ -648,6 +659,9 @@ AgentDepsFactory2 = _ts_decorate2([
648
659
  ])
649
660
  ], AgentDepsFactory2);
650
661
 
662
+ // src/agent-service.token.ts
663
+ var AGENT_SERVICE = /* @__PURE__ */ Symbol.for("@dudousxd/nestjs-agent:agent-service");
664
+
651
665
  // src/agent.service.ts
652
666
  var import_nestjs_agent_core9 = require("@dudousxd/nestjs-agent-core");
653
667
  var import_common6 = require("@nestjs/common");
@@ -1477,7 +1491,7 @@ function sendableParams(params) {
1477
1491
  };
1478
1492
  }
1479
1493
  __name(sendableParams, "sendableParams");
1480
- var AgentService = class {
1494
+ var AgentService2 = class {
1481
1495
  static {
1482
1496
  __name(this, "AgentService");
1483
1497
  }
@@ -2660,7 +2674,7 @@ var AgentService = class {
2660
2674
  }
2661
2675
  }
2662
2676
  };
2663
- AgentService = _ts_decorate5([
2677
+ AgentService2 = _ts_decorate5([
2664
2678
  (0, import_common6.Injectable)(),
2665
2679
  _ts_param4(0, (0, import_common6.Inject)(import_nestjs_agent_core9.AGENT_RUNNER)),
2666
2680
  _ts_param4(1, (0, import_common6.Inject)(import_nestjs_agent_core9.AGENT_STORE)),
@@ -2687,7 +2701,7 @@ AgentService = _ts_decorate5([
2687
2701
  typeof ChatQueueService === "undefined" ? Object : ChatQueueService,
2688
2702
  typeof ActionProposalService === "undefined" ? Object : ActionProposalService
2689
2703
  ])
2690
- ], AgentService);
2704
+ ], AgentService2);
2691
2705
 
2692
2706
  // src/approval-port.adapter.ts
2693
2707
  var import_common7 = require("@nestjs/common");
@@ -2781,7 +2795,7 @@ AgentApprovalPortAdapter = _ts_decorate6([
2781
2795
  _ts_param5(1, (0, import_common7.Optional)()),
2782
2796
  _ts_metadata5("design:type", Function),
2783
2797
  _ts_metadata5("design:paramtypes", [
2784
- typeof AgentService === "undefined" ? Object : AgentService,
2798
+ typeof AgentService2 === "undefined" ? Object : AgentService2,
2785
2799
  typeof ActionProposalService === "undefined" ? Object : ActionProposalService
2786
2800
  ])
2787
2801
  ], AgentApprovalPortAdapter);
@@ -2982,7 +2996,7 @@ AttachmentsController = _ts_decorate8([
2982
2996
  _ts_metadata7("design:paramtypes", [
2983
2997
  typeof AgentModuleOptions === "undefined" ? Object : AgentModuleOptions,
2984
2998
  typeof ActorResolver === "undefined" ? Object : ActorResolver,
2985
- typeof AgentService === "undefined" ? Object : AgentService,
2999
+ typeof AgentService2 === "undefined" ? Object : AgentService2,
2986
3000
  Object
2987
3001
  ])
2988
3002
  ], AttachmentsController);
@@ -3254,7 +3268,7 @@ ChatController = _ts_decorate9([
3254
3268
  _ts_param8(1, (0, import_common10.Inject)(import_nestjs_agent_core12.AGENT_ACTOR_RESOLVER)),
3255
3269
  _ts_metadata8("design:type", Function),
3256
3270
  _ts_metadata8("design:paramtypes", [
3257
- typeof AgentService === "undefined" ? Object : AgentService,
3271
+ typeof AgentService2 === "undefined" ? Object : AgentService2,
3258
3272
  typeof ActorResolver === "undefined" ? Object : ActorResolver
3259
3273
  ])
3260
3274
  ], ChatController);
@@ -3652,7 +3666,7 @@ MessagesController = _ts_decorate12([
3652
3666
  _ts_param11(1, (0, import_common13.Inject)(import_nestjs_agent_core15.AGENT_ACTOR_RESOLVER)),
3653
3667
  _ts_metadata11("design:type", Function),
3654
3668
  _ts_metadata11("design:paramtypes", [
3655
- typeof AgentService === "undefined" ? Object : AgentService,
3669
+ typeof AgentService2 === "undefined" ? Object : AgentService2,
3656
3670
  typeof ActorResolver === "undefined" ? Object : ActorResolver
3657
3671
  ])
3658
3672
  ], MessagesController);
@@ -3721,7 +3735,7 @@ ModelsController = _ts_decorate13([
3721
3735
  _ts_param12(1, (0, import_common14.Inject)(import_nestjs_agent_core16.AGENT_ACTOR_RESOLVER)),
3722
3736
  _ts_metadata12("design:type", Function),
3723
3737
  _ts_metadata12("design:paramtypes", [
3724
- typeof AgentService === "undefined" ? Object : AgentService,
3738
+ typeof AgentService2 === "undefined" ? Object : AgentService2,
3725
3739
  typeof ActorResolver === "undefined" ? Object : ActorResolver
3726
3740
  ])
3727
3741
  ], ModelsController);
@@ -3881,7 +3895,7 @@ QueueController = _ts_decorate14([
3881
3895
  _ts_param13(1, (0, import_common15.Inject)(import_nestjs_agent_core17.AGENT_ACTOR_RESOLVER)),
3882
3896
  _ts_metadata13("design:type", Function),
3883
3897
  _ts_metadata13("design:paramtypes", [
3884
- typeof AgentService === "undefined" ? Object : AgentService,
3898
+ typeof AgentService2 === "undefined" ? Object : AgentService2,
3885
3899
  typeof ActorResolver === "undefined" ? Object : ActorResolver
3886
3900
  ])
3887
3901
  ], QueueController);
@@ -3948,7 +3962,7 @@ QuotaController = _ts_decorate15([
3948
3962
  _ts_param14(1, (0, import_common16.Inject)(import_nestjs_agent_core18.AGENT_ACTOR_RESOLVER)),
3949
3963
  _ts_metadata14("design:type", Function),
3950
3964
  _ts_metadata14("design:paramtypes", [
3951
- typeof AgentService === "undefined" ? Object : AgentService,
3965
+ typeof AgentService2 === "undefined" ? Object : AgentService2,
3952
3966
  typeof ActorResolver === "undefined" ? Object : ActorResolver
3953
3967
  ])
3954
3968
  ], QuotaController);
@@ -4211,7 +4225,7 @@ ThreadsController = _ts_decorate17([
4211
4225
  _ts_param16(1, (0, import_common18.Inject)(import_nestjs_agent_core20.AGENT_ACTOR_RESOLVER)),
4212
4226
  _ts_metadata16("design:type", Function),
4213
4227
  _ts_metadata16("design:paramtypes", [
4214
- typeof AgentService === "undefined" ? Object : AgentService,
4228
+ typeof AgentService2 === "undefined" ? Object : AgentService2,
4215
4229
  typeof ActorResolver === "undefined" ? Object : ActorResolver
4216
4230
  ])
4217
4231
  ], ThreadsController);
@@ -4426,7 +4440,7 @@ ToolCallController = _ts_decorate18([
4426
4440
  _ts_param17(1, (0, import_common19.Inject)(import_nestjs_agent_core21.AGENT_ACTOR_RESOLVER)),
4427
4441
  _ts_metadata17("design:type", Function),
4428
4442
  _ts_metadata17("design:paramtypes", [
4429
- typeof AgentService === "undefined" ? Object : AgentService,
4443
+ typeof AgentService2 === "undefined" ? Object : AgentService2,
4430
4444
  typeof ActorResolver === "undefined" ? Object : ActorResolver
4431
4445
  ])
4432
4446
  ], ToolCallController);
@@ -6360,7 +6374,11 @@ function sharedProviders(durable, engine) {
6360
6374
  useExisting: ChatQueueService
6361
6375
  },
6362
6376
  InlineAgentRunner,
6363
- AgentService,
6377
+ AgentService2,
6378
+ {
6379
+ provide: AGENT_SERVICE,
6380
+ useExisting: AgentService2
6381
+ },
6364
6382
  ActionProposalService,
6365
6383
  ActionProposalWorkerService,
6366
6384
  // Bound ALWAYS (durable or inline) — the console's cross-thread approvals inbox routes decisions
@@ -6427,7 +6445,8 @@ function exportsFor(engine) {
6427
6445
  import_nestjs_agent_core34.AGENT_MEMORY,
6428
6446
  import_nestjs_agent_core34.AGENT_DEPS_FACTORY,
6429
6447
  AgentDepsFactory2,
6430
- AgentService,
6448
+ AgentService2,
6449
+ AGENT_SERVICE,
6431
6450
  ActionProposalService,
6432
6451
  ActionProposalWorkerService,
6433
6452
  ChatQueueService,
@@ -6588,7 +6607,9 @@ AgentModule = _ts_decorate27([
6588
6607
 
6589
6608
  // src/ag-ui/ag-ui.adapter.ts
6590
6609
  var import_nestjs_agent_core35 = require("@dudousxd/nestjs-agent-core");
6610
+ var import_a2ui = require("@dudousxd/nestjs-agent-core/a2ui");
6591
6611
  var import_ag_ui = require("@dudousxd/nestjs-agent-core/ag-ui");
6612
+ var import_genui3 = require("@dudousxd/nestjs-agent-core/genui");
6592
6613
  var import_common29 = require("@nestjs/common");
6593
6614
  function _ts_decorate28(decorators, target, key, desc) {
6594
6615
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
@@ -6644,12 +6665,14 @@ var AgUiRunHandler = class {
6644
6665
  options;
6645
6666
  staging;
6646
6667
  quietMs;
6647
- constructor(agent, actorResolver, options, staging, quietMs) {
6668
+ a2ui;
6669
+ constructor(agent, actorResolver, options, staging, quietMs, a2ui = void 0) {
6648
6670
  this.agent = agent;
6649
6671
  this.actorResolver = actorResolver;
6650
6672
  this.options = options;
6651
6673
  this.staging = staging;
6652
6674
  this.quietMs = quietMs;
6675
+ this.a2ui = a2ui;
6653
6676
  }
6654
6677
  async handle(req, res, body) {
6655
6678
  const input = (0, import_ag_ui.parseRunInput)(body);
@@ -6698,12 +6721,22 @@ var AgUiRunHandler = class {
6698
6721
  skip: first.address.position,
6699
6722
  answered: plan.decisions.map((decision) => decision.address.toolCallId),
6700
6723
  ...quiet,
6724
+ ...this.a2uiFor(input),
6701
6725
  preamble: warningEvents(warnings)
6702
6726
  });
6703
6727
  return;
6704
6728
  }
6705
6729
  }
6706
- const turn = (0, import_ag_ui.readUserTurn)(input.messages);
6730
+ const action = forwarded.uiAction;
6731
+ if (typeof action === "string") {
6732
+ throw invalid("invalid_ui_action", action);
6733
+ }
6734
+ const turn = action !== void 0 ? {
6735
+ text: (0, import_genui3.uiActionText)(action),
6736
+ media: [],
6737
+ staged: [],
6738
+ dropped: []
6739
+ } : (0, import_ag_ui.readUserTurn)(input.messages);
6707
6740
  if (turn === null) {
6708
6741
  throw invalid(NO_USER_MESSAGE_CODE, "messages carries no user message to answer");
6709
6742
  }
@@ -6715,7 +6748,7 @@ var AgUiRunHandler = class {
6715
6748
  if (forwarded.regenerate === true && owner === null) {
6716
6749
  throw invalid("invalid_input", "regenerate needs a thread that already has an exchange");
6717
6750
  }
6718
- if (owner !== null && forwarded.regenerate !== true && turn.media.length === 0 && turn.staged.length === 0) {
6751
+ if (owner !== null && forwarded.regenerate !== true && action === void 0 && turn.media.length === 0 && turn.staged.length === 0) {
6719
6752
  const decision = await this.agent.handleTextDecision(input.threadId, actor, turn.text);
6720
6753
  if ("proposalDecision" in decision) {
6721
6754
  this.writeEvents(res, [
@@ -6777,6 +6810,7 @@ var AgUiRunHandler = class {
6777
6810
  streamRunId: started.runId,
6778
6811
  streamThreadId: started.threadId,
6779
6812
  ...quiet,
6813
+ ...this.a2uiFor(input),
6780
6814
  preamble: warningEvents(warnings)
6781
6815
  });
6782
6816
  }
@@ -6923,6 +6957,13 @@ var AgUiRunHandler = class {
6923
6957
  for (const event of events) res.write((0, import_ag_ui.agUiSse)(event));
6924
6958
  res.end();
6925
6959
  }
6960
+ /** A2UI for this request's client: the basic catalog under the id it advertises. Off when off. */
6961
+ a2uiFor(input) {
6962
+ if (this.a2ui === void 0) return {};
6963
+ return {
6964
+ a2ui: (0, import_a2ui.negotiateA2uiCatalog)(this.a2ui, (0, import_a2ui.readAgUiA2uiCatalogIds)(input), import_a2ui.A2UI_LEGACY_BASIC_CATALOG_ID)
6965
+ };
6966
+ }
6926
6967
  /**
6927
6968
  * Pipe a run to the client as AG-UI 1.0 over SSE: one event per `data:` line, from `RUN_STARTED`
6928
6969
  * to the run's terminal event. It ends when the run stops to ask — the library run stays parked,
@@ -6964,12 +7005,13 @@ var AgUiRunHandler = class {
6964
7005
  function agUiAdapter(options = {}) {
6965
7006
  const path = (options.path ?? "ag-ui").replace(/^\/+|\/+$/g, "");
6966
7007
  const quietMs = options.quietMs;
7008
+ const a2ui = options.a2ui === void 0 || options.a2ui === false ? void 0 : options.a2ui === true ? {} : options.a2ui;
6967
7009
  let AgUiController = class AgUiController extends AgUiRunHandler {
6968
7010
  static {
6969
7011
  __name(this, "AgUiController");
6970
7012
  }
6971
- constructor(agent, actorResolver, moduleOptions, staging) {
6972
- super(agent, actorResolver, moduleOptions, staging, quietMs);
7013
+ constructor(agent, actorResolver, moduleOptions, staging, catalog) {
7014
+ super(agent, actorResolver, moduleOptions, staging, quietMs, a2ui !== void 0 ? withCatalog(a2ui, catalog) : void 0);
6973
7015
  }
6974
7016
  run(req, res, body) {
6975
7017
  return this.handle(req, res, body);
@@ -6991,17 +7033,20 @@ function agUiAdapter(options = {}) {
6991
7033
  ], AgUiController.prototype, "run", null);
6992
7034
  AgUiController = _ts_decorate28([
6993
7035
  (0, import_common29.Controller)(),
6994
- _ts_param26(0, (0, import_common29.Inject)(AgentService)),
7036
+ _ts_param26(0, (0, import_common29.Inject)(AgentService2)),
6995
7037
  _ts_param26(1, (0, import_common29.Inject)(import_nestjs_agent_core35.AGENT_ACTOR_RESOLVER)),
6996
7038
  _ts_param26(2, (0, import_common29.Inject)(import_nestjs_agent_core35.AGENT_OPTIONS)),
6997
7039
  _ts_param26(3, (0, import_common29.Optional)()),
6998
7040
  _ts_param26(3, (0, import_common29.Inject)(import_nestjs_agent_core35.AGENT_ATTACHMENT_STAGING)),
7041
+ _ts_param26(4, (0, import_common29.Optional)()),
7042
+ _ts_param26(4, (0, import_common29.Inject)(GENUI_CATALOG)),
6999
7043
  _ts_metadata26("design:type", Function),
7000
7044
  _ts_metadata26("design:paramtypes", [
7001
- typeof AgentService === "undefined" ? Object : AgentService,
7045
+ typeof AgentService2 === "undefined" ? Object : AgentService2,
7002
7046
  typeof ActorResolver === "undefined" ? Object : ActorResolver,
7003
7047
  typeof AgentModuleOptions === "undefined" ? Object : AgentModuleOptions,
7004
- typeof AttachmentStagingStore === "undefined" ? Object : AttachmentStagingStore
7048
+ typeof AttachmentStagingStore === "undefined" ? Object : AttachmentStagingStore,
7049
+ typeof Catalog === "undefined" ? Object : Catalog
7005
7050
  ])
7006
7051
  ], AgUiController);
7007
7052
  return {
@@ -7012,9 +7057,362 @@ function agUiAdapter(options = {}) {
7012
7057
  };
7013
7058
  }
7014
7059
  __name(agUiAdapter, "agUiAdapter");
7060
+ function withCatalog(options, catalog) {
7061
+ if (options.catalog !== void 0 || catalog === void 0) return options;
7062
+ return {
7063
+ ...options,
7064
+ catalog
7065
+ };
7066
+ }
7067
+ __name(withCatalog, "withCatalog");
7015
7068
 
7016
- // src/resolver/header-actor-resolver.ts
7069
+ // src/a2ui/a2ui.adapter.ts
7070
+ var import_nestjs_agent_core36 = require("@dudousxd/nestjs-agent-core");
7071
+ var import_a2ui2 = require("@dudousxd/nestjs-agent-core/a2ui");
7072
+ var import_ag_ui2 = require("@dudousxd/nestjs-agent-core/ag-ui");
7073
+ var import_genui4 = require("@dudousxd/nestjs-agent-core/genui");
7017
7074
  var import_common30 = require("@nestjs/common");
7075
+ function _ts_decorate29(decorators, target, key, desc) {
7076
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
7077
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") {
7078
+ r = Reflect.decorate(decorators, target, key, desc);
7079
+ } else {
7080
+ for (var i = decorators.length - 1; i >= 0; i--) {
7081
+ if (d = decorators[i]) {
7082
+ r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
7083
+ }
7084
+ }
7085
+ }
7086
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7087
+ }
7088
+ __name(_ts_decorate29, "_ts_decorate");
7089
+ function _ts_metadata27(metadataKey, metadataValue) {
7090
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") {
7091
+ return Reflect.metadata(metadataKey, metadataValue);
7092
+ }
7093
+ }
7094
+ __name(_ts_metadata27, "_ts_metadata");
7095
+ function _ts_param27(paramIndex, decorator) {
7096
+ return function(target, key) {
7097
+ decorator(target, key, paramIndex);
7098
+ };
7099
+ }
7100
+ __name(_ts_param27, "_ts_param");
7101
+ var A2UI_VIA = "a2ui";
7102
+ function isRecord(value) {
7103
+ return typeof value === "object" && value !== null && !Array.isArray(value);
7104
+ }
7105
+ __name(isRecord, "isRecord");
7106
+ function invalid2(code, message) {
7107
+ return new import_common30.BadRequestException({
7108
+ statusCode: 400,
7109
+ code,
7110
+ message
7111
+ });
7112
+ }
7113
+ __name(invalid2, "invalid");
7114
+ function bodyField(body, key) {
7115
+ if (body[key] !== void 0) return body[key];
7116
+ return isRecord(body.metadata) ? body.metadata[key] : void 0;
7117
+ }
7118
+ __name(bodyField, "bodyField");
7119
+ function readDataModel(raw, maxBytes) {
7120
+ if (raw === void 0) return void 0;
7121
+ if (!isRecord(raw) || !isRecord(raw.surfaces)) {
7122
+ return "a2uiClientDataModel carries { version, surfaces }";
7123
+ }
7124
+ let size;
7125
+ try {
7126
+ size = new TextEncoder().encode(JSON.stringify(raw.surfaces)).length;
7127
+ } catch {
7128
+ return "a2uiClientDataModel must be JSON";
7129
+ }
7130
+ if (size > maxBytes) {
7131
+ return `a2uiClientDataModel may be at most ${maxBytes} bytes (this one is ${size})`;
7132
+ }
7133
+ return Object.keys(raw.surfaces).length > 0 ? raw.surfaces : void 0;
7134
+ }
7135
+ __name(readDataModel, "readDataModel");
7136
+ var A2uiRunHandler = class {
7137
+ static {
7138
+ __name(this, "A2uiRunHandler");
7139
+ }
7140
+ agent;
7141
+ actorResolver;
7142
+ projection;
7143
+ quietMs;
7144
+ maxActionBytes;
7145
+ maxDataModelBytes;
7146
+ constructor(agent, actorResolver, projection, quietMs, maxActionBytes, maxDataModelBytes = void 0) {
7147
+ this.agent = agent;
7148
+ this.actorResolver = actorResolver;
7149
+ this.projection = projection;
7150
+ this.quietMs = quietMs;
7151
+ this.maxActionBytes = maxActionBytes;
7152
+ this.maxDataModelBytes = maxDataModelBytes;
7153
+ }
7154
+ /**
7155
+ * `GET <path>/a2ui/threads/:threadId`: a stored thread as `{ threadId, entries }`
7156
+ * (`a2uiThreadReplay`) — what a client draws again after a reload. Owner-scoped; a thread nobody
7157
+ * has answers `{ entries: [] }`. `?catalog=<id>` names the client's basic catalog id.
7158
+ */
7159
+ async replay(req, threadId, catalog) {
7160
+ const actor = await this.actorResolver.resolve(req);
7161
+ const owner = await this.agent.threadOwner(threadId);
7162
+ if (owner === null) return {
7163
+ threadId,
7164
+ entries: []
7165
+ };
7166
+ const thread = await this.agent.getThread(actor, threadId);
7167
+ const supported = typeof catalog === "string" ? [
7168
+ catalog
7169
+ ] : Array.isArray(catalog) ? catalog.filter((id) => typeof id === "string") : void 0;
7170
+ return {
7171
+ threadId,
7172
+ entries: (0, import_a2ui2.a2uiThreadReplay)(thread?.messages ?? [], (0, import_a2ui2.negotiateA2uiCatalog)(this.projection, supported))
7173
+ };
7174
+ }
7175
+ async handle(req, res, raw) {
7176
+ const body = isRecord(raw) ? raw : {};
7177
+ const agentName = typeof body.agent === "string" && body.agent.length > 0 ? body.agent : void 0;
7178
+ const actor = await this.actorResolver.resolve(req);
7179
+ const projection = (0, import_a2ui2.negotiateA2uiCatalog)(this.projection, (0, import_a2ui2.readA2uiClientCapabilities)(bodyField(body, "a2uiClientCapabilities")));
7180
+ const dataModel = readDataModel(bodyField(body, "a2uiClientDataModel"), this.maxDataModelBytes ?? 32768);
7181
+ if (typeof dataModel === "string") throw invalid2("invalid_data_model", dataModel);
7182
+ let action;
7183
+ if (body.action !== void 0) {
7184
+ const read = isRecord(body.action) ? (0, import_a2ui2.readA2uiAction)(body.action, {
7185
+ ...this.maxActionBytes !== void 0 ? {
7186
+ maxBytes: this.maxActionBytes
7187
+ } : {}
7188
+ }) : "action must be an A2UI action message";
7189
+ if (typeof read === "string") throw invalid2("invalid_action", read);
7190
+ action = read;
7191
+ }
7192
+ if (action?.name === import_a2ui2.A2UI_APPROVE_ACTION || action?.name === import_a2ui2.A2UI_REJECT_ACTION) {
7193
+ const interruptId = action.context.interruptId;
7194
+ const address = typeof interruptId === "string" ? (0, import_ag_ui2.decodeInterruptId)(interruptId) : void 0;
7195
+ if (address === void 0 || address === null || address.kind === "elicitation") {
7196
+ throw invalid2("invalid_action", "an approval action carries the interruptId it decides");
7197
+ }
7198
+ if (address.kind === "proposal") {
7199
+ if (address.proposalId === void 0 || address.threadId === void 0) {
7200
+ throw invalid2("invalid_action", "the interruptId names no proposal");
7201
+ }
7202
+ const decided = await this.agent.decideActionProposal(actor, address.threadId, address.proposalId, {
7203
+ decision: action.name === import_a2ui2.A2UI_APPROVE_ACTION ? "approved" : "rejected",
7204
+ via: A2UI_VIA
7205
+ });
7206
+ this.writeHead(res, {
7207
+ "X-Agent-Thread-Id": address.threadId
7208
+ });
7209
+ const projector = new import_a2ui2.A2uiProjector(projection);
7210
+ const messageId = `proposal-${address.proposalId}`;
7211
+ for (const event of [
7212
+ {
7213
+ type: "TEXT_MESSAGE_START",
7214
+ messageId,
7215
+ role: "assistant"
7216
+ },
7217
+ {
7218
+ type: "TEXT_MESSAGE_CONTENT",
7219
+ messageId,
7220
+ delta: decided.text
7221
+ }
7222
+ ]) {
7223
+ for (const message2 of projector.project(event)) res.write(`${JSON.stringify(message2)}
7224
+ `);
7225
+ }
7226
+ res.end();
7227
+ return;
7228
+ }
7229
+ await this.agent.assertResumable(actor, address.stream);
7230
+ await this.agent.checkDecision(actor, address.toolCallId);
7231
+ if (action.name === import_a2ui2.A2UI_APPROVE_ACTION) {
7232
+ await this.agent.approve(actor, address.toolCallId, {
7233
+ via: A2UI_VIA
7234
+ });
7235
+ } else {
7236
+ await this.agent.reject(actor, address.toolCallId, void 0, {
7237
+ via: A2UI_VIA
7238
+ });
7239
+ }
7240
+ await this.stream(res, address.stream, {
7241
+ skip: address.position,
7242
+ answered: [
7243
+ address.toolCallId
7244
+ ],
7245
+ projection
7246
+ });
7247
+ return;
7248
+ }
7249
+ const message = typeof body.message === "string" ? body.message : "";
7250
+ const text = action !== void 0 ? (0, import_genui4.uiActionText)(action) : message;
7251
+ if (text.trim().length === 0) {
7252
+ throw invalid2("no_user_message", "send a message or an action");
7253
+ }
7254
+ const threadId = typeof body.threadId === "string" && body.threadId.length > 0 ? body.threadId : void 0;
7255
+ const owner = threadId !== void 0 ? await this.agent.threadOwner(threadId) : null;
7256
+ if (owner !== null && owner !== actor.id) {
7257
+ throw new import_common30.ForbiddenException("thread belongs to another actor");
7258
+ }
7259
+ let uiCapabilities;
7260
+ if (Object.hasOwn(body, "uiCapabilities")) {
7261
+ try {
7262
+ uiCapabilities = (0, import_genui4.validateUiCapabilities)(body.uiCapabilities);
7263
+ } catch (error) {
7264
+ throw invalid2("invalid_input", error.message);
7265
+ }
7266
+ }
7267
+ const started = await this.agent.chat({
7268
+ actor,
7269
+ message: text,
7270
+ ...threadId === void 0 ? {} : owner !== null ? {
7271
+ threadId
7272
+ } : {
7273
+ newThreadId: threadId
7274
+ },
7275
+ ...agentName !== void 0 ? {
7276
+ agentName
7277
+ } : {},
7278
+ ...uiCapabilities !== void 0 ? {
7279
+ uiCapabilities
7280
+ } : {},
7281
+ ...dataModel !== void 0 ? {
7282
+ pageContext: {
7283
+ a2uiDataModel: dataModel
7284
+ }
7285
+ } : {}
7286
+ });
7287
+ await this.stream(res, started.runId, {
7288
+ threadId: started.threadId,
7289
+ projection
7290
+ });
7291
+ }
7292
+ /** Open the JSON Lines response. */
7293
+ writeHead(res, extra) {
7294
+ res.status(200);
7295
+ res.setHeader("Content-Type", "application/jsonl; charset=utf-8");
7296
+ res.setHeader("Cache-Control", "no-cache, no-transform");
7297
+ res.setHeader("Connection", "keep-alive");
7298
+ res.setHeader("X-Accel-Buffering", "no");
7299
+ for (const [name, value] of Object.entries(extra)) res.setHeader(name, value);
7300
+ res.flushHeaders();
7301
+ }
7302
+ /** Write one run as A2UI JSON Lines, until it ends or stops to ask. */
7303
+ async stream(res, runId, options) {
7304
+ this.writeHead(res, {
7305
+ "X-Agent-Run-Id": runId,
7306
+ ...options.threadId !== void 0 ? {
7307
+ "X-Agent-Thread-Id": options.threadId
7308
+ } : {}
7309
+ });
7310
+ const projector = new import_a2ui2.A2uiProjector(options.projection ?? this.projection);
7311
+ const write = /* @__PURE__ */ __name((messages) => {
7312
+ for (const message of messages) res.write(`${JSON.stringify(message)}
7313
+ `);
7314
+ }, "write");
7315
+ try {
7316
+ const frames = (0, import_ag_ui2.agUiFramesFromNdjson)(this.agent.subscribe(runId));
7317
+ for await (const event of (0, import_ag_ui2.agUiEvents)(frames, {
7318
+ threadId: options.threadId ?? runId,
7319
+ runId,
7320
+ streamRunId: runId,
7321
+ ...options.threadId !== void 0 ? {
7322
+ streamThreadId: options.threadId
7323
+ } : {},
7324
+ ...options.skip !== void 0 ? {
7325
+ skip: options.skip
7326
+ } : {},
7327
+ ...options.answered !== void 0 ? {
7328
+ answered: options.answered
7329
+ } : {},
7330
+ ...this.quietMs !== void 0 ? {
7331
+ quietMs: this.quietMs
7332
+ } : {}
7333
+ })) {
7334
+ write(projector.project(event));
7335
+ }
7336
+ } catch {
7337
+ write(projector.project({
7338
+ type: "RUN_ERROR",
7339
+ message: "The run could not be followed."
7340
+ }));
7341
+ }
7342
+ res.end();
7343
+ }
7344
+ };
7345
+ function a2uiAdapter(options = {}) {
7346
+ const path = (options.path ?? "a2ui").replace(/^\/+|\/+$/g, "");
7347
+ const { path: _path, quietMs, maxActionBytes, maxDataModelBytes, ...projection } = options;
7348
+ let A2uiController = class A2uiController extends A2uiRunHandler {
7349
+ static {
7350
+ __name(this, "A2uiController");
7351
+ }
7352
+ constructor(agent, actorResolver, catalog) {
7353
+ super(agent, actorResolver, projection.catalog === void 0 && catalog !== void 0 ? {
7354
+ ...projection,
7355
+ catalog
7356
+ } : projection, quietMs, maxActionBytes, maxDataModelBytes);
7357
+ }
7358
+ thread(req, threadId, catalog) {
7359
+ return this.replay(req, threadId, catalog);
7360
+ }
7361
+ run(req, res, body) {
7362
+ return this.handle(req, res, body);
7363
+ }
7364
+ };
7365
+ _ts_decorate29([
7366
+ (0, import_common30.Get)(`${path}/threads/:threadId`),
7367
+ _ts_param27(0, (0, import_common30.Req)()),
7368
+ _ts_param27(1, (0, import_common30.Param)("threadId")),
7369
+ _ts_param27(2, (0, import_common30.Query)("catalog")),
7370
+ _ts_metadata27("design:type", Function),
7371
+ _ts_metadata27("design:paramtypes", [
7372
+ typeof Request === "undefined" ? Object : Request,
7373
+ String,
7374
+ Object
7375
+ ]),
7376
+ _ts_metadata27("design:returntype", typeof ReturnType === "undefined" ? Object : ReturnType)
7377
+ ], A2uiController.prototype, "thread", null);
7378
+ _ts_decorate29([
7379
+ (0, import_common30.Post)(path),
7380
+ (0, import_common30.HttpCode)(200),
7381
+ _ts_param27(0, (0, import_common30.Req)()),
7382
+ _ts_param27(1, (0, import_common30.Res)()),
7383
+ _ts_param27(2, (0, import_common30.Body)()),
7384
+ _ts_metadata27("design:type", Function),
7385
+ _ts_metadata27("design:paramtypes", [
7386
+ typeof Request === "undefined" ? Object : Request,
7387
+ typeof Response === "undefined" ? Object : Response,
7388
+ Object
7389
+ ]),
7390
+ _ts_metadata27("design:returntype", typeof Promise === "undefined" ? Object : Promise)
7391
+ ], A2uiController.prototype, "run", null);
7392
+ A2uiController = _ts_decorate29([
7393
+ (0, import_common30.Controller)(),
7394
+ _ts_param27(0, (0, import_common30.Inject)(AGENT_SERVICE)),
7395
+ _ts_param27(1, (0, import_common30.Inject)(import_nestjs_agent_core36.AGENT_ACTOR_RESOLVER)),
7396
+ _ts_param27(2, (0, import_common30.Optional)()),
7397
+ _ts_param27(2, (0, import_common30.Inject)(GENUI_CATALOG)),
7398
+ _ts_metadata27("design:type", Function),
7399
+ _ts_metadata27("design:paramtypes", [
7400
+ typeof AgentService === "undefined" ? Object : AgentService,
7401
+ typeof ActorResolver === "undefined" ? Object : ActorResolver,
7402
+ typeof Catalog === "undefined" ? Object : Catalog
7403
+ ])
7404
+ ], A2uiController);
7405
+ return {
7406
+ name: "a2ui",
7407
+ controllers: [
7408
+ A2uiController
7409
+ ]
7410
+ };
7411
+ }
7412
+ __name(a2uiAdapter, "a2uiAdapter");
7413
+
7414
+ // src/resolver/header-actor-resolver.ts
7415
+ var import_common31 = require("@nestjs/common");
7018
7416
  function readHeader(req, name) {
7019
7417
  if (typeof req !== "object" || req === null || !("headers" in req)) return void 0;
7020
7418
  const { headers } = req;
@@ -7030,7 +7428,7 @@ var HeaderActorResolver = class {
7030
7428
  resolve(req) {
7031
7429
  const id = readHeader(req, "x-actor-id");
7032
7430
  if (id === void 0 || id.length === 0) {
7033
- throw new import_common30.UnauthorizedException("HeaderActorResolver: missing x-actor-id header. No default actor is fabricated. Send x-actor-id from a trusted gateway, or configure AgentModule.forRoot({ actorResolver }) with a resolver that reads your authenticated principal.");
7431
+ throw new import_common31.UnauthorizedException("HeaderActorResolver: missing x-actor-id header. No default actor is fabricated. Send x-actor-id from a trusted gateway, or configure AgentModule.forRoot({ actorResolver }) with a resolver that reads your authenticated principal.");
7034
7432
  }
7035
7433
  const roles = (readHeader(req, "x-actor-role") ?? "").split(",").map((role) => role.trim()).filter((role) => role.length > 0);
7036
7434
  const tenantRef = readHeader(req, "x-tenant-ref");
@@ -7045,7 +7443,7 @@ var HeaderActorResolver = class {
7045
7443
  };
7046
7444
 
7047
7445
  // src/resolver/request-user-actor-resolver.ts
7048
- var import_common31 = require("@nestjs/common");
7446
+ var import_common32 = require("@nestjs/common");
7049
7447
  function field(user, ...names) {
7050
7448
  for (const name of names) {
7051
7449
  const value = user[name];
@@ -7057,7 +7455,7 @@ __name(field, "field");
7057
7455
  function defaultRequestUserMapper(user) {
7058
7456
  const id = field(user, "id", "sub", "_id", "userId");
7059
7457
  if (id === void 0) {
7060
- throw new import_common31.UnauthorizedException("requestUserActorResolver: req.user has no id/sub/_id/userId \u2014 pass a mapper: requestUserActorResolver((user) => ({ id: \u2026, roles: \u2026 }))");
7458
+ throw new import_common32.UnauthorizedException("requestUserActorResolver: req.user has no id/sub/_id/userId \u2014 pass a mapper: requestUserActorResolver((user) => ({ id: \u2026, roles: \u2026 }))");
7061
7459
  }
7062
7460
  const rawRoles = field(user, "roles", "role");
7063
7461
  const roles = Array.isArray(rawRoles) ? rawRoles.map(String) : typeof rawRoles === "string" ? [
@@ -7078,7 +7476,7 @@ function requestUserActorResolver(map) {
7078
7476
  async resolve(req) {
7079
7477
  const user = typeof req === "object" && req !== null ? req.user : void 0;
7080
7478
  if (user === void 0 || user === null || user === false) {
7081
- throw new import_common31.UnauthorizedException("Sign in to use the agent.");
7479
+ throw new import_common32.UnauthorizedException("Sign in to use the agent.");
7082
7480
  }
7083
7481
  if (map !== void 0) return map(user, req);
7084
7482
  return defaultRequestUserMapper(user);
@@ -7091,8 +7489,10 @@ __name(requestUserActorResolver, "requestUserActorResolver");
7091
7489
  __reExport(index_exports, require("@dudousxd/nestjs-agent-core"), module.exports);
7092
7490
  // Annotate the CommonJS export names for ESM import in node:
7093
7491
  0 && (module.exports = {
7492
+ A2uiRunHandler,
7094
7493
  AGENT_CHAT_QUEUE,
7095
7494
  AGENT_METADATA,
7495
+ AGENT_SERVICE,
7096
7496
  AGENT_TOOL_BRAND,
7097
7497
  AI_TOOL_METADATA,
7098
7498
  ATTACHMENT_PAGE_SIZE,
@@ -7134,6 +7534,7 @@ __reExport(index_exports, require("@dudousxd/nestjs-agent-core"), module.exports
7134
7534
  SystemPrompt,
7135
7535
  SystemPromptContributor,
7136
7536
  ToolsController,
7537
+ a2uiAdapter,
7137
7538
  agUiAdapter,
7138
7539
  attachmentLimits,
7139
7540
  declaredSkillProvider,