@dudousxd/nestjs-agent 1.10.0 → 1.11.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.js CHANGED
@@ -2,9 +2,9 @@ var __defProp = Object.defineProperty;
2
2
  var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
3
3
 
4
4
  // src/agent.module.ts
5
- import { AGENT_ACTOR_RESOLVER as AGENT_ACTOR_RESOLVER11, AGENT_APPROVAL_PORT, AGENT_DEPS_FACTORY as AGENT_DEPS_FACTORY5, AGENT_DURABLE_RUNNER, AGENT_MEMORY as AGENT_MEMORY3, AGENT_MODEL as AGENT_MODEL2, AGENT_MODEL_CATALOG as AGENT_MODEL_CATALOG2, AGENT_OPTIONS as AGENT_OPTIONS5, AGENT_PROMPT_CONTRIBUTORS as AGENT_PROMPT_CONTRIBUTORS3, AGENT_QUOTA_PROVIDER as AGENT_QUOTA_PROVIDER2, AGENT_QUOTA_STORE as AGENT_QUOTA_STORE3, AGENT_REGISTRY as AGENT_REGISTRY6, AGENT_ROLES_POLICY as AGENT_ROLES_POLICY2, AGENT_RUNNER as AGENT_RUNNER2, AGENT_SINK as AGENT_SINK2, AGENT_SKILLS as AGENT_SKILLS3, AGENT_SKILL_SOURCES as AGENT_SKILL_SOURCES2, AGENT_STORE as AGENT_STORE4, AGENT_TOOL_REGISTRY as AGENT_TOOL_REGISTRY3, AgentRegistry as AgentRegistry6, DefaultRolesPolicy, ToolRegistry as ToolRegistry3 } from "@dudousxd/nestjs-agent-core";
6
- import { Global, Module } from "@nestjs/common";
7
- import { DiscoveryModule, RouterModule } from "@nestjs/core";
5
+ import { AGENT_ACTOR_RESOLVER as AGENT_ACTOR_RESOLVER11, AGENT_APPROVAL_PORT, AGENT_DEPS_FACTORY as AGENT_DEPS_FACTORY5, AGENT_DURABLE_RUNNER, AGENT_MEMORY as AGENT_MEMORY3, AGENT_MODEL as AGENT_MODEL2, AGENT_MODEL_CATALOG as AGENT_MODEL_CATALOG2, AGENT_OPTIONS as AGENT_OPTIONS5, AGENT_PROMPT_CONTRIBUTORS as AGENT_PROMPT_CONTRIBUTORS3, AGENT_QUOTA_PROVIDER as AGENT_QUOTA_PROVIDER2, AGENT_QUOTA_STORE as AGENT_QUOTA_STORE3, AGENT_REGISTRY as AGENT_REGISTRY6, AGENT_ROLES_POLICY as AGENT_ROLES_POLICY2, AGENT_RUNNER as AGENT_RUNNER2, AGENT_SINK as AGENT_SINK2, AGENT_SKILLS as AGENT_SKILLS3, AGENT_SKILL_SOURCES as AGENT_SKILL_SOURCES2, AGENT_STORE as AGENT_STORE4, AGENT_TOOL_REGISTRY as AGENT_TOOL_REGISTRY3, AgentRegistry as AgentRegistry6, DefaultRolesPolicy, InMemoryAgentStore, ToolRegistry as ToolRegistry3 } from "@dudousxd/nestjs-agent-core";
6
+ import { Global, Logger as Logger5, Module } from "@nestjs/common";
7
+ import { DiscoveryModule, ModulesContainer, RouterModule } from "@nestjs/core";
8
8
 
9
9
  // src/agent-deps.factory.ts
10
10
  import { AGENT_MEMORY, AGENT_MODEL, AGENT_PRICING_STORE, AGENT_PROMPT_CONTRIBUTORS, AGENT_QUOTA_STORE, AGENT_REGISTRY, AGENT_ROLES_POLICY, AGENT_SINK, AGENT_SKILLS, AGENT_STORE, AGENT_TOOL_REGISTRY, AgentRegistry as AgentRegistry2, ToolRegistry as ToolRegistry2, normalizeDelegation, summarizeWithModel, windowHistory } from "@dudousxd/nestjs-agent-core";
@@ -127,7 +127,7 @@ var AgentDepsFactory2 = class {
127
127
  } : {},
128
128
  registry: this.registry,
129
129
  promptContributors: this.promptContributors,
