@dudousxd/nestjs-agent-core 0.10.0 → 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -98,6 +98,16 @@ interface ToolSpec {
98
98
  targetAgent?: string;
99
99
  /** Roles allowed to invoke. Undefined → defaults applied by RolesPolicy (e.g. ADMIN-only). */
100
100
  roles?: string[];
101
+ /**
102
+ * Whether the tool exists in this deployment. `false` (or a predicate returning `false`) drops it
103
+ * before the role filter, so it is never offered to the model and cannot be invoked. Undefined →
104
+ * enabled.
105
+ *
106
+ * A predicate is re-evaluated every turn, so a flag flipped at runtime takes effect on the next
107
+ * message with nothing re-registered. For availability that depends on injected services, put
108
+ * `isEnabled()` on the handler instead — a spec is data, a handler is a provider.
109
+ */
110
+ enabled?: boolean | (() => boolean | Promise<boolean>);
101
111
  /**
102
112
  * An authorization ability name (e.g. 'cache.purge'). Consumed by an ability-aware RolesPolicy
103
113
  * such as the `@dudousxd/nestjs-agent-authz` Gate adapter. Apps that don't use authz ignore it
@@ -465,6 +475,33 @@ interface AiToolCtx {
465
475
  /** A tool implementation. `I` is the parsed (Zod-validated) input. */
466
476
  interface ToolHandler<I = unknown> {
467
477
  execute(input: I, ctx: AiToolCtx): Promise<unknown>;
478
+ /**
479
+ * Whether this tool exists in this deployment at all — evaluated per turn, BEFORE the roles
480
+ * policy, so a `false` here means the model is never shown the tool rather than being shown one
481
+ * it will be refused. Omit → always enabled.
482
+ *
483
+ * This is the seam for a feature flag or a licensing tier: the handler is an ordinary provider,
484
+ * so it can read injected config (`this.config.featureX`) that a decorator, evaluated at import
485
+ * time, cannot. Answering "does this capability exist here?"; `roles`/`RolesPolicy` answers the
486
+ * separate question "may THIS actor use it?", and both still run.
487
+ *
488
+ * Prefer this over conditionally registering the provider: registration happens while the
489
+ * `@Module` metadata is built, which in most apps is before configuration is loaded.
490
+ */
491
+ isEnabled?(): boolean | Promise<boolean>;
492
+ /**
493
+ * Whether THIS actor may use the tool, decided per turn. Omit → the role gate alone decides.
494
+ *
495
+ * The three existing gates all answer the question somewhere else: `roles` is static data,
496
+ * `RolesPolicy` is one app-wide rule for every tool, and an agent's `tools` allow-list is fixed
497
+ * when the agent is declared. This one lives on the tool and runs with DI, so it can ask the
498
+ * questions only the tool knows to ask — is this user's org on the plan that includes it, does
499
+ * this actor own the base being queried, is the per-user override in the DB set today.
500
+ *
501
+ * Runs AFTER {@link isEnabled} and the `RolesPolicy`, and all of them must pass. Applied both
502
+ * when the turn's tool list is built (a denied actor is never shown it) and again on invoke.
503
+ */
504
+ canUse?(actor: Actor): boolean | Promise<boolean>;
468
505
  }
469
506
 
470
507
  /**
@@ -1044,6 +1081,13 @@ interface ToolStatRow {
1044
1081
  calls: number;
1045
1082
  failed: number;
1046
1083
  rejected: number;
1084
+ /**
1085
+ * p50 (median) of executionMs across calls that recorded one; null when none carry it. Reported
1086
+ * alongside p95 rather than a mean: tool latency is long-tailed (a retry or a slow upstream drags
1087
+ * an average somewhere no single call ever was), so the pair "typical / tail" is what an operator
1088
+ * can actually act on.
1089
+ */
1090
+ p50ExecutionMs: number | null;
1047
1091
  /** p95 of executionMs across executed calls; null when none carry it. */
1048
1092
  p95ExecutionMs: number | null;
1049
1093
  }
@@ -1095,6 +1139,115 @@ interface RunWhere {
1095
1139
  fromDay?: string;
1096
1140
  toDay?: string;
1097
1141
  }
