@dudousxd/nestjs-agent-telescope 0.3.4 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/agent-telescope.extension.ts","../src/agent-dashboard.ts","../src/agent-data-providers.ts","../src/agent-governance-providers.ts","../src/agent-telescope.watcher.ts"],"sourcesContent":["export { agentTelescopeExtension } from './agent-telescope.extension.js';\nexport { AgentTelescopeWatcher } from './agent-telescope.watcher.js';\nexport { agentDashboard } from './agent-dashboard.js';\nexport {\n agentRunsProvider,\n agentTokensProvider,\n agentToolsProvider,\n agentToolStatusProvider,\n} from './agent-data-providers.js';\nexport {\n agentActorSpendTableProvider,\n agentModelSpendTableProvider,\n agentSpendByActorProvider,\n agentSpendByModelProvider,\n agentSpendTotalProvider,\n agentTokensTotalProvider,\n agentUsageTrendProvider,\n resolveRange,\n shiftUtcDay,\n toActorSpendRows,\n toActorSpendSegments,\n toModelSpendRows,\n toModelSpendSegments,\n totalCostUsd,\n totalTokens,\n toUsageTrendRows,\n} from './agent-governance-providers.js';\n","import { defineTelescopeExtension } from '@dudousxd/nestjs-telescope';\nimport { agentDashboard } from './agent-dashboard.js';\nimport {\n agentRunsProvider,\n agentTokensProvider,\n agentToolStatusProvider,\n agentToolsProvider,\n} from './agent-data-providers.js';\nimport {\n agentActorSpendTableProvider,\n agentModelSpendTableProvider,\n agentSpendByActorProvider,\n agentSpendByModelProvider,\n agentSpendTotalProvider,\n agentTokensTotalProvider,\n agentTopThreadsTableProvider,\n agentUsageTrendProvider,\n} from './agent-governance-providers.js';\nimport { AgentTelescopeWatcher } from './agent-telescope.watcher.js';\n\n/**\n * The first-class Telescope extension for nestjs-agent: an \"Agent\" tab fed by two sources —\n * the `aviary:agent:*` diagnostics channel (live runs, tool calls) via the watcher, and the\n * authoritative `AGENT_GOVERNANCE_QUERIES` read-model (historical spend/usage) via the governance\n * providers. The extension `name`, entry-type id, dashboard id, and every provider name share the\n * `agent` prefix so the registry's global-uniqueness namespaces never collide with sibling extensions.\n *\n * Host wiring: the governance (Spend/Models/Actors) panels resolve `AGENT_GOVERNANCE_QUERIES` from\n * the host DI container at request time (via `ctx.moduleRef`). The host must bind that token — from\n * its store adapter (e.g. `store-mikro-orm` / `store-drizzle` / `testing`) — in the same module that\n * registers `TelescopeModule.forRoot({ extensions: [agentTelescopeExtension()] })`. If the binding is\n * absent, those panels render an empty state; the live watcher-fed panels keep working regardless.\n */\nexport function agentTelescopeExtension() {\n return defineTelescopeExtension({\n name: 'agent',\n watchers: () => [new AgentTelescopeWatcher()],\n entryTypes: () => [{ id: 'agent', label: 'Agent', dot: 'bg-violet-400' }],\n dashboards: () => [agentDashboard()],\n dataProviders: () => [\n agentRunsProvider(),\n agentTokensProvider(),\n agentToolsProvider(),\n agentToolStatusProvider(),\n agentSpendTotalProvider(),\n agentTokensTotalProvider(),\n agentSpendByModelProvider(),\n agentModelSpendTableProvider(),\n agentUsageTrendProvider(),\n agentActorSpendTableProvider(),\n agentSpendByActorProvider(),\n agentTopThreadsTableProvider(),\n ],\n });\n}\n","import type { DashboardSpec } from '@dudousxd/nestjs-telescope';\n\n/** The \"Agent\" overview dashboard. Panels bind to the `agent.*` data providers. */\nexport function agentDashboard(): DashboardSpec {\n return {\n id: 'agent.overview',\n label: 'Agent',\n panels: [],\n sections: [\n {\n title: 'Overview',\n cols: 2,\n panels: [\n { kind: 'stat', title: 'Runs', data: { provider: 'agent.runs' } },\n { kind: 'stat', title: 'Tokens', data: { provider: 'agent.tokens' } },\n ],\n },\n {\n title: 'Spend',\n cols: 2,\n panels: [\n {\n kind: 'stat',\n title: 'Total spend (USD)',\n data: { provider: 'agent.spend.totalCost' },\n format: 'number',\n },\n {\n kind: 'stat',\n title: 'Total tokens',\n data: { provider: 'agent.spend.totalTokens' },\n format: 'number',\n },\n {\n kind: 'breakdown',\n title: 'Spend by model',\n data: { provider: 'agent.spend.byModel' },\n style: 'donut',\n },\n {\n kind: 'timeseries',\n title: 'Daily spend & tokens',\n data: { provider: 'agent.usage.trend' },\n series: ['costUsd', 'totalTokens'],\n style: 'area',\n },\n ],\n },\n {\n title: 'Models',\n panels: [\n {\n kind: 'table',\n title: 'Usage & cost by model',\n data: { provider: 'agent.spend.byModelTable' },\n columns: [\n { key: 'modelId', label: 'Model' },\n { key: 'requests', label: 'Requests' },\n { key: 'inputTokens', label: 'Input tokens' },\n { key: 'outputTokens', label: 'Output tokens' },\n { key: 'costUsd', label: 'Cost (USD)' },\n ],\n },\n ],\n },\n {\n title: 'Actors',\n cols: 2,\n panels: [\n {\n kind: 'breakdown',\n title: 'Spend share by actor',\n data: { provider: 'agent.spend.byActorShare' },\n style: 'bar',\n },\n {\n kind: 'table',\n title: 'Spend by actor',\n data: { provider: 'agent.spend.byActor' },\n columns: [\n { key: 'actorRef', label: 'Actor' },\n { key: 'requests', label: 'Requests' },\n { key: 'totalTokens', label: 'Tokens' },\n { key: 'costUsd', label: 'Cost (USD)' },\n ],\n },\n ],\n },\n {\n title: 'Threads',\n panels: [\n {\n kind: 'table',\n title: 'Top threads by cost',\n data: { provider: 'agent.threads.topSpend' },\n columns: [\n { key: 'title', label: 'Thread' },\n { key: 'actorRef', label: 'Actor' },\n { key: 'requests', label: 'Requests' },\n { key: 'totalTokens', label: 'Tokens' },\n { key: 'costUsd', label: 'Cost (USD)' },\n ],\n },\n ],\n },\n {\n title: 'Tools',\n cols: 2,\n panels: [\n {\n kind: 'breakdown',\n title: 'Tool-call status',\n data: { provider: 'agent.toolStatus' },\n style: 'donut',\n },\n {\n kind: 'table',\n title: 'Recent tool calls',\n data: { provider: 'agent.tools' },\n columns: [\n { key: 'toolName', label: 'Tool' },\n { key: 'toolType', label: 'Type' },\n { key: 'status', label: 'Status' },\n { key: 'runId', label: 'Run' },\n ],\n },\n ],\n },\n ],\n };\n}\n","import type { DataProvider, ExtensionContext } from '@dudousxd/nestjs-telescope';\nimport { TELESCOPE_STORAGE } from '@dudousxd/nestjs-telescope';\n\ninterface AgentEntryContent {\n event: string;\n runId?: string;\n threadId?: string;\n toolName?: string;\n toolType?: string;\n status?: string;\n steps?: number;\n inputTokens?: number;\n outputTokens?: number;\n}\n\ninterface StorageEntry {\n content?: AgentEntryContent;\n createdAt?: Date;\n}\n\nasync function fetchEntries(ctx: ExtensionContext): Promise<StorageEntry[]> {\n const storage = ctx.moduleRef.get(TELESCOPE_STORAGE, { strict: false }) as {\n get(query: { type?: string; limit?: number }): Promise<{ data: StorageEntry[] }>;\n };\n const page = await storage.get({ type: 'agent', limit: 5_000 });\n return page.data;\n}\n\nfunction ofEvent(entries: StorageEntry[], event: string): StorageEntry[] {\n return entries.filter((entry) => entry.content?.event === event);\n}\n\n/** stat → total agent runs (run.finished entries). */\nexport function agentRunsProvider(): DataProvider {\n return {\n name: 'agent.runs',\n async resolve(_query, ctx) {\n const finished = ofEvent(await fetchEntries(ctx), 'run.finished');\n return { value: finished.length };\n },\n };\n}\n\n/** stat → total tokens across all finished runs. */\nexport function agentTokensProvider(): DataProvider {\n return {\n name: 'agent.tokens',\n async resolve(_query, ctx) {\n const finished = ofEvent(await fetchEntries(ctx), 'run.finished');\n const value = finished.reduce(\n (sum, entry) =>\n sum + (entry.content?.inputTokens ?? 0) + (entry.content?.outputTokens ?? 0),\n 0,\n );\n return { value };\n },\n };\n}\n\n/** table → recent tool calls. */\nexport function agentToolsProvider(): DataProvider {\n return {\n name: 'agent.tools',\n async resolve(_query, ctx) {\n const calls = ofEvent(await fetchEntries(ctx), 'tool-call')\n .slice(-50)\n .reverse()\n .map((entry) => ({\n toolName: entry.content?.toolName ?? '',\n toolType: entry.content?.toolType ?? '',\n status: entry.content?.status ?? '',\n runId: entry.content?.runId ?? '',\n }));\n return { rows: calls };\n },\n };\n}\n\n/** breakdown → tool-call status distribution. */\nexport function agentToolStatusProvider(): DataProvider {\n return {\n name: 'agent.toolStatus',\n async resolve(_query, ctx) {\n const calls = ofEvent(await fetchEntries(ctx), 'tool-call');\n const counts = new Map<string, number>();\n for (const call of calls) {\n const status = call.content?.status ?? 'unknown';\n counts.set(status, (counts.get(status) ?? 0) + 1);\n }\n return { segments: [...counts.entries()].map(([label, value]) => ({ label, value })) };\n },\n };\n}\n","import type {\n ActorSpendRow,\n AgentGovernanceQueries,\n GovernanceRange,\n ModelSpendRow,\n ThreadSpendRow,\n UsageTrendPoint,\n} from '@dudousxd/nestjs-agent-core';\nimport { AGENT_GOVERNANCE_QUERIES } from '@dudousxd/nestjs-agent-core';\nimport type { DataProvider, ExtensionContext } from '@dudousxd/nestjs-telescope';\n\n/**\n * Governance data providers for the \"Agent\" Telescope tab. Unlike the live watcher-fed providers\n * in `agent-data-providers.ts` (which read the ephemeral Telescope event storage), these read the\n * authoritative, restart-surviving read-model: `AGENT_GOVERNANCE_QUERIES` (usage ⋈ pricing).\n *\n * The read-model is resolved from the host's DI container via `ctx.moduleRef` — the exact same\n * mechanism the existing providers use for `TELESCOPE_STORAGE`. The host must bind\n * `AGENT_GOVERNANCE_QUERIES` (from its store adapter) in the same module that registers Telescope;\n * when the binding is absent every provider degrades to an empty-but-valid shape rather than throwing.\n */\n\n/** Default trailing window (in days, inclusive) when a panel query omits an explicit range. */\nconst DEFAULT_TREND_WINDOW_DAYS = 30;\n\nconst ISO_DAY_PATTERN = /^\\d{4}-\\d{2}-\\d{2}$/;\n\n/** A breakdown-panel segment (Telescope core: `{ segments: Array<{ label, value, color? }> }`). */\ninterface BreakdownSegment {\n label: string;\n value: number;\n}\n\n/** One row of the per-model usage/cost table. */\ninterface ModelSpendTableRow {\n modelId: string;\n requests: number;\n inputTokens: number;\n outputTokens: number;\n costUsd: number;\n}\n\n/** One row of the per-actor spend table. */\ninterface ActorSpendTableRow {\n actorRef: string;\n requests: number;\n totalTokens: number;\n costUsd: number;\n}\n\n/** One row of the top-threads-by-cost table. */\ninterface ThreadSpendTableRow {\n title: string;\n actorRef: string;\n requests: number;\n totalTokens: number;\n costUsd: number;\n}\n\n/** Top threads by cost within the range, capped to this count. */\nconst TOP_THREADS_LIMIT = 10;\n\n/** One point of the timeseries trend (Telescope core: `{ label } & Record<string, number>`). */\ninterface UsageTrendTableRow {\n label: string;\n costUsd: number;\n totalTokens: number;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null;\n}\n\n/** Structural guard so the DI-resolved binding is narrowed without an `as`/`any` cast. */\nfunction isGovernanceQueries(value: unknown): value is AgentGovernanceQueries {\n return (\n isRecord(value) &&\n typeof value.spendByModel === 'function' &&\n typeof value.spendByActor === 'function' &&\n typeof value.spendByThread === 'function' &&\n typeof value.usageTrend === 'function' &&\n typeof value.recentToolCalls === 'function' &&\n typeof value.recentThreads === 'function'\n );\n}\n\n/**\n * Resolve the governance read-model from the host container. Returns `null` when the host has not\n * bound `AGENT_GOVERNANCE_QUERIES` (missing token throws inside `moduleRef.get`) so panels can render\n * an empty state instead of erroring.\n */\nfunction resolveGovernanceQueries(ctx: ExtensionContext): AgentGovernanceQueries | null {\n let resolved: unknown;\n try {\n resolved = ctx.moduleRef.get(AGENT_GOVERNANCE_QUERIES, { strict: false });\n } catch {\n return null;\n }\n return isGovernanceQueries(resolved) ? resolved : null;\n}\n\nfunction isIsoDay(value: unknown): value is string {\n return typeof value === 'string' && ISO_DAY_PATTERN.test(value);\n}\n\nfunction todayUtcDay(): string {\n return new Date().toISOString().slice(0, 10);\n}\n\n/** Shift a `YYYY-MM-DD` UTC day by `deltaDays` (negative goes back in time). */\nexport function shiftUtcDay(day: string, deltaDays: number): string {\n const shifted = new Date(`${day}T00:00:00.000Z`);\n shifted.setUTCDate(shifted.getUTCDate() + deltaDays);\n return shifted.toISOString().slice(0, 10);\n}\n\n/**\n * Derive the query range: honour explicit `fromDay`/`toDay` (validated ISO days), otherwise default\n * to the trailing {@link DEFAULT_TREND_WINDOW_DAYS}-day window ending today (UTC).\n */\nexport function resolveRange(query: Record<string, unknown> | undefined): GovernanceRange {\n const toDay = query && isIsoDay(query.toDay) ? query.toDay : todayUtcDay();\n const fromDay =\n query && isIsoDay(query.fromDay)\n ? query.fromDay\n : shiftUtcDay(toDay, -(DEFAULT_TREND_WINDOW_DAYS - 1));\n return { fromDay, toDay };\n}\n\nfunction roundCents(value: number): number {\n return Math.round(value * 100) / 100;\n}\n\n/** Sum authoritative spend across every model row. */\nexport function totalCostUsd(rows: ModelSpendRow[]): number {\n return roundCents(rows.reduce((sum, row) => sum + row.costUsd, 0));\n}\n\n/** Sum input + output tokens across every model row. */\nexport function totalTokens(rows: ModelSpendRow[]): number {\n return rows.reduce((sum, row) => sum + row.inputTokens + row.outputTokens, 0);\n}\n\n/** Spend-by-model as breakdown segments (models with zero cost are dropped from the donut). */\nexport function toModelSpendSegments(rows: ModelSpendRow[]): BreakdownSegment[] {\n return rows\n .filter((row) => row.costUsd > 0)\n .map((row) => ({ label: row.modelId, value: roundCents(row.costUsd) }));\n}\n\n/** Spend-by-model as table rows (cost rounded to cents; usage kept exact). */\nexport function toModelSpendRows(rows: ModelSpendRow[]): ModelSpendTableRow[] {\n return rows.map((row) => ({\n modelId: row.modelId,\n requests: row.requests,\n inputTokens: row.inputTokens,\n outputTokens: row.outputTokens,\n costUsd: roundCents(row.costUsd),\n }));\n}\n\n/** Spend-by-actor as table rows. */\nexport function toActorSpendRows(rows: ActorSpendRow[]): ActorSpendTableRow[] {\n return rows.map((row) => ({\n actorRef: row.actorRef,\n requests: row.requests,\n totalTokens: row.totalTokens,\n costUsd: roundCents(row.costUsd),\n }));\n}\n\n/** Top-threads-by-cost as table rows. */\nexport function toThreadSpendRows(rows: ThreadSpendRow[]): ThreadSpendTableRow[] {\n return rows.map((row) => ({\n title: row.title || row.threadId,\n actorRef: row.actorRef,\n requests: row.requests,\n totalTokens: row.totalTokens,\n costUsd: roundCents(row.costUsd),\n }));\n}\n\n/** Spend-by-actor as breakdown segments (actors with zero cost are dropped). */\nexport function toActorSpendSegments(rows: ActorSpendRow[]): BreakdownSegment[] {\n return rows\n .filter((row) => row.costUsd > 0)\n .map((row) => ({ label: row.actorRef, value: roundCents(row.costUsd) }));\n}\n\n/** Daily usage trend as timeseries rows keyed by `label` (the day). */\nexport function toUsageTrendRows(points: UsageTrendPoint[]): UsageTrendTableRow[] {\n return points.map((point) => ({\n label: point.day,\n costUsd: roundCents(point.costUsd),\n totalTokens: point.totalTokens,\n }));\n}\n\n/**\n * Build a governance `DataProvider` from a fetch + a format step. Every provider follows the same\n * shape: resolve the read-model, run ONE query over the panel's range, then format the rows into the\n * panel's result shape. When the host hasn't bound the read-model, `fetch` is skipped and `format`\n * runs over `[]` — which is exactly the empty-but-valid shape each formatter already yields (0 for\n * totals, `[]` for segments/rows), so the degraded case needs no special-casing.\n */\nfunction governanceStatProvider<TRow>(\n name: string,\n fetch: (queries: AgentGovernanceQueries, range: GovernanceRange) => Promise<TRow[]>,\n format: (rows: TRow[]) => unknown,\n): DataProvider {\n return {\n name,\n async resolve(query, ctx) {\n const queries = resolveGovernanceQueries(ctx);\n const rows = queries ? await fetch(queries, resolveRange(query)) : [];\n return format(rows);\n },\n };\n}\n\n/** stat → authoritative total spend (USD) over the range. */\nexport function agentSpendTotalProvider(): DataProvider {\n return governanceStatProvider(\n 'agent.spend.totalCost',\n (queries, range) => queries.spendByModel(range),\n (rows) => ({ value: totalCostUsd(rows) }),\n );\n}\n\n/** stat → authoritative total tokens (input + output) over the range. */\nexport function agentTokensTotalProvider(): DataProvider {\n return governanceStatProvider(\n 'agent.spend.totalTokens',\n (queries, range) => queries.spendByModel(range),\n (rows) => ({ value: totalTokens(rows) }),\n );\n}\n\n/** breakdown → spend share per model. */\nexport function agentSpendByModelProvider(): DataProvider {\n return governanceStatProvider(\n 'agent.spend.byModel',\n (queries, range) => queries.spendByModel(range),\n (rows) => ({ segments: toModelSpendSegments(rows) }),\n );\n}\n\n/** table → per-model requests / in+out tokens / cost. */\nexport function agentModelSpendTableProvider(): DataProvider {\n return governanceStatProvider(\n 'agent.spend.byModelTable',\n (queries, range) => queries.spendByModel(range),\n (rows) => ({ rows: toModelSpendRows(rows) }),\n );\n}\n\n/** timeseries → daily spend + tokens trend. */\nexport function agentUsageTrendProvider(): DataProvider {\n return governanceStatProvider(\n 'agent.usage.trend',\n (queries, range) => queries.usageTrend(range),\n (points) => ({ rows: toUsageTrendRows(points) }),\n );\n}\n\n/** table → spend per acting ref (user/tenant). */\nexport function agentActorSpendTableProvider(): DataProvider {\n return governanceStatProvider(\n 'agent.spend.byActor',\n (queries, range) => queries.spendByActor(range),\n (rows) => ({ rows: toActorSpendRows(rows) }),\n );\n}\n\n/** breakdown → spend share per actor. */\nexport function agentSpendByActorProvider(): DataProvider {\n return governanceStatProvider(\n 'agent.spend.byActorShare',\n (queries, range) => queries.spendByActor(range),\n (rows) => ({ segments: toActorSpendSegments(rows) }),\n );\n}\n\n/** table → top threads by cost (title, actor, requests, tokens, cost). */\nexport function agentTopThreadsTableProvider(): DataProvider {\n return governanceStatProvider(\n 'agent.threads.topSpend',\n (queries, range) => queries.spendByThread(range, TOP_THREADS_LIMIT),\n (rows) => ({ rows: toThreadSpendRows(rows) }),\n );\n}\n","import { subscribe } from 'node:diagnostics_channel';\nimport { channelName } from '@dudousxd/nestjs-diagnostics';\nimport type { Watcher, WatcherContext } from '@dudousxd/nestjs-telescope';\n\nconst AGENT_EVENTS = ['run.started', 'message', 'tool-call', 'quota.exceeded', 'run.finished'];\n\ninterface DiagnosticEnvelope {\n event: string;\n payload: Record<string, unknown>;\n}\n\n/**\n * Records `aviary:agent:*` diagnostics events as Telescope entries of type `agent`. It depends\n * only on the diagnostics channel — not on the agent runtime — so it stays fully decoupled.\n */\nexport class AgentTelescopeWatcher implements Watcher {\n readonly type = 'agent';\n\n register(ctx: WatcherContext): void {\n for (const event of AGENT_EVENTS) {\n subscribe(channelName('agent', event), (message) => {\n const envelope = message as DiagnosticEnvelope;\n ctx.record({\n type: 'agent',\n content: { event: envelope.event, ...envelope.payload },\n tags: [envelope.event],\n });\n });\n }\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACAA,IAAAA,2BAAyC;;;ACGlC,SAASC,iBAAAA;AACd,SAAO;IACLC,IAAI;IACJC,OAAO;IACPC,QAAQ,CAAA;IACRC,UAAU;MACR;QACEC,OAAO;QACPC,MAAM;QACNH,QAAQ;UACN;YAAEI,MAAM;YAAQF,OAAO;YAAQG,MAAM;cAAEC,UAAU;YAAa;UAAE;UAChE;YAAEF,MAAM;YAAQF,OAAO;YAAUG,MAAM;cAAEC,UAAU;YAAe;UAAE;;MAExE;MACA;QACEJ,OAAO;QACPC,MAAM;QACNH,QAAQ;UACN;YACEI,MAAM;YACNF,OAAO;YACPG,MAAM;cAAEC,UAAU;YAAwB;YAC1CC,QAAQ;UACV;UACA;YACEH,MAAM;YACNF,OAAO;YACPG,MAAM;cAAEC,UAAU;YAA0B;YAC5CC,QAAQ;UACV;UACA;YACEH,MAAM;YACNF,OAAO;YACPG,MAAM;cAAEC,UAAU;YAAsB;YACxCE,OAAO;UACT;UACA;YACEJ,MAAM;YACNF,OAAO;YACPG,MAAM;cAAEC,UAAU;YAAoB;YACtCG,QAAQ;cAAC;cAAW;;YACpBD,OAAO;UACT;;MAEJ;MACA;QACEN,OAAO;QACPF,QAAQ;UACN;YACEI,MAAM;YACNF,OAAO;YACPG,MAAM;cAAEC,UAAU;YAA2B;YAC7CI,SAAS;cACP;gBAAEC,KAAK;gBAAWZ,OAAO;cAAQ;cACjC;gBAAEY,KAAK;gBAAYZ,OAAO;cAAW;cACrC;gBAAEY,KAAK;gBAAeZ,OAAO;cAAe;cAC5C;gBAAEY,KAAK;gBAAgBZ,OAAO;cAAgB;cAC9C;gBAAEY,KAAK;gBAAWZ,OAAO;cAAa;;UAE1C;;MAEJ;MACA;QACEG,OAAO;QACPC,MAAM;QACNH,QAAQ;UACN;YACEI,MAAM;YACNF,OAAO;YACPG,MAAM;cAAEC,UAAU;YAA2B;YAC7CE,OAAO;UACT;UACA;YACEJ,MAAM;YACNF,OAAO;YACPG,MAAM;cAAEC,UAAU;YAAsB;YACxCI,SAAS;cACP;gBAAEC,KAAK;gBAAYZ,OAAO;cAAQ;cAClC;gBAAEY,KAAK;gBAAYZ,OAAO;cAAW;cACrC;gBAAEY,KAAK;gBAAeZ,OAAO;cAAS;cACtC;gBAAEY,KAAK;gBAAWZ,OAAO;cAAa;;UAE1C;;MAEJ;MACA;QACEG,OAAO;QACPF,QAAQ;UACN;YACEI,MAAM;YACNF,OAAO;YACPG,MAAM;cAAEC,UAAU;YAAyB;YAC3CI,SAAS;cACP;gBAAEC,KAAK;gBAASZ,OAAO;cAAS;cAChC;gBAAEY,KAAK;gBAAYZ,OAAO;cAAQ;cAClC;gBAAEY,KAAK;gBAAYZ,OAAO;cAAW;cACrC;gBAAEY,KAAK;gBAAeZ,OAAO;cAAS;cACtC;gBAAEY,KAAK;gBAAWZ,OAAO;cAAa;;UAE1C;;MAEJ;MACA;QACEG,OAAO;QACPC,MAAM;QACNH,QAAQ;UACN;YACEI,MAAM;YACNF,OAAO;YACPG,MAAM;cAAEC,UAAU;YAAmB;YACrCE,OAAO;UACT;UACA;YACEJ,MAAM;YACNF,OAAO;YACPG,MAAM;cAAEC,UAAU;YAAc;YAChCI,SAAS;cACP;gBAAEC,KAAK;gBAAYZ,OAAO;cAAO;cACjC;gBAAEY,KAAK;gBAAYZ,OAAO;cAAO;cACjC;gBAAEY,KAAK;gBAAUZ,OAAO;cAAS;cACjC;gBAAEY,KAAK;gBAASZ,OAAO;cAAM;;UAEjC;;MAEJ;;EAEJ;AACF;AA/HgBF;;;ACFhB,8BAAkC;AAmBlC,eAAee,aAAaC,KAAqB;AAC/C,QAAMC,UAAUD,IAAIE,UAAUC,IAAIC,2CAAmB;IAAEC,QAAQ;EAAM,CAAA;AAGrE,QAAMC,OAAO,MAAML,QAAQE,IAAI;IAAEI,MAAM;IAASC,OAAO;EAAM,CAAA;AAC7D,SAAOF,KAAKG;AACd;AANeV;AAQf,SAASW,QAAQC,SAAyBC,OAAa;AACrD,SAAOD,QAAQE,OAAO,CAACC,UAAUA,MAAMC,SAASH,UAAUA,KAAAA;AAC5D;AAFSF;AAKF,SAASM,oBAAAA;AACd,SAAO;IACLC,MAAM;IACN,MAAMC,QAAQC,QAAQnB,KAAG;AACvB,YAAMoB,WAAWV,QAAQ,MAAMX,aAAaC,GAAAA,GAAM,cAAA;AAClD,aAAO;QAAEqB,OAAOD,SAASE;MAAO;IAClC;EACF;AACF;AARgBN;AAWT,SAASO,sBAAAA;AACd,SAAO;IACLN,MAAM;IACN,MAAMC,QAAQC,QAAQnB,KAAG;AACvB,YAAMoB,WAAWV,QAAQ,MAAMX,aAAaC,GAAAA,GAAM,cAAA;AAClD,YAAMqB,QAAQD,SAASI,OACrB,CAACC,KAAKX,UACJW,OAAOX,MAAMC,SAASW,eAAe,MAAMZ,MAAMC,SAASY,gBAAgB,IAC5E,CAAA;AAEF,aAAO;QAAEN;MAAM;IACjB;EACF;AACF;AAbgBE;AAgBT,SAASK,qBAAAA;AACd,SAAO;IACLX,MAAM;IACN,MAAMC,QAAQC,QAAQnB,KAAG;AACvB,YAAM6B,QAAQnB,QAAQ,MAAMX,aAAaC,GAAAA,GAAM,WAAA,EAC5C8B,MAAM,GAAC,EACPC,QAAO,EACPC,IAAI,CAAClB,WAAW;QACfmB,UAAUnB,MAAMC,SAASkB,YAAY;QACrCC,UAAUpB,MAAMC,SAASmB,YAAY;QACrCC,QAAQrB,MAAMC,SAASoB,UAAU;QACjCC,OAAOtB,MAAMC,SAASqB,SAAS;MACjC,EAAA;AACF,aAAO;QAAEC,MAAMR;MAAM;IACvB;EACF;AACF;AAhBgBD;AAmBT,SAASU,0BAAAA;AACd,SAAO;IACLrB,MAAM;IACN,MAAMC,QAAQC,QAAQnB,KAAG;AACvB,YAAM6B,QAAQnB,QAAQ,MAAMX,aAAaC,GAAAA,GAAM,WAAA;AAC/C,YAAMuC,SAAS,oBAAIC,IAAAA;AACnB,iBAAWC,QAAQZ,OAAO;AACxB,cAAMM,SAASM,KAAK1B,SAASoB,UAAU;AACvCI,eAAOG,IAAIP,SAASI,OAAOpC,IAAIgC,MAAAA,KAAW,KAAK,CAAA;MACjD;AACA,aAAO;QAAEQ,UAAU;aAAIJ,OAAO5B,QAAO;UAAIqB,IAAI,CAAC,CAACY,OAAOvB,KAAAA,OAAY;UAAEuB;UAAOvB;QAAM,EAAA;MAAI;IACvF;EACF;AACF;AAbgBiB;;;ACvEhB,+BAAyC;AAezC,IAAMO,4BAA4B;AAElC,IAAMC,kBAAkB;AAmCxB,IAAMC,oBAAoB;AAS1B,SAASC,SAASC,OAAc;AAC9B,SAAO,OAAOA,UAAU,YAAYA,UAAU;AAChD;AAFSD;AAKT,SAASE,oBAAoBD,OAAc;AACzC,SACED,SAASC,KAAAA,KACT,OAAOA,MAAME,iBAAiB,cAC9B,OAAOF,MAAMG,iBAAiB,cAC9B,OAAOH,MAAMI,kBAAkB,cAC/B,OAAOJ,MAAMK,eAAe,cAC5B,OAAOL,MAAMM,oBAAoB,cACjC,OAAON,MAAMO,kBAAkB;AAEnC;AAVSN;AAiBT,SAASO,yBAAyBC,KAAqB;AACrD,MAAIC;AACJ,MAAI;AACFA,eAAWD,IAAIE,UAAUC,IAAIC,mDAA0B;MAAEC,QAAQ;IAAM,CAAA;EACzE,QAAQ;AACN,WAAO;EACT;AACA,SAAOb,oBAAoBS,QAAAA,IAAYA,WAAW;AACpD;AARSF;AAUT,SAASO,SAASf,OAAc;AAC9B,SAAO,OAAOA,UAAU,YAAYH,gBAAgBmB,KAAKhB,KAAAA;AAC3D;AAFSe;AAIT,SAASE,cAAAA;AACP,UAAO,oBAAIC,KAAAA,GAAOC,YAAW,EAAGC,MAAM,GAAG,EAAA;AAC3C;AAFSH;AAKF,SAASI,YAAYC,KAAaC,WAAiB;AACxD,QAAMC,UAAU,oBAAIN,KAAK,GAAGI,GAAAA,gBAAmB;AAC/CE,UAAQC,WAAWD,QAAQE,WAAU,IAAKH,SAAAA;AAC1C,SAAOC,QAAQL,YAAW,EAAGC,MAAM,GAAG,EAAA;AACxC;AAJgBC;AAUT,SAASM,aAAaC,OAA0C;AACrE,QAAMC,QAAQD,SAASb,SAASa,MAAMC,KAAK,IAAID,MAAMC,QAAQZ,YAAAA;AAC7D,QAAMa,UACJF,SAASb,SAASa,MAAME,OAAO,IAC3BF,MAAME,UACNT,YAAYQ,OAAO,EAAEjC,4BAA4B,EAAA;AACvD,SAAO;IAAEkC;IAASD;EAAM;AAC1B;AAPgBF;AAShB,SAASI,WAAW/B,OAAa;AAC/B,SAAOgC,KAAKC,MAAMjC,QAAQ,GAAA,IAAO;AACnC;AAFS+B;AAKF,SAASG,aAAaC,MAAqB;AAChD,SAAOJ,WAAWI,KAAKC,OAAO,CAACC,KAAKC,QAAQD,MAAMC,IAAIC,SAAS,CAAA,CAAA;AACjE;AAFgBL;AAKT,SAASM,YAAYL,MAAqB;AAC/C,SAAOA,KAAKC,OAAO,CAACC,KAAKC,QAAQD,MAAMC,IAAIG,cAAcH,IAAII,cAAc,CAAA;AAC7E;AAFgBF;AAKT,SAASG,qBAAqBR,MAAqB;AACxD,SAAOA,KACJS,OAAO,CAACN,QAAQA,IAAIC,UAAU,CAAA,EAC9BM,IAAI,CAACP,SAAS;IAAEQ,OAAOR,IAAIS;IAAS/C,OAAO+B,WAAWO,IAAIC,OAAO;EAAE,EAAA;AACxE;AAJgBI;AAOT,SAASK,iBAAiBb,MAAqB;AACpD,SAAOA,KAAKU,IAAI,CAACP,SAAS;IACxBS,SAAST,IAAIS;IACbE,UAAUX,IAAIW;IACdR,aAAaH,IAAIG;IACjBC,cAAcJ,IAAII;IAClBH,SAASR,WAAWO,IAAIC,OAAO;EACjC,EAAA;AACF;AARgBS;AAWT,SAASE,iBAAiBf,MAAqB;AACpD,SAAOA,KAAKU,IAAI,CAACP,SAAS;IACxBa,UAAUb,IAAIa;IACdF,UAAUX,IAAIW;IACdT,aAAaF,IAAIE;IACjBD,SAASR,WAAWO,IAAIC,OAAO;EACjC,EAAA;AACF;AAPgBW;AAUT,SAASE,kBAAkBjB,MAAsB;AACtD,SAAOA,KAAKU,IAAI,CAACP,SAAS;IACxBe,OAAOf,IAAIe,SAASf,IAAIgB;IACxBH,UAAUb,IAAIa;IACdF,UAAUX,IAAIW;IACdT,aAAaF,IAAIE;IACjBD,SAASR,WAAWO,IAAIC,OAAO;EACjC,EAAA;AACF;AARgBa;AAWT,SAASG,qBAAqBpB,MAAqB;AACxD,SAAOA,KACJS,OAAO,CAACN,QAAQA,IAAIC,UAAU,CAAA,EAC9BM,IAAI,CAACP,SAAS;IAAEQ,OAAOR,IAAIa;IAAUnD,OAAO+B,WAAWO,IAAIC,OAAO;EAAE,EAAA;AACzE;AAJgBgB;AAOT,SAASC,iBAAiBC,QAAyB;AACxD,SAAOA,OAAOZ,IAAI,CAACa,WAAW;IAC5BZ,OAAOY,MAAMpC;IACbiB,SAASR,WAAW2B,MAAMnB,OAAO;IACjCC,aAAakB,MAAMlB;EACrB,EAAA;AACF;AANgBgB;AAehB,SAASG,uBACPC,MACAC,OACAC,QAAiC;AAEjC,SAAO;IACLF;IACA,MAAMG,QAAQnC,OAAOnB,KAAG;AACtB,YAAMuD,UAAUxD,yBAAyBC,GAAAA;AACzC,YAAM0B,OAAO6B,UAAU,MAAMH,MAAMG,SAASrC,aAAaC,KAAAA,CAAAA,IAAU,CAAA;AACnE,aAAOkC,OAAO3B,IAAAA;IAChB;EACF;AACF;AAbSwB;AAgBF,SAASM,0BAAAA;AACd,SAAON,uBACL,yBACA,CAACK,SAASE,UAAUF,QAAQ9D,aAAagE,KAAAA,GACzC,CAAC/B,UAAU;IAAEnC,OAAOkC,aAAaC,IAAAA;EAAM,EAAA;AAE3C;AANgB8B;AAST,SAASE,2BAAAA;AACd,SAAOR,uBACL,2BACA,CAACK,SAASE,UAAUF,QAAQ9D,aAAagE,KAAAA,GACzC,CAAC/B,UAAU;IAAEnC,OAAOwC,YAAYL,IAAAA;EAAM,EAAA;AAE1C;AANgBgC;AAST,SAASC,4BAAAA;AACd,SAAOT,uBACL,uBACA,CAACK,SAASE,UAAUF,QAAQ9D,aAAagE,KAAAA,GACzC,CAAC/B,UAAU;IAAEkC,UAAU1B,qBAAqBR,IAAAA;EAAM,EAAA;AAEtD;AANgBiC;AAST,SAASE,+BAAAA;AACd,SAAOX,uBACL,4BACA,CAACK,SAASE,UAAUF,QAAQ9D,aAAagE,KAAAA,GACzC,CAAC/B,UAAU;IAAEA,MAAMa,iBAAiBb,IAAAA;EAAM,EAAA;AAE9C;AANgBmC;AAST,SAASC,0BAAAA;AACd,SAAOZ,uBACL,qBACA,CAACK,SAASE,UAAUF,QAAQ3D,WAAW6D,KAAAA,GACvC,CAACT,YAAY;IAAEtB,MAAMqB,iBAAiBC,MAAAA;EAAQ,EAAA;AAElD;AANgBc;AAST,SAASC,+BAAAA;AACd,SAAOb,uBACL,uBACA,CAACK,SAASE,UAAUF,QAAQ7D,aAAa+D,KAAAA,GACzC,CAAC/B,UAAU;IAAEA,MAAMe,iBAAiBf,IAAAA;EAAM,EAAA;AAE9C;AANgBqC;AAST,SAASC,4BAAAA;AACd,SAAOd,uBACL,4BACA,CAACK,SAASE,UAAUF,QAAQ7D,aAAa+D,KAAAA,GACzC,CAAC/B,UAAU;IAAEkC,UAAUd,qBAAqBpB,IAAAA;EAAM,EAAA;AAEtD;AANgBsC;AAST,SAASC,+BAAAA;AACd,SAAOf,uBACL,0BACA,CAACK,SAASE,UAAUF,QAAQ5D,cAAc8D,OAAOpE,iBAAAA,GACjD,CAACqC,UAAU;IAAEA,MAAMiB,kBAAkBjB,IAAAA;EAAM,EAAA;AAE/C;AANgBuC;;;AC5RhB,sCAA0B;AAC1B,gCAA4B;AAG5B,IAAMC,eAAe;EAAC;EAAe;EAAW;EAAa;EAAkB;;AAWxE,IAAMC,wBAAN,MAAMA;EAfb,OAeaA;;;EACFC,OAAO;EAEhBC,SAASC,KAA2B;AAClC,eAAWC,SAASL,cAAc;AAChCM,yDAAUC,uCAAY,SAASF,KAAAA,GAAQ,CAACG,YAAAA;AACtC,cAAMC,WAAWD;AACjBJ,YAAIM,OAAO;UACTR,MAAM;UACNS,SAAS;YAAEN,OAAOI,SAASJ;YAAO,GAAGI,SAASG;UAAQ;UACtDC,MAAM;YAACJ,SAASJ;;QAClB,CAAA;MACF,CAAA;IACF;EACF;AACF;;;AJGO,SAASS,0BAAAA;AACd,aAAOC,mDAAyB;IAC9BC,MAAM;IACNC,UAAU,6BAAM;MAAC,IAAIC,sBAAAA;OAAX;IACVC,YAAY,6BAAM;MAAC;QAAEC,IAAI;QAASC,OAAO;QAASC,KAAK;MAAgB;OAA3D;IACZC,YAAY,6BAAM;MAACC,eAAAA;OAAP;IACZC,eAAe,6BAAM;MACnBC,kBAAAA;MACAC,oBAAAA;MACAC,mBAAAA;MACAC,wBAAAA;MACAC,wBAAAA;MACAC,yBAAAA;MACAC,0BAAAA;MACAC,6BAAAA;MACAC,wBAAAA;MACAC,6BAAAA;MACAC,0BAAAA;MACAC,6BAAAA;OAZa;EAcjB,CAAA;AACF;AArBgBvB;","names":["import_nestjs_telescope","agentDashboard","id","label","panels","sections","title","cols","kind","data","provider","format","style","series","columns","key","fetchEntries","ctx","storage","moduleRef","get","TELESCOPE_STORAGE","strict","page","type","limit","data","ofEvent","entries","event","filter","entry","content","agentRunsProvider","name","resolve","_query","finished","value","length","agentTokensProvider","reduce","sum","inputTokens","outputTokens","agentToolsProvider","calls","slice","reverse","map","toolName","toolType","status","runId","rows","agentToolStatusProvider","counts","Map","call","set","segments","label","DEFAULT_TREND_WINDOW_DAYS","ISO_DAY_PATTERN","TOP_THREADS_LIMIT","isRecord","value","isGovernanceQueries","spendByModel","spendByActor","spendByThread","usageTrend","recentToolCalls","recentThreads","resolveGovernanceQueries","ctx","resolved","moduleRef","get","AGENT_GOVERNANCE_QUERIES","strict","isIsoDay","test","todayUtcDay","Date","toISOString","slice","shiftUtcDay","day","deltaDays","shifted","setUTCDate","getUTCDate","resolveRange","query","toDay","fromDay","roundCents","Math","round","totalCostUsd","rows","reduce","sum","row","costUsd","totalTokens","inputTokens","outputTokens","toModelSpendSegments","filter","map","label","modelId","toModelSpendRows","requests","toActorSpendRows","actorRef","toThreadSpendRows","title","threadId","toActorSpendSegments","toUsageTrendRows","points","point","governanceStatProvider","name","fetch","format","resolve","queries","agentSpendTotalProvider","range","agentTokensTotalProvider","agentSpendByModelProvider","segments","agentModelSpendTableProvider","agentUsageTrendProvider","agentActorSpendTableProvider","agentSpendByActorProvider","agentTopThreadsTableProvider","AGENT_EVENTS","AgentTelescopeWatcher","type","register","ctx","event","subscribe","channelName","message","envelope","record","content","payload","tags","agentTelescopeExtension","defineTelescopeExtension","name","watchers","AgentTelescopeWatcher","entryTypes","id","label","dot","dashboards","agentDashboard","dataProviders","agentRunsProvider","agentTokensProvider","agentToolsProvider","agentToolStatusProvider","agentSpendTotalProvider","agentTokensTotalProvider","agentSpendByModelProvider","agentModelSpendTableProvider","agentUsageTrendProvider","agentActorSpendTableProvider","agentSpendByActorProvider","agentTopThreadsTableProvider"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/agent-telescope.extension.ts","../src/agent-dashboard.spec-data.ts","../src/agent-data-providers.ts","../src/agent-governance-providers.ts","../src/agent-telescope.watcher.ts"],"sourcesContent":["export { agentTelescopeExtension } from './agent-telescope.extension.js';\nexport { AgentTelescopeWatcher } from './agent-telescope.watcher.js';\nexport { agentDashboard } from './agent-dashboard.spec-data.js';\nexport {\n agentRunsProvider,\n agentTokensProvider,\n agentToolsProvider,\n agentToolStatusProvider,\n} from './agent-data-providers.js';\nexport {\n agentActorSpendTableProvider,\n agentModelSpendTableProvider,\n agentPendingApprovalsCountProvider,\n agentPendingApprovalsTableProvider,\n agentRecentRunsTableProvider,\n agentRecentThreadsTableProvider,\n agentRecentToolCallsTableProvider,\n agentRunErrorsProvider,\n agentRunsByAgentTableProvider,\n agentRunsDurationProvider,\n agentRunsFailedProvider,\n agentRunsRetriesProvider,\n agentRunsSuccessRateProvider,\n agentRunsTotalProvider,\n agentRunsTrendProvider,\n agentSpendByActorProvider,\n agentSpendByModelProvider,\n agentSpendTotalProvider,\n agentTokensTotalProvider,\n agentToolStatsTableProvider,\n agentTopThreadsTableProvider,\n agentUsageTrendProvider,\n capErrorMessage,\n resolveRange,\n shiftUtcDay,\n shortPromptHash,\n toActorSpendRows,\n toActorSpendSegments,\n toModelSpendRows,\n toModelSpendSegments,\n toPendingApprovalTableRows,\n toRecentRunTableRows,\n toRecentThreadTableRows,\n toRecentToolCallRows,\n toRunAgentTableRows,\n toRunErrorSegments,\n toRunTrendRows,\n toThreadSpendRows,\n toToolStatTableRows,\n totalCostUsd,\n totalTokens,\n toUsageTrendRows,\n} from './agent-governance-providers.js';\n","import { defineTelescopeExtension } from '@dudousxd/nestjs-telescope';\nimport { agentDashboard } from './agent-dashboard.spec-data.js';\nimport {\n agentRunsProvider,\n agentTokensProvider,\n agentToolStatusProvider,\n} from './agent-data-providers.js';\nimport {\n agentActorSpendTableProvider,\n agentModelSpendTableProvider,\n agentPendingApprovalsCountProvider,\n agentPendingApprovalsTableProvider,\n agentRecentRunsTableProvider,\n agentRecentThreadsTableProvider,\n agentRecentToolCallsTableProvider,\n agentRunErrorsProvider,\n agentRunsByAgentTableProvider,\n agentRunsDurationProvider,\n agentRunsFailedProvider,\n agentRunsRetriesProvider,\n agentRunsSuccessRateProvider,\n agentRunsTotalProvider,\n agentRunsTrendProvider,\n agentSpendByActorProvider,\n agentSpendByModelProvider,\n agentSpendTotalProvider,\n agentTokensTotalProvider,\n agentToolStatsTableProvider,\n agentTopThreadsTableProvider,\n agentUsageTrendProvider,\n} from './agent-governance-providers.js';\nimport { AgentTelescopeWatcher } from './agent-telescope.watcher.js';\n\n/**\n * The first-class Telescope extension for nestjs-agent: an \"Agent\" tab fed by two sources —\n * the `aviary:agent:*` diagnostics channel (live runs, tool calls) via the watcher, and the\n * authoritative `AGENT_GOVERNANCE_QUERIES` read-model (historical spend/usage, run reliability,\n * tool activity, the approvals inbox) via the governance providers. The extension `name`,\n * entry-type id, dashboard id, and every provider name share the `agent` prefix so the registry's\n * global-uniqueness namespaces never collide with sibling extensions.\n *\n * `threadHref`/`runHref` deep-link a table row's `threadId`/`runId` cell out to the host's own\n * thread/run viewer — passed straight through to {@link agentDashboard}, mirroring\n * `durableTelescopeExtension`'s `runHref` option.\n *\n * Host wiring: the governance panels (Spend/Models/Actors/Reliability/Runs/Threads/Approvals/Tool\n * stats/Recent tool calls) resolve `AGENT_GOVERNANCE_QUERIES` from the host DI container at\n * request time (via `ctx.moduleRef`). The host must bind that token — from its store adapter\n * (e.g. `store-mikro-orm` / `store-drizzle` / `testing`) — in the same module that registers\n * `TelescopeModule.forRoot({ extensions: [agentTelescopeExtension()] })`. If the binding is\n * absent, those panels render an empty state; the live watcher-fed panels (Runs/Tokens stats and\n * the Tool-call status breakdown) keep working regardless.\n */\nexport function agentTelescopeExtension(opts: { threadHref?: string; runHref?: string } = {}) {\n return defineTelescopeExtension({\n name: 'agent',\n watchers: () => [new AgentTelescopeWatcher()],\n entryTypes: () => [{ id: 'agent', label: 'Agent', dot: 'bg-violet-400' }],\n dashboards: () => [agentDashboard(opts)],\n dataProviders: () => [\n agentRunsProvider(),\n agentTokensProvider(),\n agentToolStatusProvider(),\n agentSpendTotalProvider(),\n agentTokensTotalProvider(),\n agentSpendByModelProvider(),\n agentModelSpendTableProvider(),\n agentUsageTrendProvider(),\n agentActorSpendTableProvider(),\n agentSpendByActorProvider(),\n agentTopThreadsTableProvider(),\n agentRunsTotalProvider(),\n agentRunsSuccessRateProvider(),\n agentRunsFailedProvider(),\n agentRunsRetriesProvider(),\n agentRunsDurationProvider(),\n agentRunsByAgentTableProvider(),\n agentRunErrorsProvider(),\n agentRunsTrendProvider(),\n agentRecentRunsTableProvider(),\n agentRecentToolCallsTableProvider(),\n agentRecentThreadsTableProvider(),\n agentPendingApprovalsCountProvider(),\n agentPendingApprovalsTableProvider(),\n agentToolStatsTableProvider(),\n ],\n });\n}\n","import type { Column, DashboardSpec } from '@dudousxd/nestjs-telescope';\n\n/** A plain column, or one carrying a `Column.link` to `href` when `href` is given. */\nfunction col(key: string, label: string, href?: string): Column {\n return href !== undefined ? { key, label, link: { href } } : { key, label };\n}\n\n/**\n * The \"Agent\" overview dashboard. Panels bind to the `agent.*` data providers.\n *\n * `threadHref`/`runHref` are URL templates for deep-linking a `{threadId}`/`{runId}` cell out to\n * the host's own thread/run viewer (e.g. the standalone `@dudousxd/nestjs-agent-dashboard` SPA),\n * mirroring `durableTelescopeExtension`'s `runHref` option. Every table whose rows carry a\n * `threadId`/`runId` gets a `Column.link` for it (via {@link col}); omit an option to leave that\n * column plain text.\n */\nexport function agentDashboard(\n opts: { threadHref?: string; runHref?: string } = {},\n): DashboardSpec {\n return {\n id: 'agent.overview',\n label: 'Agent',\n panels: [],\n sections: [\n {\n title: 'Overview',\n cols: 2,\n panels: [\n { kind: 'stat', title: 'Runs', data: { provider: 'agent.runs' } },\n { kind: 'stat', title: 'Tokens', data: { provider: 'agent.tokens' } },\n ],\n },\n {\n title: 'Reliability',\n cols: 4,\n panels: [\n { kind: 'stat', title: 'Runs', data: { provider: 'agent.runs.total' } },\n {\n kind: 'stat',\n title: 'Success rate',\n data: { provider: 'agent.runs.successRate' },\n format: 'percent',\n },\n { kind: 'stat', title: 'Failed', data: { provider: 'agent.runs.failed' } },\n { kind: 'stat', title: 'Retries', data: { provider: 'agent.runs.retries' } },\n ],\n },\n {\n title: 'Run trends',\n cols: 3,\n panels: [\n {\n kind: 'timeseries',\n title: 'Runs & failures',\n data: { provider: 'agent.runs.trend' },\n series: ['runs', 'failed'],\n style: 'stacked',\n },\n {\n kind: 'distribution',\n title: 'Run duration',\n data: { provider: 'agent.runs.duration' },\n markers: ['p50', 'p95'],\n format: 'duration',\n },\n {\n kind: 'breakdown',\n title: 'Run errors',\n data: { provider: 'agent.runs.errors' },\n style: 'donut',\n },\n ],\n },\n {\n title: 'Runs',\n panels: [\n {\n kind: 'table',\n title: 'Runs by agent',\n data: { provider: 'agent.runs.byAgent' },\n columns: [\n { key: 'agentName', label: 'Agent' },\n { key: 'runs', label: 'Runs' },\n { key: 'failed', label: 'Failed' },\n { key: 'retries', label: 'Retries' },\n ],\n },\n {\n kind: 'table',\n title: 'Recent runs',\n data: { provider: 'agent.runs.recent' },\n columns: [\n { key: 'startedAt', label: 'Started' },\n col('runId', 'Run', opts.runHref),\n col('threadId', 'Thread', opts.threadHref),\n { key: 'actorRef', label: 'Actor' },\n { key: 'agentName', label: 'Agent' },\n { key: 'status', label: 'Status' },\n { key: 'durationMs', label: 'Duration (ms)' },\n { key: 'retries', label: 'Retries' },\n { key: 'errorCode', label: 'Error code' },\n { key: 'errorMessage', label: 'Error' },\n { key: 'promptHash', label: 'Prompt' },\n ],\n },\n ],\n },\n {\n title: 'Spend',\n cols: 2,\n panels: [\n {\n kind: 'stat',\n title: 'Total spend (USD)',\n data: { provider: 'agent.spend.totalCost' },\n format: 'number',\n },\n {\n kind: 'stat',\n title: 'Total tokens',\n data: { provider: 'agent.spend.totalTokens' },\n format: 'number',\n },\n {\n kind: 'breakdown',\n title: 'Spend by model',\n data: { provider: 'agent.spend.byModel' },\n style: 'donut',\n },\n {\n kind: 'timeseries',\n title: 'Daily spend & tokens',\n data: { provider: 'agent.usage.trend' },\n series: ['costUsd', 'totalTokens'],\n style: 'area',\n },\n ],\n },\n {\n title: 'Models',\n panels: [\n {\n kind: 'table',\n title: 'Usage & cost by model',\n data: { provider: 'agent.spend.byModelTable' },\n columns: [\n { key: 'modelId', label: 'Model' },\n { key: 'requests', label: 'Requests' },\n { key: 'inputTokens', label: 'Input tokens' },\n { key: 'outputTokens', label: 'Output tokens' },\n { key: 'costUsd', label: 'Cost (USD)' },\n ],\n },\n ],\n },\n {\n title: 'Actors',\n cols: 2,\n panels: [\n {\n kind: 'breakdown',\n title: 'Spend share by actor',\n data: { provider: 'agent.spend.byActorShare' },\n style: 'bar',\n },\n {\n kind: 'table',\n title: 'Spend by actor',\n data: { provider: 'agent.spend.byActor' },\n columns: [\n { key: 'actorRef', label: 'Actor' },\n { key: 'requests', label: 'Requests' },\n { key: 'totalTokens', label: 'Tokens' },\n { key: 'costUsd', label: 'Cost (USD)' },\n ],\n },\n ],\n },\n {\n title: 'Threads',\n cols: 2,\n panels: [\n {\n kind: 'table',\n title: 'Top threads by cost',\n data: { provider: 'agent.threads.topSpend' },\n columns: [\n { key: 'title', label: 'Thread' },\n { key: 'actorRef', label: 'Actor' },\n { key: 'requests', label: 'Requests' },\n { key: 'totalTokens', label: 'Tokens' },\n { key: 'costUsd', label: 'Cost (USD)' },\n ],\n },\n {\n kind: 'table',\n title: 'Recently active threads',\n data: { provider: 'agent.threads.recent' },\n columns: [\n col('threadId', 'Thread', opts.threadHref),\n { key: 'title', label: 'Title' },\n { key: 'actorRef', label: 'Actor' },\n { key: 'messageCount', label: 'Messages' },\n { key: 'totalTokens', label: 'Tokens' },\n { key: 'lastActivityAt', label: 'Last activity' },\n ],\n },\n ],\n },\n {\n title: 'Approvals',\n cols: 3,\n panels: [\n {\n kind: 'stat',\n title: 'Pending approvals',\n data: { provider: 'agent.approvals.pending' },\n },\n {\n kind: 'table',\n title: 'Approvals inbox',\n data: { provider: 'agent.approvals.recent' },\n columns: [\n { key: 'requestedAt', label: 'Requested' },\n { key: 'toolName', label: 'Tool' },\n { key: 'threadTitle', label: 'Thread' },\n col('threadId', 'Thread id', opts.threadHref),\n { key: 'actorRef', label: 'Actor' },\n { key: 'agentName', label: 'Agent' },\n ],\n },\n ],\n },\n {\n title: 'Tools',\n cols: 2,\n panels: [\n {\n kind: 'breakdown',\n title: 'Tool-call status',\n data: { provider: 'agent.toolStatus' },\n style: 'donut',\n },\n {\n kind: 'table',\n title: 'Tool stats',\n data: { provider: 'agent.tools.stats' },\n columns: [\n { key: 'toolName', label: 'Tool' },\n { key: 'toolType', label: 'Type' },\n { key: 'calls', label: 'Calls' },\n { key: 'failed', label: 'Failed' },\n { key: 'rejected', label: 'Rejected' },\n { key: 'p95ExecutionMs', label: 'p95 (ms)' },\n ],\n },\n {\n kind: 'table',\n title: 'Recent tool calls',\n data: { provider: 'agent.tools.recent' },\n columns: [\n { key: 'createdAt', label: 'When' },\n { key: 'toolName', label: 'Tool' },\n { key: 'toolType', label: 'Type' },\n { key: 'status', label: 'Status' },\n col('threadId', 'Thread', opts.threadHref),\n ],\n },\n ],\n },\n ],\n };\n}\n","import type { DataProvider, ExtensionContext } from '@dudousxd/nestjs-telescope';\nimport { TELESCOPE_STORAGE } from '@dudousxd/nestjs-telescope';\n\ninterface AgentEntryContent {\n event: string;\n runId?: string;\n threadId?: string;\n toolName?: string;\n toolType?: string;\n status?: string;\n steps?: number;\n inputTokens?: number;\n outputTokens?: number;\n}\n\ninterface StorageEntry {\n content?: AgentEntryContent;\n createdAt?: Date;\n}\n\nasync function fetchEntries(ctx: ExtensionContext): Promise<StorageEntry[]> {\n const storage = ctx.moduleRef.get(TELESCOPE_STORAGE, { strict: false }) as {\n get(query: { type?: string; limit?: number }): Promise<{ data: StorageEntry[] }>;\n };\n const page = await storage.get({ type: 'agent', limit: 5_000 });\n return page.data;\n}\n\nfunction ofEvent(entries: StorageEntry[], event: string): StorageEntry[] {\n return entries.filter((entry) => entry.content?.event === event);\n}\n\n/** stat → total agent runs (run.finished entries). */\nexport function agentRunsProvider(): DataProvider {\n return {\n name: 'agent.runs',\n async resolve(_query, ctx) {\n const finished = ofEvent(await fetchEntries(ctx), 'run.finished');\n return { value: finished.length };\n },\n };\n}\n\n/** stat → total tokens across all finished runs. */\nexport function agentTokensProvider(): DataProvider {\n return {\n name: 'agent.tokens',\n async resolve(_query, ctx) {\n const finished = ofEvent(await fetchEntries(ctx), 'run.finished');\n const value = finished.reduce(\n (sum, entry) =>\n sum + (entry.content?.inputTokens ?? 0) + (entry.content?.outputTokens ?? 0),\n 0,\n );\n return { value };\n },\n };\n}\n\n/**\n * table → recent tool calls, from Telescope's own ephemeral event storage.\n *\n * @deprecated Superseded in the shipped dashboard by `agentRecentToolCallsTableProvider`\n * (`agent.tools.recent`, in `agent-governance-providers.ts`), which reads the durable,\n * restart-surviving `AGENT_GOVERNANCE_QUERIES.recentToolCalls` read-model. That durable route is\n * never behind this ephemeral one: `agent-loop.ts` always awaits `store.recordToolCall` /\n * `store.updateToolCall` (the durable write) BEFORE calling `publishAgentToolCall` (the event this\n * provider reads), so a row is durably queryable strictly before the ephemeral entry exists. The\n * durable route also captures the `pending_approval` state this ephemeral channel never emits at\n * all (no `publishAgentToolCall` call sits between `recordToolCall(status: 'pending_approval')`\n * and the eventual terminal transition) — so there's no in-flight state left for this table to\n * uniquely show. Kept exported (not removed — that would be a breaking export change) for hosts\n * that use `agentTelescopeExtension()` without wiring `AGENT_GOVERNANCE_QUERIES`, or that compose\n * a custom extension from these lower-level provider functions directly.\n */\nexport function agentToolsProvider(): DataProvider {\n return {\n name: 'agent.tools',\n async resolve(_query, ctx) {\n const calls = ofEvent(await fetchEntries(ctx), 'tool-call')\n .slice(-50)\n .reverse()\n .map((entry) => ({\n toolName: entry.content?.toolName ?? '',\n toolType: entry.content?.toolType ?? '',\n status: entry.content?.status ?? '',\n runId: entry.content?.runId ?? '',\n }));\n return { rows: calls };\n },\n };\n}\n\n/** breakdown → tool-call status distribution. */\nexport function agentToolStatusProvider(): DataProvider {\n return {\n name: 'agent.toolStatus',\n async resolve(_query, ctx) {\n const calls = ofEvent(await fetchEntries(ctx), 'tool-call');\n const counts = new Map<string, number>();\n for (const call of calls) {\n const status = call.content?.status ?? 'unknown';\n counts.set(status, (counts.get(status) ?? 0) + 1);\n }\n return { segments: [...counts.entries()].map(([label, value]) => ({ label, value })) };\n },\n };\n}\n","import type {\n ActorSpendRow,\n AgentGovernanceQueries,\n GovernanceRange,\n ModelSpendRow,\n PendingApprovalRow,\n RecentRunRow,\n RunAgentBreakdownRow,\n RunErrorBreakdownRow,\n RunMetrics,\n RunTrendPoint,\n ThreadActivityRow,\n ThreadSpendRow,\n ToolCallActivityRow,\n ToolStatRow,\n UsageTrendPoint,\n} from '@dudousxd/nestjs-agent-core';\nimport { AGENT_GOVERNANCE_QUERIES } from '@dudousxd/nestjs-agent-core';\nimport type { DataProvider, ExtensionContext } from '@dudousxd/nestjs-telescope';\n\n/**\n * Governance data providers for the \"Agent\" Telescope tab: spend/usage, run reliability, tool\n * activity, and the cross-thread approvals inbox. Unlike the live watcher-fed providers in\n * `agent-data-providers.ts` (which read the ephemeral Telescope event storage), these read the\n * authoritative, restart-surviving read-model: `AGENT_GOVERNANCE_QUERIES` (usage ⋈ pricing, plus\n * run/tool-call/thread history).\n *\n * The read-model is resolved from the host's DI container via `ctx.moduleRef` — the exact same\n * mechanism the existing providers use for `TELESCOPE_STORAGE`. The host must bind\n * `AGENT_GOVERNANCE_QUERIES` (from its store adapter) in the same module that registers Telescope;\n * when the binding is absent every provider degrades to an empty-but-valid shape rather than throwing.\n */\n\n/** Default trailing window (in days, inclusive) when a panel query omits an explicit range. */\nconst DEFAULT_TREND_WINDOW_DAYS = 30;\n\nconst ISO_DAY_PATTERN = /^\\d{4}-\\d{2}-\\d{2}$/;\n\n/** A breakdown-panel segment (Telescope core: `{ segments: Array<{ label, value, color? }> }`). */\ninterface BreakdownSegment {\n label: string;\n value: number;\n}\n\n/** One row of the per-model usage/cost table. */\ninterface ModelSpendTableRow {\n modelId: string;\n requests: number;\n inputTokens: number;\n outputTokens: number;\n costUsd: number;\n}\n\n/** One row of the per-actor spend table. */\ninterface ActorSpendTableRow {\n actorRef: string;\n requests: number;\n totalTokens: number;\n costUsd: number;\n}\n\n/** One row of the top-threads-by-cost table. */\ninterface ThreadSpendTableRow {\n title: string;\n actorRef: string;\n requests: number;\n totalTokens: number;\n costUsd: number;\n}\n\n/** Top threads by cost within the range, capped to this count. */\nconst TOP_THREADS_LIMIT = 10;\n\n/** One point of the timeseries trend (Telescope core: `{ label } & Record<string, number>`). */\ninterface UsageTrendTableRow {\n label: string;\n costUsd: number;\n totalTokens: number;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null;\n}\n\n/** Structural guard so the DI-resolved binding is narrowed without an `as`/`any` cast. */\nfunction isGovernanceQueries(value: unknown): value is AgentGovernanceQueries {\n return (\n isRecord(value) &&\n typeof value.spendByModel === 'function' &&\n typeof value.spendByActor === 'function' &&\n typeof value.spendByThread === 'function' &&\n typeof value.usageTrend === 'function' &&\n typeof value.recentToolCalls === 'function' &&\n typeof value.recentThreads === 'function' &&\n typeof value.runMetrics === 'function' &&\n typeof value.runsByAgent === 'function' &&\n typeof value.runErrors === 'function' &&\n typeof value.runTrend === 'function' &&\n typeof value.recentRuns === 'function' &&\n typeof value.pendingApprovals === 'function' &&\n typeof value.toolStats === 'function'\n );\n}\n\n/**\n * Resolve the governance read-model from the host container. Returns `null` when the host has not\n * bound `AGENT_GOVERNANCE_QUERIES` (missing token throws inside `moduleRef.get`) so panels can render\n * an empty state instead of erroring.\n */\nfunction resolveGovernanceQueries(ctx: ExtensionContext): AgentGovernanceQueries | null {\n let resolved: unknown;\n try {\n resolved = ctx.moduleRef.get(AGENT_GOVERNANCE_QUERIES, { strict: false });\n } catch {\n return null;\n }\n return isGovernanceQueries(resolved) ? resolved : null;\n}\n\nfunction isIsoDay(value: unknown): value is string {\n return typeof value === 'string' && ISO_DAY_PATTERN.test(value);\n}\n\nfunction todayUtcDay(): string {\n return new Date().toISOString().slice(0, 10);\n}\n\n/** Shift a `YYYY-MM-DD` UTC day by `deltaDays` (negative goes back in time). */\nexport function shiftUtcDay(day: string, deltaDays: number): string {\n const shifted = new Date(`${day}T00:00:00.000Z`);\n shifted.setUTCDate(shifted.getUTCDate() + deltaDays);\n return shifted.toISOString().slice(0, 10);\n}\n\n/**\n * Derive the query range: honour explicit `fromDay`/`toDay` (validated ISO days), otherwise default\n * to the trailing {@link DEFAULT_TREND_WINDOW_DAYS}-day window ending today (UTC).\n */\nexport function resolveRange(query: Record<string, unknown> | undefined): GovernanceRange {\n const toDay = query && isIsoDay(query.toDay) ? query.toDay : todayUtcDay();\n const fromDay =\n query && isIsoDay(query.fromDay)\n ? query.fromDay\n : shiftUtcDay(toDay, -(DEFAULT_TREND_WINDOW_DAYS - 1));\n return { fromDay, toDay };\n}\n\nfunction roundCents(value: number): number {\n return Math.round(value * 100) / 100;\n}\n\n/** Sum authoritative spend across every model row. */\nexport function totalCostUsd(rows: ModelSpendRow[]): number {\n return roundCents(rows.reduce((sum, row) => sum + row.costUsd, 0));\n}\n\n/** Sum input + output tokens across every model row. */\nexport function totalTokens(rows: ModelSpendRow[]): number {\n return rows.reduce((sum, row) => sum + row.inputTokens + row.outputTokens, 0);\n}\n\n/** Spend-by-model as breakdown segments (models with zero cost are dropped from the donut). */\nexport function toModelSpendSegments(rows: ModelSpendRow[]): BreakdownSegment[] {\n return rows\n .filter((row) => row.costUsd > 0)\n .map((row) => ({ label: row.modelId, value: roundCents(row.costUsd) }));\n}\n\n/** Spend-by-model as table rows (cost rounded to cents; usage kept exact). */\nexport function toModelSpendRows(rows: ModelSpendRow[]): ModelSpendTableRow[] {\n return rows.map((row) => ({\n modelId: row.modelId,\n requests: row.requests,\n inputTokens: row.inputTokens,\n outputTokens: row.outputTokens,\n costUsd: roundCents(row.costUsd),\n }));\n}\n\n/** Spend-by-actor as table rows. */\nexport function toActorSpendRows(rows: ActorSpendRow[]): ActorSpendTableRow[] {\n return rows.map((row) => ({\n actorRef: row.actorRef,\n requests: row.requests,\n totalTokens: row.totalTokens,\n costUsd: roundCents(row.costUsd),\n }));\n}\n\n/** Top-threads-by-cost as table rows. */\nexport function toThreadSpendRows(rows: ThreadSpendRow[]): ThreadSpendTableRow[] {\n return rows.map((row) => ({\n title: row.title || row.threadId,\n actorRef: row.actorRef,\n requests: row.requests,\n totalTokens: row.totalTokens,\n costUsd: roundCents(row.costUsd),\n }));\n}\n\n/** Spend-by-actor as breakdown segments (actors with zero cost are dropped). */\nexport function toActorSpendSegments(rows: ActorSpendRow[]): BreakdownSegment[] {\n return rows\n .filter((row) => row.costUsd > 0)\n .map((row) => ({ label: row.actorRef, value: roundCents(row.costUsd) }));\n}\n\n/** Daily usage trend as timeseries rows keyed by `label` (the day). */\nexport function toUsageTrendRows(points: UsageTrendPoint[]): UsageTrendTableRow[] {\n return points.map((point) => ({\n label: point.day,\n costUsd: roundCents(point.costUsd),\n totalTokens: point.totalTokens,\n }));\n}\n\n// ─── Run reliability + tools + approvals shaping ─────────────────────────────\n\n/** Placeholder shown for a table cell whose source value is `null`/unmeasured — matches the\n * convention `@dudousxd/nestjs-durable-telescope` uses for the same case (e.g. `fmtNum`). */\nconst NO_VALUE = '—';\n\n/** Run/failure/retry rollup as table rows — `RunAgentBreakdownRow` is already table-shaped. */\nexport function toRunAgentTableRows(\n rows: RunAgentBreakdownRow[],\n): Array<{ agentName: string; runs: number; failed: number; retries: number }> {\n return rows.map((row) => ({\n agentName: row.agentName,\n runs: row.runs,\n failed: row.failed,\n retries: row.retries,\n }));\n}\n\n/** Failed-run counts by error code as breakdown segments. */\nexport function toRunErrorSegments(rows: RunErrorBreakdownRow[]): BreakdownSegment[] {\n return rows.map((row) => ({ label: row.errorCode, value: row.count }));\n}\n\n/** One point of the run/failure trend (Telescope core: `{ label } & Record<string, number>`). */\ninterface RunTrendTableRow {\n label: string;\n runs: number;\n failed: number;\n}\n\n/** Daily run/failure trend as timeseries rows keyed by `label` (the day). */\nexport function toRunTrendRows(points: RunTrendPoint[]): RunTrendTableRow[] {\n return points.map((point) => ({ label: point.day, runs: point.runs, failed: point.failed }));\n}\n\n/** Cap this many characters before a byte length; matches the DB column's practical display width. */\nconst ERROR_MESSAGE_CAP = 500;\n\n/**\n * Cap a run's error message to {@link ERROR_MESSAGE_CAP} characters before it leaves the provider.\n * `DataProvider.resolve` output bypasses Telescope core's `redact()` pipeline — that only runs on\n * entries a `Watcher` records via `ctx.record`, not on values a provider computes and returns\n * directly to a panel — so an unbounded stack trace or secret-laden failure message would ride\n * straight into a table cell with no truncation/redaction safety net. This cap is a stopgap\n * mitigation, not a substitute for the (out-of-scope this wave) telescope-core redaction hook for\n * DataProvider output.\n */\nexport function capErrorMessage(message: string | null): string | null {\n if (message === null) return null;\n return message.length > ERROR_MESSAGE_CAP ? `${message.slice(0, ERROR_MESSAGE_CAP)}…` : message;\n}\n\n/** How many leading hex characters of a promptHash the table shows as a short chip. */\nconst PROMPT_HASH_CHIP_LENGTH = 10;\n\n/** Shorten a full sha256 promptHash to a compact chip for the table column. */\nexport function shortPromptHash(promptHash: string | null): string | null {\n return promptHash === null ? null : promptHash.slice(0, PROMPT_HASH_CHIP_LENGTH);\n}\n\n/** One row of the recent-runs table — every nullable field falls back to {@link NO_VALUE}. */\ninterface RecentRunTableRow {\n startedAt: string;\n runId: string;\n threadId: string;\n actorRef: string;\n agentName: string;\n status: string;\n durationMs: number | string;\n retries: number;\n errorCode: string;\n errorMessage: string;\n promptHash: string;\n}\n\n/** Recent runs as table rows: errorMessage capped, promptHash shortened to a chip. */\nexport function toRecentRunTableRows(rows: RecentRunRow[]): RecentRunTableRow[] {\n return rows.map((row) => ({\n startedAt: row.startedAt,\n runId: row.runId,\n threadId: row.threadId,\n actorRef: row.actorRef,\n agentName: row.agentName ?? NO_VALUE,\n status: row.status,\n durationMs: row.durationMs ?? NO_VALUE,\n retries: row.retries,\n errorCode: row.errorCode ?? NO_VALUE,\n errorMessage: capErrorMessage(row.errorMessage) ?? NO_VALUE,\n promptHash: shortPromptHash(row.promptHash) ?? NO_VALUE,\n }));\n}\n\n/** Recent tool calls as table rows — `ToolCallActivityRow` is already table-shaped. */\nexport function toRecentToolCallRows(rows: ToolCallActivityRow[]): ToolCallActivityRow[] {\n return rows;\n}\n\n/** Recent threads as table rows — `ThreadActivityRow` is already table-shaped. */\nexport function toRecentThreadTableRows(rows: ThreadActivityRow[]): ThreadActivityRow[] {\n return rows;\n}\n\n/** One row of the pending-approvals inbox table, `input` stringified for display. */\ninterface PendingApprovalTableRow {\n toolCallId: string;\n toolName: string;\n threadId: string;\n threadTitle: string;\n actorRef: string;\n agentName: string;\n requestedAt: string;\n}\n\n/** Pending-approvals rows as table rows (drops the raw `input` — not renderable in a table cell). */\nexport function toPendingApprovalTableRows(rows: PendingApprovalRow[]): PendingApprovalTableRow[] {\n return rows.map((row) => ({\n toolCallId: row.toolCallId,\n toolName: row.toolName,\n threadId: row.threadId,\n threadTitle: row.threadTitle,\n actorRef: row.actorRef,\n agentName: row.agentName ?? NO_VALUE,\n requestedAt: row.requestedAt,\n }));\n}\n\n/** One row of the per-tool stats table, `p95ExecutionMs` falling back to {@link NO_VALUE}. */\ninterface ToolStatTableRow {\n toolName: string;\n toolType: string;\n calls: number;\n failed: number;\n rejected: number;\n p95ExecutionMs: number | string;\n}\n\n/** Per-tool call/failure/rejection/latency rollup as table rows. */\nexport function toToolStatTableRows(rows: ToolStatRow[]): ToolStatTableRow[] {\n return rows.map((row) => ({\n toolName: row.toolName,\n toolType: row.toolType,\n calls: row.calls,\n failed: row.failed,\n rejected: row.rejected,\n p95ExecutionMs: row.p95ExecutionMs ?? NO_VALUE,\n }));\n}\n\n/** Zero-valued `RunMetrics`, returned when the read-model isn't bound. */\nconst EMPTY_RUN_METRICS: RunMetrics = {\n runs: 0,\n completed: 0,\n failed: 0,\n successRate: 0,\n retries: 0,\n durationP50Ms: null,\n durationP95Ms: null,\n};\n\n/**\n * Build a governance `DataProvider` from a fetch + a format step. Every provider follows the same\n * shape: resolve the read-model, run ONE query over the panel's range, then format the rows into the\n * panel's result shape. When the host hasn't bound the read-model, `fetch` is skipped and `format`\n * runs over `[]` — which is exactly the empty-but-valid shape each formatter already yields (0 for\n * totals, `[]` for segments/rows), so the degraded case needs no special-casing.\n */\nfunction governanceStatProvider<TRow>(\n name: string,\n fetch: (queries: AgentGovernanceQueries, range: GovernanceRange) => Promise<TRow[]>,\n format: (rows: TRow[]) => unknown,\n): DataProvider {\n return {\n name,\n async resolve(query, ctx) {\n const queries = resolveGovernanceQueries(ctx);\n const rows = queries ? await fetch(queries, resolveRange(query)) : [];\n return format(rows);\n },\n };\n}\n\n/** stat → authoritative total spend (USD) over the range. */\nexport function agentSpendTotalProvider(): DataProvider {\n return governanceStatProvider(\n 'agent.spend.totalCost',\n (queries, range) => queries.spendByModel(range),\n (rows) => ({ value: totalCostUsd(rows) }),\n );\n}\n\n/** stat → authoritative total tokens (input + output) over the range. */\nexport function agentTokensTotalProvider(): DataProvider {\n return governanceStatProvider(\n 'agent.spend.totalTokens',\n (queries, range) => queries.spendByModel(range),\n (rows) => ({ value: totalTokens(rows) }),\n );\n}\n\n/** breakdown → spend share per model. */\nexport function agentSpendByModelProvider(): DataProvider {\n return governanceStatProvider(\n 'agent.spend.byModel',\n (queries, range) => queries.spendByModel(range),\n (rows) => ({ segments: toModelSpendSegments(rows) }),\n );\n}\n\n/** table → per-model requests / in+out tokens / cost. */\nexport function agentModelSpendTableProvider(): DataProvider {\n return governanceStatProvider(\n 'agent.spend.byModelTable',\n (queries, range) => queries.spendByModel(range),\n (rows) => ({ rows: toModelSpendRows(rows) }),\n );\n}\n\n/** timeseries → daily spend + tokens trend. */\nexport function agentUsageTrendProvider(): DataProvider {\n return governanceStatProvider(\n 'agent.usage.trend',\n (queries, range) => queries.usageTrend(range),\n (points) => ({ rows: toUsageTrendRows(points) }),\n );\n}\n\n/** table → spend per acting ref (user/tenant). */\nexport function agentActorSpendTableProvider(): DataProvider {\n return governanceStatProvider(\n 'agent.spend.byActor',\n (queries, range) => queries.spendByActor(range),\n (rows) => ({ rows: toActorSpendRows(rows) }),\n );\n}\n\n/** breakdown → spend share per actor. */\nexport function agentSpendByActorProvider(): DataProvider {\n return governanceStatProvider(\n 'agent.spend.byActorShare',\n (queries, range) => queries.spendByActor(range),\n (rows) => ({ segments: toActorSpendSegments(rows) }),\n );\n}\n\n/** table → top threads by cost (title, actor, requests, tokens, cost). */\nexport function agentTopThreadsTableProvider(): DataProvider {\n return governanceStatProvider(\n 'agent.threads.topSpend',\n (queries, range) => queries.spendByThread(range, TOP_THREADS_LIMIT),\n (rows) => ({ rows: toThreadSpendRows(rows) }),\n );\n}\n\n// ─── Reliability providers ────────────────────────────────────────────────────\n\n/**\n * Build a `DataProvider` from ONE range-scoped `runMetrics` call + a format step — the\n * `governanceStatProvider` pattern specialized for the single-object `RunMetrics` shape (the five\n * reliability stats all reuse the same underlying query, exactly like the spend stats above reuse\n * `spendByModel`). Degrades to {@link EMPTY_RUN_METRICS} when the read-model isn't bound.\n */\nfunction governanceRunMetricsProvider(\n name: string,\n format: (metrics: RunMetrics) => unknown,\n): DataProvider {\n return {\n name,\n async resolve(query, ctx) {\n const queries = resolveGovernanceQueries(ctx);\n const metrics = queries ? await queries.runMetrics(resolveRange(query)) : EMPTY_RUN_METRICS;\n return format(metrics);\n },\n };\n}\n\n/** stat → total runs over the range. */\nexport function agentRunsTotalProvider(): DataProvider {\n return governanceRunMetricsProvider('agent.runs.total', (metrics) => ({ value: metrics.runs }));\n}\n\n/** stat → completed/total success rate over the range. */\nexport function agentRunsSuccessRateProvider(): DataProvider {\n return governanceRunMetricsProvider('agent.runs.successRate', (metrics) => ({\n value: metrics.successRate,\n }));\n}\n\n/** stat → failed run count over the range. */\nexport function agentRunsFailedProvider(): DataProvider {\n return governanceRunMetricsProvider('agent.runs.failed', (metrics) => ({\n value: metrics.failed,\n }));\n}\n\n/** stat → total llm-step retries across the range's runs. */\nexport function agentRunsRetriesProvider(): DataProvider {\n return governanceRunMetricsProvider('agent.runs.retries', (metrics) => ({\n value: metrics.retries,\n }));\n}\n\n/**\n * distribution → run duration. `RunMetrics` exposes only the two percentiles (no raw per-run\n * samples), so there is nothing to bucket into a histogram — the panel renders its `p50`/`p95`\n * markers over an empty bucket series. `exactOptionalPropertyTypes` means a `null` percentile is\n * omitted from the result rather than carried as an explicit `undefined`.\n */\nexport function agentRunsDurationProvider(): DataProvider {\n return governanceRunMetricsProvider('agent.runs.duration', (metrics) => ({\n buckets: [],\n ...(metrics.durationP50Ms !== null ? { p50: metrics.durationP50Ms } : {}),\n ...(metrics.durationP95Ms !== null ? { p95: metrics.durationP95Ms } : {}),\n }));\n}\n\n/** table → run/failure/retry rollup per agent. */\nexport function agentRunsByAgentTableProvider(): DataProvider {\n return governanceStatProvider(\n 'agent.runs.byAgent',\n (queries, range) => queries.runsByAgent(range),\n (rows) => ({ rows: toRunAgentTableRows(rows) }),\n );\n}\n\n/** breakdown → failed runs by error code. */\nexport function agentRunErrorsProvider(): DataProvider {\n return governanceStatProvider(\n 'agent.runs.errors',\n (queries, range) => queries.runErrors(range),\n (rows) => ({ segments: toRunErrorSegments(rows) }),\n );\n}\n\n/** timeseries → daily runs + failures trend. */\nexport function agentRunsTrendProvider(): DataProvider {\n return governanceStatProvider(\n 'agent.runs.trend',\n (queries, range) => queries.runTrend(range),\n (points) => ({ rows: toRunTrendRows(points) }),\n );\n}\n\n// ─── Limit-scoped providers (recent-activity feeds + the approvals inbox) ────\n\n/** Default row count for a \"recent …\" feed when a panel's query omits `limit`. */\nconst DEFAULT_RECENT_LIMIT = 50;\n/** Hard ceiling on `limit`, regardless of what a panel's query requests. */\nconst MAX_RECENT_LIMIT = 500;\n\n/** Clamp a panel-supplied `limit` into `[1, MAX_RECENT_LIMIT]`, defaulting when absent/invalid. */\nfunction resolveLimit(query: Record<string, unknown> | undefined, fallback: number): number {\n const raw = query?.limit;\n const value = typeof raw === 'number' && Number.isFinite(raw) ? raw : fallback;\n return Math.min(MAX_RECENT_LIMIT, Math.max(1, Math.trunc(value)));\n}\n\n/**\n * Build a governance `DataProvider` from a `limit`-scoped fetch + a format step — the sibling of\n * {@link governanceStatProvider} for the read-model's \"recent N\" queries, which take a row cap\n * instead of a day range. Degrades to `[]` when the read-model isn't bound.\n */\nfunction governanceLimitProvider<TRow>(\n name: string,\n defaultLimit: number,\n fetch: (queries: AgentGovernanceQueries, limit: number) => Promise<TRow[]>,\n format: (rows: TRow[]) => unknown,\n): DataProvider {\n return {\n name,\n async resolve(query, ctx) {\n const queries = resolveGovernanceQueries(ctx);\n const rows = queries ? await fetch(queries, resolveLimit(query, defaultLimit)) : [];\n return format(rows);\n },\n };\n}\n\n/**\n * table → most recent runs (newest first), errorMessage capped and promptHash shortened to a chip\n * — see {@link capErrorMessage} for why the cap happens here rather than downstream.\n */\nexport function agentRecentRunsTableProvider(): DataProvider {\n return governanceLimitProvider(\n 'agent.runs.recent',\n DEFAULT_RECENT_LIMIT,\n (queries, limit) => queries.recentRuns(limit),\n (rows) => ({ rows: toRecentRunTableRows(rows) }),\n );\n}\n\n/**\n * table → most recent tool calls (newest first), from the durable read-model. Replaces the\n * ephemeral, watcher-fed `agent.tools` provider in `agent-data-providers.ts` for the shipped\n * dashboard — see that file's header comment for why.\n */\nexport function agentRecentToolCallsTableProvider(): DataProvider {\n return governanceLimitProvider(\n 'agent.tools.recent',\n DEFAULT_RECENT_LIMIT,\n (queries, limit) => queries.recentToolCalls(limit),\n (rows) => ({ rows: toRecentToolCallRows(rows) }),\n );\n}\n\n/** table → most recently active threads, with rolled-up message/token counts. */\nexport function agentRecentThreadsTableProvider(): DataProvider {\n return governanceLimitProvider(\n 'agent.threads.recent',\n DEFAULT_RECENT_LIMIT,\n (queries, limit) => queries.recentThreads(limit),\n (rows) => ({ rows: toRecentThreadTableRows(rows) }),\n );\n}\n\n/** Row cap used to approximate a \"pending approvals\" COUNT (the SPI only exposes a capped list —\n * see {@link agentPendingApprovalsCountProvider}). */\nconst PENDING_APPROVALS_COUNT_LIMIT = 500;\n\n/**\n * stat → count of tool calls sitting `pending_approval` across every thread. The SPI's\n * `pendingApprovals` only returns a capped list, not a true count, so this undercounts a backlog\n * larger than {@link PENDING_APPROVALS_COUNT_LIMIT} — a backlog that size signals a bigger\n * operational problem than an off-by-N stat, so the approximation is an acceptable tradeoff.\n */\nexport function agentPendingApprovalsCountProvider(): DataProvider {\n return {\n name: 'agent.approvals.pending',\n async resolve(_query, ctx) {\n const queries = resolveGovernanceQueries(ctx);\n const rows = queries ? await queries.pendingApprovals(PENDING_APPROVALS_COUNT_LIMIT) : [];\n return { value: rows.length };\n },\n };\n}\n\n/** table → the pending-approvals inbox, oldest request first. */\nexport function agentPendingApprovalsTableProvider(): DataProvider {\n return governanceLimitProvider(\n 'agent.approvals.recent',\n DEFAULT_RECENT_LIMIT,\n (queries, limit) => queries.pendingApprovals(limit),\n (rows) => ({ rows: toPendingApprovalTableRows(rows) }),\n );\n}\n\n/** table → per-tool call/failure/rejection/latency rollup over the range. */\nexport function agentToolStatsTableProvider(): DataProvider {\n return governanceStatProvider(\n 'agent.tools.stats',\n (queries, range) => queries.toolStats(range),\n (rows) => ({ rows: toToolStatTableRows(rows) }),\n );\n}\n","import { subscribe, unsubscribe } from 'node:diagnostics_channel';\nimport { AGENT_DIAGNOSTIC_EVENTS } from '@dudousxd/nestjs-agent-core';\nimport { channelName } from '@dudousxd/nestjs-diagnostics';\nimport type { Watcher, WatcherContext } from '@dudousxd/nestjs-telescope';\n\ninterface DiagnosticEnvelope {\n event: string;\n payload: Record<string, unknown>;\n}\n\n/**\n * Records `aviary:agent:*` diagnostics events as Telescope entries of type `agent`. It depends\n * only on the diagnostics channel — not on the agent runtime — so it stays fully decoupled.\n *\n * Iterates {@link AGENT_DIAGNOSTIC_EVENTS} (all 8 events on `ChannelRegistry['agent']`) rather\n * than a hand-written literal, so `run.failed`/`delegated`/`retrieved` are recorded and tagged —\n * filterable in the Telescope UI — like every other agent event.\n *\n * **Superseded by `@dudousxd/nestjs-diagnostics-telescope`'s generic watcher,** which\n * auto-captures every `aviary:agent:*` channel registered in the diagnostics registry — prefer\n * that when the generic bridge is already in use; pass `agentDiagnosticKey(event)` keys to its\n * `exclude` option to mute a noisy one. This watcher is kept for standalone use without the\n * diagnostics telescope bridge.\n *\n * Register it with the telescope module's watcher list.\n */\nexport class AgentTelescopeWatcher implements Watcher {\n readonly type = 'agent';\n private readonly disposers: Array<() => void> = [];\n\n register(ctx: WatcherContext): void {\n for (const event of AGENT_DIAGNOSTIC_EVENTS) {\n const channel = channelName('agent', event);\n const onMessage = (message: unknown) => {\n const envelope = message as DiagnosticEnvelope;\n ctx.record({\n type: 'agent',\n content: { event: envelope.event, ...envelope.payload },\n tags: [envelope.event],\n });\n };\n subscribe(channel, onMessage);\n this.disposers.push(() => unsubscribe(channel, onMessage));\n }\n }\n\n /** Detach all channel subscriptions (e.g. on module destroy). */\n dispose(): void {\n while (this.disposers.length) this.disposers.pop()?.();\n }\n}\n"],"mappings":"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","names":["import_nestjs_telescope","col","key","label","href","undefined","link","agentDashboard","opts","id","panels","sections","title","cols","kind","data","provider","format","series","style","markers","columns","runHref","threadHref","fetchEntries","ctx","storage","moduleRef","get","TELESCOPE_STORAGE","strict","page","type","limit","data","ofEvent","entries","event","filter","entry","content","agentRunsProvider","name","resolve","_query","finished","value","length","agentTokensProvider","reduce","sum","inputTokens","outputTokens","agentToolsProvider","calls","slice","reverse","map","toolName","toolType","status","runId","rows","agentToolStatusProvider","counts","Map","call","set","segments","label","DEFAULT_TREND_WINDOW_DAYS","ISO_DAY_PATTERN","TOP_THREADS_LIMIT","isRecord","value","isGovernanceQueries","spendByModel","spendByActor","spendByThread","usageTrend","recentToolCalls","recentThreads","runMetrics","runsByAgent","runErrors","runTrend","recentRuns","pendingApprovals","toolStats","resolveGovernanceQueries","ctx","resolved","moduleRef","get","AGENT_GOVERNANCE_QUERIES","strict","isIsoDay","test","todayUtcDay","Date","toISOString","slice","shiftUtcDay","day","deltaDays","shifted","setUTCDate","getUTCDate","resolveRange","query","toDay","fromDay","roundCents","Math","round","totalCostUsd","rows","reduce","sum","row","costUsd","totalTokens","inputTokens","outputTokens","toModelSpendSegments","filter","map","label","modelId","toModelSpendRows","requests","toActorSpendRows","actorRef","toThreadSpendRows","title","threadId","toActorSpendSegments","toUsageTrendRows","points","point","NO_VALUE","toRunAgentTableRows","agentName","runs","failed","retries","toRunErrorSegments","errorCode","count","toRunTrendRows","ERROR_MESSAGE_CAP","capErrorMessage","message","length","PROMPT_HASH_CHIP_LENGTH","shortPromptHash","promptHash","toRecentRunTableRows","startedAt","runId","status","durationMs","errorMessage","toRecentToolCallRows","toRecentThreadTableRows","toPendingApprovalTableRows","toolCallId","toolName","threadTitle","requestedAt","toToolStatTableRows","toolType","calls","rejected","p95ExecutionMs","EMPTY_RUN_METRICS","completed","successRate","durationP50Ms","durationP95Ms","governanceStatProvider","name","fetch","format","resolve","queries","agentSpendTotalProvider","range","agentTokensTotalProvider","agentSpendByModelProvider","segments","agentModelSpendTableProvider","agentUsageTrendProvider","agentActorSpendTableProvider","agentSpendByActorProvider","agentTopThreadsTableProvider","governanceRunMetricsProvider","metrics","agentRunsTotalProvider","agentRunsSuccessRateProvider","agentRunsFailedProvider","agentRunsRetriesProvider","agentRunsDurationProvider","buckets","p50","p95","agentRunsByAgentTableProvider","agentRunErrorsProvider","agentRunsTrendProvider","DEFAULT_RECENT_LIMIT","MAX_RECENT_LIMIT","resolveLimit","fallback","raw","limit","Number","isFinite","min","max","trunc","governanceLimitProvider","defaultLimit","agentRecentRunsTableProvider","agentRecentToolCallsTableProvider","agentRecentThreadsTableProvider","PENDING_APPROVALS_COUNT_LIMIT","agentPendingApprovalsCountProvider","_query","agentPendingApprovalsTableProvider","agentToolStatsTableProvider","import_nestjs_agent_core","AgentTelescopeWatcher","type","disposers","register","ctx","event","AGENT_DIAGNOSTIC_EVENTS","channel","channelName","onMessage","message","envelope","record","content","payload","tags","subscribe","push","unsubscribe","dispose","length","pop","agentTelescopeExtension","opts","defineTelescopeExtension","name","watchers","AgentTelescopeWatcher","entryTypes","id","label","dot","dashboards","agentDashboard","dataProviders","agentRunsProvider","agentTokensProvider","agentToolStatusProvider","agentSpendTotalProvider","agentTokensTotalProvider","agentSpendByModelProvider","agentModelSpendTableProvider","agentUsageTrendProvider","agentActorSpendTableProvider","agentSpendByActorProvider","agentTopThreadsTableProvider","agentRunsTotalProvider","agentRunsSuccessRateProvider","agentRunsFailedProvider","agentRunsRetriesProvider","agentRunsDurationProvider","agentRunsByAgentTableProvider","agentRunErrorsProvider","agentRunsTrendProvider","agentRecentRunsTableProvider","agentRecentToolCallsTableProvider","agentRecentThreadsTableProvider","agentPendingApprovalsCountProvider","agentPendingApprovalsTableProvider","agentToolStatsTableProvider"]}
package/dist/index.d.cts CHANGED
@@ -1,39 +1,90 @@
1
1
  import * as _dudousxd_nestjs_telescope from '@dudousxd/nestjs-telescope';
