@dudousxd/nestjs-agent 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +49 -0
- package/dist/agent-deps.factory-D9BHJJqm.d.cts +173 -0
- package/dist/agent-deps.factory-D9BHJJqm.d.ts +173 -0
- package/dist/durable/index.cjs +1590 -0
- package/dist/durable/index.cjs.map +1 -0
- package/dist/durable/index.d.cts +66 -0
- package/dist/durable/index.d.ts +66 -0
- package/dist/durable/index.js +1562 -0
- package/dist/durable/index.js.map +1 -0
- package/dist/index.cjs +1468 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +195 -0
- package/dist/index.d.ts +195 -0
- package/dist/index.js +1427 -0
- package/dist/index.js.map +1 -0
- package/package.json +80 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/agent.module.ts","../src/agent-deps.factory.ts","../src/agent.service.ts","../src/agent-deps.ts","../src/controller/chat.controller.ts","../src/controller/quota.controller.ts","../src/controller/threads.controller.ts","../src/controller/tool-call.controller.ts","../src/discovery/ai-tool-discovery.service.ts","../src/decorator/ai-tool.decorator.ts","../src/functional-tool.ts","../src/in-process-sink.ts","../src/ledger-quota-store.ts","../src/runner/inline-agent-runner.ts","../src/resolver/header-actor-resolver.ts"],"sourcesContent":["export { AgentModule } from './agent.module.js';\nexport type {\n AgentModuleOptions,\n AgentModuleAsyncOptions,\n DefaultAgentOptions,\n} from './agent.options.js';\nexport { AgentService, type ChatParams } from './agent.service.js';\nexport {\n AiTool,\n type AiToolOptions,\n AI_TOOL_METADATA,\n readAiToolMetadata,\n} from './decorator/ai-tool.decorator.js';\nexport { AiToolDiscoveryService } from './discovery/ai-tool-discovery.service.js';\nexport {\n provideAgentTool,\n AGENT_TOOL_BRAND,\n type FunctionalTool,\n} from './functional-tool.js';\nexport { InlineAgentRunner } from './runner/inline-agent-runner.js';\nexport { InProcessTokenStreamSink } from './in-process-sink.js';\nexport { LedgerQuotaStore } from './ledger-quota-store.js';\nexport { type AgentDeps, utcDay } from './agent-deps.js';\nexport { AgentDepsFactory, delegateToolName } from './agent-deps.factory.js';\nexport { HeaderActorResolver } from './resolver/header-actor-resolver.js';\n\n// Re-export the core surface so consumers import tools/types from one place.\nexport * from '@dudousxd/nestjs-agent-core';\n","import {\n AGENT_ACTOR_RESOLVER,\n AGENT_DEPS_FACTORY,\n AGENT_DURABLE_RUNNER,\n AGENT_MODEL,\n AGENT_OPTIONS,\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 type AgentDefinition,\n AgentRegistry,\n type AgentRunner,\n type AgentStore,\n DefaultRolesPolicy,\n ToolRegistry,\n} from '@dudousxd/nestjs-agent-core';\nimport { type DynamicModule, Global, Module, type Provider } 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 { 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 { 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\nconst FEATURE_INIT = Symbol('nestjs-agent:feature-init');\n\n/** Default route prefix the controllers mount under. */\nconst DEFAULT_PATH = 'agent';\n\n/**\n * The implicit single agent, built from `options.defaultAgent`. `DefaultAgentOptions` is exactly an\n * `AgentDefinition` with `name` optional, so we just default the name and spread the rest. forFeature\n * adds more named agents.\n */\nfunction defaultDefinition(options: AgentModuleOptions): AgentDefinition {\n return { name: 'default', ...options.defaultAgent };\n}\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 {\n provide: AGENT_REGISTRY,\n useFactory: (options: AgentModuleOptions) => {\n const registry = new AgentRegistry();\n registry.register(defaultDefinition(options));\n return registry;\n },\n inject: [AGENT_OPTIONS],\n },\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 AiToolDiscoveryService,\n InlineAgentRunner,\n AgentService,\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_DEPS_FACTORY,\n AgentDepsFactory,\n AgentService,\n InlineAgentRunner,\n ];\n}\n\nconst CONTROLLERS = [ChatController, ThreadsController, ToolCallController, QuotaController];\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@Global()\n@Module({})\nexport class AgentModule {\n static forRoot(options: AgentModuleOptions): DynamicModule {\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 return {\n module: AgentModule,\n global: true,\n imports: [DiscoveryModule, routerFor(path)],\n controllers: CONTROLLERS,\n providers: [\n { provide: AGENT_OPTIONS, useValue: options },\n ...sharedProviders(options.durable ?? false, includeStore),\n ],\n exports: exportsFor(includeStore),\n };\n }\n\n static forRootAsync(options: AgentModuleAsyncOptions): DynamicModule {\n const path = options.path ?? DEFAULT_PATH;\n return {\n module: AgentModule,\n global: true,\n imports: [DiscoveryModule, routerFor(path), ...(options.imports ?? [])],\n controllers: CONTROLLERS,\n providers: [\n {\n provide: AGENT_OPTIONS,\n useFactory: options.useFactory,\n inject: options.inject ?? [],\n },\n // The async factory resolves too late to inspect `store`, so we always bind AGENT_STORE here\n // (its factory reads the resolved options). Omit-and-import-a-store-module is a `forRoot` path.\n ...sharedProviders(options.durable ?? false, true),\n ],\n exports: exportsFor(true),\n };\n }\n\n /** Register additional named agents (an orchestrator + its sub-agents). */\n static forFeature(definitions: AgentDefinition[]): DynamicModule {\n return {\n module: AgentModule,\n providers: [\n {\n provide: FEATURE_INIT,\n useFactory: (registry: AgentRegistry) => {\n for (const definition of definitions) {\n registry.register(definition);\n }\n return true;\n },\n inject: [AGENT_REGISTRY],\n },\n ],\n };\n }\n}\n","import {\n AGENT_MODEL,\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 AgentRegistry,\n type AgentStore,\n type ModelProvider,\n type Persona,\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 } 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 delegate 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 `default` definition. */\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_QUOTA_STORE) private readonly quota: QuotaStore | undefined,\n ) {}\n\n defaultAgentName(): string {\n return this.options.defaultAgent?.name ?? '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 personas = new Map<string, Persona>();\n for (const persona of definition?.personas ?? []) {\n personas.set(persona.id, persona);\n }\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 systemPrompt: definition?.systemPrompt ?? 'You are a helpful assistant.',\n maxSteps: definition?.maxSteps ?? 8,\n personas,\n defaultPersona: definition?.defaultPersona ?? 'default',\n ...(definition?.modelId !== undefined ? { modelId: definition.modelId } : {}),\n ...(this.quota !== undefined ? { quota: this.quota } : {}),\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_RUNNER,\n AGENT_STORE,\n type Actor,\n type AgentRunInput,\n type AgentRunner,\n type AgentStore,\n type PageContext,\n type Persona,\n type ThreadDetail,\n type ThreadSummary,\n} from '@dudousxd/nestjs-agent-core';\nimport {\n BadRequestException,\n ForbiddenException,\n Inject,\n Injectable,\n NotFoundException,\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 personaId?: string;\n pageContext?: PageContext;\n /** Re-run the last exchange instead of adding a new message. Requires an existing `threadId`. */\n regenerate?: 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 ) {}\n\n async chat(params: ChatParams): Promise<{ runId: string; threadId: string }> {\n const agentName = params.agentName ?? this.deps.defaultAgentName();\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 persona: params.personaId ?? this.deps.forAgent(agentName).defaultPersona,\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 persona = this.resolvePersona(agentName, params.personaId);\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 ...(persona !== undefined ? { persona } : {}),\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 const runId = await this.runForOwnedToolCall(actor, toolCallId);\n return this.runner.signal(runId, toolCallId, { approved: true });\n }\n\n async reject(actor: Actor, toolCallId: string, reason?: string): Promise<void> {\n const runId = await this.runForOwnedToolCall(actor, toolCallId);\n return this.runner.signal(runId, toolCallId, {\n approved: false,\n ...(reason !== undefined ? { reason } : {}),\n });\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 resolvePersona(agentName?: string, id?: string): Persona | undefined {\n const deps = this.deps.forAgent(agentName);\n return deps.personas.get(id ?? deps.defaultPersona);\n }\n\n personaCatalog(agentName?: string): { id: string; label: string }[] {\n return [...this.deps.forAgent(agentName).personas.values()].map((persona) => ({\n id: persona.id,\n label: persona.label,\n }));\n }\n\n listThreads(actorRef: string): Promise<ThreadSummary[]> {\n return this.store.listThreads(actorRef);\n }\n\n async getThread(actor: Actor, threadId: string): Promise<ThreadDetail | null> {\n await this.assertOwnsThread(actor, threadId);\n return this.store.getThread(threadId);\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 async quotaToday(actorRef: string): Promise<{ usedTokens: number }> {\n return this.store.quotaToday(actorRef, utcDay());\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 + routing seam for HITL approve/reject: assert the caller owns the tool call's\n * thread, then resolve the run currently awaiting that call (its thread's active stream). That run\n * is the sub-agent's own child run when the pending call belongs to a delegated agent — the client\n * never knows or supplies a runId; it is derived here from the tool call alone.\n */\n private async runForOwnedToolCall(actor: Actor, toolCallId: string): Promise<string> {\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 const runId = await this.store.runForToolCall(toolCallId);\n if (runId === null) {\n throw new NotFoundException(`tool call ${toolCallId} has no active run to signal`);\n }\n return runId;\n }\n\n /** Authorization seam for `cancel`: the caller must own the thread currently streaming this run. */\n private async assertOwnsActiveStream(actor: Actor, runId: string): Promise<void> {\n const owner = await this.store.ownerOfActiveStream(runId);\n if (owner === null) {\n throw new NotFoundException(`no active run ${runId}`);\n }\n if (owner !== actor.id) {\n throw new ForbiddenException('run belongs to another actor');\n }\n }\n}\n","import type {\n AgentStore,\n ModelProvider,\n Persona,\n PromptBuilder,\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 maxSteps: number;\n personas: Map<string, Persona>;\n defaultPersona: string;\n /** Agent-level tool allow-list (intersected with the persona's). Undefined → all tools. */\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}\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_ACTOR_RESOLVER,\n type ActorResolver,\n AgentStreamError,\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 persona?: string;\n pageContext?: PageContext;\n /** Re-run the last exchange on `threadId` instead of adding a new message. */\n regenerate?: 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.persona !== undefined ? { personaId: body.persona } : {}),\n ...(body.pageContext !== undefined ? { pageContext: body.pageContext } : {}),\n ...(body.regenerate === true ? { regenerate: 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 const decoder = new TextDecoder();\n try {\n for await (const chunk of this.agent.subscribe(runId)) {\n res.write(`data: ${JSON.stringify({ delta: decoder.decode(chunk) })}\\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 { Controller, Delete, Get, Inject, Param, Post, Req } from '@nestjs/common';\nimport type { Request } from 'express';\nimport { AgentService } from '../agent.service.js';\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('personas/catalog')\n personas() {\n return this.agent.personaCatalog();\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","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_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 `delegatesTo` (typo, or a sub-agent never registered via forFeature) would\n // 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}\" delegatesTo \"${target}\", which is not a registered agent. Register it via AgentModule.forFeature([...]) or fix the name.`,\n );\n }\n const name = delegateToolName(target);\n if (this.registry.has(name)) {\n continue;\n }\n // Only a flat string prompt is worth surfacing in the tool description; a PromptBuilder is\n // per-request and would stringify to source, so skip it.\n const targetBlurb =\n typeof targetDefinition.systemPrompt === 'string'\n ? ` It is: ${targetDefinition.systemPrompt}`\n : '';\n this.registry.register(\n {\n name,\n kind: 'agent',\n targetAgent: target,\n description: `Delegate a task to the \"${target}\" agent and get its answer.${targetBlurb}`,\n inputSchema: z.object({ task: z.string() }),\n },\n // Loop-handled (kind 'agent'); the handler is never called.\n { execute: async () => ({}) },\n );\n delegates += 1;\n }\n }\n this.logger.log(\n `registered ${count} AI tool(s), ${functional} functional tool(s) and ${delegates} delegate tool(s)`,\n );\n }\n\n /**\n * Registers a functional tool's `{ spec, handler }`, skipping it if a tool of the same name is\n * already registered. Returns whether it was newly registered.\n */\n private registerFunctionalTool(tool: FunctionalTool): boolean {\n if (this.registry.has(tool.spec.name)) {\n this.logger.warn(\n `functional tool \"${tool.spec.name}\" duplicates a registered name — skipped`,\n );\n return false;\n }\n this.registry.register(tool.spec, tool.handler);\n return true;\n }\n}\n","import 'reflect-metadata';\nimport type { StandardSchemaV1 } from '@standard-schema/spec';\n\nexport const AI_TOOL_METADATA = Symbol('nestjs-agent:ai-tool');\n\nexport interface AiToolOptions {\n name: string;\n /**\n * `read` auto-executes; `action` requires HITL approval. (Core's `ToolKind` also has `agent`\n * for delegation, but that kind is synthesized from `delegatesTo` — never authored here.)\n */\n kind: 'read' | 'action';\n description: string;\n /**\n * Input schema as a [Standard Schema](https://standardschema.dev) — Zod, Valibot, or ArkType.\n * Validated before the handler runs.\n */\n input: StandardSchemaV1;\n /** Roles allowed to invoke. Omit to inherit the module's default roles. */\n roles?: string[];\n /**\n * Authz ability checked by an ability-aware RolesPolicy (e.g. `AgentAuthzModule`'s\n * `AuthzRolesPolicy` → `gate.forUser(actor).allows(ability)`). Ignored by the default\n * role-based policy, which uses `roles`.\n */\n ability?: string;\n}\n\n/**\n * Marks a provider class as an AI tool. The class must implement `execute(input, ctx)`.\n * `AiToolDiscoveryService` registers every `@AiTool` provider into the `ToolRegistry` at boot.\n *\n * ```ts\n * @AiTool({ name: 'getWeather', kind: 'read', description: '...', input: z.object({ city: z.string() }) })\n * class GetWeatherTool implements ToolHandler<{ city: string }> {\n * async execute(input, ctx) { return { tempC: 21 }; }\n * }\n * ```\n */\nexport function AiTool(options: AiToolOptions): ClassDecorator {\n return (target) => {\n Reflect.defineMetadata(AI_TOOL_METADATA, options, target);\n };\n}\n\nexport function readAiToolMetadata(target: object): AiToolOptions | undefined {\n return Reflect.getMetadata(AI_TOOL_METADATA, target.constructor) as AiToolOptions | undefined;\n}\n","import type { ToolHandler, ToolSpec } from '@dudousxd/nestjs-agent-core';\nimport type { FactoryProvider, Provider } from '@nestjs/common';\n\n/**\n * Brand stamped onto a functional-tool provider instance so `AiToolDiscoveryService` picks it up\n * when it walks every provider at boot — the declarative alternative to a manual `registry.register`.\n */\nexport const AGENT_TOOL_BRAND = Symbol.for('@dudousxd/nestjs-agent:functional-tool');\n\n/** A tool expressed as data + handler (e.g. from `createExecuteSqlTool`), not an `@AiTool` class. */\nexport interface FunctionalTool {\n spec: ToolSpec;\n handler: ToolHandler;\n}\n\n/** A {@link FunctionalTool} carrying {@link AGENT_TOOL_BRAND} — what a provider resolves to. */\nexport interface BrandedFunctionalTool extends FunctionalTool {\n readonly [AGENT_TOOL_BRAND]: true;\n}\n\nfunction brand(tool: FunctionalTool): BrandedFunctionalTool {\n return { [AGENT_TOOL_BRAND]: true, spec: tool.spec, handler: tool.handler };\n}\n\n/** Narrows a provider instance to a branded functional tool for boot-time registration. */\nexport function isBrandedFunctionalTool(value: object): value is BrandedFunctionalTool {\n return AGENT_TOOL_BRAND in value && 'spec' in value && 'handler' in value;\n}\n\n/**\n * Registers a functional tool declaratively — drop the returned provider in a module's `providers`\n * and `AiToolDiscoveryService` auto-registers it at boot. Each call uses a fresh, unique provide\n * token so the same tool can be provided many times without collisions.\n *\n * Two forms: a static tool (`useValue`) or a factory with `inject` for DI-resolved dependencies\n * (`useFactory`). Either way the resolved instance is branded with {@link AGENT_TOOL_BRAND}.\n */\nexport function provideAgentTool(tool: FunctionalTool): Provider;\nexport function provideAgentTool(\n factory: (...deps: never[]) => FunctionalTool,\n inject?: FactoryProvider['inject'],\n): Provider;\nexport function provideAgentTool(\n factoryOrTool: FunctionalTool | ((...deps: never[]) => FunctionalTool),\n inject?: FactoryProvider['inject'],\n): Provider {\n const provide = Symbol('nestjs-agent:functional-tool-instance');\n if (typeof factoryOrTool === 'function') {\n return {\n provide,\n useFactory: (...deps: never[]) => brand(factoryOrTool(...deps)),\n inject: inject ?? [],\n };\n }\n return { provide, useValue: brand(factoryOrTool) };\n}\n","import {\n AgentStreamError,\n type SinkWriter,\n type StreamError,\n type TokenStreamSink,\n} from '@dudousxd/nestjs-agent-core';\n\ninterface RunBuffer {\n chunks: Uint8Array[];\n ended: boolean;\n failure?: StreamError;\n notify: Set<() => void>;\n}\n\n/**\n * The default `TokenStreamSink`: buffers chunks per run in-process so a reconnecting subscriber\n * replays everything so far, then follows live.\n *\n * Single-replica only. Because the buffer lives in one process's memory, a resume/reconnect that\n * lands on a different replica than the one running the turn finds an empty buffer — the stream\n * appears stalled. For multi-replica deployments, supply a shared-transport `TokenStreamSink`\n * (e.g. Redis pub/sub keyed by runId) via `AgentModule.forRoot({ sink })`.\n */\nexport class InProcessTokenStreamSink implements TokenStreamSink {\n private readonly runs = new Map<string, RunBuffer>();\n\n private buffer(runId: string): RunBuffer {\n let buf = this.runs.get(runId);\n if (buf === undefined) {\n buf = { chunks: [], ended: false, notify: new Set() };\n this.runs.set(runId, buf);\n }\n return buf;\n }\n\n private wake(buf: RunBuffer): void {\n for (const resolve of buf.notify) {\n resolve();\n }\n buf.notify.clear();\n }\n\n open(runId: string): SinkWriter {\n const buf = this.buffer(runId);\n return {\n write: (chunk: Uint8Array) => {\n buf.chunks.push(chunk);\n this.wake(buf);\n },\n end: () => {\n buf.ended = true;\n this.wake(buf);\n },\n fail: (error: StreamError) => {\n buf.failure = error;\n buf.ended = true;\n this.wake(buf);\n },\n };\n }\n\n async *subscribe(runId: string): AsyncIterable<Uint8Array> {\n const buf = this.buffer(runId);\n let index = 0;\n while (true) {\n while (index < buf.chunks.length) {\n const chunk = buf.chunks[index];\n index += 1;\n if (chunk !== undefined) {\n yield chunk;\n }\n }\n if (buf.ended) {\n // Drain buffered chunks first, then raise the failure as a typed terminal.\n if (buf.failure !== undefined) {\n throw new AgentStreamError(buf.failure);\n }\n return;\n }\n await new Promise<void>((resolve) => buf.notify.add(resolve));\n }\n }\n\n close(runId: string): void {\n this.runs.delete(runId);\n }\n}\n","import type { AgentStore, QuotaState, QuotaStore } from '@dudousxd/nestjs-agent-core';\n\n/**\n * A production {@link QuotaStore} backed by the persisted usage ledger. `check` reads the actor's\n * tokens-so-far for the day straight from {@link AgentStore.quotaToday} and compares it to a fixed\n * daily limit; `bump` is a deliberate no-op because the loop's `recordUsage` already writes every\n * turn's tokens to that same ledger. One source of truth — so enforcement and what the dashboard\n * reports can never drift, and it works across replicas with no extra shared state.\n */\nexport class LedgerQuotaStore implements QuotaStore {\n constructor(\n private readonly store: AgentStore,\n private readonly limitTokens: number,\n ) {}\n\n async check(actorRef: string, day: string): Promise<QuotaState> {\n const { usedTokens } = await this.store.quotaToday(actorRef, day);\n return {\n usedTokens,\n limitTokens: this.limitTokens,\n withinLimit: usedTokens < this.limitTokens,\n };\n }\n\n async bump(): Promise<void> {\n // No-op: the ledger is the source of truth — recordUsage already persisted this turn's tokens.\n }\n}\n","import {\n AGENT_DEPS_FACTORY,\n AGENT_STORE,\n type Actor,\n type AgentLoopHooks,\n type AgentRunInput,\n type AgentRunner,\n type AgentStore,\n type Decision,\n QuotaExceededError,\n publishAgentRunFailed,\n runAgentLoop,\n} from '@dudousxd/nestjs-agent-core';\nimport { Inject, Injectable, Logger } from '@nestjs/common';\nimport type { AgentDepsFactory } from '../agent-deps.factory.js';\nimport { type AgentDeps, childSinkWriter, utcDay } from '../agent-deps.js';\n\n/**\n * Runs the agent turn in-process. HITL approval resolves a pending promise keyed by\n * `runId:toolCallId`. Sub-agent delegation runs a nested loop that streams into the top-level run's\n * sink (so a human sees it) and shares the same approval mechanism — a sub-agent's action tools go\n * through the same human gate, keyed by the sub-agent's own runId. Single-replica only (the pending\n * map is in-process); durable is the scaled path.\n */\n@Injectable()\nexport class InlineAgentRunner implements AgentRunner {\n private readonly logger = new Logger(InlineAgentRunner.name);\n private readonly pending = new Map<string, (decision: Decision) => void>();\n\n constructor(\n @Inject(AGENT_DEPS_FACTORY) private readonly factory: AgentDepsFactory,\n @Inject(AGENT_STORE) private readonly store: AgentStore,\n ) {}\n\n async start(input: AgentRunInput): Promise<{ runId: string }> {\n const runId = crypto.randomUUID();\n const day = input.day ?? utcDay();\n const deps = this.factory.forAgent(input.agentName);\n const hooks = this.topLevelHooks(runId, deps, input.actor, day);\n\n void runAgentLoop({ ...deps, day }, input, hooks).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 // 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, persona: 'default', 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 return 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 }\n}\n","import type { Actor, ActorResolver } from '@dudousxd/nestjs-agent-core';\n\n/** Read a string header off an unknown transport request, narrowing without trusting its shape. */\nfunction readHeader(req: unknown, name: string): string | undefined {\n if (typeof req !== 'object' || req === null || !('headers' in req)) return undefined;\n const { headers } = req;\n if (typeof headers !== 'object' || headers === null || !(name in headers)) return undefined;\n const value: unknown = Reflect.get(headers, name);\n return typeof value === 'string' ? value : undefined;\n}\n\n/**\n * A development / gateway {@link ActorResolver} that trusts request headers:\n * `x-actor-id` (required), `x-actor-role` (comma-separated → `roles`), `x-tenant-ref`.\n *\n * **Security:** it throws when `x-actor-id` is absent — it never fabricates an identity\n * and never grants a default role (an actor with no `x-actor-role` gets `roles: []`, i.e.\n * no tools). Trusting client headers is only safe behind a gateway that strips and re-sets\n * them from an authenticated principal. Real deployments should provide their own resolver\n * that reads a verified session/JWT instead of installing this one.\n */\nexport class HeaderActorResolver implements ActorResolver {\n resolve(req: unknown): Actor {\n const id = readHeader(req, 'x-actor-id');\n if (id === undefined || id.length === 0) {\n throw new Error(\n 'HeaderActorResolver: missing x-actor-id header. No default actor is fabricated. ' +\n 'Send x-actor-id from a trusted gateway, or configure ' +\n 'AgentModule.forRoot({ actorResolver }) with a resolver that reads your ' +\n 'authenticated principal.',\n );\n }\n const roles = (readHeader(req, 'x-actor-role') ?? '')\n .split(',')\n .map((role) => role.trim())\n .filter((role) => role.length > 0);\n const tenantRef = readHeader(req, 'x-tenant-ref');\n return {\n id,\n roles,\n ...(tenantRef !== undefined ? { tenantRef } : {}),\n };\n }\n}\n"],"mappings":"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","names":["AgentDepsFactory","import_nestjs_agent_core","import_common","import_core","import_nestjs_agent_core","delegateToolName","target","replace","AgentDepsFactory","options","model","store","sink","rolesPolicy","registry","agents","quota","defaultAgentName","defaultAgent","name","effectiveTools","definition","undefined","delegated","delegatesTo","map","tools","length","forAgent","agentName","get","personas","Map","persona","set","id","toolAllowList","followUpsCount","retrieval","systemPrompt","maxSteps","defaultPersona","modelId","toolTimeoutMs","mode","retriever","topK","retrievalTopK","followUps","count","import_nestjs_agent_core","import_common","utcDay","date","Date","toISOString","slice","childSinkWriter","writer","write","chunk","end","fail","AgentService","runner","store","deps","chat","params","agentName","defaultAgentName","threadId","undefined","regenerate","BadRequestException","created","createThread","actor","persona","personaId","forAgent","defaultPersona","id","assertOwnsThread","resolvePersona","input","userText","message","day","utcDay","pageContext","runId","start","setActiveStream","subscribe","sink","approve","toolCallId","runForOwnedToolCall","signal","approved","reject","reason","cancel","assertOwnsActiveStream","personas","get","personaCatalog","values","map","label","listThreads","actorRef","getThread","deleteThread","softDeleteThread","forkThread","fromMessageId","quotaToday","owner","ownerOfThread","NotFoundException","ForbiddenException","ownerOfToolCall","runForToolCall","ownerOfActiveStream","import_nestjs_agent_core","import_common","ChatController","agent","actorResolver","chat","req","res","body","actor","resolve","runId","threadId","message","undefined","agentName","persona","personaId","pageContext","regenerate","pipe","stream","cancel","aborted","setHeader","write","JSON","stringify","decoder","TextDecoder","chunk","subscribe","delta","decode","error","payload","AgentStreamError","code","Error","end","import_nestjs_agent_core","import_common","QuotaController","agent","actorResolver","today","req","actor","resolve","quotaToday","id","import_nestjs_agent_core","import_common","ThreadsController","agent","actorResolver","list","req","actor","resolve","listThreads","id","personas","personaCatalog","detail","getThread","remove","deleteThread","ok","fork","messageId","forkThread","import_nestjs_agent_core","import_common","ToolCallController","agent","actorResolver","approve","req","body","actor","resolve","toolCallId","ok","reject","reason","import_nestjs_agent_core","import_common","AI_TOOL_METADATA","Symbol","AiTool","options","target","Reflect","defineMetadata","readAiToolMetadata","getMetadata","AGENT_TOOL_BRAND","Symbol","for","brand","tool","spec","handler","isBrandedFunctionalTool","value","provideAgentTool","factoryOrTool","inject","provide","useFactory","deps","useValue","AiToolDiscoveryService","logger","Logger","name","discovery","registry","agents","options","onApplicationBootstrap","count","functional","wrapper","getProviders","instance","undefined","isBrandedFunctionalTool","registerFunctionalTool","meta","readAiToolMetadata","handler","execute","warn","register","kind","description","inputSchema","input","roles","ability","ctx","tool","tools","delegates","definition","list","target","delegatesTo","targetDefinition","get","Error","delegateToolName","has","targetBlurb","systemPrompt","targetAgent","z","object","task","string","log","spec","import_nestjs_agent_core","InProcessTokenStreamSink","runs","Map","buffer","runId","buf","get","undefined","chunks","ended","notify","Set","set","wake","resolve","clear","open","write","chunk","push","end","fail","error","failure","subscribe","index","length","AgentStreamError","Promise","add","close","delete","LedgerQuotaStore","store","limitTokens","check","actorRef","day","usedTokens","quotaToday","withinLimit","bump","import_nestjs_agent_core","import_common","InlineAgentRunner","logger","Logger","name","pending","Map","factory","store","start","input","runId","crypto","randomUUID","day","utcDay","deps","forAgent","agentName","hooks","topLevelHooks","actor","runAgentLoop","catch","error","message","Error","String","code","QuotaExceededError","publishAgentRunFailed","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","persona","transient","setActiveStream","childSinkWriter","childName","childTask","threadId","userText","delegationDepth","FEATURE_INIT","Symbol","DEFAULT_PATH","defaultDefinition","options","name","defaultAgent","sharedProviders","durable","includeStore","providers","provide","AGENT_TOOL_REGISTRY","useFactory","ToolRegistry","AGENT_REGISTRY","registry","AgentRegistry","register","inject","AGENT_OPTIONS","AGENT_SINK","sink","InProcessTokenStreamSink","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","AiToolDiscoveryService","InlineAgentRunner","AgentService","push","AGENT_RUNNER","durableRunner","Error","token","AGENT_DURABLE_RUNNER","optional","exportsFor","CONTROLLERS","ChatController","ThreadsController","ToolCallController","QuotaController","routerFor","path","RouterModule","module","AgentModule","forRoot","global","imports","DiscoveryModule","controllers","useValue","exports","forRootAsync","forFeature","definitions","definition","readHeader","req","name","undefined","headers","value","Reflect","get","HeaderActorResolver","resolve","id","length","Error","roles","split","map","role","trim","filter","tenantRef"]}
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
import { AgentDefinition, AgentRunner, AgentStore, Actor, PageContext, Persona, ThreadSummary, ThreadDetail, ToolRegistry, AgentRegistry, AgentRunInput, Decision, TokenStreamSink, SinkWriter, QuotaStore, QuotaState, ActorResolver } from '@dudousxd/nestjs-agent-core';
|
|
2
|
+
export * from '@dudousxd/nestjs-agent-core';
|
|
3
|
+
import { DynamicModule, OnApplicationBootstrap } from '@nestjs/common';
|
|
4
|
+
import { a as AgentModuleOptions, b as AgentModuleAsyncOptions, A as AgentDepsFactory } from './agent-deps.factory-D9BHJJqm.cjs';
|
|
5
|
+
export { c as AGENT_TOOL_BRAND, d as AgentDeps, D as DefaultAgentOptions, F as FunctionalTool, e as delegateToolName, p as provideAgentTool, u as utcDay } from './agent-deps.factory-D9BHJJqm.cjs';
|
|
6
|
+
import { StandardSchemaV1 } from '@standard-schema/spec';
|
|
7
|
+
import { DiscoveryService } from '@nestjs/core';
|
|
8
|
+
|
|
9
|
+
declare class AgentModule {
|
|
10
|
+
static forRoot(options: AgentModuleOptions): DynamicModule;
|
|
11
|
+
static forRootAsync(options: AgentModuleAsyncOptions): DynamicModule;
|
|
12
|
+
/** Register additional named agents (an orchestrator + its sub-agents). */
|
|
13
|
+
static forFeature(definitions: AgentDefinition[]): DynamicModule;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
interface ChatParams {
|
|
17
|
+
actor: Actor;
|
|
18
|
+
message: string;
|
|
19
|
+
threadId?: string;
|
|
20
|
+
agentName?: string;
|
|
21
|
+
personaId?: string;
|
|
22
|
+
pageContext?: PageContext;
|
|
23
|
+
/** Re-run the last exchange instead of adding a new message. Requires an existing `threadId`. */
|
|
24
|
+
regenerate?: boolean;
|
|
25
|
+
}
|
|
26
|
+
/** The orchestration facade the controllers call. */
|
|
27
|
+
declare class AgentService {
|
|
28
|
+
private readonly runner;
|
|
29
|
+
private readonly store;
|
|
30
|
+
private readonly deps;
|
|
31
|
+
constructor(runner: AgentRunner, store: AgentStore, deps: AgentDepsFactory);
|
|
32
|
+
chat(params: ChatParams): Promise<{
|
|
33
|
+
runId: string;
|
|
34
|
+
threadId: string;
|
|
35
|
+
}>;
|
|
36
|
+
subscribe(runId: string): AsyncIterable<Uint8Array>;
|
|
37
|
+
approve(actor: Actor, toolCallId: string): Promise<void>;
|
|
38
|
+
reject(actor: Actor, toolCallId: string, reason?: string): Promise<void>;
|
|
39
|
+
cancel(actor: Actor, runId: string): Promise<void>;
|
|
40
|
+
resolvePersona(agentName?: string, id?: string): Persona | undefined;
|
|
41
|
+
personaCatalog(agentName?: string): {
|
|
42
|
+
id: string;
|
|
43
|
+
label: string;
|
|
44
|
+
}[];
|
|
45
|
+
listThreads(actorRef: string): Promise<ThreadSummary[]>;
|
|
46
|
+
getThread(actor: Actor, threadId: string): Promise<ThreadDetail | null>;
|
|
47
|
+
deleteThread(actor: Actor, threadId: string): Promise<void>;
|
|
48
|
+
forkThread(actor: Actor, threadId: string, fromMessageId: string): Promise<ThreadSummary>;
|
|
49
|
+
quotaToday(actorRef: string): Promise<{
|
|
50
|
+
usedTokens: number;
|
|
51
|
+
}>;
|
|
52
|
+
/**
|
|
53
|
+
* Authorization seam for thread-scoped endpoints: the caller must own the thread. A missing
|
|
54
|
+
* thread is a 404; someone else's thread is a 403 — one actor never touches another's thread.
|
|
55
|
+
*/
|
|
56
|
+
private assertOwnsThread;
|
|
57
|
+
/**
|
|
58
|
+
* Authorization + routing seam for HITL approve/reject: assert the caller owns the tool call's
|
|
59
|
+
* thread, then resolve the run currently awaiting that call (its thread's active stream). That run
|
|
60
|
+
* is the sub-agent's own child run when the pending call belongs to a delegated agent — the client
|
|
61
|
+
* never knows or supplies a runId; it is derived here from the tool call alone.
|
|
62
|
+
*/
|
|
63
|
+
private runForOwnedToolCall;
|
|
64
|
+
/** Authorization seam for `cancel`: the caller must own the thread currently streaming this run. */
|
|
65
|
+
private assertOwnsActiveStream;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
declare const AI_TOOL_METADATA: unique symbol;
|
|
69
|
+
interface AiToolOptions {
|
|
70
|
+
name: string;
|
|
71
|
+
/**
|
|
72
|
+
* `read` auto-executes; `action` requires HITL approval. (Core's `ToolKind` also has `agent`
|
|
73
|
+
* for delegation, but that kind is synthesized from `delegatesTo` — never authored here.)
|
|
74
|
+
*/
|
|
75
|
+
kind: 'read' | 'action';
|
|
76
|
+
description: string;
|
|
77
|
+
/**
|
|
78
|
+
* Input schema as a [Standard Schema](https://standardschema.dev) — Zod, Valibot, or ArkType.
|
|
79
|
+
* Validated before the handler runs.
|
|
80
|
+
*/
|
|
81
|
+
input: StandardSchemaV1;
|
|
82
|
+
/** Roles allowed to invoke. Omit to inherit the module's default roles. */
|
|
83
|
+
roles?: string[];
|
|
84
|
+
/**
|
|
85
|
+
* Authz ability checked by an ability-aware RolesPolicy (e.g. `AgentAuthzModule`'s
|
|
86
|
+
* `AuthzRolesPolicy` → `gate.forUser(actor).allows(ability)`). Ignored by the default
|
|
87
|
+
* role-based policy, which uses `roles`.
|
|
88
|
+
*/
|
|
89
|
+
ability?: string;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Marks a provider class as an AI tool. The class must implement `execute(input, ctx)`.
|
|
93
|
+
* `AiToolDiscoveryService` registers every `@AiTool` provider into the `ToolRegistry` at boot.
|
|
94
|
+
*
|
|
95
|
+
* ```ts
|
|
96
|
+
* @AiTool({ name: 'getWeather', kind: 'read', description: '...', input: z.object({ city: z.string() }) })
|
|
97
|
+
* class GetWeatherTool implements ToolHandler<{ city: string }> {
|
|
98
|
+
* async execute(input, ctx) { return { tempC: 21 }; }
|
|
99
|
+
* }
|
|
100
|
+
* ```
|
|
101
|
+
*/
|
|
102
|
+
declare function AiTool(options: AiToolOptions): ClassDecorator;
|
|
103
|
+
declare function readAiToolMetadata(target: object): AiToolOptions | undefined;
|
|
104
|
+
|
|
105
|
+
/** Walks every provider at boot and registers `@AiTool` classes into the shared registry. */
|
|
106
|
+
declare class AiToolDiscoveryService implements OnApplicationBootstrap {
|
|
107
|
+
private readonly discovery;
|
|
108
|
+
private readonly registry;
|
|
109
|
+
private readonly agents;
|
|
110
|
+
private readonly options;
|
|
111
|
+
private readonly logger;
|
|
112
|
+
constructor(discovery: DiscoveryService, registry: ToolRegistry, agents: AgentRegistry, options: AgentModuleOptions);
|
|
113
|
+
onApplicationBootstrap(): void;
|
|
114
|
+
/**
|
|
115
|
+
* Registers a functional tool's `{ spec, handler }`, skipping it if a tool of the same name is
|
|
116
|
+
* already registered. Returns whether it was newly registered.
|
|
117
|
+
*/
|
|
118
|
+
private registerFunctionalTool;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Runs the agent turn in-process. HITL approval resolves a pending promise keyed by
|
|
123
|
+
* `runId:toolCallId`. Sub-agent delegation runs a nested loop that streams into the top-level run's
|
|
124
|
+
* sink (so a human sees it) and shares the same approval mechanism — a sub-agent's action tools go
|
|
125
|
+
* through the same human gate, keyed by the sub-agent's own runId. Single-replica only (the pending
|
|
126
|
+
* map is in-process); durable is the scaled path.
|
|
127
|
+
*/
|
|
128
|
+
declare class InlineAgentRunner implements AgentRunner {
|
|
129
|
+
private readonly factory;
|
|
130
|
+
private readonly store;
|
|
131
|
+
private readonly logger;
|
|
132
|
+
private readonly pending;
|
|
133
|
+
constructor(factory: AgentDepsFactory, store: AgentStore);
|
|
134
|
+
start(input: AgentRunInput): Promise<{
|
|
135
|
+
runId: string;
|
|
136
|
+
}>;
|
|
137
|
+
signal(runId: string, toolCallId: string, decision: Decision): Promise<void>;
|
|
138
|
+
cancel(runId: string): Promise<void>;
|
|
139
|
+
private topLevelHooks;
|
|
140
|
+
/**
|
|
141
|
+
* Delegate to another agent as a nested in-process run. The sub-agent streams into `sinkRunId`
|
|
142
|
+
* (the top-level run the human is watching) so its output and any pending action tool are visible,
|
|
143
|
+
* and its own approvals resolve through the shared pending map keyed by its own runId.
|
|
144
|
+
*/
|
|
145
|
+
private runNested;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* The default `TokenStreamSink`: buffers chunks per run in-process so a reconnecting subscriber
|
|
150
|
+
* replays everything so far, then follows live.
|
|
151
|
+
*
|
|
152
|
+
* Single-replica only. Because the buffer lives in one process's memory, a resume/reconnect that
|
|
153
|
+
* lands on a different replica than the one running the turn finds an empty buffer — the stream
|
|
154
|
+
* appears stalled. For multi-replica deployments, supply a shared-transport `TokenStreamSink`
|
|
155
|
+
* (e.g. Redis pub/sub keyed by runId) via `AgentModule.forRoot({ sink })`.
|
|
156
|
+
*/
|
|
157
|
+
declare class InProcessTokenStreamSink implements TokenStreamSink {
|
|
158
|
+
private readonly runs;
|
|
159
|
+
private buffer;
|
|
160
|
+
private wake;
|
|
161
|
+
open(runId: string): SinkWriter;
|
|
162
|
+
subscribe(runId: string): AsyncIterable<Uint8Array>;
|
|
163
|
+
close(runId: string): void;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* A production {@link QuotaStore} backed by the persisted usage ledger. `check` reads the actor's
|
|
168
|
+
* tokens-so-far for the day straight from {@link AgentStore.quotaToday} and compares it to a fixed
|
|
169
|
+
* daily limit; `bump` is a deliberate no-op because the loop's `recordUsage` already writes every
|
|
170
|
+
* turn's tokens to that same ledger. One source of truth — so enforcement and what the dashboard
|
|
171
|
+
* reports can never drift, and it works across replicas with no extra shared state.
|
|
172
|
+
*/
|
|
173
|
+
declare class LedgerQuotaStore implements QuotaStore {
|
|
174
|
+
private readonly store;
|
|
175
|
+
private readonly limitTokens;
|
|
176
|
+
constructor(store: AgentStore, limitTokens: number);
|
|
177
|
+
check(actorRef: string, day: string): Promise<QuotaState>;
|
|
178
|
+
bump(): Promise<void>;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* A development / gateway {@link ActorResolver} that trusts request headers:
|
|
183
|
+
* `x-actor-id` (required), `x-actor-role` (comma-separated → `roles`), `x-tenant-ref`.
|
|
184
|
+
*
|
|
185
|
+
* **Security:** it throws when `x-actor-id` is absent — it never fabricates an identity
|
|
186
|
+
* and never grants a default role (an actor with no `x-actor-role` gets `roles: []`, i.e.
|
|
187
|
+
* no tools). Trusting client headers is only safe behind a gateway that strips and re-sets
|
|
188
|
+
* them from an authenticated principal. Real deployments should provide their own resolver
|
|
189
|
+
* that reads a verified session/JWT instead of installing this one.
|
|
190
|
+
*/
|
|
191
|
+
declare class HeaderActorResolver implements ActorResolver {
|
|
192
|
+
resolve(req: unknown): Actor;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
export { AI_TOOL_METADATA, AgentDepsFactory, AgentModule, AgentModuleAsyncOptions, AgentModuleOptions, AgentService, AiTool, AiToolDiscoveryService, type AiToolOptions, type ChatParams, HeaderActorResolver, InProcessTokenStreamSink, InlineAgentRunner, LedgerQuotaStore, readAiToolMetadata };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
import { AgentDefinition, AgentRunner, AgentStore, Actor, PageContext, Persona, ThreadSummary, ThreadDetail, ToolRegistry, AgentRegistry, AgentRunInput, Decision, TokenStreamSink, SinkWriter, QuotaStore, QuotaState, ActorResolver } from '@dudousxd/nestjs-agent-core';
|
|
2
|
+
export * from '@dudousxd/nestjs-agent-core';
|
|
3
|
+
import { DynamicModule, OnApplicationBootstrap } from '@nestjs/common';
|
|
4
|
+
import { a as AgentModuleOptions, b as AgentModuleAsyncOptions, A as AgentDepsFactory } from './agent-deps.factory-D9BHJJqm.js';
|
|
5
|
+
export { c as AGENT_TOOL_BRAND, d as AgentDeps, D as DefaultAgentOptions, F as FunctionalTool, e as delegateToolName, p as provideAgentTool, u as utcDay } from './agent-deps.factory-D9BHJJqm.js';
|
|
6
|
+
import { StandardSchemaV1 } from '@standard-schema/spec';
|
|
7
|
+
import { DiscoveryService } from '@nestjs/core';
|
|
8
|
+
|
|
9
|
+
declare class AgentModule {
|
|
10
|
+
static forRoot(options: AgentModuleOptions): DynamicModule;
|
|
11
|
+
static forRootAsync(options: AgentModuleAsyncOptions): DynamicModule;
|
|
12
|
+
/** Register additional named agents (an orchestrator + its sub-agents). */
|
|
13
|
+
static forFeature(definitions: AgentDefinition[]): DynamicModule;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
interface ChatParams {
|
|
17
|
+
actor: Actor;
|
|
18
|
+
message: string;
|
|
19
|
+
threadId?: string;
|
|
20
|
+
agentName?: string;
|
|
21
|
+
personaId?: string;
|
|
22
|
+
pageContext?: PageContext;
|
|
23
|
+
/** Re-run the last exchange instead of adding a new message. Requires an existing `threadId`. */
|
|
24
|
+
regenerate?: boolean;
|
|
25
|
+
}
|
|
26
|
+
/** The orchestration facade the controllers call. */
|
|
27
|
+
declare class AgentService {
|
|
28
|
+
private readonly runner;
|
|
29
|
+
private readonly store;
|
|
30
|
+
private readonly deps;
|
|
31
|
+
constructor(runner: AgentRunner, store: AgentStore, deps: AgentDepsFactory);
|
|
32
|
+
chat(params: ChatParams): Promise<{
|
|
33
|
+
runId: string;
|
|
34
|
+
threadId: string;
|
|
35
|
+
}>;
|
|
36
|
+
subscribe(runId: string): AsyncIterable<Uint8Array>;
|
|
37
|
+
approve(actor: Actor, toolCallId: string): Promise<void>;
|
|
38
|
+
reject(actor: Actor, toolCallId: string, reason?: string): Promise<void>;
|
|
39
|
+
cancel(actor: Actor, runId: string): Promise<void>;
|
|
40
|
+
resolvePersona(agentName?: string, id?: string): Persona | undefined;
|
|
41
|
+
personaCatalog(agentName?: string): {
|
|
42
|
+
id: string;
|
|
43
|
+
label: string;
|
|
44
|
+
}[];
|
|
45
|
+
listThreads(actorRef: string): Promise<ThreadSummary[]>;
|
|
46
|
+
getThread(actor: Actor, threadId: string): Promise<ThreadDetail | null>;
|
|
47
|
+
deleteThread(actor: Actor, threadId: string): Promise<void>;
|
|
48
|
+
forkThread(actor: Actor, threadId: string, fromMessageId: string): Promise<ThreadSummary>;
|
|
49
|
+
quotaToday(actorRef: string): Promise<{
|
|
50
|
+
usedTokens: number;
|
|
51
|
+
}>;
|
|
52
|
+
/**
|
|
53
|
+
* Authorization seam for thread-scoped endpoints: the caller must own the thread. A missing
|
|
54
|
+
* thread is a 404; someone else's thread is a 403 — one actor never touches another's thread.
|
|
55
|
+
*/
|
|
56
|
+
private assertOwnsThread;
|
|
57
|
+
/**
|
|
58
|
+
* Authorization + routing seam for HITL approve/reject: assert the caller owns the tool call's
|
|
59
|
+
* thread, then resolve the run currently awaiting that call (its thread's active stream). That run
|
|
60
|
+
* is the sub-agent's own child run when the pending call belongs to a delegated agent — the client
|
|
61
|
+
* never knows or supplies a runId; it is derived here from the tool call alone.
|
|
62
|
+
*/
|
|
63
|
+
private runForOwnedToolCall;
|
|
64
|
+
/** Authorization seam for `cancel`: the caller must own the thread currently streaming this run. */
|
|
65
|
+
private assertOwnsActiveStream;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
declare const AI_TOOL_METADATA: unique symbol;
|
|
69
|
+
interface AiToolOptions {
|
|
70
|
+
name: string;
|
|
71
|
+
/**
|
|
72
|
+
* `read` auto-executes; `action` requires HITL approval. (Core's `ToolKind` also has `agent`
|
|
73
|
+
* for delegation, but that kind is synthesized from `delegatesTo` — never authored here.)
|
|
74
|
+
*/
|
|
75
|
+
kind: 'read' | 'action';
|
|
76
|
+
description: string;
|
|
77
|
+
/**
|
|
78
|
+
* Input schema as a [Standard Schema](https://standardschema.dev) — Zod, Valibot, or ArkType.
|
|
79
|
+
* Validated before the handler runs.
|
|
80
|
+
*/
|
|
81
|
+
input: StandardSchemaV1;
|
|
82
|
+
/** Roles allowed to invoke. Omit to inherit the module's default roles. */
|
|
83
|
+
roles?: string[];
|
|
84
|
+
/**
|
|
85
|
+
* Authz ability checked by an ability-aware RolesPolicy (e.g. `AgentAuthzModule`'s
|
|
86
|
+
* `AuthzRolesPolicy` → `gate.forUser(actor).allows(ability)`). Ignored by the default
|
|
87
|
+
* role-based policy, which uses `roles`.
|
|
88
|
+
*/
|
|
89
|
+
ability?: string;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Marks a provider class as an AI tool. The class must implement `execute(input, ctx)`.
|
|
93
|
+
* `AiToolDiscoveryService` registers every `@AiTool` provider into the `ToolRegistry` at boot.
|
|
94
|
+
*
|
|
95
|
+
* ```ts
|
|
96
|
+
* @AiTool({ name: 'getWeather', kind: 'read', description: '...', input: z.object({ city: z.string() }) })
|
|
97
|
+
* class GetWeatherTool implements ToolHandler<{ city: string }> {
|
|
98
|
+
* async execute(input, ctx) { return { tempC: 21 }; }
|
|
99
|
+
* }
|
|
100
|
+
* ```
|
|
101
|
+
*/
|
|
102
|
+
declare function AiTool(options: AiToolOptions): ClassDecorator;
|
|
103
|
+
declare function readAiToolMetadata(target: object): AiToolOptions | undefined;
|
|
104
|
+
|
|
105
|
+
/** Walks every provider at boot and registers `@AiTool` classes into the shared registry. */
|
|
106
|
+
declare class AiToolDiscoveryService implements OnApplicationBootstrap {
|
|
107
|
+
private readonly discovery;
|
|
108
|
+
private readonly registry;
|
|
109
|
+
private readonly agents;
|
|
110
|
+
private readonly options;
|
|
111
|
+
private readonly logger;
|
|
112
|
+
constructor(discovery: DiscoveryService, registry: ToolRegistry, agents: AgentRegistry, options: AgentModuleOptions);
|
|
113
|
+
onApplicationBootstrap(): void;
|
|
114
|
+
/**
|
|
115
|
+
* Registers a functional tool's `{ spec, handler }`, skipping it if a tool of the same name is
|
|
116
|
+
* already registered. Returns whether it was newly registered.
|
|
117
|
+
*/
|
|
118
|
+
private registerFunctionalTool;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Runs the agent turn in-process. HITL approval resolves a pending promise keyed by
|
|
123
|
+
* `runId:toolCallId`. Sub-agent delegation runs a nested loop that streams into the top-level run's
|
|
124
|
+
* sink (so a human sees it) and shares the same approval mechanism — a sub-agent's action tools go
|
|
125
|
+
* through the same human gate, keyed by the sub-agent's own runId. Single-replica only (the pending
|
|
126
|
+
* map is in-process); durable is the scaled path.
|
|
127
|
+
*/
|
|
128
|
+
declare class InlineAgentRunner implements AgentRunner {
|
|
129
|
+
private readonly factory;
|
|
130
|
+
private readonly store;
|
|
131
|
+
private readonly logger;
|
|
132
|
+
private readonly pending;
|
|
133
|
+
constructor(factory: AgentDepsFactory, store: AgentStore);
|
|
134
|
+
start(input: AgentRunInput): Promise<{
|
|
135
|
+
runId: string;
|
|
136
|
+
}>;
|
|
137
|
+
signal(runId: string, toolCallId: string, decision: Decision): Promise<void>;
|
|
138
|
+
cancel(runId: string): Promise<void>;
|
|
139
|
+
private topLevelHooks;
|
|
140
|
+
/**
|
|
141
|
+
* Delegate to another agent as a nested in-process run. The sub-agent streams into `sinkRunId`
|
|
142
|
+
* (the top-level run the human is watching) so its output and any pending action tool are visible,
|
|
143
|
+
* and its own approvals resolve through the shared pending map keyed by its own runId.
|
|
144
|
+
*/
|
|
145
|
+
private runNested;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* The default `TokenStreamSink`: buffers chunks per run in-process so a reconnecting subscriber
|
|
150
|
+
* replays everything so far, then follows live.
|
|
151
|
+
*
|
|
152
|
+
* Single-replica only. Because the buffer lives in one process's memory, a resume/reconnect that
|
|
153
|
+
* lands on a different replica than the one running the turn finds an empty buffer — the stream
|
|
154
|
+
* appears stalled. For multi-replica deployments, supply a shared-transport `TokenStreamSink`
|
|
155
|
+
* (e.g. Redis pub/sub keyed by runId) via `AgentModule.forRoot({ sink })`.
|
|
156
|
+
*/
|
|
157
|
+
declare class InProcessTokenStreamSink implements TokenStreamSink {
|
|
158
|
+
private readonly runs;
|
|
159
|
+
private buffer;
|
|
160
|
+
private wake;
|
|
161
|
+
open(runId: string): SinkWriter;
|
|
162
|
+
subscribe(runId: string): AsyncIterable<Uint8Array>;
|
|
163
|
+
close(runId: string): void;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* A production {@link QuotaStore} backed by the persisted usage ledger. `check` reads the actor's
|
|
168
|
+
* tokens-so-far for the day straight from {@link AgentStore.quotaToday} and compares it to a fixed
|
|
169
|
+
* daily limit; `bump` is a deliberate no-op because the loop's `recordUsage` already writes every
|
|
170
|
+
* turn's tokens to that same ledger. One source of truth — so enforcement and what the dashboard
|
|
171
|
+
* reports can never drift, and it works across replicas with no extra shared state.
|
|
172
|
+
*/
|
|
173
|
+
declare class LedgerQuotaStore implements QuotaStore {
|
|
174
|
+
private readonly store;
|
|
175
|
+
private readonly limitTokens;
|
|
176
|
+
constructor(store: AgentStore, limitTokens: number);
|
|
177
|
+
check(actorRef: string, day: string): Promise<QuotaState>;
|
|
178
|
+
bump(): Promise<void>;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* A development / gateway {@link ActorResolver} that trusts request headers:
|
|
183
|
+
* `x-actor-id` (required), `x-actor-role` (comma-separated → `roles`), `x-tenant-ref`.
|
|
184
|
+
*
|
|
185
|
+
* **Security:** it throws when `x-actor-id` is absent — it never fabricates an identity
|
|
186
|
+
* and never grants a default role (an actor with no `x-actor-role` gets `roles: []`, i.e.
|
|
187
|
+
* no tools). Trusting client headers is only safe behind a gateway that strips and re-sets
|
|
188
|
+
* them from an authenticated principal. Real deployments should provide their own resolver
|
|
189
|
+
* that reads a verified session/JWT instead of installing this one.
|
|
190
|
+
*/
|
|
191
|
+
declare class HeaderActorResolver implements ActorResolver {
|
|
192
|
+
resolve(req: unknown): Actor;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
export { AI_TOOL_METADATA, AgentDepsFactory, AgentModule, AgentModuleAsyncOptions, AgentModuleOptions, AgentService, AiTool, AiToolDiscoveryService, type AiToolOptions, type ChatParams, HeaderActorResolver, InProcessTokenStreamSink, InlineAgentRunner, LedgerQuotaStore, readAiToolMetadata };
|