130
- systemPrompt: definition?.systemPrompt ?? "You are a helpful assistant.",
130
+ systemPrompt: definition?.systemPrompt ?? this.options.systemPrompt ?? "You are a helpful assistant.",
131
131
  maxSteps: definition?.maxSteps ?? 8,
132
132
  ...definition?.maxDelegationDepth !== void 0 ? {
133
133
  maxDelegationDepth: definition.maxDelegationDepth
@@ -2652,9 +2652,23 @@ import { z } from "zod";
2652
2652
  // src/decorator/ai-tool.decorator.ts
2653
2653
  import "reflect-metadata";
2654
2654
  var AI_TOOL_METADATA = /* @__PURE__ */ Symbol("nestjs-agent:ai-tool");
2655
+ function toolNameFromClass(className) {
2656
+ const base = className.replace(/Tool$/, "") || className;
2657
+ const leadingCaps = /^[A-Z]+(?=[A-Z][a-z]|$)/.exec(base)?.[0];
2658
+ if (leadingCaps !== void 0 && leadingCaps.length > 1) {
2659
+ return leadingCaps.toLowerCase() + base.slice(leadingCaps.length);
2660
+ }
2661
+ return base.charAt(0).toLowerCase() + base.slice(1);
2662
+ }
2663
+ __name(toolNameFromClass, "toolNameFromClass");
2655
2664
  function AiTool(options) {
2656
2665
  return (target) => {
2657
- Reflect.defineMetadata(AI_TOOL_METADATA, options, target);
2666
+ const resolved = {
2667
+ ...options,
2668
+ name: options.name ?? toolNameFromClass(target.name),
2669
+ kind: options.kind ?? "read"
2670
+ };
2671
+ Reflect.defineMetadata(AI_TOOL_METADATA, resolved, target);
2658
2672
  };
2659
2673
  }
2660
2674
  __name(AiTool, "AiTool");
@@ -3143,6 +3157,93 @@ var LedgerQuotaStore = class {
3143
3157
  }
3144
3158
  };
3145
3159
 
3160
+ // src/resolver/anonymous-actor-resolver.ts
3161
+ import { createHash, randomBytes } from "crypto";
3162
+ var TOKEN_PATTERN = /^[A-Za-z0-9_-]{43}$/;
3163
+ var MINTED = /* @__PURE__ */ Symbol("nestjs-agent:anonymous-token");
3164
+ function readCookie(req, name) {
3165
+ const header = req.headers?.cookie;
3166
+ const raw = Array.isArray(header) ? header.join("; ") : header;
3167
+ if (raw === void 0) return void 0;
3168
+ for (const pair of raw.split(";")) {
3169
+ const index = pair.indexOf("=");
3170
+ if (index === -1) continue;
3171
+ if (pair.slice(0, index).trim() === name) {
3172
+ try {
3173
+ return decodeURIComponent(pair.slice(index + 1).trim());
3174
+ } catch {
3175
+ return void 0;
3176
+ }
3177
+ }
3178
+ }
3179
+ return void 0;
3180
+ }
3181
+ __name(readCookie, "readCookie");
3182
+ function isHttps(req) {
3183
+ if (req.secure === true) return true;
3184
+ const forwarded = req.headers?.["x-forwarded-proto"];
3185
+ const proto = Array.isArray(forwarded) ? forwarded[0] : forwarded;
3186
+ return proto?.split(",")[0]?.trim() === "https";
3187
+ }
3188
+ __name(isHttps, "isHttps");
3189
+ var AnonymousActorResolver = class {
3190
+ static {
3191
+ __name(this, "AnonymousActorResolver");
3192
+ }
3193
+ options;
3194
+ cookieName;
3195
+ roles;
3196
+ constructor(options = {}) {
3197
+ this.options = options;
3198
+ this.cookieName = options.cookieName ?? "agent_anon";
3199
+ this.roles = options.roles ?? [
3200
+ "anonymous"
3201
+ ];
3202
+ }
3203
+ resolve(request) {
3204
+ const req = typeof request === "object" && request !== null ? request : {};
3205
+ let token = req[MINTED] ?? readCookie(req, this.cookieName);
3206
+ if (token === void 0 || !TOKEN_PATTERN.test(token)) {
3207
+ token = randomBytes(32).toString("base64url");
3208
+ req[MINTED] = token;
3209
+ this.setCookie(req, token);
3210
+ }
3211
+ const digest = createHash("sha256").update(token).digest("base64url").slice(0, 32);
3212
+ return {
3213
+ id: `anon:${digest}`,
3214
+ roles: [
3215
+ ...this.roles
3216
+ ]
3217
+ };
3218
+ }
3219
+ setCookie(req, token) {
3220
+ const res = req.res;
3221
+ if (res?.setHeader === void 0 || res.headersSent === true) return;
3222
+ const sameSite = this.options.sameSite ?? "lax";
3223
+ const secureOption = this.options.secure ?? "auto";
3224
+ const secure = sameSite === "none" || (secureOption === "auto" ? isHttps(req) : secureOption);
3225
+ const maxAge = Math.round((this.options.maxAgeDays ?? 365) * 24 * 60 * 60);
3226
+ const cookie = [
3227
+ `${this.cookieName}=${token}`,
3228
+ `Path=${this.options.path ?? "/"}`,
3229
+ `Max-Age=${maxAge}`,
3230
+ "HttpOnly",
3231
+ `SameSite=${sameSite === "none" ? "None" : sameSite === "strict" ? "Strict" : "Lax"}`,
3232
+ ...secure ? [
3233
+ "Secure"
3234
+ ] : []
3235
+ ].join("; ");
3236
+ const existing = res.getHeader?.("Set-Cookie");
3237
+ const list = Array.isArray(existing) ? existing.map(String) : existing !== void 0 ? [
3238
+ String(existing)
3239
+ ] : [];
3240
+ res.setHeader("Set-Cookie", [
3241
+ ...list,
3242
+ cookie
3243
+ ]);
3244
+ }
3245
+ };
3246
+
3146
3247
  // src/runner/inline-agent-runner.ts