2
2
  import { Watcher, WatcherContext, DashboardSpec, DataProvider } from '@dudousxd/nestjs-telescope';
3
- import { GovernanceRange, ActorSpendRow, ModelSpendRow, UsageTrendPoint } from '@dudousxd/nestjs-agent-core';
3
+ import { GovernanceRange, ActorSpendRow, ModelSpendRow, PendingApprovalRow, RecentRunRow, ThreadActivityRow, ToolCallActivityRow, RunAgentBreakdownRow, RunErrorBreakdownRow, RunTrendPoint, ThreadSpendRow, ToolStatRow, UsageTrendPoint } from '@dudousxd/nestjs-agent-core';
4
4
 
5
5
  /**
6
6
  * The first-class Telescope extension for nestjs-agent: an "Agent" tab fed by two sources —
7
7
  * the `aviary:agent:*` diagnostics channel (live runs, tool calls) via the watcher, and the
8
- * authoritative `AGENT_GOVERNANCE_QUERIES` read-model (historical spend/usage) via the governance
9
- * providers. The extension `name`, entry-type id, dashboard id, and every provider name share the
10
- * `agent` prefix so the registry's global-uniqueness namespaces never collide with sibling extensions.
8
+ * authoritative `AGENT_GOVERNANCE_QUERIES` read-model (historical spend/usage, run reliability,
9
+ * tool activity, the approvals inbox) via the governance providers. The extension `name`,
10
+ * entry-type id, dashboard id, and every provider name share the `agent` prefix so the registry's
11
+ * global-uniqueness namespaces never collide with sibling extensions.
11
12
  *
12
- * Host wiring: the governance (Spend/Models/Actors) panels resolve `AGENT_GOVERNANCE_QUERIES` from
13
- * the host DI container at request time (via `ctx.moduleRef`). The host must bind that token — from
14
- * its store adapter (e.g. `store-mikro-orm` / `store-drizzle` / `testing`) — in the same module that
15
- * registers `TelescopeModule.forRoot({ extensions: [agentTelescopeExtension()] })`. If the binding is
16
- * absent, those panels render an empty state; the live watcher-fed panels keep working regardless.
13
+ * `threadHref`/`runHref` deep-link a table row's `threadId`/`runId` cell out to the host's own
14
+ * thread/run viewer passed straight through to {@link agentDashboard}, mirroring
15
+ * `durableTelescopeExtension`'s `runHref` option.
16
+ *
17
+ * Host wiring: the governance panels (Spend/Models/Actors/Reliability/Runs/Threads/Approvals/Tool
18
+ * stats/Recent tool calls) resolve `AGENT_GOVERNANCE_QUERIES` from the host DI container at
19
+ * request time (via `ctx.moduleRef`). The host must bind that token — from its store adapter
20
+ * (e.g. `store-mikro-orm` / `store-drizzle` / `testing`) — in the same module that registers
21
+ * `TelescopeModule.forRoot({ extensions: [agentTelescopeExtension()] })`. If the binding is
22
+ * absent, those panels render an empty state; the live watcher-fed panels (Runs/Tokens stats and
23
+ * the Tool-call status breakdown) keep working regardless.
17
24
  */
