@dudousxd/nestjs-agent 0.8.2 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/durable/agent-run.workflow.ts","../../src/agent-deps.ts","../../src/durable/agent-run.steps.ts","../../src/durable/dispatched-steps.token.ts","../../src/durable/durable-agent-runner.ts","../../src/durable/agent-durable.module.ts","../../src/in-process-sink.ts","../../src/agent.module.ts","../../src/agent-deps.factory.ts","../../src/agent.service.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/ledger-quota-store.ts","../../src/runner/inline-agent-runner.ts","../../src/durable/agent-durable.ts"],"sourcesContent":["import {\n AGENT_DEPS_FACTORY,\n AGENT_STORE,\n type AgentLoopHooks,\n type AgentRunInput,\n type AgentStore,\n type Decision,\n type LlmStepEnvelope,\n QuotaExceededError,\n type ToolCallRequest,\n type ToolStepEnvelope,\n publishAgentRunFailed,\n runAgentLoop,\n} from '@dudousxd/nestjs-agent-core';\nimport { Workflow } from '@dudousxd/nestjs-durable';\nimport { type WorkflowCtx, isWorkflowControlFlowSignal } from '@dudousxd/nestjs-durable-core';\nimport { Inject, Injectable } from '@nestjs/common';\nimport type { AgentDepsFactory } from '../agent-deps.factory.js';\nimport { childSinkWriter, utcDay } from '../agent-deps.js';\nimport { AgentRunSteps } from './agent-run.steps.js';\nimport { AGENT_DISPATCHED_STEPS } from './dispatched-steps.token.js';\n\n/**\n * The agent turn AS a durable workflow. Persist/stream checkpoints are `ctx.localStep`s — the\n * in-process primitive, NOT the always-dispatched `ctx.step`: their names are dynamic checkpoint\n * identities (`persist:toolcall:<id>`), not routable worker groups, and their deps (store, sink)\n * live in THIS workflow worker's DI. The two LONG steps (model call, tool execution) are dispatched\n * through `AgentRunSteps` by default (`AGENT_DISPATCHED_STEPS`, ON under `durable: true`) so the\n * run isn't pinned to this pod while they execute; `dispatchedSteps: false` keeps them localSteps\n * too. HITL is `ctx.waitForSignal`, and sub-agent delegation is `ctx.child(AgentRunWorkflow)` — a\n * replay-safe, observable child run (it shows up as a node in the durable dashboard). A child\n * streams into its top-level ancestor's sink (`sinkRunId`) so the human watching the parent sees it\n * and can approve its action tools; the approval routes to the child's own run via `runForToolCall`.\n */\n@Injectable()\n@Workflow({ name: 'agent.run', version: '1' })\nexport class AgentRunWorkflow {\n constructor(\n @Inject(AGENT_DEPS_FACTORY) private readonly factory: AgentDepsFactory,\n @Inject(AGENT_STORE) private readonly store: AgentStore,\n private readonly steps: AgentRunSteps,\n @Inject(AGENT_DISPATCHED_STEPS) private readonly dispatchedSteps: boolean,\n ) {}\n\n async run(ctx: WorkflowCtx, input: AgentRunInput): Promise<{ text: string }> {\n const day = input.day ?? utcDay();\n const deps = this.factory.forAgent(input.agentName);\n // A sub-agent run (one with an ancestor sink) marks its subthread as streaming THIS child run,\n // so a human approving its action tool routes the signal back here (runForToolCall).\n if (input.sinkRunId !== undefined) {\n await ctx.localStep('activate', () => this.store.setActiveStream(input.threadId, ctx.runId));\n }\n const sinkRunId = input.sinkRunId ?? ctx.runId;\n const hooks: AgentLoopHooks = {\n runId: ctx.runId,\n // A child forwards into the top-level sink but must not end/fail it (the top-level run owns it).\n openSink: async () =>\n input.sinkRunId !== undefined\n ? childSinkWriter(await deps.sink.open(sinkRunId))\n : deps.sink.open(ctx.runId),\n awaitApproval: (call) => ctx.waitForSignal<Decision>(`tool:${ctx.runId}:${call.id}`),\n step: (name, fn) => ctx.localStep(name, fn),\n // Dispatched-step suspends must escape the loop's tool catch — control flow, not a tool\n // failure. Marker-based predicate, NOT instanceof: the signal's CLASS differs by runtime\n // (engine in-process throws durable-core's WorkflowSuspended/ContinueAsNew; the BullMQ thin\n // worker throws durable-worker's own Suspend), so only the Symbol.for marker is reliable.\n isControlFlowError: (error) => isWorkflowControlFlowSignal(error),\n runAgent: async (agentName, task) => {\n const subThreadId = await ctx.localStep(`subthread:${agentName}`, async () => {\n const thread = await this.store.createThread({\n actor: input.actor,\n transient: true,\n });\n return thread.id;\n });\n return ctx.child(AgentRunWorkflow, {\n agentName,\n threadId: subThreadId,\n actor: input.actor,\n userText: task,\n day,\n delegationDepth: (input.delegationDepth ?? 0) + 1,\n sinkRunId,\n });\n },\n // Routes the two long steps through AgentRunSteps as engine-dispatched `ctx.step`s instead of\n // `ctx.localStep`s, so a turn isn't pinned to this workflow worker for the model call or a tool\n // execution. `sinkRunId`/`childSink` are sink routing this workflow already resolved above —\n // core's dispatchLlm signature stays sink-topology-agnostic, so we add them here, not in core.\n ...(this.dispatchedSteps\n ? {\n dispatchLlm: (index: number, envelope: LlmStepEnvelope) =>\n ctx.step(this.steps.llm, {\n ...envelope,\n runId: ctx.runId,\n step: index,\n sinkRunId,\n childSink: input.sinkRunId !== undefined,\n }),\n // Fold the call identity (`toolCallId`/`toolType`) into the wire payload — the handler\n // emits the `tool.execution` span with it. Only read/action calls reach dispatchTool\n // ('agent'-kind delegations branch to runAgent earlier in the loop), so anything that\n // isn't 'action' is defensively 'read' — the same posture core takes for an\n // unresolvable `kind`.\n dispatchTool: (call: ToolCallRequest, envelope: ToolStepEnvelope) =>\n ctx.step(this.steps.tool, {\n ...envelope,\n toolCallId: call.id,\n toolType: call.kind === 'action' ? 'action' : 'read',\n }),\n }\n : {}),\n };\n try {\n const result = await runAgentLoop({ ...deps, day }, input, hooks);\n // Genuine completion (not a suspend) — clear so `activeRunForThread` no longer reports this\n // run. `input.threadId` is whichever thread this run's own `activate`/the top-level `chat()`\n // call marked active, so this is correct for both a top-level run and a sub-agent's subthread.\n await ctx.localStep('deactivate', () => this.store.setActiveStream(input.threadId, null));\n return result;\n } catch (error) {\n // A suspend / continue-as-new is control flow, not a failure — let the engine handle it. The\n // thread stays \"active\" across the suspend, which is correct: the turn hasn't finished.\n // Marker-based predicate, NOT instanceof: control-flow signals differ BY CLASS across the two\n // runtimes (the in-process engine throws durable-core's WorkflowSuspended/ContinueAsNew; the\n // BullMQ thin worker throws durable-worker's own Suspend). An instanceof check here\n // misclassified a thin-worker dispatch suspend as a real failure and ran the failure path\n // DURING the suspend — corrupting the run's history with extra checkpoints, so the resume\n // died with NondeterminismError. Only the Symbol.for marker is reliable cross-runtime (and\n // across duplicated module copies).\n if (isWorkflowControlFlowSignal(error)) {\n throw error;\n }\n // A real failure (e.g. quota exceeded, which throws before the sink is even opened) would\n // otherwise leave the HTTP subscriber hanging on a stream that never ends. Fail the sink with\n // a typed terminal so the controller emits an `event: error` frame, then rethrow so the engine\n // still records the run as failed.\n const message = error instanceof Error ? error.message : String(error);\n const code = error instanceof QuotaExceededError ? 'quota_exceeded' : 'run_failed';\n publishAgentRunFailed({ runId: ctx.runId, code, message });\n // Settle the run's persisted outcome (the loop only records completions — it can't catch its\n // own crash). Optional-call: a store without run recording degrades to no reliability metrics.\n await ctx.localStep(\n 'persist:run:fail',\n () =>\n this.store.recordRunEnd?.({\n runId: ctx.runId,\n status: 'failed',\n errorCode: code,\n errorMessage: message,\n }) ?? Promise.resolve(),\n );\n await ctx.localStep('deactivate', () => this.store.setActiveStream(input.threadId, null));\n // Reuse the run's own sink resolution: a top-level run fails the watched stream; a child run's\n // writer no-ops fail, deferring the surfaced error to the ancestor whose run also unwinds.\n const writer = await hooks.openSink();\n await writer.fail({ code, message });\n throw error;\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} 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 /** 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 {\n AGENT_DEPS_FACTORY,\n type AiToolCtx,\n type LlmStepEnvelope,\n type ModelTurnResult,\n type ToolStepEnvelope,\n traceLlmTurn,\n traceToolExecution,\n withToolTimeout,\n} from '@dudousxd/nestjs-agent-core';\nimport { Step } from '@dudousxd/nestjs-durable';\nimport { Inject, Injectable } from '@nestjs/common';\nimport type { AgentDepsFactory } from '../agent-deps.factory.js';\nimport { childSinkWriter } from '../agent-deps.js';\n\n/**\n * Serializable input for the dispatched `llm` step: a {@link LlmStepEnvelope} plus the sink routing\n * only the durable runner knows (`sinkRunId`/`childSink`) — core's `AgentLoopHooks.dispatchLlm` stays\n * sink-topology-agnostic, so the workflow adds these two fields when it builds the envelope.\n */\nexport interface DispatchedLlmInput extends LlmStepEnvelope {\n /**\n * The dispatching workflow's own `ctx.runId` — the run this step's outcome accrues to for\n * reliability metrics (`bumpRunRetries`). Carried even though the handler cannot bump retries\n * today: the durable handler boundary (`runStepHandler`) hands a `@Step` method only\n * `(input, StepLogger)` — the wire task's `attempt` is not exposed — so there is no clean way to\n * detect a retry from inside the handler. Kept on the envelope so the bump can be wired without a\n * wire-contract change once the durable runtime exposes the attempt.\n */\n runId: string;\n /** The turn index within the run (`llm:<step>`) — the `llm.turn` span's `step` metadata. */\n step: number;\n /** The stream target: `input.sinkRunId ?? ctx.runId` of the dispatching workflow. */\n sinkRunId: string;\n /** True for a sub-agent run — wrap the writer with {@link childSinkWriter} (no end/fail). */\n childSink: boolean;\n}\n\n/**\n * Serializable input for the dispatched `tool` step: a {@link ToolStepEnvelope} plus the call\n * identity the `tool.execution` span needs (`toolCallId`/`toolType`) — core's\n * `AgentLoopHooks.dispatchTool` passes those on the separate `ToolCallRequest` argument, so the\n * workflow folds them into the wire payload when it dispatches (same pattern as\n * {@link DispatchedLlmInput}'s sink routing).\n */\nexport interface DispatchedToolInput extends ToolStepEnvelope {\n toolCallId: string;\n toolType: 'read' | 'action';\n}\n\n/**\n * The two long steps `AgentRunWorkflow` dispatches as routed remote steps (`AgentRunSteps.llm` /\n * `AgentRunSteps.tool`) — the default under `durable: true`; `dispatchedSteps: false` runs them\n * in-process under `ctx.localStep` instead. Both re-resolve their deps from THIS worker's own DI via\n * `AGENT_DEPS_FACTORY.forAgent` — a step can be served by any worker in the fleet, not just the one\n * that started the run. Always provided by `AgentDurableModule` regardless of `dispatchedSteps`, so\n * the worker group is never orphaned.\n */\n@Injectable()\nexport class AgentRunSteps {\n constructor(@Inject(AGENT_DEPS_FACTORY) private readonly factory: AgentDepsFactory) {}\n\n /**\n * Retryable: every side effect (persist/quota/stream markers) happens loop-side under\n * `hooks.step`, so a durable retry only re-runs the model call and re-streams its tokens — never\n * double-writes. NEVER call `writer.end()`/`fail()` here: the workflow owns the stream's lifecycle,\n * across however many turns/retries it takes.\n */\n @Step({ retries: 3 })\n async llm(input: DispatchedLlmInput): Promise<ModelTurnResult> {\n const deps = this.factory.forAgent(input.agentName);\n // The envelope carries only wire-safe data — a `ToolDefinition` holds a live Zod/StandardSchema\n // instance that can't survive JSON transport, so this handler re-derives it from `input.actor`,\n // exactly like the loop's own non-dispatched branch does.\n const tools = await deps.registry.definitionsFor(\n input.actor,\n deps.rolesPolicy,\n deps.toolAllowList,\n );\n const opened = await deps.sink.open(input.sinkRunId);\n const writer = input.childSink ? childSinkWriter(opened) : opened;\n // Span-wrapped HERE (the genuine execution site), emitting the identical `aviary:agent:llm.turn`\n // span core's non-dispatched branch emits — from whichever worker actually serves the step.\n // Replay-safe by construction: a dispatched step's handler only runs on genuine dispatch (replay\n // resolves the step from its checkpoint without re-invoking a worker), which is exactly why core\n // exports the helper instead of wrapping the `hooks.dispatchLlm` CALL site itself.\n return traceLlmTurn(input.runId, input.step, () =>\n deps.model.runTurn({\n system: input.system,\n messages: input.messages,\n tools,\n sink: writer,\n }),\n );\n }\n\n /**\n * No retries — a tool may not be idempotent (a bare `@Step()` carries none, unlike `llm` above).\n * The timeout is applied HERE, handler-side, via `withToolTimeout` — never as a durable dispatch\n * `timeoutMs`, which bounds engine liveness (retryable) rather than the tool's own business outcome.\n */\n @Step()\n async tool(input: DispatchedToolInput): Promise<unknown> {\n const deps = this.factory.forAgent(input.ctx.agentName);\n // AgentDeps carries no `host` today (AgentDepsFactory never populates one), so the rebuilt ctx\n // is exactly `input.ctx` — no narrower than what the non-dispatched path already threads through.\n const ctx: AiToolCtx = { ...input.ctx };\n // Span-wrapped HERE like `llm` above (same replay-safety-by-construction reasoning) — the\n // timeout sits INSIDE the span so a timed-out tool surfaces as the span's error phase.\n return traceToolExecution(\n input.ctx.runId,\n { toolCallId: input.toolCallId, toolName: input.toolName, toolType: input.toolType },\n () => {\n const invocation = deps.registry.invoke(input.toolName, input.input, ctx, deps.rolesPolicy);\n return input.timeoutMs !== undefined\n ? withToolTimeout(invocation, input.timeoutMs, input.toolName)\n : invocation;\n },\n );\n }\n}\n","/**\n * DI flag carrying the EFFECTIVE `dispatchedSteps` value: whether `AgentRunWorkflow` dispatches its\n * `llm`/`tool` steps as routed remote steps (`AgentRunSteps`) instead of in-process `ctx.localStep`s.\n * `AgentDurableModule` derives it from `AGENT_OPTIONS` (`durable === true && dispatchedSteps !==\n * false` — default ON under durable); `AgentRunWorkflow` injects it. Kept in its own file —\n * `AgentDurableModule` provides `AgentRunWorkflow` and `AgentRunWorkflow` injects this token, so\n * declaring it in either of those two files would make them import each other.\n */\nexport const AGENT_DISPATCHED_STEPS = Symbol.for('@dudousxd/nestjs-agent:dispatched-steps');\n","import { randomUUID } from 'node:crypto';\nimport type { AgentRunInput, AgentRunner, Decision } from '@dudousxd/nestjs-agent-core';\nimport { WorkflowService } from '@dudousxd/nestjs-durable';\nimport { isWorkflowControlFlowSignal } from '@dudousxd/nestjs-durable-core';\nimport { Injectable } from '@nestjs/common';\nimport { utcDay } from '../agent-deps.js';\nimport { AgentRunWorkflow } from './agent-run.workflow.js';\n\n/**\n * Runs the agent turn as a `@dudousxd/nestjs-durable` workflow. `start` creates the run and returns\n * its id immediately; a worker runs the body and streams tokens to the sink. HITL approval is\n * delivered as a durable signal namespaced by run, so it can never cross-resolve another run.\n */\n@Injectable()\nexport class DurableAgentRunner implements AgentRunner {\n constructor(private readonly workflows: WorkflowService) {}\n\n async start(input: AgentRunInput): Promise<{ runId: string }> {\n const stamped: AgentRunInput = { ...input, day: input.day ?? utcDay() };\n // Own the run id so we can still return it when the run suspends synchronously (below).\n const runId = randomUUID();\n try {\n await this.workflows.start(AgentRunWorkflow, stamped, runId);\n } catch (error) {\n // A run that suspends on its FIRST step (waiting on the model/tool worker, a signal, or a\n // sleep) surfaces the runtime's internal suspend signal here whenever the start ran under a\n // DRIVING dispatcher (e.g. a durable tenant/worker) rather than the enqueue-only one. That is\n // expected control flow, NOT a failure: the run is already persisted and a worker will resume\n // it, while the caller streams the sink meanwhile. Swallow it and return the run id; any\n // other error is a real start failure and propagates. Marker-based predicate, NOT instanceof:\n // the signal's CLASS differs by runtime (engine in-process WorkflowSuspended vs the BullMQ\n // thin worker's own Suspend), so only the Symbol.for marker is reliable.\n if (!isWorkflowControlFlowSignal(error)) {\n throw error;\n }\n }\n return { runId };\n }\n\n async signal(runId: string, toolCallId: string, decision: Decision): Promise<void> {\n await this.workflows.signal(`tool:${runId}:${toolCallId}`, decision);\n }\n\n async cancel(_runId: string): Promise<void> {\n // WorkflowService exposes no hard cancel; rely on the execution timeout / control plane.\n // Apps needing immediate cancel can resolve WorkflowEngine and call engine.cancel(runId).\n await Promise.resolve();\n }\n}\n","import {\n AGENT_DURABLE_RUNNER,\n AGENT_OPTIONS,\n AGENT_SINK,\n type TokenStreamSink,\n} from '@dudousxd/nestjs-agent-core';\nimport { type DynamicModule, Global, Logger, Module } from '@nestjs/common';\nimport type { AgentModuleOptions } from '../agent.options.js';\nimport { InProcessTokenStreamSink } from '../in-process-sink.js';\nimport { AgentRunSteps } from './agent-run.steps.js';\nimport { AgentRunWorkflow } from './agent-run.workflow.js';\nimport { AGENT_DISPATCHED_STEPS } from './dispatched-steps.token.js';\nimport { DurableAgentRunner } from './durable-agent-runner.js';\n\nconst logger = new Logger('AgentDurableModule');\n\n/**\n * Opt-in durable runner. Import this alongside `AgentModule.forRoot({ durable: true })` and a\n * configured `DurableModule`. It registers the `agent.run` workflow (discovered by DurableModule)\n * and exposes the durable runner via `AGENT_DURABLE_RUNNER`, which AgentModule binds to\n * `AGENT_RUNNER`. Forgetting this import makes AgentModule throw a clear error at boot.\n *\n * Always provides `AgentRunSteps` regardless of `dispatchedSteps` — the worker group it serves\n * (`AgentRunSteps.llm`/`.tool`) must never be orphaned by a config flag the durable step registrar\n * can't see ahead of time.\n */\n@Global()\n@Module({\n providers: [\n AgentRunWorkflow,\n AgentRunSteps,\n DurableAgentRunner,\n { provide: AGENT_DURABLE_RUNNER, useExisting: DurableAgentRunner },\n {\n provide: AGENT_DISPATCHED_STEPS,\n useFactory: (options: AgentModuleOptions, sink: TokenStreamSink) => {\n // Default ON under durable: dispatching moves the run off its pod during the two long\n // steps (the correct production posture) and AgentRunSteps is always registered, so the\n // routed groups are never unserved. `dispatchedSteps: false` opts back into localSteps.\n const enabled = options.durable === true && options.dispatchedSteps !== false;\n // The default sink only buffers in-process: a dispatched `llm` step served by another\n // worker has no way to reach a buffer that lives in THIS process's memory. Detectable only\n // via `instanceof` (the sink SPI carries no \"am I cross-process\" capability) — good enough\n // for the built-in default, silent for any custom sink (which may well be cross-process).\n // Keyed off the EFFECTIVE value, so it fires for the durable default too — desired: the\n // cross-process-sink requirement is really a property of durable itself (any worker may\n // take agent.run), dispatch just widens how much of the turn runs elsewhere.\n if (enabled && sink instanceof InProcessTokenStreamSink) {\n logger.warn(\n 'Dispatched steps are active (the default under durable: true) with the default ' +\n 'InProcessTokenStreamSink, which only buffers tokens in-process. A dispatched `llm` ' +\n 'step served by a different worker cannot stream into this buffer. Wire a ' +\n 'cross-process TokenStreamSink (e.g. a Redis pub/sub sink) via ' +\n 'AgentModule.forRoot({ sink }) before running multi-pod, or set ' +\n 'dispatchedSteps: false to keep the turn in-process localSteps.',\n );\n }\n return enabled;\n },\n inject: [AGENT_OPTIONS, AGENT_SINK],\n },\n ],\n exports: [AGENT_DURABLE_RUNNER, AgentRunWorkflow, AgentRunSteps, AGENT_DISPATCHED_STEPS],\n})\nexport class AgentDurableModule {\n /**\n * The dynamic form used by the `agentDurable` helper. The module needs no configuration of its\n * own (its providers come from the decorator above), so this just yields the module reference —\n * importing `AgentDurableModule` directly stays equivalent.\n */\n static forRoot(): DynamicModule {\n return { module: AgentDurableModule, global: true };\n }\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 {\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 ...(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 { 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 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 { DynamicModule } from '@nestjs/common';\nimport { AgentModule } from '../agent.module.js';\nimport type { AgentModuleOptions } from '../agent.options.js';\nimport { AgentDurableModule } from './agent-durable.module.js';\n\n/**\n * One-import setup for the durable runner. Spread the result into a module's `imports`:\n *\n * ```ts\n * imports: [DurableModule.forRoot({ ... }), ...agentDurable({ model, store, defaultAgent })]\n * ```\n *\n * It wires `AgentModule.forRoot({ ...options, durable: true })` together with `AgentDurableModule`,\n * the equivalent of importing both by hand. A configured `DurableModule` is still required. The\n * durable runner has no configuration of its own, so `options` is exactly the agent options.\n */\nexport function agentDurable(options: AgentModuleOptions): DynamicModule[] {\n return [AgentModule.forRoot({ ...options, durable: true }), AgentDurableModule.forRoot()];\n}\n"],"mappings":";;;;AAAA,SACEA,sBAAAA,qBACAC,aAMAC,oBAGAC,uBACAC,oBACK;AACP,SAASC,gBAAgB;AACzB,SAA2BC,mCAAmC;AAC9D,SAASC,UAAAA,SAAQC,cAAAA,mBAAkB;;;AC0B5B,SAASC,OAAOC,OAAO,oBAAIC,KAAAA,GAAM;AACtC,SAAOD,KAAKE,YAAW,EAAGC,MAAM,GAAG,EAAA;AACrC;AAFgBJ;AAUT,SAASK,gBAAgBC,QAAkB;AAChD,SAAO;IACLC,OAAO,wBAACC,UAAUF,OAAOC,MAAMC,KAAAA,GAAxB;IACPC,KAAK,mCAAA;IAAa,GAAb;IACLC,MAAM,mCAAA;IAAa,GAAb;EACR;AACF;AANgBL;;;ACpDhB,SACEM,oBAKAC,cACAC,oBACAC,uBACK;AACP,SAASC,YAAY;AACrB,SAASC,QAAQC,kBAAkB;;;;;;;;;;;;;;;;;;AAgD5B,IAAMC,gBAAN,MAAMA;SAAAA;;;;EACX,YAAyDC,SAA2B;SAA3BA,UAAAA;EAA4B;;;;;;;EAQrF,MACMC,IAAIC,OAAqD;AAC7D,UAAMC,OAAO,KAAKH,QAAQI,SAASF,MAAMG,SAAS;AAIlD,UAAMC,QAAQ,MAAMH,KAAKI,SAASC,eAChCN,MAAMO,OACNN,KAAKO,aACLP,KAAKQ,aAAa;AAEpB,UAAMC,SAAS,MAAMT,KAAKU,KAAKC,KAAKZ,MAAMa,SAAS;AACnD,UAAMC,SAASd,MAAMe,YAAYC,gBAAgBN,MAAAA,IAAUA;AAM3D,WAAOO,aAAajB,MAAMkB,OAAOlB,MAAMmB,MAAM,MAC3ClB,KAAKmB,MAAMC,QAAQ;MACjBC,QAAQtB,MAAMsB;MACdC,UAAUvB,MAAMuB;MAChBnB;MACAO,MAAMG;IACR,CAAA,CAAA;EAEJ;;;;;;EAOA,MACMU,KAAKxB,OAA8C;AACvD,UAAMC,OAAO,KAAKH,QAAQI,SAASF,MAAMyB,IAAItB,SAAS;AAGtD,UAAMsB,MAAiB;MAAE,GAAGzB,MAAMyB;IAAI;AAGtC,WAAOC,mBACL1B,MAAMyB,IAAIP,OACV;MAAES,YAAY3B,MAAM2B;MAAYC,UAAU5B,MAAM4B;MAAUC,UAAU7B,MAAM6B;IAAS,GACnF,MAAA;AACE,YAAMC,aAAa7B,KAAKI,SAAS0B,OAAO/B,MAAM4B,UAAU5B,MAAMA,OAAOyB,KAAKxB,KAAKO,WAAW;AAC1F,aAAOR,MAAMgC,cAAcC,SACvBC,gBAAgBJ,YAAY9B,MAAMgC,WAAWhC,MAAM4B,QAAQ,IAC3DE;IACN,CAAA;EAEJ;AACF;;;IApDUK,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;AC5DZ,IAAMC,yBAAyBC,OAAOC,IAAI,yCAAA;;;;;;;;;;;;;;;;;;;;AH4B1C,IAAMC,mBAAN,MAAMA,kBAAAA;SAAAA;;;;;;;EACX,YAC+CC,SACPC,OACrBC,OACgCC,iBACjD;SAJ6CH,UAAAA;SACPC,QAAAA;SACrBC,QAAAA;SACgCC,kBAAAA;EAChD;EAEH,MAAMC,IAAIC,KAAkBC,OAAiD;AAC3E,UAAMC,MAAMD,MAAMC,OAAOC,OAAAA;AACzB,UAAMC,OAAO,KAAKT,QAAQU,SAASJ,MAAMK,SAAS;AAGlD,QAAIL,MAAMM,cAAcC,QAAW;AACjC,YAAMR,IAAIS,UAAU,YAAY,MAAM,KAAKb,MAAMc,gBAAgBT,MAAMU,UAAUX,IAAIY,KAAK,CAAA;IAC5F;AACA,UAAML,YAAYN,MAAMM,aAAaP,IAAIY;AACzC,UAAMC,QAAwB;MAC5BD,OAAOZ,IAAIY;;MAEXE,UAAU,mCACRb,MAAMM,cAAcC,SAChBO,gBAAgB,MAAMX,KAAKY,KAAKC,KAAKV,SAAAA,CAAAA,IACrCH,KAAKY,KAAKC,KAAKjB,IAAIY,KAAK,GAHpB;MAIVM,eAAe,wBAACC,SAASnB,IAAIoB,cAAwB,QAAQpB,IAAIY,KAAK,IAAIO,KAAKE,EAAE,EAAE,GAApE;MACfC,MAAM,wBAACC,MAAMC,OAAOxB,IAAIS,UAAUc,MAAMC,EAAAA,GAAlC;;;;;MAKNC,oBAAoB,wBAACC,UAAUC,4BAA4BD,KAAAA,GAAvC;MACpBE,UAAU,8BAAOtB,WAAWuB,SAAAA;AAC1B,cAAMC,cAAc,MAAM9B,IAAIS,UAAU,aAAaH,SAAAA,IAAa,YAAA;AAChE,gBAAMyB,SAAS,MAAM,KAAKnC,MAAMoC,aAAa;YAC3CC,OAAOhC,MAAMgC;YACbC,WAAW;UACb,CAAA;AACA,iBAAOH,OAAOV;QAChB,CAAA;AACA,eAAOrB,IAAImC,MAAMzC,mBAAkB;UACjCY;UACAK,UAAUmB;UACVG,OAAOhC,MAAMgC;UACbG,UAAUP;UACV3B;UACAmC,kBAAkBpC,MAAMoC,mBAAmB,KAAK;UAChD9B;QACF,CAAA;MACF,GAjBU;;;;;MAsBV,GAAI,KAAKT,kBACL;QACEwC,aAAa,wBAACC,OAAeC,aAC3BxC,IAAIsB,KAAK,KAAKzB,MAAM4C,KAAK;UACvB,GAAGD;UACH5B,OAAOZ,IAAIY;UACXU,MAAMiB;UACNhC;UACAmC,WAAWzC,MAAMM,cAAcC;QACjC,CAAA,GAPW;;;;;;QAabmC,cAAc,wBAACxB,MAAuBqB,aACpCxC,IAAIsB,KAAK,KAAKzB,MAAM+C,MAAM;UACxB,GAAGJ;UACHK,YAAY1B,KAAKE;UACjByB,UAAU3B,KAAK4B,SAAS,WAAW,WAAW;QAChD,CAAA,GALY;MAMhB,IACA,CAAC;IACP;AACA,QAAI;AACF,YAAMC,SAAS,MAAMC,aAAa;QAAE,GAAG7C;QAAMF;MAAI,GAAGD,OAAOY,KAAAA;AAI3D,YAAMb,IAAIS,UAAU,cAAc,MAAM,KAAKb,MAAMc,gBAAgBT,MAAMU,UAAU,IAAA,CAAA;AACnF,aAAOqC;IACT,SAAStB,OAAO;AAUd,UAAIC,4BAA4BD,KAAAA,GAAQ;AACtC,cAAMA;MACR;AAKA,YAAMwB,UAAUxB,iBAAiByB,QAAQzB,MAAMwB,UAAUE,OAAO1B,KAAAA;AAChE,YAAM2B,OAAO3B,iBAAiB4B,qBAAqB,mBAAmB;AACtEC,4BAAsB;QAAE3C,OAAOZ,IAAIY;QAAOyC;QAAMH;MAAQ,CAAA;AAGxD,YAAMlD,IAAIS,UACR,oBACA,MACE,KAAKb,MAAM4D,eAAe;QACxB5C,OAAOZ,IAAIY;QACX6C,QAAQ;QACRC,WAAWL;QACXM,cAAcT;MAChB,CAAA,KAAMU,QAAQC,QAAO,CAAA;AAEzB,YAAM7D,IAAIS,UAAU,cAAc,MAAM,KAAKb,MAAMc,gBAAgBT,MAAMU,UAAU,IAAA,CAAA;AAGnF,YAAMmD,SAAS,MAAMjD,MAAMC,SAAQ;AACnC,YAAMgD,OAAOC,KAAK;QAAEV;QAAMH;MAAQ,CAAA;AAClC,YAAMxB;IACR;EACF;AACF;;;;IA7HYH,MAAM;IAAayC,SAAS;;;;;;;;;;;;;;;AInCxC,SAASC,kBAAkB;AAE3B,SAASC,uBAAuB;AAChC,SAASC,+BAAAA,oCAAmC;AAC5C,SAASC,cAAAA,mBAAkB;;;;;;;;;;;;AAUpB,IAAMC,qBAAN,MAAMA;SAAAA;;;;EACX,YAA6BC,WAA4B;SAA5BA,YAAAA;EAA6B;EAE1D,MAAMC,MAAMC,OAAkD;AAC5D,UAAMC,UAAyB;MAAE,GAAGD;MAAOE,KAAKF,MAAME,OAAOC,OAAAA;IAAS;AAEtE,UAAMC,QAAQC,WAAAA;AACd,QAAI;AACF,YAAM,KAAKP,UAAUC,MAAMO,kBAAkBL,SAASG,KAAAA;IACxD,SAASG,OAAO;AASd,UAAI,CAACC,6BAA4BD,KAAAA,GAAQ;AACvC,cAAMA;MACR;IACF;AACA,WAAO;MAAEH;IAAM;EACjB;EAEA,MAAMK,OAAOL,OAAeM,YAAoBC,UAAmC;AACjF,UAAM,KAAKb,UAAUW,OAAO,QAAQL,KAAAA,IAASM,UAAAA,IAAcC,QAAAA;EAC7D;EAEA,MAAMC,OAAOC,QAA+B;AAG1C,UAAMC,QAAQC,QAAO;EACvB;AACF;;;;;;;;;;AChDA,SACEC,sBACAC,eACAC,kBAEK;AACP,SAA6BC,QAAQC,QAAQC,cAAc;;;ACN3D,SACEC,wBAIK;AAkBA,IAAMC,2BAAN,MAAMA;EAvBb,OAuBaA;;;EACMC,OAAO,oBAAIC,IAAAA;EAEpBC,OAAOC,OAA0B;AACvC,QAAIC,MAAM,KAAKJ,KAAKK,IAAIF,KAAAA;AACxB,QAAIC,QAAQE,QAAW;AACrBF,YAAM;QAAEG,QAAQ,CAAA;QAAIC,OAAO;QAAOC,QAAQ,oBAAIC,IAAAA;MAAM;AACpD,WAAKV,KAAKW,IAAIR,OAAOC,GAAAA;IACvB;AACA,WAAOA;EACT;EAEQQ,KAAKR,KAAsB;AACjC,eAAWS,WAAWT,IAAIK,QAAQ;AAChCI,cAAAA;IACF;AACAT,QAAIK,OAAOK,MAAK;EAClB;EAEAC,KAAKZ,OAA2B;AAC9B,UAAMC,MAAM,KAAKF,OAAOC,KAAAA;AACxB,WAAO;MACLa,OAAO,wBAACC,UAAAA;AACNb,YAAIG,OAAOW,KAAKD,KAAAA;AAChB,aAAKL,KAAKR,GAAAA;MACZ,GAHO;MAIPe,KAAK,6BAAA;AACHf,YAAII,QAAQ;AACZ,aAAKI,KAAKR,GAAAA;MACZ,GAHK;MAILgB,MAAM,wBAACC,UAAAA;AACLjB,YAAIkB,UAAUD;AACdjB,YAAII,QAAQ;AACZ,aAAKI,KAAKR,GAAAA;MACZ,GAJM;IAKR;EACF;EAEA,OAAOmB,UAAUpB,OAA0C;AACzD,UAAMC,MAAM,KAAKF,OAAOC,KAAAA;AACxB,QAAIqB,QAAQ;AACZ,WAAO,MAAM;AACX,aAAOA,QAAQpB,IAAIG,OAAOkB,QAAQ;AAChC,cAAMR,QAAQb,IAAIG,OAAOiB,KAAAA;AACzBA,iBAAS;AACT,YAAIP,UAAUX,QAAW;AACvB,gBAAMW;QACR;MACF;AACA,UAAIb,IAAII,OAAO;AAEb,YAAIJ,IAAIkB,YAAYhB,QAAW;AAC7B,gBAAM,IAAIoB,iBAAiBtB,IAAIkB,OAAO;QACxC;AACA;MACF;AACA,YAAM,IAAIK,QAAc,CAACd,YAAYT,IAAIK,OAAOmB,IAAIf,OAAAA,CAAAA;IACtD;EACF;EAEAgB,MAAM1B,OAAqB;AACzB,SAAKH,KAAK8B,OAAO3B,KAAAA;EACnB;AACF;;;;;;;;;;ADxEA,IAAM4B,SAAS,IAAIC,OAAO,oBAAA;AAkDnB,IAAMC,qBAAN,MAAMA,oBAAAA;SAAAA;;;;;;;;EAMX,OAAOC,UAAyB;AAC9B,WAAO;MAAEC,QAAQF;MAAoBG,QAAQ;IAAK;EACpD;AACF;;;;IA7CEC,WAAW;MACTC;MACAC;MACAC;MACA;QAAEC,SAASC;QAAsBC,aAAaH;MAAmB;MACjE;QACEC,SAASG;QACTC,YAAY,wBAACC,SAA6BC,SAAAA;AAIxC,gBAAMC,UAAUF,QAAQG,YAAY,QAAQH,QAAQI,oBAAoB;AAQxE,cAAIF,WAAWD,gBAAgBI,0BAA0B;AACvDpB,mBAAOqB,KACL,waAKE;UAEN;AACA,iBAAOJ;QACT,GAvBY;QAwBZK,QAAQ;UAACC;UAAeC;;MAC1B;;IAEFC,SAAS;MAACd;MAAsBJ;MAAkBC;MAAeK;;;;;;AE9DnE,SACEa,wBAAAA,uBACAC,qBACAC,sBAAAA,qBACAC,wBAAAA,uBACAC,eAAAA,cACAC,iBAAAA,gBACAC,6BAAAA,4BACAC,qBAAAA,oBACAC,kBAAAA,iBACAC,sBAAAA,qBACAC,gBAAAA,eACAC,cAAAA,aACAC,eAAAA,cACAC,uBAAAA,sBACAC,iBAAAA,gBAGAC,oBACAC,gBAAAA,qBACK;AACP,SAGEC,UAAAA,SACAC,UAAAA,eAGK;AACP,SAASC,iBAAiBC,oBAAoB;;;AC7B9C,SACEC,aACAC,qBACAC,2BACAC,mBACAC,gBACAC,oBACAC,cAAAA,aACAC,eAAAA,cACAC,qBAGAC,iBAAAA,gBAOAC,gBAAAA,qBACK;AACP,SAASC,iBAAAA,sBAAqB;AAC9B,SAASC,UAAAA,SAAQC,cAAAA,aAAYC,gBAAgB;;;;;;;;;;;;;;;;;;AAKtC,SAASC,iBAAiBC,QAAc;AAC7C,SAAO,OAAOA,OAAOC,QAAQ,kBAAkB,GAAA,CAAA;AACjD;AAFgBF;AAMT,IAAMG,oBAAN,MAAMA;SAAAA;;;;;;;;;;;;;EACX,YAC0CC,SACFC,OACAC,OACDC,MACQC,aACCC,UACLC,QACWC,oBACRC,OAM3BC,cACjB;SAfwCT,UAAAA;SACFC,QAAAA;SACAC,QAAAA;SACDC,OAAAA;SACQC,cAAAA;SACCC,WAAAA;SACLC,SAAAA;SACWC,qBAAAA;SACRC,QAAAA;SAM3BC,eAAAA;EAChB;;;;;EAMHC,mBAA2B;AACzB,QAAI,KAAKV,QAAQW,iBAAiBC,QAAW;AAC3C,aAAO,KAAKZ,QAAQW;IACtB;AACA,UAAME,aAAa,KAAKP,OAAOQ,KAAI;AACnC,WAAOD,WAAWE,WAAW,IAAKF,WAAW,CAAA,GAAIG,QAAQ,YAAa;EACxE;EAEQC,eAAeC,YAA+D;AACpF,QAAIA,eAAeN,QAAW;AAC5B,aAAOA;IACT;AACA,UAAMO,aAAaD,WAAWE,eAAe,CAAA,GAAIC,IAAIzB,gBAAAA;AACrD,QAAIsB,WAAWI,UAAUV,UAAaO,UAAUJ,WAAW,GAAG;AAC5D,aAAOH;IACT;AACA,WAAO;SAAKM,WAAWI,SAAS,CAAA;SAAQH;;EAC1C;EAEAI,SAASC,WAA+B;AACtC,UAAMR,OAAOQ,aAAa,KAAKd,iBAAgB;AAC/C,UAAMQ,aAAa,KAAKZ,OAAOmB,IAAIT,IAAAA;AACnC,UAAMU,gBAAgB,KAAKT,eAAeC,UAAAA;AAC1C,UAAMS,iBAAiB,KAAKA,eAAc;AAC1C,UAAMC,YAAY,KAAK5B,QAAQ4B;AAC/B,WAAO;MACL3B,OAAO,KAAKA;MACZC,OAAO,KAAKA;MACZC,MAAM,KAAKA;MACXC,aAAa,KAAKA;MAClBC,UAAU,KAAKA;MACfE,oBAAoB,KAAKA;MACzBsB,cAAcX,YAAYW,gBAAgB;MAC1CC,UAAUZ,YAAYY,YAAY;MAClC,GAAIZ,YAAYa,YAAYnB,SAAY;QAAEmB,SAASb,WAAWa;MAAQ,IAAI,CAAC;MAC3E,GAAI,KAAKvB,UAAUI,SAAY;QAAEJ,OAAO,KAAKA;MAAM,IAAI,CAAC;MACxD,GAAI,KAAKC,iBAAiBG,SAAY;QAAEH,cAAc,KAAKA;MAAa,IAAI,CAAC;MAC7E,GAAIiB,kBAAkBd,SAAY;QAAEc;MAAc,IAAI,CAAC;MACvD,GAAI,KAAK1B,QAAQgC,kBAAkBpB,SAC/B;QAAEoB,eAAe,KAAKhC,QAAQgC;MAAc,IAC5C,CAAC;MACL,GAAIL,mBAAmBf,SAAY;QAAEe;MAAe,IAAI,CAAC;MACzD,GAAIC,WAAWK,SAAS,WACpB;QACEC,WAAWN,UAAUM;QACrB,GAAIN,UAAUO,SAASvB,SAAY;UAAEwB,eAAeR,UAAUO;QAAK,IAAI,CAAC;MAC1E,IACA,CAAC;IACP;EACF;;EAGQR,iBAAqC;AAC3C,UAAMU,YAAY,KAAKrC,QAAQqC;AAC/B,QAAIA,cAAc,MAAM;AACtB,aAAO;IACT;AACA,QAAI,OAAOA,cAAc,UAAU;AACjC,aAAOA,UAAUC;IACnB;AACA,WAAO1B;EACT;AACF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACtHA,SACE2B,sBAAAA,qBACAC,qBAAAA,oBACAC,cACAC,eAAAA,oBAaK;AACP,SACEC,qBACAC,oBACAC,UAAAA,SACAC,cAAAA,aACAC,mBACAC,+BACK;;;;;;;;;;;;;;;;;;AAuBA,IAAMC,eAAN,MAAMA;SAAAA;;;;;;;EACX,YACyCC,QACDC,OACOC,MACDC,OAC5C;SAJuCH,SAAAA;SACDC,QAAAA;SACOC,OAAAA;SACDC,QAAAA;EAC3C;EAEH,MAAMC,KAAKC,QAAkE;AAI3E,UAAMC,YAAY,MAAM,KAAKC,iBAAiBF,OAAOC,WAAWD,OAAOG,QAAQ;AAC/E,QAAIA,WAAWH,OAAOG;AACtB,QAAIA,aAAaC,QAAW;AAC1B,UAAIJ,OAAOK,eAAe,MAAM;AAC9B,cAAM,IAAIC,oBAAoB,0CAAA;MAChC;AACA,YAAMC,UAAU,MAAM,KAAKX,MAAMY,aAAa;QAC5CC,OAAOT,OAAOS;QACd,GAAIT,OAAOU,cAAc,OAAO;UAAEA,WAAW;QAAK,IAAI,CAAC;MACzD,CAAA;AACAP,iBAAWI,QAAQI;IACrB,WAAWX,OAAOK,eAAe,MAAM;AAGrC,YAAM,KAAKO,iBAAiBZ,OAAOS,OAAON,QAAAA;IAC5C;AAEA,UAAMU,QAAuB;MAC3BV;MACAM,OAAOT,OAAOS;MACdK,UAAUd,OAAOe;MACjBC,KAAKC,OAAAA;MACLhB;MACA,GAAID,OAAOK,eAAe,OAAO;QAAEA,YAAY;MAAK,IAAI,CAAC;MACzD,GAAIL,OAAOkB,gBAAgBd,SAAY;QAAEc,aAAalB,OAAOkB;MAAY,IAAI,CAAC;MAC9E,GAAIlB,OAAOmB,gBAAgBf,SAAY;QAAEe,aAAanB,OAAOmB;MAAY,IAAI,CAAC;IAChF;AAEA,UAAM,EAAEC,MAAK,IAAK,MAAM,KAAKzB,OAAO0B,MAAMR,KAAAA;AAC1C,UAAM,KAAKjB,MAAM0B,gBAAgBnB,UAAUiB,KAAAA;AAC3C,WAAO;MAAEA;MAAOjB;IAAS;EAC3B;EAEAoB,UAAUH,OAA0C;AAClD,WAAO,KAAKvB,KAAK2B,SAAQ,EAAGC,KAAKF,UAAUH,KAAAA;EAC7C;EAEA,MAAMM,QAAQjB,OAAckB,YAAmC;AAC7D,UAAM,KAAKC,mBAAmBnB,OAAOkB,UAAAA;AACrC,WAAO,KAAKE,eAAeF,YAAY;MAAEG,UAAU;IAAK,CAAA;EAC1D;EAEA,MAAMC,OAAOtB,OAAckB,YAAoBK,QAAgC;AAC7E,UAAM,KAAKJ,mBAAmBnB,OAAOkB,UAAAA;AACrC,WAAO,KAAKE,eAAeF,YAAY;MACrCG,UAAU;MACV,GAAIE,WAAW5B,SAAY;QAAE4B;MAAO,IAAI,CAAC;IAC3C,CAAA;EACF;;;;;;;;;EAUA,MAAMH,eAAeF,YAAoBM,UAAmC;AAC1E,UAAMb,QAAQ,MAAM,KAAKc,sBAAsBP,UAAAA;AAC/C,WAAO,KAAKhC,OAAOwC,OAAOf,OAAOO,YAAYM,QAAAA;EAC/C;EAEA,MAAMG,OAAO3B,OAAcW,OAA8B;AACvD,UAAM,KAAKiB,uBAAuB5B,OAAOW,KAAAA;AACzC,WAAO,KAAKzB,OAAOyC,OAAOhB,KAAAA;EAC5B;EAEA,MAAMkB,YAAYC,UAA4C;AAC5D,UAAMC,UAAU,MAAM,KAAK5C,MAAM0C,YAAYC,QAAAA;AAC7C,WAAOE,QAAQC,IAAIF,QAAQG,IAAI,CAACC,WAAW,KAAKC,cAAcD,MAAAA,CAAAA,CAAAA;EAChE;EAEA,MAAME,UAAUrC,OAAcN,UAAgD;AAC5E,UAAM,KAAKS,iBAAiBH,OAAON,QAAAA;AACnC,UAAMyC,SAAS,MAAM,KAAKhD,MAAMkD,UAAU3C,QAAAA;AAC1C,WAAOyC,WAAW,OAAO,OAAO,KAAKG,aAAaH,MAAAA;EACpD;EAEA,MAAMI,aAAavC,OAAcN,UAAiC;AAChE,UAAM,KAAKS,iBAAiBH,OAAON,QAAAA;AACnC,WAAO,KAAKP,MAAMqD,iBAAiB9C,QAAAA;EACrC;EAEA,MAAM+C,WAAWzC,OAAcN,UAAkBgD,eAA+C;AAC9F,UAAM,KAAKvC,iBAAiBH,OAAON,QAAAA;AACnC,WAAO,KAAKP,MAAMsD,WAAW/C,UAAUgD,aAAAA;EACzC;;EAGA,MAAMC,aAAa3C,OAAcN,UAAkBkD,OAA8B;AAC/E,WAAO,KAAKC,aAAa7C,OAAON,UAAU;MAAEkD;IAAM,CAAA;EACpD;;;;;;;EAQA,MAAMC,aAAa7C,OAAcN,UAAkBoD,OAAyC;AAC1F,UAAMF,QAAQE,MAAMF,UAAUjD,SAAY,KAAKoD,cAAcD,MAAMF,KAAK,IAAIjD;AAC5E,UAAM,KAAKQ,iBAAiBH,OAAON,QAAAA;AACnC,QAAIoD,MAAME,iBAAiBrD,QAAW;AACpC,UAAIiD,UAAUjD,QAAW;AACvB,cAAM,KAAKR,MAAM8D,SAASvD,UAAUkD,KAAAA;MACtC;AACA;IACF;AACA,QAAI,KAAKzD,MAAM0D,iBAAiBlD,QAAW;AACzC,YAAM,IAAIuD,wBACR,6HACE;IAEN;AACA,UAAM,KAAK/D,MAAM0D,aAAanD,UAAU;MACtC,GAAIkD,UAAUjD,SAAY;QAAEiD;MAAM,IAAI,CAAC;MACvCI,cAAcF,MAAME;IACtB,CAAA;EACF;EAEQD,cAAcH,OAAuB;AAC3C,UAAMO,UAAUP,MAAMQ,KAAI;AAC1B,QAAID,QAAQE,WAAW,GAAG;AACxB,YAAM,IAAIxD,oBAAoB,yBAAA;IAChC;AACA,QAAIsD,QAAQE,SAAS,KAAK;AACxB,YAAM,IAAIxD,oBAAoB,sCAAA;IAChC;AACA,WAAOsD;EACT;;;;;;EAOA,MAAc1D,iBACZD,WACAE,UACiB;AACjB,QAAIF,cAAcG,QAAW;AAC3B,aAAOH;IACT;AACA,QAAIE,aAAaC,QAAW;AAC1B,YAAMwC,SAAS,MAAM,KAAKhD,MAAMkD,UAAU3C,QAAAA;AAC1C,UAAIyC,QAAQa,iBAAiBrD,UAAawC,OAAOa,iBAAiB,MAAM;AACtE,eAAOb,OAAOa;MAChB;IACF;AACA,WAAO,KAAK5D,KAAKkE,iBAAgB;EACnC;EAEA,MAAclB,cAAcD,QAA+C;AACzE,WAAO;MACL,GAAGA;MACHa,cAAcb,OAAOa,gBAAgB;MACrCO,aAAc,MAAM,KAAKpE,MAAMqE,qBAAqBrB,OAAOjC,EAAE,KAAM;IACrE;EACF;EAEA,MAAcoC,aAAaH,QAA6C;AACtE,UAAMsB,UAAU,MAAM,KAAKrB,cAAcD,MAAAA;AACzC,WAAO;MACL,GAAGsB;MACHC,UAAUvB,OAAOuB;MACjB,GAAIvB,OAAOwB,mBAAmBhE,SAAY;QAAEgE,gBAAgBxB,OAAOwB;MAAe,IAAI,CAAC;IACzF;EACF;EAEA,MAAMC,cAAc5D,OAAcN,UAAiC;AACjE,UAAM,KAAKS,iBAAiBH,OAAON,QAAAA;AACnC,WAAO,KAAKP,MAAMyE,cAAclE,QAAAA;EAClC;;;;;;EAOA,MAAMmE,mBAAmB7D,OAAcN,UAAkBoE,WAAkC;AACzF,UAAM,KAAK3D,iBAAiBH,OAAON,QAAAA;AACnC,WAAO,KAAKP,MAAM4E,aAAarE,UAAUoE,SAAAA;EAC3C;;;;;;EAOA,MAAME,WAAWlC,UAAsC;AACrD,UAAMvB,MAAMC,OAAAA;AACZ,UAAM,EAAEyD,YAAYC,QAAO,IAAK,MAAM,KAAK/E,MAAM6E,WAAWlC,UAAUvB,GAAAA;AACtE,QAAI,KAAKlB,UAAUM,QAAW;AAC5B,aAAO;QAAEsE;QAAYC;QAASC,aAAa;QAAMC,aAAa;MAAK;IACrE;AACA,UAAMC,QAAQ,MAAM,KAAKhF,MAAMiF,MAAMxC,UAAUvB,GAAAA;AAC/C,WAAO;MACL0D,YAAYI,MAAMJ;MAClBC;MACAC,aAAaE,MAAMF;MACnBC,aAAaC,MAAMD;IACrB;EACF;;;;;EAMA,MAAcjE,iBAAiBH,OAAcN,UAAiC;AAC5E,UAAM6E,QAAQ,MAAM,KAAKpF,MAAMqF,cAAc9E,QAAAA;AAC7C,QAAI6E,UAAU,MAAM;AAClB,YAAM,IAAIE,kBAAkB,UAAU/E,QAAAA,YAAoB;IAC5D;AACA,QAAI6E,UAAUvE,MAAME,IAAI;AACtB,YAAM,IAAIwE,mBAAmB,iCAAA;IAC/B;EACF;;;;;;EAOA,MAAcvD,mBAAmBnB,OAAckB,YAAmC;AAChF,UAAMqD,QAAQ,MAAM,KAAKpF,MAAMwF,gBAAgBzD,UAAAA;AAC/C,QAAIqD,UAAU,MAAM;AAClB,YAAM,IAAIE,kBAAkB,aAAavD,UAAAA,YAAsB;IACjE;AACA,QAAIqD,UAAUvE,MAAME,IAAI;AACtB,YAAM,IAAIwE,mBAAmB,oCAAA;IAC/B;EACF;;;;;;EAOA,MAAcjD,sBAAsBP,YAAqC;AACvE,UAAMP,QAAQ,MAAM,KAAKxB,MAAMyF,eAAe1D,UAAAA;AAC9C,QAAIP,UAAU,MAAM;AAClB,YAAM,IAAI8D,kBAAkB,aAAavD,UAAAA,8BAAwC;IACnF;AACA,WAAOP;EACT;;EAGA,MAAciB,uBAAuB5B,OAAcW,OAA8B;AAC/E,UAAM4D,QAAQ,MAAM,KAAKpF,MAAM0F,oBAAoBlE,KAAAA;AACnD,QAAI4D,UAAU,MAAM;AAClB,YAAM,IAAIE,kBAAkB,iBAAiB9D,KAAAA,EAAO;IACtD;AACA,QAAI4D,UAAUvE,MAAME,IAAI;AACtB,YAAM,IAAIwE,mBAAmB,8BAAA;IAC/B;EACF;AACF;;;;;;;;;;;;;;;;;AC5TA,SAASI,cAAAA,mBAAkB;;;;;;;;;;;;AAiBpB,IAAMC,2BAAN,MAAMA;SAAAA;;;;EACX,YAA6BC,OAAqB;SAArBA,QAAAA;EAAsB;EAEnD,MAAMC,QAAQC,YAAoBC,MAAkD;AAClF,UAAM,KAAKH,MAAMI,eAAeF,YAAY;MAC1CG,UAAU;MACV,GAAIF,MAAMG,kBAAkBC,SAAY;QAAED,eAAeH,KAAKG;MAAc,IAAI,CAAC;IACnF,CAAA;EACF;EAEA,MAAME,OACJN,YACAC,MACe;AACf,UAAM,KAAKH,MAAMI,eAAeF,YAAY;MAC1CG,UAAU;MACV,GAAIF,MAAMG,kBAAkBC,SAAY;QAAED,eAAeH,KAAKG;MAAc,IAAI,CAAC;MACjF,GAAIH,MAAMM,WAAWF,SAAY;QAAEE,QAAQN,KAAKM;MAAO,IAAI,CAAC;IAC9D,CAAA;EACF;AACF;;;;;;;;;;ACtCA,SACEC,sBAAAA,qBACAC,kBAAAA,iBAEAC,iBAAAA,sBACK;AACP,SAASC,YAAYC,KAAKC,UAAAA,eAAc;;;;;;;;;;;;;;;;;;AAKjC,IAAMC,mBAAN,MAAMA;SAAAA;;;;;EACX,YAC2CC,QACIC,aAC7C;SAFyCD,SAAAA;SACIC,cAAAA;EAC5C;EAGHC,OAA4B;AAC1B,UAAMC,mBAAmB,KAAKF,YAAYE,iBAAgB;AAC1D,WAAO,KAAKH,OAAOE,KAAI,EAAGE,IAAI,CAACC,gBAAgB;MAC7CC,MAAMD,WAAWC;MACjBC,aAAaF,WAAWE,eAAe;MACvC,GAAIF,WAAWC,SAASH,mBAAmB;QAAEK,WAAW;MAAK,IAAI,CAAC;IACpE,EAAA;EACF;AACF;;;;;;;;;;;;;;;;;;;AC1BA,SACEC,sBACAC,0BACAC,iBAAAA,sBAIK;AACP,SACEC,uBAAAA,sBACAC,cAAAA,aACAC,UAAAA,SACAC,2BAAAA,0BAEAC,YAAAA,WACAC,0BACAC,MACAC,KACAC,+BACAC,cACAC,uBACK;AACP,SAASC,uBAAuB;;;;;;;;;;;;;;;;;;AAKzB,IAAMC,+BAA+B,KAAK,OAAO;AAKjD,IAAMC,2CAA8D;EACzE;EACA;EACA;EACA;EACA;EACA;EACA;;AAWK,IAAMC,wBAAN,MAAMA;SAAAA;;;;;;EACX,YAC0CC,SACOC,eAG9BC,SACjB;SALwCF,UAAAA;SACOC,gBAAAA;SAG9BC,UAAAA;EAChB;;;;;;;EAQHC,eAAqB;AACnB,QAAI,KAAKH,QAAQI,aAAaC,WAAW,QAAQ,KAAKH,YAAYI,QAAW;AAC3E,YAAM,IAAIC,MACR,8PAEE;IAEN;EACF;EAEA,MAEMF,OACGG,KACSC,MACY;AAC5B,QAAI,KAAKP,YAAYI,QAAW;AAI9B,YAAM,IAAII,yBAAwB,qDAAA;IACpC;AACA,QAAID,SAASH,QAAW;AACtB,YAAM,IAAIK,qBAAoB,oCAAA;IAChC;AACA,UAAMC,sBACJ,KAAKZ,QAAQI,aAAaQ,uBAAuBd;AACnD,QAAI,CAACc,oBAAoBC,SAASJ,KAAKK,QAAQ,GAAG;AAChD,YAAM,IAAIC,8BACR,iBAAiBN,KAAKK,QAAQ,8BAA8BF,oBAAoBI,KAAK,IAAA,CAAA,GAAQ;IAEjG;AACA,UAAMC,WAAW,KAAKjB,QAAQI,aAAaa,YAAYpB;AACvD,QAAIY,KAAKS,OAAOD,UAAU;AACxB,YAAM,IAAIE,yBAAyB,oBAAoBF,QAAAA,aAAqB;IAC9E;AACA,UAAMG,QAAQ,MAAM,KAAKnB,cAAcoB,QAAQb,GAAAA;AAC/C,WAAO,KAAKN,QAAQoB,MAAM;MACxBC,MAAMd,KAAKe;MACXC,UAAUhB,KAAKiB;MACfC,aAAalB,KAAKK;MAClBc,WAAWnB,KAAKS;MAChBE;IACF,CAAA;EACF;AACF;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC9GA,SACES,wBAAAA,uBAEAC,oBAAAA,yBAGK;AACP,SAASC,MAAMC,cAAAA,aAAYC,OAAAA,MAAKC,UAAAA,SAAQC,OAAOC,QAAAA,OAAMC,OAAAA,MAAKC,WAAW;;;;;;;;;;;;;;;;;;AAmB9D,IAAMC,iBAAN,MAAMA;SAAAA;;;;;EACX,YACmBC,OAC8BC,eAC/C;SAFiBD,QAAAA;SAC8BC,gBAAAA;EAC9C;EAEH,MACMC,KAAYC,KAAqBC,KAAuBC,MAA+B;AAC3F,UAAMC,QAAQ,MAAM,KAAKL,cAAcM,QAAQJ,GAAAA;AAC/C,UAAM,EAAEK,OAAOC,SAAQ,IAAK,MAAM,KAAKT,MAAME,KAAK;MAChDI;MACAI,SAASL,KAAKK;MACd,GAAIL,KAAKI,aAAaE,SAAY;QAAEF,UAAUJ,KAAKI;MAAS,IAAI,CAAC;MACjE,GAAIJ,KAAKL,UAAUW,SAAY;QAAEC,WAAWP,KAAKL;MAAM,IAAI,CAAC;MAC5D,GAAIK,KAAKQ,gBAAgBF,SAAY;QAAEE,aAAaR,KAAKQ;MAAY,IAAI,CAAC;MAC1E,GAAIR,KAAKS,gBAAgBH,SAAY;QAAEG,aAAaT,KAAKS;MAAY,IAAI,CAAC;MAC1E,GAAIT,KAAKU,eAAe,OAAO;QAAEA,YAAY;MAAK,IAAI,CAAC;MACvD,GAAIV,KAAKW,cAAc,OAAO;QAAEA,WAAW;MAAK,IAAI,CAAC;IACvD,CAAA;AACA,UAAM,KAAKC,KAAKb,KAAKI,OAAOC,QAAAA;EAC9B;EAEA,MACMS,OAAuBV,OAAsBJ,KAA8B;AAC/E,UAAM,KAAKa,KAAKb,KAAKI,KAAAA;EACvB;EAEA,MACMW,OAAchB,KAA8BK,OAA8C;AAC9F,UAAMF,QAAQ,MAAM,KAAKL,cAAcM,QAAQJ,GAAAA;AAC/C,UAAM,KAAKH,MAAMmB,OAAOb,OAAOE,KAAAA;AAC/B,WAAO;MAAEY,SAAS;IAAK;EACzB;EAEA,MAAcH,KAAKb,KAAeI,OAAeC,UAAkC;AACjFL,QAAIiB,UAAU,gBAAgB,mBAAA;AAC9BjB,QAAIiB,UAAU,iBAAiB,UAAA;AAC/BjB,QAAIiB,UAAU,cAAc,YAAA;AAC5BjB,QAAIiB,UAAU,kBAAkBb,KAAAA;AAChC,QAAIC,aAAaE,QAAW;AAC1BP,UAAIiB,UAAU,qBAAqBZ,QAAAA;IACrC;AACAL,QAAIkB,MAAM;QAAsBC,KAAKC,UAAU;MAAEhB;MAAOC;IAAS,CAAA,CAAA;;CAAQ;AAIzE,UAAMgB,UAAU,IAAIC,YAAAA;AACpB,QAAIC,SAAS;AACb,QAAI;AACF,uBAAiBC,SAAS,KAAK5B,MAAM6B,UAAUrB,KAAAA,GAAQ;AACrDmB,kBAAUF,QAAQK,OAAOF,OAAO;UAAEV,QAAQ;QAAK,CAAA;AAC/C,YAAIa,UAAUJ,OAAOK,QAAQ,IAAA;AAC7B,eAAOD,YAAY,IAAI;AACrB,gBAAME,OAAON,OAAOO,MAAM,GAAGH,OAAAA;AAC7BJ,mBAASA,OAAOO,MAAMH,UAAU,CAAA;AAChC,cAAIE,KAAKE,SAAS,GAAG;AACnB/B,gBAAIkB,MAAM,SAASW,IAAAA;;CAAU;UAC/B;AACAF,oBAAUJ,OAAOK,QAAQ,IAAA;QAC3B;MACF;AACA,UAAIL,OAAOQ,SAAS,GAAG;AACrB/B,YAAIkB,MAAM,SAASK,MAAAA;;CAAY;MACjC;AACAvB,UAAIkB,MAAM,2BAAA;IACZ,SAASc,OAAO;AAGd,YAAMC,UACJD,iBAAiBE,oBACb;QAAEC,MAAMH,MAAMG;QAAM7B,SAAS0B,MAAM1B;MAAQ,IAC3C;QACE6B,MAAM;QACN7B,SAAS0B,iBAAiBI,QAAQJ,MAAM1B,UAAU;MACpD;AACNN,UAAIkB,MAAM;QAAuBC,KAAKC,UAAUa,OAAAA,CAAAA;;CAAc;IAChE;AACAjC,QAAIqC,IAAG;EACT;AACF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACzGA,SAASC,wBAAAA,6BAAgD;AACzD,SAASC,cAAAA,aAAYC,OAAAA,MAAKC,UAAAA,SAAQC,OAAAA,YAAW;;;;;;;;;;;;;;;;;;AAKtC,IAAMC,kBAAN,MAAMA;SAAAA;;;;;EACX,YACmBC,OAC8BC,eAC/C;SAFiBD,QAAAA;SAC8BC,gBAAAA;EAC9C;EAEH,MACMC,MAAaC,KAAc;AAC/B,UAAMC,QAAQ,MAAM,KAAKH,cAAcI,QAAQF,GAAAA;AAC/C,WAAO,KAAKH,MAAMM,WAAWF,MAAMG,EAAE;EACvC;AACF;;;;;;;;;;;;;;;;;;;;;ACjBA,SAASC,wBAAAA,6BAAgD;AACzD,SAASC,QAAAA,OAAMC,cAAAA,aAAYC,QAAQC,OAAAA,MAAKC,UAAAA,SAAQC,SAAAA,QAAOC,OAAOC,QAAAA,OAAMC,OAAAA,YAAW;;;;;;;;;;;;;;;;;;AAWxE,IAAMC,oBAAN,MAAMA;SAAAA;;;;;EACX,YACmBC,OAC8BC,eAC/C;SAFiBD,QAAAA;SAC8BC,gBAAAA;EAC9C;EAEH,MACMC,KAAYC,KAAc;AAC9B,UAAMC,QAAQ,MAAM,KAAKH,cAAcI,QAAQF,GAAAA;AAC/C,WAAO,KAAKH,MAAMM,YAAYF,MAAMG,EAAE;EACxC;EAEA,MACMC,OAAcL,KAA2BI,IAAY;AACzD,UAAMH,QAAQ,MAAM,KAAKH,cAAcI,QAAQF,GAAAA;AAC/C,WAAO,KAAKH,MAAMS,UAAUL,OAAOG,EAAAA;EACrC;EAEA,MACMG,OAAcP,KAA2BI,IAAsC;AACnF,UAAMH,QAAQ,MAAM,KAAKH,cAAcI,QAAQF,GAAAA;AAC/C,UAAM,KAAKH,MAAMW,aAAaP,OAAOG,EAAAA;AACrC,WAAO;MAAEK,IAAI;IAAK;EACpB;EAEA,MACMC,KAAYV,KAA2BI,IAAgCO,WAAmB;AAC9F,UAAMV,QAAQ,MAAM,KAAKH,cAAcI,QAAQF,GAAAA;AAC/C,WAAO,KAAKH,MAAMe,WAAWX,OAAOG,IAAIO,SAAAA;EAC1C;;;;;;EAOA,MACME,OACGb,KACMI,IACLU,MACkB;AAC1B,UAAMb,QAAQ,MAAM,KAAKH,cAAcI,QAAQF,GAAAA;AAC/C,UAAM,KAAKH,MAAMkB,aAAad,OAAOG,IAAI;MACvC,GAAIU,KAAKE,UAAUC,SAAY;QAAED,OAAOF,KAAKE;MAAM,IAAI,CAAC;MACxD,GAAI,kBAAkBF,OAAO;QAAEI,cAAcJ,KAAKI,gBAAgB;MAAK,IAAI,CAAC;IAC9E,CAAA;AACA,WAAO;MAAET,IAAI;IAAK;EACpB;EAEA,MACMU,QAAenB,KAA2BI,IAAsC;AACpF,UAAMH,QAAQ,MAAM,KAAKH,cAAcI,QAAQF,GAAAA;AAC/C,UAAM,KAAKH,MAAMuB,cAAcnB,OAAOG,EAAAA;AACtC,WAAO;MAAEK,IAAI;IAAK;EACpB;EAEA,MACMY,aACGrB,KACMI,IACOO,WACM;AAC1B,UAAMV,QAAQ,MAAM,KAAKH,cAAcI,QAAQF,GAAAA;AAC/C,UAAM,KAAKH,MAAMyB,mBAAmBrB,OAAOG,IAAIO,SAAAA;AAC/C,WAAO;MAAEF,IAAI;IAAK;EACpB;AACF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC/EA,SAASc,wBAAAA,6BAAgD;AACzD,SAASC,QAAAA,OAAMC,cAAAA,aAAYC,UAAAA,UAAQC,QAAAA,OAAMC,OAAAA,YAAW;;;;;;;;;;;;;;;;;;AAY7C,IAAMC,qBAAN,MAAMA;SAAAA;;;;;EACX,YACmBC,OAC8BC,eAC/C;SAFiBD,QAAAA;SAC8BC,gBAAAA;EAC9C;EAEH,MACMC,QAAeC,KAAsBC,MAA6C;AACtF,UAAMC,QAAQ,MAAM,KAAKJ,cAAcK,QAAQH,GAAAA;AAC/C,UAAM,KAAKH,MAAME,QAAQG,OAAOD,KAAKG,UAAU;AAC/C,WAAO;MAAEC,IAAI;IAAK;EACpB;EAEA,MACMC,OAAcN,KAAsBC,MAA4C;AACpF,UAAMC,QAAQ,MAAM,KAAKJ,cAAcK,QAAQH,GAAAA;AAC/C,UAAM,KAAKH,MAAMS,OAAOJ,OAAOD,KAAKG,YAAYH,KAAKM,MAAM;AAC3D,WAAO;MAAEF,IAAI;IAAK;EACpB;AACF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AChCA,SACEG,6BAAAA,4BACAC,kBAAAA,iBAEAC,iBAAAA,sBAIK;AACP,SAASC,UAAAA,UAAQC,cAAAA,aAAYC,UAAAA,eAAiC;AAC9D,SAASC,kBAAkBC,uBAAuB;;;ACVlD,OAAO;AAgCA,IAAMC,iBAAiBC,OAAOC,IAAI,uCAAA;AAelC,SAASC,kBAAkBC,QAAuB;AACvD,SAAOC,QAAQC,YAAYC,gBAAgBH,MAAAA;AAC7C;AAFgBD;;;AC/ChB,OAAO;AAQA,IAAMK,yBAAyBC,OAAOC,IAAI,sCAAA;AAQ1C,IAAMC,qCAAqCF,OAAOC,IACvD,kDAAA;;;;;;;;;;;;;;;;;;;;AFOK,IAAME,wBAAN,MAAMA,uBAAAA;SAAAA;;;;;;;EACMC,SAAS,IAAIC,QAAOF,uBAAsBG,IAAI;EAE/D,YACmBC,WACAC,SACwBC,UACWC,cACpD;SAJiBH,YAAAA;SACAC,UAAAA;SACwBC,WAAAA;SACWC,eAAAA;EACnD;EAEHC,eAAqB;AACnB,eAAWC,WAAW,KAAKL,UAAUM,aAAY,GAAI;AACnD,YAAMC,WAAWF,QAAQE;AACzB,UAAIA,aAAa,QAAQ,OAAOA,aAAa,UAAU;AACrD;MACF;AACA,YAAMC,OAAOC,kBAAkBF,SAAS,WAAW;AACnD,UAAIC,SAASE,QAAW;AACtB,aAAKR,SAASS,SAAS,KAAKC,eAAeL,UAAUC,IAAAA,CAAAA;MACvD;AACA,WAAKK,oBAAoBN,QAAAA;IAC3B;EACF;;EAGQK,eAAeL,UAAkBC,MAAqC;AAC5E,UAAMM,eAAe,KAAKC,WAAWR,UAAUS,sBAAAA;AAC/C,UAAMC,eACJH,iBAAiBJ,SACb,CAACQ,QAAuBJ,aAAaI,GAAAA,IACpCV,KAAKS,gBAAgB;AAC5B,WAAO;MACLlB,MAAMS,KAAKT;MACX,GAAIS,KAAKW,gBAAgBT,SAAY;QAAES,aAAaX,KAAKW;MAAY,IAAI,CAAC;MAC1EF;MACA,GAAIT,KAAKY,UAAUV,SAAY;QAAEU,OAAOZ,KAAKY;MAAM,IAAI,CAAC;MACxD,GAAIZ,KAAKa,UAAUX,SAAY;QAAEY,SAASd,KAAKa;MAAM,IAAI,CAAC;MAC1D,GAAIb,KAAKe,aAAab,SAAY;QAAEa,UAAUf,KAAKe;MAAS,IAAI,CAAC;MACjE,GAAIf,KAAKgB,YAAYd,SAAY;QAAEe,aAAa,KAAKC,aAAalB,IAAAA;MAAM,IAAI,CAAC;IAC/E;EACF;;EAGQkB,aAAalB,MAA8B;AACjD,UAAMmB,QAAkB,CAAA;AACxB,eAAWC,UAAUpB,KAAKgB,WAAW,CAAA,GAAI;AACvC,YAAMK,aAAapB,kBAAkBmB,MAAAA;AACrC,UAAIC,eAAenB,QAAW;AAC5B,aAAKb,OAAOiC,KACV,UAAUtB,KAAKT,IAAI,kBAAkB6B,OAAO7B,IAAI,0CAAqC;AAEvF;MACF;AACA4B,YAAMI,KAAKF,WAAW9B,IAAI;IAC5B;AACA,WAAO4B;EACT;;EAGQd,oBAAoBN,UAAwB;AAClD,UAAMyB,YAAYC,OAAOC,eAAe3B,QAAAA;AACxC,eAAWR,QAAQ,KAAKE,QAAQkC,kBAAkBH,SAAAA,GAAY;AAC5D,UAAII,QAAQC,YAAYC,oCAAoCN,WAAWjC,IAAAA,MAAU,MAAM;AACrF,cAAMwC,SAAS,KAAKC,YAAYjC,UAAUR,IAAAA;AAC1C,YAAIwC,WAAW7B,QAAW;AACxB,eAAKP,aAAa4B,KAChB,CAACb,QAAuBqB,OAAOrB,GAAAA,CAAAA;QAEnC;MACF;IACF;EACF;;EAGQH,WACNR,UACAkC,aAC+C;AAC/C,UAAMT,YAAYC,OAAOC,eAAe3B,QAAAA;AACxC,eAAWR,QAAQ,KAAKE,QAAQkC,kBAAkBH,SAAAA,GAAY;AAC5D,UAAII,QAAQC,YAAYI,aAAaT,WAAWjC,IAAAA,MAAU,MAAM;AAC9D,eAAO,KAAKyC,YAAYjC,UAAUR,IAAAA;MACpC;IACF;AACA,WAAOW;EACT;;EAGQ8B,YACNjC,UACAR,MAC+C;AAC/C,UAAM2C,YAAanC,SAAqCR,IAAAA;AACxD,QAAI,OAAO2C,cAAc,YAAY;AACnC,aAAOhC;IACT;AACA,WAAO,CAACQ,QACLwB,UAA8CC,KAAKpC,UAAUW,GAAAA;EAClE;AACF;;;;;;;;;;;;;;;AG3HA,SACE0B,iBAAAA,gBACAC,kBAAAA,iBACAC,uBAAAA,4BAIK;AACP,SAASC,UAAAA,UAAQC,cAAAA,aAAYC,UAAAA,eAA2C;AACxE,SAASC,oBAAAA,yBAAwB;AACjC,SAASC,SAAS;;;ACVlB,OAAO;AAGA,IAAMC,mBAAmBC,OAAO,sBAAA;AA0ChC,SAASC,mBAAmBC,QAAc;AAC/C,SAAOC,QAAQC,YAAYC,kBAAkBH,OAAO,WAAW;AACjE;AAFgBD;;;ACtCT,IAAMK,mBAAmBC,OAAOC,IAAI,wCAAA;AAkBpC,SAASC,wBAAwBC,OAAa;AACnD,SAAOC,oBAAoBD,SAAS,UAAUA,SAAS,aAAaA;AACtE;AAFgBD;;;;;;;;;;;;;;;;;;;;AFPT,IAAMG,yBAAN,MAAMA,wBAAAA;SAAAA;;;;;;;EACMC,SAAS,IAAIC,QAAOF,wBAAuBG,IAAI;EAEhE,YACmBC,WAC6BC,UACLC,QACDC,SACxC;SAJiBH,YAAAA;SAC6BC,WAAAA;SACLC,SAAAA;SACDC,UAAAA;EACvC;EAEHC,yBAA+B;AAC7B,QAAIC,QAAQ;AACZ,QAAIC,aAAa;AACjB,eAAWC,WAAW,KAAKP,UAAUQ,aAAY,GAAI;AACnD,YAAMC,WAAWF,QAAQE;AACzB,UAAIA,aAAa,QAAQA,aAAaC,UAAa,OAAOD,aAAa,UAAU;AAC/E;MACF;AAEA,UAAIE,wBAAwBF,QAAAA,GAAW;AACrC,YAAI,KAAKG,uBAAuBH,QAAAA,GAAW;AACzCH,wBAAc;QAChB;AACA;MACF;AACA,YAAMO,OAAOC,mBAAmBL,QAAAA;AAChC,UAAII,SAASH,QAAW;AACtB;MACF;AACA,YAAMK,UAAUN;AAChB,UAAI,OAAOM,QAAQC,YAAY,YAAY;AACzC,aAAKnB,OAAOoB,KAAK,YAAYJ,KAAKd,IAAI,0CAAqC;AAC3E;MACF;AACA,WAAKE,SAASiB,SACZ;QACEnB,MAAMc,KAAKd;QACXoB,MAAMN,KAAKM;QACXC,aAAaP,KAAKO;QAClBC,aAAaR,KAAKS;;;QAGlB,GAAIT,KAAKU,UAAUb,SAAY;UAAEa,OAAOV,KAAKU;QAAM,IAAI,CAAC;QACxD,GAAIV,KAAKW,YAAYd,SAAY;UAAEc,SAASX,KAAKW;QAAQ,IAAI,CAAC;MAChE,GACA;QAAER,SAAS,wBAACM,OAAOG,QAAShB,SAAyBO,QAAQM,OAAOG,GAAAA,GAAzD;MAA8D,CAAA;AAE3EpB,eAAS;IACX;AAGA,eAAWqB,QAAQ,KAAKvB,QAAQwB,SAAS,CAAA,GAAI;AAC3C,UAAI,KAAKf,uBAAuBc,IAAAA,GAAO;AACrCpB,sBAAc;MAChB;IACF;AAGA,QAAIsB,YAAY;AAChB,eAAWC,cAAc,KAAK3B,OAAO4B,KAAI,GAAI;AAC3C,iBAAWC,UAAUF,WAAWG,eAAe,CAAA,GAAI;AACjD,cAAMC,mBAAmB,KAAK/B,OAAOgC,IAAIH,MAAAA;AAIzC,YAAIE,qBAAqBvB,QAAW;AAClC,gBAAM,IAAIyB,MACR,UAAUN,WAAW9B,IAAI,mBAAmBgC,MAAAA,6FAAmG;QAEnJ;AACA,cAAMhC,OAAOqC,iBAAiBL,MAAAA;AAC9B,YAAI,KAAK9B,SAASoC,IAAItC,IAAAA,GAAO;AAC3B;QACF;AAGA,cAAMuC,cACJ,OAAOL,iBAAiBM,iBAAiB,WACrC,WAAWN,iBAAiBM,YAAY,KACxC;AACN,aAAKtC,SAASiB;UACZ;YACEnB;YACAoB,MAAM;YACNqB,aAAaT;YACbX,aAAa,2BAA2BW,MAAAA,8BAAoCO,WAAAA;YAC5EjB,aAAaoB,EAAEC,OAAO;cAAEC,MAAMF,EAAEG,OAAM;YAAG,CAAA;UAC3C;;UAEA;YAAE5B,SAAS,oCAAa,CAAC,IAAd;UAAiB;QAAA;AAE9BY,qBAAa;MACf;IACF;AACA,SAAK/B,OAAOgD,IACV,cAAcxC,KAAAA,gBAAqBC,UAAAA,2BAAqCsB,SAAAA,mBAA4B;EAExG;;;;;EAMQhB,uBAAuBc,MAA+B;AAC5D,QAAI,KAAKzB,SAASoC,IAAIX,KAAKoB,KAAK/C,IAAI,GAAG;AACrC,WAAKF,OAAOoB,KACV,oBAAoBS,KAAKoB,KAAK/C,IAAI,+CAA0C;AAE9E,aAAO;IACT;AACA,SAAKE,SAASiB,SAASQ,KAAKoB,MAAMpB,KAAKX,OAAO;AAC9C,WAAO;EACT;AACF;;;;;;;;;;;;;;;;AG1HO,IAAMgC,mBAAN,MAAMA;EAPb,OAOaA;;;;;EACX,YACmBC,OACAC,aACjB;SAFiBD,QAAAA;SACAC,cAAAA;EAChB;EAEH,MAAMC,MAAMC,UAAkBC,KAAkC;AAC9D,UAAM,EAAEC,WAAU,IAAK,MAAM,KAAKL,MAAMM,WAAWH,UAAUC,GAAAA;AAC7D,WAAO;MACLC;MACAJ,aAAa,KAAKA;MAClBM,aAAaF,aAAa,KAAKJ;IACjC;EACF;EAEA,MAAMO,OAAsB;EAE5B;AACF;;;AC3BA,SACEC,sBAAAA,qBACAC,eAAAA,cAOAC,sBAAAA,qBACAC,yBAAAA,wBACAC,gBAAAA,qBACK;AACP,SAASC,UAAAA,UAAQC,cAAAA,aAAYC,UAAAA,eAAc;;;;;;;;;;;;;;;;;;AAYpC,IAAMC,oBAAN,MAAMA,mBAAAA;SAAAA;;;;;EACMC,SAAS,IAAIC,QAAOF,mBAAkBG,IAAI;EAC1CC,UAAU,oBAAIC,IAAAA;EAE/B,YAC+CC,SACPC,OACtC;SAF6CD,UAAAA;SACPC,QAAAA;EACrC;EAEH,MAAMC,MAAMC,OAAkD;AAC5D,UAAMC,QAAQC,OAAOC,WAAU;AAC/B,UAAMC,MAAMJ,MAAMI,OAAOC,OAAAA;AACzB,UAAMC,OAAO,KAAKT,QAAQU,SAASP,MAAMQ,SAAS;AAClD,UAAMC,QAAQ,KAAKC,cAAcT,OAAOK,MAAMN,MAAMW,OAAOP,GAAAA;AAE3D,SAAKQ,cAAa;MAAE,GAAGN;MAAMF;IAAI,GAAGJ,OAAOS,KAAAA,EACxCI,KAAK,MAAM,KAAKf,MAAMgB,gBAAgBd,MAAMe,UAAU,IAAA,CAAA,EACtDC,MAAM,OAAOC,UAAAA;AACZ,YAAMC,UAAUD,iBAAiBE,QAAQF,MAAMC,UAAUE,OAAOH,KAAAA;AAChE,YAAMI,OAAOJ,iBAAiBK,sBAAqB,mBAAmB;AACtE,WAAK9B,OAAOyB,MAAM,aAAahB,KAAAA,YAAiBoB,IAAAA,MAAUH,OAAAA,EAAS;AACnEK,MAAAA,uBAAsB;QAAEtB;QAAOoB;QAAMH;MAAQ,CAAA;AAG7C,YAAM,KAAKpB,MAAM0B,eAAe;QAC9BvB;QACAwB,QAAQ;QACRC,WAAWL;QACXM,cAAcT;MAChB,CAAA;AAEA,YAAM,KAAKpB,MAAMgB,gBAAgBd,MAAMe,UAAU,IAAA;AAGjD,YAAMa,SAAS,MAAMtB,KAAKuB,KAAKC,KAAK7B,KAAAA;AACpC,YAAM2B,OAAOG,KAAK;QAAEV;QAAMH;MAAQ,CAAA;IACpC,CAAA;AAEF,WAAO;MAAEjB;IAAM;EACjB;EAEA,MAAM+B,OAAO/B,OAAegC,YAAoBC,UAAmC;AACjF,UAAMC,MAAM,GAAGlC,KAAAA,IAASgC,UAAAA;AACxB,UAAMG,UAAU,KAAKzC,QAAQ0C,IAAIF,GAAAA;AACjC,QAAIC,YAAYE,QAAW;AACzB,WAAK3C,QAAQ4C,OAAOJ,GAAAA;AACpBC,cAAQF,QAAAA;IACV;EACF;EAEA,MAAMM,OAAOvC,OAA8B;AACzC,UAAMK,OAAO,KAAKT,QAAQU,SAAQ;AAClC,UAAMqB,SAAS,MAAMtB,KAAKuB,KAAKC,KAAK7B,KAAAA;AACpC,UAAM2B,OAAOa,IAAG;EAClB;EAEQ/B,cAAcT,OAAeK,MAAiBK,OAAcP,KAA6B;AAC/F,WAAO;MACLH;MACAyC,UAAU,6BAAMpC,KAAKuB,KAAKC,KAAK7B,KAAAA,GAArB;MACV0C,eAAe,wBAACC,SACd,IAAIC,QAAkB,CAACT,YAAAA;AACrB,aAAKzC,QAAQmD,IAAI,GAAG7C,KAAAA,IAAS2C,KAAKG,EAAE,IAAIX,OAAAA;MAC1C,CAAA,GAHa;MAIfY,MAAM,wBAACC,OAAOC,OAAOA,GAAAA,GAAf;MACNC,UAAU,wBAAC3C,WAAW4C,SAAS,KAAKC,UAAU7C,WAAW4C,MAAMzC,OAAOP,KAAK,GAAGH,KAAAA,GAApE;IACZ;EACF;;;;;;EAOA,MAAcoD,UACZ7C,WACA4C,MACAzC,OACAP,KACAkD,OACAC,WAC2B;AAC3B,UAAMC,YAAY,MAAM,KAAK1D,MAAM2D,aAAa;MAAE9C;MAAO+C,WAAW;IAAK,CAAA;AACzE,UAAMzD,QAAQC,OAAOC,WAAU;AAG/B,UAAM,KAAKL,MAAMgB,gBAAgB0C,UAAUT,IAAI9C,KAAAA;AAC/C,UAAMK,OAAO,KAAKT,QAAQU,SAASC,SAAAA;AACnC,UAAMC,QAAwB;MAC5BR;;MAEAyC,UAAU,mCAAYiB,gBAAgB,MAAMrD,KAAKuB,KAAKC,KAAKyB,SAAAA,CAAAA,GAAjD;MACVZ,eAAe,wBAACC,SACd,IAAIC,QAAkB,CAACT,YAAAA;AACrB,aAAKzC,QAAQmD,IAAI,GAAG7C,KAAAA,IAAS2C,KAAKG,EAAE,IAAIX,OAAAA;MAC1C,CAAA,GAHa;MAIfY,MAAM,wBAACC,OAAOC,OAAOA,GAAAA,GAAf;MACNC,UAAU,wBAACS,WAAWC,cACpB,KAAKR,UAAUO,WAAWC,WAAWlD,OAAOP,KAAKkD,QAAQ,GAAGC,SAAAA,GADpD;IAEZ;AACA,QAAI;AACF,aAAO,MAAM3C,cACX;QAAE,GAAGN;QAAMF;MAAI,GACf;QACEW,UAAUyC,UAAUT;QACpBpC;QACAmD,UAAUV;QACV5C;QACAJ;QACA2D,iBAAiBT;QACjBC;MACF,GACA9C,KAAAA;IAEJ,UAAA;AAGE,YAAM,KAAKX,MAAMgB,gBAAgB0C,UAAUT,IAAI,IAAA;IACjD;EACF;AACF;;;;;;;;;;;;;;;;;;;;AjBlGA,IAAMiB,eAAe;AAOrB,SAASC,gBAAgBC,SAAkBC,cAAqB;AAC9D,QAAMC,YAAwB;IAC5B;MAAEC,SAASC;MAAqBC,YAAY,6BAAM,IAAIC,cAAAA,GAAV;IAAyB;;IAErE;MAAEH,SAASI;MAAgBF,YAAY,6BAAM,IAAIG,eAAAA,GAAV;IAA0B;;IAEjE;MAAEL,SAASM;MAA2BJ,YAAY,6BAAM,CAAA,GAAN;IAAS;IAC3D;MACEF,SAASO;MACTL,YAAY,wBAACM,YAAgCA,QAAQC,QAAQ,IAAIC,yBAAAA,GAArD;MACZC,QAAQ;QAACC;;IACX;IACA;MACEZ,SAASa;MACTX,YAAY,wBAACM,YACXA,QAAQM,eAAe,IAAIC,mBAAmBP,QAAQQ,YAAY,GADxD;MAEZL,QAAQ;QAACC;;IACX;IACA;MACEZ,SAASiB;MACTf,YAAY,wBAACM,YAAgCA,QAAQU,eAAzC;MACZP,QAAQ;QAACC;;IACX;IACA;MACEZ,SAASmB;MACTjB,YAAY,wBAACkB,MAA0BA,EAAEC,OAA7B;MACZV,QAAQ;QAACC;;IACX;IACA;;;;MAIEZ,SAASsB;MACTpB,YAAY,wBAACkB,GAAuBG,UAClCH,EAAEI,UACDJ,EAAEK,qBAAqBC,SACpB,IAAIC,iBAAiBJ,OAAOH,EAAEK,gBAAgB,IAC9CC,SAJM;MAKZf,QAAQ;QAACC;QAAegB;;IAC1B;IACAC;IACA;MAAE7B,SAAS8B;MAAoBC,aAAaF;IAAiB;;;IAG7DG;IACAC;IACAC;IACAC;;;IAGAC;IACA;MAAEpC,SAASqC;MAAqBN,aAAaK;IAAyB;;AAExE,MAAItC,cAAc;AAChBC,cAAUuC,KAAK;MACbtC,SAAS4B;MACT1B,YAAY,wBAACkB,MAA0BA,EAAEG,OAA7B;MACZZ,QAAQ;QAACC;;IACX,CAAA;EACF;AACA,MAAIf,SAAS;AAGXE,cAAUuC,KAAK;MACbtC,SAASuC;MACTrC,YAAY,wBAACsC,kBAAAA;AACX,YAAIA,kBAAkBd,QAAW;AAC/B,gBAAM,IAAIe,MACR,8KACE;QAEN;AACA,eAAOD;MACT,GARY;MASZ7B,QAAQ;QAAC;UAAE+B,OAAOC;UAAsBC,UAAU;QAAK;;IACzD,CAAA;EACF,OAAO;AACL7C,cAAUuC,KAAK;MAAEtC,SAASuC;MAAcR,aAAaG;IAAkB,CAAA;EACzE;AACA,SAAOnC;AACT;AAhFSH;AAsFT,SAASiD,WAAW/C,cAAqB;AACvC,SAAO;IACLc;IACAX;IACAG;IACAG;IACAM;IACAI;IACAE;OACIrB,eAAe;MAAC8B;QAAe,CAAA;IACnCN;IACAhB;IACAwB;IACAD;IACAM;IACAD;IACAG;;AAEJ;AAlBSQ;AAoBT,IAAMC,mBAAmB;EACvBC;EACAC;EACAC;EACAC;EACAC;;AAIF,IAAMC,wBAAwB;KAAIN;EAAkBO;;AAGpD,SAASC,eAAeC,kBAAyB;AAC/C,SAAOA,mBAAmB;OAAIT;IAAkBO;MAAyBP;AAC3E;AAFSQ;AAYT,IAAME,kBAAkB;AAcxB,SAASC,YAAYC,QAAuC;AAC1D,QAAMC,WAAWD,UAAU,CAAA;AAC3B,aAAWE,cAAcR,uBAAuB;AAC9CS,YAAQC,eAAeN,iBAAiBG,UAAUC,UAAAA;EACpD;AACF;AALSH;AAQT,SAASM,eAAeL,QAAuC;AAC7D,SAAO;OAAI,IAAIM,IAAIN,UAAU,CAAA,CAAE;;AACjC;AAFSK;AAKT,SAASE,UAAUC,MAAY;AAC7B,SAAOC,aAAaC,SAAS;IAAC;MAAEF;MAAMG,QAAQC;IAAY;GAAE;AAC9D;AAFSL;AAUT,SAASM,qCAAqCC,iBAA0B3E,SAAgB;AACtF,MAAI2E,mBAAmB,CAAC3E,SAAS;AAC/B,UAAM,IAAI4C,MACR,mKACE;EAEN;AACF;AAPS8B;AAWF,IAAMD,cAAN,MAAMA,aAAAA;SAAAA;;;EACX,OAAOG,QAAQjE,SAA4C;AACzD+D,yCACE/D,QAAQgE,mBAAmB,OAC3BhE,QAAQX,WAAW,KAAA;AAErB,UAAMqE,OAAO1D,QAAQ0D,QAAQvE;AAE7B,UAAMG,eAAeU,QAAQe,UAAUG;AACvC+B,gBAAYjD,QAAQkD,MAAM;AAC1B,WAAO;MACLW,QAAQC;MACRI,QAAQ;MACRC,SAAS;QAACC;QAAiBX,UAAUC,IAAAA;;MACrCW,aAAavB,eAAe9C,QAAQsE,aAAaC,WAAW,IAAA;MAC5DhF,WAAW;QACT;UAAEC,SAASY;UAAeoE,UAAUxE;QAAQ;WACzCZ,gBAAgBY,QAAQX,WAAW,OAAOC,YAAAA;WAC1CiE,eAAevD,QAAQkD,MAAM;;MAElCuB,SAASpC,WAAW/C,YAAAA;IACtB;EACF;EAEA,OAAOoF,aAAa1E,SAAiD;AACnE+D,yCACE/D,QAAQgE,mBAAmB,OAC3BhE,QAAQX,WAAW,KAAA;AAErB,UAAMqE,OAAO1D,QAAQ0D,QAAQvE;AAK7B,UAAMG,eAAeU,QAAQ2E,kBAAkB;AAC/C1B,gBAAYjD,QAAQkD,MAAM;AAC1B,WAAO;MACLW,QAAQC;MACRI,QAAQ;MACRC,SAAS;QAACC;QAAiBX,UAAUC,IAAAA;WAAW1D,QAAQmE,WAAW,CAAA;;MACnEE,aAAavB,eAAe9C,QAAQ4E,sBAAsB,IAAA;MAC1DrF,WAAW;QACT;UACEC,SAASY;;;;;UAKTV,YAAY,iCAAUmF,UAAmB;YACvC,GAAI,MAAM7E,QAAQN,WAAU,GAAImF,IAAAA;YAChCxF,SAASW,QAAQX,WAAW;YAC5B,GAAIW,QAAQgE,oBAAoB9C,SAC5B;cAAE8C,iBAAiBhE,QAAQgE;YAAgB,IAC3C,CAAC;UACP,IANY;UAOZ7D,QAAQH,QAAQG,UAAU,CAAA;QAC5B;WACGf,gBAAgBY,QAAQX,WAAW,OAAOC,YAAAA;WAC1CiE,eAAevD,QAAQkD,MAAM;;MAElCuB,SAASpC,WAAW/C,YAAAA;IACtB;EACF;AACF;;;;;;;AkBvRO,SAASwF,aAAaC,SAA2B;AACtD,SAAO;IAACC,YAAYC,QAAQ;MAAE,GAAGF;MAASG,SAAS;IAAK,CAAA;IAAIC,mBAAmBF,QAAO;;AACxF;AAFgBH;","names":["AGENT_DEPS_FACTORY","AGENT_STORE","QuotaExceededError","publishAgentRunFailed","runAgentLoop","Workflow","isWorkflowControlFlowSignal","Inject","Injectable","utcDay","date","Date","toISOString","slice","childSinkWriter","writer","write","chunk","end","fail","AGENT_DEPS_FACTORY","traceLlmTurn","traceToolExecution","withToolTimeout","Step","Inject","Injectable","AgentRunSteps","factory","llm","input","deps","forAgent","agentName","tools","registry","definitionsFor","actor","rolesPolicy","toolAllowList","opened","sink","open","sinkRunId","writer","childSink","childSinkWriter","traceLlmTurn","runId","step","model","runTurn","system","messages","tool","ctx","traceToolExecution","toolCallId","toolName","toolType","invocation","invoke","timeoutMs","undefined","withToolTimeout","retries","AGENT_DISPATCHED_STEPS","Symbol","for","AgentRunWorkflow","factory","store","steps","dispatchedSteps","run","ctx","input","day","utcDay","deps","forAgent","agentName","sinkRunId","undefined","localStep","setActiveStream","threadId","runId","hooks","openSink","childSinkWriter","sink","open","awaitApproval","call","waitForSignal","id","step","name","fn","isControlFlowError","error","isWorkflowControlFlowSignal","runAgent","task","subThreadId","thread","createThread","actor","transient","child","userText","delegationDepth","dispatchLlm","index","envelope","llm","childSink","dispatchTool","tool","toolCallId","toolType","kind","result","runAgentLoop","message","Error","String","code","QuotaExceededError","publishAgentRunFailed","recordRunEnd","status","errorCode","errorMessage","Promise","resolve","writer","fail","version","randomUUID","WorkflowService","isWorkflowControlFlowSignal","Injectable","DurableAgentRunner","workflows","start","input","stamped","day","utcDay","runId","randomUUID","AgentRunWorkflow","error","isWorkflowControlFlowSignal","signal","toolCallId","decision","cancel","_runId","Promise","resolve","AGENT_DURABLE_RUNNER","AGENT_OPTIONS","AGENT_SINK","Global","Logger","Module","AgentStreamError","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","logger","Logger","AgentDurableModule","forRoot","module","global","providers","AgentRunWorkflow","AgentRunSteps","DurableAgentRunner","provide","AGENT_DURABLE_RUNNER","useExisting","AGENT_DISPATCHED_STEPS","useFactory","options","sink","enabled","durable","dispatchedSteps","InProcessTokenStreamSink","warn","inject","AGENT_OPTIONS","AGENT_SINK","exports","AGENT_ACTOR_RESOLVER","AGENT_APPROVAL_PORT","AGENT_DEPS_FACTORY","AGENT_DURABLE_RUNNER","AGENT_MODEL","AGENT_OPTIONS","AGENT_PROMPT_CONTRIBUTORS","AGENT_QUOTA_STORE","AGENT_REGISTRY","AGENT_ROLES_POLICY","AGENT_RUNNER","AGENT_SINK","AGENT_STORE","AGENT_TOOL_REGISTRY","AgentRegistry","DefaultRolesPolicy","ToolRegistry","Global","Module","DiscoveryModule","RouterModule","AGENT_MODEL","AGENT_PRICING_STORE","AGENT_PROMPT_CONTRIBUTORS","AGENT_QUOTA_STORE","AGENT_REGISTRY","AGENT_ROLES_POLICY","AGENT_SINK","AGENT_STORE","AGENT_TOOL_REGISTRY","AgentRegistry","ToolRegistry","AGENT_OPTIONS","Inject","Injectable","Optional","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","mode","retriever","topK","retrievalTopK","followUps","count","AGENT_DEPS_FACTORY","AGENT_QUOTA_STORE","AGENT_RUNNER","AGENT_STORE","BadRequestException","ForbiddenException","Inject","Injectable","NotFoundException","NotImplementedException","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","Injectable","AgentApprovalPortAdapter","agent","approve","toolCallId","opts","signalToolCall","approved","executedByRef","undefined","reject","reason","AGENT_DEPS_FACTORY","AGENT_REGISTRY","AgentRegistry","Controller","Get","Inject","AgentsController","agents","depsFactory","list","defaultAgentName","map","definition","name","description","isDefault","AGENT_ACTOR_RESOLVER","AGENT_ATTACHMENT_STAGING","AGENT_OPTIONS","BadRequestException","Controller","Inject","NotImplementedException","Optional","PayloadTooLargeException","Post","Req","UnsupportedMediaTypeException","UploadedFile","UseInterceptors","FileInterceptor","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","AGENT_ACTOR_RESOLVER","AgentStreamError","Body","Controller","Get","Inject","Param","Post","Req","Res","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","AGENT_ACTOR_RESOLVER","Controller","Get","Inject","Req","QuotaController","agent","actorResolver","today","req","actor","resolve","quotaToday","id","AGENT_ACTOR_RESOLVER","Body","Controller","Delete","Get","Inject","Param","Patch","Post","Req","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","AGENT_ACTOR_RESOLVER","Body","Controller","Inject","Post","Req","ToolCallController","agent","actorResolver","approve","req","body","actor","resolve","toolCallId","ok","reject","reason","AGENT_PROMPT_CONTRIBUTORS","AGENT_REGISTRY","AgentRegistry","Inject","Injectable","Logger","DiscoveryService","MetadataScanner","AGENT_METADATA","Symbol","for","readAgentMetadata","target","Reflect","getMetadata","AGENT_METADATA","SYSTEM_PROMPT_METADATA","Symbol","for","SYSTEM_PROMPT_CONTRIBUTOR_METADATA","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","AGENT_OPTIONS","AGENT_REGISTRY","AGENT_TOOL_REGISTRY","Inject","Injectable","Logger","DiscoveryService","z","AI_TOOL_METADATA","Symbol","readAiToolMetadata","target","Reflect","getMetadata","AI_TOOL_METADATA","AGENT_TOOL_BRAND","Symbol","for","isBrandedFunctionalTool","value","AGENT_TOOL_BRAND","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","LedgerQuotaStore","store","limitTokens","check","actorRef","day","usedTokens","quotaToday","withinLimit","bump","AGENT_DEPS_FACTORY","AGENT_STORE","QuotaExceededError","publishAgentRunFailed","runAgentLoop","Inject","Injectable","Logger","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","agentDurable","options","AgentModule","forRoot","durable","AgentDurableModule"]}
1
+ {"version":3,"sources":["../../src/durable/agent-run.workflow.ts","../../src/agent-deps.ts","../../src/durable/agent-run.steps.ts","../../src/durable/dispatched-steps.token.ts","../../src/durable/durable-agent-runner.ts","../../src/durable/agent-durable.module.ts","../../src/in-process-sink.ts","../../src/agent.module.ts","../../src/agent-deps.factory.ts","../../src/agent.service.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/ledger-quota-store.ts","../../src/runner/inline-agent-runner.ts","../../src/durable/agent-durable.ts"],"sourcesContent":["import {\n AGENT_DEPS_FACTORY,\n AGENT_STORE,\n type AgentLoopHooks,\n type AgentRunInput,\n type AgentStore,\n type Decision,\n type LlmStepEnvelope,\n QuotaExceededError,\n type ToolCallRequest,\n type ToolStepEnvelope,\n publishAgentRunFailed,\n runAgentLoop,\n} from '@dudousxd/nestjs-agent-core';\nimport { Workflow } from '@dudousxd/nestjs-durable';\nimport { type WorkflowCtx, isWorkflowControlFlowSignal } from '@dudousxd/nestjs-durable-core';\nimport { Inject, Injectable } from '@nestjs/common';\nimport type { AgentDepsFactory } from '../agent-deps.factory.js';\nimport { childSinkWriter, utcDay } from '../agent-deps.js';\nimport { AgentRunSteps } from './agent-run.steps.js';\nimport { AGENT_DISPATCHED_STEPS } from './dispatched-steps.token.js';\n\n/**\n * The agent turn AS a durable workflow. Persist/stream checkpoints are `ctx.localStep`s — the\n * in-process primitive, NOT the always-dispatched `ctx.step`: their names are dynamic checkpoint\n * identities (`persist:toolcall:<id>`), not routable worker groups, and their deps (store, sink)\n * live in THIS workflow worker's DI. The two LONG steps (model call, tool execution) are dispatched\n * through `AgentRunSteps` by default (`AGENT_DISPATCHED_STEPS`, ON under `durable: true`) so the\n * run isn't pinned to this pod while they execute; `dispatchedSteps: false` keeps them localSteps\n * too. HITL is `ctx.waitForSignal`, and sub-agent delegation is `ctx.child(AgentRunWorkflow)` — a\n * replay-safe, observable child run (it shows up as a node in the durable dashboard). A child\n * streams into its top-level ancestor's sink (`sinkRunId`) so the human watching the parent sees it\n * and can approve its action tools; the approval routes to the child's own run via `runForToolCall`.\n */\n@Injectable()\n@Workflow({ name: 'agent.run', version: '1' })\nexport class AgentRunWorkflow {\n constructor(\n @Inject(AGENT_DEPS_FACTORY) private readonly factory: AgentDepsFactory,\n @Inject(AGENT_STORE) private readonly store: AgentStore,\n private readonly steps: AgentRunSteps,\n @Inject(AGENT_DISPATCHED_STEPS) private readonly dispatchedSteps: boolean,\n ) {}\n\n async run(ctx: WorkflowCtx, input: AgentRunInput): Promise<{ text: string }> {\n const day = input.day ?? utcDay();\n const deps = this.factory.forAgent(input.agentName);\n // A sub-agent run (one with an ancestor sink) marks its subthread as streaming THIS child run,\n // so a human approving its action tool routes the signal back here (runForToolCall).\n if (input.sinkRunId !== undefined) {\n await ctx.localStep('activate', () => this.store.setActiveStream(input.threadId, ctx.runId));\n }\n const sinkRunId = input.sinkRunId ?? ctx.runId;\n const hooks: AgentLoopHooks = {\n runId: ctx.runId,\n // A child forwards into the top-level sink but must not end/fail it (the top-level run owns it).\n openSink: async () =>\n input.sinkRunId !== undefined\n ? childSinkWriter(await deps.sink.open(sinkRunId))\n : deps.sink.open(ctx.runId),\n awaitApproval: (call) => ctx.waitForSignal<Decision>(`tool:${ctx.runId}:${call.id}`),\n step: (name, fn) => ctx.localStep(name, fn),\n // Dispatched-step suspends must escape the loop's tool catch — control flow, not a tool\n // failure. Marker-based predicate, NOT instanceof: the signal's CLASS differs by runtime\n // (engine in-process throws durable-core's WorkflowSuspended/ContinueAsNew; the BullMQ thin\n // worker throws durable-worker's own Suspend), so only the Symbol.for marker is reliable.\n isControlFlowError: (error) => isWorkflowControlFlowSignal(error),\n runAgent: async (agentName, task) => {\n const subThreadId = await ctx.localStep(`subthread:${agentName}`, async () => {\n const thread = await this.store.createThread({\n actor: input.actor,\n transient: true,\n });\n return thread.id;\n });\n return ctx.child(AgentRunWorkflow, {\n agentName,\n threadId: subThreadId,\n actor: input.actor,\n userText: task,\n day,\n delegationDepth: (input.delegationDepth ?? 0) + 1,\n sinkRunId,\n });\n },\n // Routes the two long steps through AgentRunSteps as engine-dispatched `ctx.step`s instead of\n // `ctx.localStep`s, so a turn isn't pinned to this workflow worker for the model call or a tool\n // execution. `sinkRunId`/`childSink` are sink routing this workflow already resolved above —\n // core's dispatchLlm signature stays sink-topology-agnostic, so we add them here, not in core.\n ...(this.dispatchedSteps\n ? {\n dispatchLlm: (index: number, envelope: LlmStepEnvelope) =>\n ctx.step(this.steps.llm, {\n ...envelope,\n runId: ctx.runId,\n step: index,\n sinkRunId,\n childSink: input.sinkRunId !== undefined,\n }),\n // Fold the call identity (`toolCallId`/`toolType`) into the wire payload — the handler\n // emits the `tool.execution` span with it. Only read/action calls reach dispatchTool\n // ('agent'-kind delegations branch to runAgent earlier in the loop), so anything that\n // isn't 'action' is defensively 'read' — the same posture core takes for an\n // unresolvable `kind`.\n dispatchTool: (call: ToolCallRequest, envelope: ToolStepEnvelope) =>\n ctx.step(this.steps.tool, {\n ...envelope,\n toolCallId: call.id,\n toolType: call.kind === 'action' ? 'action' : 'read',\n }),\n }\n : {}),\n };\n try {\n const result = await runAgentLoop({ ...deps, day }, input, hooks);\n // Genuine completion (not a suspend) — clear so `activeRunForThread` no longer reports this\n // run. `input.threadId` is whichever thread this run's own `activate`/the top-level `chat()`\n // call marked active, so this is correct for both a top-level run and a sub-agent's subthread.\n await ctx.localStep('deactivate', () => this.store.setActiveStream(input.threadId, null));\n return result;\n } catch (error) {\n // A suspend / continue-as-new is control flow, not a failure — let the engine handle it. The\n // thread stays \"active\" across the suspend, which is correct: the turn hasn't finished.\n // Marker-based predicate, NOT instanceof: control-flow signals differ BY CLASS across the two\n // runtimes (the in-process engine throws durable-core's WorkflowSuspended/ContinueAsNew; the\n // BullMQ thin worker throws durable-worker's own Suspend). An instanceof check here\n // misclassified a thin-worker dispatch suspend as a real failure and ran the failure path\n // DURING the suspend — corrupting the run's history with extra checkpoints, so the resume\n // died with NondeterminismError. Only the Symbol.for marker is reliable cross-runtime (and\n // across duplicated module copies).\n if (isWorkflowControlFlowSignal(error)) {\n throw error;\n }\n // A real failure (e.g. quota exceeded, which throws before the sink is even opened) would\n // otherwise leave the HTTP subscriber hanging on a stream that never ends. Fail the sink with\n // a typed terminal so the controller emits an `event: error` frame, then rethrow so the engine\n // still records the run as failed.\n const message = error instanceof Error ? error.message : String(error);\n const code = error instanceof QuotaExceededError ? 'quota_exceeded' : 'run_failed';\n publishAgentRunFailed({ runId: ctx.runId, code, message });\n // Settle the run's persisted outcome (the loop only records completions — it can't catch its\n // own crash). Optional-call: a store without run recording degrades to no reliability metrics.\n await ctx.localStep(\n 'persist:run:fail',\n () =>\n this.store.recordRunEnd?.({\n runId: ctx.runId,\n status: 'failed',\n errorCode: code,\n errorMessage: message,\n }) ?? Promise.resolve(),\n );\n await ctx.localStep('deactivate', () => this.store.setActiveStream(input.threadId, null));\n // Reuse the run's own sink resolution: a top-level run fails the watched stream; a child run's\n // writer no-ops fail, deferring the surfaced error to the ancestor whose run also unwinds.\n const writer = await hooks.openSink();\n await writer.fail({ code, message });\n throw error;\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 {\n AGENT_DEPS_FACTORY,\n type AiToolCtx,\n type LlmStepEnvelope,\n type ModelTurnResult,\n type ToolStepEnvelope,\n type ToolTransientRetrySetting,\n invokeWithTransientRetry,\n publishAgentToolRetry,\n traceLlmTurn,\n traceToolExecution,\n withToolTimeout,\n} from '@dudousxd/nestjs-agent-core';\nimport { Step } from '@dudousxd/nestjs-durable';\nimport { Inject, Injectable } from '@nestjs/common';\nimport type { AgentDepsFactory } from '../agent-deps.factory.js';\nimport { childSinkWriter } from '../agent-deps.js';\n\n/**\n * Serializable input for the dispatched `llm` step: a {@link LlmStepEnvelope} plus the sink routing\n * only the durable runner knows (`sinkRunId`/`childSink`) — core's `AgentLoopHooks.dispatchLlm` stays\n * sink-topology-agnostic, so the workflow adds these two fields when it builds the envelope.\n */\nexport interface DispatchedLlmInput extends LlmStepEnvelope {\n /**\n * The dispatching workflow's own `ctx.runId` — the run this step's outcome accrues to for\n * reliability metrics (`bumpRunRetries`). Carried even though the handler cannot bump retries\n * today: the durable handler boundary (`runStepHandler`) hands a `@Step` method only\n * `(input, StepLogger)` — the wire task's `attempt` is not exposed — so there is no clean way to\n * detect a retry from inside the handler. Kept on the envelope so the bump can be wired without a\n * wire-contract change once the durable runtime exposes the attempt.\n */\n runId: string;\n /** The turn index within the run (`llm:<step>`) — the `llm.turn` span's `step` metadata. */\n step: number;\n /** The stream target: `input.sinkRunId ?? ctx.runId` of the dispatching workflow. */\n sinkRunId: string;\n /** True for a sub-agent run — wrap the writer with {@link childSinkWriter} (no end/fail). */\n childSink: boolean;\n}\n\n/**\n * Serializable input for the dispatched `tool` step: a {@link ToolStepEnvelope} plus the call\n * identity the `tool.execution` span needs (`toolCallId`/`toolType`) — core's\n * `AgentLoopHooks.dispatchTool` passes those on the separate `ToolCallRequest` argument, so the\n * workflow folds them into the wire payload when it dispatches (same pattern as\n * {@link DispatchedLlmInput}'s sink routing).\n */\nexport interface DispatchedToolInput extends ToolStepEnvelope {\n toolCallId: string;\n toolType: 'read' | 'action';\n}\n\n/**\n * The two long steps `AgentRunWorkflow` dispatches as routed remote steps (`AgentRunSteps.llm` /\n * `AgentRunSteps.tool`) — the default under `durable: true`; `dispatchedSteps: false` runs them\n * in-process under `ctx.localStep` instead. Both re-resolve their deps from THIS worker's own DI via\n * `AGENT_DEPS_FACTORY.forAgent` — a step can be served by any worker in the fleet, not just the one\n * that started the run. Always provided by `AgentDurableModule` regardless of `dispatchedSteps`, so\n * the worker group is never orphaned.\n */\n@Injectable()\nexport class AgentRunSteps {\n constructor(@Inject(AGENT_DEPS_FACTORY) private readonly factory: AgentDepsFactory) {}\n\n /**\n * Retryable: every side effect (persist/quota/stream markers) happens loop-side under\n * `hooks.step`, so a durable retry only re-runs the model call and re-streams its tokens — never\n * double-writes. NEVER call `writer.end()`/`fail()` here: the workflow owns the stream's lifecycle,\n * across however many turns/retries it takes.\n */\n @Step({ retries: 3 })\n async llm(input: DispatchedLlmInput): Promise<ModelTurnResult> {\n const deps = this.factory.forAgent(input.agentName);\n // The envelope carries only wire-safe data — a `ToolDefinition` holds a live Zod/StandardSchema\n // instance that can't survive JSON transport, so this handler re-derives it from `input.actor`,\n // exactly like the loop's own non-dispatched branch does.\n const tools = await deps.registry.definitionsFor(\n input.actor,\n deps.rolesPolicy,\n deps.toolAllowList,\n );\n const opened = await deps.sink.open(input.sinkRunId);\n const writer = input.childSink ? childSinkWriter(opened) : opened;\n // Span-wrapped HERE (the genuine execution site), emitting the identical `aviary:agent:llm.turn`\n // span core's non-dispatched branch emits — from whichever worker actually serves the step.\n // Replay-safe by construction: a dispatched step's handler only runs on genuine dispatch (replay\n // resolves the step from its checkpoint without re-invoking a worker), which is exactly why core\n // exports the helper instead of wrapping the `hooks.dispatchLlm` CALL site itself.\n return traceLlmTurn(input.runId, input.step, () =>\n deps.model.runTurn({\n system: input.system,\n messages: input.messages,\n tools,\n sink: writer,\n }),\n );\n }\n\n /**\n * NO DURABLE retries — a tool may not be idempotent (a bare `@Step()` carries none, unlike `llm`\n * above). What it does retry, in place, is a CLASSIFIED-TRANSIENT error from the tool's own\n * invocation (a DB deadlock, a lock-wait timeout — see `isTransientToolError`): the server rolled\n * that work back, so re-invoking it is safe, and doing it here (inside this one step, never a new\n * checkpoint) is exactly how the non-dispatched loop path handles it too. The timeout is applied\n * HERE, handler-side, via `withToolTimeout` — never as a durable dispatch `timeoutMs`, which\n * bounds engine liveness (retryable) rather than the tool's own business outcome — and per\n * ATTEMPT, so a retried invocation gets its own fresh timeout window.\n */\n @Step()\n async tool(input: DispatchedToolInput): Promise<unknown> {\n const deps = this.factory.forAgent(input.ctx.agentName);\n // AgentDeps carries no `host` today (AgentDepsFactory never populates one), so the rebuilt ctx\n // is exactly `input.ctx` — no narrower than what the non-dispatched path already threads through.\n const ctx: AiToolCtx = { ...input.ctx };\n // The envelope carries the numeric half (attempts/backoffMs) the dispatching loop already\n // resolved — the SAME policy as the non-dispatched path. `classify` isn't wire-safe, so it's\n // resolved from THIS worker's own local module options instead (same DI re-resolution as\n // `registry`/`rolesPolicy` above) — a custom classifier applies host-side in both processes.\n const localClassify =\n deps.toolTransientRetry !== false ? deps.toolTransientRetry?.classify : undefined;\n const transientRetry: ToolTransientRetrySetting =\n input.transientRetry === false\n ? false\n : {\n attempts: input.transientRetry.attempts,\n backoffMs: input.transientRetry.backoffMs,\n ...(localClassify !== undefined ? { classify: localClassify } : {}),\n };\n // Span-wrapped HERE like `llm` above (same replay-safety-by-construction reasoning) — the\n // timeout AND the retry loop sit INSIDE the span so every attempt (and a timed-out attempt)\n // surfaces under the span's error phase.\n return traceToolExecution(\n input.ctx.runId,\n { toolCallId: input.toolCallId, toolName: input.toolName, toolType: input.toolType },\n () =>\n invokeWithTransientRetry(\n () => {\n const invocation = deps.registry.invoke(\n input.toolName,\n input.input,\n ctx,\n deps.rolesPolicy,\n );\n return input.timeoutMs !== undefined\n ? withToolTimeout(invocation, input.timeoutMs, input.toolName)\n : invocation;\n },\n transientRetry,\n {\n onRetry: (attempt, error) => {\n publishAgentToolRetry({\n toolName: input.toolName,\n toolCallId: input.toolCallId,\n attempt,\n message: error instanceof Error ? error.message : String(error),\n });\n },\n },\n ),\n );\n }\n}\n","/**\n * DI flag carrying the EFFECTIVE `dispatchedSteps` value: whether `AgentRunWorkflow` dispatches its\n * `llm`/`tool` steps as routed remote steps (`AgentRunSteps`) instead of in-process `ctx.localStep`s.\n * `AgentDurableModule` derives it from `AGENT_OPTIONS` (`durable === true && dispatchedSteps !==\n * false` — default ON under durable); `AgentRunWorkflow` injects it. Kept in its own file —\n * `AgentDurableModule` provides `AgentRunWorkflow` and `AgentRunWorkflow` injects this token, so\n * declaring it in either of those two files would make them import each other.\n */\nexport const AGENT_DISPATCHED_STEPS = Symbol.for('@dudousxd/nestjs-agent:dispatched-steps');\n","import { randomUUID } from 'node:crypto';\nimport type { AgentRunInput, AgentRunner, Decision } from '@dudousxd/nestjs-agent-core';\nimport { WorkflowService } from '@dudousxd/nestjs-durable';\nimport { isWorkflowControlFlowSignal } from '@dudousxd/nestjs-durable-core';\nimport { Injectable } from '@nestjs/common';\nimport { utcDay } from '../agent-deps.js';\nimport { AgentRunWorkflow } from './agent-run.workflow.js';\n\n/**\n * Runs the agent turn as a `@dudousxd/nestjs-durable` workflow. `start` creates the run and returns\n * its id immediately; a worker runs the body and streams tokens to the sink. HITL approval is\n * delivered as a durable signal namespaced by run, so it can never cross-resolve another run.\n */\n@Injectable()\nexport class DurableAgentRunner implements AgentRunner {\n constructor(private readonly workflows: WorkflowService) {}\n\n async start(input: AgentRunInput): Promise<{ runId: string }> {\n const stamped: AgentRunInput = { ...input, day: input.day ?? utcDay() };\n // Own the run id so we can still return it when the run suspends synchronously (below).\n const runId = randomUUID();\n try {\n await this.workflows.start(AgentRunWorkflow, stamped, runId);\n } catch (error) {\n // A run that suspends on its FIRST step (waiting on the model/tool worker, a signal, or a\n // sleep) surfaces the runtime's internal suspend signal here whenever the start ran under a\n // DRIVING dispatcher (e.g. a durable tenant/worker) rather than the enqueue-only one. That is\n // expected control flow, NOT a failure: the run is already persisted and a worker will resume\n // it, while the caller streams the sink meanwhile. Swallow it and return the run id; any\n // other error is a real start failure and propagates. Marker-based predicate, NOT instanceof:\n // the signal's CLASS differs by runtime (engine in-process WorkflowSuspended vs the BullMQ\n // thin worker's own Suspend), so only the Symbol.for marker is reliable.\n if (!isWorkflowControlFlowSignal(error)) {\n throw error;\n }\n }\n return { runId };\n }\n\n async signal(runId: string, toolCallId: string, decision: Decision): Promise<void> {\n await this.workflows.signal(`tool:${runId}:${toolCallId}`, decision);\n }\n\n async cancel(_runId: string): Promise<void> {\n // WorkflowService exposes no hard cancel; rely on the execution timeout / control plane.\n // Apps needing immediate cancel can resolve WorkflowEngine and call engine.cancel(runId).\n await Promise.resolve();\n }\n}\n","import {\n AGENT_DURABLE_RUNNER,\n AGENT_OPTIONS,\n AGENT_SINK,\n type TokenStreamSink,\n} from '@dudousxd/nestjs-agent-core';\nimport { type DynamicModule, Global, Logger, Module } from '@nestjs/common';\nimport type { AgentModuleOptions } from '../agent.options.js';\nimport { InProcessTokenStreamSink } from '../in-process-sink.js';\nimport { AgentRunSteps } from './agent-run.steps.js';\nimport { AgentRunWorkflow } from './agent-run.workflow.js';\nimport { AGENT_DISPATCHED_STEPS } from './dispatched-steps.token.js';\nimport { DurableAgentRunner } from './durable-agent-runner.js';\n\nconst logger = new Logger('AgentDurableModule');\n\n/**\n * Opt-in durable runner. Import this alongside `AgentModule.forRoot({ durable: true })` and a\n * configured `DurableModule`. It registers the `agent.run` workflow (discovered by DurableModule)\n * and exposes the durable runner via `AGENT_DURABLE_RUNNER`, which AgentModule binds to\n * `AGENT_RUNNER`. Forgetting this import makes AgentModule throw a clear error at boot.\n *\n * Always provides `AgentRunSteps` regardless of `dispatchedSteps` — the worker group it serves\n * (`AgentRunSteps.llm`/`.tool`) must never be orphaned by a config flag the durable step registrar\n * can't see ahead of time.\n */\n@Global()\n@Module({\n providers: [\n AgentRunWorkflow,\n AgentRunSteps,\n DurableAgentRunner,\n { provide: AGENT_DURABLE_RUNNER, useExisting: DurableAgentRunner },\n {\n provide: AGENT_DISPATCHED_STEPS,\n useFactory: (options: AgentModuleOptions, sink: TokenStreamSink) => {\n // Default ON under durable: dispatching moves the run off its pod during the two long\n // steps (the correct production posture) and AgentRunSteps is always registered, so the\n // routed groups are never unserved. `dispatchedSteps: false` opts back into localSteps.\n const enabled = options.durable === true && options.dispatchedSteps !== false;\n // The default sink only buffers in-process: a dispatched `llm` step served by another\n // worker has no way to reach a buffer that lives in THIS process's memory. Detectable only\n // via `instanceof` (the sink SPI carries no \"am I cross-process\" capability) — good enough\n // for the built-in default, silent for any custom sink (which may well be cross-process).\n // Keyed off the EFFECTIVE value, so it fires for the durable default too — desired: the\n // cross-process-sink requirement is really a property of durable itself (any worker may\n // take agent.run), dispatch just widens how much of the turn runs elsewhere.\n if (enabled && sink instanceof InProcessTokenStreamSink) {\n logger.warn(\n 'Dispatched steps are active (the default under durable: true) with the default ' +\n 'InProcessTokenStreamSink, which only buffers tokens in-process. A dispatched `llm` ' +\n 'step served by a different worker cannot stream into this buffer. Wire a ' +\n 'cross-process TokenStreamSink (e.g. a Redis pub/sub sink) via ' +\n 'AgentModule.forRoot({ sink }) before running multi-pod, or set ' +\n 'dispatchedSteps: false to keep the turn in-process localSteps.',\n );\n }\n return enabled;\n },\n inject: [AGENT_OPTIONS, AGENT_SINK],\n },\n ],\n exports: [AGENT_DURABLE_RUNNER, AgentRunWorkflow, AgentRunSteps, AGENT_DISPATCHED_STEPS],\n})\nexport class AgentDurableModule {\n /**\n * The dynamic form used by the `agentDurable` helper. The module needs no configuration of its\n * own (its providers come from the decorator above), so this just yields the module reference —\n * importing `AgentDurableModule` directly stays equivalent.\n */\n static forRoot(): DynamicModule {\n return { module: AgentDurableModule, global: true };\n }\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 {\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 { 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 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 { DynamicModule } from '@nestjs/common';\nimport { AgentModule } from '../agent.module.js';\nimport type { AgentModuleOptions } from '../agent.options.js';\nimport { AgentDurableModule } from './agent-durable.module.js';\n\n/**\n * One-import setup for the durable runner. Spread the result into a module's `imports`:\n *\n * ```ts\n * imports: [DurableModule.forRoot({ ... }), ...agentDurable({ model, store, defaultAgent })]\n * ```\n *\n * It wires `AgentModule.forRoot({ ...options, durable: true })` together with `AgentDurableModule`,\n * the equivalent of importing both by hand. A configured `DurableModule` is still required. The\n * durable runner has no configuration of its own, so `options` is exactly the agent options.\n */\nexport function agentDurable(options: AgentModuleOptions): DynamicModule[] {\n return [AgentModule.forRoot({ ...options, durable: true }), AgentDurableModule.forRoot()];\n}\n"],"mappings":"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","names":["AGENT_DEPS_FACTORY","AGENT_STORE","QuotaExceededError","publishAgentRunFailed","runAgentLoop","Workflow","isWorkflowControlFlowSignal","Inject","Injectable","utcDay","date","Date","toISOString","slice","childSinkWriter","writer","write","chunk","end","fail","AGENT_DEPS_FACTORY","invokeWithTransientRetry","publishAgentToolRetry","traceLlmTurn","traceToolExecution","withToolTimeout","Step","Inject","Injectable","AgentRunSteps","factory","llm","input","deps","forAgent","agentName","tools","registry","definitionsFor","actor","rolesPolicy","toolAllowList","opened","sink","open","sinkRunId","writer","childSink","childSinkWriter","traceLlmTurn","runId","step","model","runTurn","system","messages","tool","ctx","localClassify","toolTransientRetry","classify","undefined","transientRetry","attempts","backoffMs","traceToolExecution","toolCallId","toolName","toolType","invokeWithTransientRetry","invocation","invoke","timeoutMs","withToolTimeout","onRetry","attempt","error","publishAgentToolRetry","message","Error","String","retries","AGENT_DISPATCHED_STEPS","Symbol","for","AgentRunWorkflow","factory","store","steps","dispatchedSteps","run","ctx","input","day","utcDay","deps","forAgent","agentName","sinkRunId","undefined","localStep","setActiveStream","threadId","runId","hooks","openSink","childSinkWriter","sink","open","awaitApproval","call","waitForSignal","id","step","name","fn","isControlFlowError","error","isWorkflowControlFlowSignal","runAgent","task","subThreadId","thread","createThread","actor","transient","child","userText","delegationDepth","dispatchLlm","index","envelope","llm","childSink","dispatchTool","tool","toolCallId","toolType","kind","result","runAgentLoop","message","Error","String","code","QuotaExceededError","publishAgentRunFailed","recordRunEnd","status","errorCode","errorMessage","Promise","resolve","writer","fail","version","randomUUID","WorkflowService","isWorkflowControlFlowSignal","Injectable","DurableAgentRunner","workflows","start","input","stamped","day","utcDay","runId","randomUUID","AgentRunWorkflow","error","isWorkflowControlFlowSignal","signal","toolCallId","decision","cancel","_runId","Promise","resolve","AGENT_DURABLE_RUNNER","AGENT_OPTIONS","AGENT_SINK","Global","Logger","Module","AgentStreamError","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","logger","Logger","AgentDurableModule","forRoot","module","global","providers","AgentRunWorkflow","AgentRunSteps","DurableAgentRunner","provide","AGENT_DURABLE_RUNNER","useExisting","AGENT_DISPATCHED_STEPS","useFactory","options","sink","enabled","durable","dispatchedSteps","InProcessTokenStreamSink","warn","inject","AGENT_OPTIONS","AGENT_SINK","exports","AGENT_ACTOR_RESOLVER","AGENT_APPROVAL_PORT","AGENT_DEPS_FACTORY","AGENT_DURABLE_RUNNER","AGENT_MODEL","AGENT_OPTIONS","AGENT_PROMPT_CONTRIBUTORS","AGENT_QUOTA_STORE","AGENT_REGISTRY","AGENT_ROLES_POLICY","AGENT_RUNNER","AGENT_SINK","AGENT_STORE","AGENT_TOOL_REGISTRY","AgentRegistry","DefaultRolesPolicy","ToolRegistry","Global","Module","DiscoveryModule","RouterModule","AGENT_MODEL","AGENT_PRICING_STORE","AGENT_PROMPT_CONTRIBUTORS","AGENT_QUOTA_STORE","AGENT_REGISTRY","AGENT_ROLES_POLICY","AGENT_SINK","AGENT_STORE","AGENT_TOOL_REGISTRY","AgentRegistry","ToolRegistry","AGENT_OPTIONS","Inject","Injectable","Optional","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","AGENT_DEPS_FACTORY","AGENT_QUOTA_STORE","AGENT_RUNNER","AGENT_STORE","BadRequestException","ForbiddenException","Inject","Injectable","NotFoundException","NotImplementedException","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","Injectable","AgentApprovalPortAdapter","agent","approve","toolCallId","opts","signalToolCall","approved","executedByRef","undefined","reject","reason","AGENT_DEPS_FACTORY","AGENT_REGISTRY","AgentRegistry","Controller","Get","Inject","AgentsController","agents","depsFactory","list","defaultAgentName","map","definition","name","description","isDefault","AGENT_ACTOR_RESOLVER","AGENT_ATTACHMENT_STAGING","AGENT_OPTIONS","BadRequestException","Controller","Inject","NotImplementedException","Optional","PayloadTooLargeException","Post","Req","UnsupportedMediaTypeException","UploadedFile","UseInterceptors","FileInterceptor","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","AGENT_ACTOR_RESOLVER","AgentStreamError","Body","Controller","Get","Inject","Param","Post","Req","Res","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","AGENT_ACTOR_RESOLVER","Controller","Get","Inject","Req","QuotaController","agent","actorResolver","today","req","actor","resolve","quotaToday","id","AGENT_ACTOR_RESOLVER","Body","Controller","Delete","Get","Inject","Param","Patch","Post","Req","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","AGENT_ACTOR_RESOLVER","Body","Controller","Inject","Post","Req","ToolCallController","agent","actorResolver","approve","req","body","actor","resolve","toolCallId","ok","reject","reason","AGENT_PROMPT_CONTRIBUTORS","AGENT_REGISTRY","AgentRegistry","Inject","Injectable","Logger","DiscoveryService","MetadataScanner","AGENT_METADATA","Symbol","for","readAgentMetadata","target","Reflect","getMetadata","AGENT_METADATA","SYSTEM_PROMPT_METADATA","Symbol","for","SYSTEM_PROMPT_CONTRIBUTOR_METADATA","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","AGENT_OPTIONS","AGENT_REGISTRY","AGENT_TOOL_REGISTRY","Inject","Injectable","Logger","DiscoveryService","z","AI_TOOL_METADATA","Symbol","readAiToolMetadata","target","Reflect","getMetadata","AI_TOOL_METADATA","AGENT_TOOL_BRAND","Symbol","for","isBrandedFunctionalTool","value","AGENT_TOOL_BRAND","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","LedgerQuotaStore","store","limitTokens","check","actorRef","day","usedTokens","quotaToday","withinLimit","bump","AGENT_DEPS_FACTORY","AGENT_STORE","QuotaExceededError","publishAgentRunFailed","runAgentLoop","Inject","Injectable","Logger","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","agentDurable","options","AgentModule","forRoot","durable","AgentDurableModule"]}