3147
3248
  import { AGENT_DEPS_FACTORY as AGENT_DEPS_FACTORY4, AGENT_STORE as AGENT_STORE3, RunCancelledError, agentFailureCode, encodeStreamEvent, publishAgentRunFailed, runAgentLoop, settleAll, settleUnsettledDelegation } from "@dudousxd/nestjs-agent-core";
3148
3249
  import { Inject as Inject17, Injectable as Injectable7, Logger as Logger4 } from "@nestjs/common";
@@ -3617,7 +3718,51 @@ function _ts_decorate19(decorators, target, key, desc) {
3617
3718
  }
3618
3719
  __name(_ts_decorate19, "_ts_decorate");
3619
3720
  var DEFAULT_PATH = "agent";
3620
- function sharedProviders(durable, includeStore) {
3721
+ var logger = new Logger5("AgentModule");
3722
+ function externalStoreWrapper(modules) {
3723
+ for (const module of modules.values()) {
3724
+ if (module.metatype === AgentModule) continue;
3725
+ const wrapper = module.providers.get(AGENT_STORE4);
3726
+ if (wrapper !== void 0) return wrapper;
3727
+ }
3728
+ return void 0;
3729
+ }
3730
+ __name(externalStoreWrapper, "externalStoreWrapper");
3731
+ function forwardingStore(wrapper) {
3732
+ const target = /* @__PURE__ */ __name(() => {
3733
+ const instance = wrapper.instance;
3734
+ if (instance === void 0 || instance === null) {
3735
+ throw new Error("AgentModule: the AGENT_STORE bound by another module is not ready yet");
3736
+ }
3737
+ return instance;
3738
+ }, "target");
3739
+ return new Proxy({}, {
3740
+ get(_, property) {
3741
+ const store = target();
3742
+ const value = store[property];
3743
+ return typeof value === "function" ? value.bind(store) : value;
3744
+ },
3745
+ has(_, property) {
3746
+ return property in target();
3747
+ }
3748
+ });
3749
+ }
3750
+ __name(forwardingStore, "forwardingStore");
3751
+ function resolveStore(options, modules) {
3752
+ if (options.store !== void 0) return options.store;
3753
+ const external = externalStoreWrapper(modules);
3754
+ if (external !== void 0) return forwardingStore(external);
3755
+ logger.warn("No `store` configured and no store module imported \u2014 using the in-memory store. Threads are lost on restart and not shared between processes: not for production. Pass `store`, or import a store module (e.g. MikroOrmAgentStoreModule.forFeature()).");
3756
+ return new InMemoryAgentStore();
3757
+ }
3758
+ __name(resolveStore, "resolveStore");
3759
+ function resolveCatalog(options) {
3760
+ if (options.models !== void 0) return options.models;
3761
+ const carried = options.model.catalog;
3762
+ return carried !== void 0 && typeof carried.list === "function" ? carried : void 0;
3763
+ }
3764
+ __name(resolveCatalog, "resolveCatalog");
3765
+ function sharedProviders(durable) {
3621
3766
  const providers = [
3622
3767
  {
3623
3768
  provide: AGENT_TOOL_REGISTRY3,
@@ -3675,7 +3820,11 @@ function sharedProviders(durable, includeStore) {
3675
3820
  },
3676
3821
  {
3677
3822
  provide: AGENT_ACTOR_RESOLVER11,
3678
- useFactory: /* @__PURE__ */ __name((options) => options.actorResolver, "useFactory"),
3823
+ useFactory: /* @__PURE__ */ __name((options) => {
3824
+ if (options.actorResolver !== void 0) return options.actorResolver;
3825
+ logger.warn("No `actorResolver` configured \u2014 the agent endpoints are PUBLIC: every browser gets its own anonymous identity (an HttpOnly cookie). Set `actorResolver: requestUserActorResolver()` (or your own) to require login.");
3826
+ return new AnonymousActorResolver();
3827
+ }, "useFactory"),
3679
3828
  inject: [
3680
3829
  AGENT_OPTIONS5
3681
3830
  ]
@@ -3709,7 +3858,7 @@ function sharedProviders(durable, includeStore) {
3709
3858
  },
3710
3859
  {
3711
3860
  provide: AGENT_MODEL_CATALOG2,
3712
- useFactory: /* @__PURE__ */ __name((o) => o.models, "useFactory"),
3861
+ useFactory: /* @__PURE__ */ __name((o) => resolveCatalog(o), "useFactory"),
3713
3862
  inject: [
3714
3863
  AGENT_OPTIONS5
3715
3864
  ]
@@ -3734,15 +3883,14 @@ function sharedProviders(durable, includeStore) {
3734
3883
  useExisting: AgentApprovalPortAdapter
3735
3884
  }
3736
3885
  ];
3737
- if (includeStore) {
3738
- providers.push({
3739
- provide: AGENT_STORE4,
3740
- useFactory: /* @__PURE__ */ __name((o) => o.store, "useFactory"),
3741
- inject: [
3742
- AGENT_OPTIONS5
3743
- ]
3744
- });
3745
- }
3886
+ providers.push({
3887
+ provide: AGENT_STORE4,
3888
+ useFactory: /* @__PURE__ */ __name((o, modules) => resolveStore(o, modules), "useFactory"),
3889
+ inject: [
3890
+ AGENT_OPTIONS5,
3891
+ ModulesContainer
3892
+ ]
3893
+ });
3746
3894
  if (durable) {
3747
3895
  providers.push({
3748
3896
  provide: AGENT_RUNNER2,
@@ -3768,7 +3916,7 @@ function sharedProviders(durable, includeStore) {
3768
3916
  return providers;
3769
3917
  }
3770
3918
  __name(sharedProviders, "sharedProviders");
3771
- function exportsFor(includeStore) {
3919
+ function exportsFor() {
3772
3920
  return [
3773
3921
  AGENT_OPTIONS5,
3774
3922
  AGENT_TOOL_REGISTRY3,
@@ -3777,9 +3925,7 @@ function exportsFor(includeStore) {
3777
3925
  AGENT_ROLES_POLICY2,
3778
3926
  AGENT_ACTOR_RESOLVER11,
3779
3927
  AGENT_MODEL2,
3780
- ...includeStore ? [
3781
- AGENT_STORE4
3782
- ] : [],
3928
+ AGENT_STORE4,
3783
3929
  AGENT_QUOTA_STORE3,
3784
3930
  AGENT_MODEL_CATALOG2,
3785
3931
  AGENT_QUOTA_PROVIDER2,
@@ -3850,7 +3996,6 @@ var AgentModule = class _AgentModule {
3850
3996
  }
3851
3997
  static forRoot(options) {
3852
3998
  const path = options.path ?? DEFAULT_PATH;
3853
- const includeStore = options.store !== void 0;
3854
3999
  applyGuards(options.guards);
3855
4000
  return {
3856
4001
  module: _AgentModule,
@@ -3865,15 +4010,14 @@ var AgentModule = class _AgentModule {
3865
4010
  provide: AGENT_OPTIONS5,
3866
4011
  useValue: options
3867
4012
  },
3868
- ...sharedProviders(options.durable ?? false, includeStore),
4013
+ ...sharedProviders(options.durable ?? false),
3869
4014
  ...guardProviders(options.guards)
3870
4015
  ],
3871
- exports: exportsFor(includeStore)
4016
+ exports: exportsFor()
3872
4017
  };
3873
4018
  }
3874
4019
  static forRootAsync(options) {
3875
4020
  const path = options.path ?? DEFAULT_PATH;
3876
- const includeStore = options.externalStore !== true;
3877
4021
  applyGuards(options.guards);
3878
4022
  return {
3879
4023
  module: _AgentModule,
@@ -3900,10 +4044,10 @@ var AgentModule = class _AgentModule {
3900
4044
  }), "useFactory"),
3901
4045
  inject: options.inject ?? []
3902
4046
  },
3903
- ...sharedProviders(options.durable ?? false, includeStore),
4047
+ ...sharedProviders(options.durable ?? false),
3904
4048
  ...guardProviders(options.guards)
3905
4049
  ],
3906
- exports: exportsFor(includeStore)
4050
+ exports: exportsFor()
3907
4051
  };
3908
4052
  }
3909
4053
  };
@@ -3943,6 +4087,49 @@ var HeaderActorResolver = class {
3943
4087
  }
3944
4088
  };
3945
4089
 
4090
+ // src/resolver/request-user-actor-resolver.ts
4091
+ import { UnauthorizedException as UnauthorizedException2 } from "@nestjs/common";
4092
+ function field(user, ...names) {
4093
+ for (const name of names) {
4094
+ const value = user[name];
4095
+ if (value !== void 0 && value !== null && value !== "") return value;
4096
+ }
4097
+ return void 0;
4098
+ }
4099
+ __name(field, "field");
4100
+ function defaultRequestUserMapper(user) {
4101
+ const id = field(user, "id", "sub", "_id", "userId");
4102
+ if (id === void 0) {
4103
+ throw new UnauthorizedException2("requestUserActorResolver: req.user has no id/sub/_id/userId \u2014 pass a mapper: requestUserActorResolver((user) => ({ id: \u2026, roles: \u2026 }))");
4104
+ }
4105
+ const rawRoles = field(user, "roles", "role");
4106
+ const roles = Array.isArray(rawRoles) ? rawRoles.map(String) : typeof rawRoles === "string" ? [
4107
+ rawRoles
4108
+ ] : [];
4109
+ const tenant = field(user, "tenantRef", "tenantId", "orgId");
4110
+ return {
4111
+ id: String(id),
4112
+ roles,
4113
+ ...tenant !== void 0 ? {
4114
+ tenantRef: String(tenant)
4115
+ } : {}
4116
+ };
4117
+ }
4118
+ __name(defaultRequestUserMapper, "defaultRequestUserMapper");
4119
+ function requestUserActorResolver(map) {
4120
+ return {
4121
+ async resolve(req) {
4122
+ const user = typeof req === "object" && req !== null ? req.user : void 0;
4123
+ if (user === void 0 || user === null || user === false) {
4124
+ throw new UnauthorizedException2("Sign in to use the agent.");
4125
+ }
4126
+ if (map !== void 0) return map(user, req);
4127
+ return defaultRequestUserMapper(user);
4128
+ }
4129
+ };
4130
+ }
4131
+ __name(requestUserActorResolver, "requestUserActorResolver");
4132
+
3946
4133
  // src/index.ts
3947
4134
  export * from "@dudousxd/nestjs-agent-core";
3948
4135
  export {
@@ -3958,6 +4145,7 @@ export {
3958
4145
  AgentService,
3959
4146
  AiTool,
3960
4147
  AiToolDiscoveryService,
4148
+ AnonymousActorResolver,
3961
4149
  AttachmentsController,
3962
4150
  DEFAULT_ALLOWED_ATTACHMENT_CONTENT_TYPES,
3963
4151
  DEFAULT_MAX_ATTACHMENT_BYTES,
@@ -3979,14 +4167,17 @@ export {
3979
4167
  SystemPromptContributor,
3980
4168
  ToolsController,
3981
4169
  declaredSkillProvider,
4170
+ defaultRequestUserMapper,
3982
4171
  delegateToolName,
3983
4172
  provideAgentTool,
3984
4173
  provideAgentTools,
3985
4174
  readAgentMetadata,
3986
4175
  readAiToolMetadata,
3987
4176
  readSkillMetadata,
4177
+ requestUserActorResolver,
3988
4178
  resolveSkillsConfig,
3989
4179
  skillScope,
4180
+ toolNameFromClass,
3990
4181
  utcDay
3991
4182
  };
3992
4183
  //# sourceMappingURL=index.js.map