18
- declare function agentTelescopeExtension(): _dudousxd_nestjs_telescope.TelescopeExtension;
25
+ declare function agentTelescopeExtension(opts?: {
26
+ threadHref?: string;
27
+ runHref?: string;
28
+ }): _dudousxd_nestjs_telescope.TelescopeExtension;
19
29
 
20
30
  /**
21
31
  * Records `aviary:agent:*` diagnostics events as Telescope entries of type `agent`. It depends
22
32
  * only on the diagnostics channel — not on the agent runtime — so it stays fully decoupled.
33
+ *
34
+ * Iterates {@link AGENT_DIAGNOSTIC_EVENTS} (all 8 events on `ChannelRegistry['agent']`) rather
35
+ * than a hand-written literal, so `run.failed`/`delegated`/`retrieved` are recorded and tagged —
36
+ * filterable in the Telescope UI — like every other agent event.
37
+ *
38
+ * **Superseded by `@dudousxd/nestjs-diagnostics-telescope`'s generic watcher,** which
39
+ * auto-captures every `aviary:agent:*` channel registered in the diagnostics registry — prefer
40
+ * that when the generic bridge is already in use; pass `agentDiagnosticKey(event)` keys to its
41
+ * `exclude` option to mute a noisy one. This watcher is kept for standalone use without the
42
+ * diagnostics telescope bridge.
43
+ *
44
+ * Register it with the telescope module's watcher list.
23
45
  */
