@dudousxd/nestjs-agent 0.10.1 → 0.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.d.cts CHANGED
@@ -177,6 +177,17 @@ interface AiToolOptions {
177
177
  input: StandardSchemaV1;
178
178
  /** Roles allowed to invoke. Omit to inherit the module's default roles. */
179
179
  roles?: string[];
180
+ /**
181
+ * Whether this tool exists in this deployment. `false` — or a predicate returning `false`, which
182
+ * is re-evaluated every turn — drops it before the role filter, so the model is never shown it.
183
+ * Omit → enabled.
184
+ *
185
+ * Use this for availability that is knowable without DI (a constant, `process.env`, a closure
186
+ * over something the app already holds). When the answer lives in an injected service, implement
187
+ * `isEnabled()` on the class instead: this object is built while the decorator is evaluated, at
188
+ * import time, and can't reach the container.
189
+ */
190
+ enabled?: boolean | (() => boolean | Promise<boolean>);
180
191
  /**
181
192
  * Authz ability checked by an ability-aware RolesPolicy (e.g. `AgentAuthzModule`'s
182
193
  * `AuthzRolesPolicy` → `gate.forUser(actor).allows(ability)`). Ignored by the default
@@ -194,6 +205,18 @@ interface AiToolOptions {
194
205
  * async execute(input, ctx) { return { tempC: 21 }; }
195
206
  * }
196
207
  * ```
208
+ *
209
+ * A tool the deployment can turn off — the flag read through DI, so `.env` and a config service
210
+ * both work:
211
+ *
212
+ * ```ts
213
+ * @AiTool({ name: 'searchDocs', kind: 'read', description: '...', input: schema })
214
+ * class SearchDocsTool implements ToolHandler<Input> {
215
+ * constructor(private readonly config: ConfigService) {}
216
+ * isEnabled() { return this.config.get('DOCS_SEARCH_ENABLED') === 'true'; }
217
+ * async execute(input, ctx) { ... }
218
+ * }
219
+ * ```
197
220
  */
198
221
  declare function AiTool(options: AiToolOptions): ClassDecorator;
199
222
  declare function readAiToolMetadata(target: object): AiToolOptions | undefined;
package/dist/index.d.ts CHANGED
@@ -177,6 +177,17 @@ interface AiToolOptions {
177
177
  input: StandardSchemaV1;
178
178
  /** Roles allowed to invoke. Omit to inherit the module's default roles. */
179
179
  roles?: string[];
180
+ /**
181
+ * Whether this tool exists in this deployment. `false` — or a predicate returning `false`, which
182
+ * is re-evaluated every turn — drops it before the role filter, so the model is never shown it.
183
+ * Omit → enabled.
184
+ *
185
+ * Use this for availability that is knowable without DI (a constant, `process.env`, a closure
186
+ * over something the app already holds). When the answer lives in an injected service, implement
187
+ * `isEnabled()` on the class instead: this object is built while the decorator is evaluated, at
188
+ * import time, and can't reach the container.
189
+ */
190
+ enabled?: boolean | (() => boolean | Promise<boolean>);
180
191
  /**
181
192
  * Authz ability checked by an ability-aware RolesPolicy (e.g. `AgentAuthzModule`'s
182
193
  * `AuthzRolesPolicy` → `gate.forUser(actor).allows(ability)`). Ignored by the default
@@ -194,6 +205,18 @@ interface AiToolOptions {
194
205
  * async execute(input, ctx) { return { tempC: 21 }; }
195
206
  * }
196
207
  * ```
208
+ *
209
+ * A tool the deployment can turn off — the flag read through DI, so `.env` and a config service
210
+ * both work:
211
+ *
212
+ * ```ts
213
+ * @AiTool({ name: 'searchDocs', kind: 'read', description: '...', input: schema })
214
+ * class SearchDocsTool implements ToolHandler<Input> {
215
+ * constructor(private readonly config: ConfigService) {}
216
+ * isEnabled() { return this.config.get('DOCS_SEARCH_ENABLED') === 'true'; }
217
+ * async execute(input, ctx) { ... }
218
+ * }
219
+ * ```
197
220
  */
198
221
  declare function AiTool(options: AiToolOptions): ClassDecorator;
199
222
  declare function readAiToolMetadata(target: object): AiToolOptions | undefined;
package/dist/index.js CHANGED
@@ -1450,9 +1450,21 @@ var AiToolDiscoveryService = class _AiToolDiscoveryService {
1450
1450
  } : {},
1451
1451
  ...meta.ability !== void 0 ? {
1452
1452
  ability: meta.ability
1453
+ } : {},
1454
+ ...meta.enabled !== void 0 ? {
1455
+ enabled: meta.enabled
1453
1456
  } : {}
1454
1457
  }, {
1455
- execute: /* @__PURE__ */ __name((input, ctx) => instance.execute(input, ctx), "execute")
1458
+ execute: /* @__PURE__ */ __name((input, ctx) => instance.execute(input, ctx), "execute"),
1459
+ // Forwarded, not copied: the registry holds this wrapper rather than the provider, so an
1460
+ // `isEnabled()`/`canUse()` left behind here would be a gate that silently never applies.
1461
+ // Called through `instance` so each keeps its `this` (and its injected deps).
1462
+ ...typeof handler.isEnabled === "function" ? {
1463
+ isEnabled: /* @__PURE__ */ __name(() => instance.isEnabled(), "isEnabled")
1464
+ } : {},
1465
+ ...typeof handler.canUse === "function" ? {
1466
+ canUse: /* @__PURE__ */ __name((actor) => instance.canUse(actor), "canUse")
1467
+ } : {}
1456
1468
  });
1457
1469
  count += 1;
1458
1470
  }