1142
+ /** Filters for {@link AgentGovernanceQueries.approvalsPage}. */
1143
+ interface ApprovalWhere {
1144
+ toolName?: string;
1145
+ threadId?: string;
1146
+ /** The requesting thread's owner. */
1147
+ actorRef?: string;
1148
+ agentName?: string;
1149
+ /** Inclusive UTC day bounds on when the approval was requested, `YYYY-MM-DD`. */
1150
+ fromDay?: string;
1151
+ toDay?: string;
1152
+ }
1153
+ /** One tool call inside a {@link GovernanceRunDetail}, with the execution outcome a list row can't afford to carry. */
1154
+ interface RunToolCallRow {
1155
+ toolCallId: string;
1156
+ toolName: string;
1157
+ toolType: string;
1158
+ status: string;
1159
+ /** Wall time of the execution; null for a call that never executed (rejected/still pending). */
1160
+ executionMs: number | null;
1161
+ /** Who executed/decided it, when the store recorded an attribution. */
1162
+ executedByRef: string | null;
1163
+ /** The failure text for a `failed` call; null otherwise. */
1164
+ error: string | null;
1165
+ /** ISO timestamp. */
1166
+ createdAt: string;
1167
+ }
1168
+ /** The owning thread's headline, carried on a drill-down so it can be named without a second read. */
1169
+ interface DetailThreadRef {
1170
+ threadId: string;
1171
+ title: string;
1172
+ actorRef: string;
1173
+ /** True when the thread is soft-deleted — its history is still readable, the thread is not. */
1174
+ deleted: boolean;
1175
+ }
1176
+ /**
1177
+ * Everything a run drill-down renders: the run row itself, its owning thread's headline, and the
1178
+ * tool calls attributed to it.
1179
+ *
1180
+ * `toolCalls` is empty for a run recorded before tool calls carried a `runId` (the column is
1181
+ * nullable and pre-rollout rows have none) — indistinguishable, from here, from a run that called
1182
+ * no tools. There is deliberately no cost figure: the token ledger has no run column, so per-run
1183
+ * spend is not attributable without a store migration.
1184
+ */
1185
+ interface GovernanceRunDetail {
1186
+ run: RecentRunRow;
1187
+ thread: DetailThreadRef;
1188
+ /** The run's tool calls, oldest first — the order they were requested in. */
1189
+ toolCalls: RunToolCallRow[];
1190
+ }
1191
+ /** One message inside a {@link GovernanceThreadDetail}. `content` is capped server-side. */
1192
+ interface ThreadMessageRow {
1193
+ messageId: string;
1194
+ role: string;
1195
+ /** Message text, cut to {@link THREAD_DETAIL_CONTENT_CHARS}; see `truncated`. */
1196
+ content: string;
1197
+ /** True when `content` was cut — the console shows an explicit "…" rather than implying the tail. */
1198
+ truncated: boolean;
1199
+ agentName: string | null;
1200
+ /** How many tool calls this message requested. */
1201
+ toolCallCount: number;
1202
+ /** ISO timestamp. */
1203
+ createdAt: string;
1204
+ }
1205
+ /** Token/cost rollup across a thread's whole ledger (not range-scoped — a thread's lifetime). */
1206
+ interface ThreadUsageRollup {
1207
+ /** Ledger rows, i.e. billed turns. */
1208
+ requests: number;
1209
+ inputTokens: number;
1210
+ outputTokens: number;
1211
+ totalTokens: number;
1212
+ costUsd: number;
1213
+ }
1214
+ /** Everything a thread drill-down renders, in one call. */
1215
+ interface GovernanceThreadDetail {
1216
+ /** The thread's own activity row (`messageCount` is the thread total, not the page below). */
1217
+ thread: ThreadActivityRow;
1218
+ /** True when the thread is soft-deleted. */
1219
+ deleted: boolean;
1220
+ usage: ThreadUsageRollup;
1221
+ /** The thread's runs, newest first, capped at the query's `runLimit`. */
1222
+ runs: RecentRunRow[];
1223
+ /** Runs on this thread in total — `runs.length < runTotal` means the cap bit. */
1224
+ runTotal: number;
1225
+ /** The thread's messages, newest first, capped at the query's `messageLimit`. */
1226
+ messages: ThreadMessageRow[];
1227
+ }
1228
+ /** Row caps for {@link AgentGovernanceQueries.threadDetail}, already clamped by the caller. */
1229
+ interface GovernanceThreadDetailQuery {
1230
+ threadId: string;
1231
+ /** Max messages returned, newest first. */
1232
+ messageLimit: number;
1233
+ /** Max runs returned, newest first. */
1234
+ runLimit: number;
1235
+ }
1236
+ /**
1237
+ * Per-message content cap for {@link ThreadMessageRow.content}. A drill-down is a triage view, not a
1238
+ * transcript reader: capping here keeps one response bounded regardless of how long an assistant
1239
+ * turn ran. Shared by every adapter so the cut is identical wherever the console is served from.
1240
+ */
1241
+ declare const THREAD_DETAIL_CONTENT_CHARS = 2000;
1242
+ /**
1243
+ * Cut a message body to {@link THREAD_DETAIL_CONTENT_CHARS}, reporting whether it was cut. Lives
1244
+ * next to the cap so every adapter truncates at the same boundary — a console comparing two stores
1245
+ * must not see two different "…".
1246
+ */
1247
+ declare function truncateDetailContent(content: string): {
1248
+ content: string;
1249
+ truncated: boolean;
1250
+ };
1098
1251
  /**
1099
1252
  * The governance read-model. Cost is `inputTokens/1e6 * inputPricePer1m + outputTokens/1e6 *
1100
1253
  * outputPricePer1m` against the current pricing row per model; an unpriced model contributes 0 cost
@@ -1113,8 +1266,19 @@ interface AgentGovernanceQueries {
1113
1266
  runErrors(range: GovernanceRange): Promise<RunErrorBreakdownRow[]>;
1114
1267
  runTrend(range: GovernanceRange): Promise<RunTrendPoint[]>;
1115
1268
  recentRuns(limit: number): Promise<RecentRunRow[]>;
1116
- /** Tool calls sitting `pending_approval`, oldest first — an inbox drains from the back. Capped at `limit`. */
1269
+ /**
1270
+ * Tool calls sitting `pending_approval`, oldest first — an inbox drains from the back. Capped at
1271
+ * `limit`, with NO total: a caller that needs to know whether the cap hid anything wants
1272
+ * {@link approvalsPage} instead.
1273
+ */
1117
1274
  pendingApprovals(limit: number): Promise<PendingApprovalRow[]>;
1275
+ /**
1276
+ * Paged, filterable approvals inbox, oldest first (same ordering as `pendingApprovals`). Unlike
1277
+ * that method this reports `total`, so a console can page a backlog and say how much of it is
1278
+ * off-screen — the one failure this surface cannot afford is a pending approval nobody sees.
1279
+ * An adapter without the backing data returns an empty page (`total: 0`) rather than throwing.
1280
+ */
1281
+ approvalsPage(query: GovernancePageQuery<ApprovalWhere>): Promise<GovernancePage<PendingApprovalRow>>;
1118
1282
  /** Per-tool call/failure/rejection/latency rollup over the range, highest call count first. */
1119
1283
  toolStats(range: GovernanceRange): Promise<ToolStatRow[]>;
1120
1284
  /**
@@ -1132,6 +1296,21 @@ interface AgentGovernanceQueries {
1132
1296
  * by a store without run recording (no `recordRunStart`) returns an empty page (`total: 0`).
1133
1297
  */
1134
1298
  runsPage(query: GovernancePageQuery<RunWhere>): Promise<GovernancePage<RecentRunRow>>;
1299
+ /**
1300
+ * One run with its owning thread and its tool calls — the drill-down behind a row in the runs
1301
+ * table. `null` when no run has that id. ONE call, not one per tool call: a failed run is the
1302
+ * thing an operator opens first and it should not cost a query per step.
1303
+ *
1304
+ * An adapter backed by a store without run recording returns `null` for every id.
1305
+ */
1306
+ runDetail(runId: string): Promise<GovernanceRunDetail | null>;
1307
+ /**
1308
+ * One thread with its lifetime usage rollup, its recent runs and its recent messages — the
1309
+ * drill-down behind a row in the threads table. `null` when no thread has that id; a soft-deleted
1310
+ * thread IS returned (with `deleted: true`), because "what did the thread we just deleted do" is
1311
+ * exactly the question an audit asks.
1312
+ */
1313
+ threadDetail(query: GovernanceThreadDetailQuery): Promise<GovernanceThreadDetail | null>;
1135
1314
  }
1136
1315
 
1137
1316
  /**
@@ -1248,6 +1427,12 @@ declare function bucketByThread(rows: GovernanceUsageInput[], prices: ReadonlyMa
1248
1427
  limit: number;
1249
1428
  includeUnknownThreads: boolean;
1250
1429
  }): ThreadSpendRow[];
1430
+ /**
1431
+ * Sum an already-scoped set of usage rows into one rollup — the thread drill-down's headline. Same
1432
+ * `rowCost` as every bucketer above (provider-reported cost wins, else the cache-aware estimate), so
1433
+ * a thread's detail cost and its row in the by-thread ranking can never disagree.
1434
+ */
1435
+ declare function rollupThreadUsage(rows: GovernanceUsageInput[], prices: ReadonlyMap<string, ModelPrice>): ThreadUsageRollup;
1251
1436
  /** Aggregate usage rows into a daily token/cost trend, ascending by day. */
1252
1437
  declare function bucketUsageTrend(rows: GovernanceUsageInput[], prices: ReadonlyMap<string, ModelPrice>): UsageTrendPoint[];
1253
1438
  /** Turn an inclusive `YYYY-MM-DD` day range into the UTC datetime bounds used to filter usage rows. */
@@ -1256,6 +1441,36 @@ declare function dayBoundsUtc(range: GovernanceRange): {
1256
1441
  end: Date;
1257
1442
  };
1258
1443
 