24
46
  declare class AgentTelescopeWatcher implements Watcher {
25
47
  readonly type = "agent";
48
+ private readonly disposers;
26
49
  register(ctx: WatcherContext): void;
50
+ /** Detach all channel subscriptions (e.g. on module destroy). */
51
+ dispose(): void;
27
52
  }
28
53
 
29
- /** The "Agent" overview dashboard. Panels bind to the `agent.*` data providers. */
30
- declare function agentDashboard(): DashboardSpec;
54
+ /**
55
+ * The "Agent" overview dashboard. Panels bind to the `agent.*` data providers.
56
+ *
57
+ * `threadHref`/`runHref` are URL templates for deep-linking a `{threadId}`/`{runId}` cell out to
58
+ * the host's own thread/run viewer (e.g. the standalone `@dudousxd/nestjs-agent-dashboard` SPA),
59
+ * mirroring `durableTelescopeExtension`'s `runHref` option. Every table whose rows carry a
60
+ * `threadId`/`runId` gets a `Column.link` for it (via {@link col}); omit an option to leave that
61
+ * column plain text.
62
+ */
63
+ declare function agentDashboard(opts?: {
64
+ threadHref?: string;
65
+ runHref?: string;
66
+ }): DashboardSpec;
31
67
 
32
68
  /** stat → total agent runs (run.finished entries). */
