@dudousxd/nestjs-agent-core 0.3.0 → 0.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +148 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +99 -5
- package/dist/index.d.ts +99 -5
- package/dist/index.js +142 -0
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -46,6 +46,12 @@ __export(index_exports, {
|
|
|
46
46
|
ToolInputInvalidError: () => ToolInputInvalidError,
|
|
47
47
|
ToolNotFoundError: () => ToolNotFoundError,
|
|
48
48
|
ToolRegistry: () => ToolRegistry,
|
|
49
|
+
bucketByActor: () => bucketByActor,
|
|
50
|
+
bucketByModel: () => bucketByModel,
|
|
51
|
+
bucketByThread: () => bucketByThread,
|
|
52
|
+
bucketUsageTrend: () => bucketUsageTrend,
|
|
53
|
+
dayBoundsUtc: () => dayBoundsUtc,
|
|
54
|
+
estimateCost: () => estimateCost,
|
|
49
55
|
filterToolsByAllowList: () => filterToolsByAllowList,
|
|
50
56
|
filterToolsByRole: () => filterToolsByRole,
|
|
51
57
|
publishAgentDelegated: () => publishAgentDelegated,
|
|
@@ -101,6 +107,142 @@ async function seedModelPrices(store, prices) {
|
|
|
101
107
|
}
|
|
102
108
|
__name(seedModelPrices, "seedModelPrices");
|
|
103
109
|
|
|
110
|
+
// src/governance/compute.ts
|
|
111
|
+
function estimateCost(usage, price) {
|
|
112
|
+
if (price === void 0) {
|
|
113
|
+
return 0;
|
|
114
|
+
}
|
|
115
|
+
const cacheWriteTokens = usage.cacheWriteTokens ?? 0;
|
|
116
|
+
const cacheReadTokens = usage.cacheReadTokens ?? 0;
|
|
117
|
+
const uncachedInputTokens = usage.inputTokens - cacheWriteTokens - cacheReadTokens;
|
|
118
|
+
return uncachedInputTokens / 1e6 * price.inputPricePer1m + cacheWriteTokens / 1e6 * (price.cacheWritePricePer1m ?? price.inputPricePer1m) + cacheReadTokens / 1e6 * (price.cacheReadPricePer1m ?? price.inputPricePer1m) + usage.outputTokens / 1e6 * price.outputPricePer1m;
|
|
119
|
+
}
|
|
120
|
+
__name(estimateCost, "estimateCost");
|
|
121
|
+
function rowCost(row, prices) {
|
|
122
|
+
return row.costUsd ?? estimateCost(row, prices.get(row.modelId));
|
|
123
|
+
}
|
|
124
|
+
__name(rowCost, "rowCost");
|
|
125
|
+
function bucketByModel(rows, prices) {
|
|
126
|
+
const byModel = /* @__PURE__ */ new Map();
|
|
127
|
+
for (const row of rows) {
|
|
128
|
+
const bucket = byModel.get(row.modelId) ?? {
|
|
129
|
+
requests: 0,
|
|
130
|
+
inputTokens: 0,
|
|
131
|
+
outputTokens: 0,
|
|
132
|
+
costUsd: 0
|
|
133
|
+
};
|
|
134
|
+
bucket.requests += 1;
|
|
135
|
+
bucket.inputTokens += row.inputTokens;
|
|
136
|
+
bucket.outputTokens += row.outputTokens;
|
|
137
|
+
bucket.costUsd += rowCost(row, prices);
|
|
138
|
+
byModel.set(row.modelId, bucket);
|
|
139
|
+
}
|
|
140
|
+
const result = [];
|
|
141
|
+
for (const [modelId, bucket] of byModel) {
|
|
142
|
+
result.push({
|
|
143
|
+
modelId,
|
|
144
|
+
requests: bucket.requests,
|
|
145
|
+
inputTokens: bucket.inputTokens,
|
|
146
|
+
outputTokens: bucket.outputTokens,
|
|
147
|
+
costUsd: bucket.costUsd
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
result.sort((left, right) => right.costUsd - left.costUsd || left.modelId.localeCompare(right.modelId));
|
|
151
|
+
return result;
|
|
152
|
+
}
|
|
153
|
+
__name(bucketByModel, "bucketByModel");
|
|
154
|
+
function bucketByActor(rows, prices) {
|
|
155
|
+
const byActor = /* @__PURE__ */ new Map();
|
|
156
|
+
for (const row of rows) {
|
|
157
|
+
const bucket = byActor.get(row.actorRef) ?? {
|
|
158
|
+
requests: 0,
|
|
159
|
+
totalTokens: 0,
|
|
160
|
+
costUsd: 0,
|
|
161
|
+
threadIds: /* @__PURE__ */ new Set()
|
|
162
|
+
};
|
|
163
|
+
bucket.requests += 1;
|
|
164
|
+
bucket.totalTokens += row.inputTokens + row.outputTokens;
|
|
165
|
+
bucket.costUsd += rowCost(row, prices);
|
|
166
|
+
bucket.threadIds.add(row.threadId);
|
|
167
|
+
byActor.set(row.actorRef, bucket);
|
|
168
|
+
}
|
|
169
|
+
const result = [];
|
|
170
|
+
for (const [actorRef, bucket] of byActor) {
|
|
171
|
+
result.push({
|
|
172
|
+
actorRef,
|
|
173
|
+
requests: bucket.requests,
|
|
174
|
+
totalTokens: bucket.totalTokens,
|
|
175
|
+
costUsd: bucket.costUsd,
|
|
176
|
+
threadCount: bucket.threadIds.size
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
result.sort((left, right) => right.costUsd - left.costUsd || left.actorRef.localeCompare(right.actorRef));
|
|
180
|
+
return result;
|
|
181
|
+
}
|
|
182
|
+
__name(bucketByActor, "bucketByActor");
|
|
183
|
+
function bucketByThread(rows, prices, threads, options) {
|
|
184
|
+
const byThread = /* @__PURE__ */ new Map();
|
|
185
|
+
for (const row of rows) {
|
|
186
|
+
const bucket = byThread.get(row.threadId) ?? {
|
|
187
|
+
requests: 0,
|
|
188
|
+
totalTokens: 0,
|
|
189
|
+
costUsd: 0
|
|
190
|
+
};
|
|
191
|
+
bucket.requests += 1;
|
|
192
|
+
bucket.totalTokens += row.inputTokens + row.outputTokens;
|
|
193
|
+
bucket.costUsd += rowCost(row, prices);
|
|
194
|
+
byThread.set(row.threadId, bucket);
|
|
195
|
+
}
|
|
196
|
+
const result = [];
|
|
197
|
+
for (const [threadId, bucket] of byThread) {
|
|
198
|
+
const thread = threads.get(threadId);
|
|
199
|
+
if (thread === void 0 && !options.includeUnknownThreads) {
|
|
200
|
+
continue;
|
|
201
|
+
}
|
|
202
|
+
result.push({
|
|
203
|
+
threadId,
|
|
204
|
+
title: thread?.title ?? "",
|
|
205
|
+
actorRef: thread?.actorRef ?? "",
|
|
206
|
+
requests: bucket.requests,
|
|
207
|
+
totalTokens: bucket.totalTokens,
|
|
208
|
+
costUsd: bucket.costUsd
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
result.sort((left, right) => right.costUsd - left.costUsd || left.threadId.localeCompare(right.threadId));
|
|
212
|
+
return result.slice(0, options.limit);
|
|
213
|
+
}
|
|
214
|
+
__name(bucketByThread, "bucketByThread");
|
|
215
|
+
function bucketUsageTrend(rows, prices) {
|
|
216
|
+
const byDay = /* @__PURE__ */ new Map();
|
|
217
|
+
for (const row of rows) {
|
|
218
|
+
const bucket = byDay.get(row.day) ?? {
|
|
219
|
+
totalTokens: 0,
|
|
220
|
+
costUsd: 0
|
|
221
|
+
};
|
|
222
|
+
bucket.totalTokens += row.inputTokens + row.outputTokens;
|
|
223
|
+
bucket.costUsd += rowCost(row, prices);
|
|
224
|
+
byDay.set(row.day, bucket);
|
|
225
|
+
}
|
|
226
|
+
const result = [];
|
|
227
|
+
for (const [day, bucket] of byDay) {
|
|
228
|
+
result.push({
|
|
229
|
+
day,
|
|
230
|
+
totalTokens: bucket.totalTokens,
|
|
231
|
+
costUsd: bucket.costUsd
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
result.sort((left, right) => left.day.localeCompare(right.day));
|
|
235
|
+
return result;
|
|
236
|
+
}
|
|
237
|
+
__name(bucketUsageTrend, "bucketUsageTrend");
|
|
238
|
+
function dayBoundsUtc(range) {
|
|
239
|
+
return {
|
|
240
|
+
start: /* @__PURE__ */ new Date(`${range.fromDay}T00:00:00.000Z`),
|
|
241
|
+
end: /* @__PURE__ */ new Date(`${range.toDay}T23:59:59.999Z`)
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
__name(dayBoundsUtc, "dayBoundsUtc");
|
|
245
|
+
|
|
104
246
|
// src/tool-filters.ts
|
|
105
247
|
async function filterToolsByRole(tools, actor, policy) {
|
|
106
248
|
const checked = await Promise.all(tools.map(async (tool) => ({
|
|
@@ -782,6 +924,12 @@ __name(runAgentLoop, "runAgentLoop");
|
|
|
782
924
|
ToolInputInvalidError,
|
|
783
925
|
ToolNotFoundError,
|
|
784
926
|
ToolRegistry,
|
|
927
|
+
bucketByActor,
|
|
928
|
+
bucketByModel,
|
|
929
|
+
bucketByThread,
|
|
930
|
+
bucketUsageTrend,
|
|
931
|
+
dayBoundsUtc,
|
|
932
|
+
estimateCost,
|
|
785
933
|
filterToolsByAllowList,
|
|
786
934
|
filterToolsByRole,
|
|
787
935
|
publishAgentDelegated,
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/tokens.ts","../src/spi/token-stream-sink.ts","../src/spi/pricing-store.ts","../src/tool-filters.ts","../src/agent-registry.ts","../src/tool-registry.ts","../src/diagnostics.ts","../src/agent-loop.ts"],"sourcesContent":["export * from './types.js';\nexport * from './tokens.js';\nexport * from './spi/tool.js';\nexport * from './spi/model-provider.js';\nexport * from './spi/token-stream-sink.js';\nexport * from './spi/agent-store.js';\nexport * from './spi/roles-policy.js';\nexport * from './spi/quota-store.js';\nexport * from './spi/pricing-store.js';\nexport * from './spi/retriever.js';\nexport * from './spi/embedding-provider.js';\nexport * from './spi/reranker.js';\nexport * from './spi/agent-runner.js';\nexport * from './spi/actor-resolver.js';\nexport * from './spi/governance-queries.js';\nexport * from './tool-filters.js';\nexport { AgentRegistry } from './agent-registry.js';\nexport {\n ToolRegistry,\n DefaultRolesPolicy,\n ToolForbiddenError,\n ToolNotFoundError,\n ToolInputInvalidError,\n} from './tool-registry.js';\nexport {\n runAgentLoop,\n QuotaExceededError,\n type AgentLoopDeps,\n type AgentLoopHooks,\n} from './agent-loop.js';\nexport * from './diagnostics.js';\n","/**\n * Public, cross-lib-discoverable DI tokens.\n *\n * These use `Symbol.for(...)` (the global symbol registry) on purpose: pnpm peer\n * multiplexing + dual ESM/CJS can load `core` more than once, and a plain `Symbol()`\n * would mint a distinct token per copy and break DI across package boundaries. A\n * registered symbol collapses every copy onto the same token, and lets a sibling lib\n * resolve our injectables by name without importing our internals.\n *\n * Naming convention (ecosystem-wide): `@dudousxd/nestjs-<lib>:<name>`.\n */\nexport const AGENT_OPTIONS = Symbol.for('@dudousxd/nestjs-agent:options');\nexport const AGENT_STORE = Symbol.for('@dudousxd/nestjs-agent:store');\nexport const AGENT_RUNNER = Symbol.for('@dudousxd/nestjs-agent:runner');\n/**\n * The durable runner, provided ONLY by `AgentDurableModule`. When `durable: true`, the module\n * binds `AGENT_RUNNER` to this via an optional injection, so a missing `AgentDurableModule`\n * fails with a clear error instead of a cryptic unresolved-dependency one.\n */\nexport const AGENT_DURABLE_RUNNER = Symbol.for('@dudousxd/nestjs-agent:durable-runner');\nexport const AGENT_SINK = Symbol.for('@dudousxd/nestjs-agent:sink');\nexport const AGENT_MODEL = Symbol.for('@dudousxd/nestjs-agent:model');\nexport const AGENT_ROLES_POLICY = Symbol.for('@dudousxd/nestjs-agent:roles-policy');\nexport const AGENT_QUOTA_STORE = Symbol.for('@dudousxd/nestjs-agent:quota-store');\nexport const AGENT_TOOL_REGISTRY = Symbol.for('@dudousxd/nestjs-agent:tool-registry');\nexport const AGENT_REGISTRY = Symbol.for('@dudousxd/nestjs-agent:agent-registry');\nexport const AGENT_ACTOR_RESOLVER = Symbol.for('@dudousxd/nestjs-agent:actor-resolver');\n/** The governance read-model (usage/spend/threads), consumed by the dashboard + telescope surfaces. */\nexport const AGENT_GOVERNANCE_QUERIES = Symbol.for('@dudousxd/nestjs-agent:governance-queries');\n/** The pricing WRITE side (`AgentPricingStore`) — seeds/updates the per-model rates cost is priced against. */\nexport const AGENT_PRICING_STORE = Symbol.for('@dudousxd/nestjs-agent:pricing-store');\n/** The RAG retrieval seam (`Retriever`) — vector/keyword search behind the agentic tool or inject mode. */\nexport const AGENT_RETRIEVER = Symbol.for('@dudousxd/nestjs-agent:retriever');\n/** The embedding provider (`EmbeddingProvider`) — text→vector for retrieval + ingestion. */\nexport const AGENT_EMBEDDING_PROVIDER = Symbol.for('@dudousxd/nestjs-agent:embedding-provider');\n// Per-agent deps factory. A Symbol.for token (not the class) so DI survives tsup's dual\n// index/durable bundles, which each get their own copy of the AgentDepsFactory class.\nexport const AGENT_DEPS_FACTORY = Symbol.for('@dudousxd/nestjs-agent:deps-factory');\n/** App-wide, ordered `@SystemPromptContributor()` functions the loop appends after the agent base. */\nexport const AGENT_PROMPT_CONTRIBUTORS = Symbol.for('@dudousxd/nestjs-agent:prompt-contributors');\n","/**\n * The \"data plane\": live token transport, decoupled from the durable control plane.\n *\n * The model turn writes deltas to a `SinkWriter` keyed by runId; the HTTP layer\n * `subscribe`s by runId and pipes the chunks to the browser as SSE. A late subscriber\n * (reconnect/resume) replays buffered chunks first, then follows live — which is what\n * makes streaming survive a dropped connection or a pod restart.\n */\nexport interface SinkWriter {\n write(chunk: Uint8Array): void | Promise<void>;\n /** Mark the run's stream finished (no more chunks). */\n end(): void | Promise<void>;\n /**\n * Terminate the run's stream with an error instead of a normal end. Subscribers replay any\n * buffered chunks first, then throw an {@link AgentStreamError} carrying this `code`/`message`\n * — so the transport can surface a typed failure frame instead of leaking it as assistant text.\n */\n fail(error: StreamError): void | Promise<void>;\n}\n\n/** A machine-readable stream failure. `code` is a stable slug; `message` is human-facing. */\nexport interface StreamError {\n code: string;\n message: string;\n}\n\n/**\n * Thrown out of {@link TokenStreamSink.subscribe} when a run ended via {@link SinkWriter.fail}.\n * Carries the structured {@link StreamError} so the HTTP layer can emit an `event: error` frame.\n */\nexport class AgentStreamError extends Error {\n readonly code: string;\n constructor(error: StreamError) {\n super(error.message);\n this.name = 'AgentStreamError';\n this.code = error.code;\n }\n}\n\nexport interface TokenStreamSink {\n /** Open (or reopen) the writer for a run. */\n open(runId: string): SinkWriter | Promise<SinkWriter>;\n /**\n * Replay buffered chunks for the run, then yield live ones until `end()`. Throws\n * {@link AgentStreamError} if the run was terminated with {@link SinkWriter.fail}.\n */\n subscribe(runId: string): AsyncIterable<Uint8Array>;\n /** Drop any buffer/resources for the run. */\n close(runId: string): void | Promise<void>;\n}\n","/**\n * The WRITE side of the pricing table the {@link import('./governance-queries.js').AgentGovernanceQueries}\n * read-model prices usage against. Cost is $0 for an unpriced model, so an app seeds its models'\n * per-1M rates once (and re-`upsert`s when a provider changes prices). A store adapter implements\n * this; consumers inject via `AGENT_PRICING_STORE`. Use `seedModelPrices` for a one-shot batch.\n */\n\n/** A per-1M-token price for one model. Cache rates fall back to the input rate when omitted. */\nexport interface ModelPriceInput {\n modelId: string;\n inputPricePer1m: number;\n outputPricePer1m: number;\n /** Per-1M price for cache-write (prompt-cache) input tokens. Omit → priced at the input rate. */\n cacheWritePricePer1m?: number;\n /** Per-1M price for cache-read (prompt-cache) input tokens. Omit → priced at the input rate. */\n cacheReadPricePer1m?: number;\n}\n\n/** A current price row as read back, with the timestamp it took effect. */\nexport interface CurrentModelPrice extends ModelPriceInput {\n effectiveFrom: string;\n}\n\nexport interface AgentPricingStore {\n /**\n * Set the current price for a model. Atomic supersede: the model's prior `isCurrent` row (if any)\n * is retired and this one is inserted as current, effective now — so the read-model always joins\n * to exactly one live price per model, with no window where two rows race for `isCurrent`.\n */\n upsertModelPrice(input: ModelPriceInput): Promise<void>;\n /** The current price row per model (`isCurrent`), for a pricing admin view. */\n listCurrentPrices(): Promise<CurrentModelPrice[]>;\n}\n\n/** Seed (or refresh) a batch of model prices — one `upsertModelPrice` per row, in order. */\nexport async function seedModelPrices(\n store: AgentPricingStore,\n prices: ModelPriceInput[],\n): Promise<void> {\n for (const price of prices) {\n await store.upsertModelPrice(price);\n }\n}\n","import type { RolesPolicy } from './spi/roles-policy.js';\nimport type { Actor, ToolSpec } from './types.js';\n\n/** First filter layer: drop tools the actor's role may not invoke. `can` may be async (authz). */\nexport async function filterToolsByRole(\n tools: ToolSpec[],\n actor: Actor,\n policy: RolesPolicy,\n): Promise<ToolSpec[]> {\n const checked = await Promise.all(\n tools.map(async (tool) => ({ tool, allowed: await policy.can(actor, tool) })),\n );\n return checked.filter((entry) => entry.allowed).map((entry) => entry.tool);\n}\n\n/** Second filter layer: if the agent pins an allow-list, keep only those tool names. */\nexport function filterToolsByAllowList(\n tools: ToolSpec[],\n allowedTools: string[] | undefined,\n): ToolSpec[] {\n if (allowedTools === undefined) {\n return tools;\n }\n const allowed = new Set(allowedTools);\n return tools.filter((tool) => allowed.has(tool.name));\n}\n","import type { AgentDefinition } from './types.js';\n\n/** Holds the named agent definitions registered via `AgentModule.forFeature([...])`. */\nexport class AgentRegistry {\n private readonly definitions = new Map<string, AgentDefinition>();\n\n register(definition: AgentDefinition): void {\n this.definitions.set(definition.name, definition);\n }\n\n get(name: string): AgentDefinition | undefined {\n return this.definitions.get(name);\n }\n\n has(name: string): boolean {\n return this.definitions.has(name);\n }\n\n list(): AgentDefinition[] {\n return [...this.definitions.values()];\n }\n}\n","import type { StandardSchemaV1 } from '@standard-schema/spec';\nimport type { RolesPolicy } from './spi/roles-policy.js';\nimport type { AiToolCtx, ToolHandler } from './spi/tool.js';\nimport { filterToolsByAllowList, filterToolsByRole } from './tool-filters.js';\nimport type { Actor, ToolDefinition, ToolSpec } from './types.js';\n\n/** Thrown when an actor invokes a tool their role is not allowed. */\nexport class ToolForbiddenError extends Error {\n constructor(public readonly toolName: string) {\n super(`Tool \"${toolName}\" is not allowed for this role`);\n this.name = 'ToolForbiddenError';\n }\n}\n\n/** Thrown when a tool is invoked that was never registered. */\nexport class ToolNotFoundError extends Error {\n constructor(public readonly toolName: string) {\n super(`Tool \"${toolName}\" is not registered`);\n this.name = 'ToolNotFoundError';\n }\n}\n\n/** Thrown when a tool's input fails its Standard Schema validation. */\nexport class ToolInputInvalidError extends Error {\n constructor(\n public readonly toolName: string,\n public readonly issues: readonly StandardSchemaV1.Issue[],\n ) {\n super(\n `Invalid input for tool \"${toolName}\": ${issues.map((issue) => issue.message).join('; ')}`,\n );\n this.name = 'ToolInputInvalidError';\n }\n}\n\ninterface Entry {\n spec: ToolSpec;\n handler: ToolHandler;\n}\n\n/**\n * Holds every registered tool and gates invocation.\n *\n * Note: `definitionsFor` returns NEUTRAL definitions (no `execute`). The agent loop runs\n * each tool itself as a (durable) step — so even read tools are not auto-executed by the\n * model. `action` tools additionally require HITL approval before the loop runs them.\n */\nexport class ToolRegistry {\n private readonly entries = new Map<string, Entry>();\n\n register(spec: ToolSpec, handler: ToolHandler): void {\n this.entries.set(spec.name, { spec, handler });\n }\n\n has(name: string): boolean {\n return this.entries.has(name);\n }\n\n spec(name: string): ToolSpec | undefined {\n return this.entries.get(name)?.spec;\n }\n\n allSpecs(): ToolSpec[] {\n return [...this.entries.values()].map((entry) => entry.spec);\n }\n\n /** The tools to offer the model for this actor+agent, after the two filter layers. */\n async definitionsFor(\n actor: Actor,\n policy: RolesPolicy,\n allowedTools?: string[],\n ): Promise<ToolDefinition[]> {\n const roleScoped = await filterToolsByRole(this.allSpecs(), actor, policy);\n const allowScoped = filterToolsByAllowList(roleScoped, allowedTools);\n return allowScoped.map((spec) => ({\n name: spec.name,\n kind: spec.kind,\n description: spec.description,\n inputSchema: spec.inputSchema,\n }));\n }\n\n /** Run a tool. Re-checks the role (defense-in-depth) and re-parses the input via Zod. */\n async invoke(\n name: string,\n input: unknown,\n ctx: AiToolCtx,\n policy: RolesPolicy,\n ): Promise<unknown> {\n const entry = this.entries.get(name);\n if (entry === undefined) {\n throw new ToolNotFoundError(name);\n }\n if (!(await policy.can(ctx.actor, entry.spec))) {\n throw new ToolForbiddenError(name);\n }\n const validation = await entry.spec.inputSchema['~standard'].validate(input);\n if (validation.issues !== undefined) {\n throw new ToolInputInvalidError(name, validation.issues);\n }\n return entry.handler.execute(validation.value, ctx);\n }\n}\n\n/** Default gate: one of the actor's roles must be in spec.roles (defaulting to ADMIN-only). */\nexport class DefaultRolesPolicy implements RolesPolicy {\n constructor(private readonly defaultRoles: string[] = ['ADMIN']) {}\n\n can(actor: Actor, tool: ToolSpec): boolean {\n const allowed = tool.roles ?? this.defaultRoles;\n return (actor.roles ?? []).some((role) => allowed.includes(role));\n }\n}\n","import { emit } from '@dudousxd/nestjs-diagnostics';\n\n/** Payloads carried on each `aviary:agent:*` channel. */\nexport interface AgentRunStarted {\n runId: string;\n threadId: string;\n actorId: string;\n /** Which agent is handling the run. */\n agentName?: string;\n}\nexport interface AgentMessageEvent {\n runId: string;\n threadId: string;\n role: 'user' | 'assistant';\n textLength: number;\n}\nexport interface AgentToolCallEvent {\n runId: string;\n toolName: string;\n toolType: 'read' | 'action';\n status: string;\n durationMs?: number;\n}\nexport interface AgentQuotaExceeded {\n actorId: string;\n usedTokens: number;\n limitTokens: number;\n}\nexport interface AgentRunFinished {\n runId: string;\n threadId: string;\n steps: number;\n inputTokens: number;\n outputTokens: number;\n}\nexport interface AgentRunFailed {\n runId: string;\n /** Stable failure slug, e.g. `quota_exceeded` or `run_failed`. */\n code: string;\n message: string;\n}\nexport interface AgentDelegated {\n runId: string;\n fromAgent?: string;\n toAgent: string;\n}\nexport interface AgentRetrieved {\n runId: string;\n query: string;\n /** How many passages the retriever returned. */\n count: number;\n}\n\n/** Declaration-merge so `emit('agent', ...)` and telescope infer the agent payloads. */\ndeclare module '@dudousxd/nestjs-diagnostics' {\n interface ChannelRegistry {\n agent: {\n 'run.started': AgentRunStarted;\n message: AgentMessageEvent;\n 'tool-call': AgentToolCallEvent;\n 'quota.exceeded': AgentQuotaExceeded;\n 'run.finished': AgentRunFinished;\n 'run.failed': AgentRunFailed;\n delegated: AgentDelegated;\n retrieved: AgentRetrieved;\n };\n }\n}\n\nexport function publishAgentRunStarted(payload: AgentRunStarted): void {\n emit('agent', 'run.started', payload);\n}\nexport function publishAgentMessage(payload: AgentMessageEvent): void {\n emit('agent', 'message', payload);\n}\nexport function publishAgentToolCall(payload: AgentToolCallEvent): void {\n emit('agent', 'tool-call', payload);\n}\nexport function publishAgentQuotaExceeded(payload: AgentQuotaExceeded): void {\n emit('agent', 'quota.exceeded', payload);\n}\nexport function publishAgentRunFinished(payload: AgentRunFinished): void {\n emit('agent', 'run.finished', payload);\n}\nexport function publishAgentRunFailed(payload: AgentRunFailed): void {\n emit('agent', 'run.failed', payload);\n}\nexport function publishAgentDelegated(payload: AgentDelegated): void {\n emit('agent', 'delegated', payload);\n}\nexport function publishAgentRetrieved(payload: AgentRetrieved): void {\n emit('agent', 'retrieved', payload);\n}\n","import {\n publishAgentDelegated,\n publishAgentMessage,\n publishAgentQuotaExceeded,\n publishAgentRetrieved,\n publishAgentRunFinished,\n publishAgentRunStarted,\n publishAgentToolCall,\n} from './diagnostics.js';\nimport type { AgentStore } from './spi/agent-store.js';\nimport type { ModelProvider } from './spi/model-provider.js';\nimport type { QuotaStore } from './spi/quota-store.js';\nimport type { Passage, Retriever } from './spi/retriever.js';\nimport type { RolesPolicy } from './spi/roles-policy.js';\nimport type { SinkWriter } from './spi/token-stream-sink.js';\nimport type { AiToolCtx } from './spi/tool.js';\nimport type { ToolRegistry } from './tool-registry.js';\nimport type {\n AgentRunInput,\n Decision,\n MessageUsage,\n ModelMessage,\n PromptBuilder,\n PromptContext,\n PromptContributor,\n ToolCallRequest,\n ToolResult,\n} from './types.js';\n\nexport interface AgentLoopDeps {\n model: ModelProvider;\n store: AgentStore;\n registry: ToolRegistry;\n rolesPolicy: RolesPolicy;\n quota?: QuotaStore;\n /**\n * Fallback accounting label when the provider's turn result doesn't report a `modelId`.\n * Optional — a provider that reports its own model makes this unnecessary.\n */\n modelId?: string;\n /** Pre-computed (YYYY-MM-DD) so the loop body stays deterministic under durable replay. */\n day: string;\n /** The agent's base prompt. A flat string, or a {@link PromptBuilder} resolved per turn. */\n systemPrompt: string | PromptBuilder;\n /**\n * Cross-agent system-prompt contributors, applied in order AFTER the agent's base prompt. Each\n * returns a section to append (or `null` to skip this turn). The app registers them via\n * `@SystemPromptContributor()`; the loop composes base + contributors into the effective prompt.\n */\n promptContributors?: PromptContributor[];\n maxSteps?: number;\n /** Optional host handle threaded to tool ctx (e.g. an ORM EntityManager). */\n host?: unknown;\n /** Agent-level tool allow-list. Undefined → all tools (after role filtering). */\n toolAllowList?: string[];\n /**\n * Per-tool execution timeout in ms. A tool that runs longer is aborted and recorded as failed\n * (the model gets the timeout as its result and can adapt) rather than hanging the turn.\n * Undefined → no timeout.\n */\n toolTimeoutMs?: number;\n /**\n * When set, after the final turn the loop makes one extra model call to propose up to this many\n * short follow-up questions, stored on the assistant message's `followUps`. Costs an extra call\n * (recorded as `follow_ups` usage). Undefined/0 → disabled.\n */\n followUpsCount?: number;\n /**\n * Enables always-on (\"inject\") RAG: before the turn, retrieve passages for the user message and\n * augment the system prompt with them. Its presence IS inject mode — agentic (tool) retrieval sets\n * no retriever here (it rides a normal `read` tool). Undefined → no injection.\n */\n retriever?: Retriever;\n /** How many passages inject-mode retrieval requests. Undefined → 5. */\n retrievalTopK?: number;\n}\n\n/** Renders retrieved passages as a numbered, citable context block for the system prompt. */\nfunction buildContextBlock(passages: Passage[]): string {\n const items = passages\n .map((passage, index) => {\n const label = passage.source !== undefined ? ` (${passage.source})` : '';\n return `[${index + 1}]${label} ${passage.text}`;\n })\n .join('\\n\\n');\n return `<retrieved_context>\\n${items}\\n</retrieved_context>\\nUse the retrieved context above to answer when relevant, and cite sources by their bracket number.`;\n}\n\nexport interface AgentLoopHooks {\n runId: string;\n /** A writer for this run's live token stream (data plane). */\n openSink(): SinkWriter | Promise<SinkWriter>;\n /** HITL gate for an action tool. Inline resolves a pending promise; durable awaits a signal. */\n awaitApproval(call: ToolCallRequest, ctx: AiToolCtx): Promise<Decision>;\n /**\n * Run another named agent and return its answer. Provided only when the host wired multi-agent\n * support (durable → child workflow, inline → nested loop). Exposed to tools as `ctx.runAgent`.\n */\n runAgent?(agentName: string, task: string): Promise<{ text: string }>;\n /**\n * Checkpoint wrapper. Inline = call fn directly; durable = ctx.step(name, fn).\n * EVERY side-effect and control-flow read goes through this so durable replay returns\n * cached results (stable ids, no double-write, no re-streaming).\n */\n step<T>(name: string, fn: () => Promise<T>): Promise<T>;\n}\n\nexport class QuotaExceededError extends Error {\n constructor() {\n super('Daily token quota exceeded');\n this.name = 'QuotaExceededError';\n }\n}\n\n/**\n * How deep agent→agent delegation may nest before the loop refuses further hops. A cap, not a\n * tuning knob: it stops a mis-wired `delegatesTo` cycle (A→B→A) from spawning runs unbounded.\n */\nexport const MAX_DELEGATION_DEPTH = 5;\n\n/** Resolve a prompt that may be a flat string or a {@link PromptBuilder}. */\nasync function resolvePrompt(prompt: string | PromptBuilder, ctx: PromptContext): Promise<string> {\n return typeof prompt === 'function' ? prompt(ctx) : prompt;\n}\n\n/**\n * The effective system prompt for a turn: the agent's own base prompt, then each cross-agent\n * contributor's section appended in order (skipping any that return `null`/empty this turn). This is\n * resolved from stable inputs (actor / agent / pageContext) once per turn; contributors should be\n * derived from those rather than from uncached I/O so it stays replay-safe.\n */\nasync function resolveSystemPrompt(deps: AgentLoopDeps, input: AgentRunInput): Promise<string> {\n const ctx: PromptContext = {\n actor: input.actor,\n agentName: input.agentName ?? 'default',\n ...(input.pageContext !== undefined ? { pageContext: input.pageContext } : {}),\n };\n const sections = [await resolvePrompt(deps.systemPrompt, ctx)];\n for (const contribute of deps.promptContributors ?? []) {\n const section = await contribute(ctx);\n if (section !== null && section.length > 0) {\n sections.push(section);\n }\n }\n return sections.join('\\n\\n');\n}\n\n/** An `agent`-kind tool's input is `{ task }` by convention; fall back to a JSON dump. */\nfunction extractTask(input: unknown): string {\n if (typeof input === 'object' && input !== null && 'task' in input) {\n const task = (input as { task: unknown }).task;\n if (typeof task === 'string') {\n return task;\n }\n }\n return JSON.stringify(input);\n}\n\nfunction deriveTitle(userText: string): string {\n const trimmed = userText.trim().replace(/\\s+/g, ' ');\n return trimmed.length > 60 ? `${trimmed.slice(0, 57)}...` : trimmed || 'New chat';\n}\n\n/** Thrown when a tool exceeds `toolTimeoutMs`; caught by the loop and recorded as a failed call. */\nclass ToolTimeoutError extends Error {\n constructor(toolName: string, ms: number) {\n super(`Tool \"${toolName}\" exceeded its ${ms}ms timeout`);\n this.name = 'ToolTimeoutError';\n }\n}\n\n/** Reject if `work` doesn't settle within `ms`. The underlying work is left to finish on its own. */\nfunction withTimeout<T>(work: Promise<T>, ms: number, toolName: string): Promise<T> {\n return new Promise<T>((resolve, reject) => {\n const timer = setTimeout(() => reject(new ToolTimeoutError(toolName, ms)), ms);\n work.then(\n (value) => {\n clearTimeout(timer);\n resolve(value);\n },\n (error) => {\n clearTimeout(timer);\n reject(error);\n },\n );\n });\n}\n\n/** Best-effort parse of the follow-ups model reply: a bare JSON array, tolerating code fences/prose. */\nfunction parseFollowUps(text: string, count: number): string[] {\n const source = text.match(/\\[[\\s\\S]*\\]/)?.[0] ?? text;\n try {\n const parsed: unknown = JSON.parse(source);\n if (Array.isArray(parsed)) {\n return parsed.filter((item): item is string => typeof item === 'string').slice(0, count);\n }\n } catch {\n /* not JSON — no follow-ups this turn */\n }\n return [];\n}\n\n/**\n * One extra, non-streamed model call that proposes short follow-up questions. Writes to a discarding\n * sink so its tokens never reach the user's live stream; the reply is parsed as a JSON string array.\n */\nasync function generateFollowUps(\n model: ModelProvider,\n messages: ModelMessage[],\n count: number,\n): Promise<{ followUps: string[]; usage: MessageUsage; modelId?: string }> {\n const discard: SinkWriter = { write: () => {}, end: () => {}, fail: () => {} };\n const turn = await model.runTurn({\n system: `Based on the conversation so far, propose up to ${count} short, distinct follow-up questions the user is likely to ask next. Respond with ONLY a JSON array of strings — no prose, no code fences.`,\n messages,\n tools: [],\n sink: discard,\n });\n return {\n followUps: parseFollowUps(turn.text, count),\n usage: turn.usage,\n ...(turn.modelId !== undefined ? { modelId: turn.modelId } : {}),\n };\n}\n\n/**\n * The provider-agnostic agent turn, reused by both the inline and durable runners.\n * It drives the model→tools→model iteration; the runner supplies the `step`/`awaitApproval`\n * hooks that make the same loop body either in-process or a replay-safe durable workflow.\n */\nexport async function runAgentLoop(\n deps: AgentLoopDeps,\n input: AgentRunInput,\n hooks: AgentLoopHooks,\n): Promise<{ text: string }> {\n const maxSteps = deps.maxSteps ?? 8;\n let system = await resolveSystemPrompt(deps, input);\n\n if (deps.quota !== undefined) {\n const quota = deps.quota;\n const state = await hooks.step('quota:check', () => quota.check(input.actor.id, deps.day));\n if (!state.withinLimit) {\n publishAgentQuotaExceeded({\n actorId: input.actor.id,\n usedTokens: state.usedTokens,\n limitTokens: state.limitTokens,\n });\n throw new QuotaExceededError();\n }\n }\n\n if (input.regenerate === true) {\n // Re-run the last exchange: drop every message after the thread's last user message (keeping\n // it), then answer it again. No new user message is appended.\n await hooks.step('regenerate:truncate', async () => {\n const existing = await deps.store.getThread(input.threadId);\n const messages = existing?.messages ?? [];\n let lastUserIndex = -1;\n for (let index = messages.length - 1; index >= 0; index -= 1) {\n if (messages[index]?.role === 'user') {\n lastUserIndex = index;\n break;\n }\n }\n const firstDropped = messages[lastUserIndex + 1];\n if (firstDropped !== undefined) {\n await deps.store.truncateFrom(input.threadId, firstDropped.id);\n }\n });\n } else {\n await hooks.step('persist:user', () =>\n deps.store.appendMessage({\n threadId: input.threadId,\n role: 'user',\n content: input.userText,\n }),\n );\n }\n\n const thread = await hooks.step('load:thread', () => deps.store.getThread(input.threadId));\n const modelMessages: ModelMessage[] = (thread?.messages ?? []).map((message) => ({\n role: message.role,\n content: message.content,\n ...(message.toolCalls !== undefined ? { toolCalls: message.toolCalls } : {}),\n ...(message.toolResults !== undefined ? { toolResults: message.toolResults } : {}),\n }));\n\n const writer = await hooks.openSink();\n let lastText = '';\n let steps = 0;\n let totalInput = 0;\n let totalOutput = 0;\n\n publishAgentRunStarted({\n runId: hooks.runId,\n threadId: input.threadId,\n actorId: input.actor.id,\n ...(input.agentName !== undefined ? { agentName: input.agentName } : {}),\n });\n\n // Inject-mode RAG: retrieve once for the user message and fold the passages into the system prompt\n // (a `ctx.step` so it's replay-cached under durable). Recorded below as a synthetic tool call on\n // the first assistant message, so citations surface through the same machinery as agentic search.\n let injectedPassages: Passage[] | undefined;\n if (deps.retriever !== undefined) {\n const retriever = deps.retriever;\n const passages = await hooks.step('retrieve', () =>\n retriever.retrieve(input.userText, { topK: deps.retrievalTopK ?? 5 }),\n );\n if (passages.length > 0) {\n injectedPassages = passages;\n system = `${system}\\n\\n${buildContextBlock(passages)}`;\n }\n publishAgentRetrieved({ runId: hooks.runId, query: input.userText, count: passages.length });\n }\n\n // NOTE: no try/finally around this loop. A durable runner suspends by THROWING through the stack\n // at `awaitApproval` (ctx.waitForSignal); a finally would then call writer.end() on every suspend\n // and prematurely close the live stream. We only end on normal completion — the throw propagates\n // to the engine, and the resumed replay reaches the writer.end() below.\n for (let i = 0; i < maxSteps; i += 1) {\n const tools = await deps.registry.definitionsFor(\n input.actor,\n deps.rolesPolicy,\n deps.toolAllowList,\n );\n\n const turn = await hooks.step(`llm:${i}`, () =>\n deps.model.runTurn({ system, messages: modelMessages, tools, sink: writer }),\n );\n\n await hooks.step(`persist:usage:${i}`, () =>\n deps.store.recordUsage({\n threadId: input.threadId,\n actorRef: input.actor.id,\n // provider-reported model wins over the configured fallback, so cost can't misattribute\n modelId: turn.modelId ?? deps.modelId ?? 'unknown',\n purpose: 'chat',\n usage: turn.usage,\n // persist the provider's actual cost when reported; the read-model prefers it over pricing\n ...(turn.costUsd !== undefined ? { costUsd: turn.costUsd } : {}),\n }),\n );\n if (deps.quota !== undefined) {\n const quota = deps.quota;\n await hooks.step(`quota:bump:${i}`, () =>\n quota.bump(input.actor.id, deps.day, turn.usage.inputTokens + turn.usage.outputTokens),\n );\n }\n\n steps += 1;\n totalInput += turn.usage.inputTokens;\n totalOutput += turn.usage.outputTokens;\n lastText = turn.text;\n publishAgentMessage({\n runId: hooks.runId,\n threadId: input.threadId,\n role: 'assistant',\n textLength: turn.text.length,\n });\n\n // A turn with no tool calls is the last one. Generate follow-up suggestions here (before the\n // append) so they land on the final assistant message, and stop after.\n const isFinalTurn = turn.toolCalls.length === 0;\n let followUps: string[] | undefined;\n if (isFinalTurn && deps.followUpsCount !== undefined && deps.followUpsCount > 0) {\n const count = deps.followUpsCount;\n const generated = await hooks.step(`followups:${i}`, () =>\n generateFollowUps(\n deps.model,\n [...modelMessages, { role: 'assistant', content: turn.text }],\n count,\n ),\n );\n if (generated.followUps.length > 0) {\n followUps = generated.followUps;\n }\n await hooks.step(`persist:usage:followups:${i}`, () =>\n deps.store.recordUsage({\n threadId: input.threadId,\n actorRef: input.actor.id,\n modelId: generated.modelId ?? deps.modelId ?? 'unknown',\n purpose: 'follow_ups',\n usage: generated.usage,\n }),\n );\n }\n\n const assistant = await hooks.step(`persist:assistant:${i}`, () =>\n deps.store.appendMessage({\n threadId: input.threadId,\n role: 'assistant',\n content: turn.text,\n usage: turn.usage,\n ...(input.agentName !== undefined ? { agentName: input.agentName } : {}),\n ...(turn.toolCalls.length > 0 ? { toolCalls: turn.toolCalls } : {}),\n ...(followUps !== undefined ? { followUps } : {}),\n }),\n );\n modelMessages.push({\n role: 'assistant',\n content: turn.text,\n ...(turn.toolCalls.length > 0 ? { toolCalls: turn.toolCalls } : {}),\n });\n\n // Record inject-mode retrieval as a synthetic auto-executed `retrieve` tool call on the assistant\n // message it informed — so its passages persist and render as citations exactly like an agentic\n // search would, without a new message field.\n if (i === 0 && injectedPassages !== undefined) {\n const passages = injectedPassages;\n const toolCallId = `retrieve-${assistant.id}`;\n await hooks.step(`persist:retrieval:${assistant.id}`, async () => {\n await deps.store.recordToolCall({\n toolCallId,\n messageId: assistant.id,\n toolName: 'retrieve',\n toolType: 'read',\n input: { query: input.userText },\n status: 'auto_executed',\n });\n await deps.store.updateToolCall({ toolCallId, status: 'executed', output: { passages } });\n });\n }\n\n if (isFinalTurn) {\n break;\n }\n\n const results: ToolResult[] = [];\n for (const call of turn.toolCalls) {\n const spec = deps.registry.spec(call.name);\n const toolType = spec?.kind ?? 'read';\n const ctx: AiToolCtx = {\n actor: input.actor,\n threadId: input.threadId,\n runId: hooks.runId,\n requestId: hooks.runId,\n ...(input.agentName !== undefined ? { agentName: input.agentName } : {}),\n ...(input.pageContext !== undefined ? { pageContext: input.pageContext } : {}),\n ...(deps.host !== undefined ? { host: deps.host } : {}),\n };\n\n // Delegation: an `agent`-kind tool runs another agent. Handled at the LOOP level (not in a\n // step) because the durable runner maps it to `ctx.child`, a ctx-level suspend point.\n if (toolType === 'agent') {\n const targetAgent = spec?.targetAgent ?? call.name;\n const task = extractTask(call.input);\n await hooks.step(`persist:toolcall:${call.id}`, () =>\n deps.store.recordToolCall({\n toolCallId: call.id,\n messageId: assistant.id,\n toolName: call.name,\n toolType: 'read',\n input: call.input,\n status: 'auto_executed',\n }),\n );\n // Cap nesting so a mis-wired delegation cycle can't spawn runs without bound.\n const overDepth = (input.delegationDepth ?? 0) >= MAX_DELEGATION_DEPTH;\n publishAgentDelegated({\n runId: hooks.runId,\n toAgent: targetAgent,\n ...(input.agentName !== undefined ? { fromAgent: input.agentName } : {}),\n });\n let sub: { text: string };\n if (overDepth) {\n sub = { text: `(delegation depth limit of ${MAX_DELEGATION_DEPTH} reached)` };\n } else if (hooks.runAgent) {\n sub = await hooks.runAgent(targetAgent, task);\n } else {\n sub = { text: `(no multi-agent support wired; cannot reach \"${targetAgent}\")` };\n }\n await hooks.step(`persist:toolexec:${call.id}`, () =>\n deps.store.updateToolCall({ toolCallId: call.id, status: 'executed', output: sub }),\n );\n results.push({ id: call.id, name: call.name, output: sub });\n continue;\n }\n\n if (toolType === 'action') {\n await hooks.step(`persist:toolcall:${call.id}`, () =>\n deps.store.recordToolCall({\n toolCallId: call.id,\n messageId: assistant.id,\n toolName: call.name,\n toolType: 'action',\n input: call.input,\n status: 'pending_approval',\n }),\n );\n const decision = await hooks.awaitApproval(call, ctx);\n if (!decision.approved) {\n await hooks.step(`persist:toolreject:${call.id}`, () =>\n deps.store.updateToolCall({\n toolCallId: call.id,\n status: 'rejected',\n ...(decision.reason !== undefined ? { error: decision.reason } : {}),\n }),\n );\n results.push({\n id: call.id,\n name: call.name,\n output: { rejected: true, reason: decision.reason ?? 'rejected by user' },\n error: 'rejected',\n });\n publishAgentToolCall({\n runId: hooks.runId,\n toolName: call.name,\n toolType,\n status: 'rejected',\n });\n continue;\n }\n } else {\n await hooks.step(`persist:toolcall:${call.id}`, () =>\n deps.store.recordToolCall({\n toolCallId: call.id,\n messageId: assistant.id,\n toolName: call.name,\n toolType: 'read',\n input: call.input,\n status: 'auto_executed',\n }),\n );\n }\n\n const startedAt = Date.now();\n try {\n const invocation = hooks.step(`tool:${call.id}`, () =>\n deps.registry.invoke(call.name, call.input, ctx, deps.rolesPolicy),\n );\n const output =\n deps.toolTimeoutMs !== undefined\n ? await withTimeout(invocation, deps.toolTimeoutMs, call.name)\n : await invocation;\n const executionMs = Date.now() - startedAt;\n await hooks.step(`persist:toolexec:${call.id}`, () =>\n deps.store.updateToolCall({\n toolCallId: call.id,\n status: 'executed',\n output,\n executionMs,\n ...(toolType === 'action' ? { executedByRef: input.actor.id } : {}),\n }),\n );\n results.push({ id: call.id, name: call.name, output });\n publishAgentToolCall({\n runId: hooks.runId,\n toolName: call.name,\n toolType,\n status: 'executed',\n durationMs: executionMs,\n });\n } catch (error) {\n const executionMs = Date.now() - startedAt;\n const message = error instanceof Error ? error.message : String(error);\n await hooks.step(`persist:toolfail:${call.id}`, () =>\n deps.store.updateToolCall({\n toolCallId: call.id,\n status: 'failed',\n error: message,\n executionMs,\n }),\n );\n results.push({ id: call.id, name: call.name, output: null, error: message });\n publishAgentToolCall({\n runId: hooks.runId,\n toolName: call.name,\n toolType,\n status: 'failed',\n durationMs: executionMs,\n });\n }\n }\n\n modelMessages.push({ role: 'user', content: '', toolResults: results });\n }\n\n if (thread !== null && (thread.title === '' || thread.title === 'New chat')) {\n await hooks.step('persist:title', () =>\n deps.store.setTitle(input.threadId, deriveTitle(input.userText)),\n );\n }\n\n await writer.end();\n publishAgentRunFinished({\n runId: hooks.runId,\n threadId: input.threadId,\n steps,\n inputTokens: totalInput,\n outputTokens: totalOutput,\n });\n return { text: lastText };\n}\n"],"mappings":"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","names":["AGENT_OPTIONS","Symbol","for","AGENT_STORE","AGENT_RUNNER","AGENT_DURABLE_RUNNER","AGENT_SINK","AGENT_MODEL","AGENT_ROLES_POLICY","AGENT_QUOTA_STORE","AGENT_TOOL_REGISTRY","AGENT_REGISTRY","AGENT_ACTOR_RESOLVER","AGENT_GOVERNANCE_QUERIES","AGENT_PRICING_STORE","AGENT_RETRIEVER","AGENT_EMBEDDING_PROVIDER","AGENT_DEPS_FACTORY","AGENT_PROMPT_CONTRIBUTORS","AgentStreamError","Error","code","error","message","name","seedModelPrices","store","prices","price","upsertModelPrice","filterToolsByRole","tools","actor","policy","checked","Promise","all","map","tool","allowed","can","filter","entry","filterToolsByAllowList","allowedTools","undefined","Set","has","name","AgentRegistry","definitions","Map","register","definition","set","name","get","has","list","values","ToolForbiddenError","Error","toolName","name","ToolNotFoundError","ToolInputInvalidError","issues","map","issue","message","join","ToolRegistry","entries","Map","register","spec","handler","set","has","get","allSpecs","values","entry","definitionsFor","actor","policy","allowedTools","roleScoped","filterToolsByRole","allowScoped","filterToolsByAllowList","kind","description","inputSchema","invoke","input","ctx","undefined","can","validation","validate","execute","value","DefaultRolesPolicy","defaultRoles","tool","allowed","roles","some","role","includes","publishAgentRunStarted","payload","emit","publishAgentMessage","publishAgentToolCall","publishAgentQuotaExceeded","publishAgentRunFinished","publishAgentRunFailed","publishAgentDelegated","publishAgentRetrieved","buildContextBlock","passages","items","map","passage","index","label","source","undefined","text","join","QuotaExceededError","Error","name","MAX_DELEGATION_DEPTH","resolvePrompt","prompt","ctx","resolveSystemPrompt","deps","input","actor","agentName","pageContext","sections","systemPrompt","contribute","promptContributors","section","length","push","extractTask","task","JSON","stringify","deriveTitle","userText","trimmed","trim","replace","slice","ToolTimeoutError","toolName","ms","withTimeout","work","Promise","resolve","reject","timer","setTimeout","then","value","clearTimeout","error","parseFollowUps","count","match","parsed","parse","Array","isArray","filter","item","generateFollowUps","model","messages","discard","write","end","fail","turn","runTurn","system","tools","sink","followUps","usage","modelId","runAgentLoop","hooks","maxSteps","quota","state","step","check","id","day","withinLimit","publishAgentQuotaExceeded","actorId","usedTokens","limitTokens","regenerate","existing","store","getThread","threadId","lastUserIndex","role","firstDropped","truncateFrom","appendMessage","content","thread","modelMessages","message","toolCalls","toolResults","writer","openSink","lastText","steps","totalInput","totalOutput","publishAgentRunStarted","runId","injectedPassages","retriever","retrieve","topK","retrievalTopK","publishAgentRetrieved","query","i","registry","definitionsFor","rolesPolicy","toolAllowList","recordUsage","actorRef","purpose","costUsd","bump","inputTokens","outputTokens","publishAgentMessage","textLength","isFinalTurn","followUpsCount","generated","assistant","toolCallId","recordToolCall","messageId","toolType","status","updateToolCall","output","results","call","spec","kind","requestId","host","targetAgent","overDepth","delegationDepth","publishAgentDelegated","toAgent","fromAgent","sub","runAgent","decision","awaitApproval","approved","reason","rejected","publishAgentToolCall","startedAt","Date","now","invocation","invoke","toolTimeoutMs","executionMs","executedByRef","durationMs","String","title","setTitle","publishAgentRunFinished"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/tokens.ts","../src/spi/token-stream-sink.ts","../src/spi/pricing-store.ts","../src/governance/compute.ts","../src/tool-filters.ts","../src/agent-registry.ts","../src/tool-registry.ts","../src/diagnostics.ts","../src/agent-loop.ts"],"sourcesContent":["export * from './types.js';\nexport * from './tokens.js';\nexport * from './spi/tool.js';\nexport * from './spi/model-provider.js';\nexport * from './spi/token-stream-sink.js';\nexport * from './spi/agent-store.js';\nexport * from './spi/roles-policy.js';\nexport * from './spi/quota-store.js';\nexport * from './spi/pricing-store.js';\nexport * from './spi/retriever.js';\nexport * from './spi/embedding-provider.js';\nexport * from './spi/reranker.js';\nexport * from './spi/agent-runner.js';\nexport * from './spi/actor-resolver.js';\nexport * from './spi/governance-queries.js';\nexport * from './governance/compute.js';\nexport * from './tool-filters.js';\nexport { AgentRegistry } from './agent-registry.js';\nexport {\n ToolRegistry,\n DefaultRolesPolicy,\n ToolForbiddenError,\n ToolNotFoundError,\n ToolInputInvalidError,\n} from './tool-registry.js';\nexport {\n runAgentLoop,\n QuotaExceededError,\n type AgentLoopDeps,\n type AgentLoopHooks,\n} from './agent-loop.js';\nexport * from './diagnostics.js';\n","/**\n * Public, cross-lib-discoverable DI tokens.\n *\n * These use `Symbol.for(...)` (the global symbol registry) on purpose: pnpm peer\n * multiplexing + dual ESM/CJS can load `core` more than once, and a plain `Symbol()`\n * would mint a distinct token per copy and break DI across package boundaries. A\n * registered symbol collapses every copy onto the same token, and lets a sibling lib\n * resolve our injectables by name without importing our internals.\n *\n * Naming convention (ecosystem-wide): `@dudousxd/nestjs-<lib>:<name>`.\n */\nexport const AGENT_OPTIONS = Symbol.for('@dudousxd/nestjs-agent:options');\nexport const AGENT_STORE = Symbol.for('@dudousxd/nestjs-agent:store');\nexport const AGENT_RUNNER = Symbol.for('@dudousxd/nestjs-agent:runner');\n/**\n * The durable runner, provided ONLY by `AgentDurableModule`. When `durable: true`, the module\n * binds `AGENT_RUNNER` to this via an optional injection, so a missing `AgentDurableModule`\n * fails with a clear error instead of a cryptic unresolved-dependency one.\n */\nexport const AGENT_DURABLE_RUNNER = Symbol.for('@dudousxd/nestjs-agent:durable-runner');\nexport const AGENT_SINK = Symbol.for('@dudousxd/nestjs-agent:sink');\nexport const AGENT_MODEL = Symbol.for('@dudousxd/nestjs-agent:model');\nexport const AGENT_ROLES_POLICY = Symbol.for('@dudousxd/nestjs-agent:roles-policy');\nexport const AGENT_QUOTA_STORE = Symbol.for('@dudousxd/nestjs-agent:quota-store');\nexport const AGENT_TOOL_REGISTRY = Symbol.for('@dudousxd/nestjs-agent:tool-registry');\nexport const AGENT_REGISTRY = Symbol.for('@dudousxd/nestjs-agent:agent-registry');\nexport const AGENT_ACTOR_RESOLVER = Symbol.for('@dudousxd/nestjs-agent:actor-resolver');\n/** The governance read-model (usage/spend/threads), consumed by the dashboard + telescope surfaces. */\nexport const AGENT_GOVERNANCE_QUERIES = Symbol.for('@dudousxd/nestjs-agent:governance-queries');\n/** The pricing WRITE side (`AgentPricingStore`) — seeds/updates the per-model rates cost is priced against. */\nexport const AGENT_PRICING_STORE = Symbol.for('@dudousxd/nestjs-agent:pricing-store');\n/** The RAG retrieval seam (`Retriever`) — vector/keyword search behind the agentic tool or inject mode. */\nexport const AGENT_RETRIEVER = Symbol.for('@dudousxd/nestjs-agent:retriever');\n/** The embedding provider (`EmbeddingProvider`) — text→vector for retrieval + ingestion. */\nexport const AGENT_EMBEDDING_PROVIDER = Symbol.for('@dudousxd/nestjs-agent:embedding-provider');\n// Per-agent deps factory. A Symbol.for token (not the class) so DI survives tsup's dual\n// index/durable bundles, which each get their own copy of the AgentDepsFactory class.\nexport const AGENT_DEPS_FACTORY = Symbol.for('@dudousxd/nestjs-agent:deps-factory');\n/** App-wide, ordered `@SystemPromptContributor()` functions the loop appends after the agent base. */\nexport const AGENT_PROMPT_CONTRIBUTORS = Symbol.for('@dudousxd/nestjs-agent:prompt-contributors');\n","/**\n * The \"data plane\": live token transport, decoupled from the durable control plane.\n *\n * The model turn writes deltas to a `SinkWriter` keyed by runId; the HTTP layer\n * `subscribe`s by runId and pipes the chunks to the browser as SSE. A late subscriber\n * (reconnect/resume) replays buffered chunks first, then follows live — which is what\n * makes streaming survive a dropped connection or a pod restart.\n */\nexport interface SinkWriter {\n write(chunk: Uint8Array): void | Promise<void>;\n /** Mark the run's stream finished (no more chunks). */\n end(): void | Promise<void>;\n /**\n * Terminate the run's stream with an error instead of a normal end. Subscribers replay any\n * buffered chunks first, then throw an {@link AgentStreamError} carrying this `code`/`message`\n * — so the transport can surface a typed failure frame instead of leaking it as assistant text.\n */\n fail(error: StreamError): void | Promise<void>;\n}\n\n/** A machine-readable stream failure. `code` is a stable slug; `message` is human-facing. */\nexport interface StreamError {\n code: string;\n message: string;\n}\n\n/**\n * Thrown out of {@link TokenStreamSink.subscribe} when a run ended via {@link SinkWriter.fail}.\n * Carries the structured {@link StreamError} so the HTTP layer can emit an `event: error` frame.\n */\nexport class AgentStreamError extends Error {\n readonly code: string;\n constructor(error: StreamError) {\n super(error.message);\n this.name = 'AgentStreamError';\n this.code = error.code;\n }\n}\n\nexport interface TokenStreamSink {\n /** Open (or reopen) the writer for a run. */\n open(runId: string): SinkWriter | Promise<SinkWriter>;\n /**\n * Replay buffered chunks for the run, then yield live ones until `end()`. Throws\n * {@link AgentStreamError} if the run was terminated with {@link SinkWriter.fail}.\n */\n subscribe(runId: string): AsyncIterable<Uint8Array>;\n /** Drop any buffer/resources for the run. */\n close(runId: string): void | Promise<void>;\n}\n","/**\n * The WRITE side of the pricing table the {@link import('./governance-queries.js').AgentGovernanceQueries}\n * read-model prices usage against. Cost is $0 for an unpriced model, so an app seeds its models'\n * per-1M rates once (and re-`upsert`s when a provider changes prices). A store adapter implements\n * this; consumers inject via `AGENT_PRICING_STORE`. Use `seedModelPrices` for a one-shot batch.\n */\n\n/** A per-1M-token price for one model. Cache rates fall back to the input rate when omitted. */\nexport interface ModelPriceInput {\n modelId: string;\n inputPricePer1m: number;\n outputPricePer1m: number;\n /** Per-1M price for cache-write (prompt-cache) input tokens. Omit → priced at the input rate. */\n cacheWritePricePer1m?: number;\n /** Per-1M price for cache-read (prompt-cache) input tokens. Omit → priced at the input rate. */\n cacheReadPricePer1m?: number;\n}\n\n/** A current price row as read back, with the timestamp it took effect. */\nexport interface CurrentModelPrice extends ModelPriceInput {\n effectiveFrom: string;\n}\n\nexport interface AgentPricingStore {\n /**\n * Set the current price for a model. Atomic supersede: the model's prior `isCurrent` row (if any)\n * is retired and this one is inserted as current, effective now — so the read-model always joins\n * to exactly one live price per model, with no window where two rows race for `isCurrent`.\n */\n upsertModelPrice(input: ModelPriceInput): Promise<void>;\n /** The current price row per model (`isCurrent`), for a pricing admin view. */\n listCurrentPrices(): Promise<CurrentModelPrice[]>;\n}\n\n/** Seed (or refresh) a batch of model prices — one `upsertModelPrice` per row, in order. */\nexport async function seedModelPrices(\n store: AgentPricingStore,\n prices: ModelPriceInput[],\n): Promise<void> {\n for (const price of prices) {\n await store.upsertModelPrice(price);\n }\n}\n","import type {\n ActorSpendRow,\n GovernanceRange,\n ModelSpendRow,\n ThreadSpendRow,\n UsageTrendPoint,\n} from '../spi/governance-queries.js';\n\n/**\n * The pure aggregation core shared by every {@link import('../spi/governance-queries.js').AgentGovernanceQueries}\n * adapter (MikroORM, Drizzle, in-memory). An adapter's only job is the DB-specific row fetch; the\n * cost formula, the group→sort bucketing, and the day-bounds math live here so all three surfaces\n * report identical numbers.\n */\n\n/** The current per-1M token prices for one model; cache rates fall back to the input rate. */\nexport interface ModelPrice {\n inputPricePer1m: number;\n outputPricePer1m: number;\n cacheWritePricePer1m?: number | null;\n cacheReadPricePer1m?: number | null;\n}\n\n/** The token split of one turn needed to estimate its cost. */\nexport interface CostUsage {\n inputTokens: number;\n outputTokens: number;\n cacheWriteTokens?: number | null | undefined;\n cacheReadTokens?: number | null | undefined;\n}\n\n/**\n * A normalized usage row the bucketers consume. Each adapter maps its raw DB row into this shape\n * (MikroORM reads `thread.id` + `createdAt`, Drizzle/in-memory read the flat `threadId` + `day`).\n */\nexport interface GovernanceUsageInput extends CostUsage {\n modelId: string;\n actorRef: string;\n threadId: string;\n /** The `YYYY-MM-DD` UTC day the row belongs to (its trend bucket). */\n day: string;\n /** Provider-reported spend for the row; wins over the token estimate when present. */\n costUsd?: number | null | undefined;\n}\n\n/** Thread metadata joined onto a spend bucket. */\nexport interface ThreadMeta {\n title: string;\n actorRef: string;\n}\n\n/**\n * Token-ledger estimate for one turn against a pricing row: the uncached input at the input rate,\n * cache-write/cache-read tokens at their own rates (falling back to the input rate when unpriced),\n * plus output at the output rate. An unpriced model (`price === undefined`) contributes 0 — its\n * tokens still count. Cache token counts are subsets of `inputTokens`, so the uncached remainder is\n * the difference.\n */\nexport function estimateCost(usage: CostUsage, price: ModelPrice | undefined): number {\n if (price === undefined) {\n return 0;\n }\n const cacheWriteTokens = usage.cacheWriteTokens ?? 0;\n const cacheReadTokens = usage.cacheReadTokens ?? 0;\n const uncachedInputTokens = usage.inputTokens - cacheWriteTokens - cacheReadTokens;\n return (\n (uncachedInputTokens / 1_000_000) * price.inputPricePer1m +\n (cacheWriteTokens / 1_000_000) * (price.cacheWritePricePer1m ?? price.inputPricePer1m) +\n (cacheReadTokens / 1_000_000) * (price.cacheReadPricePer1m ?? price.inputPricePer1m) +\n (usage.outputTokens / 1_000_000) * price.outputPricePer1m\n );\n}\n\n/** Provider-reported cost wins per row; otherwise the cache-aware token estimate. */\nfunction rowCost(row: GovernanceUsageInput, prices: ReadonlyMap<string, ModelPrice>): number {\n return row.costUsd ?? estimateCost(row, prices.get(row.modelId));\n}\n\n/** Aggregate usage rows into per-model spend, highest cost first then modelId ascending. */\nexport function bucketByModel(\n rows: GovernanceUsageInput[],\n prices: ReadonlyMap<string, ModelPrice>,\n): ModelSpendRow[] {\n const byModel = new Map<\n string,\n { requests: number; inputTokens: number; outputTokens: number; costUsd: number }\n >();\n for (const row of rows) {\n const bucket = byModel.get(row.modelId) ?? {\n requests: 0,\n inputTokens: 0,\n outputTokens: 0,\n costUsd: 0,\n };\n bucket.requests += 1;\n bucket.inputTokens += row.inputTokens;\n bucket.outputTokens += row.outputTokens;\n bucket.costUsd += rowCost(row, prices);\n byModel.set(row.modelId, bucket);\n }\n const result: ModelSpendRow[] = [];\n for (const [modelId, bucket] of byModel) {\n result.push({\n modelId,\n requests: bucket.requests,\n inputTokens: bucket.inputTokens,\n outputTokens: bucket.outputTokens,\n costUsd: bucket.costUsd,\n });\n }\n result.sort(\n (left, right) => right.costUsd - left.costUsd || left.modelId.localeCompare(right.modelId),\n );\n return result;\n}\n\n/** Aggregate usage rows into per-actor spend (with distinct thread counts), highest cost first. */\nexport function bucketByActor(\n rows: GovernanceUsageInput[],\n prices: ReadonlyMap<string, ModelPrice>,\n): ActorSpendRow[] {\n const byActor = new Map<\n string,\n { requests: number; totalTokens: number; costUsd: number; threadIds: Set<string> }\n >();\n for (const row of rows) {\n const bucket = byActor.get(row.actorRef) ?? {\n requests: 0,\n totalTokens: 0,\n costUsd: 0,\n threadIds: new Set<string>(),\n };\n bucket.requests += 1;\n bucket.totalTokens += row.inputTokens + row.outputTokens;\n bucket.costUsd += rowCost(row, prices);\n bucket.threadIds.add(row.threadId);\n byActor.set(row.actorRef, bucket);\n }\n const result: ActorSpendRow[] = [];\n for (const [actorRef, bucket] of byActor) {\n result.push({\n actorRef,\n requests: bucket.requests,\n totalTokens: bucket.totalTokens,\n costUsd: bucket.costUsd,\n threadCount: bucket.threadIds.size,\n });\n }\n result.sort(\n (left, right) => right.costUsd - left.costUsd || left.actorRef.localeCompare(right.actorRef),\n );\n return result;\n}\n\n/**\n * Aggregate usage rows into per-thread spend, highest cost first then threadId ascending, capped at\n * `limit`. A thread absent from `threads` is dropped when `includeUnknownThreads` is false (the SQL\n * adapters fetch only non-deleted threads, so a soft-deleted thread's rows vanish from the ranking);\n * when true it is kept with blank title/actor (the in-memory adapter's semantics).\n */\nexport function bucketByThread(\n rows: GovernanceUsageInput[],\n prices: ReadonlyMap<string, ModelPrice>,\n threads: ReadonlyMap<string, ThreadMeta>,\n options: { limit: number; includeUnknownThreads: boolean },\n): ThreadSpendRow[] {\n const byThread = new Map<string, { requests: number; totalTokens: number; costUsd: number }>();\n for (const row of rows) {\n const bucket = byThread.get(row.threadId) ?? { requests: 0, totalTokens: 0, costUsd: 0 };\n bucket.requests += 1;\n bucket.totalTokens += row.inputTokens + row.outputTokens;\n bucket.costUsd += rowCost(row, prices);\n byThread.set(row.threadId, bucket);\n }\n const result: ThreadSpendRow[] = [];\n for (const [threadId, bucket] of byThread) {\n const thread = threads.get(threadId);\n if (thread === undefined && !options.includeUnknownThreads) {\n continue;\n }\n result.push({\n threadId,\n title: thread?.title ?? '',\n actorRef: thread?.actorRef ?? '',\n requests: bucket.requests,\n totalTokens: bucket.totalTokens,\n costUsd: bucket.costUsd,\n });\n }\n result.sort(\n (left, right) => right.costUsd - left.costUsd || left.threadId.localeCompare(right.threadId),\n );\n return result.slice(0, options.limit);\n}\n\n/** Aggregate usage rows into a daily token/cost trend, ascending by day. */\nexport function bucketUsageTrend(\n rows: GovernanceUsageInput[],\n prices: ReadonlyMap<string, ModelPrice>,\n): UsageTrendPoint[] {\n const byDay = new Map<string, { totalTokens: number; costUsd: number }>();\n for (const row of rows) {\n const bucket = byDay.get(row.day) ?? { totalTokens: 0, costUsd: 0 };\n bucket.totalTokens += row.inputTokens + row.outputTokens;\n bucket.costUsd += rowCost(row, prices);\n byDay.set(row.day, bucket);\n }\n const result: UsageTrendPoint[] = [];\n for (const [day, bucket] of byDay) {\n result.push({ day, totalTokens: bucket.totalTokens, costUsd: bucket.costUsd });\n }\n result.sort((left, right) => left.day.localeCompare(right.day));\n return result;\n}\n\n/** Turn an inclusive `YYYY-MM-DD` day range into the UTC datetime bounds used to filter usage rows. */\nexport function dayBoundsUtc(range: GovernanceRange): { start: Date; end: Date } {\n return {\n start: new Date(`${range.fromDay}T00:00:00.000Z`),\n end: new Date(`${range.toDay}T23:59:59.999Z`),\n };\n}\n","import type { RolesPolicy } from './spi/roles-policy.js';\nimport type { Actor, ToolSpec } from './types.js';\n\n/** First filter layer: drop tools the actor's role may not invoke. `can` may be async (authz). */\nexport async function filterToolsByRole(\n tools: ToolSpec[],\n actor: Actor,\n policy: RolesPolicy,\n): Promise<ToolSpec[]> {\n const checked = await Promise.all(\n tools.map(async (tool) => ({ tool, allowed: await policy.can(actor, tool) })),\n );\n return checked.filter((entry) => entry.allowed).map((entry) => entry.tool);\n}\n\n/** Second filter layer: if the agent pins an allow-list, keep only those tool names. */\nexport function filterToolsByAllowList(\n tools: ToolSpec[],\n allowedTools: string[] | undefined,\n): ToolSpec[] {\n if (allowedTools === undefined) {\n return tools;\n }\n const allowed = new Set(allowedTools);\n return tools.filter((tool) => allowed.has(tool.name));\n}\n","import type { AgentDefinition } from './types.js';\n\n/** Holds the named agent definitions registered via `AgentModule.forFeature([...])`. */\nexport class AgentRegistry {\n private readonly definitions = new Map<string, AgentDefinition>();\n\n register(definition: AgentDefinition): void {\n this.definitions.set(definition.name, definition);\n }\n\n get(name: string): AgentDefinition | undefined {\n return this.definitions.get(name);\n }\n\n has(name: string): boolean {\n return this.definitions.has(name);\n }\n\n list(): AgentDefinition[] {\n return [...this.definitions.values()];\n }\n}\n","import type { StandardSchemaV1 } from '@standard-schema/spec';\nimport type { RolesPolicy } from './spi/roles-policy.js';\nimport type { AiToolCtx, ToolHandler } from './spi/tool.js';\nimport { filterToolsByAllowList, filterToolsByRole } from './tool-filters.js';\nimport type { Actor, ToolDefinition, ToolSpec } from './types.js';\n\n/** Thrown when an actor invokes a tool their role is not allowed. */\nexport class ToolForbiddenError extends Error {\n constructor(public readonly toolName: string) {\n super(`Tool \"${toolName}\" is not allowed for this role`);\n this.name = 'ToolForbiddenError';\n }\n}\n\n/** Thrown when a tool is invoked that was never registered. */\nexport class ToolNotFoundError extends Error {\n constructor(public readonly toolName: string) {\n super(`Tool \"${toolName}\" is not registered`);\n this.name = 'ToolNotFoundError';\n }\n}\n\n/** Thrown when a tool's input fails its Standard Schema validation. */\nexport class ToolInputInvalidError extends Error {\n constructor(\n public readonly toolName: string,\n public readonly issues: readonly StandardSchemaV1.Issue[],\n ) {\n super(\n `Invalid input for tool \"${toolName}\": ${issues.map((issue) => issue.message).join('; ')}`,\n );\n this.name = 'ToolInputInvalidError';\n }\n}\n\ninterface Entry {\n spec: ToolSpec;\n handler: ToolHandler;\n}\n\n/**\n * Holds every registered tool and gates invocation.\n *\n * Note: `definitionsFor` returns NEUTRAL definitions (no `execute`). The agent loop runs\n * each tool itself as a (durable) step — so even read tools are not auto-executed by the\n * model. `action` tools additionally require HITL approval before the loop runs them.\n */\nexport class ToolRegistry {\n private readonly entries = new Map<string, Entry>();\n\n register(spec: ToolSpec, handler: ToolHandler): void {\n this.entries.set(spec.name, { spec, handler });\n }\n\n has(name: string): boolean {\n return this.entries.has(name);\n }\n\n spec(name: string): ToolSpec | undefined {\n return this.entries.get(name)?.spec;\n }\n\n allSpecs(): ToolSpec[] {\n return [...this.entries.values()].map((entry) => entry.spec);\n }\n\n /** The tools to offer the model for this actor+agent, after the two filter layers. */\n async definitionsFor(\n actor: Actor,\n policy: RolesPolicy,\n allowedTools?: string[],\n ): Promise<ToolDefinition[]> {\n const roleScoped = await filterToolsByRole(this.allSpecs(), actor, policy);\n const allowScoped = filterToolsByAllowList(roleScoped, allowedTools);\n return allowScoped.map((spec) => ({\n name: spec.name,\n kind: spec.kind,\n description: spec.description,\n inputSchema: spec.inputSchema,\n }));\n }\n\n /** Run a tool. Re-checks the role (defense-in-depth) and re-parses the input via Zod. */\n async invoke(\n name: string,\n input: unknown,\n ctx: AiToolCtx,\n policy: RolesPolicy,\n ): Promise<unknown> {\n const entry = this.entries.get(name);\n if (entry === undefined) {\n throw new ToolNotFoundError(name);\n }\n if (!(await policy.can(ctx.actor, entry.spec))) {\n throw new ToolForbiddenError(name);\n }\n const validation = await entry.spec.inputSchema['~standard'].validate(input);\n if (validation.issues !== undefined) {\n throw new ToolInputInvalidError(name, validation.issues);\n }\n return entry.handler.execute(validation.value, ctx);\n }\n}\n\n/** Default gate: one of the actor's roles must be in spec.roles (defaulting to ADMIN-only). */\nexport class DefaultRolesPolicy implements RolesPolicy {\n constructor(private readonly defaultRoles: string[] = ['ADMIN']) {}\n\n can(actor: Actor, tool: ToolSpec): boolean {\n const allowed = tool.roles ?? this.defaultRoles;\n return (actor.roles ?? []).some((role) => allowed.includes(role));\n }\n}\n","import { emit } from '@dudousxd/nestjs-diagnostics';\n\n/** Payloads carried on each `aviary:agent:*` channel. */\nexport interface AgentRunStarted {\n runId: string;\n threadId: string;\n actorId: string;\n /** Which agent is handling the run. */\n agentName?: string;\n}\nexport interface AgentMessageEvent {\n runId: string;\n threadId: string;\n role: 'user' | 'assistant';\n textLength: number;\n}\nexport interface AgentToolCallEvent {\n runId: string;\n toolName: string;\n toolType: 'read' | 'action';\n status: string;\n durationMs?: number;\n}\nexport interface AgentQuotaExceeded {\n actorId: string;\n usedTokens: number;\n limitTokens: number;\n}\nexport interface AgentRunFinished {\n runId: string;\n threadId: string;\n steps: number;\n inputTokens: number;\n outputTokens: number;\n}\nexport interface AgentRunFailed {\n runId: string;\n /** Stable failure slug, e.g. `quota_exceeded` or `run_failed`. */\n code: string;\n message: string;\n}\nexport interface AgentDelegated {\n runId: string;\n fromAgent?: string;\n toAgent: string;\n}\nexport interface AgentRetrieved {\n runId: string;\n query: string;\n /** How many passages the retriever returned. */\n count: number;\n}\n\n/** Declaration-merge so `emit('agent', ...)` and telescope infer the agent payloads. */\ndeclare module '@dudousxd/nestjs-diagnostics' {\n interface ChannelRegistry {\n agent: {\n 'run.started': AgentRunStarted;\n message: AgentMessageEvent;\n 'tool-call': AgentToolCallEvent;\n 'quota.exceeded': AgentQuotaExceeded;\n 'run.finished': AgentRunFinished;\n 'run.failed': AgentRunFailed;\n delegated: AgentDelegated;\n retrieved: AgentRetrieved;\n };\n }\n}\n\nexport function publishAgentRunStarted(payload: AgentRunStarted): void {\n emit('agent', 'run.started', payload);\n}\nexport function publishAgentMessage(payload: AgentMessageEvent): void {\n emit('agent', 'message', payload);\n}\nexport function publishAgentToolCall(payload: AgentToolCallEvent): void {\n emit('agent', 'tool-call', payload);\n}\nexport function publishAgentQuotaExceeded(payload: AgentQuotaExceeded): void {\n emit('agent', 'quota.exceeded', payload);\n}\nexport function publishAgentRunFinished(payload: AgentRunFinished): void {\n emit('agent', 'run.finished', payload);\n}\nexport function publishAgentRunFailed(payload: AgentRunFailed): void {\n emit('agent', 'run.failed', payload);\n}\nexport function publishAgentDelegated(payload: AgentDelegated): void {\n emit('agent', 'delegated', payload);\n}\nexport function publishAgentRetrieved(payload: AgentRetrieved): void {\n emit('agent', 'retrieved', payload);\n}\n","import {\n publishAgentDelegated,\n publishAgentMessage,\n publishAgentQuotaExceeded,\n publishAgentRetrieved,\n publishAgentRunFinished,\n publishAgentRunStarted,\n publishAgentToolCall,\n} from './diagnostics.js';\nimport type { AgentStore } from './spi/agent-store.js';\nimport type { ModelProvider } from './spi/model-provider.js';\nimport type { QuotaStore } from './spi/quota-store.js';\nimport type { Passage, Retriever } from './spi/retriever.js';\nimport type { RolesPolicy } from './spi/roles-policy.js';\nimport type { SinkWriter } from './spi/token-stream-sink.js';\nimport type { AiToolCtx } from './spi/tool.js';\nimport type { ToolRegistry } from './tool-registry.js';\nimport type {\n AgentRunInput,\n Decision,\n MessageUsage,\n ModelMessage,\n PromptBuilder,\n PromptContext,\n PromptContributor,\n ToolCallRequest,\n ToolResult,\n} from './types.js';\n\nexport interface AgentLoopDeps {\n model: ModelProvider;\n store: AgentStore;\n registry: ToolRegistry;\n rolesPolicy: RolesPolicy;\n quota?: QuotaStore;\n /**\n * Fallback accounting label when the provider's turn result doesn't report a `modelId`.\n * Optional — a provider that reports its own model makes this unnecessary.\n */\n modelId?: string;\n /** Pre-computed (YYYY-MM-DD) so the loop body stays deterministic under durable replay. */\n day: string;\n /** The agent's base prompt. A flat string, or a {@link PromptBuilder} resolved per turn. */\n systemPrompt: string | PromptBuilder;\n /**\n * Cross-agent system-prompt contributors, applied in order AFTER the agent's base prompt. Each\n * returns a section to append (or `null` to skip this turn). The app registers them via\n * `@SystemPromptContributor()`; the loop composes base + contributors into the effective prompt.\n */\n promptContributors?: PromptContributor[];\n maxSteps?: number;\n /** Optional host handle threaded to tool ctx (e.g. an ORM EntityManager). */\n host?: unknown;\n /** Agent-level tool allow-list. Undefined → all tools (after role filtering). */\n toolAllowList?: string[];\n /**\n * Per-tool execution timeout in ms. A tool that runs longer is aborted and recorded as failed\n * (the model gets the timeout as its result and can adapt) rather than hanging the turn.\n * Undefined → no timeout.\n */\n toolTimeoutMs?: number;\n /**\n * When set, after the final turn the loop makes one extra model call to propose up to this many\n * short follow-up questions, stored on the assistant message's `followUps`. Costs an extra call\n * (recorded as `follow_ups` usage). Undefined/0 → disabled.\n */\n followUpsCount?: number;\n /**\n * Enables always-on (\"inject\") RAG: before the turn, retrieve passages for the user message and\n * augment the system prompt with them. Its presence IS inject mode — agentic (tool) retrieval sets\n * no retriever here (it rides a normal `read` tool). Undefined → no injection.\n */\n retriever?: Retriever;\n /** How many passages inject-mode retrieval requests. Undefined → 5. */\n retrievalTopK?: number;\n}\n\n/** Renders retrieved passages as a numbered, citable context block for the system prompt. */\nfunction buildContextBlock(passages: Passage[]): string {\n const items = passages\n .map((passage, index) => {\n const label = passage.source !== undefined ? ` (${passage.source})` : '';\n return `[${index + 1}]${label} ${passage.text}`;\n })\n .join('\\n\\n');\n return `<retrieved_context>\\n${items}\\n</retrieved_context>\\nUse the retrieved context above to answer when relevant, and cite sources by their bracket number.`;\n}\n\nexport interface AgentLoopHooks {\n runId: string;\n /** A writer for this run's live token stream (data plane). */\n openSink(): SinkWriter | Promise<SinkWriter>;\n /** HITL gate for an action tool. Inline resolves a pending promise; durable awaits a signal. */\n awaitApproval(call: ToolCallRequest, ctx: AiToolCtx): Promise<Decision>;\n /**\n * Run another named agent and return its answer. Provided only when the host wired multi-agent\n * support (durable → child workflow, inline → nested loop). Exposed to tools as `ctx.runAgent`.\n */\n runAgent?(agentName: string, task: string): Promise<{ text: string }>;\n /**\n * Checkpoint wrapper. Inline = call fn directly; durable = ctx.step(name, fn).\n * EVERY side-effect and control-flow read goes through this so durable replay returns\n * cached results (stable ids, no double-write, no re-streaming).\n */\n step<T>(name: string, fn: () => Promise<T>): Promise<T>;\n}\n\nexport class QuotaExceededError extends Error {\n constructor() {\n super('Daily token quota exceeded');\n this.name = 'QuotaExceededError';\n }\n}\n\n/**\n * How deep agent→agent delegation may nest before the loop refuses further hops. A cap, not a\n * tuning knob: it stops a mis-wired `delegatesTo` cycle (A→B→A) from spawning runs unbounded.\n */\nexport const MAX_DELEGATION_DEPTH = 5;\n\n/** Resolve a prompt that may be a flat string or a {@link PromptBuilder}. */\nasync function resolvePrompt(prompt: string | PromptBuilder, ctx: PromptContext): Promise<string> {\n return typeof prompt === 'function' ? prompt(ctx) : prompt;\n}\n\n/**\n * The effective system prompt for a turn: the agent's own base prompt, then each cross-agent\n * contributor's section appended in order (skipping any that return `null`/empty this turn). This is\n * resolved from stable inputs (actor / agent / pageContext) once per turn; contributors should be\n * derived from those rather than from uncached I/O so it stays replay-safe.\n */\nasync function resolveSystemPrompt(deps: AgentLoopDeps, input: AgentRunInput): Promise<string> {\n const ctx: PromptContext = {\n actor: input.actor,\n agentName: input.agentName ?? 'default',\n ...(input.pageContext !== undefined ? { pageContext: input.pageContext } : {}),\n };\n const sections = [await resolvePrompt(deps.systemPrompt, ctx)];\n for (const contribute of deps.promptContributors ?? []) {\n const section = await contribute(ctx);\n if (section !== null && section.length > 0) {\n sections.push(section);\n }\n }\n return sections.join('\\n\\n');\n}\n\n/** An `agent`-kind tool's input is `{ task }` by convention; fall back to a JSON dump. */\nfunction extractTask(input: unknown): string {\n if (typeof input === 'object' && input !== null && 'task' in input) {\n const task = (input as { task: unknown }).task;\n if (typeof task === 'string') {\n return task;\n }\n }\n return JSON.stringify(input);\n}\n\nfunction deriveTitle(userText: string): string {\n const trimmed = userText.trim().replace(/\\s+/g, ' ');\n return trimmed.length > 60 ? `${trimmed.slice(0, 57)}...` : trimmed || 'New chat';\n}\n\n/** Thrown when a tool exceeds `toolTimeoutMs`; caught by the loop and recorded as a failed call. */\nclass ToolTimeoutError extends Error {\n constructor(toolName: string, ms: number) {\n super(`Tool \"${toolName}\" exceeded its ${ms}ms timeout`);\n this.name = 'ToolTimeoutError';\n }\n}\n\n/** Reject if `work` doesn't settle within `ms`. The underlying work is left to finish on its own. */\nfunction withTimeout<T>(work: Promise<T>, ms: number, toolName: string): Promise<T> {\n return new Promise<T>((resolve, reject) => {\n const timer = setTimeout(() => reject(new ToolTimeoutError(toolName, ms)), ms);\n work.then(\n (value) => {\n clearTimeout(timer);\n resolve(value);\n },\n (error) => {\n clearTimeout(timer);\n reject(error);\n },\n );\n });\n}\n\n/** Best-effort parse of the follow-ups model reply: a bare JSON array, tolerating code fences/prose. */\nfunction parseFollowUps(text: string, count: number): string[] {\n const source = text.match(/\\[[\\s\\S]*\\]/)?.[0] ?? text;\n try {\n const parsed: unknown = JSON.parse(source);\n if (Array.isArray(parsed)) {\n return parsed.filter((item): item is string => typeof item === 'string').slice(0, count);\n }\n } catch {\n /* not JSON — no follow-ups this turn */\n }\n return [];\n}\n\n/**\n * One extra, non-streamed model call that proposes short follow-up questions. Writes to a discarding\n * sink so its tokens never reach the user's live stream; the reply is parsed as a JSON string array.\n */\nasync function generateFollowUps(\n model: ModelProvider,\n messages: ModelMessage[],\n count: number,\n): Promise<{ followUps: string[]; usage: MessageUsage; modelId?: string }> {\n const discard: SinkWriter = { write: () => {}, end: () => {}, fail: () => {} };\n const turn = await model.runTurn({\n system: `Based on the conversation so far, propose up to ${count} short, distinct follow-up questions the user is likely to ask next. Respond with ONLY a JSON array of strings — no prose, no code fences.`,\n messages,\n tools: [],\n sink: discard,\n });\n return {\n followUps: parseFollowUps(turn.text, count),\n usage: turn.usage,\n ...(turn.modelId !== undefined ? { modelId: turn.modelId } : {}),\n };\n}\n\n/**\n * The provider-agnostic agent turn, reused by both the inline and durable runners.\n * It drives the model→tools→model iteration; the runner supplies the `step`/`awaitApproval`\n * hooks that make the same loop body either in-process or a replay-safe durable workflow.\n */\nexport async function runAgentLoop(\n deps: AgentLoopDeps,\n input: AgentRunInput,\n hooks: AgentLoopHooks,\n): Promise<{ text: string }> {\n const maxSteps = deps.maxSteps ?? 8;\n let system = await resolveSystemPrompt(deps, input);\n\n if (deps.quota !== undefined) {\n const quota = deps.quota;\n const state = await hooks.step('quota:check', () => quota.check(input.actor.id, deps.day));\n if (!state.withinLimit) {\n publishAgentQuotaExceeded({\n actorId: input.actor.id,\n usedTokens: state.usedTokens,\n limitTokens: state.limitTokens,\n });\n throw new QuotaExceededError();\n }\n }\n\n if (input.regenerate === true) {\n // Re-run the last exchange: drop every message after the thread's last user message (keeping\n // it), then answer it again. No new user message is appended.\n await hooks.step('regenerate:truncate', async () => {\n const existing = await deps.store.getThread(input.threadId);\n const messages = existing?.messages ?? [];\n let lastUserIndex = -1;\n for (let index = messages.length - 1; index >= 0; index -= 1) {\n if (messages[index]?.role === 'user') {\n lastUserIndex = index;\n break;\n }\n }\n const firstDropped = messages[lastUserIndex + 1];\n if (firstDropped !== undefined) {\n await deps.store.truncateFrom(input.threadId, firstDropped.id);\n }\n });\n } else {\n await hooks.step('persist:user', () =>\n deps.store.appendMessage({\n threadId: input.threadId,\n role: 'user',\n content: input.userText,\n }),\n );\n }\n\n const thread = await hooks.step('load:thread', () => deps.store.getThread(input.threadId));\n const modelMessages: ModelMessage[] = (thread?.messages ?? []).map((message) => ({\n role: message.role,\n content: message.content,\n ...(message.toolCalls !== undefined ? { toolCalls: message.toolCalls } : {}),\n ...(message.toolResults !== undefined ? { toolResults: message.toolResults } : {}),\n }));\n\n const writer = await hooks.openSink();\n let lastText = '';\n let steps = 0;\n let totalInput = 0;\n let totalOutput = 0;\n\n publishAgentRunStarted({\n runId: hooks.runId,\n threadId: input.threadId,\n actorId: input.actor.id,\n ...(input.agentName !== undefined ? { agentName: input.agentName } : {}),\n });\n\n // Inject-mode RAG: retrieve once for the user message and fold the passages into the system prompt\n // (a `ctx.step` so it's replay-cached under durable). Recorded below as a synthetic tool call on\n // the first assistant message, so citations surface through the same machinery as agentic search.\n let injectedPassages: Passage[] | undefined;\n if (deps.retriever !== undefined) {\n const retriever = deps.retriever;\n const passages = await hooks.step('retrieve', () =>\n retriever.retrieve(input.userText, { topK: deps.retrievalTopK ?? 5 }),\n );\n if (passages.length > 0) {\n injectedPassages = passages;\n system = `${system}\\n\\n${buildContextBlock(passages)}`;\n }\n publishAgentRetrieved({ runId: hooks.runId, query: input.userText, count: passages.length });\n }\n\n // NOTE: no try/finally around this loop. A durable runner suspends by THROWING through the stack\n // at `awaitApproval` (ctx.waitForSignal); a finally would then call writer.end() on every suspend\n // and prematurely close the live stream. We only end on normal completion — the throw propagates\n // to the engine, and the resumed replay reaches the writer.end() below.\n for (let i = 0; i < maxSteps; i += 1) {\n const tools = await deps.registry.definitionsFor(\n input.actor,\n deps.rolesPolicy,\n deps.toolAllowList,\n );\n\n const turn = await hooks.step(`llm:${i}`, () =>\n deps.model.runTurn({ system, messages: modelMessages, tools, sink: writer }),\n );\n\n await hooks.step(`persist:usage:${i}`, () =>\n deps.store.recordUsage({\n threadId: input.threadId,\n actorRef: input.actor.id,\n // provider-reported model wins over the configured fallback, so cost can't misattribute\n modelId: turn.modelId ?? deps.modelId ?? 'unknown',\n purpose: 'chat',\n usage: turn.usage,\n // persist the provider's actual cost when reported; the read-model prefers it over pricing\n ...(turn.costUsd !== undefined ? { costUsd: turn.costUsd } : {}),\n }),\n );\n if (deps.quota !== undefined) {\n const quota = deps.quota;\n await hooks.step(`quota:bump:${i}`, () =>\n quota.bump(input.actor.id, deps.day, turn.usage.inputTokens + turn.usage.outputTokens),\n );\n }\n\n steps += 1;\n totalInput += turn.usage.inputTokens;\n totalOutput += turn.usage.outputTokens;\n lastText = turn.text;\n publishAgentMessage({\n runId: hooks.runId,\n threadId: input.threadId,\n role: 'assistant',\n textLength: turn.text.length,\n });\n\n // A turn with no tool calls is the last one. Generate follow-up suggestions here (before the\n // append) so they land on the final assistant message, and stop after.\n const isFinalTurn = turn.toolCalls.length === 0;\n let followUps: string[] | undefined;\n if (isFinalTurn && deps.followUpsCount !== undefined && deps.followUpsCount > 0) {\n const count = deps.followUpsCount;\n const generated = await hooks.step(`followups:${i}`, () =>\n generateFollowUps(\n deps.model,\n [...modelMessages, { role: 'assistant', content: turn.text }],\n count,\n ),\n );\n if (generated.followUps.length > 0) {\n followUps = generated.followUps;\n }\n await hooks.step(`persist:usage:followups:${i}`, () =>\n deps.store.recordUsage({\n threadId: input.threadId,\n actorRef: input.actor.id,\n modelId: generated.modelId ?? deps.modelId ?? 'unknown',\n purpose: 'follow_ups',\n usage: generated.usage,\n }),\n );\n }\n\n const assistant = await hooks.step(`persist:assistant:${i}`, () =>\n deps.store.appendMessage({\n threadId: input.threadId,\n role: 'assistant',\n content: turn.text,\n usage: turn.usage,\n ...(input.agentName !== undefined ? { agentName: input.agentName } : {}),\n ...(turn.toolCalls.length > 0 ? { toolCalls: turn.toolCalls } : {}),\n ...(followUps !== undefined ? { followUps } : {}),\n }),\n );\n modelMessages.push({\n role: 'assistant',\n content: turn.text,\n ...(turn.toolCalls.length > 0 ? { toolCalls: turn.toolCalls } : {}),\n });\n\n // Record inject-mode retrieval as a synthetic auto-executed `retrieve` tool call on the assistant\n // message it informed — so its passages persist and render as citations exactly like an agentic\n // search would, without a new message field.\n if (i === 0 && injectedPassages !== undefined) {\n const passages = injectedPassages;\n const toolCallId = `retrieve-${assistant.id}`;\n await hooks.step(`persist:retrieval:${assistant.id}`, async () => {\n await deps.store.recordToolCall({\n toolCallId,\n messageId: assistant.id,\n toolName: 'retrieve',\n toolType: 'read',\n input: { query: input.userText },\n status: 'auto_executed',\n });\n await deps.store.updateToolCall({ toolCallId, status: 'executed', output: { passages } });\n });\n }\n\n if (isFinalTurn) {\n break;\n }\n\n const results: ToolResult[] = [];\n for (const call of turn.toolCalls) {\n const spec = deps.registry.spec(call.name);\n const toolType = spec?.kind ?? 'read';\n const ctx: AiToolCtx = {\n actor: input.actor,\n threadId: input.threadId,\n runId: hooks.runId,\n requestId: hooks.runId,\n ...(input.agentName !== undefined ? { agentName: input.agentName } : {}),\n ...(input.pageContext !== undefined ? { pageContext: input.pageContext } : {}),\n ...(deps.host !== undefined ? { host: deps.host } : {}),\n };\n\n // Delegation: an `agent`-kind tool runs another agent. Handled at the LOOP level (not in a\n // step) because the durable runner maps it to `ctx.child`, a ctx-level suspend point.\n if (toolType === 'agent') {\n const targetAgent = spec?.targetAgent ?? call.name;\n const task = extractTask(call.input);\n await hooks.step(`persist:toolcall:${call.id}`, () =>\n deps.store.recordToolCall({\n toolCallId: call.id,\n messageId: assistant.id,\n toolName: call.name,\n toolType: 'read',\n input: call.input,\n status: 'auto_executed',\n }),\n );\n // Cap nesting so a mis-wired delegation cycle can't spawn runs without bound.\n const overDepth = (input.delegationDepth ?? 0) >= MAX_DELEGATION_DEPTH;\n publishAgentDelegated({\n runId: hooks.runId,\n toAgent: targetAgent,\n ...(input.agentName !== undefined ? { fromAgent: input.agentName } : {}),\n });\n let sub: { text: string };\n if (overDepth) {\n sub = { text: `(delegation depth limit of ${MAX_DELEGATION_DEPTH} reached)` };\n } else if (hooks.runAgent) {\n sub = await hooks.runAgent(targetAgent, task);\n } else {\n sub = { text: `(no multi-agent support wired; cannot reach \"${targetAgent}\")` };\n }\n await hooks.step(`persist:toolexec:${call.id}`, () =>\n deps.store.updateToolCall({ toolCallId: call.id, status: 'executed', output: sub }),\n );\n results.push({ id: call.id, name: call.name, output: sub });\n continue;\n }\n\n if (toolType === 'action') {\n await hooks.step(`persist:toolcall:${call.id}`, () =>\n deps.store.recordToolCall({\n toolCallId: call.id,\n messageId: assistant.id,\n toolName: call.name,\n toolType: 'action',\n input: call.input,\n status: 'pending_approval',\n }),\n );\n const decision = await hooks.awaitApproval(call, ctx);\n if (!decision.approved) {\n await hooks.step(`persist:toolreject:${call.id}`, () =>\n deps.store.updateToolCall({\n toolCallId: call.id,\n status: 'rejected',\n ...(decision.reason !== undefined ? { error: decision.reason } : {}),\n }),\n );\n results.push({\n id: call.id,\n name: call.name,\n output: { rejected: true, reason: decision.reason ?? 'rejected by user' },\n error: 'rejected',\n });\n publishAgentToolCall({\n runId: hooks.runId,\n toolName: call.name,\n toolType,\n status: 'rejected',\n });\n continue;\n }\n } else {\n await hooks.step(`persist:toolcall:${call.id}`, () =>\n deps.store.recordToolCall({\n toolCallId: call.id,\n messageId: assistant.id,\n toolName: call.name,\n toolType: 'read',\n input: call.input,\n status: 'auto_executed',\n }),\n );\n }\n\n const startedAt = Date.now();\n try {\n const invocation = hooks.step(`tool:${call.id}`, () =>\n deps.registry.invoke(call.name, call.input, ctx, deps.rolesPolicy),\n );\n const output =\n deps.toolTimeoutMs !== undefined\n ? await withTimeout(invocation, deps.toolTimeoutMs, call.name)\n : await invocation;\n const executionMs = Date.now() - startedAt;\n await hooks.step(`persist:toolexec:${call.id}`, () =>\n deps.store.updateToolCall({\n toolCallId: call.id,\n status: 'executed',\n output,\n executionMs,\n ...(toolType === 'action' ? { executedByRef: input.actor.id } : {}),\n }),\n );\n results.push({ id: call.id, name: call.name, output });\n publishAgentToolCall({\n runId: hooks.runId,\n toolName: call.name,\n toolType,\n status: 'executed',\n durationMs: executionMs,\n });\n } catch (error) {\n const executionMs = Date.now() - startedAt;\n const message = error instanceof Error ? error.message : String(error);\n await hooks.step(`persist:toolfail:${call.id}`, () =>\n deps.store.updateToolCall({\n toolCallId: call.id,\n status: 'failed',\n error: message,\n executionMs,\n }),\n );\n results.push({ id: call.id, name: call.name, output: null, error: message });\n publishAgentToolCall({\n runId: hooks.runId,\n toolName: call.name,\n toolType,\n status: 'failed',\n durationMs: executionMs,\n });\n }\n }\n\n modelMessages.push({ role: 'user', content: '', toolResults: results });\n }\n\n if (thread !== null && (thread.title === '' || thread.title === 'New chat')) {\n await hooks.step('persist:title', () =>\n deps.store.setTitle(input.threadId, deriveTitle(input.userText)),\n );\n }\n\n await writer.end();\n publishAgentRunFinished({\n runId: hooks.runId,\n threadId: input.threadId,\n steps,\n inputTokens: totalInput,\n outputTokens: totalOutput,\n });\n return { text: lastText };\n}\n"],"mappings":"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","names":["AGENT_OPTIONS","Symbol","for","AGENT_STORE","AGENT_RUNNER","AGENT_DURABLE_RUNNER","AGENT_SINK","AGENT_MODEL","AGENT_ROLES_POLICY","AGENT_QUOTA_STORE","AGENT_TOOL_REGISTRY","AGENT_REGISTRY","AGENT_ACTOR_RESOLVER","AGENT_GOVERNANCE_QUERIES","AGENT_PRICING_STORE","AGENT_RETRIEVER","AGENT_EMBEDDING_PROVIDER","AGENT_DEPS_FACTORY","AGENT_PROMPT_CONTRIBUTORS","AgentStreamError","Error","code","error","message","name","seedModelPrices","store","prices","price","upsertModelPrice","estimateCost","usage","price","undefined","cacheWriteTokens","cacheReadTokens","uncachedInputTokens","inputTokens","inputPricePer1m","cacheWritePricePer1m","cacheReadPricePer1m","outputTokens","outputPricePer1m","rowCost","row","prices","costUsd","get","modelId","bucketByModel","rows","byModel","Map","bucket","requests","set","result","push","sort","left","right","localeCompare","bucketByActor","byActor","actorRef","totalTokens","threadIds","Set","add","threadId","threadCount","size","bucketByThread","threads","options","byThread","thread","includeUnknownThreads","title","slice","limit","bucketUsageTrend","byDay","day","dayBoundsUtc","range","start","Date","fromDay","end","toDay","filterToolsByRole","tools","actor","policy","checked","Promise","all","map","tool","allowed","can","filter","entry","filterToolsByAllowList","allowedTools","undefined","Set","has","name","AgentRegistry","definitions","Map","register","definition","set","name","get","has","list","values","ToolForbiddenError","Error","toolName","name","ToolNotFoundError","ToolInputInvalidError","issues","map","issue","message","join","ToolRegistry","entries","Map","register","spec","handler","set","has","get","allSpecs","values","entry","definitionsFor","actor","policy","allowedTools","roleScoped","filterToolsByRole","allowScoped","filterToolsByAllowList","kind","description","inputSchema","invoke","input","ctx","undefined","can","validation","validate","execute","value","DefaultRolesPolicy","defaultRoles","tool","allowed","roles","some","role","includes","publishAgentRunStarted","payload","emit","publishAgentMessage","publishAgentToolCall","publishAgentQuotaExceeded","publishAgentRunFinished","publishAgentRunFailed","publishAgentDelegated","publishAgentRetrieved","buildContextBlock","passages","items","map","passage","index","label","source","undefined","text","join","QuotaExceededError","Error","name","MAX_DELEGATION_DEPTH","resolvePrompt","prompt","ctx","resolveSystemPrompt","deps","input","actor","agentName","pageContext","sections","systemPrompt","contribute","promptContributors","section","length","push","extractTask","task","JSON","stringify","deriveTitle","userText","trimmed","trim","replace","slice","ToolTimeoutError","toolName","ms","withTimeout","work","Promise","resolve","reject","timer","setTimeout","then","value","clearTimeout","error","parseFollowUps","count","match","parsed","parse","Array","isArray","filter","item","generateFollowUps","model","messages","discard","write","end","fail","turn","runTurn","system","tools","sink","followUps","usage","modelId","runAgentLoop","hooks","maxSteps","quota","state","step","check","id","day","withinLimit","publishAgentQuotaExceeded","actorId","usedTokens","limitTokens","regenerate","existing","store","getThread","threadId","lastUserIndex","role","firstDropped","truncateFrom","appendMessage","content","thread","modelMessages","message","toolCalls","toolResults","writer","openSink","lastText","steps","totalInput","totalOutput","publishAgentRunStarted","runId","injectedPassages","retriever","retrieve","topK","retrievalTopK","publishAgentRetrieved","query","i","registry","definitionsFor","rolesPolicy","toolAllowList","recordUsage","actorRef","purpose","costUsd","bump","inputTokens","outputTokens","publishAgentMessage","textLength","isFinalTurn","followUpsCount","generated","assistant","toolCallId","recordToolCall","messageId","toolType","status","updateToolCall","output","results","call","spec","kind","requestId","host","targetAgent","overDepth","delegationDepth","publishAgentDelegated","toAgent","fromAgent","sub","runAgent","decision","awaitApproval","approved","reason","rejected","publishAgentToolCall","startedAt","Date","now","invocation","invoke","toolTimeoutMs","executionMs","executedByRef","durationMs","String","title","setTitle","publishAgentRunFinished"]}
|