1444
+ /**
1445
+ * Is this tool part of this deployment right now? `ToolSpec.enabled` and the handler's
1446
+ * `isEnabled()` are ANDed — either one saying no is enough — and both default to yes.
1447
+ *
1448
+ * Resolved per turn rather than at registration, so the answer can come from configuration that
1449
+ * did not exist when the module was built.
1450
+ */
1451
+ declare function isToolEnabled(spec: ToolSpec, handler?: ToolHandler): Promise<boolean>;
1452
+ /**
1453
+ * Zeroth filter layer: drop tools this deployment has turned off, before anyone asks who may call
1454
+ * them. A disabled tool is absent, not forbidden — the difference matters, because "forbidden"
1455
+ * tells the model (and the user reading a refusal) that the capability exists.
1456
+ */
1457
+ declare function filterToolsByEnabled<T extends {
1458
+ spec: ToolSpec;
1459
+ handler?: ToolHandler;
1460
+ }>(entries: T[]): Promise<T[]>;
1461
+ /**
1462
+ * May this actor use this tool, per the tool's OWN gate? Tools without a `canUse` say yes and are
1463
+ * governed by the `RolesPolicy` alone.
1464
+ */
1465
+ declare function canActorUseTool(actor: Actor, handler?: ToolHandler): Promise<boolean>;
1466
+ /**
1467
+ * Third filter layer: drop tools whose own `canUse` refuses this actor. Runs after the app-wide
1468
+ * `RolesPolicy`, and is additive to it — a tool can narrow who reaches it, never widen.
1469
+ */
1470
+ declare function filterToolsByCanUse<T extends {
1471
+ spec: ToolSpec;
1472
+ handler?: ToolHandler;
1473
+ }>(entries: T[], actor: Actor): Promise<T[]>;
1259
1474
  /** First filter layer: drop tools the actor's role may not invoke. `can` may be async (authz). */
1260
1475
  declare function filterToolsByRole(tools: ToolSpec[], actor: Actor, policy: RolesPolicy): Promise<ToolSpec[]>;
1261
1476
  /** Second filter layer: if the agent pins an allow-list, keep only those tool names. */
@@ -1275,6 +1490,19 @@ declare class ToolForbiddenError extends Error {
1275
1490
  readonly toolName: string;
1276
1491
  constructor(toolName: string);
1277
1492
  }
1493
+ /**
1494
+ * Thrown when a registered tool is invoked while this deployment has it turned off (`enabled` /
1495
+ * `isEnabled()`). Distinct from {@link ToolForbiddenError}, which is about the actor, and from
1496
+ * {@link ToolNotFoundError}, which is about a name nobody registered — an operator reading a log
1497
+ * needs to tell "you flipped the flag" apart from "that tool does not exist in this build".
1498
+ *
1499
+ * Reachable in normal operation, not just from a forged call: a HITL `action` approved before the
1500
+ * flag was turned off runs its tool afterwards.
1501
+ */
1502
+ declare class ToolDisabledError extends Error {
1503
+ readonly toolName: string;
1504
+ constructor(toolName: string);
1505
+ }
1278
1506
  /** Thrown when a tool is invoked that was never registered. */