33
69
  declare function agentRunsProvider(): DataProvider;
34
70
  /** stat → total tokens across all finished runs. */
35
71
  declare function agentTokensProvider(): DataProvider;
36
- /** table → recent tool calls. */
72
+ /**
73
+ * table → recent tool calls, from Telescope's own ephemeral event storage.
74
+ *
75
+ * @deprecated Superseded in the shipped dashboard by `agentRecentToolCallsTableProvider`
76
+ * (`agent.tools.recent`, in `agent-governance-providers.ts`), which reads the durable,
77
+ * restart-surviving `AGENT_GOVERNANCE_QUERIES.recentToolCalls` read-model. That durable route is
78
+ * never behind this ephemeral one: `agent-loop.ts` always awaits `store.recordToolCall` /
79
+ * `store.updateToolCall` (the durable write) BEFORE calling `publishAgentToolCall` (the event this
80
+ * provider reads), so a row is durably queryable strictly before the ephemeral entry exists. The
81
+ * durable route also captures the `pending_approval` state this ephemeral channel never emits at
82
+ * all (no `publishAgentToolCall` call sits between `recordToolCall(status: 'pending_approval')`
83
+ * and the eventual terminal transition) — so there's no in-flight state left for this table to
84
+ * uniquely show. Kept exported (not removed — that would be a breaking export change) for hosts
85
+ * that use `agentTelescopeExtension()` without wiring `AGENT_GOVERNANCE_QUERIES`, or that compose
86
+ * a custom extension from these lower-level provider functions directly.
87
+ */
37
88
  declare function agentToolsProvider(): DataProvider;
