@dudousxd/nestjs-agent 0.9.0 → 0.10.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/agent.module.ts","../src/agent-deps.factory.ts","../src/agent.service.ts","../src/agent-deps.ts","../src/approval-port.adapter.ts","../src/controller/agents.controller.ts","../src/controller/attachments.controller.ts","../src/controller/chat.controller.ts","../src/controller/quota.controller.ts","../src/controller/threads.controller.ts","../src/controller/tool-call.controller.ts","../src/discovery/agent-discovery.service.ts","../src/decorator/agent.decorator.ts","../src/decorator/system-prompt.decorator.ts","../src/discovery/ai-tool-discovery.service.ts","../src/decorator/ai-tool.decorator.ts","../src/functional-tool.ts","../src/in-process-sink.ts","../src/ledger-quota-store.ts","../src/runner/inline-agent-runner.ts","../src/resolver/header-actor-resolver.ts"],"sourcesContent":["export { AgentModule } from './agent.module.js';\nexport { AgentApprovalPortAdapter } from './approval-port.adapter.js';\nexport type {\n AgentModuleOptions,\n AgentModuleAsyncOptions,\n AgentAttachmentsOptions,\n} from './agent.options.js';\nexport { AgentService, type ChatParams } from './agent.service.js';\nexport {\n AttachmentsController,\n DEFAULT_MAX_ATTACHMENT_BYTES,\n DEFAULT_ALLOWED_ATTACHMENT_CONTENT_TYPES,\n} from './controller/attachments.controller.js';\nexport {\n AiTool,\n type AiToolOptions,\n AI_TOOL_METADATA,\n readAiToolMetadata,\n} from './decorator/ai-tool.decorator.js';\nexport {\n Agent,\n type AgentOptions,\n AGENT_METADATA,\n readAgentMetadata,\n} from './decorator/agent.decorator.js';\nexport {\n SystemPrompt,\n SystemPromptContributor,\n SYSTEM_PROMPT_METADATA,\n SYSTEM_PROMPT_CONTRIBUTOR_METADATA,\n} from './decorator/system-prompt.decorator.js';\nexport { AiToolDiscoveryService } from './discovery/ai-tool-discovery.service.js';\nexport { AgentDiscoveryService } from './discovery/agent-discovery.service.js';\nexport {\n provideAgentTool,\n AGENT_TOOL_BRAND,\n type FunctionalTool,\n} from './functional-tool.js';\nexport { InlineAgentRunner } from './runner/inline-agent-runner.js';\nexport { InProcessTokenStreamSink } from './in-process-sink.js';\nexport { LedgerQuotaStore } from './ledger-quota-store.js';\nexport { type AgentDeps, utcDay } from './agent-deps.js';\nexport { AgentDepsFactory, delegateToolName } from './agent-deps.factory.js';\nexport { HeaderActorResolver } from './resolver/header-actor-resolver.js';\n\n// Re-export the core surface so consumers import tools/types from one place.\nexport * from '@dudousxd/nestjs-agent-core';\n","import {\n AGENT_ACTOR_RESOLVER,\n AGENT_APPROVAL_PORT,\n AGENT_DEPS_FACTORY,\n AGENT_DURABLE_RUNNER,\n AGENT_MODEL,\n AGENT_OPTIONS,\n AGENT_PROMPT_CONTRIBUTORS,\n AGENT_QUOTA_STORE,\n AGENT_REGISTRY,\n AGENT_ROLES_POLICY,\n AGENT_RUNNER,\n AGENT_SINK,\n AGENT_STORE,\n AGENT_TOOL_REGISTRY,\n AgentRegistry,\n type AgentRunner,\n type AgentStore,\n DefaultRolesPolicy,\n ToolRegistry,\n} from '@dudousxd/nestjs-agent-core';\nimport {\n type CanActivate,\n type DynamicModule,\n Global,\n Module,\n type Provider,\n type Type,\n} from '@nestjs/common';\nimport { DiscoveryModule, RouterModule } from '@nestjs/core';\nimport { AgentDepsFactory } from './agent-deps.factory.js';\nimport type { AgentModuleAsyncOptions, AgentModuleOptions } from './agent.options.js';\nimport { AgentService } from './agent.service.js';\nimport { AgentApprovalPortAdapter } from './approval-port.adapter.js';\nimport { AgentsController } from './controller/agents.controller.js';\nimport { AttachmentsController } from './controller/attachments.controller.js';\nimport { ChatController } from './controller/chat.controller.js';\nimport { QuotaController } from './controller/quota.controller.js';\nimport { ThreadsController } from './controller/threads.controller.js';\nimport { ToolCallController } from './controller/tool-call.controller.js';\nimport { AgentDiscoveryService } from './discovery/agent-discovery.service.js';\nimport { AiToolDiscoveryService } from './discovery/ai-tool-discovery.service.js';\nimport { InProcessTokenStreamSink } from './in-process-sink.js';\nimport { LedgerQuotaStore } from './ledger-quota-store.js';\nimport { InlineAgentRunner } from './runner/inline-agent-runner.js';\n\n/** Default route prefix the controllers mount under. */\nconst DEFAULT_PATH = 'agent';\n\n/**\n * The core wiring shared by `forRoot` / `forRootAsync`. `includeStore` controls whether we bind\n * `AGENT_STORE` locally: when the host omits `options.store` we leave it unbound so a globally-bound\n * store module (which binds `AGENT_STORE` app-wide) satisfies the dependency instead.\n */\nfunction sharedProviders(durable: boolean, includeStore: boolean): Provider[] {\n const providers: Provider[] = [\n { provide: AGENT_TOOL_REGISTRY, useFactory: () => new ToolRegistry() },\n // Starts empty; AgentDiscoveryService populates it from `@Agent`-decorated providers at boot.\n { provide: AGENT_REGISTRY, useFactory: () => new AgentRegistry() },\n // A shared, mutable list AgentDiscoveryService fills with `@SystemPromptContributor()` methods.\n { provide: AGENT_PROMPT_CONTRIBUTORS, useFactory: () => [] },\n {\n provide: AGENT_SINK,\n useFactory: (options: AgentModuleOptions) => options.sink ?? new InProcessTokenStreamSink(),\n inject: [AGENT_OPTIONS],\n },\n {\n provide: AGENT_ROLES_POLICY,\n useFactory: (options: AgentModuleOptions) =>\n options.rolesPolicy ?? new DefaultRolesPolicy(options.defaultRoles),\n inject: [AGENT_OPTIONS],\n },\n {\n provide: AGENT_ACTOR_RESOLVER,\n useFactory: (options: AgentModuleOptions) => options.actorResolver,\n inject: [AGENT_OPTIONS],\n },\n {\n provide: AGENT_MODEL,\n useFactory: (o: AgentModuleOptions) => o.model,\n inject: [AGENT_OPTIONS],\n },\n {\n // An explicit `quota` wins; otherwise `quotaLimitTokens` binds the built-in ledger-backed\n // store; otherwise quotas are off (undefined). The ledger store reads the same usage rows\n // the loop already writes, so enforcement needs no extra shared state across replicas.\n provide: AGENT_QUOTA_STORE,\n useFactory: (o: AgentModuleOptions, store: AgentStore) =>\n o.quota ??\n (o.quotaLimitTokens !== undefined\n ? new LedgerQuotaStore(store, o.quotaLimitTokens)\n : undefined),\n inject: [AGENT_OPTIONS, AGENT_STORE],\n },\n AgentDepsFactory,\n { provide: AGENT_DEPS_FACTORY, useExisting: AgentDepsFactory },\n // Populates the registry + contributors (onModuleInit) BEFORE AiToolDiscoveryService synthesizes\n // handoff tools (onApplicationBootstrap) reads the registry.\n AgentDiscoveryService,\n AiToolDiscoveryService,\n InlineAgentRunner,\n AgentService,\n // Bound ALWAYS (durable or inline) — the console's cross-thread approvals inbox routes decisions\n // through AgentService.signalToolCall, which reaches whichever AGENT_RUNNER is bound above.\n AgentApprovalPortAdapter,\n { provide: AGENT_APPROVAL_PORT, useExisting: AgentApprovalPortAdapter },\n ];\n if (includeStore) {\n providers.push({\n provide: AGENT_STORE,\n useFactory: (o: AgentModuleOptions) => o.store,\n inject: [AGENT_OPTIONS],\n });\n }\n if (durable) {\n // Bind AGENT_RUNNER to the durable runner AgentDurableModule provides. Optional injection turns\n // a forgotten `AgentDurableModule` import into a clear error instead of an unresolved-dep crash.\n providers.push({\n provide: AGENT_RUNNER,\n useFactory: (durableRunner: AgentRunner | undefined) => {\n if (durableRunner === undefined) {\n throw new Error(\n 'AgentModule.forRoot({ durable: true }) requires importing AgentDurableModule from ' +\n \"'@dudousxd/nestjs-agent/durable' (alongside a configured DurableModule). It was not found.\",\n );\n }\n return durableRunner;\n },\n inject: [{ token: AGENT_DURABLE_RUNNER, optional: true }],\n });\n } else {\n providers.push({ provide: AGENT_RUNNER, useExisting: InlineAgentRunner });\n }\n return providers;\n}\n\n/**\n * The module's public tokens. `AGENT_STORE` is only re-exported when we bind it locally — a module\n * cannot export a token it neither provides nor imports (the store module binds it globally instead).\n */\nfunction exportsFor(includeStore: boolean): NonNullable<DynamicModule['exports']> {\n return [\n AGENT_OPTIONS,\n AGENT_TOOL_REGISTRY,\n AGENT_REGISTRY,\n AGENT_SINK,\n AGENT_ROLES_POLICY,\n AGENT_ACTOR_RESOLVER,\n AGENT_MODEL,\n ...(includeStore ? [AGENT_STORE] : []),\n AGENT_QUOTA_STORE,\n AGENT_PROMPT_CONTRIBUTORS,\n AGENT_DEPS_FACTORY,\n AgentDepsFactory,\n AgentService,\n InlineAgentRunner,\n AGENT_APPROVAL_PORT,\n ];\n}\n\nconst BASE_CONTROLLERS = [\n ChatController,\n ThreadsController,\n ToolCallController,\n QuotaController,\n AgentsController,\n];\n\n/** Every controller class `guards` may ever target — stamped uniformly regardless of which of them are actually mounted this build (harmless: metadata on an unregistered class is simply unused). */\nconst GUARDABLE_CONTROLLERS = [...BASE_CONTROLLERS, AttachmentsController];\n\n/** The controllers to mount: the base five, plus attachments when the host opted into uploads. */\nfunction controllersFor(mountAttachments: boolean): Type<object>[] {\n return mountAttachments ? [...BASE_CONTROLLERS, AttachmentsController] : BASE_CONTROLLERS;\n}\n\n/**\n * Nest's `GUARDS_METADATA` key (`@nestjs/common/constants`), inlined as a literal: `@nestjs/common`\n * has no `exports` map and its ESM-facing files are CJS, so a deep `import ... from\n * '@nestjs/common/constants'` in our ESM build is emitted extensionless and rejected by Node's\n * strict ESM resolver (surfaced by a consumer's bundler/test runner externalizing this package).\n * `agent-guards.spec.ts` asserts this literal still matches the real constant, so upstream drift\n * fails loudly instead of silently stamping a dead metadata key.\n */\nconst GUARDS_METADATA = '__guards__';\n\n/**\n * Stamp (or clear) `@UseGuards`-equivalent metadata on every controller this module MIGHT mount.\n *\n * Mechanism: `@UseGuards(...guards)` on a controller just does `Reflect.defineMetadata(GUARDS_METADATA,\n * guards, ControllerClass)` (via Nest's `extendArrayMetadata`, which *appends* to any existing array).\n * We call `Reflect.defineMetadata` directly instead, so each `forRoot`/`forRootAsync` call REPLACES\n * the metadata rather than appending to it — appending would leak guards across repeated module\n * registrations in the same process (every test file that calls `forRoot` more than once, say) since\n * these controller classes are module-level singletons shared by every registration. Nest's\n * `GuardsConsumer` reads this metadata per-request via `Reflector`, not once at boot, so the LAST call\n * to stamp it before a request is served wins for that controller class in this process.\n */\nfunction applyGuards(guards: Type<CanActivate>[] | undefined): void {\n const resolved = guards ?? [];\n for (const controller of GUARDABLE_CONTROLLERS) {\n Reflect.defineMetadata(GUARDS_METADATA, resolved, controller);\n }\n}\n\n/** Distinct guard classes for the module's `providers`, so Nest can DI-instantiate them. */\nfunction guardProviders(guards: Type<CanActivate>[] | undefined): Type<CanActivate>[] {\n return [...new Set(guards ?? [])];\n}\n\n/** Mount the controllers under `path` (Nest applies the prefix to their relative routes). */\nfunction routerFor(path: string): DynamicModule {\n return RouterModule.register([{ path, module: AgentModule }]);\n}\n\n/**\n * `dispatchedSteps` routes the turn's model/tool calls through `AgentRunSteps` — a durable-only\n * worker group. It defaults ON under `durable: true` (see `AgentModuleOptions.dispatchedSteps`), but\n * an EXPLICIT `dispatchedSteps: true` without `durable: true` is still a config error: there is no\n * workflow to dispatch from, so it would silently no-op — fail loudly at build time instead.\n */\nfunction assertDispatchedStepsRequiresDurable(dispatchedSteps: boolean, durable: boolean): void {\n if (dispatchedSteps && !durable) {\n throw new Error(\n 'AgentModule dispatchedSteps: true requires durable: true — dispatched steps are routed ' +\n 'durable steps (AgentRunSteps.llm/tool) with no in-process equivalent.',\n );\n }\n}\n\n@Global()\n@Module({})\nexport class AgentModule {\n static forRoot(options: AgentModuleOptions): DynamicModule {\n assertDispatchedStepsRequiresDurable(\n options.dispatchedSteps ?? false,\n options.durable ?? false,\n );\n const path = options.path ?? DEFAULT_PATH;\n // Bind AGENT_STORE locally only when the host passes a store; otherwise defer to a global one.\n const includeStore = options.store !== undefined;\n applyGuards(options.guards);\n return {\n module: AgentModule,\n global: true,\n imports: [DiscoveryModule, routerFor(path)],\n controllers: controllersFor(options.attachments?.upload === true),\n providers: [\n { provide: AGENT_OPTIONS, useValue: options },\n ...sharedProviders(options.durable ?? false, includeStore),\n ...guardProviders(options.guards),\n ],\n exports: exportsFor(includeStore),\n };\n }\n\n static forRootAsync(options: AgentModuleAsyncOptions): DynamicModule {\n assertDispatchedStepsRequiresDurable(\n options.dispatchedSteps ?? false,\n options.durable ?? false,\n );\n const path = options.path ?? DEFAULT_PATH;\n // The async factory resolves too late to inspect `store`, so `forRootAsync` binds AGENT_STORE\n // locally from the factory result by default. `externalStore: true` opts out — deferring to a\n // globally-imported store module (e.g. `MikroOrmAgentStoreModule.forFeature()`) so the host\n // doesn't have to inject that store just to hand it back as `store`.\n const includeStore = options.externalStore !== true;\n applyGuards(options.guards);\n return {\n module: AgentModule,\n global: true,\n imports: [DiscoveryModule, routerFor(path), ...(options.imports ?? [])],\n controllers: controllersFor(options.attachmentsUpload === true),\n providers: [\n {\n provide: AGENT_OPTIONS,\n // Stamp the STATIC wiring flags onto the factory result: `durable`/`dispatchedSteps` are\n // authoritative on the async config object (they decided the actual wiring above), and\n // `AgentDurableModule` derives the effective dispatched-steps value from AGENT_OPTIONS —\n // without this stamp, an async host would get in-process localSteps despite durable: true.\n useFactory: async (...args: never[]) => ({\n ...(await options.useFactory(...args)),\n durable: options.durable ?? false,\n ...(options.dispatchedSteps !== undefined\n ? { dispatchedSteps: options.dispatchedSteps }\n : {}),\n }),\n inject: options.inject ?? [],\n },\n ...sharedProviders(options.durable ?? false, includeStore),\n ...guardProviders(options.guards),\n ],\n exports: exportsFor(includeStore),\n };\n }\n}\n","import {\n AGENT_MODEL,\n AGENT_PRICING_STORE,\n AGENT_PROMPT_CONTRIBUTORS,\n AGENT_QUOTA_STORE,\n AGENT_REGISTRY,\n AGENT_ROLES_POLICY,\n AGENT_SINK,\n AGENT_STORE,\n AGENT_TOOL_REGISTRY,\n type AgentDefinition,\n type AgentPricingStore,\n AgentRegistry,\n type AgentStore,\n type ModelProvider,\n type PromptContributor,\n type QuotaStore,\n type RolesPolicy,\n type TokenStreamSink,\n ToolRegistry,\n} from '@dudousxd/nestjs-agent-core';\nimport { AGENT_OPTIONS } from '@dudousxd/nestjs-agent-core';\nimport { Inject, Injectable, Optional } from '@nestjs/common';\nimport type { AgentDeps } from './agent-deps.js';\nimport type { AgentModuleOptions } from './agent.options.js';\n\n/** The synthesized `agent`-kind tool name an orchestrator uses to hand off to `target`. */\nexport function delegateToolName(target: string): string {\n return `ask_${target.replace(/[^a-zA-Z0-9]+/g, '_')}`;\n}\n\n/** Builds the per-agent loop deps. The single-agent case is just the one registered `@Agent`. */\n@Injectable()\nexport class AgentDepsFactory {\n constructor(\n @Inject(AGENT_OPTIONS) private readonly options: AgentModuleOptions,\n @Inject(AGENT_MODEL) private readonly model: ModelProvider,\n @Inject(AGENT_STORE) private readonly store: AgentStore,\n @Inject(AGENT_SINK) private readonly sink: TokenStreamSink,\n @Inject(AGENT_ROLES_POLICY) private readonly rolesPolicy: RolesPolicy,\n @Inject(AGENT_TOOL_REGISTRY) private readonly registry: ToolRegistry,\n @Inject(AGENT_REGISTRY) private readonly agents: AgentRegistry,\n @Inject(AGENT_PROMPT_CONTRIBUTORS) private readonly promptContributors: PromptContributor[],\n @Inject(AGENT_QUOTA_STORE) private readonly quota: QuotaStore | undefined,\n // Optional: AGENT_PRICING_STORE has no local provider in this module (unlike AGENT_QUOTA_STORE,\n // which is always a registered factory) — it's bound externally (e.g. by a store module), so a\n // plain @Inject would throw when nothing binds it.\n @Optional()\n @Inject(AGENT_PRICING_STORE)\n private readonly pricingStore: AgentPricingStore | undefined,\n ) {}\n\n /**\n * The agent a turn uses when the caller names none: the explicit `defaultAgent` option, else the\n * sole registered `@Agent` when there is exactly one, else `'default'` (a bare assistant).\n */\n defaultAgentName(): string {\n if (this.options.defaultAgent !== undefined) {\n return this.options.defaultAgent;\n }\n const registered = this.agents.list();\n return registered.length === 1 ? (registered[0]?.name ?? 'default') : 'default';\n }\n\n private effectiveTools(definition: AgentDefinition | undefined): string[] | undefined {\n if (definition === undefined) {\n return undefined;\n }\n const delegated = (definition.delegatesTo ?? []).map(delegateToolName);\n if (definition.tools === undefined && delegated.length === 0) {\n return undefined; // no restriction\n }\n return [...(definition.tools ?? []), ...delegated];\n }\n\n forAgent(agentName?: string): AgentDeps {\n const name = agentName ?? this.defaultAgentName();\n const definition = this.agents.get(name);\n const toolAllowList = this.effectiveTools(definition);\n const followUpsCount = this.followUpsCount();\n const retrieval = this.options.retrieval;\n return {\n model: this.model,\n store: this.store,\n sink: this.sink,\n rolesPolicy: this.rolesPolicy,\n registry: this.registry,\n promptContributors: this.promptContributors,\n systemPrompt: definition?.systemPrompt ?? 'You are a helpful assistant.',\n maxSteps: definition?.maxSteps ?? 8,\n ...(definition?.modelId !== undefined ? { modelId: definition.modelId } : {}),\n ...(this.quota !== undefined ? { quota: this.quota } : {}),\n ...(this.pricingStore !== undefined ? { pricingStore: this.pricingStore } : {}),\n ...(toolAllowList !== undefined ? { toolAllowList } : {}),\n ...(this.options.toolTimeoutMs !== undefined\n ? { toolTimeoutMs: this.options.toolTimeoutMs }\n : {}),\n ...(this.options.toolTransientRetry !== undefined\n ? { toolTransientRetry: this.options.toolTransientRetry }\n : {}),\n ...(followUpsCount !== undefined ? { followUpsCount } : {}),\n ...(retrieval?.mode === 'inject'\n ? {\n retriever: retrieval.retriever,\n ...(retrieval.topK !== undefined ? { retrievalTopK: retrieval.topK } : {}),\n }\n : {}),\n };\n }\n\n /** Normalize the `followUps` option (`true` → 3, `{ count }` → count) to a number, or undefined. */\n private followUpsCount(): number | undefined {\n const followUps = this.options.followUps;\n if (followUps === true) {\n return 3;\n }\n if (typeof followUps === 'object') {\n return followUps.count;\n }\n return undefined;\n }\n}\n","import {\n AGENT_DEPS_FACTORY,\n AGENT_QUOTA_STORE,\n AGENT_RUNNER,\n AGENT_STORE,\n type Actor,\n type AgentRunInput,\n type AgentRunner,\n type AgentStore,\n type Decision,\n type MessageAttachment,\n type PageContext,\n type QuotaStore,\n type QuotaView,\n type ThreadDetail,\n type ThreadSummary,\n type UpdateThreadInput,\n} from '@dudousxd/nestjs-agent-core';\nimport {\n BadRequestException,\n ForbiddenException,\n Inject,\n Injectable,\n NotFoundException,\n NotImplementedException,\n} from '@nestjs/common';\nimport type { AgentDepsFactory } from './agent-deps.factory.js';\nimport { utcDay } from './agent-deps.js';\n\nexport interface ChatParams {\n actor: Actor;\n message: string;\n threadId?: string;\n agentName?: string;\n /** Files attached to this message (image/PDF) for a vision-capable model. */\n attachments?: MessageAttachment[];\n pageContext?: PageContext;\n /** Re-run the last exchange instead of adding a new message. Requires an existing `threadId`. */\n regenerate?: boolean;\n /**\n * When creating a thread (no `threadId`), start it transient — a scratch conversation hidden from\n * the thread list until the caller promotes it. Ignored when `threadId` is set.\n */\n transient?: boolean;\n}\n\n/** The orchestration facade the controllers call. */\n@Injectable()\nexport class AgentService {\n constructor(\n @Inject(AGENT_RUNNER) private readonly runner: AgentRunner,\n @Inject(AGENT_STORE) private readonly store: AgentStore,\n @Inject(AGENT_DEPS_FACTORY) private readonly deps: AgentDepsFactory,\n @Inject(AGENT_QUOTA_STORE) private readonly quota: QuotaStore | undefined,\n ) {}\n\n async chat(params: ChatParams): Promise<{ runId: string; threadId: string }> {\n // Precedence: explicit agentName > the thread's own defaultAgent (set via updateThread) > the\n // module's configured default. Resolved up front (before thread creation) so a brand-new thread\n // — which has no defaultAgent yet — falls straight through to the module default.\n const agentName = await this.resolveAgentName(params.agentName, params.threadId);\n let threadId = params.threadId;\n if (threadId === undefined) {\n if (params.regenerate === true) {\n throw new BadRequestException('regenerate requires an existing threadId');\n }\n const created = await this.store.createThread({\n actor: params.actor,\n ...(params.transient === true ? { transient: true } : {}),\n });\n threadId = created.id;\n } else if (params.regenerate === true) {\n // Regenerate re-runs a run on an existing thread — gate it by ownership like the other\n // thread-scoped actions so one actor can't rewind another's conversation.\n await this.assertOwnsThread(params.actor, threadId);\n }\n\n const input: AgentRunInput = {\n threadId,\n actor: params.actor,\n userText: params.message,\n day: utcDay(),\n agentName,\n ...(params.regenerate === true ? { regenerate: true } : {}),\n ...(params.attachments !== undefined ? { attachments: params.attachments } : {}),\n ...(params.pageContext !== undefined ? { pageContext: params.pageContext } : {}),\n };\n\n const { runId } = await this.runner.start(input);\n await this.store.setActiveStream(threadId, runId);\n return { runId, threadId };\n }\n\n subscribe(runId: string): AsyncIterable<Uint8Array> {\n return this.deps.forAgent().sink.subscribe(runId);\n }\n\n async approve(actor: Actor, toolCallId: string): Promise<void> {\n await this.assertOwnsToolCall(actor, toolCallId);\n return this.signalToolCall(toolCallId, { approved: true });\n }\n\n async reject(actor: Actor, toolCallId: string, reason?: string): Promise<void> {\n await this.assertOwnsToolCall(actor, toolCallId);\n return this.signalToolCall(toolCallId, {\n approved: false,\n ...(reason !== undefined ? { reason } : {}),\n });\n }\n\n /**\n * The decision core behind approve/reject, WITHOUT an ownership check: resolves the run\n * currently awaiting `toolCallId` and signals it. `approve`/`reject` above call this after their\n * own `assertOwnsToolCall` gate; the console `AgentApprovalPort` adapter (bound by `AgentModule`)\n * calls it directly — a console caller is already authorized by the dashboard's own guards, and\n * re-deriving thread ownership here would reject a legitimate operator decision (an operator is\n * not the thread's own actor).\n */\n async signalToolCall(toolCallId: string, decision: Decision): Promise<void> {\n const runId = await this.resolveRunForToolCall(toolCallId);\n return this.runner.signal(runId, toolCallId, decision);\n }\n\n async cancel(actor: Actor, runId: string): Promise<void> {\n await this.assertOwnsActiveStream(actor, runId);\n return this.runner.cancel(runId);\n }\n\n async listThreads(actorRef: string): Promise<ThreadSummary[]> {\n const threads = await this.store.listThreads(actorRef);\n return Promise.all(threads.map((thread) => this.toSummaryView(thread)));\n }\n\n async getThread(actor: Actor, threadId: string): Promise<ThreadDetail | null> {\n await this.assertOwnsThread(actor, threadId);\n const thread = await this.store.getThread(threadId);\n return thread === null ? null : this.toDetailView(thread);\n }\n\n async deleteThread(actor: Actor, threadId: string): Promise<void> {\n await this.assertOwnsThread(actor, threadId);\n return this.store.softDeleteThread(threadId);\n }\n\n async forkThread(actor: Actor, threadId: string, fromMessageId: string): Promise<ThreadSummary> {\n await this.assertOwnsThread(actor, threadId);\n return this.store.forkThread(threadId, fromMessageId);\n }\n\n /** Kept for source compatibility — a thin wrapper over the more general `updateThread`. */\n async renameThread(actor: Actor, threadId: string, title: string): Promise<void> {\n return this.updateThread(actor, threadId, { title });\n }\n\n /**\n * Rename a thread and/or set its default agent. Title-only patches work against ANY store (via\n * the required `setTitle`); a `defaultAgent` change requires the bound store to implement the\n * optional `updateThread` — 501 with a clear message when it doesn't, rather than silently\n * dropping the field.\n */\n async updateThread(actor: Actor, threadId: string, patch: UpdateThreadInput): Promise<void> {\n const title = patch.title !== undefined ? this.validateTitle(patch.title) : undefined;\n await this.assertOwnsThread(actor, threadId);\n if (patch.defaultAgent === undefined) {\n if (title !== undefined) {\n await this.store.setTitle(threadId, title);\n }\n return;\n }\n if (this.store.updateThread === undefined) {\n throw new NotImplementedException(\n \"Setting a thread's defaultAgent requires an AgentStore that implements updateThread(); \" +\n 'the bound store does not support it.',\n );\n }\n await this.store.updateThread(threadId, {\n ...(title !== undefined ? { title } : {}),\n defaultAgent: patch.defaultAgent,\n });\n }\n\n private validateTitle(title: string): string {\n const trimmed = title.trim();\n if (trimmed.length === 0) {\n throw new BadRequestException('title must not be empty');\n }\n if (trimmed.length > 200) {\n throw new BadRequestException('title must be at most 200 characters');\n }\n return trimmed;\n }\n\n /**\n * Agent-selection precedence for a `chat()` call with no explicit `agentName`: the thread's own\n * `defaultAgent` (if the thread exists and one is set) wins over the module's configured default.\n * Skips the thread lookup entirely when the caller already named an agent or there's no thread yet.\n */\n private async resolveAgentName(\n agentName: string | undefined,\n threadId: string | undefined,\n ): Promise<string> {\n if (agentName !== undefined) {\n return agentName;\n }\n if (threadId !== undefined) {\n const thread = await this.store.getThread(threadId);\n if (thread?.defaultAgent !== undefined && thread.defaultAgent !== null) {\n return thread.defaultAgent;\n }\n }\n return this.deps.defaultAgentName();\n }\n\n private async toSummaryView(thread: ThreadSummary): Promise<ThreadSummary> {\n return {\n ...thread,\n defaultAgent: thread.defaultAgent ?? null,\n activeRunId: (await this.store.activeRunForThread?.(thread.id)) ?? null,\n };\n }\n\n private async toDetailView(thread: ThreadDetail): Promise<ThreadDetail> {\n const summary = await this.toSummaryView(thread);\n return {\n ...summary,\n messages: thread.messages,\n ...(thread.activeStreamId !== undefined ? { activeStreamId: thread.activeStreamId } : {}),\n };\n }\n\n async promoteThread(actor: Actor, threadId: string): Promise<void> {\n await this.assertOwnsThread(actor, threadId);\n return this.store.promoteThread(threadId);\n }\n\n /**\n * Drop a message and everything after it — the \"edit and resend\" / \"delete from here\" primitive.\n * The client then sends a fresh turn on the truncated thread. Ownership-gated like the other\n * thread-scoped mutations.\n */\n async truncateThreadFrom(actor: Actor, threadId: string, messageId: string): Promise<void> {\n await this.assertOwnsThread(actor, threadId);\n return this.store.truncateFrom(threadId, messageId);\n }\n\n /**\n * The day's usage for the badge: tokens + summed USD cost from the store, and the configured\n * limit from the quota store (null → unlimited). `withinLimit` comes from the quota store so it\n * can never drift from what enforcement uses.\n */\n async quotaToday(actorRef: string): Promise<QuotaView> {\n const day = utcDay();\n const { usedTokens, costUsd } = await this.store.quotaToday(actorRef, day);\n if (this.quota === undefined) {\n return { usedTokens, costUsd, limitTokens: null, withinLimit: true };\n }\n const state = await this.quota.check(actorRef, day);\n return {\n usedTokens: state.usedTokens,\n costUsd,\n limitTokens: state.limitTokens,\n withinLimit: state.withinLimit,\n };\n }\n\n /**\n * Authorization seam for thread-scoped endpoints: the caller must own the thread. A missing\n * thread is a 404; someone else's thread is a 403 — one actor never touches another's thread.\n */\n private async assertOwnsThread(actor: Actor, threadId: string): Promise<void> {\n const owner = await this.store.ownerOfThread(threadId);\n if (owner === null) {\n throw new NotFoundException(`thread ${threadId} not found`);\n }\n if (owner !== actor.id) {\n throw new ForbiddenException('thread belongs to another actor');\n }\n }\n\n /**\n * Authorization seam for HITL approve/reject: the caller must own the tool call's thread. Split\n * out from run resolution (see {@link resolveRunForToolCall}) so the console `AgentApprovalPort`\n * adapter can resolve+signal a decision WITHOUT this check — it is authorized upstream instead.\n */\n private async assertOwnsToolCall(actor: Actor, toolCallId: string): Promise<void> {\n const owner = await this.store.ownerOfToolCall(toolCallId);\n if (owner === null) {\n throw new NotFoundException(`tool call ${toolCallId} not found`);\n }\n if (owner !== actor.id) {\n throw new ForbiddenException('tool call belongs to another actor');\n }\n }\n\n /**\n * Resolve the run currently awaiting `toolCallId` (its thread's active stream). That run is the\n * sub-agent's own child run when the pending call belongs to a delegated agent — the client never\n * knows or supplies a runId; it is derived here from the tool call alone.\n */\n private async resolveRunForToolCall(toolCallId: string): Promise<string> {\n const runId = await this.store.runForToolCall(toolCallId);\n if (runId === null) {\n throw new NotFoundException(`tool call ${toolCallId} has no active run to signal`);\n }\n return runId;\n }\n\n /** Authorization seam for `cancel`: the caller must own the thread currently streaming this run. */\n private async assertOwnsActiveStream(actor: Actor, runId: string): Promise<void> {\n const owner = await this.store.ownerOfActiveStream(runId);\n if (owner === null) {\n throw new NotFoundException(`no active run ${runId}`);\n }\n if (owner !== actor.id) {\n throw new ForbiddenException('run belongs to another actor');\n }\n }\n}\n","import type {\n AgentPricingStore,\n AgentStore,\n ModelProvider,\n PromptBuilder,\n PromptContributor,\n QuotaStore,\n Retriever,\n RolesPolicy,\n SinkWriter,\n TokenStreamSink,\n ToolRegistry,\n ToolTransientRetrySetting,\n} from '@dudousxd/nestjs-agent-core';\n\n/** Everything `runAgentLoop` needs, minus the per-run `day` the runner stamps. */\nexport interface AgentDeps {\n model: ModelProvider;\n store: AgentStore;\n registry: ToolRegistry;\n rolesPolicy: RolesPolicy;\n quota?: QuotaStore;\n sink: TokenStreamSink;\n /** Fallback accounting label; the provider's turn result overrides it when set. */\n modelId?: string;\n systemPrompt: string | PromptBuilder;\n /** App-wide `@SystemPromptContributor()` sections appended after the agent's base prompt. */\n promptContributors: PromptContributor[];\n maxSteps: number;\n /** Agent-level tool allow-list. Undefined → all tools (after role filtering). */\n toolAllowList?: string[];\n /** Per-tool execution timeout in ms (from module options). Undefined → no timeout. */\n toolTimeoutMs?: number;\n /**\n * Transient-tool-error retry policy (from module options). Undefined → default ON\n * (`{ attempts: 2, backoffMs: 150 }` with the default classifier); `false` → disabled.\n */\n toolTransientRetry?: ToolTransientRetrySetting;\n /** How many follow-up suggestions to generate after the final turn. Undefined/0 → off. */\n followUpsCount?: number;\n /** Inject-mode retriever (from `forRoot({ retrieval })`). Undefined → no prompt augmentation. */\n retriever?: Retriever;\n /** Passages inject-mode retrieval requests. Undefined → loop default (5). */\n retrievalTopK?: number;\n /** Bound `AGENT_PRICING_STORE`, when a module (e.g. a store's) provides one. Undefined → no pricing. */\n pricingStore?: AgentPricingStore;\n}\n\nexport function utcDay(date = new Date()): string {\n return date.toISOString().slice(0, 10);\n}\n\n/**\n * Wraps a parent run's sink writer for a sub-agent: `write` forwards (so the sub-agent's tokens and\n * pending action-tool frames reach the human's live stream), but `end` / `fail` are swallowed — the\n * top-level run owns the stream's lifecycle, so a finished/failed child must not close or error the\n * shared stream out from under the parent that is still running.\n */\nexport function childSinkWriter(writer: SinkWriter): SinkWriter {\n return {\n write: (chunk) => writer.write(chunk),\n end: async () => {},\n fail: async () => {},\n };\n}\n","import type { AgentApprovalPort } from '@dudousxd/nestjs-agent-core';\nimport { Injectable } from '@nestjs/common';\nimport { AgentService } from './agent.service.js';\n\n/**\n * Binds `AGENT_APPROVAL_PORT` for the console's cross-thread approvals inbox to the SAME decision\n * path chat approvals use — `AgentService.signalToolCall` (resolve the run awaiting `toolCallId`,\n * then `AgentRunner.signal`, which is either the inline pending-promise map or the durable signal\n * `tool:<runId>:<callId>`, depending on how the host configured `AgentModule`).\n *\n * Deliberately WITHOUT `AgentService.approve`/`reject`'s ownership check: a console caller reaches\n * this port only through the dashboard's own guards (already authorized), not as the thread's own\n * actor — re-deriving \"does this actor own the thread\" here would reject a legitimate operator\n * decision. `opts.executedByRef` is an OPAQUE decider ref, not re-authorized against anything: it\n * rides the `Decision` and the loop records it as the tool call's decider\n * (`decision.executedByRef ?? input.actor.id`, on both the executed and rejected paths).\n */\n@Injectable()\nexport class AgentApprovalPortAdapter implements AgentApprovalPort {\n constructor(private readonly agent: AgentService) {}\n\n async approve(toolCallId: string, opts?: { executedByRef?: string }): Promise<void> {\n await this.agent.signalToolCall(toolCallId, {\n approved: true,\n ...(opts?.executedByRef !== undefined ? { executedByRef: opts.executedByRef } : {}),\n });\n }\n\n async reject(\n toolCallId: string,\n opts?: { executedByRef?: string; reason?: string },\n ): Promise<void> {\n await this.agent.signalToolCall(toolCallId, {\n approved: false,\n ...(opts?.executedByRef !== undefined ? { executedByRef: opts.executedByRef } : {}),\n ...(opts?.reason !== undefined ? { reason: opts.reason } : {}),\n });\n }\n}\n","import {\n AGENT_DEPS_FACTORY,\n AGENT_REGISTRY,\n type AgentCatalogEntry,\n AgentRegistry,\n} from '@dudousxd/nestjs-agent-core';\nimport { Controller, Get, Inject } from '@nestjs/common';\nimport type { AgentDepsFactory } from '../agent-deps.factory.js';\n\n/** Lists the registered `@Agent`s so a host can render a persona picker instead of hardcoding one. */\n@Controller('agents')\nexport class AgentsController {\n constructor(\n @Inject(AGENT_REGISTRY) private readonly agents: AgentRegistry,\n @Inject(AGENT_DEPS_FACTORY) private readonly depsFactory: AgentDepsFactory,\n ) {}\n\n @Get()\n list(): AgentCatalogEntry[] {\n const defaultAgentName = this.depsFactory.defaultAgentName();\n return this.agents.list().map((definition) => ({\n name: definition.name,\n description: definition.description ?? '',\n ...(definition.name === defaultAgentName ? { isDefault: true } : {}),\n }));\n }\n}\n","import {\n AGENT_ACTOR_RESOLVER,\n AGENT_ATTACHMENT_STAGING,\n AGENT_OPTIONS,\n type ActorResolver,\n type AttachmentStagingStore,\n type MessageAttachment,\n} from '@dudousxd/nestjs-agent-core';\nimport {\n BadRequestException,\n Controller,\n Inject,\n NotImplementedException,\n type OnModuleInit,\n Optional,\n PayloadTooLargeException,\n Post,\n Req,\n UnsupportedMediaTypeException,\n UploadedFile,\n UseInterceptors,\n} from '@nestjs/common';\nimport { FileInterceptor } from '@nestjs/platform-express';\nimport type { Request } from 'express';\nimport type { AgentModuleOptions } from '../agent.options.js';\n\n/** Default per-file size cap when `AgentModuleOptions.attachments.maxBytes` is omitted (20 MiB). */\nexport const DEFAULT_MAX_ATTACHMENT_BYTES = 20 * 1024 * 1024;\n\n/**\n * Default allowlist: what multimodal model providers commonly accept as native image/file parts.\n */\nexport const DEFAULT_ALLOWED_ATTACHMENT_CONTENT_TYPES: readonly string[] = [\n 'image/png',\n 'image/jpeg',\n 'image/gif',\n 'image/webp',\n 'application/pdf',\n 'text/plain',\n 'text/csv',\n];\n\n/**\n * Optional `POST /agent/attachments` upload surface — mounted only when `AgentModuleOptions\n * .attachments.upload` (or the async config's `attachmentsUpload`) is `true` (see `agent.module.ts`).\n * Multipart single file field `'file'`, buffered in memory (no disk write — `FileInterceptor`'s\n * default storage), validated against the configured size cap + content-type allowlist, then handed\n * to the bound {@link AttachmentStagingStore} to persist and turn into a model-fetchable URL.\n */\n@Controller('attachments')\nexport class AttachmentsController implements OnModuleInit {\n constructor(\n @Inject(AGENT_OPTIONS) private readonly options: AgentModuleOptions,\n @Inject(AGENT_ACTOR_RESOLVER) private readonly actorResolver: ActorResolver,\n @Optional()\n @Inject(AGENT_ATTACHMENT_STAGING)\n private readonly staging: AttachmentStagingStore | undefined,\n ) {}\n\n /**\n * `attachments.upload: true` is what mounts this controller at all (see `agent.module.ts`), so by\n * the time an instance exists the host clearly intends uploads to work. Fail boot loudly rather\n * than mounting a controller that would 501 on every single request because nobody bound\n * `AGENT_ATTACHMENT_STAGING`.\n */\n onModuleInit(): void {\n if (this.options.attachments?.upload === true && this.staging === undefined) {\n throw new Error(\n 'AgentModule: attachments.upload is true but no AGENT_ATTACHMENT_STAGING provider is bound. ' +\n 'Bind one (e.g. `{ provide: AGENT_ATTACHMENT_STAGING, useClass: MyStagingStore }`) in a ' +\n 'module imported alongside AgentModule, or set attachments.upload to false.',\n );\n }\n }\n\n @Post()\n @UseInterceptors(FileInterceptor('file'))\n async upload(\n @Req() req: Request,\n @UploadedFile() file: Express.Multer.File | undefined,\n ): Promise<MessageAttachment> {\n if (this.staging === undefined) {\n // Reachable only if the module was built with attachments.upload left false/omitted while\n // this controller was somehow still wired up by hand — the normal boot path prevents this via\n // onModuleInit above. Kept as defense in depth with a precise status instead of a stack trace.\n throw new NotImplementedException('Attachment upload is not configured on this server.');\n }\n if (file === undefined) {\n throw new BadRequestException('multipart field \"file\" is required');\n }\n const allowedContentTypes =\n this.options.attachments?.allowedContentTypes ?? DEFAULT_ALLOWED_ATTACHMENT_CONTENT_TYPES;\n if (!allowedContentTypes.includes(file.mimetype)) {\n throw new UnsupportedMediaTypeException(\n `content type \"${file.mimetype}\" is not allowed (allowed: ${allowedContentTypes.join(', ')})`,\n );\n }\n const maxBytes = this.options.attachments?.maxBytes ?? DEFAULT_MAX_ATTACHMENT_BYTES;\n if (file.size > maxBytes) {\n throw new PayloadTooLargeException(`file exceeds the ${maxBytes}-byte limit`);\n }\n const actor = await this.actorResolver.resolve(req);\n return this.staging.stage({\n data: file.buffer,\n filename: file.originalname,\n contentType: file.mimetype,\n sizeBytes: file.size,\n actor,\n });\n }\n}\n","import {\n AGENT_ACTOR_RESOLVER,\n type ActorResolver,\n AgentStreamError,\n type MessageAttachment,\n type PageContext,\n} from '@dudousxd/nestjs-agent-core';\nimport { Body, Controller, Get, Inject, Param, Post, Req, Res } from '@nestjs/common';\nimport type { Request, Response } from 'express';\nimport { AgentService } from '../agent.service.js';\n\ninterface ChatBody {\n message: string;\n threadId?: string;\n /** Name of the agent to run (orchestrator or a sub-agent). Defaults to the module's default. */\n agent?: string;\n /** Files attached to this message (image/PDF) for a vision-capable model. */\n attachments?: MessageAttachment[];\n pageContext?: PageContext;\n /** Re-run the last exchange on `threadId` instead of adding a new message. */\n regenerate?: boolean;\n /** Start a new thread transient (hidden from history until promoted). Ignored with `threadId`. */\n transient?: boolean;\n}\n\n@Controller()\nexport class ChatController {\n constructor(\n private readonly agent: AgentService,\n @Inject(AGENT_ACTOR_RESOLVER) private readonly actorResolver: ActorResolver,\n ) {}\n\n @Post('chat')\n async chat(@Req() req: Request, @Res() res: Response, @Body() body: ChatBody): Promise<void> {\n const actor = await this.actorResolver.resolve(req);\n const { runId, threadId } = await this.agent.chat({\n actor,\n message: body.message,\n ...(body.threadId !== undefined ? { threadId: body.threadId } : {}),\n ...(body.agent !== undefined ? { agentName: body.agent } : {}),\n ...(body.attachments !== undefined ? { attachments: body.attachments } : {}),\n ...(body.pageContext !== undefined ? { pageContext: body.pageContext } : {}),\n ...(body.regenerate === true ? { regenerate: true } : {}),\n ...(body.transient === true ? { transient: true } : {}),\n });\n await this.pipe(res, runId, threadId);\n }\n\n @Get('chat/:runId/stream')\n async stream(@Param('runId') runId: string, @Res() res: Response): Promise<void> {\n await this.pipe(res, runId);\n }\n\n @Post('chat/:runId/cancel')\n async cancel(@Req() req: Request, @Param('runId') runId: string): Promise<{ aborted: boolean }> {\n const actor = await this.actorResolver.resolve(req);\n await this.agent.cancel(actor, runId);\n return { aborted: true };\n }\n\n private async pipe(res: Response, runId: string, threadId?: string): Promise<void> {\n res.setHeader('Content-Type', 'text/event-stream');\n res.setHeader('Cache-Control', 'no-cache');\n res.setHeader('Connection', 'keep-alive');\n res.setHeader('X-Agent-Run-Id', runId);\n if (threadId !== undefined) {\n res.setHeader('X-Agent-Thread-Id', threadId);\n }\n res.write(`event: meta\\ndata: ${JSON.stringify({ runId, threadId })}\\n\\n`);\n // The sink now carries NDJSON `AgentStreamEvent`s (one `{...}\\n` per write). Forward each line\n // as an SSE `data:` frame verbatim — the client transport maps them to the AI SDK UI-message\n // chunk protocol. Buffer across chunk boundaries in case a transport batches multiple writes.\n const decoder = new TextDecoder();\n let buffer = '';\n try {\n for await (const chunk of this.agent.subscribe(runId)) {\n buffer += decoder.decode(chunk, { stream: true });\n let newline = buffer.indexOf('\\n');\n while (newline !== -1) {\n const line = buffer.slice(0, newline);\n buffer = buffer.slice(newline + 1);\n if (line.length > 0) {\n res.write(`data: ${line}\\n\\n`);\n }\n newline = buffer.indexOf('\\n');\n }\n }\n if (buffer.length > 0) {\n res.write(`data: ${buffer}\\n\\n`);\n }\n res.write('event: done\\ndata: {}\\n\\n');\n } catch (error) {\n // A run that failed terminates the sink with an AgentStreamError; surface it as a typed\n // error frame so the client can render a failure state instead of parsing it as a token.\n const payload =\n error instanceof AgentStreamError\n ? { code: error.code, message: error.message }\n : {\n code: 'run_failed',\n message: error instanceof Error ? error.message : 'stream error',\n };\n res.write(`event: error\\ndata: ${JSON.stringify(payload)}\\n\\n`);\n }\n res.end();\n }\n}\n","import { AGENT_ACTOR_RESOLVER, type ActorResolver } from '@dudousxd/nestjs-agent-core';\nimport { Controller, Get, Inject, Req } from '@nestjs/common';\nimport type { Request } from 'express';\nimport { AgentService } from '../agent.service.js';\n\n@Controller('quota')\nexport class QuotaController {\n constructor(\n private readonly agent: AgentService,\n @Inject(AGENT_ACTOR_RESOLVER) private readonly actorResolver: ActorResolver,\n ) {}\n\n @Get('today')\n async today(@Req() req: Request) {\n const actor = await this.actorResolver.resolve(req);\n return this.agent.quotaToday(actor.id);\n }\n}\n","import { AGENT_ACTOR_RESOLVER, type ActorResolver } from '@dudousxd/nestjs-agent-core';\nimport { Body, Controller, Delete, Get, Inject, Param, Patch, Post, Req } from '@nestjs/common';\nimport type { Request } from 'express';\nimport { AgentService } from '../agent.service.js';\n\ninterface UpdateThreadBody {\n title?: string;\n /** `null` clears the thread's default agent. Omitted → left untouched. */\n defaultAgent?: string | null;\n}\n\n@Controller('threads')\nexport class ThreadsController {\n constructor(\n private readonly agent: AgentService,\n @Inject(AGENT_ACTOR_RESOLVER) private readonly actorResolver: ActorResolver,\n ) {}\n\n @Get()\n async list(@Req() req: Request) {\n const actor = await this.actorResolver.resolve(req);\n return this.agent.listThreads(actor.id);\n }\n\n @Get(':id')\n async detail(@Req() req: Request, @Param('id') id: string) {\n const actor = await this.actorResolver.resolve(req);\n return this.agent.getThread(actor, id);\n }\n\n @Delete(':id')\n async remove(@Req() req: Request, @Param('id') id: string): Promise<{ ok: boolean }> {\n const actor = await this.actorResolver.resolve(req);\n await this.agent.deleteThread(actor, id);\n return { ok: true };\n }\n\n @Post(':id/fork-from/:messageId')\n async fork(@Req() req: Request, @Param('id') id: string, @Param('messageId') messageId: string) {\n const actor = await this.actorResolver.resolve(req);\n return this.agent.forkThread(actor, id, messageId);\n }\n\n /**\n * Renames the thread and/or sets its default agent. `defaultAgent` is only present in the request\n * body when the client actually sent the key (JSON has no `undefined`), so `'defaultAgent' in body`\n * distinguishes \"leave it alone\" from \"set it to null\" (clear it) unambiguously.\n */\n @Patch(':id')\n async update(\n @Req() req: Request,\n @Param('id') id: string,\n @Body() body: UpdateThreadBody,\n ): Promise<{ ok: boolean }> {\n const actor = await this.actorResolver.resolve(req);\n await this.agent.updateThread(actor, id, {\n ...(body.title !== undefined ? { title: body.title } : {}),\n ...('defaultAgent' in body ? { defaultAgent: body.defaultAgent ?? null } : {}),\n });\n return { ok: true };\n }\n\n @Post(':id/promote')\n async promote(@Req() req: Request, @Param('id') id: string): Promise<{ ok: boolean }> {\n const actor = await this.actorResolver.resolve(req);\n await this.agent.promoteThread(actor, id);\n return { ok: true };\n }\n\n @Delete(':id/from/:messageId')\n async truncateFrom(\n @Req() req: Request,\n @Param('id') id: string,\n @Param('messageId') messageId: string,\n ): Promise<{ ok: boolean }> {\n const actor = await this.actorResolver.resolve(req);\n await this.agent.truncateThreadFrom(actor, id, messageId);\n return { ok: true };\n }\n}\n","import { AGENT_ACTOR_RESOLVER, type ActorResolver } from '@dudousxd/nestjs-agent-core';\nimport { Body, Controller, Inject, Post, Req } from '@nestjs/common';\nimport type { Request } from 'express';\nimport { AgentService } from '../agent.service.js';\n\ninterface ApproveBody {\n toolCallId: string;\n}\ninterface RejectBody extends ApproveBody {\n reason?: string;\n}\n\n@Controller('tool-call')\nexport class ToolCallController {\n constructor(\n private readonly agent: AgentService,\n @Inject(AGENT_ACTOR_RESOLVER) private readonly actorResolver: ActorResolver,\n ) {}\n\n @Post('approve')\n async approve(@Req() req: Request, @Body() body: ApproveBody): Promise<{ ok: boolean }> {\n const actor = await this.actorResolver.resolve(req);\n await this.agent.approve(actor, body.toolCallId);\n return { ok: true };\n }\n\n @Post('reject')\n async reject(@Req() req: Request, @Body() body: RejectBody): Promise<{ ok: boolean }> {\n const actor = await this.actorResolver.resolve(req);\n await this.agent.reject(actor, body.toolCallId, body.reason);\n return { ok: true };\n }\n}\n","import {\n AGENT_PROMPT_CONTRIBUTORS,\n AGENT_REGISTRY,\n type AgentDefinition,\n AgentRegistry,\n type PromptBuilder,\n type PromptContext,\n type PromptContributor,\n} from '@dudousxd/nestjs-agent-core';\nimport { Inject, Injectable, Logger, type OnModuleInit } from '@nestjs/common';\nimport { DiscoveryService, MetadataScanner } from '@nestjs/core';\nimport { type AgentOptions, readAgentMetadata } from '../decorator/agent.decorator.js';\nimport {\n SYSTEM_PROMPT_CONTRIBUTOR_METADATA,\n SYSTEM_PROMPT_METADATA,\n} from '../decorator/system-prompt.decorator.js';\n\n/**\n * Populates the {@link AgentRegistry} from `@Agent`-decorated providers and collects every\n * `@SystemPromptContributor()` method into the app-wide contributor list — the discovery counterpart\n * to authoring agents as config objects. Runs on `onModuleInit`, so agents/contributors are in place\n * before `AiToolDiscoveryService` (which synthesizes handoff tools) runs its `onApplicationBootstrap`.\n */\n@Injectable()\nexport class AgentDiscoveryService implements OnModuleInit {\n private readonly logger = new Logger(AgentDiscoveryService.name);\n\n constructor(\n private readonly discovery: DiscoveryService,\n private readonly scanner: MetadataScanner,\n @Inject(AGENT_REGISTRY) private readonly registry: AgentRegistry,\n @Inject(AGENT_PROMPT_CONTRIBUTORS) private readonly contributors: PromptContributor[],\n ) {}\n\n onModuleInit(): void {\n for (const wrapper of this.discovery.getProviders()) {\n const instance = wrapper.instance;\n if (instance === null || typeof instance !== 'object') {\n continue;\n }\n const meta = readAgentMetadata(instance.constructor);\n if (meta !== undefined) {\n this.registry.register(this.definitionFrom(instance, meta));\n }\n this.collectContributors(instance);\n }\n }\n\n /** Build the internal {@link AgentDefinition} from an `@Agent` instance and its options. */\n private definitionFrom(instance: object, meta: AgentOptions): AgentDefinition {\n const promptMethod = this.methodWith(instance, SYSTEM_PROMPT_METADATA);\n const systemPrompt: string | PromptBuilder =\n promptMethod !== undefined\n ? (ctx: PromptContext) => promptMethod(ctx) as string | Promise<string>\n : (meta.systemPrompt ?? 'You are a helpful assistant.');\n return {\n name: meta.name,\n ...(meta.description !== undefined ? { description: meta.description } : {}),\n systemPrompt,\n ...(meta.tools !== undefined ? { tools: meta.tools } : {}),\n ...(meta.model !== undefined ? { modelId: meta.model } : {}),\n ...(meta.maxSteps !== undefined ? { maxSteps: meta.maxSteps } : {}),\n ...(meta.handoff !== undefined ? { delegatesTo: this.handoffNames(meta) } : {}),\n };\n }\n\n /** Resolve each handoff `@Agent` class to its registered name (skipping non-agent classes). */\n private handoffNames(meta: AgentOptions): string[] {\n const names: string[] = [];\n for (const target of meta.handoff ?? []) {\n const targetMeta = readAgentMetadata(target);\n if (targetMeta === undefined) {\n this.logger.warn(\n `Agent \"${meta.name}\" hands off to ${target.name}, which is not an @Agent — skipped.`,\n );\n continue;\n }\n names.push(targetMeta.name);\n }\n return names;\n }\n\n /** Push every `@SystemPromptContributor()` method on `instance` (bound) into the contributor list. */\n private collectContributors(instance: object): void {\n const prototype = Object.getPrototypeOf(instance) as object;\n for (const name of this.scanner.getAllMethodNames(prototype)) {\n if (Reflect.getMetadata(SYSTEM_PROMPT_CONTRIBUTOR_METADATA, prototype, name) === true) {\n const method = this.boundMethod(instance, name);\n if (method !== undefined) {\n this.contributors.push(\n (ctx: PromptContext) => method(ctx) as ReturnType<PromptContributor>,\n );\n }\n }\n }\n }\n\n /** The single method on `instance` carrying `metadataKey`, bound to the instance, or undefined. */\n private methodWith(\n instance: object,\n metadataKey: symbol,\n ): ((ctx: PromptContext) => unknown) | undefined {\n const prototype = Object.getPrototypeOf(instance) as object;\n for (const name of this.scanner.getAllMethodNames(prototype)) {\n if (Reflect.getMetadata(metadataKey, prototype, name) === true) {\n return this.boundMethod(instance, name);\n }\n }\n return undefined;\n }\n\n /** Bind a named method to its instance, guarding that it is actually a function. */\n private boundMethod(\n instance: object,\n name: string,\n ): ((ctx: PromptContext) => unknown) | undefined {\n const candidate = (instance as Record<string, unknown>)[name];\n if (typeof candidate !== 'function') {\n return undefined;\n }\n return (ctx: PromptContext) =>\n (candidate as (ctx: PromptContext) => unknown).call(instance, ctx);\n }\n}\n","import 'reflect-metadata';\nimport type { Type } from '@nestjs/common';\n\n/**\n * Declares a class as an agent. The class is discovered at boot (via `DiscoveryService`) and\n * registered into the `AgentRegistry` — its name, base prompt, tool allow-list, and handoff targets\n * become an internal `AgentDefinition` the loop consumes. The class is an ordinary provider, so it\n * gets constructor DI (its retriever, schema service, policy) — the reason an agent is a class and\n * not a config object.\n *\n * The base prompt is either the `systemPrompt` string here or, for a dynamic prompt, a\n * `@SystemPrompt()` method on the class (which may inject services and read the turn's\n * `PromptContext`). Tools are the global `@AiTool` providers named in `tools` (omit → all tools the\n * actor's role allows); handoff targets are other `@Agent` classes.\n */\nexport interface AgentOptions {\n /** Unique agent name — how a turn selects it and how a message records its provenance. */\n name: string;\n /** Human-readable summary (shown to an orchestrator that may hand off to this agent). */\n description?: string;\n /** A flat base prompt. For a dynamic prompt, add a `@SystemPrompt()` method instead. */\n systemPrompt?: string;\n /** Accounting label for the model this agent uses (the model provider itself is shared). */\n model?: string;\n /** Max model→tool iterations for this agent's turn. Default 8. */\n maxSteps?: number;\n /** Allow-list of global tool names this agent may use. Omit → every tool its role allows. */\n tools?: string[];\n /** Other `@Agent` classes this agent may hand off to (auto-exposed as handoff tools). */\n handoff?: Type[];\n}\n\nexport const AGENT_METADATA = Symbol.for('@dudousxd/nestjs-agent:agent-metadata');\n\n/** Marks a provider class as an agent. See {@link AgentOptions}. */\nexport function Agent(options: AgentOptions): ClassDecorator {\n return (target) => {\n Reflect.defineMetadata(AGENT_METADATA, options, target);\n };\n}\n\n/**\n * Reads {@link AgentOptions} off a class (its constructor), or `undefined` if not an `@Agent`. The\n * reflection target is a class or Nest's provider `metatype`, whose type is precisely `Type |\n * Function`; narrowing it away from `Function` would reject valid callers.\n */\n// biome-ignore lint/complexity/noBannedTypes: the reflection target's type is precisely `Type | Function`.\nexport function readAgentMetadata(target: Type | Function): AgentOptions | undefined {\n return Reflect.getMetadata(AGENT_METADATA, target) as AgentOptions | undefined;\n}\n","import 'reflect-metadata';\n\n/**\n * Marks the method on an `@Agent` class that builds the agent's base system prompt. The method\n * receives the turn's `PromptContext` and returns a string (optionally async); because it lives on a\n * provider, it can inject services (e.g. describe a schema, read the actor). Exactly one per agent —\n * it takes precedence over the `@Agent({ systemPrompt })` string.\n */\nexport const SYSTEM_PROMPT_METADATA = Symbol.for('@dudousxd/nestjs-agent:system-prompt');\n\n/**\n * Marks a method on any provider as a cross-agent system-prompt contributor: it returns an ordered\n * section appended to the composed prompt (after the selected agent's base), or `null` to contribute\n * nothing this turn. This is the seam an app uses to inject domain sections (base scope, a mentions\n * legend, schema hints) across every agent without forking the loop.\n */\nexport const SYSTEM_PROMPT_CONTRIBUTOR_METADATA = Symbol.for(\n '@dudousxd/nestjs-agent:system-prompt-contributor',\n);\n\n/** Marks an `@Agent` method as the agent's dynamic base prompt. See {@link SYSTEM_PROMPT_METADATA}. */\nexport function SystemPrompt(): MethodDecorator {\n return (target, key) => {\n Reflect.defineMetadata(SYSTEM_PROMPT_METADATA, true, target, key);\n };\n}\n\n/** Marks a provider method as a cross-agent prompt contributor. See {@link SYSTEM_PROMPT_CONTRIBUTOR_METADATA}. */\nexport function SystemPromptContributor(): MethodDecorator {\n return (target, key) => {\n Reflect.defineMetadata(SYSTEM_PROMPT_CONTRIBUTOR_METADATA, true, target, key);\n };\n}\n","import {\n AGENT_OPTIONS,\n AGENT_REGISTRY,\n AGENT_TOOL_REGISTRY,\n type AgentRegistry,\n type ToolHandler,\n type ToolRegistry,\n} from '@dudousxd/nestjs-agent-core';\nimport { Inject, Injectable, Logger, type OnApplicationBootstrap } from '@nestjs/common';\nimport { DiscoveryService } from '@nestjs/core';\nimport { z } from 'zod';\nimport { delegateToolName } from '../agent-deps.factory.js';\nimport type { AgentModuleOptions } from '../agent.options.js';\nimport { readAiToolMetadata } from '../decorator/ai-tool.decorator.js';\nimport { type FunctionalTool, isBrandedFunctionalTool } from '../functional-tool.js';\n\n/** Walks every provider at boot and registers `@AiTool` classes into the shared registry. */\n@Injectable()\nexport class AiToolDiscoveryService implements OnApplicationBootstrap {\n private readonly logger = new Logger(AiToolDiscoveryService.name);\n\n constructor(\n private readonly discovery: DiscoveryService,\n @Inject(AGENT_TOOL_REGISTRY) private readonly registry: ToolRegistry,\n @Inject(AGENT_REGISTRY) private readonly agents: AgentRegistry,\n @Inject(AGENT_OPTIONS) private readonly options: AgentModuleOptions,\n ) {}\n\n onApplicationBootstrap(): void {\n let count = 0;\n let functional = 0;\n for (const wrapper of this.discovery.getProviders()) {\n const instance = wrapper.instance;\n if (instance === null || instance === undefined || typeof instance !== 'object') {\n continue;\n }\n // Functional tools registered via `provideAgentTool` resolve to a branded { spec, handler }.\n if (isBrandedFunctionalTool(instance)) {\n if (this.registerFunctionalTool(instance)) {\n functional += 1;\n }\n continue;\n }\n const meta = readAiToolMetadata(instance);\n if (meta === undefined) {\n continue;\n }\n const handler = instance as Partial<ToolHandler>;\n if (typeof handler.execute !== 'function') {\n this.logger.warn(`@AiTool \"${meta.name}\" has no execute() method — skipped`);\n continue;\n }\n this.registry.register(\n {\n name: meta.name,\n kind: meta.kind,\n description: meta.description,\n inputSchema: meta.input,\n // Leave roles unset when the tool didn't declare any — the RolesPolicy owns the default\n // (its `defaultRoles`). Baking it in here too would leak it into custom policies.\n ...(meta.roles !== undefined ? { roles: meta.roles } : {}),\n ...(meta.ability !== undefined ? { ability: meta.ability } : {}),\n },\n { execute: (input, ctx) => (instance as ToolHandler).execute(input, ctx) },\n );\n count += 1;\n }\n\n // Static functional tools passed straight to `forRoot({ tools })`.\n for (const tool of this.options.tools ?? []) {\n if (this.registerFunctionalTool(tool)) {\n functional += 1;\n }\n }\n\n // Synthesize an `agent`-kind delegate tool for each agent->agent edge declared via `delegatesTo`.\n let delegates = 0;\n for (const definition of this.agents.list()) {\n for (const target of definition.delegatesTo ?? []) {\n const targetDefinition = this.agents.get(target);\n // A dangling handoff target (a `@Agent({ handoff })` class that isn't itself an `@Agent`)\n // would otherwise synthesize a delegate to a phantom agent that resolves to an UNRESTRICTED\n // default agent at runtime — a privilege-escalation footgun. Fail the boot instead.\n if (targetDefinition === undefined) {\n throw new Error(\n `Agent \"${definition.name}\" hands off to \"${target}\", which is not a registered @Agent. Declare it as an @Agent provider or fix the reference.`,\n );\n }\n const name = delegateToolName(target);\n if (this.registry.has(name)) {\n continue;\n }\n // Only a flat string prompt is worth surfacing in the tool description; a PromptBuilder is\n // per-request and would stringify to source, so skip it.\n const targetBlurb =\n typeof targetDefinition.systemPrompt === 'string'\n ? ` It is: ${targetDefinition.systemPrompt}`\n : '';\n this.registry.register(\n {\n name,\n kind: 'agent',\n targetAgent: target,\n description: `Delegate a task to the \"${target}\" agent and get its answer.${targetBlurb}`,\n inputSchema: z.object({ task: z.string() }),\n },\n // Loop-handled (kind 'agent'); the handler is never called.\n { execute: async () => ({}) },\n );\n delegates += 1;\n }\n }\n this.logger.log(\n `registered ${count} AI tool(s), ${functional} functional tool(s) and ${delegates} delegate tool(s)`,\n );\n }\n\n /**\n * Registers a functional tool's `{ spec, handler }`, skipping it if a tool of the same name is\n * already registered. Returns whether it was newly registered.\n */\n private registerFunctionalTool(tool: FunctionalTool): boolean {\n if (this.registry.has(tool.spec.name)) {\n this.logger.warn(\n `functional tool \"${tool.spec.name}\" duplicates a registered name — skipped`,\n );\n return false;\n }\n this.registry.register(tool.spec, tool.handler);\n return true;\n }\n}\n","import 'reflect-metadata';\nimport type { StandardSchemaV1 } from '@standard-schema/spec';\n\nexport const AI_TOOL_METADATA = Symbol('nestjs-agent:ai-tool');\n\nexport interface AiToolOptions {\n name: string;\n /**\n * `read` auto-executes; `action` requires HITL approval. (Core's `ToolKind` also has `agent`\n * for delegation, but that kind is synthesized from `delegatesTo` — never authored here.)\n */\n kind: 'read' | 'action';\n description: string;\n /**\n * Input schema as a [Standard Schema](https://standardschema.dev) — Zod, Valibot, or ArkType.\n * Validated before the handler runs.\n */\n input: StandardSchemaV1;\n /** Roles allowed to invoke. Omit to inherit the module's default roles. */\n roles?: string[];\n /**\n * Authz ability checked by an ability-aware RolesPolicy (e.g. `AgentAuthzModule`'s\n * `AuthzRolesPolicy` → `gate.forUser(actor).allows(ability)`). Ignored by the default\n * role-based policy, which uses `roles`.\n */\n ability?: string;\n}\n\n/**\n * Marks a provider class as an AI tool. The class must implement `execute(input, ctx)`.\n * `AiToolDiscoveryService` registers every `@AiTool` provider into the `ToolRegistry` at boot.\n *\n * ```ts\n * @AiTool({ name: 'getWeather', kind: 'read', description: '...', input: z.object({ city: z.string() }) })\n * class GetWeatherTool implements ToolHandler<{ city: string }> {\n * async execute(input, ctx) { return { tempC: 21 }; }\n * }\n * ```\n */\nexport function AiTool(options: AiToolOptions): ClassDecorator {\n return (target) => {\n Reflect.defineMetadata(AI_TOOL_METADATA, options, target);\n };\n}\n\nexport function readAiToolMetadata(target: object): AiToolOptions | undefined {\n return Reflect.getMetadata(AI_TOOL_METADATA, target.constructor) as AiToolOptions | undefined;\n}\n","import type { ToolHandler, ToolSpec } 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","import {\n AgentStreamError,\n type SinkWriter,\n type StreamError,\n type TokenStreamSink,\n} from '@dudousxd/nestjs-agent-core';\n\ninterface RunBuffer {\n chunks: Uint8Array[];\n ended: boolean;\n failure?: StreamError;\n notify: Set<() => void>;\n}\n\n/**\n * The default `TokenStreamSink`: buffers chunks per run in-process so a reconnecting subscriber\n * replays everything so far, then follows live.\n *\n * Single-replica only. Because the buffer lives in one process's memory, a resume/reconnect that\n * lands on a different replica than the one running the turn finds an empty buffer — the stream\n * appears stalled. For multi-replica deployments, supply a shared-transport `TokenStreamSink`\n * (e.g. Redis pub/sub keyed by runId) via `AgentModule.forRoot({ sink })`.\n */\nexport class InProcessTokenStreamSink implements TokenStreamSink {\n private readonly runs = new Map<string, RunBuffer>();\n\n private buffer(runId: string): RunBuffer {\n let buf = this.runs.get(runId);\n if (buf === undefined) {\n buf = { chunks: [], ended: false, notify: new Set() };\n this.runs.set(runId, buf);\n }\n return buf;\n }\n\n private wake(buf: RunBuffer): void {\n for (const resolve of buf.notify) {\n resolve();\n }\n buf.notify.clear();\n }\n\n open(runId: string): SinkWriter {\n const buf = this.buffer(runId);\n return {\n write: (chunk: Uint8Array) => {\n buf.chunks.push(chunk);\n this.wake(buf);\n },\n end: () => {\n buf.ended = true;\n this.wake(buf);\n },\n fail: (error: StreamError) => {\n buf.failure = error;\n buf.ended = true;\n this.wake(buf);\n },\n };\n }\n\n async *subscribe(runId: string): AsyncIterable<Uint8Array> {\n const buf = this.buffer(runId);\n let index = 0;\n while (true) {\n while (index < buf.chunks.length) {\n const chunk = buf.chunks[index];\n index += 1;\n if (chunk !== undefined) {\n yield chunk;\n }\n }\n if (buf.ended) {\n // Drain buffered chunks first, then raise the failure as a typed terminal.\n if (buf.failure !== undefined) {\n throw new AgentStreamError(buf.failure);\n }\n return;\n }\n await new Promise<void>((resolve) => buf.notify.add(resolve));\n }\n }\n\n close(runId: string): void {\n this.runs.delete(runId);\n }\n}\n","import type { AgentStore, QuotaState, QuotaStore } from '@dudousxd/nestjs-agent-core';\n\n/**\n * A production {@link QuotaStore} backed by the persisted usage ledger. `check` reads the actor's\n * tokens-so-far for the day straight from {@link AgentStore.quotaToday} and compares it to a fixed\n * daily limit; `bump` is a deliberate no-op because the loop's `recordUsage` already writes every\n * turn's tokens to that same ledger. One source of truth — so enforcement and what the dashboard\n * reports can never drift, and it works across replicas with no extra shared state.\n */\nexport class LedgerQuotaStore implements QuotaStore {\n constructor(\n private readonly store: AgentStore,\n private readonly limitTokens: number,\n ) {}\n\n async check(actorRef: string, day: string): Promise<QuotaState> {\n const { usedTokens } = await this.store.quotaToday(actorRef, day);\n return {\n usedTokens,\n limitTokens: this.limitTokens,\n withinLimit: usedTokens < this.limitTokens,\n };\n }\n\n async bump(): Promise<void> {\n // No-op: the ledger is the source of truth — recordUsage already persisted this turn's tokens.\n }\n}\n","import {\n AGENT_DEPS_FACTORY,\n AGENT_STORE,\n type Actor,\n type AgentLoopHooks,\n type AgentRunInput,\n type AgentRunner,\n type AgentStore,\n type Decision,\n QuotaExceededError,\n publishAgentRunFailed,\n runAgentLoop,\n} from '@dudousxd/nestjs-agent-core';\nimport { Inject, Injectable, Logger } from '@nestjs/common';\nimport type { AgentDepsFactory } from '../agent-deps.factory.js';\nimport { type AgentDeps, childSinkWriter, utcDay } from '../agent-deps.js';\n\n/**\n * Runs the agent turn in-process. HITL approval resolves a pending promise keyed by\n * `runId:toolCallId`. Sub-agent delegation runs a nested loop that streams into the top-level run's\n * sink (so a human sees it) and shares the same approval mechanism — a sub-agent's action tools go\n * through the same human gate, keyed by the sub-agent's own runId. Single-replica only (the pending\n * map is in-process); durable is the scaled path.\n */\n@Injectable()\nexport class InlineAgentRunner implements AgentRunner {\n private readonly logger = new Logger(InlineAgentRunner.name);\n private readonly pending = new Map<string, (decision: Decision) => void>();\n\n constructor(\n @Inject(AGENT_DEPS_FACTORY) private readonly factory: AgentDepsFactory,\n @Inject(AGENT_STORE) private readonly store: AgentStore,\n ) {}\n\n async start(input: AgentRunInput): Promise<{ runId: string }> {\n const runId = crypto.randomUUID();\n const day = input.day ?? utcDay();\n const deps = this.factory.forAgent(input.agentName);\n const hooks = this.topLevelHooks(runId, deps, input.actor, day);\n\n void runAgentLoop({ ...deps, day }, input, hooks)\n .then(() => this.store.setActiveStream(input.threadId, null))\n .catch(async (error) => {\n const message = error instanceof Error ? error.message : String(error);\n const code = error instanceof QuotaExceededError ? 'quota_exceeded' : 'run_failed';\n this.logger.error(`agent run ${runId} failed (${code}): ${message}`);\n publishAgentRunFailed({ runId, code, message });\n // Settle the run's persisted outcome (the loop only records completions — it can't catch\n // its own crash). Optional-call: a store without run recording skips reliability metrics.\n await this.store.recordRunEnd?.({\n runId,\n status: 'failed',\n errorCode: code,\n errorMessage: message,\n });\n // Clear the thread's active run — a failed run isn't \"still running\" for `activeRunForThread`.\n await this.store.setActiveStream(input.threadId, null);\n // Terminate the live stream with a typed failure so the transport emits an error frame\n // instead of leaking the message as assistant text.\n const writer = await deps.sink.open(runId);\n await writer.fail({ code, message });\n });\n\n return { runId };\n }\n\n async signal(runId: string, toolCallId: string, decision: Decision): Promise<void> {\n const key = `${runId}:${toolCallId}`;\n const resolve = this.pending.get(key);\n if (resolve !== undefined) {\n this.pending.delete(key);\n resolve(decision);\n }\n }\n\n async cancel(runId: string): Promise<void> {\n const deps = this.factory.forAgent();\n const writer = await deps.sink.open(runId);\n await writer.end();\n }\n\n private topLevelHooks(runId: string, deps: AgentDeps, actor: Actor, day: string): AgentLoopHooks {\n return {\n runId,\n openSink: () => deps.sink.open(runId),\n awaitApproval: (call) =>\n new Promise<Decision>((resolve) => {\n this.pending.set(`${runId}:${call.id}`, resolve);\n }),\n step: (_name, fn) => fn(),\n runAgent: (agentName, task) => this.runNested(agentName, task, actor, day, 1, runId),\n };\n }\n\n /**\n * Delegate to another agent as a nested in-process run. The sub-agent streams into `sinkRunId`\n * (the top-level run the human is watching) so its output and any pending action tool are visible,\n * and its own approvals resolve through the shared pending map keyed by its own runId.\n */\n private async runNested(\n agentName: string,\n task: string,\n actor: Actor,\n day: string,\n depth: number,\n sinkRunId: string,\n ): Promise<{ text: string }> {\n const subThread = await this.store.createThread({ actor, transient: true });\n const runId = crypto.randomUUID();\n // Mark the subthread as streaming THIS sub-run so a human approval routes back here\n // (runForToolCall → subthread.activeStreamId → this runId).\n await this.store.setActiveStream(subThread.id, runId);\n const deps = this.factory.forAgent(agentName);\n const hooks: AgentLoopHooks = {\n runId,\n // Forward into the top-level stream; the top-level run owns end/fail on that shared sink.\n openSink: async () => childSinkWriter(await deps.sink.open(sinkRunId)),\n awaitApproval: (call) =>\n new Promise<Decision>((resolve) => {\n this.pending.set(`${runId}:${call.id}`, resolve);\n }),\n step: (_name, fn) => fn(),\n runAgent: (childName, childTask) =>\n this.runNested(childName, childTask, actor, day, depth + 1, sinkRunId),\n };\n try {\n return await runAgentLoop(\n { ...deps, day },\n {\n threadId: subThread.id,\n actor,\n userText: task,\n agentName,\n day,\n delegationDepth: depth,\n sinkRunId,\n },\n hooks,\n );\n } finally {\n // No durable-style suspend to worry about here (inline runs to completion synchronously from\n // this call's point of view) — always clear so `activeRunForThread` reflects reality.\n await this.store.setActiveStream(subThread.id, null);\n }\n }\n}\n","import type { Actor, ActorResolver } from '@dudousxd/nestjs-agent-core';\n\n/** Read a string header off an unknown transport request, narrowing without trusting its shape. */\nfunction readHeader(req: unknown, name: string): string | undefined {\n if (typeof req !== 'object' || req === null || !('headers' in req)) return undefined;\n const { headers } = req;\n if (typeof headers !== 'object' || headers === null || !(name in headers)) return undefined;\n const value: unknown = Reflect.get(headers, name);\n return typeof value === 'string' ? value : undefined;\n}\n\n/**\n * A development / gateway {@link ActorResolver} that trusts request headers:\n * `x-actor-id` (required), `x-actor-role` (comma-separated → `roles`), `x-tenant-ref`.\n *\n * **Security:** it throws when `x-actor-id` is absent — it never fabricates an identity\n * and never grants a default role (an actor with no `x-actor-role` gets `roles: []`, i.e.\n * no tools). Trusting client headers is only safe behind a gateway that strips and re-sets\n * them from an authenticated principal. Real deployments should provide their own resolver\n * that reads a verified session/JWT instead of installing this one.\n */\nexport class HeaderActorResolver implements ActorResolver {\n resolve(req: unknown): Actor {\n const id = readHeader(req, 'x-actor-id');\n if (id === undefined || id.length === 0) {\n throw new Error(\n 'HeaderActorResolver: missing x-actor-id header. No default actor is fabricated. ' +\n 'Send x-actor-id from a trusted gateway, or configure ' +\n 'AgentModule.forRoot({ actorResolver }) with a resolver that reads your ' +\n 'authenticated principal.',\n );\n }\n const roles = (readHeader(req, 'x-actor-role') ?? '')\n .split(',')\n .map((role) => role.trim())\n .filter((role) => role.length > 0);\n const tenantRef = readHeader(req, 'x-tenant-ref');\n return {\n id,\n roles,\n ...(tenantRef !== undefined ? { tenantRef } : {}),\n };\n }\n}\n"],"mappings":"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","names":["AgentDepsFactory","import_nestjs_agent_core","import_common","import_core","import_nestjs_agent_core","delegateToolName","target","replace","AgentDepsFactory","options","model","store","sink","rolesPolicy","registry","agents","promptContributors","quota","pricingStore","defaultAgentName","defaultAgent","undefined","registered","list","length","name","effectiveTools","definition","delegated","delegatesTo","map","tools","forAgent","agentName","get","toolAllowList","followUpsCount","retrieval","systemPrompt","maxSteps","modelId","toolTimeoutMs","toolTransientRetry","mode","retriever","topK","retrievalTopK","followUps","count","import_nestjs_agent_core","import_common","utcDay","date","Date","toISOString","slice","childSinkWriter","writer","write","chunk","end","fail","AgentService","runner","store","deps","quota","chat","params","agentName","resolveAgentName","threadId","undefined","regenerate","BadRequestException","created","createThread","actor","transient","id","assertOwnsThread","input","userText","message","day","utcDay","attachments","pageContext","runId","start","setActiveStream","subscribe","forAgent","sink","approve","toolCallId","assertOwnsToolCall","signalToolCall","approved","reject","reason","decision","resolveRunForToolCall","signal","cancel","assertOwnsActiveStream","listThreads","actorRef","threads","Promise","all","map","thread","toSummaryView","getThread","toDetailView","deleteThread","softDeleteThread","forkThread","fromMessageId","renameThread","title","updateThread","patch","validateTitle","defaultAgent","setTitle","NotImplementedException","trimmed","trim","length","defaultAgentName","activeRunId","activeRunForThread","summary","messages","activeStreamId","promoteThread","truncateThreadFrom","messageId","truncateFrom","quotaToday","usedTokens","costUsd","limitTokens","withinLimit","state","check","owner","ownerOfThread","NotFoundException","ForbiddenException","ownerOfToolCall","runForToolCall","ownerOfActiveStream","import_common","AgentApprovalPortAdapter","agent","approve","toolCallId","opts","signalToolCall","approved","executedByRef","undefined","reject","reason","import_nestjs_agent_core","import_common","AgentsController","agents","depsFactory","list","defaultAgentName","map","definition","name","description","isDefault","import_nestjs_agent_core","import_common","DEFAULT_MAX_ATTACHMENT_BYTES","DEFAULT_ALLOWED_ATTACHMENT_CONTENT_TYPES","AttachmentsController","options","actorResolver","staging","onModuleInit","attachments","upload","undefined","Error","req","file","NotImplementedException","BadRequestException","allowedContentTypes","includes","mimetype","UnsupportedMediaTypeException","join","maxBytes","size","PayloadTooLargeException","actor","resolve","stage","data","buffer","filename","originalname","contentType","sizeBytes","import_nestjs_agent_core","import_common","ChatController","agent","actorResolver","chat","req","res","body","actor","resolve","runId","threadId","message","undefined","agentName","attachments","pageContext","regenerate","transient","pipe","stream","cancel","aborted","setHeader","write","JSON","stringify","decoder","TextDecoder","buffer","chunk","subscribe","decode","newline","indexOf","line","slice","length","error","payload","AgentStreamError","code","Error","end","import_nestjs_agent_core","import_common","QuotaController","agent","actorResolver","today","req","actor","resolve","quotaToday","id","import_nestjs_agent_core","import_common","ThreadsController","agent","actorResolver","list","req","actor","resolve","listThreads","id","detail","getThread","remove","deleteThread","ok","fork","messageId","forkThread","update","body","updateThread","title","undefined","defaultAgent","promote","promoteThread","truncateFrom","truncateThreadFrom","import_nestjs_agent_core","import_common","ToolCallController","agent","actorResolver","approve","req","body","actor","resolve","toolCallId","ok","reject","reason","import_nestjs_agent_core","import_common","AGENT_METADATA","Symbol","for","Agent","options","target","Reflect","defineMetadata","readAgentMetadata","getMetadata","import_reflect_metadata","SYSTEM_PROMPT_METADATA","Symbol","for","SYSTEM_PROMPT_CONTRIBUTOR_METADATA","SystemPrompt","target","key","Reflect","defineMetadata","SystemPromptContributor","AgentDiscoveryService","logger","Logger","name","discovery","scanner","registry","contributors","onModuleInit","wrapper","getProviders","instance","meta","readAgentMetadata","undefined","register","definitionFrom","collectContributors","promptMethod","methodWith","SYSTEM_PROMPT_METADATA","systemPrompt","ctx","description","tools","model","modelId","maxSteps","handoff","delegatesTo","handoffNames","names","target","targetMeta","warn","push","prototype","Object","getPrototypeOf","getAllMethodNames","Reflect","getMetadata","SYSTEM_PROMPT_CONTRIBUTOR_METADATA","method","boundMethod","metadataKey","candidate","call","import_nestjs_agent_core","import_common","import_core","import_reflect_metadata","AI_TOOL_METADATA","Symbol","AiTool","options","target","Reflect","defineMetadata","readAiToolMetadata","getMetadata","AGENT_TOOL_BRAND","Symbol","for","brand","tool","spec","handler","isBrandedFunctionalTool","value","provideAgentTool","factoryOrTool","inject","provide","useFactory","deps","useValue","AiToolDiscoveryService","logger","Logger","name","discovery","registry","agents","options","onApplicationBootstrap","count","functional","wrapper","getProviders","instance","undefined","isBrandedFunctionalTool","registerFunctionalTool","meta","readAiToolMetadata","handler","execute","warn","register","kind","description","inputSchema","input","roles","ability","ctx","tool","tools","delegates","definition","list","target","delegatesTo","targetDefinition","get","Error","delegateToolName","has","targetBlurb","systemPrompt","targetAgent","z","object","task","string","log","spec","import_nestjs_agent_core","InProcessTokenStreamSink","runs","Map","buffer","runId","buf","get","undefined","chunks","ended","notify","Set","set","wake","resolve","clear","open","write","chunk","push","end","fail","error","failure","subscribe","index","length","AgentStreamError","Promise","add","close","delete","LedgerQuotaStore","store","limitTokens","check","actorRef","day","usedTokens","quotaToday","withinLimit","bump","import_nestjs_agent_core","import_common","InlineAgentRunner","logger","Logger","name","pending","Map","factory","store","start","input","runId","crypto","randomUUID","day","utcDay","deps","forAgent","agentName","hooks","topLevelHooks","actor","runAgentLoop","then","setActiveStream","threadId","catch","error","message","Error","String","code","QuotaExceededError","publishAgentRunFailed","recordRunEnd","status","errorCode","errorMessage","writer","sink","open","fail","signal","toolCallId","decision","key","resolve","get","undefined","delete","cancel","end","openSink","awaitApproval","call","Promise","set","id","step","_name","fn","runAgent","task","runNested","depth","sinkRunId","subThread","createThread","transient","childSinkWriter","childName","childTask","userText","delegationDepth","DEFAULT_PATH","sharedProviders","durable","includeStore","providers","provide","AGENT_TOOL_REGISTRY","useFactory","ToolRegistry","AGENT_REGISTRY","AgentRegistry","AGENT_PROMPT_CONTRIBUTORS","AGENT_SINK","options","sink","InProcessTokenStreamSink","inject","AGENT_OPTIONS","AGENT_ROLES_POLICY","rolesPolicy","DefaultRolesPolicy","defaultRoles","AGENT_ACTOR_RESOLVER","actorResolver","AGENT_MODEL","o","model","AGENT_QUOTA_STORE","store","quota","quotaLimitTokens","undefined","LedgerQuotaStore","AGENT_STORE","AgentDepsFactory","AGENT_DEPS_FACTORY","useExisting","AgentDiscoveryService","AiToolDiscoveryService","InlineAgentRunner","AgentService","AgentApprovalPortAdapter","AGENT_APPROVAL_PORT","push","AGENT_RUNNER","durableRunner","Error","token","AGENT_DURABLE_RUNNER","optional","exportsFor","BASE_CONTROLLERS","ChatController","ThreadsController","ToolCallController","QuotaController","AgentsController","GUARDABLE_CONTROLLERS","AttachmentsController","controllersFor","mountAttachments","GUARDS_METADATA","applyGuards","guards","resolved","controller","Reflect","defineMetadata","guardProviders","Set","routerFor","path","RouterModule","register","module","AgentModule","assertDispatchedStepsRequiresDurable","dispatchedSteps","forRoot","global","imports","DiscoveryModule","controllers","attachments","upload","useValue","exports","forRootAsync","externalStore","attachmentsUpload","args","readHeader","req","name","undefined","headers","value","Reflect","get","HeaderActorResolver","resolve","id","length","Error","roles","split","map","role","trim","filter","tenantRef"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/agent.module.ts","../src/agent-deps.factory.ts","../src/agent.service.ts","../src/agent-deps.ts","../src/approval-port.adapter.ts","../src/controller/agents.controller.ts","../src/controller/attachments.controller.ts","../src/controller/chat.controller.ts","../src/controller/quota.controller.ts","../src/controller/threads.controller.ts","../src/controller/tool-call.controller.ts","../src/discovery/agent-discovery.service.ts","../src/decorator/agent.decorator.ts","../src/decorator/system-prompt.decorator.ts","../src/discovery/ai-tool-discovery.service.ts","../src/decorator/ai-tool.decorator.ts","../src/functional-tool.ts","../src/in-process-sink.ts","../src/ledger-quota-store.ts","../src/runner/inline-agent-runner.ts","../src/resolver/header-actor-resolver.ts"],"sourcesContent":["export { AgentModule } from './agent.module.js';\nexport { AgentApprovalPortAdapter } from './approval-port.adapter.js';\nexport type {\n AgentModuleOptions,\n AgentModuleAsyncOptions,\n AgentAttachmentsOptions,\n AgentSurface,\n} from './agent.options.js';\nexport { AgentService, type ChatParams } from './agent.service.js';\nexport {\n AttachmentsController,\n DEFAULT_MAX_ATTACHMENT_BYTES,\n DEFAULT_ALLOWED_ATTACHMENT_CONTENT_TYPES,\n} from './controller/attachments.controller.js';\nexport {\n AiTool,\n type AiToolOptions,\n AI_TOOL_METADATA,\n readAiToolMetadata,\n} from './decorator/ai-tool.decorator.js';\nexport {\n Agent,\n type AgentOptions,\n AGENT_METADATA,\n readAgentMetadata,\n} from './decorator/agent.decorator.js';\nexport {\n SystemPrompt,\n SystemPromptContributor,\n SYSTEM_PROMPT_METADATA,\n SYSTEM_PROMPT_CONTRIBUTOR_METADATA,\n} from './decorator/system-prompt.decorator.js';\nexport { AiToolDiscoveryService } from './discovery/ai-tool-discovery.service.js';\nexport { AgentDiscoveryService } from './discovery/agent-discovery.service.js';\nexport {\n provideAgentTool,\n AGENT_TOOL_BRAND,\n type FunctionalTool,\n} from './functional-tool.js';\nexport { InlineAgentRunner } from './runner/inline-agent-runner.js';\nexport { InProcessTokenStreamSink } from './in-process-sink.js';\nexport { LedgerQuotaStore } from './ledger-quota-store.js';\nexport { type AgentDeps, utcDay } from './agent-deps.js';\nexport { AgentDepsFactory, delegateToolName } from './agent-deps.factory.js';\nexport { HeaderActorResolver } from './resolver/header-actor-resolver.js';\n\n// Re-export the core surface so consumers import tools/types from one place.\nexport * from '@dudousxd/nestjs-agent-core';\n","import {\n AGENT_ACTOR_RESOLVER,\n AGENT_APPROVAL_PORT,\n AGENT_DEPS_FACTORY,\n AGENT_DURABLE_RUNNER,\n AGENT_MODEL,\n AGENT_OPTIONS,\n AGENT_PROMPT_CONTRIBUTORS,\n AGENT_QUOTA_STORE,\n AGENT_REGISTRY,\n AGENT_ROLES_POLICY,\n AGENT_RUNNER,\n AGENT_SINK,\n AGENT_STORE,\n AGENT_TOOL_REGISTRY,\n AgentRegistry,\n type AgentRunner,\n type AgentStore,\n DefaultRolesPolicy,\n ToolRegistry,\n} from '@dudousxd/nestjs-agent-core';\nimport {\n type CanActivate,\n type DynamicModule,\n Global,\n Module,\n type Provider,\n type Type,\n} from '@nestjs/common';\nimport { DiscoveryModule, RouterModule } from '@nestjs/core';\nimport { AgentDepsFactory } from './agent-deps.factory.js';\nimport type { AgentModuleAsyncOptions, AgentModuleOptions, AgentSurface } from './agent.options.js';\nimport { AgentService } from './agent.service.js';\nimport { AgentApprovalPortAdapter } from './approval-port.adapter.js';\nimport { AgentsController } from './controller/agents.controller.js';\nimport { AttachmentsController } from './controller/attachments.controller.js';\nimport { ChatController } from './controller/chat.controller.js';\nimport { QuotaController } from './controller/quota.controller.js';\nimport { ThreadsController } from './controller/threads.controller.js';\nimport { ToolCallController } from './controller/tool-call.controller.js';\nimport { AgentDiscoveryService } from './discovery/agent-discovery.service.js';\nimport { AiToolDiscoveryService } from './discovery/ai-tool-discovery.service.js';\nimport { InProcessTokenStreamSink } from './in-process-sink.js';\nimport { LedgerQuotaStore } from './ledger-quota-store.js';\nimport { InlineAgentRunner } from './runner/inline-agent-runner.js';\n\n/** Default route prefix the controllers mount under. */\nconst DEFAULT_PATH = 'agent';\n\n/**\n * The core wiring shared by `forRoot` / `forRootAsync`. `includeStore` controls whether we bind\n * `AGENT_STORE` locally: when the host omits `options.store` we leave it unbound so a globally-bound\n * store module (which binds `AGENT_STORE` app-wide) satisfies the dependency instead.\n */\nfunction sharedProviders(durable: boolean, includeStore: boolean): Provider[] {\n const providers: Provider[] = [\n { provide: AGENT_TOOL_REGISTRY, useFactory: () => new ToolRegistry() },\n // Starts empty; AgentDiscoveryService populates it from `@Agent`-decorated providers at boot.\n { provide: AGENT_REGISTRY, useFactory: () => new AgentRegistry() },\n // A shared, mutable list AgentDiscoveryService fills with `@SystemPromptContributor()` methods.\n { provide: AGENT_PROMPT_CONTRIBUTORS, useFactory: () => [] },\n {\n provide: AGENT_SINK,\n useFactory: (options: AgentModuleOptions) => options.sink ?? new InProcessTokenStreamSink(),\n inject: [AGENT_OPTIONS],\n },\n {\n provide: AGENT_ROLES_POLICY,\n useFactory: (options: AgentModuleOptions) =>\n options.rolesPolicy ?? new DefaultRolesPolicy(options.defaultRoles),\n inject: [AGENT_OPTIONS],\n },\n {\n provide: AGENT_ACTOR_RESOLVER,\n useFactory: (options: AgentModuleOptions) => options.actorResolver,\n inject: [AGENT_OPTIONS],\n },\n {\n provide: AGENT_MODEL,\n useFactory: (o: AgentModuleOptions) => o.model,\n inject: [AGENT_OPTIONS],\n },\n {\n // An explicit `quota` wins; otherwise `quotaLimitTokens` binds the built-in ledger-backed\n // store; otherwise quotas are off (undefined). The ledger store reads the same usage rows\n // the loop already writes, so enforcement needs no extra shared state across replicas.\n provide: AGENT_QUOTA_STORE,\n useFactory: (o: AgentModuleOptions, store: AgentStore) =>\n o.quota ??\n (o.quotaLimitTokens !== undefined\n ? new LedgerQuotaStore(store, o.quotaLimitTokens)\n : undefined),\n inject: [AGENT_OPTIONS, AGENT_STORE],\n },\n AgentDepsFactory,\n { provide: AGENT_DEPS_FACTORY, useExisting: AgentDepsFactory },\n // Populates the registry + contributors (onModuleInit) BEFORE AiToolDiscoveryService synthesizes\n // handoff tools (onApplicationBootstrap) reads the registry.\n AgentDiscoveryService,\n AiToolDiscoveryService,\n InlineAgentRunner,\n AgentService,\n // Bound ALWAYS (durable or inline) — the console's cross-thread approvals inbox routes decisions\n // through AgentService.signalToolCall, which reaches whichever AGENT_RUNNER is bound above.\n AgentApprovalPortAdapter,\n { provide: AGENT_APPROVAL_PORT, useExisting: AgentApprovalPortAdapter },\n ];\n if (includeStore) {\n providers.push({\n provide: AGENT_STORE,\n useFactory: (o: AgentModuleOptions) => o.store,\n inject: [AGENT_OPTIONS],\n });\n }\n if (durable) {\n // Bind AGENT_RUNNER to the durable runner AgentDurableModule provides. Optional injection turns\n // a forgotten `AgentDurableModule` import into a clear error instead of an unresolved-dep crash.\n providers.push({\n provide: AGENT_RUNNER,\n useFactory: (durableRunner: AgentRunner | undefined) => {\n if (durableRunner === undefined) {\n throw new Error(\n 'AgentModule.forRoot({ durable: true }) requires importing AgentDurableModule from ' +\n \"'@dudousxd/nestjs-agent/durable' (alongside a configured DurableModule). It was not found.\",\n );\n }\n return durableRunner;\n },\n inject: [{ token: AGENT_DURABLE_RUNNER, optional: true }],\n });\n } else {\n providers.push({ provide: AGENT_RUNNER, useExisting: InlineAgentRunner });\n }\n return providers;\n}\n\n/**\n * The module's public tokens. `AGENT_STORE` is only re-exported when we bind it locally — a module\n * cannot export a token it neither provides nor imports (the store module binds it globally instead).\n */\nfunction exportsFor(includeStore: boolean): NonNullable<DynamicModule['exports']> {\n return [\n AGENT_OPTIONS,\n AGENT_TOOL_REGISTRY,\n AGENT_REGISTRY,\n AGENT_SINK,\n AGENT_ROLES_POLICY,\n AGENT_ACTOR_RESOLVER,\n AGENT_MODEL,\n ...(includeStore ? [AGENT_STORE] : []),\n AGENT_QUOTA_STORE,\n AGENT_PROMPT_CONTRIBUTORS,\n AGENT_DEPS_FACTORY,\n AgentDepsFactory,\n AgentService,\n InlineAgentRunner,\n AGENT_APPROVAL_PORT,\n ];\n}\n\nconst BASE_CONTROLLERS = [\n ChatController,\n ThreadsController,\n ToolCallController,\n QuotaController,\n AgentsController,\n];\n\n/** Every controller class `guards` may ever target — stamped uniformly regardless of which of them are actually mounted this build (harmless: metadata on an unregistered class is simply unused). */\nconst GUARDABLE_CONTROLLERS = [...BASE_CONTROLLERS, AttachmentsController];\n\n/** The controllers to mount: the base five, plus attachments when the host opted into uploads. */\nfunction controllersFor(mountAttachments: boolean): Type<object>[] {\n return mountAttachments ? [...BASE_CONTROLLERS, AttachmentsController] : BASE_CONTROLLERS;\n}\n\n/**\n * `surface: 'engine'` mounts NO controllers — a worker pod never receives HTTP traffic, so its\n * routes (and whatever guards they'd carry) have no business existing there. `'http'`/`'both'`\n * (and the omitted default) mount the same set `controllersFor` always has.\n */\nfunction controllersForSurface(\n surface: AgentSurface | undefined,\n mountAttachments: boolean,\n): Type<object>[] {\n return surface === 'engine' ? [] : controllersFor(mountAttachments);\n}\n\n/**\n * Nest's `GUARDS_METADATA` key (`@nestjs/common/constants`), inlined as a literal: `@nestjs/common`\n * has no `exports` map and its ESM-facing files are CJS, so a deep `import ... from\n * '@nestjs/common/constants'` in our ESM build is emitted extensionless and rejected by Node's\n * strict ESM resolver (surfaced by a consumer's bundler/test runner externalizing this package).\n * `agent-guards.spec.ts` asserts this literal still matches the real constant, so upstream drift\n * fails loudly instead of silently stamping a dead metadata key.\n */\nconst GUARDS_METADATA = '__guards__';\n\n/**\n * Stamp (or clear) `@UseGuards`-equivalent metadata on every controller this module MIGHT mount.\n *\n * Mechanism: `@UseGuards(...guards)` on a controller just does `Reflect.defineMetadata(GUARDS_METADATA,\n * guards, ControllerClass)` (via Nest's `extendArrayMetadata`, which *appends* to any existing array).\n * We call `Reflect.defineMetadata` directly instead, so each `forRoot`/`forRootAsync` call REPLACES\n * the metadata rather than appending to it — appending would leak guards across repeated module\n * registrations in the same process (every test file that calls `forRoot` more than once, say) since\n * these controller classes are module-level singletons shared by every registration. Nest's\n * `GuardsConsumer` reads this metadata per-request via `Reflector`, not once at boot, so the LAST call\n * to stamp it before a request is served wins for that controller class in this process.\n */\nfunction applyGuards(guards: Type<CanActivate>[] | undefined): void {\n const resolved = guards ?? [];\n for (const controller of GUARDABLE_CONTROLLERS) {\n Reflect.defineMetadata(GUARDS_METADATA, resolved, controller);\n }\n}\n\n/** Distinct guard classes for the module's `providers`, so Nest can DI-instantiate them. */\nfunction guardProviders(guards: Type<CanActivate>[] | undefined): Type<CanActivate>[] {\n return [...new Set(guards ?? [])];\n}\n\n/** Mount the controllers under `path` (Nest applies the prefix to their relative routes). */\nfunction routerFor(path: string): DynamicModule {\n return RouterModule.register([{ path, module: AgentModule }]);\n}\n\n/**\n * `dispatchedSteps` routes the turn's model/tool calls through `AgentRunSteps` — a durable-only\n * worker group. It defaults ON under `durable: true` (see `AgentModuleOptions.dispatchedSteps`), but\n * an EXPLICIT `dispatchedSteps: true` without `durable: true` is still a config error: there is no\n * workflow to dispatch from, so it would silently no-op — fail loudly at build time instead.\n */\nfunction assertDispatchedStepsRequiresDurable(dispatchedSteps: boolean, durable: boolean): void {\n if (dispatchedSteps && !durable) {\n throw new Error(\n 'AgentModule dispatchedSteps: true requires durable: true — dispatched steps are routed ' +\n 'durable steps (AgentRunSteps.llm/tool) with no in-process equivalent.',\n );\n }\n}\n\n@Global()\n@Module({})\nexport class AgentModule {\n static forRoot(options: AgentModuleOptions): DynamicModule {\n assertDispatchedStepsRequiresDurable(\n options.dispatchedSteps ?? false,\n options.durable ?? false,\n );\n const path = options.path ?? DEFAULT_PATH;\n // Bind AGENT_STORE locally only when the host passes a store; otherwise defer to a global one.\n const includeStore = options.store !== undefined;\n applyGuards(options.guards);\n return {\n module: AgentModule,\n global: true,\n imports: [DiscoveryModule, routerFor(path)],\n controllers: controllersForSurface(options.surface, options.attachments?.upload === true),\n providers: [\n { provide: AGENT_OPTIONS, useValue: options },\n ...sharedProviders(options.durable ?? false, includeStore),\n ...guardProviders(options.guards),\n ],\n exports: exportsFor(includeStore),\n };\n }\n\n static forRootAsync(options: AgentModuleAsyncOptions): DynamicModule {\n assertDispatchedStepsRequiresDurable(\n options.dispatchedSteps ?? false,\n options.durable ?? false,\n );\n const path = options.path ?? DEFAULT_PATH;\n // The async factory resolves too late to inspect `store`, so `forRootAsync` binds AGENT_STORE\n // locally from the factory result by default. `externalStore: true` opts out — deferring to a\n // globally-imported store module (e.g. `MikroOrmAgentStoreModule.forFeature()`) so the host\n // doesn't have to inject that store just to hand it back as `store`.\n const includeStore = options.externalStore !== true;\n applyGuards(options.guards);\n return {\n module: AgentModule,\n global: true,\n imports: [DiscoveryModule, routerFor(path), ...(options.imports ?? [])],\n controllers: controllersForSurface(options.surface, options.attachmentsUpload === true),\n providers: [\n {\n provide: AGENT_OPTIONS,\n // Stamp the STATIC wiring flags onto the factory result: `durable`/`dispatchedSteps`/\n // `surface` are authoritative on the async config object (they decided the actual wiring\n // above), and `AgentDurableModule` derives the effective dispatched-steps value from\n // AGENT_OPTIONS — without this stamp, an async host would get in-process localSteps\n // despite durable: true. `surface` isn't read back by anything today (AgentDurableModule\n // takes its own mirror option — see its doc for why), but it's stamped here too so the\n // EFFECTIVE value is always observable off AGENT_OPTIONS, sync or async alike.\n useFactory: async (...args: never[]) => ({\n ...(await options.useFactory(...args)),\n durable: options.durable ?? false,\n surface: options.surface ?? 'both',\n ...(options.dispatchedSteps !== undefined\n ? { dispatchedSteps: options.dispatchedSteps }\n : {}),\n }),\n inject: options.inject ?? [],\n },\n ...sharedProviders(options.durable ?? false, includeStore),\n ...guardProviders(options.guards),\n ],\n exports: exportsFor(includeStore),\n };\n }\n}\n","import {\n AGENT_MODEL,\n AGENT_PRICING_STORE,\n AGENT_PROMPT_CONTRIBUTORS,\n AGENT_QUOTA_STORE,\n AGENT_REGISTRY,\n AGENT_ROLES_POLICY,\n AGENT_SINK,\n AGENT_STORE,\n AGENT_TOOL_REGISTRY,\n type AgentDefinition,\n type AgentPricingStore,\n AgentRegistry,\n type AgentStore,\n type ModelProvider,\n type PromptContributor,\n type QuotaStore,\n type RolesPolicy,\n type TokenStreamSink,\n ToolRegistry,\n} from '@dudousxd/nestjs-agent-core';\nimport { AGENT_OPTIONS } from '@dudousxd/nestjs-agent-core';\nimport { Inject, Injectable, Optional } from '@nestjs/common';\nimport type { AgentDeps } from './agent-deps.js';\nimport type { AgentModuleOptions } from './agent.options.js';\n\n/** The synthesized `agent`-kind tool name an orchestrator uses to hand off to `target`. */\nexport function delegateToolName(target: string): string {\n return `ask_${target.replace(/[^a-zA-Z0-9]+/g, '_')}`;\n}\n\n/** Builds the per-agent loop deps. The single-agent case is just the one registered `@Agent`. */\n@Injectable()\nexport class AgentDepsFactory {\n constructor(\n @Inject(AGENT_OPTIONS) private readonly options: AgentModuleOptions,\n @Inject(AGENT_MODEL) private readonly model: ModelProvider,\n @Inject(AGENT_STORE) private readonly store: AgentStore,\n @Inject(AGENT_SINK) private readonly sink: TokenStreamSink,\n @Inject(AGENT_ROLES_POLICY) private readonly rolesPolicy: RolesPolicy,\n @Inject(AGENT_TOOL_REGISTRY) private readonly registry: ToolRegistry,\n @Inject(AGENT_REGISTRY) private readonly agents: AgentRegistry,\n @Inject(AGENT_PROMPT_CONTRIBUTORS) private readonly promptContributors: PromptContributor[],\n @Inject(AGENT_QUOTA_STORE) private readonly quota: QuotaStore | undefined,\n // Optional: AGENT_PRICING_STORE has no local provider in this module (unlike AGENT_QUOTA_STORE,\n // which is always a registered factory) — it's bound externally (e.g. by a store module), so a\n // plain @Inject would throw when nothing binds it.\n @Optional()\n @Inject(AGENT_PRICING_STORE)\n private readonly pricingStore: AgentPricingStore | undefined,\n ) {}\n\n /**\n * The agent a turn uses when the caller names none: the explicit `defaultAgent` option, else the\n * sole registered `@Agent` when there is exactly one, else `'default'` (a bare assistant).\n */\n defaultAgentName(): string {\n if (this.options.defaultAgent !== undefined) {\n return this.options.defaultAgent;\n }\n const registered = this.agents.list();\n return registered.length === 1 ? (registered[0]?.name ?? 'default') : 'default';\n }\n\n private effectiveTools(definition: AgentDefinition | undefined): string[] | undefined {\n if (definition === undefined) {\n return undefined;\n }\n const delegated = (definition.delegatesTo ?? []).map(delegateToolName);\n if (definition.tools === undefined && delegated.length === 0) {\n return undefined; // no restriction\n }\n return [...(definition.tools ?? []), ...delegated];\n }\n\n forAgent(agentName?: string): AgentDeps {\n const name = agentName ?? this.defaultAgentName();\n const definition = this.agents.get(name);\n const toolAllowList = this.effectiveTools(definition);\n const followUpsCount = this.followUpsCount();\n const retrieval = this.options.retrieval;\n return {\n model: this.model,\n store: this.store,\n sink: this.sink,\n rolesPolicy: this.rolesPolicy,\n registry: this.registry,\n promptContributors: this.promptContributors,\n systemPrompt: definition?.systemPrompt ?? 'You are a helpful assistant.',\n maxSteps: definition?.maxSteps ?? 8,\n ...(definition?.modelId !== undefined ? { modelId: definition.modelId } : {}),\n ...(this.quota !== undefined ? { quota: this.quota } : {}),\n ...(this.pricingStore !== undefined ? { pricingStore: this.pricingStore } : {}),\n ...(toolAllowList !== undefined ? { toolAllowList } : {}),\n ...(this.options.toolTimeoutMs !== undefined\n ? { toolTimeoutMs: this.options.toolTimeoutMs }\n : {}),\n ...(this.options.toolTransientRetry !== undefined\n ? { toolTransientRetry: this.options.toolTransientRetry }\n : {}),\n ...(followUpsCount !== undefined ? { followUpsCount } : {}),\n ...(retrieval?.mode === 'inject'\n ? {\n retriever: retrieval.retriever,\n ...(retrieval.topK !== undefined ? { retrievalTopK: retrieval.topK } : {}),\n }\n : {}),\n };\n }\n\n /** Normalize the `followUps` option (`true` → 3, `{ count }` → count) to a number, or undefined. */\n private followUpsCount(): number | undefined {\n const followUps = this.options.followUps;\n if (followUps === true) {\n return 3;\n }\n if (typeof followUps === 'object') {\n return followUps.count;\n }\n return undefined;\n }\n}\n","import {\n AGENT_DEPS_FACTORY,\n AGENT_QUOTA_STORE,\n AGENT_RUNNER,\n AGENT_STORE,\n type Actor,\n type AgentRunInput,\n type AgentRunner,\n type AgentStore,\n type Decision,\n type MessageAttachment,\n type PageContext,\n type QuotaStore,\n type QuotaView,\n type ThreadDetail,\n type ThreadSummary,\n type UpdateThreadInput,\n} from '@dudousxd/nestjs-agent-core';\nimport {\n BadRequestException,\n ForbiddenException,\n Inject,\n Injectable,\n NotFoundException,\n NotImplementedException,\n} from '@nestjs/common';\nimport type { AgentDepsFactory } from './agent-deps.factory.js';\nimport { utcDay } from './agent-deps.js';\n\nexport interface ChatParams {\n actor: Actor;\n message: string;\n threadId?: string;\n agentName?: string;\n /** Files attached to this message (image/PDF) for a vision-capable model. */\n attachments?: MessageAttachment[];\n pageContext?: PageContext;\n /** Re-run the last exchange instead of adding a new message. Requires an existing `threadId`. */\n regenerate?: boolean;\n /**\n * When creating a thread (no `threadId`), start it transient — a scratch conversation hidden from\n * the thread list until the caller promotes it. Ignored when `threadId` is set.\n */\n transient?: boolean;\n}\n\n/** The orchestration facade the controllers call. */\n@Injectable()\nexport class AgentService {\n constructor(\n @Inject(AGENT_RUNNER) private readonly runner: AgentRunner,\n @Inject(AGENT_STORE) private readonly store: AgentStore,\n @Inject(AGENT_DEPS_FACTORY) private readonly deps: AgentDepsFactory,\n @Inject(AGENT_QUOTA_STORE) private readonly quota: QuotaStore | undefined,\n ) {}\n\n async chat(params: ChatParams): Promise<{ runId: string; threadId: string }> {\n // Precedence: explicit agentName > the thread's own defaultAgent (set via updateThread) > the\n // module's configured default. Resolved up front (before thread creation) so a brand-new thread\n // — which has no defaultAgent yet — falls straight through to the module default.\n const agentName = await this.resolveAgentName(params.agentName, params.threadId);\n let threadId = params.threadId;\n if (threadId === undefined) {\n if (params.regenerate === true) {\n throw new BadRequestException('regenerate requires an existing threadId');\n }\n const created = await this.store.createThread({\n actor: params.actor,\n ...(params.transient === true ? { transient: true } : {}),\n });\n threadId = created.id;\n } else if (params.regenerate === true) {\n // Regenerate re-runs a run on an existing thread — gate it by ownership like the other\n // thread-scoped actions so one actor can't rewind another's conversation.\n await this.assertOwnsThread(params.actor, threadId);\n }\n\n const input: AgentRunInput = {\n threadId,\n actor: params.actor,\n userText: params.message,\n day: utcDay(),\n agentName,\n ...(params.regenerate === true ? { regenerate: true } : {}),\n ...(params.attachments !== undefined ? { attachments: params.attachments } : {}),\n ...(params.pageContext !== undefined ? { pageContext: params.pageContext } : {}),\n };\n\n const { runId } = await this.runner.start(input);\n await this.store.setActiveStream(threadId, runId);\n return { runId, threadId };\n }\n\n subscribe(runId: string): AsyncIterable<Uint8Array> {\n return this.deps.forAgent().sink.subscribe(runId);\n }\n\n async approve(actor: Actor, toolCallId: string): Promise<void> {\n await this.assertOwnsToolCall(actor, toolCallId);\n return this.signalToolCall(toolCallId, { approved: true });\n }\n\n async reject(actor: Actor, toolCallId: string, reason?: string): Promise<void> {\n await this.assertOwnsToolCall(actor, toolCallId);\n return this.signalToolCall(toolCallId, {\n approved: false,\n ...(reason !== undefined ? { reason } : {}),\n });\n }\n\n /**\n * The decision core behind approve/reject, WITHOUT an ownership check: resolves the run\n * currently awaiting `toolCallId` and signals it. `approve`/`reject` above call this after their\n * own `assertOwnsToolCall` gate; the console `AgentApprovalPort` adapter (bound by `AgentModule`)\n * calls it directly — a console caller is already authorized by the dashboard's own guards, and\n * re-deriving thread ownership here would reject a legitimate operator decision (an operator is\n * not the thread's own actor).\n */\n async signalToolCall(toolCallId: string, decision: Decision): Promise<void> {\n const runId = await this.resolveRunForToolCall(toolCallId);\n return this.runner.signal(runId, toolCallId, decision);\n }\n\n async cancel(actor: Actor, runId: string): Promise<void> {\n await this.assertOwnsActiveStream(actor, runId);\n return this.runner.cancel(runId);\n }\n\n async listThreads(actorRef: string): Promise<ThreadSummary[]> {\n const threads = await this.store.listThreads(actorRef);\n return Promise.all(threads.map((thread) => this.toSummaryView(thread)));\n }\n\n async getThread(actor: Actor, threadId: string): Promise<ThreadDetail | null> {\n await this.assertOwnsThread(actor, threadId);\n const thread = await this.store.getThread(threadId);\n return thread === null ? null : this.toDetailView(thread);\n }\n\n async deleteThread(actor: Actor, threadId: string): Promise<void> {\n await this.assertOwnsThread(actor, threadId);\n return this.store.softDeleteThread(threadId);\n }\n\n async forkThread(actor: Actor, threadId: string, fromMessageId: string): Promise<ThreadSummary> {\n await this.assertOwnsThread(actor, threadId);\n return this.store.forkThread(threadId, fromMessageId);\n }\n\n /** Kept for source compatibility — a thin wrapper over the more general `updateThread`. */\n async renameThread(actor: Actor, threadId: string, title: string): Promise<void> {\n return this.updateThread(actor, threadId, { title });\n }\n\n /**\n * Rename a thread and/or set its default agent. Title-only patches work against ANY store (via\n * the required `setTitle`); a `defaultAgent` change requires the bound store to implement the\n * optional `updateThread` — 501 with a clear message when it doesn't, rather than silently\n * dropping the field.\n */\n async updateThread(actor: Actor, threadId: string, patch: UpdateThreadInput): Promise<void> {\n const title = patch.title !== undefined ? this.validateTitle(patch.title) : undefined;\n await this.assertOwnsThread(actor, threadId);\n if (patch.defaultAgent === undefined) {\n if (title !== undefined) {\n await this.store.setTitle(threadId, title);\n }\n return;\n }\n if (this.store.updateThread === undefined) {\n throw new NotImplementedException(\n \"Setting a thread's defaultAgent requires an AgentStore that implements updateThread(); \" +\n 'the bound store does not support it.',\n );\n }\n await this.store.updateThread(threadId, {\n ...(title !== undefined ? { title } : {}),\n defaultAgent: patch.defaultAgent,\n });\n }\n\n private validateTitle(title: string): string {\n const trimmed = title.trim();\n if (trimmed.length === 0) {\n throw new BadRequestException('title must not be empty');\n }\n if (trimmed.length > 200) {\n throw new BadRequestException('title must be at most 200 characters');\n }\n return trimmed;\n }\n\n /**\n * Agent-selection precedence for a `chat()` call with no explicit `agentName`: the thread's own\n * `defaultAgent` (if the thread exists and one is set) wins over the module's configured default.\n * Skips the thread lookup entirely when the caller already named an agent or there's no thread yet.\n */\n private async resolveAgentName(\n agentName: string | undefined,\n threadId: string | undefined,\n ): Promise<string> {\n if (agentName !== undefined) {\n return agentName;\n }\n if (threadId !== undefined) {\n const thread = await this.store.getThread(threadId);\n if (thread?.defaultAgent !== undefined && thread.defaultAgent !== null) {\n return thread.defaultAgent;\n }\n }\n return this.deps.defaultAgentName();\n }\n\n private async toSummaryView(thread: ThreadSummary): Promise<ThreadSummary> {\n return {\n ...thread,\n defaultAgent: thread.defaultAgent ?? null,\n activeRunId: (await this.store.activeRunForThread?.(thread.id)) ?? null,\n };\n }\n\n private async toDetailView(thread: ThreadDetail): Promise<ThreadDetail> {\n const summary = await this.toSummaryView(thread);\n return {\n ...summary,\n messages: thread.messages,\n ...(thread.activeStreamId !== undefined ? { activeStreamId: thread.activeStreamId } : {}),\n };\n }\n\n async promoteThread(actor: Actor, threadId: string): Promise<void> {\n await this.assertOwnsThread(actor, threadId);\n return this.store.promoteThread(threadId);\n }\n\n /**\n * Drop a message and everything after it — the \"edit and resend\" / \"delete from here\" primitive.\n * The client then sends a fresh turn on the truncated thread. Ownership-gated like the other\n * thread-scoped mutations.\n */\n async truncateThreadFrom(actor: Actor, threadId: string, messageId: string): Promise<void> {\n await this.assertOwnsThread(actor, threadId);\n return this.store.truncateFrom(threadId, messageId);\n }\n\n /**\n * The day's usage for the badge: tokens + summed USD cost from the store, and the configured\n * limit from the quota store (null → unlimited). `withinLimit` comes from the quota store so it\n * can never drift from what enforcement uses.\n */\n async quotaToday(actorRef: string): Promise<QuotaView> {\n const day = utcDay();\n const { usedTokens, costUsd } = await this.store.quotaToday(actorRef, day);\n if (this.quota === undefined) {\n return { usedTokens, costUsd, limitTokens: null, withinLimit: true };\n }\n const state = await this.quota.check(actorRef, day);\n return {\n usedTokens: state.usedTokens,\n costUsd,\n limitTokens: state.limitTokens,\n withinLimit: state.withinLimit,\n };\n }\n\n /**\n * Authorization seam for thread-scoped endpoints: the caller must own the thread. A missing\n * thread is a 404; someone else's thread is a 403 — one actor never touches another's thread.\n */\n private async assertOwnsThread(actor: Actor, threadId: string): Promise<void> {\n const owner = await this.store.ownerOfThread(threadId);\n if (owner === null) {\n throw new NotFoundException(`thread ${threadId} not found`);\n }\n if (owner !== actor.id) {\n throw new ForbiddenException('thread belongs to another actor');\n }\n }\n\n /**\n * Authorization seam for HITL approve/reject: the caller must own the tool call's thread. Split\n * out from run resolution (see {@link resolveRunForToolCall}) so the console `AgentApprovalPort`\n * adapter can resolve+signal a decision WITHOUT this check — it is authorized upstream instead.\n */\n private async assertOwnsToolCall(actor: Actor, toolCallId: string): Promise<void> {\n const owner = await this.store.ownerOfToolCall(toolCallId);\n if (owner === null) {\n throw new NotFoundException(`tool call ${toolCallId} not found`);\n }\n if (owner !== actor.id) {\n throw new ForbiddenException('tool call belongs to another actor');\n }\n }\n\n /**\n * Resolve the run currently awaiting `toolCallId` (its thread's active stream). That run is the\n * sub-agent's own child run when the pending call belongs to a delegated agent — the client never\n * knows or supplies a runId; it is derived here from the tool call alone.\n */\n private async resolveRunForToolCall(toolCallId: string): Promise<string> {\n const runId = await this.store.runForToolCall(toolCallId);\n if (runId === null) {\n throw new NotFoundException(`tool call ${toolCallId} has no active run to signal`);\n }\n return runId;\n }\n\n /** Authorization seam for `cancel`: the caller must own the thread currently streaming this run. */\n private async assertOwnsActiveStream(actor: Actor, runId: string): Promise<void> {\n const owner = await this.store.ownerOfActiveStream(runId);\n if (owner === null) {\n throw new NotFoundException(`no active run ${runId}`);\n }\n if (owner !== actor.id) {\n throw new ForbiddenException('run belongs to another actor');\n }\n }\n}\n","import type {\n AgentPricingStore,\n AgentStore,\n ModelProvider,\n PromptBuilder,\n PromptContributor,\n QuotaStore,\n Retriever,\n RolesPolicy,\n SinkWriter,\n TokenStreamSink,\n ToolRegistry,\n ToolTransientRetrySetting,\n} from '@dudousxd/nestjs-agent-core';\n\n/** Everything `runAgentLoop` needs, minus the per-run `day` the runner stamps. */\nexport interface AgentDeps {\n model: ModelProvider;\n store: AgentStore;\n registry: ToolRegistry;\n rolesPolicy: RolesPolicy;\n quota?: QuotaStore;\n sink: TokenStreamSink;\n /** Fallback accounting label; the provider's turn result overrides it when set. */\n modelId?: string;\n systemPrompt: string | PromptBuilder;\n /** App-wide `@SystemPromptContributor()` sections appended after the agent's base prompt. */\n promptContributors: PromptContributor[];\n maxSteps: number;\n /** Agent-level tool allow-list. Undefined → all tools (after role filtering). */\n toolAllowList?: string[];\n /** Per-tool execution timeout in ms (from module options). Undefined → no timeout. */\n toolTimeoutMs?: number;\n /**\n * Transient-tool-error retry policy (from module options). Undefined → default ON\n * (`{ attempts: 2, backoffMs: 150 }` with the default classifier); `false` → disabled.\n */\n toolTransientRetry?: ToolTransientRetrySetting;\n /** How many follow-up suggestions to generate after the final turn. Undefined/0 → off. */\n followUpsCount?: number;\n /** Inject-mode retriever (from `forRoot({ retrieval })`). Undefined → no prompt augmentation. */\n retriever?: Retriever;\n /** Passages inject-mode retrieval requests. Undefined → loop default (5). */\n retrievalTopK?: number;\n /** Bound `AGENT_PRICING_STORE`, when a module (e.g. a store's) provides one. Undefined → no pricing. */\n pricingStore?: AgentPricingStore;\n}\n\nexport function utcDay(date = new Date()): string {\n return date.toISOString().slice(0, 10);\n}\n\n/**\n * Wraps a parent run's sink writer for a sub-agent: `write` forwards (so the sub-agent's tokens and\n * pending action-tool frames reach the human's live stream), but `end` / `fail` are swallowed — the\n * top-level run owns the stream's lifecycle, so a finished/failed child must not close or error the\n * shared stream out from under the parent that is still running.\n */\nexport function childSinkWriter(writer: SinkWriter): SinkWriter {\n return {\n write: (chunk) => writer.write(chunk),\n end: async () => {},\n fail: async () => {},\n };\n}\n","import type { AgentApprovalPort } from '@dudousxd/nestjs-agent-core';\nimport { Injectable } from '@nestjs/common';\nimport { AgentService } from './agent.service.js';\n\n/**\n * Binds `AGENT_APPROVAL_PORT` for the console's cross-thread approvals inbox to the SAME decision\n * path chat approvals use — `AgentService.signalToolCall` (resolve the run awaiting `toolCallId`,\n * then `AgentRunner.signal`, which is either the inline pending-promise map or the durable signal\n * `tool:<runId>:<callId>`, depending on how the host configured `AgentModule`).\n *\n * Deliberately WITHOUT `AgentService.approve`/`reject`'s ownership check: a console caller reaches\n * this port only through the dashboard's own guards (already authorized), not as the thread's own\n * actor — re-deriving \"does this actor own the thread\" here would reject a legitimate operator\n * decision. `opts.executedByRef` is an OPAQUE decider ref, not re-authorized against anything: it\n * rides the `Decision` and the loop records it as the tool call's decider\n * (`decision.executedByRef ?? input.actor.id`, on both the executed and rejected paths).\n */\n@Injectable()\nexport class AgentApprovalPortAdapter implements AgentApprovalPort {\n constructor(private readonly agent: AgentService) {}\n\n async approve(toolCallId: string, opts?: { executedByRef?: string }): Promise<void> {\n await this.agent.signalToolCall(toolCallId, {\n approved: true,\n ...(opts?.executedByRef !== undefined ? { executedByRef: opts.executedByRef } : {}),\n });\n }\n\n async reject(\n toolCallId: string,\n opts?: { executedByRef?: string; reason?: string },\n ): Promise<void> {\n await this.agent.signalToolCall(toolCallId, {\n approved: false,\n ...(opts?.executedByRef !== undefined ? { executedByRef: opts.executedByRef } : {}),\n ...(opts?.reason !== undefined ? { reason: opts.reason } : {}),\n });\n }\n}\n","import {\n AGENT_DEPS_FACTORY,\n AGENT_REGISTRY,\n type AgentCatalogEntry,\n AgentRegistry,\n} from '@dudousxd/nestjs-agent-core';\nimport { Controller, Get, Inject } from '@nestjs/common';\nimport type { AgentDepsFactory } from '../agent-deps.factory.js';\n\n/** Lists the registered `@Agent`s so a host can render a persona picker instead of hardcoding one. */\n@Controller('agents')\nexport class AgentsController {\n constructor(\n @Inject(AGENT_REGISTRY) private readonly agents: AgentRegistry,\n @Inject(AGENT_DEPS_FACTORY) private readonly depsFactory: AgentDepsFactory,\n ) {}\n\n @Get()\n list(): AgentCatalogEntry[] {\n const defaultAgentName = this.depsFactory.defaultAgentName();\n return this.agents.list().map((definition) => ({\n name: definition.name,\n description: definition.description ?? '',\n ...(definition.name === defaultAgentName ? { isDefault: true } : {}),\n }));\n }\n}\n","import {\n AGENT_ACTOR_RESOLVER,\n AGENT_ATTACHMENT_STAGING,\n AGENT_OPTIONS,\n type ActorResolver,\n type AttachmentStagingStore,\n type MessageAttachment,\n} from '@dudousxd/nestjs-agent-core';\nimport {\n BadRequestException,\n Controller,\n Inject,\n NotImplementedException,\n type OnModuleInit,\n Optional,\n PayloadTooLargeException,\n Post,\n Req,\n UnsupportedMediaTypeException,\n UploadedFile,\n UseInterceptors,\n} from '@nestjs/common';\nimport { FileInterceptor } from '@nestjs/platform-express';\nimport type { Request } from 'express';\nimport type { AgentModuleOptions } from '../agent.options.js';\n\n/** Default per-file size cap when `AgentModuleOptions.attachments.maxBytes` is omitted (20 MiB). */\nexport const DEFAULT_MAX_ATTACHMENT_BYTES = 20 * 1024 * 1024;\n\n/**\n * Default allowlist: what multimodal model providers commonly accept as native image/file parts.\n */\nexport const DEFAULT_ALLOWED_ATTACHMENT_CONTENT_TYPES: readonly string[] = [\n 'image/png',\n 'image/jpeg',\n 'image/gif',\n 'image/webp',\n 'application/pdf',\n 'text/plain',\n 'text/csv',\n];\n\n/**\n * Optional `POST /agent/attachments` upload surface — mounted only when `AgentModuleOptions\n * .attachments.upload` (or the async config's `attachmentsUpload`) is `true` (see `agent.module.ts`).\n * Multipart single file field `'file'`, buffered in memory (no disk write — `FileInterceptor`'s\n * default storage), validated against the configured size cap + content-type allowlist, then handed\n * to the bound {@link AttachmentStagingStore} to persist and turn into a model-fetchable URL.\n */\n@Controller('attachments')\nexport class AttachmentsController implements OnModuleInit {\n constructor(\n @Inject(AGENT_OPTIONS) private readonly options: AgentModuleOptions,\n @Inject(AGENT_ACTOR_RESOLVER) private readonly actorResolver: ActorResolver,\n @Optional()\n @Inject(AGENT_ATTACHMENT_STAGING)\n private readonly staging: AttachmentStagingStore | undefined,\n ) {}\n\n /**\n * `attachments.upload: true` is what mounts this controller at all (see `agent.module.ts`), so by\n * the time an instance exists the host clearly intends uploads to work. Fail boot loudly rather\n * than mounting a controller that would 501 on every single request because nobody bound\n * `AGENT_ATTACHMENT_STAGING`.\n */\n onModuleInit(): void {\n if (this.options.attachments?.upload === true && this.staging === undefined) {\n throw new Error(\n 'AgentModule: attachments.upload is true but no AGENT_ATTACHMENT_STAGING provider is bound. ' +\n 'Bind one (e.g. `{ provide: AGENT_ATTACHMENT_STAGING, useClass: MyStagingStore }`) in a ' +\n 'module imported alongside AgentModule, or set attachments.upload to false.',\n );\n }\n }\n\n @Post()\n @UseInterceptors(FileInterceptor('file'))\n async upload(\n @Req() req: Request,\n @UploadedFile() file: Express.Multer.File | undefined,\n ): Promise<MessageAttachment> {\n if (this.staging === undefined) {\n // Reachable only if the module was built with attachments.upload left false/omitted while\n // this controller was somehow still wired up by hand — the normal boot path prevents this via\n // onModuleInit above. Kept as defense in depth with a precise status instead of a stack trace.\n throw new NotImplementedException('Attachment upload is not configured on this server.');\n }\n if (file === undefined) {\n throw new BadRequestException('multipart field \"file\" is required');\n }\n const allowedContentTypes =\n this.options.attachments?.allowedContentTypes ?? DEFAULT_ALLOWED_ATTACHMENT_CONTENT_TYPES;\n if (!allowedContentTypes.includes(file.mimetype)) {\n throw new UnsupportedMediaTypeException(\n `content type \"${file.mimetype}\" is not allowed (allowed: ${allowedContentTypes.join(', ')})`,\n );\n }\n const maxBytes = this.options.attachments?.maxBytes ?? DEFAULT_MAX_ATTACHMENT_BYTES;\n if (file.size > maxBytes) {\n throw new PayloadTooLargeException(`file exceeds the ${maxBytes}-byte limit`);\n }\n const actor = await this.actorResolver.resolve(req);\n return this.staging.stage({\n data: file.buffer,\n filename: file.originalname,\n contentType: file.mimetype,\n sizeBytes: file.size,\n actor,\n });\n }\n}\n","import {\n AGENT_ACTOR_RESOLVER,\n type ActorResolver,\n AgentStreamError,\n type MessageAttachment,\n type PageContext,\n} from '@dudousxd/nestjs-agent-core';\nimport { Body, Controller, Get, Inject, Param, Post, Req, Res } from '@nestjs/common';\nimport type { Request, Response } from 'express';\nimport { AgentService } from '../agent.service.js';\n\ninterface ChatBody {\n message: string;\n threadId?: string;\n /** Name of the agent to run (orchestrator or a sub-agent). Defaults to the module's default. */\n agent?: string;\n /** Files attached to this message (image/PDF) for a vision-capable model. */\n attachments?: MessageAttachment[];\n pageContext?: PageContext;\n /** Re-run the last exchange on `threadId` instead of adding a new message. */\n regenerate?: boolean;\n /** Start a new thread transient (hidden from history until promoted). Ignored with `threadId`. */\n transient?: boolean;\n}\n\n@Controller()\nexport class ChatController {\n constructor(\n private readonly agent: AgentService,\n @Inject(AGENT_ACTOR_RESOLVER) private readonly actorResolver: ActorResolver,\n ) {}\n\n @Post('chat')\n async chat(@Req() req: Request, @Res() res: Response, @Body() body: ChatBody): Promise<void> {\n const actor = await this.actorResolver.resolve(req);\n const { runId, threadId } = await this.agent.chat({\n actor,\n message: body.message,\n ...(body.threadId !== undefined ? { threadId: body.threadId } : {}),\n ...(body.agent !== undefined ? { agentName: body.agent } : {}),\n ...(body.attachments !== undefined ? { attachments: body.attachments } : {}),\n ...(body.pageContext !== undefined ? { pageContext: body.pageContext } : {}),\n ...(body.regenerate === true ? { regenerate: true } : {}),\n ...(body.transient === true ? { transient: true } : {}),\n });\n await this.pipe(res, runId, threadId);\n }\n\n @Get('chat/:runId/stream')\n async stream(@Param('runId') runId: string, @Res() res: Response): Promise<void> {\n await this.pipe(res, runId);\n }\n\n @Post('chat/:runId/cancel')\n async cancel(@Req() req: Request, @Param('runId') runId: string): Promise<{ aborted: boolean }> {\n const actor = await this.actorResolver.resolve(req);\n await this.agent.cancel(actor, runId);\n return { aborted: true };\n }\n\n private async pipe(res: Response, runId: string, threadId?: string): Promise<void> {\n res.setHeader('Content-Type', 'text/event-stream');\n res.setHeader('Cache-Control', 'no-cache');\n res.setHeader('Connection', 'keep-alive');\n res.setHeader('X-Agent-Run-Id', runId);\n if (threadId !== undefined) {\n res.setHeader('X-Agent-Thread-Id', threadId);\n }\n res.write(`event: meta\\ndata: ${JSON.stringify({ runId, threadId })}\\n\\n`);\n // The sink now carries NDJSON `AgentStreamEvent`s (one `{...}\\n` per write). Forward each line\n // as an SSE `data:` frame verbatim — the client transport maps them to the AI SDK UI-message\n // chunk protocol. Buffer across chunk boundaries in case a transport batches multiple writes.\n const decoder = new TextDecoder();\n let buffer = '';\n try {\n for await (const chunk of this.agent.subscribe(runId)) {\n buffer += decoder.decode(chunk, { stream: true });\n let newline = buffer.indexOf('\\n');\n while (newline !== -1) {\n const line = buffer.slice(0, newline);\n buffer = buffer.slice(newline + 1);\n if (line.length > 0) {\n res.write(`data: ${line}\\n\\n`);\n }\n newline = buffer.indexOf('\\n');\n }\n }\n if (buffer.length > 0) {\n res.write(`data: ${buffer}\\n\\n`);\n }\n res.write('event: done\\ndata: {}\\n\\n');\n } catch (error) {\n // A run that failed terminates the sink with an AgentStreamError; surface it as a typed\n // error frame so the client can render a failure state instead of parsing it as a token.\n const payload =\n error instanceof AgentStreamError\n ? { code: error.code, message: error.message }\n : {\n code: 'run_failed',\n message: error instanceof Error ? error.message : 'stream error',\n };\n res.write(`event: error\\ndata: ${JSON.stringify(payload)}\\n\\n`);\n }\n res.end();\n }\n}\n","import { AGENT_ACTOR_RESOLVER, type ActorResolver } from '@dudousxd/nestjs-agent-core';\nimport { Controller, Get, Inject, Req } from '@nestjs/common';\nimport type { Request } from 'express';\nimport { AgentService } from '../agent.service.js';\n\n@Controller('quota')\nexport class QuotaController {\n constructor(\n private readonly agent: AgentService,\n @Inject(AGENT_ACTOR_RESOLVER) private readonly actorResolver: ActorResolver,\n ) {}\n\n @Get('today')\n async today(@Req() req: Request) {\n const actor = await this.actorResolver.resolve(req);\n return this.agent.quotaToday(actor.id);\n }\n}\n","import { AGENT_ACTOR_RESOLVER, type ActorResolver } from '@dudousxd/nestjs-agent-core';\nimport { Body, Controller, Delete, Get, Inject, Param, Patch, Post, Req } from '@nestjs/common';\nimport type { Request } from 'express';\nimport { AgentService } from '../agent.service.js';\n\ninterface UpdateThreadBody {\n title?: string;\n /** `null` clears the thread's default agent. Omitted → left untouched. */\n defaultAgent?: string | null;\n}\n\n@Controller('threads')\nexport class ThreadsController {\n constructor(\n private readonly agent: AgentService,\n @Inject(AGENT_ACTOR_RESOLVER) private readonly actorResolver: ActorResolver,\n ) {}\n\n @Get()\n async list(@Req() req: Request) {\n const actor = await this.actorResolver.resolve(req);\n return this.agent.listThreads(actor.id);\n }\n\n @Get(':id')\n async detail(@Req() req: Request, @Param('id') id: string) {\n const actor = await this.actorResolver.resolve(req);\n return this.agent.getThread(actor, id);\n }\n\n @Delete(':id')\n async remove(@Req() req: Request, @Param('id') id: string): Promise<{ ok: boolean }> {\n const actor = await this.actorResolver.resolve(req);\n await this.agent.deleteThread(actor, id);\n return { ok: true };\n }\n\n @Post(':id/fork-from/:messageId')\n async fork(@Req() req: Request, @Param('id') id: string, @Param('messageId') messageId: string) {\n const actor = await this.actorResolver.resolve(req);\n return this.agent.forkThread(actor, id, messageId);\n }\n\n /**\n * Renames the thread and/or sets its default agent. `defaultAgent` is only present in the request\n * body when the client actually sent the key (JSON has no `undefined`), so `'defaultAgent' in body`\n * distinguishes \"leave it alone\" from \"set it to null\" (clear it) unambiguously.\n */\n @Patch(':id')\n async update(\n @Req() req: Request,\n @Param('id') id: string,\n @Body() body: UpdateThreadBody,\n ): Promise<{ ok: boolean }> {\n const actor = await this.actorResolver.resolve(req);\n await this.agent.updateThread(actor, id, {\n ...(body.title !== undefined ? { title: body.title } : {}),\n ...('defaultAgent' in body ? { defaultAgent: body.defaultAgent ?? null } : {}),\n });\n return { ok: true };\n }\n\n @Post(':id/promote')\n async promote(@Req() req: Request, @Param('id') id: string): Promise<{ ok: boolean }> {\n const actor = await this.actorResolver.resolve(req);\n await this.agent.promoteThread(actor, id);\n return { ok: true };\n }\n\n @Delete(':id/from/:messageId')\n async truncateFrom(\n @Req() req: Request,\n @Param('id') id: string,\n @Param('messageId') messageId: string,\n ): Promise<{ ok: boolean }> {\n const actor = await this.actorResolver.resolve(req);\n await this.agent.truncateThreadFrom(actor, id, messageId);\n return { ok: true };\n }\n}\n","import { AGENT_ACTOR_RESOLVER, type ActorResolver } from '@dudousxd/nestjs-agent-core';\nimport { Body, Controller, Inject, Post, Req } from '@nestjs/common';\nimport type { Request } from 'express';\nimport { AgentService } from '../agent.service.js';\n\ninterface ApproveBody {\n toolCallId: string;\n}\ninterface RejectBody extends ApproveBody {\n reason?: string;\n}\n\n@Controller('tool-call')\nexport class ToolCallController {\n constructor(\n private readonly agent: AgentService,\n @Inject(AGENT_ACTOR_RESOLVER) private readonly actorResolver: ActorResolver,\n ) {}\n\n @Post('approve')\n async approve(@Req() req: Request, @Body() body: ApproveBody): Promise<{ ok: boolean }> {\n const actor = await this.actorResolver.resolve(req);\n await this.agent.approve(actor, body.toolCallId);\n return { ok: true };\n }\n\n @Post('reject')\n async reject(@Req() req: Request, @Body() body: RejectBody): Promise<{ ok: boolean }> {\n const actor = await this.actorResolver.resolve(req);\n await this.agent.reject(actor, body.toolCallId, body.reason);\n return { ok: true };\n }\n}\n","import {\n AGENT_PROMPT_CONTRIBUTORS,\n AGENT_REGISTRY,\n type AgentDefinition,\n AgentRegistry,\n type PromptBuilder,\n type PromptContext,\n type PromptContributor,\n} from '@dudousxd/nestjs-agent-core';\nimport { Inject, Injectable, Logger, type OnModuleInit } from '@nestjs/common';\nimport { DiscoveryService, MetadataScanner } from '@nestjs/core';\nimport { type AgentOptions, readAgentMetadata } from '../decorator/agent.decorator.js';\nimport {\n SYSTEM_PROMPT_CONTRIBUTOR_METADATA,\n SYSTEM_PROMPT_METADATA,\n} from '../decorator/system-prompt.decorator.js';\n\n/**\n * Populates the {@link AgentRegistry} from `@Agent`-decorated providers and collects every\n * `@SystemPromptContributor()` method into the app-wide contributor list — the discovery counterpart\n * to authoring agents as config objects. Runs on `onModuleInit`, so agents/contributors are in place\n * before `AiToolDiscoveryService` (which synthesizes handoff tools) runs its `onApplicationBootstrap`.\n */\n@Injectable()\nexport class AgentDiscoveryService implements OnModuleInit {\n private readonly logger = new Logger(AgentDiscoveryService.name);\n\n constructor(\n private readonly discovery: DiscoveryService,\n private readonly scanner: MetadataScanner,\n @Inject(AGENT_REGISTRY) private readonly registry: AgentRegistry,\n @Inject(AGENT_PROMPT_CONTRIBUTORS) private readonly contributors: PromptContributor[],\n ) {}\n\n onModuleInit(): void {\n for (const wrapper of this.discovery.getProviders()) {\n const instance = wrapper.instance;\n if (instance === null || typeof instance !== 'object') {\n continue;\n }\n const meta = readAgentMetadata(instance.constructor);\n if (meta !== undefined) {\n this.registry.register(this.definitionFrom(instance, meta));\n }\n this.collectContributors(instance);\n }\n }\n\n /** Build the internal {@link AgentDefinition} from an `@Agent` instance and its options. */\n private definitionFrom(instance: object, meta: AgentOptions): AgentDefinition {\n const promptMethod = this.methodWith(instance, SYSTEM_PROMPT_METADATA);\n const systemPrompt: string | PromptBuilder =\n promptMethod !== undefined\n ? (ctx: PromptContext) => promptMethod(ctx) as string | Promise<string>\n : (meta.systemPrompt ?? 'You are a helpful assistant.');\n return {\n name: meta.name,\n ...(meta.description !== undefined ? { description: meta.description } : {}),\n systemPrompt,\n ...(meta.tools !== undefined ? { tools: meta.tools } : {}),\n ...(meta.model !== undefined ? { modelId: meta.model } : {}),\n ...(meta.maxSteps !== undefined ? { maxSteps: meta.maxSteps } : {}),\n ...(meta.handoff !== undefined ? { delegatesTo: this.handoffNames(meta) } : {}),\n };\n }\n\n /** Resolve each handoff `@Agent` class to its registered name (skipping non-agent classes). */\n private handoffNames(meta: AgentOptions): string[] {\n const names: string[] = [];\n for (const target of meta.handoff ?? []) {\n const targetMeta = readAgentMetadata(target);\n if (targetMeta === undefined) {\n this.logger.warn(\n `Agent \"${meta.name}\" hands off to ${target.name}, which is not an @Agent — skipped.`,\n );\n continue;\n }\n names.push(targetMeta.name);\n }\n return names;\n }\n\n /** Push every `@SystemPromptContributor()` method on `instance` (bound) into the contributor list. */\n private collectContributors(instance: object): void {\n const prototype = Object.getPrototypeOf(instance) as object;\n for (const name of this.scanner.getAllMethodNames(prototype)) {\n if (Reflect.getMetadata(SYSTEM_PROMPT_CONTRIBUTOR_METADATA, prototype, name) === true) {\n const method = this.boundMethod(instance, name);\n if (method !== undefined) {\n this.contributors.push(\n (ctx: PromptContext) => method(ctx) as ReturnType<PromptContributor>,\n );\n }\n }\n }\n }\n\n /** The single method on `instance` carrying `metadataKey`, bound to the instance, or undefined. */\n private methodWith(\n instance: object,\n metadataKey: symbol,\n ): ((ctx: PromptContext) => unknown) | undefined {\n const prototype = Object.getPrototypeOf(instance) as object;\n for (const name of this.scanner.getAllMethodNames(prototype)) {\n if (Reflect.getMetadata(metadataKey, prototype, name) === true) {\n return this.boundMethod(instance, name);\n }\n }\n return undefined;\n }\n\n /** Bind a named method to its instance, guarding that it is actually a function. */\n private boundMethod(\n instance: object,\n name: string,\n ): ((ctx: PromptContext) => unknown) | undefined {\n const candidate = (instance as Record<string, unknown>)[name];\n if (typeof candidate !== 'function') {\n return undefined;\n }\n return (ctx: PromptContext) =>\n (candidate as (ctx: PromptContext) => unknown).call(instance, ctx);\n }\n}\n","import 'reflect-metadata';\nimport type { Type } from '@nestjs/common';\n\n/**\n * Declares a class as an agent. The class is discovered at boot (via `DiscoveryService`) and\n * registered into the `AgentRegistry` — its name, base prompt, tool allow-list, and handoff targets\n * become an internal `AgentDefinition` the loop consumes. The class is an ordinary provider, so it\n * gets constructor DI (its retriever, schema service, policy) — the reason an agent is a class and\n * not a config object.\n *\n * The base prompt is either the `systemPrompt` string here or, for a dynamic prompt, a\n * `@SystemPrompt()` method on the class (which may inject services and read the turn's\n * `PromptContext`). Tools are the global `@AiTool` providers named in `tools` (omit → all tools the\n * actor's role allows); handoff targets are other `@Agent` classes.\n */\nexport interface AgentOptions {\n /** Unique agent name — how a turn selects it and how a message records its provenance. */\n name: string;\n /** Human-readable summary (shown to an orchestrator that may hand off to this agent). */\n description?: string;\n /** A flat base prompt. For a dynamic prompt, add a `@SystemPrompt()` method instead. */\n systemPrompt?: string;\n /** Accounting label for the model this agent uses (the model provider itself is shared). */\n model?: string;\n /** Max model→tool iterations for this agent's turn. Default 8. */\n maxSteps?: number;\n /** Allow-list of global tool names this agent may use. Omit → every tool its role allows. */\n tools?: string[];\n /** Other `@Agent` classes this agent may hand off to (auto-exposed as handoff tools). */\n handoff?: Type[];\n}\n\nexport const AGENT_METADATA = Symbol.for('@dudousxd/nestjs-agent:agent-metadata');\n\n/** Marks a provider class as an agent. See {@link AgentOptions}. */\nexport function Agent(options: AgentOptions): ClassDecorator {\n return (target) => {\n Reflect.defineMetadata(AGENT_METADATA, options, target);\n };\n}\n\n/**\n * Reads {@link AgentOptions} off a class (its constructor), or `undefined` if not an `@Agent`. The\n * reflection target is a class or Nest's provider `metatype`, whose type is precisely `Type |\n * Function`; narrowing it away from `Function` would reject valid callers.\n */\n// biome-ignore lint/complexity/noBannedTypes: the reflection target's type is precisely `Type | Function`.\nexport function readAgentMetadata(target: Type | Function): AgentOptions | undefined {\n return Reflect.getMetadata(AGENT_METADATA, target) as AgentOptions | undefined;\n}\n","import 'reflect-metadata';\n\n/**\n * Marks the method on an `@Agent` class that builds the agent's base system prompt. The method\n * receives the turn's `PromptContext` and returns a string (optionally async); because it lives on a\n * provider, it can inject services (e.g. describe a schema, read the actor). Exactly one per agent —\n * it takes precedence over the `@Agent({ systemPrompt })` string.\n */\nexport const SYSTEM_PROMPT_METADATA = Symbol.for('@dudousxd/nestjs-agent:system-prompt');\n\n/**\n * Marks a method on any provider as a cross-agent system-prompt contributor: it returns an ordered\n * section appended to the composed prompt (after the selected agent's base), or `null` to contribute\n * nothing this turn. This is the seam an app uses to inject domain sections (base scope, a mentions\n * legend, schema hints) across every agent without forking the loop.\n */\nexport const SYSTEM_PROMPT_CONTRIBUTOR_METADATA = Symbol.for(\n '@dudousxd/nestjs-agent:system-prompt-contributor',\n);\n\n/** Marks an `@Agent` method as the agent's dynamic base prompt. See {@link SYSTEM_PROMPT_METADATA}. */\nexport function SystemPrompt(): MethodDecorator {\n return (target, key) => {\n Reflect.defineMetadata(SYSTEM_PROMPT_METADATA, true, target, key);\n };\n}\n\n/** Marks a provider method as a cross-agent prompt contributor. See {@link SYSTEM_PROMPT_CONTRIBUTOR_METADATA}. */\nexport function SystemPromptContributor(): MethodDecorator {\n return (target, key) => {\n Reflect.defineMetadata(SYSTEM_PROMPT_CONTRIBUTOR_METADATA, true, target, key);\n };\n}\n","import {\n AGENT_OPTIONS,\n AGENT_REGISTRY,\n AGENT_TOOL_REGISTRY,\n type AgentRegistry,\n type ToolHandler,\n type ToolRegistry,\n} from '@dudousxd/nestjs-agent-core';\nimport { Inject, Injectable, Logger, type OnApplicationBootstrap } from '@nestjs/common';\nimport { DiscoveryService } from '@nestjs/core';\nimport { z } from 'zod';\nimport { delegateToolName } from '../agent-deps.factory.js';\nimport type { AgentModuleOptions } from '../agent.options.js';\nimport { readAiToolMetadata } from '../decorator/ai-tool.decorator.js';\nimport { type FunctionalTool, isBrandedFunctionalTool } from '../functional-tool.js';\n\n/** Walks every provider at boot and registers `@AiTool` classes into the shared registry. */\n@Injectable()\nexport class AiToolDiscoveryService implements OnApplicationBootstrap {\n private readonly logger = new Logger(AiToolDiscoveryService.name);\n\n constructor(\n private readonly discovery: DiscoveryService,\n @Inject(AGENT_TOOL_REGISTRY) private readonly registry: ToolRegistry,\n @Inject(AGENT_REGISTRY) private readonly agents: AgentRegistry,\n @Inject(AGENT_OPTIONS) private readonly options: AgentModuleOptions,\n ) {}\n\n onApplicationBootstrap(): void {\n let count = 0;\n let functional = 0;\n for (const wrapper of this.discovery.getProviders()) {\n const instance = wrapper.instance;\n if (instance === null || instance === undefined || typeof instance !== 'object') {\n continue;\n }\n // Functional tools registered via `provideAgentTool` resolve to a branded { spec, handler }.\n if (isBrandedFunctionalTool(instance)) {\n if (this.registerFunctionalTool(instance)) {\n functional += 1;\n }\n continue;\n }\n const meta = readAiToolMetadata(instance);\n if (meta === undefined) {\n continue;\n }\n const handler = instance as Partial<ToolHandler>;\n if (typeof handler.execute !== 'function') {\n this.logger.warn(`@AiTool \"${meta.name}\" has no execute() method — skipped`);\n continue;\n }\n this.registry.register(\n {\n name: meta.name,\n kind: meta.kind,\n description: meta.description,\n inputSchema: meta.input,\n // Leave roles unset when the tool didn't declare any — the RolesPolicy owns the default\n // (its `defaultRoles`). Baking it in here too would leak it into custom policies.\n ...(meta.roles !== undefined ? { roles: meta.roles } : {}),\n ...(meta.ability !== undefined ? { ability: meta.ability } : {}),\n },\n { execute: (input, ctx) => (instance as ToolHandler).execute(input, ctx) },\n );\n count += 1;\n }\n\n // Static functional tools passed straight to `forRoot({ tools })`.\n for (const tool of this.options.tools ?? []) {\n if (this.registerFunctionalTool(tool)) {\n functional += 1;\n }\n }\n\n // Synthesize an `agent`-kind delegate tool for each agent->agent edge declared via `delegatesTo`.\n let delegates = 0;\n for (const definition of this.agents.list()) {\n for (const target of definition.delegatesTo ?? []) {\n const targetDefinition = this.agents.get(target);\n // A dangling handoff target (a `@Agent({ handoff })` class that isn't itself an `@Agent`)\n // would otherwise synthesize a delegate to a phantom agent that resolves to an UNRESTRICTED\n // default agent at runtime — a privilege-escalation footgun. Fail the boot instead.\n if (targetDefinition === undefined) {\n throw new Error(\n `Agent \"${definition.name}\" hands off to \"${target}\", which is not a registered @Agent. Declare it as an @Agent provider or fix the reference.`,\n );\n }\n const name = delegateToolName(target);\n if (this.registry.has(name)) {\n continue;\n }\n // Only a flat string prompt is worth surfacing in the tool description; a PromptBuilder is\n // per-request and would stringify to source, so skip it.\n const targetBlurb =\n typeof targetDefinition.systemPrompt === 'string'\n ? ` It is: ${targetDefinition.systemPrompt}`\n : '';\n this.registry.register(\n {\n name,\n kind: 'agent',\n targetAgent: target,\n description: `Delegate a task to the \"${target}\" agent and get its answer.${targetBlurb}`,\n inputSchema: z.object({ task: z.string() }),\n },\n // Loop-handled (kind 'agent'); the handler is never called.\n { execute: async () => ({}) },\n );\n delegates += 1;\n }\n }\n this.logger.log(\n `registered ${count} AI tool(s), ${functional} functional tool(s) and ${delegates} delegate tool(s)`,\n );\n }\n\n /**\n * Registers a functional tool's `{ spec, handler }`, skipping it if a tool of the same name is\n * already registered. Returns whether it was newly registered.\n */\n private registerFunctionalTool(tool: FunctionalTool): boolean {\n if (this.registry.has(tool.spec.name)) {\n this.logger.warn(\n `functional tool \"${tool.spec.name}\" duplicates a registered name — skipped`,\n );\n return false;\n }\n this.registry.register(tool.spec, tool.handler);\n return true;\n }\n}\n","import 'reflect-metadata';\nimport type { StandardSchemaV1 } from '@standard-schema/spec';\n\nexport const AI_TOOL_METADATA = Symbol('nestjs-agent:ai-tool');\n\nexport interface AiToolOptions {\n name: string;\n /**\n * `read` auto-executes; `action` requires HITL approval. (Core's `ToolKind` also has `agent`\n * for delegation, but that kind is synthesized from `delegatesTo` — never authored here.)\n */\n kind: 'read' | 'action';\n description: string;\n /**\n * Input schema as a [Standard Schema](https://standardschema.dev) — Zod, Valibot, or ArkType.\n * Validated before the handler runs.\n */\n input: StandardSchemaV1;\n /** Roles allowed to invoke. Omit to inherit the module's default roles. */\n roles?: string[];\n /**\n * Authz ability checked by an ability-aware RolesPolicy (e.g. `AgentAuthzModule`'s\n * `AuthzRolesPolicy` → `gate.forUser(actor).allows(ability)`). Ignored by the default\n * role-based policy, which uses `roles`.\n */\n ability?: string;\n}\n\n/**\n * Marks a provider class as an AI tool. The class must implement `execute(input, ctx)`.\n * `AiToolDiscoveryService` registers every `@AiTool` provider into the `ToolRegistry` at boot.\n *\n * ```ts\n * @AiTool({ name: 'getWeather', kind: 'read', description: '...', input: z.object({ city: z.string() }) })\n * class GetWeatherTool implements ToolHandler<{ city: string }> {\n * async execute(input, ctx) { return { tempC: 21 }; }\n * }\n * ```\n */\nexport function AiTool(options: AiToolOptions): ClassDecorator {\n return (target) => {\n Reflect.defineMetadata(AI_TOOL_METADATA, options, target);\n };\n}\n\nexport function readAiToolMetadata(target: object): AiToolOptions | undefined {\n return Reflect.getMetadata(AI_TOOL_METADATA, target.constructor) as AiToolOptions | undefined;\n}\n","import type { ToolHandler, ToolSpec } 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","import {\n AgentStreamError,\n type SinkWriter,\n type StreamError,\n type TokenStreamSink,\n} from '@dudousxd/nestjs-agent-core';\n\ninterface RunBuffer {\n chunks: Uint8Array[];\n ended: boolean;\n failure?: StreamError;\n notify: Set<() => void>;\n}\n\n/**\n * The default `TokenStreamSink`: buffers chunks per run in-process so a reconnecting subscriber\n * replays everything so far, then follows live.\n *\n * Single-replica only. Because the buffer lives in one process's memory, a resume/reconnect that\n * lands on a different replica than the one running the turn finds an empty buffer — the stream\n * appears stalled. For multi-replica deployments, supply a shared-transport `TokenStreamSink`\n * (e.g. Redis pub/sub keyed by runId) via `AgentModule.forRoot({ sink })`.\n */\nexport class InProcessTokenStreamSink implements TokenStreamSink {\n private readonly runs = new Map<string, RunBuffer>();\n\n private buffer(runId: string): RunBuffer {\n let buf = this.runs.get(runId);\n if (buf === undefined) {\n buf = { chunks: [], ended: false, notify: new Set() };\n this.runs.set(runId, buf);\n }\n return buf;\n }\n\n private wake(buf: RunBuffer): void {\n for (const resolve of buf.notify) {\n resolve();\n }\n buf.notify.clear();\n }\n\n open(runId: string): SinkWriter {\n const buf = this.buffer(runId);\n return {\n write: (chunk: Uint8Array) => {\n buf.chunks.push(chunk);\n this.wake(buf);\n },\n end: () => {\n buf.ended = true;\n this.wake(buf);\n },\n fail: (error: StreamError) => {\n buf.failure = error;\n buf.ended = true;\n this.wake(buf);\n },\n };\n }\n\n async *subscribe(runId: string): AsyncIterable<Uint8Array> {\n const buf = this.buffer(runId);\n let index = 0;\n while (true) {\n while (index < buf.chunks.length) {\n const chunk = buf.chunks[index];\n index += 1;\n if (chunk !== undefined) {\n yield chunk;\n }\n }\n if (buf.ended) {\n // Drain buffered chunks first, then raise the failure as a typed terminal.\n if (buf.failure !== undefined) {\n throw new AgentStreamError(buf.failure);\n }\n return;\n }\n await new Promise<void>((resolve) => buf.notify.add(resolve));\n }\n }\n\n close(runId: string): void {\n this.runs.delete(runId);\n }\n}\n","import type { AgentStore, QuotaState, QuotaStore } from '@dudousxd/nestjs-agent-core';\n\n/**\n * A production {@link QuotaStore} backed by the persisted usage ledger. `check` reads the actor's\n * tokens-so-far for the day straight from {@link AgentStore.quotaToday} and compares it to a fixed\n * daily limit; `bump` is a deliberate no-op because the loop's `recordUsage` already writes every\n * turn's tokens to that same ledger. One source of truth — so enforcement and what the dashboard\n * reports can never drift, and it works across replicas with no extra shared state.\n */\nexport class LedgerQuotaStore implements QuotaStore {\n constructor(\n private readonly store: AgentStore,\n private readonly limitTokens: number,\n ) {}\n\n async check(actorRef: string, day: string): Promise<QuotaState> {\n const { usedTokens } = await this.store.quotaToday(actorRef, day);\n return {\n usedTokens,\n limitTokens: this.limitTokens,\n withinLimit: usedTokens < this.limitTokens,\n };\n }\n\n async bump(): Promise<void> {\n // No-op: the ledger is the source of truth — recordUsage already persisted this turn's tokens.\n }\n}\n","import {\n AGENT_DEPS_FACTORY,\n AGENT_STORE,\n type Actor,\n type AgentLoopHooks,\n type AgentRunInput,\n type AgentRunner,\n type AgentStore,\n type Decision,\n QuotaExceededError,\n publishAgentRunFailed,\n runAgentLoop,\n} from '@dudousxd/nestjs-agent-core';\nimport { Inject, Injectable, Logger } from '@nestjs/common';\nimport type { AgentDepsFactory } from '../agent-deps.factory.js';\nimport { type AgentDeps, childSinkWriter, utcDay } from '../agent-deps.js';\n\n/**\n * Runs the agent turn in-process. HITL approval resolves a pending promise keyed by\n * `runId:toolCallId`. Sub-agent delegation runs a nested loop that streams into the top-level run's\n * sink (so a human sees it) and shares the same approval mechanism — a sub-agent's action tools go\n * through the same human gate, keyed by the sub-agent's own runId. Single-replica only (the pending\n * map is in-process); durable is the scaled path.\n */\n@Injectable()\nexport class InlineAgentRunner implements AgentRunner {\n private readonly logger = new Logger(InlineAgentRunner.name);\n private readonly pending = new Map<string, (decision: Decision) => void>();\n\n constructor(\n @Inject(AGENT_DEPS_FACTORY) private readonly factory: AgentDepsFactory,\n @Inject(AGENT_STORE) private readonly store: AgentStore,\n ) {}\n\n async start(input: AgentRunInput): Promise<{ runId: string }> {\n const runId = crypto.randomUUID();\n const day = input.day ?? utcDay();\n const deps = this.factory.forAgent(input.agentName);\n const hooks = this.topLevelHooks(runId, deps, input.actor, day);\n\n void runAgentLoop({ ...deps, day }, input, hooks)\n .then(() => this.store.setActiveStream(input.threadId, null))\n .catch(async (error) => {\n const message = error instanceof Error ? error.message : String(error);\n const code = error instanceof QuotaExceededError ? 'quota_exceeded' : 'run_failed';\n this.logger.error(`agent run ${runId} failed (${code}): ${message}`);\n publishAgentRunFailed({ runId, code, message });\n // Settle the run's persisted outcome (the loop only records completions — it can't catch\n // its own crash). Optional-call: a store without run recording skips reliability metrics.\n await this.store.recordRunEnd?.({\n runId,\n status: 'failed',\n errorCode: code,\n errorMessage: message,\n });\n // Clear the thread's active run — a failed run isn't \"still running\" for `activeRunForThread`.\n await this.store.setActiveStream(input.threadId, null);\n // Terminate the live stream with a typed failure so the transport emits an error frame\n // instead of leaking the message as assistant text.\n const writer = await deps.sink.open(runId);\n await writer.fail({ code, message });\n });\n\n return { runId };\n }\n\n async signal(runId: string, toolCallId: string, decision: Decision): Promise<void> {\n const key = `${runId}:${toolCallId}`;\n const resolve = this.pending.get(key);\n if (resolve !== undefined) {\n this.pending.delete(key);\n resolve(decision);\n }\n }\n\n async cancel(runId: string): Promise<void> {\n const deps = this.factory.forAgent();\n const writer = await deps.sink.open(runId);\n await writer.end();\n }\n\n private topLevelHooks(runId: string, deps: AgentDeps, actor: Actor, day: string): AgentLoopHooks {\n return {\n runId,\n openSink: () => deps.sink.open(runId),\n awaitApproval: (call) =>\n new Promise<Decision>((resolve) => {\n this.pending.set(`${runId}:${call.id}`, resolve);\n }),\n step: (_name, fn) => fn(),\n runAgent: (agentName, task) => this.runNested(agentName, task, actor, day, 1, runId),\n };\n }\n\n /**\n * Delegate to another agent as a nested in-process run. The sub-agent streams into `sinkRunId`\n * (the top-level run the human is watching) so its output and any pending action tool are visible,\n * and its own approvals resolve through the shared pending map keyed by its own runId.\n */\n private async runNested(\n agentName: string,\n task: string,\n actor: Actor,\n day: string,\n depth: number,\n sinkRunId: string,\n ): Promise<{ text: string }> {\n const subThread = await this.store.createThread({ actor, transient: true });\n const runId = crypto.randomUUID();\n // Mark the subthread as streaming THIS sub-run so a human approval routes back here\n // (runForToolCall → subthread.activeStreamId → this runId).\n await this.store.setActiveStream(subThread.id, runId);\n const deps = this.factory.forAgent(agentName);\n const hooks: AgentLoopHooks = {\n runId,\n // Forward into the top-level stream; the top-level run owns end/fail on that shared sink.\n openSink: async () => childSinkWriter(await deps.sink.open(sinkRunId)),\n awaitApproval: (call) =>\n new Promise<Decision>((resolve) => {\n this.pending.set(`${runId}:${call.id}`, resolve);\n }),\n step: (_name, fn) => fn(),\n runAgent: (childName, childTask) =>\n this.runNested(childName, childTask, actor, day, depth + 1, sinkRunId),\n };\n try {\n return await runAgentLoop(\n { ...deps, day },\n {\n threadId: subThread.id,\n actor,\n userText: task,\n agentName,\n day,\n delegationDepth: depth,\n sinkRunId,\n },\n hooks,\n );\n } finally {\n // No durable-style suspend to worry about here (inline runs to completion synchronously from\n // this call's point of view) — always clear so `activeRunForThread` reflects reality.\n await this.store.setActiveStream(subThread.id, null);\n }\n }\n}\n","import type { Actor, ActorResolver } from '@dudousxd/nestjs-agent-core';\n\n/** Read a string header off an unknown transport request, narrowing without trusting its shape. */\nfunction readHeader(req: unknown, name: string): string | undefined {\n if (typeof req !== 'object' || req === null || !('headers' in req)) return undefined;\n const { headers } = req;\n if (typeof headers !== 'object' || headers === null || !(name in headers)) return undefined;\n const value: unknown = Reflect.get(headers, name);\n return typeof value === 'string' ? value : undefined;\n}\n\n/**\n * A development / gateway {@link ActorResolver} that trusts request headers:\n * `x-actor-id` (required), `x-actor-role` (comma-separated → `roles`), `x-tenant-ref`.\n *\n * **Security:** it throws when `x-actor-id` is absent — it never fabricates an identity\n * and never grants a default role (an actor with no `x-actor-role` gets `roles: []`, i.e.\n * no tools). Trusting client headers is only safe behind a gateway that strips and re-sets\n * them from an authenticated principal. Real deployments should provide their own resolver\n * that reads a verified session/JWT instead of installing this one.\n */\nexport class HeaderActorResolver implements ActorResolver {\n resolve(req: unknown): Actor {\n const id = readHeader(req, 'x-actor-id');\n if (id === undefined || id.length === 0) {\n throw new Error(\n 'HeaderActorResolver: missing x-actor-id header. No default actor is fabricated. ' +\n 'Send x-actor-id from a trusted gateway, or configure ' +\n 'AgentModule.forRoot({ actorResolver }) with a resolver that reads your ' +\n 'authenticated principal.',\n );\n }\n const roles = (readHeader(req, 'x-actor-role') ?? '')\n .split(',')\n .map((role) => role.trim())\n .filter((role) => role.length > 0);\n const tenantRef = readHeader(req, 'x-tenant-ref');\n return {\n id,\n roles,\n ...(tenantRef !== undefined ? { tenantRef } : {}),\n };\n }\n}\n"],"mappings":"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","names":["AgentDepsFactory","import_nestjs_agent_core","import_common","import_core","import_nestjs_agent_core","delegateToolName","target","replace","AgentDepsFactory","options","model","store","sink","rolesPolicy","registry","agents","promptContributors","quota","pricingStore","defaultAgentName","defaultAgent","undefined","registered","list","length","name","effectiveTools","definition","delegated","delegatesTo","map","tools","forAgent","agentName","get","toolAllowList","followUpsCount","retrieval","systemPrompt","maxSteps","modelId","toolTimeoutMs","toolTransientRetry","mode","retriever","topK","retrievalTopK","followUps","count","import_nestjs_agent_core","import_common","utcDay","date","Date","toISOString","slice","childSinkWriter","writer","write","chunk","end","fail","AgentService","runner","store","deps","quota","chat","params","agentName","resolveAgentName","threadId","undefined","regenerate","BadRequestException","created","createThread","actor","transient","id","assertOwnsThread","input","userText","message","day","utcDay","attachments","pageContext","runId","start","setActiveStream","subscribe","forAgent","sink","approve","toolCallId","assertOwnsToolCall","signalToolCall","approved","reject","reason","decision","resolveRunForToolCall","signal","cancel","assertOwnsActiveStream","listThreads","actorRef","threads","Promise","all","map","thread","toSummaryView","getThread","toDetailView","deleteThread","softDeleteThread","forkThread","fromMessageId","renameThread","title","updateThread","patch","validateTitle","defaultAgent","setTitle","NotImplementedException","trimmed","trim","length","defaultAgentName","activeRunId","activeRunForThread","summary","messages","activeStreamId","promoteThread","truncateThreadFrom","messageId","truncateFrom","quotaToday","usedTokens","costUsd","limitTokens","withinLimit","state","check","owner","ownerOfThread","NotFoundException","ForbiddenException","ownerOfToolCall","runForToolCall","ownerOfActiveStream","import_common","AgentApprovalPortAdapter","agent","approve","toolCallId","opts","signalToolCall","approved","executedByRef","undefined","reject","reason","import_nestjs_agent_core","import_common","AgentsController","agents","depsFactory","list","defaultAgentName","map","definition","name","description","isDefault","import_nestjs_agent_core","import_common","DEFAULT_MAX_ATTACHMENT_BYTES","DEFAULT_ALLOWED_ATTACHMENT_CONTENT_TYPES","AttachmentsController","options","actorResolver","staging","onModuleInit","attachments","upload","undefined","Error","req","file","NotImplementedException","BadRequestException","allowedContentTypes","includes","mimetype","UnsupportedMediaTypeException","join","maxBytes","size","PayloadTooLargeException","actor","resolve","stage","data","buffer","filename","originalname","contentType","sizeBytes","import_nestjs_agent_core","import_common","ChatController","agent","actorResolver","chat","req","res","body","actor","resolve","runId","threadId","message","undefined","agentName","attachments","pageContext","regenerate","transient","pipe","stream","cancel","aborted","setHeader","write","JSON","stringify","decoder","TextDecoder","buffer","chunk","subscribe","decode","newline","indexOf","line","slice","length","error","payload","AgentStreamError","code","Error","end","import_nestjs_agent_core","import_common","QuotaController","agent","actorResolver","today","req","actor","resolve","quotaToday","id","import_nestjs_agent_core","import_common","ThreadsController","agent","actorResolver","list","req","actor","resolve","listThreads","id","detail","getThread","remove","deleteThread","ok","fork","messageId","forkThread","update","body","updateThread","title","undefined","defaultAgent","promote","promoteThread","truncateFrom","truncateThreadFrom","import_nestjs_agent_core","import_common","ToolCallController","agent","actorResolver","approve","req","body","actor","resolve","toolCallId","ok","reject","reason","import_nestjs_agent_core","import_common","AGENT_METADATA","Symbol","for","Agent","options","target","Reflect","defineMetadata","readAgentMetadata","getMetadata","import_reflect_metadata","SYSTEM_PROMPT_METADATA","Symbol","for","SYSTEM_PROMPT_CONTRIBUTOR_METADATA","SystemPrompt","target","key","Reflect","defineMetadata","SystemPromptContributor","AgentDiscoveryService","logger","Logger","name","discovery","scanner","registry","contributors","onModuleInit","wrapper","getProviders","instance","meta","readAgentMetadata","undefined","register","definitionFrom","collectContributors","promptMethod","methodWith","SYSTEM_PROMPT_METADATA","systemPrompt","ctx","description","tools","model","modelId","maxSteps","handoff","delegatesTo","handoffNames","names","target","targetMeta","warn","push","prototype","Object","getPrototypeOf","getAllMethodNames","Reflect","getMetadata","SYSTEM_PROMPT_CONTRIBUTOR_METADATA","method","boundMethod","metadataKey","candidate","call","import_nestjs_agent_core","import_common","import_core","import_reflect_metadata","AI_TOOL_METADATA","Symbol","AiTool","options","target","Reflect","defineMetadata","readAiToolMetadata","getMetadata","AGENT_TOOL_BRAND","Symbol","for","brand","tool","spec","handler","isBrandedFunctionalTool","value","provideAgentTool","factoryOrTool","inject","provide","useFactory","deps","useValue","AiToolDiscoveryService","logger","Logger","name","discovery","registry","agents","options","onApplicationBootstrap","count","functional","wrapper","getProviders","instance","undefined","isBrandedFunctionalTool","registerFunctionalTool","meta","readAiToolMetadata","handler","execute","warn","register","kind","description","inputSchema","input","roles","ability","ctx","tool","tools","delegates","definition","list","target","delegatesTo","targetDefinition","get","Error","delegateToolName","has","targetBlurb","systemPrompt","targetAgent","z","object","task","string","log","spec","import_nestjs_agent_core","InProcessTokenStreamSink","runs","Map","buffer","runId","buf","get","undefined","chunks","ended","notify","Set","set","wake","resolve","clear","open","write","chunk","push","end","fail","error","failure","subscribe","index","length","AgentStreamError","Promise","add","close","delete","LedgerQuotaStore","store","limitTokens","check","actorRef","day","usedTokens","quotaToday","withinLimit","bump","import_nestjs_agent_core","import_common","InlineAgentRunner","logger","Logger","name","pending","Map","factory","store","start","input","runId","crypto","randomUUID","day","utcDay","deps","forAgent","agentName","hooks","topLevelHooks","actor","runAgentLoop","then","setActiveStream","threadId","catch","error","message","Error","String","code","QuotaExceededError","publishAgentRunFailed","recordRunEnd","status","errorCode","errorMessage","writer","sink","open","fail","signal","toolCallId","decision","key","resolve","get","undefined","delete","cancel","end","openSink","awaitApproval","call","Promise","set","id","step","_name","fn","runAgent","task","runNested","depth","sinkRunId","subThread","createThread","transient","childSinkWriter","childName","childTask","userText","delegationDepth","DEFAULT_PATH","sharedProviders","durable","includeStore","providers","provide","AGENT_TOOL_REGISTRY","useFactory","ToolRegistry","AGENT_REGISTRY","AgentRegistry","AGENT_PROMPT_CONTRIBUTORS","AGENT_SINK","options","sink","InProcessTokenStreamSink","inject","AGENT_OPTIONS","AGENT_ROLES_POLICY","rolesPolicy","DefaultRolesPolicy","defaultRoles","AGENT_ACTOR_RESOLVER","actorResolver","AGENT_MODEL","o","model","AGENT_QUOTA_STORE","store","quota","quotaLimitTokens","undefined","LedgerQuotaStore","AGENT_STORE","AgentDepsFactory","AGENT_DEPS_FACTORY","useExisting","AgentDiscoveryService","AiToolDiscoveryService","InlineAgentRunner","AgentService","AgentApprovalPortAdapter","AGENT_APPROVAL_PORT","push","AGENT_RUNNER","durableRunner","Error","token","AGENT_DURABLE_RUNNER","optional","exportsFor","BASE_CONTROLLERS","ChatController","ThreadsController","ToolCallController","QuotaController","AgentsController","GUARDABLE_CONTROLLERS","AttachmentsController","controllersFor","mountAttachments","controllersForSurface","surface","GUARDS_METADATA","applyGuards","guards","resolved","controller","Reflect","defineMetadata","guardProviders","Set","routerFor","path","RouterModule","register","module","AgentModule","assertDispatchedStepsRequiresDurable","dispatchedSteps","forRoot","global","imports","DiscoveryModule","controllers","attachments","upload","useValue","exports","forRootAsync","externalStore","attachmentsUpload","args","readHeader","req","name","undefined","headers","value","Reflect","get","HeaderActorResolver","resolve","id","length","Error","roles","split","map","role","trim","filter","tenantRef"]}