1279
1507
  declare class ToolNotFoundError extends Error {
1280
1508
  readonly toolName: string;
@@ -1299,9 +1527,19 @@ declare class ToolRegistry {
1299
1527
  has(name: string): boolean;
1300
1528
  spec(name: string): ToolSpec | undefined;
1301
1529
  allSpecs(): ToolSpec[];
1302
- /** The tools to offer the model for this actor+agent, after the two filter layers. */
1530
+ /**
1531
+ * The tools to offer the model for this actor+agent, after the four filter layers: what this
1532
+ * deployment has enabled, what this actor's role allows, what each tool's own `canUse` allows
1533
+ * this actor, and finally what this agent pinned.
1534
+ *
1535
+ * Every layer only ever removes tools, so no arrangement of them can widen what a turn reaches.
1536
+ */
1303
1537
  definitionsFor(actor: Actor, policy: RolesPolicy, allowedTools?: string[]): Promise<ToolDefinition[]>;
1304
- /** Run a tool. Re-checks the role (defense-in-depth) and re-parses the input via Zod. */
1538
+ /**
1539
+ * Run a tool. Re-checks that the tool is enabled and that the role allows it (defense-in-depth —
1540
+ * a call can reach here from a replayed durable step or an approval granted before the flag
1541
+ * moved, neither of which went through `definitionsFor` again) and re-parses the input via Zod.
1542
+ */
1305
1543
  invoke(name: string, input: unknown, ctx: AiToolCtx, policy: RolesPolicy): Promise<unknown>;
1306
1544
  }
1307
1545
  /** Default gate: one of the actor's roles must be in spec.roles (defaulting to ADMIN-only). */
@@ -1597,4 +1835,4 @@ type AgentDiagnosticKey = `agent:${AgentDiagnosticEvent}`;
1597
1835
  */
1598
1836
  declare function agentDiagnosticKey(event: AgentDiagnosticEvent): AgentDiagnosticKey;
1599
1837
 
1600
- export { AGENT_ACTOR_DIRECTORY, AGENT_ACTOR_RESOLVER, AGENT_APPROVAL_PORT, AGENT_ATTACHMENT_STAGING, AGENT_DEPS_FACTORY, AGENT_DIAGNOSTIC_EVENTS, AGENT_DURABLE_RUNNER, AGENT_EMBEDDING_PROVIDER, AGENT_GOVERNANCE_QUERIES, AGENT_MODEL, AGENT_OPTIONS, AGENT_PRICING_STORE, AGENT_PROMPT_CONTRIBUTORS, AGENT_QUOTA_STORE, AGENT_REGISTRY, AGENT_RETRIEVER, AGENT_ROLES_POLICY, AGENT_RUNNER, AGENT_SINK, AGENT_SPAN_EVENTS, AGENT_STORE, AGENT_TOOL_REGISTRY, type Actor, type ActorDirectory, type ActorResolver, type ActorSpendRow, type AgentApprovalPort, type AgentCatalogEntry, type AgentDefinition, type AgentDelegated, type AgentDiagnosticEvent, type AgentDiagnosticKey, type AgentFollowUpsSpan, type AgentGovernanceQueries, type AgentLlmTurnSpan, type AgentLoopDeps, type AgentLoopHooks, type AgentMessageEvent, type AgentPricingStore, type AgentQuotaExceeded, AgentRegistry, type AgentRetrievalSpan, type AgentRetrieved, type AgentRunFailed, type AgentRunFinished, type AgentRunInput, type AgentRunStarted, type AgentRunner, type AgentSpanEvent, type AgentStore, AgentStreamError, type AgentStreamEvent, type AgentToolCallEvent, type AgentToolExecutionSpan, type AgentToolRetry, type AiToolCtx, type AppendMessageInput, type AttachmentStagingStore, type CostUsage, type CreateThreadInput, type CurrentModelPrice, DEFAULT_TOOL_TRANSIENT_RETRY_ATTEMPTS, DEFAULT_TOOL_TRANSIENT_RETRY_BACKOFF_MS, type Decision, DefaultRolesPolicy, type EmbeddingProvider, type GovernancePage, type GovernancePageQuery, type GovernanceRange, type GovernanceUsageInput, type InvokeWithTransientRetryOptions, type LlmStepEnvelope, type MessageAttachment, type MessageRole, type MessageUsage, type ModelMessage, type ModelPrice, type ModelPriceInput, type ModelProvider, type ModelSpendRow, type ModelTurnArgs, type ModelTurnResult, type PageContext, type Passage, type PendingApprovalRow, type PromptBuilder, type PromptContext, type PromptContributor, QuotaExceededError, type QuotaState, type QuotaStore, type QuotaView, type RecentRunRow, type RecordRunEndInput, type RecordRunStartInput, type RecordToolCallInput, type RecordUsageInput, type RerankOptions, type Reranker, type RetrieveOptions, type Retriever, type RolesPolicy, type RunAgentBreakdownRow, type RunErrorBreakdownRow, type RunMetrics, type RunTrendPoint, type RunWhere, type SinkWriter, type StageAttachmentInput, type StoredMessage, type StreamError, type ThreadActivityRow, type ThreadDetail, type ThreadMeta, type ThreadSpendRow, type ThreadSummary, type ThreadWhere, type TokenStreamSink, type ToolCallActivityRow, type ToolCallRequest, type ToolCallStatus, type ToolCallWhere, type ToolDefinition, ToolForbiddenError, type ToolHandler, ToolInputInvalidError, type ToolKind, ToolNotFoundError, ToolRegistry, type ToolResult, type ToolSpec, type ToolStatRow, type ToolStepCtx, type ToolStepEnvelope, type ToolTransientRetryNumbers, type ToolTransientRetryOptions, type ToolTransientRetrySetting, type UpdateThreadInput, type UpdateToolCallInput, type UsagePurpose, type UsageTrendPoint, agentDiagnosticKey, bucketByActor, bucketByModel, bucketByThread, bucketUsageTrend, dayBoundsUtc, encodeStreamEvent, estimateCost, filterToolsByAllowList, filterToolsByRole, invokeWithTransientRetry, isTransientToolError, publishAgentDelegated, publishAgentMessage, publishAgentQuotaExceeded, publishAgentRetrieved, publishAgentRunFailed, publishAgentRunFinished, publishAgentRunStarted, publishAgentToolCall, publishAgentToolRetry, resolveToolTransientRetryNumbers, runAgentLoop, seedModelPrices, traceLlmTurn, traceToolExecution, withToolTimeout };
1838
+ export { AGENT_ACTOR_DIRECTORY, AGENT_ACTOR_RESOLVER, AGENT_APPROVAL_PORT, AGENT_ATTACHMENT_STAGING, AGENT_DEPS_FACTORY, AGENT_DIAGNOSTIC_EVENTS, AGENT_DURABLE_RUNNER, AGENT_EMBEDDING_PROVIDER, AGENT_GOVERNANCE_QUERIES, AGENT_MODEL, AGENT_OPTIONS, AGENT_PRICING_STORE, AGENT_PROMPT_CONTRIBUTORS, AGENT_QUOTA_STORE, AGENT_REGISTRY, AGENT_RETRIEVER, AGENT_ROLES_POLICY, AGENT_RUNNER, AGENT_SINK, AGENT_SPAN_EVENTS, AGENT_STORE, AGENT_TOOL_REGISTRY, type Actor, type ActorDirectory, type ActorResolver, type ActorSpendRow, type AgentApprovalPort, type AgentCatalogEntry, type AgentDefinition, type AgentDelegated, type AgentDiagnosticEvent, type AgentDiagnosticKey, type AgentFollowUpsSpan, type AgentGovernanceQueries, type AgentLlmTurnSpan, type AgentLoopDeps, type AgentLoopHooks, type AgentMessageEvent, type AgentPricingStore, type AgentQuotaExceeded, AgentRegistry, type AgentRetrievalSpan, type AgentRetrieved, type AgentRunFailed, type AgentRunFinished, type AgentRunInput, type AgentRunStarted, type AgentRunner, type AgentSpanEvent, type AgentStore, AgentStreamError, type AgentStreamEvent, type AgentToolCallEvent, type AgentToolExecutionSpan, type AgentToolRetry, type AiToolCtx, type AppendMessageInput, type ApprovalWhere, type AttachmentStagingStore, type CostUsage, type CreateThreadInput, type CurrentModelPrice, DEFAULT_TOOL_TRANSIENT_RETRY_ATTEMPTS, DEFAULT_TOOL_TRANSIENT_RETRY_BACKOFF_MS, type Decision, DefaultRolesPolicy, type DetailThreadRef, type EmbeddingProvider, type GovernancePage, type GovernancePageQuery, type GovernanceRange, type GovernanceRunDetail, type GovernanceThreadDetail, type GovernanceThreadDetailQuery, type GovernanceUsageInput, type InvokeWithTransientRetryOptions, type LlmStepEnvelope, type MessageAttachment, type MessageRole, type MessageUsage, type ModelMessage, type ModelPrice, type ModelPriceInput, type ModelProvider, type ModelSpendRow, type ModelTurnArgs, type ModelTurnResult, type PageContext, type Passage, type PendingApprovalRow, type PromptBuilder, type PromptContext, type PromptContributor, QuotaExceededError, type QuotaState, type QuotaStore, type QuotaView, type RecentRunRow, type RecordRunEndInput, type RecordRunStartInput, type RecordToolCallInput, type RecordUsageInput, type RerankOptions, type Reranker, type RetrieveOptions, type Retriever, type RolesPolicy, type RunAgentBreakdownRow, type RunErrorBreakdownRow, type RunMetrics, type RunToolCallRow, type RunTrendPoint, type RunWhere, type SinkWriter, type StageAttachmentInput, type StoredMessage, type StreamError, THREAD_DETAIL_CONTENT_CHARS, type ThreadActivityRow, type ThreadDetail, type ThreadMessageRow, type ThreadMeta, type ThreadSpendRow, type ThreadSummary, type ThreadUsageRollup, type ThreadWhere, type TokenStreamSink, type ToolCallActivityRow, type ToolCallRequest, type ToolCallStatus, type ToolCallWhere, type ToolDefinition, ToolDisabledError, ToolForbiddenError, type ToolHandler, ToolInputInvalidError, type ToolKind, ToolNotFoundError, ToolRegistry, type ToolResult, type ToolSpec, type ToolStatRow, type ToolStepCtx, type ToolStepEnvelope, type ToolTransientRetryNumbers, type ToolTransientRetryOptions, type ToolTransientRetrySetting, type UpdateThreadInput, type UpdateToolCallInput, type UsagePurpose, type UsageTrendPoint, agentDiagnosticKey, bucketByActor, bucketByModel, bucketByThread, bucketUsageTrend, canActorUseTool, dayBoundsUtc, encodeStreamEvent, estimateCost, filterToolsByAllowList, filterToolsByCanUse, filterToolsByEnabled, filterToolsByRole, invokeWithTransientRetry, isToolEnabled, isTransientToolError, publishAgentDelegated, publishAgentMessage, publishAgentQuotaExceeded, publishAgentRetrieved, publishAgentRunFailed, publishAgentRunFinished, publishAgentRunStarted, publishAgentToolCall, publishAgentToolRetry, resolveToolTransientRetryNumbers, rollupThreadUsage, runAgentLoop, seedModelPrices, traceLlmTurn, traceToolExecution, truncateDetailContent, withToolTimeout };
package/dist/index.d.ts CHANGED
@@ -98,6 +98,16 @@ interface ToolSpec {
98
98
  targetAgent?: string;
99
99
  /** Roles allowed to invoke. Undefined → defaults applied by RolesPolicy (e.g. ADMIN-only). */
100
100
  roles?: string[];
101
+ /**
102
+ * Whether the tool exists in this deployment. `false` (or a predicate returning `false`) drops it
103
+ * before the role filter, so it is never offered to the model and cannot be invoked. Undefined →
104
+ * enabled.
105
+ *
106
+ * A predicate is re-evaluated every turn, so a flag flipped at runtime takes effect on the next
107
+ * message with nothing re-registered. For availability that depends on injected services, put
108
+ * `isEnabled()` on the handler instead — a spec is data, a handler is a provider.
109
+ */
110
+ enabled?: boolean | (() => boolean | Promise<boolean>);
101
111
  /**
102
112
  * An authorization ability name (e.g. 'cache.purge'). Consumed by an ability-aware RolesPolicy
103
113
  * such as the `@dudousxd/nestjs-agent-authz` Gate adapter. Apps that don't use authz ignore it
@@ -465,6 +475,33 @@ interface AiToolCtx {
465
475
  /** A tool implementation. `I` is the parsed (Zod-validated) input. */
466
476
  interface ToolHandler<I = unknown> {
467
477
  execute(input: I, ctx: AiToolCtx): Promise<unknown>;
478
+ /**
479
+ * Whether this tool exists in this deployment at all — evaluated per turn, BEFORE the roles
480
+ * policy, so a `false` here means the model is never shown the tool rather than being shown one
481
+ * it will be refused. Omit → always enabled.
482
+ *
483
+ * This is the seam for a feature flag or a licensing tier: the handler is an ordinary provider,
484
+ * so it can read injected config (`this.config.featureX`) that a decorator, evaluated at import
485
+ * time, cannot. Answering "does this capability exist here?"; `roles`/`RolesPolicy` answers the
486
+ * separate question "may THIS actor use it?", and both still run.
487
+ *
488
+ * Prefer this over conditionally registering the provider: registration happens while the
489
+ * `@Module` metadata is built, which in most apps is before configuration is loaded.
490
+ */
491
+ isEnabled?(): boolean | Promise<boolean>;
492
+ /**
493
+ * Whether THIS actor may use the tool, decided per turn. Omit → the role gate alone decides.
494
+ *
495
+ * The three existing gates all answer the question somewhere else: `roles` is static data,
496
+ * `RolesPolicy` is one app-wide rule for every tool, and an agent's `tools` allow-list is fixed
497
+ * when the agent is declared. This one lives on the tool and runs with DI, so it can ask the
498
+ * questions only the tool knows to ask — is this user's org on the plan that includes it, does
499
+ * this actor own the base being queried, is the per-user override in the DB set today.
500
+ *
501
+ * Runs AFTER {@link isEnabled} and the `RolesPolicy`, and all of them must pass. Applied both
502
+ * when the turn's tool list is built (a denied actor is never shown it) and again on invoke.
503
+ */
504
+ canUse?(actor: Actor): boolean | Promise<boolean>;
468
505
  }
469
506
 
470
507
  /**
@@ -1044,6 +1081,13 @@ interface ToolStatRow {
1044
1081
  calls: number;
1045
1082
  failed: number;
1046
1083
  rejected: number;
1084
+ /**
1085
+ * p50 (median) of executionMs across calls that recorded one; null when none carry it. Reported
1086
+ * alongside p95 rather than a mean: tool latency is long-tailed (a retry or a slow upstream drags
1087
+ * an average somewhere no single call ever was), so the pair "typical / tail" is what an operator
1088
+ * can actually act on.
1089
+ */
1090
+ p50ExecutionMs: number | null;
1047
1091
  /** p95 of executionMs across executed calls; null when none carry it. */
1048
1092
  p95ExecutionMs: number | null;
1049
1093
  }
@@ -1095,6 +1139,115 @@ interface RunWhere {
1095
1139
  fromDay?: string;
1096
1140
  toDay?: string;
1097
1141
  }
1142
+ /** Filters for {@link AgentGovernanceQueries.approvalsPage}. */
1143
+ interface ApprovalWhere {
1144
+ toolName?: string;
1145
+ threadId?: string;
1146
+ /** The requesting thread's owner. */
1147
+ actorRef?: string;
1148
+ agentName?: string;
1149
+ /** Inclusive UTC day bounds on when the approval was requested, `YYYY-MM-DD`. */
1150
+ fromDay?: string;
1151
+ toDay?: string;
1152
+ }
1153
+ /** One tool call inside a {@link GovernanceRunDetail}, with the execution outcome a list row can't afford to carry. */
1154
+ interface RunToolCallRow {
1155
+ toolCallId: string;
1156
+ toolName: string;
1157
+ toolType: string;
1158
+ status: string;
1159
+ /** Wall time of the execution; null for a call that never executed (rejected/still pending). */
1160
+ executionMs: number | null;
1161
+ /** Who executed/decided it, when the store recorded an attribution. */
1162
+ executedByRef: string | null;
1163
+ /** The failure text for a `failed` call; null otherwise. */
1164
+ error: string | null;
1165
+ /** ISO timestamp. */
1166
+ createdAt: string;
1167
+ }
1168
+ /** The owning thread's headline, carried on a drill-down so it can be named without a second read. */
1169
+ interface DetailThreadRef {
1170
+ threadId: string;
1171
+ title: string;
1172
+ actorRef: string;
1173
+ /** True when the thread is soft-deleted — its history is still readable, the thread is not. */
1174
+ deleted: boolean;
1175
+ }
1176
+ /**
1177
+ * Everything a run drill-down renders: the run row itself, its owning thread's headline, and the
1178
+ * tool calls attributed to it.
1179
+ *
1180
+ * `toolCalls` is empty for a run recorded before tool calls carried a `runId` (the column is
1181
+ * nullable and pre-rollout rows have none) — indistinguishable, from here, from a run that called
1182
+ * no tools. There is deliberately no cost figure: the token ledger has no run column, so per-run
1183
+ * spend is not attributable without a store migration.
1184
+ */
1185
+ interface GovernanceRunDetail {
1186
+ run: RecentRunRow;
1187
+ thread: DetailThreadRef;
1188
+ /** The run's tool calls, oldest first — the order they were requested in. */
1189
+ toolCalls: RunToolCallRow[];
1190
+ }
1191
+ /** One message inside a {@link GovernanceThreadDetail}. `content` is capped server-side. */
1192
+ interface ThreadMessageRow {
1193
+ messageId: string;
1194
+ role: string;
1195
+ /** Message text, cut to {@link THREAD_DETAIL_CONTENT_CHARS}; see `truncated`. */
1196
+ content: string;
1197
+ /** True when `content` was cut — the console shows an explicit "…" rather than implying the tail. */
1198
+ truncated: boolean;
1199
+ agentName: string | null;
1200
+ /** How many tool calls this message requested. */
1201
+ toolCallCount: number;
1202
+ /** ISO timestamp. */
1203
+ createdAt: string;
1204
+ }
1205
+ /** Token/cost rollup across a thread's whole ledger (not range-scoped — a thread's lifetime). */
1206
+ interface ThreadUsageRollup {
1207
+ /** Ledger rows, i.e. billed turns. */
1208
+ requests: number;
1209
+ inputTokens: number;
1210
+ outputTokens: number;
1211
+ totalTokens: number;
1212
+ costUsd: number;
1213
+ }
1214
+ /** Everything a thread drill-down renders, in one call. */
1215
+ interface GovernanceThreadDetail {
1216
+ /** The thread's own activity row (`messageCount` is the thread total, not the page below). */
1217
+ thread: ThreadActivityRow;
1218
+ /** True when the thread is soft-deleted. */
1219
+ deleted: boolean;
1220
+ usage: ThreadUsageRollup;
1221
+ /** The thread's runs, newest first, capped at the query's `runLimit`. */
1222
+ runs: RecentRunRow[];
1223
+ /** Runs on this thread in total — `runs.length < runTotal` means the cap bit. */
1224
+ runTotal: number;
1225
+ /** The thread's messages, newest first, capped at the query's `messageLimit`. */
1226
+ messages: ThreadMessageRow[];
1227
+ }
1228
+ /** Row caps for {@link AgentGovernanceQueries.threadDetail}, already clamped by the caller. */
1229
+ interface GovernanceThreadDetailQuery {
1230
+ threadId: string;
1231
+ /** Max messages returned, newest first. */
1232
+ messageLimit: number;
1233
+ /** Max runs returned, newest first. */
1234
+ runLimit: number;
1235
+ }
1236
+ /**
1237
+ * Per-message content cap for {@link ThreadMessageRow.content}. A drill-down is a triage view, not a
1238
+ * transcript reader: capping here keeps one response bounded regardless of how long an assistant
1239
+ * turn ran. Shared by every adapter so the cut is identical wherever the console is served from.
1240
+ */
1241
+ declare const THREAD_DETAIL_CONTENT_CHARS = 2000;
1242
+ /**
1243
+ * Cut a message body to {@link THREAD_DETAIL_CONTENT_CHARS}, reporting whether it was cut. Lives
1244
+ * next to the cap so every adapter truncates at the same boundary — a console comparing two stores
1245
+ * must not see two different "…".
1246
+ */
1247
+ declare function truncateDetailContent(content: string): {
1248
+ content: string;
1249
+ truncated: boolean;
1250
+ };
1098
1251
  /**
1099
1252
  * The governance read-model. Cost is `inputTokens/1e6 * inputPricePer1m + outputTokens/1e6 *
1100
1253
  * outputPricePer1m` against the current pricing row per model; an unpriced model contributes 0 cost
@@ -1113,8 +1266,19 @@ interface AgentGovernanceQueries {
1113
1266
  runErrors(range: GovernanceRange): Promise<RunErrorBreakdownRow[]>;
1114
1267
  runTrend(range: GovernanceRange): Promise<RunTrendPoint[]>;
1115
1268
  recentRuns(limit: number): Promise<RecentRunRow[]>;
1116
- /** Tool calls sitting `pending_approval`, oldest first — an inbox drains from the back. Capped at `limit`. */
1269
+ /**
1270
+ * Tool calls sitting `pending_approval`, oldest first — an inbox drains from the back. Capped at
1271
+ * `limit`, with NO total: a caller that needs to know whether the cap hid anything wants
1272
+ * {@link approvalsPage} instead.
1273
+ */
1117
1274
  pendingApprovals(limit: number): Promise<PendingApprovalRow[]>;
1275
+ /**
1276
+ * Paged, filterable approvals inbox, oldest first (same ordering as `pendingApprovals`). Unlike
1277
+ * that method this reports `total`, so a console can page a backlog and say how much of it is
1278
+ * off-screen — the one failure this surface cannot afford is a pending approval nobody sees.
1279
+ * An adapter without the backing data returns an empty page (`total: 0`) rather than throwing.
1280
+ */
1281
+ approvalsPage(query: GovernancePageQuery<ApprovalWhere>): Promise<GovernancePage<PendingApprovalRow>>;
1118
1282
  /** Per-tool call/failure/rejection/latency rollup over the range, highest call count first. */
1119
1283
  toolStats(range: GovernanceRange): Promise<ToolStatRow[]>;
1120
1284
  /**
@@ -1132,6 +1296,21 @@ interface AgentGovernanceQueries {
1132
1296
  * by a store without run recording (no `recordRunStart`) returns an empty page (`total: 0`).
1133
1297
  */
1134
1298
  runsPage(query: GovernancePageQuery<RunWhere>): Promise<GovernancePage<RecentRunRow>>;
1299
+ /**
1300
+ * One run with its owning thread and its tool calls — the drill-down behind a row in the runs
1301
+ * table. `null` when no run has that id. ONE call, not one per tool call: a failed run is the
1302
+ * thing an operator opens first and it should not cost a query per step.
1303
+ *
1304
+ * An adapter backed by a store without run recording returns `null` for every id.
1305
+ */
1306
+ runDetail(runId: string): Promise<GovernanceRunDetail | null>;
1307
+ /**
1308
+ * One thread with its lifetime usage rollup, its recent runs and its recent messages — the
1309
+ * drill-down behind a row in the threads table. `null` when no thread has that id; a soft-deleted
1310
+ * thread IS returned (with `deleted: true`), because "what did the thread we just deleted do" is
1311
+ * exactly the question an audit asks.
1312
+ */
1313
+ threadDetail(query: GovernanceThreadDetailQuery): Promise<GovernanceThreadDetail | null>;
1135
1314
  }