38
89
  /** breakdown → tool-call status distribution. */
39
90
  declare function agentToolStatusProvider(): DataProvider;
@@ -58,6 +109,14 @@ interface ActorSpendTableRow {
58
109
  totalTokens: number;
59
110
  costUsd: number;
60
111
  }
112
+ /** One row of the top-threads-by-cost table. */
113
+ interface ThreadSpendTableRow {
114
+ title: string;
115
+ actorRef: string;
116
+ requests: number;
117
+ totalTokens: number;
118
+ costUsd: number;
119
+ }
61
120
  /** One point of the timeseries trend (Telescope core: `{ label } & Record<string, number>`). */
62
121
  interface UsageTrendTableRow {
63
122
  label: string;
@@ -81,10 +140,84 @@ declare function toModelSpendSegments(rows: ModelSpendRow[]): BreakdownSegment[]
81
140
  declare function toModelSpendRows(rows: ModelSpendRow[]): ModelSpendTableRow[];
82
141
  /** Spend-by-actor as table rows. */
83
142
  declare function toActorSpendRows(rows: ActorSpendRow[]): ActorSpendTableRow[];
143
+ /** Top-threads-by-cost as table rows. */
144
+ declare function toThreadSpendRows(rows: ThreadSpendRow[]): ThreadSpendTableRow[];
84
145
  /** Spend-by-actor as breakdown segments (actors with zero cost are dropped). */
85
146
  declare function toActorSpendSegments(rows: ActorSpendRow[]): BreakdownSegment[];
86
147
  /** Daily usage trend as timeseries rows keyed by `label` (the day). */
87
148
  declare function toUsageTrendRows(points: UsageTrendPoint[]): UsageTrendTableRow[];
149
+ /** Run/failure/retry rollup as table rows — `RunAgentBreakdownRow` is already table-shaped. */
150
+ declare function toRunAgentTableRows(rows: RunAgentBreakdownRow[]): Array<{
151
+ agentName: string;
152
+ runs: number;
153
+ failed: number;
154
+ retries: number;
155
+ }>;
156
+ /** Failed-run counts by error code as breakdown segments. */
157
+ declare function toRunErrorSegments(rows: RunErrorBreakdownRow[]): BreakdownSegment[];
158
+ /** One point of the run/failure trend (Telescope core: `{ label } & Record<string, number>`). */
159
+ interface RunTrendTableRow {
160
+ label: string;
161
+ runs: number;
162
+ failed: number;
163
+ }
164
+ /** Daily run/failure trend as timeseries rows keyed by `label` (the day). */
165
+ declare function toRunTrendRows(points: RunTrendPoint[]): RunTrendTableRow[];
166
+ /**
167
+ * Cap a run's error message to {@link ERROR_MESSAGE_CAP} characters before it leaves the provider.
168
+ * `DataProvider.resolve` output bypasses Telescope core's `redact()` pipeline — that only runs on
169
+ * entries a `Watcher` records via `ctx.record`, not on values a provider computes and returns
170
+ * directly to a panel — so an unbounded stack trace or secret-laden failure message would ride
171
+ * straight into a table cell with no truncation/redaction safety net. This cap is a stopgap
172
+ * mitigation, not a substitute for the (out-of-scope this wave) telescope-core redaction hook for
173
+ * DataProvider output.
174
+ */
175
+ declare function capErrorMessage(message: string | null): string | null;
176
+ /** Shorten a full sha256 promptHash to a compact chip for the table column. */
177
+ declare function shortPromptHash(promptHash: string | null): string | null;
178
+ /** One row of the recent-runs table — every nullable field falls back to {@link NO_VALUE}. */
179
+ interface RecentRunTableRow {
180
+ startedAt: string;
181
+ runId: string;
182
+ threadId: string;
183
+ actorRef: string;
184
+ agentName: string;
185
+ status: string;
186
+ durationMs: number | string;
187
+ retries: number;
188
+ errorCode: string;
189
+ errorMessage: string;
190
+ promptHash: string;
191
+ }
192
+ /** Recent runs as table rows: errorMessage capped, promptHash shortened to a chip. */
193
+ declare function toRecentRunTableRows(rows: RecentRunRow[]): RecentRunTableRow[];
194
+ /** Recent tool calls as table rows — `ToolCallActivityRow` is already table-shaped. */
195
+ declare function toRecentToolCallRows(rows: ToolCallActivityRow[]): ToolCallActivityRow[];
196
+ /** Recent threads as table rows — `ThreadActivityRow` is already table-shaped. */
197
+ declare function toRecentThreadTableRows(rows: ThreadActivityRow[]): ThreadActivityRow[];
198
+ /** One row of the pending-approvals inbox table, `input` stringified for display. */
199
+ interface PendingApprovalTableRow {
200
+ toolCallId: string;
201
+ toolName: string;
202
+ threadId: string;
203
+ threadTitle: string;
204
+ actorRef: string;
205
+ agentName: string;
206
+ requestedAt: string;
207
+ }
208
+ /** Pending-approvals rows as table rows (drops the raw `input` — not renderable in a table cell). */
209
+ declare function toPendingApprovalTableRows(rows: PendingApprovalRow[]): PendingApprovalTableRow[];
210
+ /** One row of the per-tool stats table, `p95ExecutionMs` falling back to {@link NO_VALUE}. */
211
+ interface ToolStatTableRow {
212
+ toolName: string;
213
+ toolType: string;
214
+ calls: number;
215
+ failed: number;
216
+ rejected: number;
217
+ p95ExecutionMs: number | string;
218
+ }
219
+ /** Per-tool call/failure/rejection/latency rollup as table rows. */
220
+ declare function toToolStatTableRows(rows: ToolStatRow[]): ToolStatTableRow[];
88
221
  /** stat → authoritative total spend (USD) over the range. */
89
222
  declare function agentSpendTotalProvider(): DataProvider;
90
223
  /** stat → authoritative total tokens (input + output) over the range. */
@@ -99,5 +232,52 @@ declare function agentUsageTrendProvider(): DataProvider;
99
232
  declare function agentActorSpendTableProvider(): DataProvider;
100
233
  /** breakdown → spend share per actor. */
101
234
  declare function agentSpendByActorProvider(): DataProvider;
235
+ /** table → top threads by cost (title, actor, requests, tokens, cost). */
236
+ declare function agentTopThreadsTableProvider(): DataProvider;
237
+ /** stat → total runs over the range. */
238
+ declare function agentRunsTotalProvider(): DataProvider;
239
+ /** stat → completed/total success rate over the range. */
240
+ declare function agentRunsSuccessRateProvider(): DataProvider;
241
+ /** stat → failed run count over the range. */
242
+ declare function agentRunsFailedProvider(): DataProvider;
243
+ /** stat → total llm-step retries across the range's runs. */
244
+ declare function agentRunsRetriesProvider(): DataProvider;
245
+ /**
246
+ * distribution → run duration. `RunMetrics` exposes only the two percentiles (no raw per-run
247
+ * samples), so there is nothing to bucket into a histogram — the panel renders its `p50`/`p95`
248
+ * markers over an empty bucket series. `exactOptionalPropertyTypes` means a `null` percentile is
249
+ * omitted from the result rather than carried as an explicit `undefined`.
250
+ */
251
+ declare function agentRunsDurationProvider(): DataProvider;
252
+ /** table → run/failure/retry rollup per agent. */
253
+ declare function agentRunsByAgentTableProvider(): DataProvider;
254
+ /** breakdown → failed runs by error code. */
255
+ declare function agentRunErrorsProvider(): DataProvider;
256
+ /** timeseries → daily runs + failures trend. */
257
+ declare function agentRunsTrendProvider(): DataProvider;
258
+ /**
259
+ * table → most recent runs (newest first), errorMessage capped and promptHash shortened to a chip
260
+ * — see {@link capErrorMessage} for why the cap happens here rather than downstream.
261
+ */
262
+ declare function agentRecentRunsTableProvider(): DataProvider;
263
+ /**
264
+ * table → most recent tool calls (newest first), from the durable read-model. Replaces the
265
+ * ephemeral, watcher-fed `agent.tools` provider in `agent-data-providers.ts` for the shipped
266
+ * dashboard — see that file's header comment for why.
267
+ */
268
+ declare function agentRecentToolCallsTableProvider(): DataProvider;
269
+ /** table → most recently active threads, with rolled-up message/token counts. */
270
+ declare function agentRecentThreadsTableProvider(): DataProvider;
271
+ /**
272
+ * stat → count of tool calls sitting `pending_approval` across every thread. The SPI's
273
+ * `pendingApprovals` only returns a capped list, not a true count, so this undercounts a backlog
274
+ * larger than {@link PENDING_APPROVALS_COUNT_LIMIT} — a backlog that size signals a bigger
275
+ * operational problem than an off-by-N stat, so the approximation is an acceptable tradeoff.
276
+ */
277
+ declare function agentPendingApprovalsCountProvider(): DataProvider;
278
+ /** table → the pending-approvals inbox, oldest request first. */
279
+ declare function agentPendingApprovalsTableProvider(): DataProvider;
280
+ /** table → per-tool call/failure/rejection/latency rollup over the range. */
281
+ declare function agentToolStatsTableProvider(): DataProvider;
102
282
 
103
- export { AgentTelescopeWatcher, agentActorSpendTableProvider, agentDashboard, agentModelSpendTableProvider, agentRunsProvider, agentSpendByActorProvider, agentSpendByModelProvider, agentSpendTotalProvider, agentTelescopeExtension, agentTokensProvider, agentTokensTotalProvider, agentToolStatusProvider, agentToolsProvider, agentUsageTrendProvider, resolveRange, shiftUtcDay, toActorSpendRows, toActorSpendSegments, toModelSpendRows, toModelSpendSegments, toUsageTrendRows, totalCostUsd, totalTokens };
283
+ export { AgentTelescopeWatcher, agentActorSpendTableProvider, agentDashboard, agentModelSpendTableProvider, agentPendingApprovalsCountProvider, agentPendingApprovalsTableProvider, agentRecentRunsTableProvider, agentRecentThreadsTableProvider, agentRecentToolCallsTableProvider, agentRunErrorsProvider, agentRunsByAgentTableProvider, agentRunsDurationProvider, agentRunsFailedProvider, agentRunsProvider, agentRunsRetriesProvider, agentRunsSuccessRateProvider, agentRunsTotalProvider, agentRunsTrendProvider, agentSpendByActorProvider, agentSpendByModelProvider, agentSpendTotalProvider, agentTelescopeExtension, agentTokensProvider, agentTokensTotalProvider, agentToolStatsTableProvider, agentToolStatusProvider, agentToolsProvider, agentTopThreadsTableProvider, agentUsageTrendProvider, capErrorMessage, resolveRange, shiftUtcDay, shortPromptHash, toActorSpendRows, toActorSpendSegments, toModelSpendRows, toModelSpendSegments, toPendingApprovalTableRows, toRecentRunTableRows, toRecentThreadTableRows, toRecentToolCallRows, toRunAgentTableRows, toRunErrorSegments, toRunTrendRows, toThreadSpendRows, toToolStatTableRows, toUsageTrendRows, totalCostUsd, totalTokens };