@dudousxd/nestjs-agent 1.27.1 → 1.28.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.
@@ -91,7 +91,7 @@ function resolverProviders(resolver) {
91
91
  }
92
92
  __name(resolverProviders, "resolverProviders");
93
93
  function toolOptions(options, resolver) {
94
- const { catalog: _catalog, ...rest } = options;
94
+ const { catalog: _catalog, sandbox: _sandbox, ...rest } = options;
95
95
  return {
96
96
  ...rest,
97
97
  ...resolver !== void 0 ? {
@@ -100,11 +100,19 @@ function toolOptions(options, resolver) {
100
100
  };
101
101
  }
102
102
  __name(toolOptions, "toolOptions");
103
+ function withSandbox(options) {
104
+ const base = options.catalog ?? (0, import_genui.defineCatalog)([]);
105
+ const { sandbox } = options;
106
+ return sandbox === void 0 || sandbox === false ? base : base.extend([
107
+ (0, import_genui.defineSandbox)(sandbox === true ? {} : sandbox)
108
+ ]);
109
+ }
110
+ __name(withSandbox, "withSandbox");
103
111
  function coreProviders(resolver) {
104
112
  return [
105
113
  {
106
114
  provide: GENUI_CATALOG,
107
- useFactory: /* @__PURE__ */ __name((options) => options.catalog ?? (0, import_genui.defineCatalog)([]), "useFactory"),
115
+ useFactory: /* @__PURE__ */ __name((options) => withSandbox(options), "useFactory"),
108
116
  inject: [
109
117
  GENUI_OPTIONS
110
118
  ]
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/genui/index.ts","../../src/genui/agent-genui.module.ts","../../src/functional-tool.ts"],"sourcesContent":["/**\n * `@dudousxd/nestjs-agent/genui` — generative UI for NestJS: {@link AgentGenuiModule} registers the\n * tools that push catalog components, `GENUI_CATALOG` / `@InjectGenuiCatalog()` expose the catalog,\n * and {@link GenuiCatalogResolver} serves per-request (per-tenant) catalogs. The catalog itself —\n * `defineComponent`, `defineCatalog`, validation, text fallbacks — is re-exported from\n * `@dudousxd/nestjs-agent-core/genui`, the isomorphic entry a browser imports too.\n */\nexport {\n AgentGenuiModule,\n type AgentGenuiModuleAsyncOptions,\n type AgentGenuiModuleOptions,\n type AgentGenuiOptions,\n GENUI_CATALOG,\n GENUI_OPTIONS,\n GenuiCatalogResolver,\n InjectGenuiCatalog,\n} from './agent-genui.module.js';\nexport * from '@dudousxd/nestjs-agent-core/genui';\n","import type { ToolPresentation } from '@dudousxd/nestjs-agent-core';\nimport type {\n Catalog,\n GenuiCatalogScope,\n GenuiStreaming,\n GenuiToolsOptions,\n TreeLimits,\n TreeSchemaMode,\n} from '@dudousxd/nestjs-agent-core/genui';\nimport { defineCatalog, genuiTools } from '@dudousxd/nestjs-agent-core/genui';\nimport {\n type DynamicModule,\n type FactoryProvider,\n Inject,\n Module,\n type ModuleMetadata,\n type Provider,\n type Type,\n} from '@nestjs/common';\nimport { provideAgentTools } from '../functional-tool.js';\n\n/** The app's genui catalog — `@InjectGenuiCatalog()` it anywhere; `overrideProvider` it in tests. */\nexport const GENUI_CATALOG = Symbol.for('@dudousxd/nestjs-agent:genui-catalog');\n\n/** The resolved {@link AgentGenuiOptions} (without the resolver). */\nexport const GENUI_OPTIONS = Symbol.for('@dudousxd/nestjs-agent:genui-options');\n\n/** Inject the app's genui catalog ({@link GENUI_CATALOG}). */\nexport const InjectGenuiCatalog = (): ParameterDecorator & PropertyDecorator =>\n Inject(GENUI_CATALOG);\n\n/**\n * Picks the catalog for ONE request — a tenant's own, versioned components. Consulted when a genui\n * call is validated and when the turn's tool list is described to the model, so components can\n * change without rebuilding tools at boot. Cache in here if resolving costs a round trip: it runs\n * once per turn per genui tool, and once per call.\n *\n * Provide it through `AgentGenuiModule.forRoot({ resolver })` (a class, resolved with DI, or an\n * instance); it is then injectable, and replaceable in a test with\n * `overrideProvider(GenuiCatalogResolver)`.\n */\nexport abstract class GenuiCatalogResolver {\n abstract resolve(scope: GenuiCatalogScope): Catalog | Promise<Catalog>;\n}\n\n/** What {@link AgentGenuiModule} builds tools from. */\nexport interface AgentGenuiOptions {\n /**\n * The catalog. With a {@link GenuiCatalogResolver} it is the boot-time one — it names the\n * per-component tools — and may be empty. Default: an empty catalog.\n */\n catalog?: Catalog;\n /**\n * `tree` (default): one `ui__render` tool taking a composed tree (a single node is pushed as that\n * component). `per-component`: one `ui__show_<snake>` tool per component.\n */\n mode?: 'per-component' | 'tree';\n /** `ui__render`'s input schema: `'strict'` (default, a `$defs` union per component) or `'loose'`. */\n treeSchema?: TreeSchemaMode;\n /**\n * Tree mode: `'complete'` (default) draws the tree once the call has run; `'partial'` streams it\n * as `partial` ui frames while the model writes it. A component's own `streaming` overrides it.\n */\n streaming?: GenuiStreaming;\n /** Least time between two partial tree frames of one call, in ms. Default 100. */\n streamingThrottleMs?: number;\n /** End the model's turn once a genui call succeeds (no narrating follow-up call). */\n terminal?: boolean;\n /** Tool name in `tree` mode. Default `ui__render`. */\n treeToolName?: string;\n /** Text prepended to the tree tool's description. */\n treeInstructions?: string;\n treeLimits?: TreeLimits;\n /** Tool-name prefix in `per-component` mode. Default `ui__show_`. */\n namePrefix?: string;\n /**\n * Also register ONE generic tool taking `{ component, props }`, validated against the request's\n * catalog — how a model reaches a tenant's own components, which no boot-time tool names. `true`\n * names it `ui__show`.\n */\n showTool?: boolean | string;\n /** Text prepended to the show tool's description. */\n showInstructions?: string;\n /** Roles allowed to call the tools. Undefined → the roles policy default. */\n roles?: string[];\n /** Override the generated presentation per component (or per tree / show tool name). */\n presentation?: (component: string) => ToolPresentation | undefined;\n}\n\ntype ResolverOption = Type<GenuiCatalogResolver> | GenuiCatalogResolver;\n\nexport interface AgentGenuiModuleOptions extends AgentGenuiOptions {\n /** Per-request catalogs. A class is instantiated with DI (its dependencies must be global or exported to the root). */\n resolver?: ResolverOption;\n}\n\nexport interface AgentGenuiModuleAsyncOptions extends Pick<ModuleMetadata, 'imports'> {\n inject?: FactoryProvider['inject'];\n useFactory: (...deps: any[]) => AgentGenuiOptions | Promise<AgentGenuiOptions>;\n /** Per-request catalogs. A class resolves its dependencies from `imports`. */\n resolver?: ResolverOption;\n}\n\nfunction resolverProviders(resolver: ResolverOption | undefined): Provider[] {\n if (resolver === undefined) return [];\n return [\n typeof resolver === 'function'\n ? { provide: GenuiCatalogResolver, useClass: resolver }\n : { provide: GenuiCatalogResolver, useValue: resolver },\n ];\n}\n\nfunction toolOptions(\n options: AgentGenuiOptions,\n resolver: GenuiCatalogResolver | undefined,\n): GenuiToolsOptions {\n const { catalog: _catalog, ...rest } = options;\n return {\n ...rest,\n ...(resolver !== undefined\n ? { resolveCatalog: (scope: GenuiCatalogScope) => resolver.resolve(scope) }\n : {}),\n };\n}\n\nfunction coreProviders(resolver: ResolverOption | undefined): Provider[] {\n return [\n {\n provide: GENUI_CATALOG,\n useFactory: (options: AgentGenuiOptions) => options.catalog ?? defineCatalog([]),\n inject: [GENUI_OPTIONS],\n },\n ...resolverProviders(resolver),\n // The generated tools, registered by the agent module's discovery like any `provideAgentTool`.\n // Built from the injected catalog, so `overrideProvider(GENUI_CATALOG)` changes them too.\n provideAgentTools(\n (options: AgentGenuiOptions, catalog: Catalog, perRequest?: GenuiCatalogResolver) =>\n genuiTools(catalog, toolOptions(options, perRequest)),\n [GENUI_OPTIONS, GENUI_CATALOG, { token: GenuiCatalogResolver, optional: true }],\n ),\n ];\n}\n\nconst EXPORTS = [GENUI_CATALOG, GENUI_OPTIONS];\n\n/**\n * Generative UI for the agent: registers the tools that let the model push catalog components\n * (one `ui__render` tree tool, or `ui__show_<component>` per component, and/or the generic\n * `ui__show`), and makes the catalog\n * injectable. Global, like `AgentModule`; import it once, next to it.\n *\n * ```ts\n * AgentGenuiModule.forRoot({ catalog, mode: 'tree', terminal: true })\n * ```\n */\n@Module({})\nexport class AgentGenuiModule {\n static forRoot(options: AgentGenuiModuleOptions = {}): DynamicModule {\n const { resolver, ...rest } = options;\n return {\n module: AgentGenuiModule,\n global: true,\n providers: [{ provide: GENUI_OPTIONS, useValue: rest }, ...coreProviders(resolver)],\n exports: resolver === undefined ? EXPORTS : [...EXPORTS, GenuiCatalogResolver],\n };\n }\n\n static forRootAsync(options: AgentGenuiModuleAsyncOptions): DynamicModule {\n return {\n module: AgentGenuiModule,\n global: true,\n imports: options.imports ?? [],\n providers: [\n { provide: GENUI_OPTIONS, useFactory: options.useFactory, inject: options.inject ?? [] },\n ...coreProviders(options.resolver),\n ],\n exports: options.resolver === undefined ? EXPORTS : [...EXPORTS, GenuiCatalogResolver],\n };\n }\n}\n","import {\n type FunctionalToolDefinition,\n type ToolHandler,\n type ToolSpec,\n createFunctionalTool,\n} from '@dudousxd/nestjs-agent-core';\nimport type { FactoryProvider, Provider } from '@nestjs/common';\n\n/**\n * Brand stamped onto a functional-tool provider instance so `AiToolDiscoveryService` picks it up\n * when it walks every provider at boot — the declarative alternative to a manual `registry.register`.\n */\nexport const AGENT_TOOL_BRAND = Symbol.for('@dudousxd/nestjs-agent:functional-tool');\n\n/** A tool expressed as data + handler (e.g. from `createExecuteSqlTool`), not an `@AiTool` class. */\nexport interface FunctionalTool {\n spec: ToolSpec;\n handler: ToolHandler;\n}\n\n/** A {@link FunctionalTool} carrying {@link AGENT_TOOL_BRAND} — what a provider resolves to. */\nexport interface BrandedFunctionalTool extends FunctionalTool {\n readonly [AGENT_TOOL_BRAND]: true;\n}\n\nfunction brand(tool: FunctionalTool): BrandedFunctionalTool {\n return { [AGENT_TOOL_BRAND]: true, spec: tool.spec, handler: tool.handler };\n}\n\n/** Narrows a provider instance to a branded functional tool for boot-time registration. */\nexport function isBrandedFunctionalTool(value: object): value is BrandedFunctionalTool {\n return AGENT_TOOL_BRAND in value && 'spec' in value && 'handler' in value;\n}\n\n/**\n * Registers a functional tool declaratively — drop the returned provider in a module's `providers`\n * and `AiToolDiscoveryService` auto-registers it at boot. Each call uses a fresh, unique provide\n * token so the same tool can be provided many times without collisions.\n *\n * Two forms: a static tool (`useValue`) or a factory with `inject` for DI-resolved dependencies\n * (`useFactory`). Either way the resolved instance is branded with {@link AGENT_TOOL_BRAND}.\n */\nexport function provideAgentTool(tool: FunctionalTool): Provider;\nexport function provideAgentTool(\n factory: (...deps: never[]) => FunctionalTool,\n inject?: FactoryProvider['inject'],\n): Provider;\nexport function provideAgentTool(\n factoryOrTool: FunctionalTool | ((...deps: never[]) => FunctionalTool),\n inject?: FactoryProvider['inject'],\n): Provider {\n const provide = Symbol('nestjs-agent:functional-tool-instance');\n if (typeof factoryOrTool === 'function') {\n return {\n provide,\n useFactory: (...deps: never[]) => brand(factoryOrTool(...deps)),\n inject: inject ?? [],\n };\n }\n return { provide, useValue: brand(factoryOrTool) };\n}\n\n/**\n * Registers a LIST of functional tools from one factory — for a producer whose tool count is only\n * known once its dependencies resolve (a catalog loaded from config, one tool per entry). The\n * factory's result is branded element by element; `AiToolDiscoveryService` registers each.\n */\nexport function provideAgentTools(\n factory: (...deps: never[]) => readonly FunctionalTool[] | Promise<readonly FunctionalTool[]>,\n inject?: FactoryProvider['inject'],\n): Provider {\n return {\n provide: Symbol('nestjs-agent:functional-tool-list'),\n useFactory: async (...deps: never[]) => (await factory(...deps)).map(brand),\n inject: inject ?? [],\n };\n}\n\n/** Author a functional tool with inferred Standard Schema input and domain output. */\nexport const defineTool = createFunctionalTool;\nexport type { FunctionalToolDefinition };\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAAA;;;;;;;;;;;ACSA,mBAA0C;AAC1C,oBAQO;;;AClBP,+BAKO;AAOA,IAAMA,mBAAmBC,uBAAOC,IAAI,wCAAA;AAa3C,SAASC,MAAMC,MAAoB;AACjC,SAAO;IAAE,CAACJ,gBAAAA,GAAmB;IAAMK,MAAMD,KAAKC;IAAMC,SAASF,KAAKE;EAAQ;AAC5E;AAFSH;AA0CF,SAASI,kBACdC,SACAC,QAAkC;AAElC,SAAO;IACLC,SAASC,uBAAO,mCAAA;IAChBC,YAAY,iCAAUC,UAAmB,MAAML,QAAAA,GAAWK,IAAAA,GAAOC,IAAIC,KAAAA,GAAzD;IACZN,QAAQA,UAAU,CAAA;EACpB;AACF;AATgBF;;;;;;;;;;;;;;;;;AD7CT,IAAMS,gBAAgBC,uBAAOC,IAAI,sCAAA;AAGjC,IAAMC,gBAAgBF,uBAAOC,IAAI,sCAAA;AAGjC,IAAME,qBAAqB,iCAChCC,sBAAOL,aAAAA,GADyB;AAa3B,IAAeM,uBAAf,MAAeA;SAAAA;;;AAEtB;AA4DA,SAASC,kBAAkBC,UAAoC;AAC7D,MAAIA,aAAaC,OAAW,QAAO,CAAA;AACnC,SAAO;IACL,OAAOD,aAAa,aAChB;MAAEE,SAASJ;MAAsBK,UAAUH;IAAS,IACpD;MAAEE,SAASJ;MAAsBM,UAAUJ;IAAS;;AAE5D;AAPSD;AAST,SAASM,YACPC,SACAN,UAA0C;AAE1C,QAAM,EAAEO,SAASC,UAAU,GAAGC,KAAAA,IAASH;AACvC,SAAO;IACL,GAAGG;IACH,GAAIT,aAAaC,SACb;MAAES,gBAAgB,wBAACC,UAA6BX,SAASY,QAAQD,KAAAA,GAA/C;IAAsD,IACxE,CAAC;EACP;AACF;AAXSN;AAaT,SAASQ,cAAcb,UAAoC;AACzD,SAAO;IACL;MACEE,SAASV;MACTsB,YAAY,wBAACR,YAA+BA,QAAQC,eAAWQ,4BAAc,CAAA,CAAE,GAAnE;MACZC,QAAQ;QAACrB;;IACX;OACGI,kBAAkBC,QAAAA;;;IAGrBiB,kBACE,CAACX,SAA4BC,SAAkBW,mBAC7CC,yBAAWZ,SAASF,YAAYC,SAASY,UAAAA,CAAAA,GAC3C;MAACvB;MAAeH;MAAe;QAAE4B,OAAOtB;QAAsBuB,UAAU;MAAK;KAAE;;AAGrF;AAhBSR;AAkBT,IAAMS,UAAU;EAAC9B;EAAeG;;AAazB,IAAM4B,mBAAN,MAAMA,kBAAAA;SAAAA;;;EACX,OAAOC,QAAQlB,UAAmC,CAAC,GAAkB;AACnE,UAAM,EAAEN,UAAU,GAAGS,KAAAA,IAASH;AAC9B,WAAO;MACLmB,QAAQF;MACRG,QAAQ;MACRC,WAAW;QAAC;UAAEzB,SAASP;UAAeS,UAAUK;QAAK;WAAMI,cAAcb,QAAAA;;MACzE4B,SAAS5B,aAAaC,SAAYqB,UAAU;WAAIA;QAASxB;;IAC3D;EACF;EAEA,OAAO+B,aAAavB,SAAsD;AACxE,WAAO;MACLmB,QAAQF;MACRG,QAAQ;MACRI,SAASxB,QAAQwB,WAAW,CAAA;MAC5BH,WAAW;QACT;UAAEzB,SAASP;UAAemB,YAAYR,QAAQQ;UAAYE,QAAQV,QAAQU,UAAU,CAAA;QAAG;WACpFH,cAAcP,QAAQN,QAAQ;;MAEnC4B,SAAStB,QAAQN,aAAaC,SAAYqB,UAAU;WAAIA;QAASxB;;IACnE;EACF;AACF;;;;;;ADlKA,0BAAc,8CAjBd;","names":["AGENT_TOOL_BRAND","Symbol","for","brand","tool","spec","handler","provideAgentTools","factory","inject","provide","Symbol","useFactory","deps","map","brand","GENUI_CATALOG","Symbol","for","GENUI_OPTIONS","InjectGenuiCatalog","Inject","GenuiCatalogResolver","resolverProviders","resolver","undefined","provide","useClass","useValue","toolOptions","options","catalog","_catalog","rest","resolveCatalog","scope","resolve","coreProviders","useFactory","defineCatalog","inject","provideAgentTools","perRequest","genuiTools","token","optional","EXPORTS","AgentGenuiModule","forRoot","module","global","providers","exports","forRootAsync","imports"]}
1
+ {"version":3,"sources":["../../src/genui/index.ts","../../src/genui/agent-genui.module.ts","../../src/functional-tool.ts"],"sourcesContent":["/**\n * `@dudousxd/nestjs-agent/genui` — generative UI for NestJS: {@link AgentGenuiModule} registers the\n * tools that push catalog components, `GENUI_CATALOG` / `@InjectGenuiCatalog()` expose the catalog,\n * and {@link GenuiCatalogResolver} serves per-request (per-tenant) catalogs. The catalog itself —\n * `defineComponent`, `defineCatalog`, validation, text fallbacks — is re-exported from\n * `@dudousxd/nestjs-agent-core/genui`, the isomorphic entry a browser imports too.\n */\nexport {\n AgentGenuiModule,\n type AgentGenuiModuleAsyncOptions,\n type AgentGenuiModuleOptions,\n type AgentGenuiOptions,\n GENUI_CATALOG,\n GENUI_OPTIONS,\n GenuiCatalogResolver,\n InjectGenuiCatalog,\n} from './agent-genui.module.js';\nexport * from '@dudousxd/nestjs-agent-core/genui';\n","import type { ToolPresentation } from '@dudousxd/nestjs-agent-core';\nimport type {\n Catalog,\n GenuiCatalogScope,\n GenuiStreaming,\n GenuiToolsOptions,\n TreeLimits,\n TreeSchemaMode,\n} from '@dudousxd/nestjs-agent-core/genui';\nimport {\n type DefineSandboxOptions,\n defineCatalog,\n defineSandbox,\n genuiTools,\n} from '@dudousxd/nestjs-agent-core/genui';\nimport {\n type DynamicModule,\n type FactoryProvider,\n Inject,\n Module,\n type ModuleMetadata,\n type Provider,\n type Type,\n} from '@nestjs/common';\nimport { provideAgentTools } from '../functional-tool.js';\n\n/** The app's genui catalog — `@InjectGenuiCatalog()` it anywhere; `overrideProvider` it in tests. */\nexport const GENUI_CATALOG = Symbol.for('@dudousxd/nestjs-agent:genui-catalog');\n\n/** The resolved {@link AgentGenuiOptions} (without the resolver). */\nexport const GENUI_OPTIONS = Symbol.for('@dudousxd/nestjs-agent:genui-options');\n\n/** Inject the app's genui catalog ({@link GENUI_CATALOG}). */\nexport const InjectGenuiCatalog = (): ParameterDecorator & PropertyDecorator =>\n Inject(GENUI_CATALOG);\n\n/**\n * Picks the catalog for ONE request — a tenant's own, versioned components. Consulted when a genui\n * call is validated and when the turn's tool list is described to the model, so components can\n * change without rebuilding tools at boot. Cache in here if resolving costs a round trip: it runs\n * once per turn per genui tool, and once per call.\n *\n * Provide it through `AgentGenuiModule.forRoot({ resolver })` (a class, resolved with DI, or an\n * instance); it is then injectable, and replaceable in a test with\n * `overrideProvider(GenuiCatalogResolver)`.\n */\nexport abstract class GenuiCatalogResolver {\n abstract resolve(scope: GenuiCatalogScope): Catalog | Promise<Catalog>;\n}\n\n/** What {@link AgentGenuiModule} builds tools from. */\nexport interface AgentGenuiOptions {\n /**\n * The catalog. With a {@link GenuiCatalogResolver} it is the boot-time one — it names the\n * per-component tools — and may be empty. Default: an empty catalog.\n */\n catalog?: Catalog;\n /**\n * `tree` (default): one `ui__render` tool taking a composed tree (a single node is pushed as that\n * component). `per-component`: one `ui__show_<snake>` tool per component.\n */\n mode?: 'per-component' | 'tree';\n /** `ui__render`'s input schema: `'strict'` (default, a `$defs` union per component) or `'loose'`. */\n treeSchema?: TreeSchemaMode;\n /**\n * Tree mode: `'complete'` (default) draws the tree once the call has run; `'partial'` streams it\n * as `partial` ui frames while the model writes it. A component's own `streaming` overrides it.\n */\n streaming?: GenuiStreaming;\n /** Least time between two partial tree frames of one call, in ms. Default 100. */\n streamingThrottleMs?: number;\n /** End the model's turn once a genui call succeeds (no narrating follow-up call). */\n terminal?: boolean;\n /** Tool name in `tree` mode. Default `ui__render`. */\n treeToolName?: string;\n /** Text prepended to the tree tool's description. */\n treeInstructions?: string;\n treeLimits?: TreeLimits;\n /** Tool-name prefix in `per-component` mode. Default `ui__show_`. */\n namePrefix?: string;\n /**\n * Also register ONE generic tool taking `{ component, props }`, validated against the request's\n * catalog — how a model reaches a tenant's own components, which no boot-time tool names. `true`\n * names it `ui__show`.\n */\n showTool?: boolean | string;\n /** Text prepended to the show tool's description. */\n showInstructions?: string;\n /** Roles allowed to call the tools. Undefined → the roles policy default. */\n roles?: string[];\n /** Override the generated presentation per component (or per tree / show tool name). */\n presentation?: (component: string) => ToolPresentation | undefined;\n /**\n * Add the sandbox component (`Sandbox`): the model may write HTML, CSS and JS for a one-off\n * interactive answer when no catalog component fits. `true` for the defaults (no network), or\n * the {@link DefineSandboxOptions} (a policy listing origins, extra instructions). Off by default.\n * The browser's catalog should carry the same definition (`defineSandbox(...)` in the shared\n * catalog file) so the renderer enforces the same policy.\n */\n sandbox?: boolean | DefineSandboxOptions;\n}\n\ntype ResolverOption = Type<GenuiCatalogResolver> | GenuiCatalogResolver;\n\nexport interface AgentGenuiModuleOptions extends AgentGenuiOptions {\n /** Per-request catalogs. A class is instantiated with DI (its dependencies must be global or exported to the root). */\n resolver?: ResolverOption;\n}\n\nexport interface AgentGenuiModuleAsyncOptions extends Pick<ModuleMetadata, 'imports'> {\n inject?: FactoryProvider['inject'];\n useFactory: (...deps: any[]) => AgentGenuiOptions | Promise<AgentGenuiOptions>;\n /** Per-request catalogs. A class resolves its dependencies from `imports`. */\n resolver?: ResolverOption;\n}\n\nfunction resolverProviders(resolver: ResolverOption | undefined): Provider[] {\n if (resolver === undefined) return [];\n return [\n typeof resolver === 'function'\n ? { provide: GenuiCatalogResolver, useClass: resolver }\n : { provide: GenuiCatalogResolver, useValue: resolver },\n ];\n}\n\nfunction toolOptions(\n options: AgentGenuiOptions,\n resolver: GenuiCatalogResolver | undefined,\n): GenuiToolsOptions {\n const { catalog: _catalog, sandbox: _sandbox, ...rest } = options;\n return {\n ...rest,\n ...(resolver !== undefined\n ? { resolveCatalog: (scope: GenuiCatalogScope) => resolver.resolve(scope) }\n : {}),\n };\n}\n\n/** The configured catalog, with the sandbox component added when `sandbox` asks for it. */\nfunction withSandbox(options: AgentGenuiOptions): Catalog {\n const base = options.catalog ?? defineCatalog([]);\n const { sandbox } = options;\n return sandbox === undefined || sandbox === false\n ? base\n : base.extend([defineSandbox(sandbox === true ? {} : sandbox)]);\n}\n\nfunction coreProviders(resolver: ResolverOption | undefined): Provider[] {\n return [\n {\n provide: GENUI_CATALOG,\n useFactory: (options: AgentGenuiOptions) => withSandbox(options),\n inject: [GENUI_OPTIONS],\n },\n ...resolverProviders(resolver),\n // The generated tools, registered by the agent module's discovery like any `provideAgentTool`.\n // Built from the injected catalog, so `overrideProvider(GENUI_CATALOG)` changes them too.\n provideAgentTools(\n (options: AgentGenuiOptions, catalog: Catalog, perRequest?: GenuiCatalogResolver) =>\n genuiTools(catalog, toolOptions(options, perRequest)),\n [GENUI_OPTIONS, GENUI_CATALOG, { token: GenuiCatalogResolver, optional: true }],\n ),\n ];\n}\n\nconst EXPORTS = [GENUI_CATALOG, GENUI_OPTIONS];\n\n/**\n * Generative UI for the agent: registers the tools that let the model push catalog components\n * (one `ui__render` tree tool, or `ui__show_<component>` per component, and/or the generic\n * `ui__show`), and makes the catalog\n * injectable. Global, like `AgentModule`; import it once, next to it.\n *\n * ```ts\n * AgentGenuiModule.forRoot({ catalog, mode: 'tree', terminal: true })\n * ```\n */\n@Module({})\nexport class AgentGenuiModule {\n static forRoot(options: AgentGenuiModuleOptions = {}): DynamicModule {\n const { resolver, ...rest } = options;\n return {\n module: AgentGenuiModule,\n global: true,\n providers: [{ provide: GENUI_OPTIONS, useValue: rest }, ...coreProviders(resolver)],\n exports: resolver === undefined ? EXPORTS : [...EXPORTS, GenuiCatalogResolver],\n };\n }\n\n static forRootAsync(options: AgentGenuiModuleAsyncOptions): DynamicModule {\n return {\n module: AgentGenuiModule,\n global: true,\n imports: options.imports ?? [],\n providers: [\n { provide: GENUI_OPTIONS, useFactory: options.useFactory, inject: options.inject ?? [] },\n ...coreProviders(options.resolver),\n ],\n exports: options.resolver === undefined ? EXPORTS : [...EXPORTS, GenuiCatalogResolver],\n };\n }\n}\n","import {\n type FunctionalToolDefinition,\n type ToolHandler,\n type ToolSpec,\n createFunctionalTool,\n} from '@dudousxd/nestjs-agent-core';\nimport type { FactoryProvider, Provider } from '@nestjs/common';\n\n/**\n * Brand stamped onto a functional-tool provider instance so `AiToolDiscoveryService` picks it up\n * when it walks every provider at boot — the declarative alternative to a manual `registry.register`.\n */\nexport const AGENT_TOOL_BRAND = Symbol.for('@dudousxd/nestjs-agent:functional-tool');\n\n/** A tool expressed as data + handler (e.g. from `createExecuteSqlTool`), not an `@AiTool` class. */\nexport interface FunctionalTool {\n spec: ToolSpec;\n handler: ToolHandler;\n}\n\n/** A {@link FunctionalTool} carrying {@link AGENT_TOOL_BRAND} — what a provider resolves to. */\nexport interface BrandedFunctionalTool extends FunctionalTool {\n readonly [AGENT_TOOL_BRAND]: true;\n}\n\nfunction brand(tool: FunctionalTool): BrandedFunctionalTool {\n return { [AGENT_TOOL_BRAND]: true, spec: tool.spec, handler: tool.handler };\n}\n\n/** Narrows a provider instance to a branded functional tool for boot-time registration. */\nexport function isBrandedFunctionalTool(value: object): value is BrandedFunctionalTool {\n return AGENT_TOOL_BRAND in value && 'spec' in value && 'handler' in value;\n}\n\n/**\n * Registers a functional tool declaratively — drop the returned provider in a module's `providers`\n * and `AiToolDiscoveryService` auto-registers it at boot. Each call uses a fresh, unique provide\n * token so the same tool can be provided many times without collisions.\n *\n * Two forms: a static tool (`useValue`) or a factory with `inject` for DI-resolved dependencies\n * (`useFactory`). Either way the resolved instance is branded with {@link AGENT_TOOL_BRAND}.\n */\nexport function provideAgentTool(tool: FunctionalTool): Provider;\nexport function provideAgentTool(\n factory: (...deps: never[]) => FunctionalTool,\n inject?: FactoryProvider['inject'],\n): Provider;\nexport function provideAgentTool(\n factoryOrTool: FunctionalTool | ((...deps: never[]) => FunctionalTool),\n inject?: FactoryProvider['inject'],\n): Provider {\n const provide = Symbol('nestjs-agent:functional-tool-instance');\n if (typeof factoryOrTool === 'function') {\n return {\n provide,\n useFactory: (...deps: never[]) => brand(factoryOrTool(...deps)),\n inject: inject ?? [],\n };\n }\n return { provide, useValue: brand(factoryOrTool) };\n}\n\n/**\n * Registers a LIST of functional tools from one factory — for a producer whose tool count is only\n * known once its dependencies resolve (a catalog loaded from config, one tool per entry). The\n * factory's result is branded element by element; `AiToolDiscoveryService` registers each.\n */\nexport function provideAgentTools(\n factory: (...deps: never[]) => readonly FunctionalTool[] | Promise<readonly FunctionalTool[]>,\n inject?: FactoryProvider['inject'],\n): Provider {\n return {\n provide: Symbol('nestjs-agent:functional-tool-list'),\n useFactory: async (...deps: never[]) => (await factory(...deps)).map(brand),\n inject: inject ?? [],\n };\n}\n\n/** Author a functional tool with inferred Standard Schema input and domain output. */\nexport const defineTool = createFunctionalTool;\nexport type { FunctionalToolDefinition };\n"],"mappings":"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","names":["AGENT_TOOL_BRAND","Symbol","for","brand","tool","spec","handler","provideAgentTools","factory","inject","provide","Symbol","useFactory","deps","map","brand","GENUI_CATALOG","Symbol","for","GENUI_OPTIONS","InjectGenuiCatalog","Inject","GenuiCatalogResolver","resolverProviders","resolver","undefined","provide","useClass","useValue","toolOptions","options","catalog","_catalog","sandbox","_sandbox","rest","resolveCatalog","scope","resolve","withSandbox","base","defineCatalog","extend","defineSandbox","coreProviders","useFactory","inject","provideAgentTools","perRequest","genuiTools","token","optional","EXPORTS","AgentGenuiModule","forRoot","module","global","providers","exports","forRootAsync","imports"]}
@@ -1,5 +1,5 @@
1
1
  import { ToolPresentation } from '@dudousxd/nestjs-agent-core';
2
- import { GenuiCatalogScope, Catalog, TreeSchemaMode, GenuiStreaming, TreeLimits } from '@dudousxd/nestjs-agent-core/genui';
2
+ import { GenuiCatalogScope, Catalog, TreeSchemaMode, GenuiStreaming, TreeLimits, DefineSandboxOptions } from '@dudousxd/nestjs-agent-core/genui';
3
3
  export * from '@dudousxd/nestjs-agent-core/genui';
4
4
  import { Type, DynamicModule, ModuleMetadata, FactoryProvider } from '@nestjs/common';
5
5
 
@@ -64,6 +64,14 @@ interface AgentGenuiOptions {
64
64
  roles?: string[];
65
65
  /** Override the generated presentation per component (or per tree / show tool name). */
66
66
  presentation?: (component: string) => ToolPresentation | undefined;
67
+ /**
68
+ * Add the sandbox component (`Sandbox`): the model may write HTML, CSS and JS for a one-off
69
+ * interactive answer when no catalog component fits. `true` for the defaults (no network), or
70
+ * the {@link DefineSandboxOptions} (a policy listing origins, extra instructions). Off by default.
71
+ * The browser's catalog should carry the same definition (`defineSandbox(...)` in the shared
72
+ * catalog file) so the renderer enforces the same policy.
73
+ */
74
+ sandbox?: boolean | DefineSandboxOptions;
67
75
  }
68
76
  type ResolverOption = Type<GenuiCatalogResolver> | GenuiCatalogResolver;
69
77
  interface AgentGenuiModuleOptions extends AgentGenuiOptions {
@@ -1,5 +1,5 @@
1
1
  import { ToolPresentation } from '@dudousxd/nestjs-agent-core';
2
- import { GenuiCatalogScope, Catalog, TreeSchemaMode, GenuiStreaming, TreeLimits } from '@dudousxd/nestjs-agent-core/genui';
2
+ import { GenuiCatalogScope, Catalog, TreeSchemaMode, GenuiStreaming, TreeLimits, DefineSandboxOptions } from '@dudousxd/nestjs-agent-core/genui';
3
3
  export * from '@dudousxd/nestjs-agent-core/genui';
4
4
  import { Type, DynamicModule, ModuleMetadata, FactoryProvider } from '@nestjs/common';
5
5
 
@@ -64,6 +64,14 @@ interface AgentGenuiOptions {
64
64
  roles?: string[];
65
65
  /** Override the generated presentation per component (or per tree / show tool name). */
66
66
  presentation?: (component: string) => ToolPresentation | undefined;
67
+ /**
68
+ * Add the sandbox component (`Sandbox`): the model may write HTML, CSS and JS for a one-off
69
+ * interactive answer when no catalog component fits. `true` for the defaults (no network), or
70
+ * the {@link DefineSandboxOptions} (a policy listing origins, extra instructions). Off by default.
71
+ * The browser's catalog should carry the same definition (`defineSandbox(...)` in the shared
72
+ * catalog file) so the renderer enforces the same policy.
73
+ */
74
+ sandbox?: boolean | DefineSandboxOptions;
67
75
  }
68
76
  type ResolverOption = Type<GenuiCatalogResolver> | GenuiCatalogResolver;
69
77
  interface AgentGenuiModuleOptions extends AgentGenuiOptions {
@@ -2,7 +2,7 @@ var __defProp = Object.defineProperty;
2
2
  var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
3
3
 
4
4
  // src/genui/agent-genui.module.ts
5
- import { defineCatalog, genuiTools } from "@dudousxd/nestjs-agent-core/genui";
5
+ import { defineCatalog, defineSandbox, genuiTools } from "@dudousxd/nestjs-agent-core/genui";
6
6
  import { Inject, Module } from "@nestjs/common";
7
7
 
8
8
  // src/functional-tool.ts
@@ -62,7 +62,7 @@ function resolverProviders(resolver) {
62
62
  }
63
63
  __name(resolverProviders, "resolverProviders");
64
64
  function toolOptions(options, resolver) {
65
- const { catalog: _catalog, ...rest } = options;
65
+ const { catalog: _catalog, sandbox: _sandbox, ...rest } = options;
66
66
  return {
67
67
  ...rest,
68
68
  ...resolver !== void 0 ? {
@@ -71,11 +71,19 @@ function toolOptions(options, resolver) {
71
71
  };
72
72
  }
73
73
  __name(toolOptions, "toolOptions");
74
+ function withSandbox(options) {
75
+ const base = options.catalog ?? defineCatalog([]);
76
+ const { sandbox } = options;
77
+ return sandbox === void 0 || sandbox === false ? base : base.extend([
78
+ defineSandbox(sandbox === true ? {} : sandbox)
79
+ ]);
80
+ }
81
+ __name(withSandbox, "withSandbox");
74
82
  function coreProviders(resolver) {
75
83
  return [
76
84
  {
77
85
  provide: GENUI_CATALOG,
78
- useFactory: /* @__PURE__ */ __name((options) => options.catalog ?? defineCatalog([]), "useFactory"),
86
+ useFactory: /* @__PURE__ */ __name((options) => withSandbox(options), "useFactory"),
79
87
  inject: [
80
88
  GENUI_OPTIONS
81
89
  ]
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/genui/agent-genui.module.ts","../../src/functional-tool.ts","../../src/genui/index.ts"],"sourcesContent":["import type { ToolPresentation } from '@dudousxd/nestjs-agent-core';\nimport type {\n Catalog,\n GenuiCatalogScope,\n GenuiStreaming,\n GenuiToolsOptions,\n TreeLimits,\n TreeSchemaMode,\n} from '@dudousxd/nestjs-agent-core/genui';\nimport { defineCatalog, genuiTools } from '@dudousxd/nestjs-agent-core/genui';\nimport {\n type DynamicModule,\n type FactoryProvider,\n Inject,\n Module,\n type ModuleMetadata,\n type Provider,\n type Type,\n} from '@nestjs/common';\nimport { provideAgentTools } from '../functional-tool.js';\n\n/** The app's genui catalog — `@InjectGenuiCatalog()` it anywhere; `overrideProvider` it in tests. */\nexport const GENUI_CATALOG = Symbol.for('@dudousxd/nestjs-agent:genui-catalog');\n\n/** The resolved {@link AgentGenuiOptions} (without the resolver). */\nexport const GENUI_OPTIONS = Symbol.for('@dudousxd/nestjs-agent:genui-options');\n\n/** Inject the app's genui catalog ({@link GENUI_CATALOG}). */\nexport const InjectGenuiCatalog = (): ParameterDecorator & PropertyDecorator =>\n Inject(GENUI_CATALOG);\n\n/**\n * Picks the catalog for ONE request — a tenant's own, versioned components. Consulted when a genui\n * call is validated and when the turn's tool list is described to the model, so components can\n * change without rebuilding tools at boot. Cache in here if resolving costs a round trip: it runs\n * once per turn per genui tool, and once per call.\n *\n * Provide it through `AgentGenuiModule.forRoot({ resolver })` (a class, resolved with DI, or an\n * instance); it is then injectable, and replaceable in a test with\n * `overrideProvider(GenuiCatalogResolver)`.\n */\nexport abstract class GenuiCatalogResolver {\n abstract resolve(scope: GenuiCatalogScope): Catalog | Promise<Catalog>;\n}\n\n/** What {@link AgentGenuiModule} builds tools from. */\nexport interface AgentGenuiOptions {\n /**\n * The catalog. With a {@link GenuiCatalogResolver} it is the boot-time one — it names the\n * per-component tools — and may be empty. Default: an empty catalog.\n */\n catalog?: Catalog;\n /**\n * `tree` (default): one `ui__render` tool taking a composed tree (a single node is pushed as that\n * component). `per-component`: one `ui__show_<snake>` tool per component.\n */\n mode?: 'per-component' | 'tree';\n /** `ui__render`'s input schema: `'strict'` (default, a `$defs` union per component) or `'loose'`. */\n treeSchema?: TreeSchemaMode;\n /**\n * Tree mode: `'complete'` (default) draws the tree once the call has run; `'partial'` streams it\n * as `partial` ui frames while the model writes it. A component's own `streaming` overrides it.\n */\n streaming?: GenuiStreaming;\n /** Least time between two partial tree frames of one call, in ms. Default 100. */\n streamingThrottleMs?: number;\n /** End the model's turn once a genui call succeeds (no narrating follow-up call). */\n terminal?: boolean;\n /** Tool name in `tree` mode. Default `ui__render`. */\n treeToolName?: string;\n /** Text prepended to the tree tool's description. */\n treeInstructions?: string;\n treeLimits?: TreeLimits;\n /** Tool-name prefix in `per-component` mode. Default `ui__show_`. */\n namePrefix?: string;\n /**\n * Also register ONE generic tool taking `{ component, props }`, validated against the request's\n * catalog — how a model reaches a tenant's own components, which no boot-time tool names. `true`\n * names it `ui__show`.\n */\n showTool?: boolean | string;\n /** Text prepended to the show tool's description. */\n showInstructions?: string;\n /** Roles allowed to call the tools. Undefined → the roles policy default. */\n roles?: string[];\n /** Override the generated presentation per component (or per tree / show tool name). */\n presentation?: (component: string) => ToolPresentation | undefined;\n}\n\ntype ResolverOption = Type<GenuiCatalogResolver> | GenuiCatalogResolver;\n\nexport interface AgentGenuiModuleOptions extends AgentGenuiOptions {\n /** Per-request catalogs. A class is instantiated with DI (its dependencies must be global or exported to the root). */\n resolver?: ResolverOption;\n}\n\nexport interface AgentGenuiModuleAsyncOptions extends Pick<ModuleMetadata, 'imports'> {\n inject?: FactoryProvider['inject'];\n useFactory: (...deps: any[]) => AgentGenuiOptions | Promise<AgentGenuiOptions>;\n /** Per-request catalogs. A class resolves its dependencies from `imports`. */\n resolver?: ResolverOption;\n}\n\nfunction resolverProviders(resolver: ResolverOption | undefined): Provider[] {\n if (resolver === undefined) return [];\n return [\n typeof resolver === 'function'\n ? { provide: GenuiCatalogResolver, useClass: resolver }\n : { provide: GenuiCatalogResolver, useValue: resolver },\n ];\n}\n\nfunction toolOptions(\n options: AgentGenuiOptions,\n resolver: GenuiCatalogResolver | undefined,\n): GenuiToolsOptions {\n const { catalog: _catalog, ...rest } = options;\n return {\n ...rest,\n ...(resolver !== undefined\n ? { resolveCatalog: (scope: GenuiCatalogScope) => resolver.resolve(scope) }\n : {}),\n };\n}\n\nfunction coreProviders(resolver: ResolverOption | undefined): Provider[] {\n return [\n {\n provide: GENUI_CATALOG,\n useFactory: (options: AgentGenuiOptions) => options.catalog ?? defineCatalog([]),\n inject: [GENUI_OPTIONS],\n },\n ...resolverProviders(resolver),\n // The generated tools, registered by the agent module's discovery like any `provideAgentTool`.\n // Built from the injected catalog, so `overrideProvider(GENUI_CATALOG)` changes them too.\n provideAgentTools(\n (options: AgentGenuiOptions, catalog: Catalog, perRequest?: GenuiCatalogResolver) =>\n genuiTools(catalog, toolOptions(options, perRequest)),\n [GENUI_OPTIONS, GENUI_CATALOG, { token: GenuiCatalogResolver, optional: true }],\n ),\n ];\n}\n\nconst EXPORTS = [GENUI_CATALOG, GENUI_OPTIONS];\n\n/**\n * Generative UI for the agent: registers the tools that let the model push catalog components\n * (one `ui__render` tree tool, or `ui__show_<component>` per component, and/or the generic\n * `ui__show`), and makes the catalog\n * injectable. Global, like `AgentModule`; import it once, next to it.\n *\n * ```ts\n * AgentGenuiModule.forRoot({ catalog, mode: 'tree', terminal: true })\n * ```\n */\n@Module({})\nexport class AgentGenuiModule {\n static forRoot(options: AgentGenuiModuleOptions = {}): DynamicModule {\n const { resolver, ...rest } = options;\n return {\n module: AgentGenuiModule,\n global: true,\n providers: [{ provide: GENUI_OPTIONS, useValue: rest }, ...coreProviders(resolver)],\n exports: resolver === undefined ? EXPORTS : [...EXPORTS, GenuiCatalogResolver],\n };\n }\n\n static forRootAsync(options: AgentGenuiModuleAsyncOptions): DynamicModule {\n return {\n module: AgentGenuiModule,\n global: true,\n imports: options.imports ?? [],\n providers: [\n { provide: GENUI_OPTIONS, useFactory: options.useFactory, inject: options.inject ?? [] },\n ...coreProviders(options.resolver),\n ],\n exports: options.resolver === undefined ? EXPORTS : [...EXPORTS, GenuiCatalogResolver],\n };\n }\n}\n","import {\n type FunctionalToolDefinition,\n type ToolHandler,\n type ToolSpec,\n createFunctionalTool,\n} from '@dudousxd/nestjs-agent-core';\nimport type { FactoryProvider, Provider } from '@nestjs/common';\n\n/**\n * Brand stamped onto a functional-tool provider instance so `AiToolDiscoveryService` picks it up\n * when it walks every provider at boot — the declarative alternative to a manual `registry.register`.\n */\nexport const AGENT_TOOL_BRAND = Symbol.for('@dudousxd/nestjs-agent:functional-tool');\n\n/** A tool expressed as data + handler (e.g. from `createExecuteSqlTool`), not an `@AiTool` class. */\nexport interface FunctionalTool {\n spec: ToolSpec;\n handler: ToolHandler;\n}\n\n/** A {@link FunctionalTool} carrying {@link AGENT_TOOL_BRAND} — what a provider resolves to. */\nexport interface BrandedFunctionalTool extends FunctionalTool {\n readonly [AGENT_TOOL_BRAND]: true;\n}\n\nfunction brand(tool: FunctionalTool): BrandedFunctionalTool {\n return { [AGENT_TOOL_BRAND]: true, spec: tool.spec, handler: tool.handler };\n}\n\n/** Narrows a provider instance to a branded functional tool for boot-time registration. */\nexport function isBrandedFunctionalTool(value: object): value is BrandedFunctionalTool {\n return AGENT_TOOL_BRAND in value && 'spec' in value && 'handler' in value;\n}\n\n/**\n * Registers a functional tool declaratively — drop the returned provider in a module's `providers`\n * and `AiToolDiscoveryService` auto-registers it at boot. Each call uses a fresh, unique provide\n * token so the same tool can be provided many times without collisions.\n *\n * Two forms: a static tool (`useValue`) or a factory with `inject` for DI-resolved dependencies\n * (`useFactory`). Either way the resolved instance is branded with {@link AGENT_TOOL_BRAND}.\n */\nexport function provideAgentTool(tool: FunctionalTool): Provider;\nexport function provideAgentTool(\n factory: (...deps: never[]) => FunctionalTool,\n inject?: FactoryProvider['inject'],\n): Provider;\nexport function provideAgentTool(\n factoryOrTool: FunctionalTool | ((...deps: never[]) => FunctionalTool),\n inject?: FactoryProvider['inject'],\n): Provider {\n const provide = Symbol('nestjs-agent:functional-tool-instance');\n if (typeof factoryOrTool === 'function') {\n return {\n provide,\n useFactory: (...deps: never[]) => brand(factoryOrTool(...deps)),\n inject: inject ?? [],\n };\n }\n return { provide, useValue: brand(factoryOrTool) };\n}\n\n/**\n * Registers a LIST of functional tools from one factory — for a producer whose tool count is only\n * known once its dependencies resolve (a catalog loaded from config, one tool per entry). The\n * factory's result is branded element by element; `AiToolDiscoveryService` registers each.\n */\nexport function provideAgentTools(\n factory: (...deps: never[]) => readonly FunctionalTool[] | Promise<readonly FunctionalTool[]>,\n inject?: FactoryProvider['inject'],\n): Provider {\n return {\n provide: Symbol('nestjs-agent:functional-tool-list'),\n useFactory: async (...deps: never[]) => (await factory(...deps)).map(brand),\n inject: inject ?? [],\n };\n}\n\n/** Author a functional tool with inferred Standard Schema input and domain output. */\nexport const defineTool = createFunctionalTool;\nexport type { FunctionalToolDefinition };\n","/**\n * `@dudousxd/nestjs-agent/genui` — generative UI for NestJS: {@link AgentGenuiModule} registers the\n * tools that push catalog components, `GENUI_CATALOG` / `@InjectGenuiCatalog()` expose the catalog,\n * and {@link GenuiCatalogResolver} serves per-request (per-tenant) catalogs. The catalog itself —\n * `defineComponent`, `defineCatalog`, validation, text fallbacks — is re-exported from\n * `@dudousxd/nestjs-agent-core/genui`, the isomorphic entry a browser imports too.\n */\nexport {\n AgentGenuiModule,\n type AgentGenuiModuleAsyncOptions,\n type AgentGenuiModuleOptions,\n type AgentGenuiOptions,\n GENUI_CATALOG,\n GENUI_OPTIONS,\n GenuiCatalogResolver,\n InjectGenuiCatalog,\n} from './agent-genui.module.js';\nexport * from '@dudousxd/nestjs-agent-core/genui';\n"],"mappings":";;;;AASA,SAASA,eAAeC,kBAAkB;AAC1C,SAGEC,QACAC,cAIK;;;AClBP,SAIEC,4BACK;AAOA,IAAMC,mBAAmBC,uBAAOC,IAAI,wCAAA;AAa3C,SAASC,MAAMC,MAAoB;AACjC,SAAO;IAAE,CAACJ,gBAAAA,GAAmB;IAAMK,MAAMD,KAAKC;IAAMC,SAASF,KAAKE;EAAQ;AAC5E;AAFSH;AA0CF,SAASI,kBACdC,SACAC,QAAkC;AAElC,SAAO;IACLC,SAASC,uBAAO,mCAAA;IAChBC,YAAY,iCAAUC,UAAmB,MAAML,QAAAA,GAAWK,IAAAA,GAAOC,IAAIC,KAAAA,GAAzD;IACZN,QAAQA,UAAU,CAAA;EACpB;AACF;AATgBF;;;;;;;;;;;;;;;;;AD7CT,IAAMS,gBAAgBC,uBAAOC,IAAI,sCAAA;AAGjC,IAAMC,gBAAgBF,uBAAOC,IAAI,sCAAA;AAGjC,IAAME,qBAAqB,6BAChCC,OAAOL,aAAAA,GADyB;AAa3B,IAAeM,uBAAf,MAAeA;SAAAA;;;AAEtB;AA4DA,SAASC,kBAAkBC,UAAoC;AAC7D,MAAIA,aAAaC,OAAW,QAAO,CAAA;AACnC,SAAO;IACL,OAAOD,aAAa,aAChB;MAAEE,SAASJ;MAAsBK,UAAUH;IAAS,IACpD;MAAEE,SAASJ;MAAsBM,UAAUJ;IAAS;;AAE5D;AAPSD;AAST,SAASM,YACPC,SACAN,UAA0C;AAE1C,QAAM,EAAEO,SAASC,UAAU,GAAGC,KAAAA,IAASH;AACvC,SAAO;IACL,GAAGG;IACH,GAAIT,aAAaC,SACb;MAAES,gBAAgB,wBAACC,UAA6BX,SAASY,QAAQD,KAAAA,GAA/C;IAAsD,IACxE,CAAC;EACP;AACF;AAXSN;AAaT,SAASQ,cAAcb,UAAoC;AACzD,SAAO;IACL;MACEE,SAASV;MACTsB,YAAY,wBAACR,YAA+BA,QAAQC,WAAWQ,cAAc,CAAA,CAAE,GAAnE;MACZC,QAAQ;QAACrB;;IACX;OACGI,kBAAkBC,QAAAA;;;IAGrBiB,kBACE,CAACX,SAA4BC,SAAkBW,eAC7CC,WAAWZ,SAASF,YAAYC,SAASY,UAAAA,CAAAA,GAC3C;MAACvB;MAAeH;MAAe;QAAE4B,OAAOtB;QAAsBuB,UAAU;MAAK;KAAE;;AAGrF;AAhBSR;AAkBT,IAAMS,UAAU;EAAC9B;EAAeG;;AAazB,IAAM4B,mBAAN,MAAMA,kBAAAA;SAAAA;;;EACX,OAAOC,QAAQlB,UAAmC,CAAC,GAAkB;AACnE,UAAM,EAAEN,UAAU,GAAGS,KAAAA,IAASH;AAC9B,WAAO;MACLmB,QAAQF;MACRG,QAAQ;MACRC,WAAW;QAAC;UAAEzB,SAASP;UAAeS,UAAUK;QAAK;WAAMI,cAAcb,QAAAA;;MACzE4B,SAAS5B,aAAaC,SAAYqB,UAAU;WAAIA;QAASxB;;IAC3D;EACF;EAEA,OAAO+B,aAAavB,SAAsD;AACxE,WAAO;MACLmB,QAAQF;MACRG,QAAQ;MACRI,SAASxB,QAAQwB,WAAW,CAAA;MAC5BH,WAAW;QACT;UAAEzB,SAASP;UAAemB,YAAYR,QAAQQ;UAAYE,QAAQV,QAAQU,UAAU,CAAA;QAAG;WACpFH,cAAcP,QAAQN,QAAQ;;MAEnC4B,SAAStB,QAAQN,aAAaC,SAAYqB,UAAU;WAAIA;QAASxB;;IACnE;EACF;AACF;;;;;;AElKA,cAAc;","names":["defineCatalog","genuiTools","Inject","Module","createFunctionalTool","AGENT_TOOL_BRAND","Symbol","for","brand","tool","spec","handler","provideAgentTools","factory","inject","provide","Symbol","useFactory","deps","map","brand","GENUI_CATALOG","Symbol","for","GENUI_OPTIONS","InjectGenuiCatalog","Inject","GenuiCatalogResolver","resolverProviders","resolver","undefined","provide","useClass","useValue","toolOptions","options","catalog","_catalog","rest","resolveCatalog","scope","resolve","coreProviders","useFactory","defineCatalog","inject","provideAgentTools","perRequest","genuiTools","token","optional","EXPORTS","AgentGenuiModule","forRoot","module","global","providers","exports","forRootAsync","imports"]}
1
+ {"version":3,"sources":["../../src/genui/agent-genui.module.ts","../../src/functional-tool.ts","../../src/genui/index.ts"],"sourcesContent":["import type { ToolPresentation } from '@dudousxd/nestjs-agent-core';\nimport type {\n Catalog,\n GenuiCatalogScope,\n GenuiStreaming,\n GenuiToolsOptions,\n TreeLimits,\n TreeSchemaMode,\n} from '@dudousxd/nestjs-agent-core/genui';\nimport {\n type DefineSandboxOptions,\n defineCatalog,\n defineSandbox,\n genuiTools,\n} from '@dudousxd/nestjs-agent-core/genui';\nimport {\n type DynamicModule,\n type FactoryProvider,\n Inject,\n Module,\n type ModuleMetadata,\n type Provider,\n type Type,\n} from '@nestjs/common';\nimport { provideAgentTools } from '../functional-tool.js';\n\n/** The app's genui catalog — `@InjectGenuiCatalog()` it anywhere; `overrideProvider` it in tests. */\nexport const GENUI_CATALOG = Symbol.for('@dudousxd/nestjs-agent:genui-catalog');\n\n/** The resolved {@link AgentGenuiOptions} (without the resolver). */\nexport const GENUI_OPTIONS = Symbol.for('@dudousxd/nestjs-agent:genui-options');\n\n/** Inject the app's genui catalog ({@link GENUI_CATALOG}). */\nexport const InjectGenuiCatalog = (): ParameterDecorator & PropertyDecorator =>\n Inject(GENUI_CATALOG);\n\n/**\n * Picks the catalog for ONE request — a tenant's own, versioned components. Consulted when a genui\n * call is validated and when the turn's tool list is described to the model, so components can\n * change without rebuilding tools at boot. Cache in here if resolving costs a round trip: it runs\n * once per turn per genui tool, and once per call.\n *\n * Provide it through `AgentGenuiModule.forRoot({ resolver })` (a class, resolved with DI, or an\n * instance); it is then injectable, and replaceable in a test with\n * `overrideProvider(GenuiCatalogResolver)`.\n */\nexport abstract class GenuiCatalogResolver {\n abstract resolve(scope: GenuiCatalogScope): Catalog | Promise<Catalog>;\n}\n\n/** What {@link AgentGenuiModule} builds tools from. */\nexport interface AgentGenuiOptions {\n /**\n * The catalog. With a {@link GenuiCatalogResolver} it is the boot-time one — it names the\n * per-component tools — and may be empty. Default: an empty catalog.\n */\n catalog?: Catalog;\n /**\n * `tree` (default): one `ui__render` tool taking a composed tree (a single node is pushed as that\n * component). `per-component`: one `ui__show_<snake>` tool per component.\n */\n mode?: 'per-component' | 'tree';\n /** `ui__render`'s input schema: `'strict'` (default, a `$defs` union per component) or `'loose'`. */\n treeSchema?: TreeSchemaMode;\n /**\n * Tree mode: `'complete'` (default) draws the tree once the call has run; `'partial'` streams it\n * as `partial` ui frames while the model writes it. A component's own `streaming` overrides it.\n */\n streaming?: GenuiStreaming;\n /** Least time between two partial tree frames of one call, in ms. Default 100. */\n streamingThrottleMs?: number;\n /** End the model's turn once a genui call succeeds (no narrating follow-up call). */\n terminal?: boolean;\n /** Tool name in `tree` mode. Default `ui__render`. */\n treeToolName?: string;\n /** Text prepended to the tree tool's description. */\n treeInstructions?: string;\n treeLimits?: TreeLimits;\n /** Tool-name prefix in `per-component` mode. Default `ui__show_`. */\n namePrefix?: string;\n /**\n * Also register ONE generic tool taking `{ component, props }`, validated against the request's\n * catalog — how a model reaches a tenant's own components, which no boot-time tool names. `true`\n * names it `ui__show`.\n */\n showTool?: boolean | string;\n /** Text prepended to the show tool's description. */\n showInstructions?: string;\n /** Roles allowed to call the tools. Undefined → the roles policy default. */\n roles?: string[];\n /** Override the generated presentation per component (or per tree / show tool name). */\n presentation?: (component: string) => ToolPresentation | undefined;\n /**\n * Add the sandbox component (`Sandbox`): the model may write HTML, CSS and JS for a one-off\n * interactive answer when no catalog component fits. `true` for the defaults (no network), or\n * the {@link DefineSandboxOptions} (a policy listing origins, extra instructions). Off by default.\n * The browser's catalog should carry the same definition (`defineSandbox(...)` in the shared\n * catalog file) so the renderer enforces the same policy.\n */\n sandbox?: boolean | DefineSandboxOptions;\n}\n\ntype ResolverOption = Type<GenuiCatalogResolver> | GenuiCatalogResolver;\n\nexport interface AgentGenuiModuleOptions extends AgentGenuiOptions {\n /** Per-request catalogs. A class is instantiated with DI (its dependencies must be global or exported to the root). */\n resolver?: ResolverOption;\n}\n\nexport interface AgentGenuiModuleAsyncOptions extends Pick<ModuleMetadata, 'imports'> {\n inject?: FactoryProvider['inject'];\n useFactory: (...deps: any[]) => AgentGenuiOptions | Promise<AgentGenuiOptions>;\n /** Per-request catalogs. A class resolves its dependencies from `imports`. */\n resolver?: ResolverOption;\n}\n\nfunction resolverProviders(resolver: ResolverOption | undefined): Provider[] {\n if (resolver === undefined) return [];\n return [\n typeof resolver === 'function'\n ? { provide: GenuiCatalogResolver, useClass: resolver }\n : { provide: GenuiCatalogResolver, useValue: resolver },\n ];\n}\n\nfunction toolOptions(\n options: AgentGenuiOptions,\n resolver: GenuiCatalogResolver | undefined,\n): GenuiToolsOptions {\n const { catalog: _catalog, sandbox: _sandbox, ...rest } = options;\n return {\n ...rest,\n ...(resolver !== undefined\n ? { resolveCatalog: (scope: GenuiCatalogScope) => resolver.resolve(scope) }\n : {}),\n };\n}\n\n/** The configured catalog, with the sandbox component added when `sandbox` asks for it. */\nfunction withSandbox(options: AgentGenuiOptions): Catalog {\n const base = options.catalog ?? defineCatalog([]);\n const { sandbox } = options;\n return sandbox === undefined || sandbox === false\n ? base\n : base.extend([defineSandbox(sandbox === true ? {} : sandbox)]);\n}\n\nfunction coreProviders(resolver: ResolverOption | undefined): Provider[] {\n return [\n {\n provide: GENUI_CATALOG,\n useFactory: (options: AgentGenuiOptions) => withSandbox(options),\n inject: [GENUI_OPTIONS],\n },\n ...resolverProviders(resolver),\n // The generated tools, registered by the agent module's discovery like any `provideAgentTool`.\n // Built from the injected catalog, so `overrideProvider(GENUI_CATALOG)` changes them too.\n provideAgentTools(\n (options: AgentGenuiOptions, catalog: Catalog, perRequest?: GenuiCatalogResolver) =>\n genuiTools(catalog, toolOptions(options, perRequest)),\n [GENUI_OPTIONS, GENUI_CATALOG, { token: GenuiCatalogResolver, optional: true }],\n ),\n ];\n}\n\nconst EXPORTS = [GENUI_CATALOG, GENUI_OPTIONS];\n\n/**\n * Generative UI for the agent: registers the tools that let the model push catalog components\n * (one `ui__render` tree tool, or `ui__show_<component>` per component, and/or the generic\n * `ui__show`), and makes the catalog\n * injectable. Global, like `AgentModule`; import it once, next to it.\n *\n * ```ts\n * AgentGenuiModule.forRoot({ catalog, mode: 'tree', terminal: true })\n * ```\n */\n@Module({})\nexport class AgentGenuiModule {\n static forRoot(options: AgentGenuiModuleOptions = {}): DynamicModule {\n const { resolver, ...rest } = options;\n return {\n module: AgentGenuiModule,\n global: true,\n providers: [{ provide: GENUI_OPTIONS, useValue: rest }, ...coreProviders(resolver)],\n exports: resolver === undefined ? EXPORTS : [...EXPORTS, GenuiCatalogResolver],\n };\n }\n\n static forRootAsync(options: AgentGenuiModuleAsyncOptions): DynamicModule {\n return {\n module: AgentGenuiModule,\n global: true,\n imports: options.imports ?? [],\n providers: [\n { provide: GENUI_OPTIONS, useFactory: options.useFactory, inject: options.inject ?? [] },\n ...coreProviders(options.resolver),\n ],\n exports: options.resolver === undefined ? EXPORTS : [...EXPORTS, GenuiCatalogResolver],\n };\n }\n}\n","import {\n type FunctionalToolDefinition,\n type ToolHandler,\n type ToolSpec,\n createFunctionalTool,\n} from '@dudousxd/nestjs-agent-core';\nimport type { FactoryProvider, Provider } from '@nestjs/common';\n\n/**\n * Brand stamped onto a functional-tool provider instance so `AiToolDiscoveryService` picks it up\n * when it walks every provider at boot — the declarative alternative to a manual `registry.register`.\n */\nexport const AGENT_TOOL_BRAND = Symbol.for('@dudousxd/nestjs-agent:functional-tool');\n\n/** A tool expressed as data + handler (e.g. from `createExecuteSqlTool`), not an `@AiTool` class. */\nexport interface FunctionalTool {\n spec: ToolSpec;\n handler: ToolHandler;\n}\n\n/** A {@link FunctionalTool} carrying {@link AGENT_TOOL_BRAND} — what a provider resolves to. */\nexport interface BrandedFunctionalTool extends FunctionalTool {\n readonly [AGENT_TOOL_BRAND]: true;\n}\n\nfunction brand(tool: FunctionalTool): BrandedFunctionalTool {\n return { [AGENT_TOOL_BRAND]: true, spec: tool.spec, handler: tool.handler };\n}\n\n/** Narrows a provider instance to a branded functional tool for boot-time registration. */\nexport function isBrandedFunctionalTool(value: object): value is BrandedFunctionalTool {\n return AGENT_TOOL_BRAND in value && 'spec' in value && 'handler' in value;\n}\n\n/**\n * Registers a functional tool declaratively — drop the returned provider in a module's `providers`\n * and `AiToolDiscoveryService` auto-registers it at boot. Each call uses a fresh, unique provide\n * token so the same tool can be provided many times without collisions.\n *\n * Two forms: a static tool (`useValue`) or a factory with `inject` for DI-resolved dependencies\n * (`useFactory`). Either way the resolved instance is branded with {@link AGENT_TOOL_BRAND}.\n */\nexport function provideAgentTool(tool: FunctionalTool): Provider;\nexport function provideAgentTool(\n factory: (...deps: never[]) => FunctionalTool,\n inject?: FactoryProvider['inject'],\n): Provider;\nexport function provideAgentTool(\n factoryOrTool: FunctionalTool | ((...deps: never[]) => FunctionalTool),\n inject?: FactoryProvider['inject'],\n): Provider {\n const provide = Symbol('nestjs-agent:functional-tool-instance');\n if (typeof factoryOrTool === 'function') {\n return {\n provide,\n useFactory: (...deps: never[]) => brand(factoryOrTool(...deps)),\n inject: inject ?? [],\n };\n }\n return { provide, useValue: brand(factoryOrTool) };\n}\n\n/**\n * Registers a LIST of functional tools from one factory — for a producer whose tool count is only\n * known once its dependencies resolve (a catalog loaded from config, one tool per entry). The\n * factory's result is branded element by element; `AiToolDiscoveryService` registers each.\n */\nexport function provideAgentTools(\n factory: (...deps: never[]) => readonly FunctionalTool[] | Promise<readonly FunctionalTool[]>,\n inject?: FactoryProvider['inject'],\n): Provider {\n return {\n provide: Symbol('nestjs-agent:functional-tool-list'),\n useFactory: async (...deps: never[]) => (await factory(...deps)).map(brand),\n inject: inject ?? [],\n };\n}\n\n/** Author a functional tool with inferred Standard Schema input and domain output. */\nexport const defineTool = createFunctionalTool;\nexport type { FunctionalToolDefinition };\n","/**\n * `@dudousxd/nestjs-agent/genui` — generative UI for NestJS: {@link AgentGenuiModule} registers the\n * tools that push catalog components, `GENUI_CATALOG` / `@InjectGenuiCatalog()` expose the catalog,\n * and {@link GenuiCatalogResolver} serves per-request (per-tenant) catalogs. The catalog itself —\n * `defineComponent`, `defineCatalog`, validation, text fallbacks — is re-exported from\n * `@dudousxd/nestjs-agent-core/genui`, the isomorphic entry a browser imports too.\n */\nexport {\n AgentGenuiModule,\n type AgentGenuiModuleAsyncOptions,\n type AgentGenuiModuleOptions,\n type AgentGenuiOptions,\n GENUI_CATALOG,\n GENUI_OPTIONS,\n GenuiCatalogResolver,\n InjectGenuiCatalog,\n} from './agent-genui.module.js';\nexport * from '@dudousxd/nestjs-agent-core/genui';\n"],"mappings":"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","names":["defineCatalog","defineSandbox","genuiTools","Inject","Module","createFunctionalTool","AGENT_TOOL_BRAND","Symbol","for","brand","tool","spec","handler","provideAgentTools","factory","inject","provide","Symbol","useFactory","deps","map","brand","GENUI_CATALOG","Symbol","for","GENUI_OPTIONS","InjectGenuiCatalog","Inject","GenuiCatalogResolver","resolverProviders","resolver","undefined","provide","useClass","useValue","toolOptions","options","catalog","_catalog","sandbox","_sandbox","rest","resolveCatalog","scope","resolve","withSandbox","base","defineCatalog","extend","defineSandbox","coreProviders","useFactory","inject","provideAgentTools","perRequest","genuiTools","token","optional","EXPORTS","AgentGenuiModule","forRoot","module","global","providers","exports","forRootAsync","imports"]}