1136
1315
 
1137
1316
  /**
@@ -1248,6 +1427,12 @@ declare function bucketByThread(rows: GovernanceUsageInput[], prices: ReadonlyMa
1248
1427
  limit: number;
1249
1428
  includeUnknownThreads: boolean;
1250
1429
  }): ThreadSpendRow[];
1430
+ /**
1431
+ * Sum an already-scoped set of usage rows into one rollup — the thread drill-down's headline. Same
1432
+ * `rowCost` as every bucketer above (provider-reported cost wins, else the cache-aware estimate), so
1433
+ * a thread's detail cost and its row in the by-thread ranking can never disagree.
1434
+ */
1435
+ declare function rollupThreadUsage(rows: GovernanceUsageInput[], prices: ReadonlyMap<string, ModelPrice>): ThreadUsageRollup;
1251
1436
  /** Aggregate usage rows into a daily token/cost trend, ascending by day. */
1252
1437
  declare function bucketUsageTrend(rows: GovernanceUsageInput[], prices: ReadonlyMap<string, ModelPrice>): UsageTrendPoint[];
1253
1438
  /** Turn an inclusive `YYYY-MM-DD` day range into the UTC datetime bounds used to filter usage rows. */
@@ -1256,6 +1441,36 @@ declare function dayBoundsUtc(range: GovernanceRange): {
1256
1441
  end: Date;
1257
1442
  };
1258
1443
 
1444
+ /**
1445
+ * Is this tool part of this deployment right now? `ToolSpec.enabled` and the handler's
1446
+ * `isEnabled()` are ANDed — either one saying no is enough — and both default to yes.
1447
+ *
1448
+ * Resolved per turn rather than at registration, so the answer can come from configuration that
1449
+ * did not exist when the module was built.
1450
+ */
1451
+ declare function isToolEnabled(spec: ToolSpec, handler?: ToolHandler): Promise<boolean>;
1452
+ /**
1453
+ * Zeroth filter layer: drop tools this deployment has turned off, before anyone asks who may call
1454
+ * them. A disabled tool is absent, not forbidden — the difference matters, because "forbidden"
1455
+ * tells the model (and the user reading a refusal) that the capability exists.
1456
+ */
1457
+ declare function filterToolsByEnabled<T extends {
1458
+ spec: ToolSpec;
1459
+ handler?: ToolHandler;
1460
+ }>(entries: T[]): Promise<T[]>;
1461
+ /**
1462
+ * May this actor use this tool, per the tool's OWN gate? Tools without a `canUse` say yes and are
1463
+ * governed by the `RolesPolicy` alone.
1464
+ */
1465
+ declare function canActorUseTool(actor: Actor, handler?: ToolHandler): Promise<boolean>;
1466
+ /**
1467
+ * Third filter layer: drop tools whose own `canUse` refuses this actor. Runs after the app-wide
1468
+ * `RolesPolicy`, and is additive to it — a tool can narrow who reaches it, never widen.
1469
+ */
1470
+ declare function filterToolsByCanUse<T extends {
1471
+ spec: ToolSpec;
1472
+ handler?: ToolHandler;
1473
+ }>(entries: T[], actor: Actor): Promise<T[]>;
1259
1474
  /** First filter layer: drop tools the actor's role may not invoke. `can` may be async (authz). */
1260
1475
  declare function filterToolsByRole(tools: ToolSpec[], actor: Actor, policy: RolesPolicy): Promise<ToolSpec[]>;
1261
1476
  /** Second filter layer: if the agent pins an allow-list, keep only those tool names. */
@@ -1275,6 +1490,19 @@ declare class ToolForbiddenError extends Error {
1275
1490
  readonly toolName: string;
1276
1491
  constructor(toolName: string);
1277
1492
  }
1493
+ /**
1494
+ * Thrown when a registered tool is invoked while this deployment has it turned off (`enabled` /
1495
+ * `isEnabled()`). Distinct from {@link ToolForbiddenError}, which is about the actor, and from
1496
+ * {@link ToolNotFoundError}, which is about a name nobody registered — an operator reading a log
1497
+ * needs to tell "you flipped the flag" apart from "that tool does not exist in this build".
1498
+ *
1499
+ * Reachable in normal operation, not just from a forged call: a HITL `action` approved before the
1500
+ * flag was turned off runs its tool afterwards.
1501
+ */
1502
+ declare class ToolDisabledError extends Error {
1503
+ readonly toolName: string;
1504
+ constructor(toolName: string);
1505
+ }
1278
1506
  /** Thrown when a tool is invoked that was never registered. */
1279
1507
  declare class ToolNotFoundError extends Error {
1280
1508
  readonly toolName: string;
@@ -1299,9 +1527,19 @@ declare class ToolRegistry {
1299
1527
  has(name: string): boolean;
1300
1528
  spec(name: string): ToolSpec | undefined;
1301
1529
  allSpecs(): ToolSpec[];
1302
- /** The tools to offer the model for this actor+agent, after the two filter layers. */
1530
+ /**
1531
+ * The tools to offer the model for this actor+agent, after the four filter layers: what this
1532
+ * deployment has enabled, what this actor's role allows, what each tool's own `canUse` allows
1533
+ * this actor, and finally what this agent pinned.
1534
+ *
1535
+ * Every layer only ever removes tools, so no arrangement of them can widen what a turn reaches.
1536
+ */
1303
1537
  definitionsFor(actor: Actor, policy: RolesPolicy, allowedTools?: string[]): Promise<ToolDefinition[]>;
1304
- /** Run a tool. Re-checks the role (defense-in-depth) and re-parses the input via Zod. */
1538
+ /**
1539
+ * Run a tool. Re-checks that the tool is enabled and that the role allows it (defense-in-depth —
1540
+ * a call can reach here from a replayed durable step or an approval granted before the flag
1541
+ * moved, neither of which went through `definitionsFor` again) and re-parses the input via Zod.
1542
+ */
1305
1543
  invoke(name: string, input: unknown, ctx: AiToolCtx, policy: RolesPolicy): Promise<unknown>;
1306
1544
  }
1307
1545
  /** Default gate: one of the actor's roles must be in spec.roles (defaulting to ADMIN-only). */
@@ -1597,4 +1835,4 @@ type AgentDiagnosticKey = `agent:${AgentDiagnosticEvent}`;
1597
1835
  */
1598
1836
  declare function agentDiagnosticKey(event: AgentDiagnosticEvent): AgentDiagnosticKey;
1599
1837
 
1600
- export { AGENT_ACTOR_DIRECTORY, AGENT_ACTOR_RESOLVER, AGENT_APPROVAL_PORT, AGENT_ATTACHMENT_STAGING, AGENT_DEPS_FACTORY, AGENT_DIAGNOSTIC_EVENTS, AGENT_DURABLE_RUNNER, AGENT_EMBEDDING_PROVIDER, AGENT_GOVERNANCE_QUERIES, AGENT_MODEL, AGENT_OPTIONS, AGENT_PRICING_STORE, AGENT_PROMPT_CONTRIBUTORS, AGENT_QUOTA_STORE, AGENT_REGISTRY, AGENT_RETRIEVER, AGENT_ROLES_POLICY, AGENT_RUNNER, AGENT_SINK, AGENT_SPAN_EVENTS, AGENT_STORE, AGENT_TOOL_REGISTRY, type Actor, type ActorDirectory, type ActorResolver, type ActorSpendRow, type AgentApprovalPort, type AgentCatalogEntry, type AgentDefinition, type AgentDelegated, type AgentDiagnosticEvent, type AgentDiagnosticKey, type AgentFollowUpsSpan, type AgentGovernanceQueries, type AgentLlmTurnSpan, type AgentLoopDeps, type AgentLoopHooks, type AgentMessageEvent, type AgentPricingStore, type AgentQuotaExceeded, AgentRegistry, type AgentRetrievalSpan, type AgentRetrieved, type AgentRunFailed, type AgentRunFinished, type AgentRunInput, type AgentRunStarted, type AgentRunner, type AgentSpanEvent, type AgentStore, AgentStreamError, type AgentStreamEvent, type AgentToolCallEvent, type AgentToolExecutionSpan, type AgentToolRetry, type AiToolCtx, type AppendMessageInput, type AttachmentStagingStore, type CostUsage, type CreateThreadInput, type CurrentModelPrice, DEFAULT_TOOL_TRANSIENT_RETRY_ATTEMPTS, DEFAULT_TOOL_TRANSIENT_RETRY_BACKOFF_MS, type Decision, DefaultRolesPolicy, type EmbeddingProvider, type GovernancePage, type GovernancePageQuery, type GovernanceRange, type GovernanceUsageInput, type InvokeWithTransientRetryOptions, type LlmStepEnvelope, type MessageAttachment, type MessageRole, type MessageUsage, type ModelMessage, type ModelPrice, type ModelPriceInput, type ModelProvider, type ModelSpendRow, type ModelTurnArgs, type ModelTurnResult, type PageContext, type Passage, type PendingApprovalRow, type PromptBuilder, type PromptContext, type PromptContributor, QuotaExceededError, type QuotaState, type QuotaStore, type QuotaView, type RecentRunRow, type RecordRunEndInput, type RecordRunStartInput, type RecordToolCallInput, type RecordUsageInput, type RerankOptions, type Reranker, type RetrieveOptions, type Retriever, type RolesPolicy, type RunAgentBreakdownRow, type RunErrorBreakdownRow, type RunMetrics, type RunTrendPoint, type RunWhere, type SinkWriter, type StageAttachmentInput, type StoredMessage, type StreamError, type ThreadActivityRow, type ThreadDetail, type ThreadMeta, type ThreadSpendRow, type ThreadSummary, type ThreadWhere, type TokenStreamSink, type ToolCallActivityRow, type ToolCallRequest, type ToolCallStatus, type ToolCallWhere, type ToolDefinition, ToolForbiddenError, type ToolHandler, ToolInputInvalidError, type ToolKind, ToolNotFoundError, ToolRegistry, type ToolResult, type ToolSpec, type ToolStatRow, type ToolStepCtx, type ToolStepEnvelope, type ToolTransientRetryNumbers, type ToolTransientRetryOptions, type ToolTransientRetrySetting, type UpdateThreadInput, type UpdateToolCallInput, type UsagePurpose, type UsageTrendPoint, agentDiagnosticKey, bucketByActor, bucketByModel, bucketByThread, bucketUsageTrend, dayBoundsUtc, encodeStreamEvent, estimateCost, filterToolsByAllowList, filterToolsByRole, invokeWithTransientRetry, isTransientToolError, publishAgentDelegated, publishAgentMessage, publishAgentQuotaExceeded, publishAgentRetrieved, publishAgentRunFailed, publishAgentRunFinished, publishAgentRunStarted, publishAgentToolCall, publishAgentToolRetry, resolveToolTransientRetryNumbers, runAgentLoop, seedModelPrices, traceLlmTurn, traceToolExecution, withToolTimeout };
1838
+ export { AGENT_ACTOR_DIRECTORY, AGENT_ACTOR_RESOLVER, AGENT_APPROVAL_PORT, AGENT_ATTACHMENT_STAGING, AGENT_DEPS_FACTORY, AGENT_DIAGNOSTIC_EVENTS, AGENT_DURABLE_RUNNER, AGENT_EMBEDDING_PROVIDER, AGENT_GOVERNANCE_QUERIES, AGENT_MODEL, AGENT_OPTIONS, AGENT_PRICING_STORE, AGENT_PROMPT_CONTRIBUTORS, AGENT_QUOTA_STORE, AGENT_REGISTRY, AGENT_RETRIEVER, AGENT_ROLES_POLICY, AGENT_RUNNER, AGENT_SINK, AGENT_SPAN_EVENTS, AGENT_STORE, AGENT_TOOL_REGISTRY, type Actor, type ActorDirectory, type ActorResolver, type ActorSpendRow, type AgentApprovalPort, type AgentCatalogEntry, type AgentDefinition, type AgentDelegated, type AgentDiagnosticEvent, type AgentDiagnosticKey, type AgentFollowUpsSpan, type AgentGovernanceQueries, type AgentLlmTurnSpan, type AgentLoopDeps, type AgentLoopHooks, type AgentMessageEvent, type AgentPricingStore, type AgentQuotaExceeded, AgentRegistry, type AgentRetrievalSpan, type AgentRetrieved, type AgentRunFailed, type AgentRunFinished, type AgentRunInput, type AgentRunStarted, type AgentRunner, type AgentSpanEvent, type AgentStore, AgentStreamError, type AgentStreamEvent, type AgentToolCallEvent, type AgentToolExecutionSpan, type AgentToolRetry, type AiToolCtx, type AppendMessageInput, type ApprovalWhere, type AttachmentStagingStore, type CostUsage, type CreateThreadInput, type CurrentModelPrice, DEFAULT_TOOL_TRANSIENT_RETRY_ATTEMPTS, DEFAULT_TOOL_TRANSIENT_RETRY_BACKOFF_MS, type Decision, DefaultRolesPolicy, type DetailThreadRef, type EmbeddingProvider, type GovernancePage, type GovernancePageQuery, type GovernanceRange, type GovernanceRunDetail, type GovernanceThreadDetail, type GovernanceThreadDetailQuery, type GovernanceUsageInput, type InvokeWithTransientRetryOptions, type LlmStepEnvelope, type MessageAttachment, type MessageRole, type MessageUsage, type ModelMessage, type ModelPrice, type ModelPriceInput, type ModelProvider, type ModelSpendRow, type ModelTurnArgs, type ModelTurnResult, type PageContext, type Passage, type PendingApprovalRow, type PromptBuilder, type PromptContext, type PromptContributor, QuotaExceededError, type QuotaState, type QuotaStore, type QuotaView, type RecentRunRow, type RecordRunEndInput, type RecordRunStartInput, type RecordToolCallInput, type RecordUsageInput, type RerankOptions, type Reranker, type RetrieveOptions, type Retriever, type RolesPolicy, type RunAgentBreakdownRow, type RunErrorBreakdownRow, type RunMetrics, type RunToolCallRow, type RunTrendPoint, type RunWhere, type SinkWriter, type StageAttachmentInput, type StoredMessage, type StreamError, THREAD_DETAIL_CONTENT_CHARS, type ThreadActivityRow, type ThreadDetail, type ThreadMessageRow, type ThreadMeta, type ThreadSpendRow, type ThreadSummary, type ThreadUsageRollup, type ThreadWhere, type TokenStreamSink, type ToolCallActivityRow, type ToolCallRequest, type ToolCallStatus, type ToolCallWhere, type ToolDefinition, ToolDisabledError, ToolForbiddenError, type ToolHandler, ToolInputInvalidError, type ToolKind, ToolNotFoundError, ToolRegistry, type ToolResult, type ToolSpec, type ToolStatRow, type ToolStepCtx, type ToolStepEnvelope, type ToolTransientRetryNumbers, type ToolTransientRetryOptions, type ToolTransientRetrySetting, type UpdateThreadInput, type UpdateToolCallInput, type UsagePurpose, type UsageTrendPoint, agentDiagnosticKey, bucketByActor, bucketByModel, bucketByThread, bucketUsageTrend, canActorUseTool, dayBoundsUtc, encodeStreamEvent, estimateCost, filterToolsByAllowList, filterToolsByCanUse, filterToolsByEnabled, filterToolsByRole, invokeWithTransientRetry, isToolEnabled, isTransientToolError, publishAgentDelegated, publishAgentMessage, publishAgentQuotaExceeded, publishAgentRetrieved, publishAgentRunFailed, publishAgentRunFinished, publishAgentRunStarted, publishAgentToolCall, publishAgentToolRetry, resolveToolTransientRetryNumbers, rollupThreadUsage, runAgentLoop, seedModelPrices, traceLlmTurn, traceToolExecution, truncateDetailContent, withToolTimeout };