@dudousxd/nestjs-agent-telescope 0.4.0 → 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -153,7 +153,7 @@ function agentDashboard(opts = {}) {
153
153
  },
154
154
  {
155
155
  title: "Run trends",
156
- cols: 3,
156
+ cols: 4,
157
157
  panels: [
158
158
  {
159
159
  kind: "timeseries",
@@ -167,16 +167,28 @@ function agentDashboard(opts = {}) {
167
167
  ],
168
168
  style: "stacked"
169
169
  },
170
+ // Two duration stats, not a `distribution` panel: RunMetrics carries only p50/p95 (no
171
+ // raw samples to bucket), so a histogram here would be a permanently-empty box.
170
172
  {
171
- kind: "distribution",
172
- title: "Run duration",
173
+ kind: "stat",
174
+ title: "Duration p50",
173
175
  data: {
174
- provider: "agent.runs.duration"
176
+ provider: "agent.runs.duration",
177
+ query: {
178
+ metric: "p50"
179
+ }
180
+ },
181
+ format: "duration"
182
+ },
183
+ {
184
+ kind: "stat",
185
+ title: "Duration p95",
186
+ data: {
187
+ provider: "agent.runs.duration",
188
+ query: {
189
+ metric: "p95"
190
+ }
175
191
  },
176
- markers: [
177
- "p50",
178
- "p95"
179
- ],
180
192
  format: "duration"
181
193
  },
182
194
  {
@@ -223,17 +235,15 @@ function agentDashboard(opts = {}) {
223
235
  data: {
224
236
  provider: "agent.runs.recent"
225
237
  },
238
+ // A deliberate SUBSET of the provider's row shape: the full 11-field row overflows the
239
+ // card horizontally. Thread/actor/retries/errorCode detail lives in the standalone
240
+ // agent dashboard; the provider keeps returning the full row for other consumers.
226
241
  columns: [
227
242
  {
228
243
  key: "startedAt",
229
244
  label: "Started"
230
245
  },
231
246
  col("runId", "Run", opts.runHref),
232
- col("threadId", "Thread", opts.threadHref),
233
- {
234
- key: "actorRef",
235
- label: "Actor"
236
- },
237
247
  {
238
248
  key: "agentName",
239
249
  label: "Agent"
@@ -246,14 +256,6 @@ function agentDashboard(opts = {}) {
246
256
  key: "durationMs",
247
257
  label: "Duration (ms)"
248
258
  },
249
- {
250
- key: "retries",
251
- label: "Retries"
252
- },
253
- {
254
- key: "errorCode",
255
- label: "Error code"
256
- },
257
259
  {
258
260
  key: "errorMessage",
259
261
  label: "Error"
@@ -947,15 +949,17 @@ function agentRunsRetriesProvider() {
947
949
  }
948
950
  __name(agentRunsRetriesProvider, "agentRunsRetriesProvider");
949
951
  function agentRunsDurationProvider() {
950
- return governanceRunMetricsProvider("agent.runs.duration", (metrics) => ({
951
- buckets: [],
952
- ...metrics.durationP50Ms !== null ? {
953
- p50: metrics.durationP50Ms
954
- } : {},
955
- ...metrics.durationP95Ms !== null ? {
956
- p95: metrics.durationP95Ms
957
- } : {}
958
- }));
952
+ return {
953
+ name: "agent.runs.duration",
954
+ async resolve(query, ctx) {
955
+ const queries = resolveGovernanceQueries(ctx);
956
+ const metrics = queries ? await queries.runMetrics(resolveRange(query)) : EMPTY_RUN_METRICS;
957
+ const value = query?.metric === "p95" ? metrics.durationP95Ms : metrics.durationP50Ms;
958
+ return {
959
+ value: value ?? 0
960
+ };
961
+ }
962
+ };
959
963
  }
960
964
  __name(agentRunsDurationProvider, "agentRunsDurationProvider");
961
965
  function agentRunsByAgentTableProvider() {
@@ -1051,6 +1055,7 @@ var AgentTelescopeWatcher = class {
1051
1055
  type = "agent";
1052
1056
  disposers = [];
1053
1057
  register(ctx) {
1058
+ this.disposers.push((0, import_nestjs_diagnostics.claimDiagnostics)("agent", import_nestjs_agent_core2.AGENT_DIAGNOSTIC_EVENTS));
1054
1059
  for (const event of import_nestjs_agent_core2.AGENT_DIAGNOSTIC_EVENTS) {
1055
1060
  const channel = (0, import_nestjs_diagnostics.channelName)("agent", event);
1056
1061
  const onMessage = /* @__PURE__ */ __name((message) => {
@@ -1070,7 +1075,7 @@ var AgentTelescopeWatcher = class {
1070
1075
  this.disposers.push(() => (0, import_node_diagnostics_channel.unsubscribe)(channel, onMessage));
1071
1076
  }
1072
1077
  }
1073
- /** Detach all channel subscriptions (e.g. on module destroy). */
1078
+ /** Detach all channel subscriptions and release the diagnostics claim (e.g. on module destroy). */
1074
1079
  dispose() {
1075
1080
  while (this.disposers.length) this.disposers.pop()?.();
1076
1081
  }
@@ -1 +1 @@
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"]}
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: 4,\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 // Two duration stats, not a `distribution` panel: RunMetrics carries only p50/p95 (no\n // raw samples to bucket), so a histogram here would be a permanently-empty box.\n {\n kind: 'stat',\n title: 'Duration p50',\n data: { provider: 'agent.runs.duration', query: { metric: 'p50' } },\n format: 'duration',\n },\n {\n kind: 'stat',\n title: 'Duration p95',\n data: { provider: 'agent.runs.duration', query: { metric: '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 // A deliberate SUBSET of the provider's row shape: the full 11-field row overflows the\n // card horizontally. Thread/actor/retries/errorCode detail lives in the standalone\n // agent dashboard; the provider keeps returning the full row for other consumers.\n columns: [\n { key: 'startedAt', label: 'Started' },\n col('runId', 'Run', opts.runHref),\n { key: 'agentName', label: 'Agent' },\n { key: 'status', label: 'Status' },\n { key: 'durationMs', label: 'Duration (ms)' },\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 * stat → run duration percentile, selected by `query.metric` (`'p95'` for p95, anything else —\n * including omitted — for p50), mirroring `durable.duration`'s stat shortcut. NOT a\n * `distribution` panel: `RunMetrics` exposes only the two percentiles (no raw per-run samples to\n * bucket into a histogram), so a distribution here would render as a permanently-empty box. A\n * `null` percentile (no settled runs in range) resolves to 0.\n */\nexport function agentRunsDurationProvider(): DataProvider {\n return {\n name: 'agent.runs.duration',\n async resolve(query, ctx) {\n const queries = resolveGovernanceQueries(ctx);\n const metrics = queries ? await queries.runMetrics(resolveRange(query)) : EMPTY_RUN_METRICS;\n const value = query?.metric === 'p95' ? metrics.durationP95Ms : metrics.durationP50Ms;\n return { value: value ?? 0 };\n },\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, claimDiagnostics } 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 point events on `ChannelRegistry['agent']`)\n * rather than a hand-written literal, so `run.failed`/`delegated`/`retrieved` are recorded and\n * tagged — filterable in the Telescope UI — like every other agent event.\n *\n * Coexists with `@dudousxd/nestjs-diagnostics-telescope`'s generic watcher: `register()` CLAIMS\n * every recorded key via `claimDiagnostics('agent', ...)` (diagnostics 0.7+), so the generic\n * bridge skips them at record time instead of duplicating each event as a `diagnostic` entry —\n * no `exclude` wiring needed anymore. `dispose()` releases the claim.\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 // Tell the generic diagnostics bridge these keys are recorded here as typed `agent` entries,\n // so it skips them (refcounted; released in dispose()).\n this.disposers.push(claimDiagnostics('agent', AGENT_DIAGNOSTIC_EVENTS));\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 and release the diagnostics claim (e.g. on module destroy). */\n dispose(): void {\n while (this.disposers.length) this.disposers.pop()?.();\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACAA,IAAAA,2BAAyC;;;ACGzC,SAASC,IAAIC,KAAaC,OAAeC,MAAa;AACpD,SAAOA,SAASC,SAAY;IAAEH;IAAKC;IAAOG,MAAM;MAAEF;IAAK;EAAE,IAAI;IAAEF;IAAKC;EAAM;AAC5E;AAFSF;AAaF,SAASM,eACdC,OAAkD,CAAC,GAAC;AAEpD,SAAO;IACLC,IAAI;IACJN,OAAO;IACPO,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;YAAEI,MAAM;YAAQF,OAAO;YAAQG,MAAM;cAAEC,UAAU;YAAmB;UAAE;UACtE;YACEF,MAAM;YACNF,OAAO;YACPG,MAAM;cAAEC,UAAU;YAAyB;YAC3CC,QAAQ;UACV;UACA;YAAEH,MAAM;YAAQF,OAAO;YAAUG,MAAM;cAAEC,UAAU;YAAoB;UAAE;UACzE;YAAEF,MAAM;YAAQF,OAAO;YAAWG,MAAM;cAAEC,UAAU;YAAqB;UAAE;;MAE/E;MACA;QACEJ,OAAO;QACPC,MAAM;QACNH,QAAQ;UACN;YACEI,MAAM;YACNF,OAAO;YACPG,MAAM;cAAEC,UAAU;YAAmB;YACrCE,QAAQ;cAAC;cAAQ;;YACjBC,OAAO;UACT;;;UAGA;YACEL,MAAM;YACNF,OAAO;YACPG,MAAM;cAAEC,UAAU;cAAuBI,OAAO;gBAAEC,QAAQ;cAAM;YAAE;YAClEJ,QAAQ;UACV;UACA;YACEH,MAAM;YACNF,OAAO;YACPG,MAAM;cAAEC,UAAU;cAAuBI,OAAO;gBAAEC,QAAQ;cAAM;YAAE;YAClEJ,QAAQ;UACV;UACA;YACEH,MAAM;YACNF,OAAO;YACPG,MAAM;cAAEC,UAAU;YAAoB;YACtCG,OAAO;UACT;;MAEJ;MACA;QACEP,OAAO;QACPF,QAAQ;UACN;YACEI,MAAM;YACNF,OAAO;YACPG,MAAM;cAAEC,UAAU;YAAqB;YACvCM,SAAS;cACP;gBAAEpB,KAAK;gBAAaC,OAAO;cAAQ;cACnC;gBAAED,KAAK;gBAAQC,OAAO;cAAO;cAC7B;gBAAED,KAAK;gBAAUC,OAAO;cAAS;cACjC;gBAAED,KAAK;gBAAWC,OAAO;cAAU;;UAEvC;UACA;YACEW,MAAM;YACNF,OAAO;YACPG,MAAM;cAAEC,UAAU;YAAoB;;;;YAItCM,SAAS;cACP;gBAAEpB,KAAK;gBAAaC,OAAO;cAAU;cACrCF,IAAI,SAAS,OAAOO,KAAKe,OAAO;cAChC;gBAAErB,KAAK;gBAAaC,OAAO;cAAQ;cACnC;gBAAED,KAAK;gBAAUC,OAAO;cAAS;cACjC;gBAAED,KAAK;gBAAcC,OAAO;cAAgB;cAC5C;gBAAED,KAAK;gBAAgBC,OAAO;cAAQ;cACtC;gBAAED,KAAK;gBAAcC,OAAO;cAAS;;UAEzC;;MAEJ;MACA;QACES,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;YACxCG,OAAO;UACT;UACA;YACEL,MAAM;YACNF,OAAO;YACPG,MAAM;cAAEC,UAAU;YAAoB;YACtCE,QAAQ;cAAC;cAAW;;YACpBC,OAAO;UACT;;MAEJ;MACA;QACEP,OAAO;QACPF,QAAQ;UACN;YACEI,MAAM;YACNF,OAAO;YACPG,MAAM;cAAEC,UAAU;YAA2B;YAC7CM,SAAS;cACP;gBAAEpB,KAAK;gBAAWC,OAAO;cAAQ;cACjC;gBAAED,KAAK;gBAAYC,OAAO;cAAW;cACrC;gBAAED,KAAK;gBAAeC,OAAO;cAAe;cAC5C;gBAAED,KAAK;gBAAgBC,OAAO;cAAgB;cAC9C;gBAAED,KAAK;gBAAWC,OAAO;cAAa;;UAE1C;;MAEJ;MACA;QACES,OAAO;QACPC,MAAM;QACNH,QAAQ;UACN;YACEI,MAAM;YACNF,OAAO;YACPG,MAAM;cAAEC,UAAU;YAA2B;YAC7CG,OAAO;UACT;UACA;YACEL,MAAM;YACNF,OAAO;YACPG,MAAM;cAAEC,UAAU;YAAsB;YACxCM,SAAS;cACP;gBAAEpB,KAAK;gBAAYC,OAAO;cAAQ;cAClC;gBAAED,KAAK;gBAAYC,OAAO;cAAW;cACrC;gBAAED,KAAK;gBAAeC,OAAO;cAAS;cACtC;gBAAED,KAAK;gBAAWC,OAAO;cAAa;;UAE1C;;MAEJ;MACA;QACES,OAAO;QACPC,MAAM;QACNH,QAAQ;UACN;YACEI,MAAM;YACNF,OAAO;YACPG,MAAM;cAAEC,UAAU;YAAyB;YAC3CM,SAAS;cACP;gBAAEpB,KAAK;gBAASC,OAAO;cAAS;cAChC;gBAAED,KAAK;gBAAYC,OAAO;cAAQ;cAClC;gBAAED,KAAK;gBAAYC,OAAO;cAAW;cACrC;gBAAED,KAAK;gBAAeC,OAAO;cAAS;cACtC;gBAAED,KAAK;gBAAWC,OAAO;cAAa;;UAE1C;UACA;YACEW,MAAM;YACNF,OAAO;YACPG,MAAM;cAAEC,UAAU;YAAuB;YACzCM,SAAS;cACPrB,IAAI,YAAY,UAAUO,KAAKgB,UAAU;cACzC;gBAAEtB,KAAK;gBAASC,OAAO;cAAQ;cAC/B;gBAAED,KAAK;gBAAYC,OAAO;cAAQ;cAClC;gBAAED,KAAK;gBAAgBC,OAAO;cAAW;cACzC;gBAAED,KAAK;gBAAeC,OAAO;cAAS;cACtC;gBAAED,KAAK;gBAAkBC,OAAO;cAAgB;;UAEpD;;MAEJ;MACA;QACES,OAAO;QACPC,MAAM;QACNH,QAAQ;UACN;YACEI,MAAM;YACNF,OAAO;YACPG,MAAM;cAAEC,UAAU;YAA0B;UAC9C;UACA;YACEF,MAAM;YACNF,OAAO;YACPG,MAAM;cAAEC,UAAU;YAAyB;YAC3CM,SAAS;cACP;gBAAEpB,KAAK;gBAAeC,OAAO;cAAY;cACzC;gBAAED,KAAK;gBAAYC,OAAO;cAAO;cACjC;gBAAED,KAAK;gBAAeC,OAAO;cAAS;cACtCF,IAAI,YAAY,aAAaO,KAAKgB,UAAU;cAC5C;gBAAEtB,KAAK;gBAAYC,OAAO;cAAQ;cAClC;gBAAED,KAAK;gBAAaC,OAAO;cAAQ;;UAEvC;;MAEJ;MACA;QACES,OAAO;QACPC,MAAM;QACNH,QAAQ;UACN;YACEI,MAAM;YACNF,OAAO;YACPG,MAAM;cAAEC,UAAU;YAAmB;YACrCG,OAAO;UACT;UACA;YACEL,MAAM;YACNF,OAAO;YACPG,MAAM;cAAEC,UAAU;YAAoB;YACtCM,SAAS;cACP;gBAAEpB,KAAK;gBAAYC,OAAO;cAAO;cACjC;gBAAED,KAAK;gBAAYC,OAAO;cAAO;cACjC;gBAAED,KAAK;gBAASC,OAAO;cAAQ;cAC/B;gBAAED,KAAK;gBAAUC,OAAO;cAAS;cACjC;gBAAED,KAAK;gBAAYC,OAAO;cAAW;cACrC;gBAAED,KAAK;gBAAkBC,OAAO;cAAW;;UAE/C;UACA;YACEW,MAAM;YACNF,OAAO;YACPG,MAAM;cAAEC,UAAU;YAAqB;YACvCM,SAAS;cACP;gBAAEpB,KAAK;gBAAaC,OAAO;cAAO;cAClC;gBAAED,KAAK;gBAAYC,OAAO;cAAO;cACjC;gBAAED,KAAK;gBAAYC,OAAO;cAAO;cACjC;gBAAED,KAAK;gBAAUC,OAAO;cAAS;cACjCF,IAAI,YAAY,UAAUO,KAAKgB,UAAU;;UAE7C;;MAEJ;;EAEJ;AACF;AAtQgBjB;;;ACfhB,8BAAkC;AAmBlC,eAAekB,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;AA+BT,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;;;AC7EhB,+BAAyC;AAiBzC,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,cAC/B,OAAOP,MAAMQ,eAAe,cAC5B,OAAOR,MAAMS,gBAAgB,cAC7B,OAAOT,MAAMU,cAAc,cAC3B,OAAOV,MAAMW,aAAa,cAC1B,OAAOX,MAAMY,eAAe,cAC5B,OAAOZ,MAAMa,qBAAqB,cAClC,OAAOb,MAAMc,cAAc;AAE/B;AAjBSb;AAwBT,SAASc,yBAAyBC,KAAqB;AACrD,MAAIC;AACJ,MAAI;AACFA,eAAWD,IAAIE,UAAUC,IAAIC,mDAA0B;MAAEC,QAAQ;IAAM,CAAA;EACzE,QAAQ;AACN,WAAO;EACT;AACA,SAAOpB,oBAAoBgB,QAAAA,IAAYA,WAAW;AACpD;AARSF;AAUT,SAASO,SAAStB,OAAc;AAC9B,SAAO,OAAOA,UAAU,YAAYH,gBAAgB0B,KAAKvB,KAAAA;AAC3D;AAFSsB;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,EAAExC,4BAA4B,EAAA;AACvD,SAAO;IAAEyC;IAASD;EAAM;AAC1B;AAPgBF;AAShB,SAASI,WAAWtC,OAAa;AAC/B,SAAOuC,KAAKC,MAAMxC,QAAQ,GAAA,IAAO;AACnC;AAFSsC;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;IAAStD,OAAOsC,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;IAAU1D,OAAOsC,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;AAYhB,IAAMG,WAAW;AAGV,SAASC,oBACdzB,MAA4B;AAE5B,SAAOA,KAAKU,IAAI,CAACP,SAAS;IACxBuB,WAAWvB,IAAIuB;IACfC,MAAMxB,IAAIwB;IACVC,QAAQzB,IAAIyB;IACZC,SAAS1B,IAAI0B;EACf,EAAA;AACF;AATgBJ;AAYT,SAASK,mBAAmB9B,MAA4B;AAC7D,SAAOA,KAAKU,IAAI,CAACP,SAAS;IAAEQ,OAAOR,IAAI4B;IAAWzE,OAAO6C,IAAI6B;EAAM,EAAA;AACrE;AAFgBF;AAYT,SAASG,eAAeX,QAAuB;AACpD,SAAOA,OAAOZ,IAAI,CAACa,WAAW;IAAEZ,OAAOY,MAAMpC;IAAKwC,MAAMJ,MAAMI;IAAMC,QAAQL,MAAMK;EAAO,EAAA;AAC3F;AAFgBK;AAKhB,IAAMC,oBAAoB;AAWnB,SAASC,gBAAgBC,SAAsB;AACpD,MAAIA,YAAY,KAAM,QAAO;AAC7B,SAAOA,QAAQC,SAASH,oBAAoB,GAAGE,QAAQnD,MAAM,GAAGiD,iBAAAA,CAAAA,WAAwBE;AAC1F;AAHgBD;AAMhB,IAAMG,0BAA0B;AAGzB,SAASC,gBAAgBC,YAAyB;AACvD,SAAOA,eAAe,OAAO,OAAOA,WAAWvD,MAAM,GAAGqD,uBAAAA;AAC1D;AAFgBC;AAoBT,SAASE,qBAAqBzC,MAAoB;AACvD,SAAOA,KAAKU,IAAI,CAACP,SAAS;IACxBuC,WAAWvC,IAAIuC;IACfC,OAAOxC,IAAIwC;IACXxB,UAAUhB,IAAIgB;IACdH,UAAUb,IAAIa;IACdU,WAAWvB,IAAIuB,aAAaF;IAC5BoB,QAAQzC,IAAIyC;IACZC,YAAY1C,IAAI0C,cAAcrB;IAC9BK,SAAS1B,IAAI0B;IACbE,WAAW5B,IAAI4B,aAAaP;IAC5BsB,cAAcX,gBAAgBhC,IAAI2C,YAAY,KAAKtB;IACnDgB,YAAYD,gBAAgBpC,IAAIqC,UAAU,KAAKhB;EACjD,EAAA;AACF;AAdgBiB;AAiBT,SAASM,qBAAqB/C,MAA2B;AAC9D,SAAOA;AACT;AAFgB+C;AAKT,SAASC,wBAAwBhD,MAAyB;AAC/D,SAAOA;AACT;AAFgBgD;AAgBT,SAASC,2BAA2BjD,MAA0B;AACnE,SAAOA,KAAKU,IAAI,CAACP,SAAS;IACxB+C,YAAY/C,IAAI+C;IAChBC,UAAUhD,IAAIgD;IACdhC,UAAUhB,IAAIgB;IACdiC,aAAajD,IAAIiD;IACjBpC,UAAUb,IAAIa;IACdU,WAAWvB,IAAIuB,aAAaF;IAC5B6B,aAAalD,IAAIkD;EACnB,EAAA;AACF;AAVgBJ;AAuBT,SAASK,oBAAoBtD,MAAmB;AACrD,SAAOA,KAAKU,IAAI,CAACP,SAAS;IACxBgD,UAAUhD,IAAIgD;IACdI,UAAUpD,IAAIoD;IACdC,OAAOrD,IAAIqD;IACX5B,QAAQzB,IAAIyB;IACZ6B,UAAUtD,IAAIsD;IACdC,gBAAgBvD,IAAIuD,kBAAkBlC;EACxC,EAAA;AACF;AATgB8B;AAYhB,IAAMK,oBAAgC;EACpChC,MAAM;EACNiC,WAAW;EACXhC,QAAQ;EACRiC,aAAa;EACbhC,SAAS;EACTiC,eAAe;EACfC,eAAe;AACjB;AASA,SAASC,uBACPC,MACAC,OACAC,QAAiC;AAEjC,SAAO;IACLF;IACA,MAAMG,QAAQ3E,OAAOnB,KAAG;AACtB,YAAM+F,UAAUhG,yBAAyBC,GAAAA;AACzC,YAAM0B,OAAOqE,UAAU,MAAMH,MAAMG,SAAS7E,aAAaC,KAAAA,CAAAA,IAAU,CAAA;AACnE,aAAO0E,OAAOnE,IAAAA;IAChB;EACF;AACF;AAbSgE;AAgBF,SAASM,0BAAAA;AACd,SAAON,uBACL,yBACA,CAACK,SAASE,UAAUF,QAAQ7G,aAAa+G,KAAAA,GACzC,CAACvE,UAAU;IAAE1C,OAAOyC,aAAaC,IAAAA;EAAM,EAAA;AAE3C;AANgBsE;AAST,SAASE,2BAAAA;AACd,SAAOR,uBACL,2BACA,CAACK,SAASE,UAAUF,QAAQ7G,aAAa+G,KAAAA,GACzC,CAACvE,UAAU;IAAE1C,OAAO+C,YAAYL,IAAAA;EAAM,EAAA;AAE1C;AANgBwE;AAST,SAASC,4BAAAA;AACd,SAAOT,uBACL,uBACA,CAACK,SAASE,UAAUF,QAAQ7G,aAAa+G,KAAAA,GACzC,CAACvE,UAAU;IAAE0E,UAAUlE,qBAAqBR,IAAAA;EAAM,EAAA;AAEtD;AANgByE;AAST,SAASE,+BAAAA;AACd,SAAOX,uBACL,4BACA,CAACK,SAASE,UAAUF,QAAQ7G,aAAa+G,KAAAA,GACzC,CAACvE,UAAU;IAAEA,MAAMa,iBAAiBb,IAAAA;EAAM,EAAA;AAE9C;AANgB2E;AAST,SAASC,0BAAAA;AACd,SAAOZ,uBACL,qBACA,CAACK,SAASE,UAAUF,QAAQ1G,WAAW4G,KAAAA,GACvC,CAACjD,YAAY;IAAEtB,MAAMqB,iBAAiBC,MAAAA;EAAQ,EAAA;AAElD;AANgBsD;AAST,SAASC,+BAAAA;AACd,SAAOb,uBACL,uBACA,CAACK,SAASE,UAAUF,QAAQ5G,aAAa8G,KAAAA,GACzC,CAACvE,UAAU;IAAEA,MAAMe,iBAAiBf,IAAAA;EAAM,EAAA;AAE9C;AANgB6E;AAST,SAASC,4BAAAA;AACd,SAAOd,uBACL,4BACA,CAACK,SAASE,UAAUF,QAAQ5G,aAAa8G,KAAAA,GACzC,CAACvE,UAAU;IAAE0E,UAAUtD,qBAAqBpB,IAAAA;EAAM,EAAA;AAEtD;AANgB8E;AAST,SAASC,+BAAAA;AACd,SAAOf,uBACL,0BACA,CAACK,SAASE,UAAUF,QAAQ3G,cAAc6G,OAAOnH,iBAAAA,GACjD,CAAC4C,UAAU;IAAEA,MAAMiB,kBAAkBjB,IAAAA;EAAM,EAAA;AAE/C;AANgB+E;AAgBhB,SAASC,6BACPf,MACAE,QAAwC;AAExC,SAAO;IACLF;IACA,MAAMG,QAAQ3E,OAAOnB,KAAG;AACtB,YAAM+F,UAAUhG,yBAAyBC,GAAAA;AACzC,YAAM2G,UAAUZ,UAAU,MAAMA,QAAQvG,WAAW0B,aAAaC,KAAAA,CAAAA,IAAUkE;AAC1E,aAAOQ,OAAOc,OAAAA;IAChB;EACF;AACF;AAZSD;AAeF,SAASE,yBAAAA;AACd,SAAOF,6BAA6B,oBAAoB,CAACC,aAAa;IAAE3H,OAAO2H,QAAQtD;EAAK,EAAA;AAC9F;AAFgBuD;AAKT,SAASC,+BAAAA;AACd,SAAOH,6BAA6B,0BAA0B,CAACC,aAAa;IAC1E3H,OAAO2H,QAAQpB;EACjB,EAAA;AACF;AAJgBsB;AAOT,SAASC,0BAAAA;AACd,SAAOJ,6BAA6B,qBAAqB,CAACC,aAAa;IACrE3H,OAAO2H,QAAQrD;EACjB,EAAA;AACF;AAJgBwD;AAOT,SAASC,2BAAAA;AACd,SAAOL,6BAA6B,sBAAsB,CAACC,aAAa;IACtE3H,OAAO2H,QAAQpD;EACjB,EAAA;AACF;AAJgBwD;AAaT,SAASC,4BAAAA;AACd,SAAO;IACLrB,MAAM;IACN,MAAMG,QAAQ3E,OAAOnB,KAAG;AACtB,YAAM+F,UAAUhG,yBAAyBC,GAAAA;AACzC,YAAM2G,UAAUZ,UAAU,MAAMA,QAAQvG,WAAW0B,aAAaC,KAAAA,CAAAA,IAAUkE;AAC1E,YAAMrG,QAAQmC,OAAO8F,WAAW,QAAQN,QAAQlB,gBAAgBkB,QAAQnB;AACxE,aAAO;QAAExG,OAAOA,SAAS;MAAE;IAC7B;EACF;AACF;AAVgBgI;AAaT,SAASE,gCAAAA;AACd,SAAOxB,uBACL,sBACA,CAACK,SAASE,UAAUF,QAAQtG,YAAYwG,KAAAA,GACxC,CAACvE,UAAU;IAAEA,MAAMyB,oBAAoBzB,IAAAA;EAAM,EAAA;AAEjD;AANgBwF;AAST,SAASC,yBAAAA;AACd,SAAOzB,uBACL,qBACA,CAACK,SAASE,UAAUF,QAAQrG,UAAUuG,KAAAA,GACtC,CAACvE,UAAU;IAAE0E,UAAU5C,mBAAmB9B,IAAAA;EAAM,EAAA;AAEpD;AANgByF;AAST,SAASC,yBAAAA;AACd,SAAO1B,uBACL,oBACA,CAACK,SAASE,UAAUF,QAAQpG,SAASsG,KAAAA,GACrC,CAACjD,YAAY;IAAEtB,MAAMiC,eAAeX,MAAAA;EAAQ,EAAA;AAEhD;AANgBoE;AAWhB,IAAMC,uBAAuB;AAE7B,IAAMC,mBAAmB;AAGzB,SAASC,aAAapG,OAA4CqG,UAAgB;AAChF,QAAMC,MAAMtG,OAAOuG;AACnB,QAAM1I,QAAQ,OAAOyI,QAAQ,YAAYE,OAAOC,SAASH,GAAAA,IAAOA,MAAMD;AACtE,SAAOjG,KAAKsG,IAAIP,kBAAkB/F,KAAKuG,IAAI,GAAGvG,KAAKwG,MAAM/I,KAAAA,CAAAA,CAAAA;AAC3D;AAJSuI;AAWT,SAASS,wBACPrC,MACAsC,cACArC,OACAC,QAAiC;AAEjC,SAAO;IACLF;IACA,MAAMG,QAAQ3E,OAAOnB,KAAG;AACtB,YAAM+F,UAAUhG,yBAAyBC,GAAAA;AACzC,YAAM0B,OAAOqE,UAAU,MAAMH,MAAMG,SAASwB,aAAapG,OAAO8G,YAAAA,CAAAA,IAAiB,CAAA;AACjF,aAAOpC,OAAOnE,IAAAA;IAChB;EACF;AACF;AAdSsG;AAoBF,SAASE,+BAAAA;AACd,SAAOF,wBACL,qBACAX,sBACA,CAACtB,SAAS2B,UAAU3B,QAAQnG,WAAW8H,KAAAA,GACvC,CAAChG,UAAU;IAAEA,MAAMyC,qBAAqBzC,IAAAA;EAAM,EAAA;AAElD;AAPgBwG;AAcT,SAASC,oCAAAA;AACd,SAAOH,wBACL,sBACAX,sBACA,CAACtB,SAAS2B,UAAU3B,QAAQzG,gBAAgBoI,KAAAA,GAC5C,CAAChG,UAAU;IAAEA,MAAM+C,qBAAqB/C,IAAAA;EAAM,EAAA;AAElD;AAPgByG;AAUT,SAASC,kCAAAA;AACd,SAAOJ,wBACL,wBACAX,sBACA,CAACtB,SAAS2B,UAAU3B,QAAQxG,cAAcmI,KAAAA,GAC1C,CAAChG,UAAU;IAAEA,MAAMgD,wBAAwBhD,IAAAA;EAAM,EAAA;AAErD;AAPgB0G;AAWhB,IAAMC,gCAAgC;AAQ/B,SAASC,qCAAAA;AACd,SAAO;IACL3C,MAAM;IACN,MAAMG,QAAQyC,QAAQvI,KAAG;AACvB,YAAM+F,UAAUhG,yBAAyBC,GAAAA;AACzC,YAAM0B,OAAOqE,UAAU,MAAMA,QAAQlG,iBAAiBwI,6BAAAA,IAAiC,CAAA;AACvF,aAAO;QAAErJ,OAAO0C,KAAKqC;MAAO;IAC9B;EACF;AACF;AATgBuE;AAYT,SAASE,qCAAAA;AACd,SAAOR,wBACL,0BACAX,sBACA,CAACtB,SAAS2B,UAAU3B,QAAQlG,iBAAiB6H,KAAAA,GAC7C,CAAChG,UAAU;IAAEA,MAAMiD,2BAA2BjD,IAAAA;EAAM,EAAA;AAExD;AAPgB8G;AAUT,SAASC,8BAAAA;AACd,SAAO/C,uBACL,qBACA,CAACK,SAASE,UAAUF,QAAQjG,UAAUmG,KAAAA,GACtC,CAACvE,UAAU;IAAEA,MAAMsD,oBAAoBtD,IAAAA;EAAM,EAAA;AAEjD;AANgB+G;;;AC3pBhB,sCAAuC;AACvC,IAAAC,4BAAwC;AACxC,gCAA8C;AAuBvC,IAAMC,wBAAN,MAAMA;EAzBb,OAyBaA;;;EACFC,OAAO;EACCC,YAA+B,CAAA;EAEhDC,SAASC,KAA2B;AAGlC,SAAKF,UAAUG,SAAKC,4CAAiB,SAASC,iDAAAA,CAAAA;AAC9C,eAAWC,SAASD,mDAAyB;AAC3C,YAAME,cAAUC,uCAAY,SAASF,KAAAA;AACrC,YAAMG,YAAY,wBAACC,YAAAA;AACjB,cAAMC,WAAWD;AACjBR,YAAIU,OAAO;UACTb,MAAM;UACNc,SAAS;YAAEP,OAAOK,SAASL;YAAO,GAAGK,SAASG;UAAQ;UACtDC,MAAM;YAACJ,SAASL;;QAClB,CAAA;MACF,GAPkB;AAQlBU,qDAAUT,SAASE,SAAAA;AACnB,WAAKT,UAAUG,KAAK,UAAMc,6CAAYV,SAASE,SAAAA,CAAAA;IACjD;EACF;;EAGAS,UAAgB;AACd,WAAO,KAAKlB,UAAUmB,OAAQ,MAAKnB,UAAUoB,IAAG,IAAA;EAClD;AACF;;;AJCO,SAASC,wBAAwBC,OAAkD,CAAC,GAAC;AAC1F,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,eAAeV,IAAAA;OAAtB;IACZW,eAAe,6BAAM;MACnBC,kBAAAA;MACAC,oBAAAA;MACAC,wBAAAA;MACAC,wBAAAA;MACAC,yBAAAA;MACAC,0BAAAA;MACAC,6BAAAA;MACAC,wBAAAA;MACAC,6BAAAA;MACAC,0BAAAA;MACAC,6BAAAA;MACAC,uBAAAA;MACAC,6BAAAA;MACAC,wBAAAA;MACAC,yBAAAA;MACAC,0BAAAA;MACAC,8BAAAA;MACAC,uBAAAA;MACAC,uBAAAA;MACAC,6BAAAA;MACAC,kCAAAA;MACAC,gCAAAA;MACAC,mCAAAA;MACAC,mCAAAA;MACAC,4BAAAA;OAzBa;EA2BjB,CAAA;AACF;AAlCgBrC;","names":["import_nestjs_telescope","col","key","label","href","undefined","link","agentDashboard","opts","id","panels","sections","title","cols","kind","data","provider","format","series","style","query","metric","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","metric","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","push","claimDiagnostics","AGENT_DIAGNOSTIC_EVENTS","event","channel","channelName","onMessage","message","envelope","record","content","payload","tags","subscribe","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
@@ -31,15 +31,14 @@ declare function agentTelescopeExtension(opts?: {
31
31
  * Records `aviary:agent:*` diagnostics events as Telescope entries of type `agent`. It depends
32
32
  * only on the diagnostics channel — not on the agent runtime — so it stays fully decoupled.
33
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.
34
+ * Iterates {@link AGENT_DIAGNOSTIC_EVENTS} (all 8 point events on `ChannelRegistry['agent']`)
35
+ * rather than a hand-written literal, so `run.failed`/`delegated`/`retrieved` are recorded and
36
+ * tagged — filterable in the Telescope UI — like every other agent event.
37
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.
38
+ * Coexists with `@dudousxd/nestjs-diagnostics-telescope`'s generic watcher: `register()` CLAIMS
39
+ * every recorded key via `claimDiagnostics('agent', ...)` (diagnostics 0.7+), so the generic
40
+ * bridge skips them at record time instead of duplicating each event as a `diagnostic` entry
41
+ * no `exclude` wiring needed anymore. `dispose()` releases the claim.
43
42
  *
44
43
  * Register it with the telescope module's watcher list.
45
44
  */
@@ -47,7 +46,7 @@ declare class AgentTelescopeWatcher implements Watcher {
47
46
  readonly type = "agent";
48
47
  private readonly disposers;
49
48
  register(ctx: WatcherContext): void;
50
- /** Detach all channel subscriptions (e.g. on module destroy). */
49
+ /** Detach all channel subscriptions and release the diagnostics claim (e.g. on module destroy). */
51
50
  dispose(): void;
52
51
  }
53
52
 
@@ -243,10 +242,11 @@ declare function agentRunsFailedProvider(): DataProvider;
243
242
  /** stat → total llm-step retries across the range's runs. */
244
243
  declare function agentRunsRetriesProvider(): DataProvider;
245
244
  /**
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`.
245
+ * stat → run duration percentile, selected by `query.metric` (`'p95'` for p95, anything else
246
+ * including omitted for p50), mirroring `durable.duration`'s stat shortcut. NOT a
247
+ * `distribution` panel: `RunMetrics` exposes only the two percentiles (no raw per-run samples to
248
+ * bucket into a histogram), so a distribution here would render as a permanently-empty box. A
249
+ * `null` percentile (no settled runs in range) resolves to 0.
250
250
  */
251
251
  declare function agentRunsDurationProvider(): DataProvider;
252
252
  /** table → run/failure/retry rollup per agent. */
package/dist/index.d.ts CHANGED
@@ -31,15 +31,14 @@ declare function agentTelescopeExtension(opts?: {
31
31
  * Records `aviary:agent:*` diagnostics events as Telescope entries of type `agent`. It depends
32
32
  * only on the diagnostics channel — not on the agent runtime — so it stays fully decoupled.
33
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.
34
+ * Iterates {@link AGENT_DIAGNOSTIC_EVENTS} (all 8 point events on `ChannelRegistry['agent']`)
35
+ * rather than a hand-written literal, so `run.failed`/`delegated`/`retrieved` are recorded and
36
+ * tagged — filterable in the Telescope UI — like every other agent event.
37
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.
38
+ * Coexists with `@dudousxd/nestjs-diagnostics-telescope`'s generic watcher: `register()` CLAIMS
39
+ * every recorded key via `claimDiagnostics('agent', ...)` (diagnostics 0.7+), so the generic
40
+ * bridge skips them at record time instead of duplicating each event as a `diagnostic` entry
41
+ * no `exclude` wiring needed anymore. `dispose()` releases the claim.
43
42
  *
44
43
  * Register it with the telescope module's watcher list.
45
44
  */
@@ -47,7 +46,7 @@ declare class AgentTelescopeWatcher implements Watcher {
47
46
  readonly type = "agent";
48
47
  private readonly disposers;
49
48
  register(ctx: WatcherContext): void;
50
- /** Detach all channel subscriptions (e.g. on module destroy). */
49
+ /** Detach all channel subscriptions and release the diagnostics claim (e.g. on module destroy). */
51
50
  dispose(): void;
52
51
  }
53
52
 
@@ -243,10 +242,11 @@ declare function agentRunsFailedProvider(): DataProvider;
243
242
  /** stat → total llm-step retries across the range's runs. */
244
243
  declare function agentRunsRetriesProvider(): DataProvider;
245
244
  /**
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`.
245
+ * stat → run duration percentile, selected by `query.metric` (`'p95'` for p95, anything else
246
+ * including omitted for p50), mirroring `durable.duration`'s stat shortcut. NOT a
247
+ * `distribution` panel: `RunMetrics` exposes only the two percentiles (no raw per-run samples to
248
+ * bucket into a histogram), so a distribution here would render as a permanently-empty box. A
249
+ * `null` percentile (no settled runs in range) resolves to 0.
250
250
  */
251
251
  declare function agentRunsDurationProvider(): DataProvider;
252
252
  /** table → run/failure/retry rollup per agent. */
package/dist/index.js CHANGED
@@ -81,7 +81,7 @@ function agentDashboard(opts = {}) {
81
81
  },
82
82
  {
83
83
  title: "Run trends",
84
- cols: 3,
84
+ cols: 4,
85
85
  panels: [
86
86
  {
87
87
  kind: "timeseries",
@@ -95,16 +95,28 @@ function agentDashboard(opts = {}) {
95
95
  ],
96
96
  style: "stacked"
97
97
  },
98
+ // Two duration stats, not a `distribution` panel: RunMetrics carries only p50/p95 (no
99
+ // raw samples to bucket), so a histogram here would be a permanently-empty box.
98
100
  {
99
- kind: "distribution",
100
- title: "Run duration",
101
+ kind: "stat",
102
+ title: "Duration p50",
101
103
  data: {
102
- provider: "agent.runs.duration"
104
+ provider: "agent.runs.duration",
105
+ query: {
106
+ metric: "p50"
107
+ }
108
+ },
109
+ format: "duration"
110
+ },
111
+ {
112
+ kind: "stat",
113
+ title: "Duration p95",
114
+ data: {
115
+ provider: "agent.runs.duration",
116
+ query: {
117
+ metric: "p95"
118
+ }
103
119
  },
104
- markers: [
105
- "p50",
106
- "p95"
107
- ],
108
120
  format: "duration"
109
121
  },
110
122
  {
@@ -151,17 +163,15 @@ function agentDashboard(opts = {}) {
151
163
  data: {
152
164
  provider: "agent.runs.recent"
153
165
  },
166
+ // A deliberate SUBSET of the provider's row shape: the full 11-field row overflows the
167
+ // card horizontally. Thread/actor/retries/errorCode detail lives in the standalone
168
+ // agent dashboard; the provider keeps returning the full row for other consumers.
154
169
  columns: [
155
170
  {
156
171
  key: "startedAt",
157
172
  label: "Started"
158
173
  },
159
174
  col("runId", "Run", opts.runHref),
160
- col("threadId", "Thread", opts.threadHref),
161
- {
162
- key: "actorRef",
163
- label: "Actor"
164
- },
165
175
  {
166
176
  key: "agentName",
167
177
  label: "Agent"
@@ -174,14 +184,6 @@ function agentDashboard(opts = {}) {
174
184
  key: "durationMs",
175
185
  label: "Duration (ms)"
176
186
  },
177
- {
178
- key: "retries",
179
- label: "Retries"
180
- },
181
- {
182
- key: "errorCode",
183
- label: "Error code"
184
- },
185
187
  {
186
188
  key: "errorMessage",
187
189
  label: "Error"
@@ -875,15 +877,17 @@ function agentRunsRetriesProvider() {
875
877
  }
876
878
  __name(agentRunsRetriesProvider, "agentRunsRetriesProvider");
877
879
  function agentRunsDurationProvider() {
878
- return governanceRunMetricsProvider("agent.runs.duration", (metrics) => ({
879
- buckets: [],
880
- ...metrics.durationP50Ms !== null ? {
881
- p50: metrics.durationP50Ms
882
- } : {},
883
- ...metrics.durationP95Ms !== null ? {
884
- p95: metrics.durationP95Ms
885
- } : {}
886
- }));
880
+ return {
881
+ name: "agent.runs.duration",
882
+ async resolve(query, ctx) {
883
+ const queries = resolveGovernanceQueries(ctx);
884
+ const metrics = queries ? await queries.runMetrics(resolveRange(query)) : EMPTY_RUN_METRICS;
885
+ const value = query?.metric === "p95" ? metrics.durationP95Ms : metrics.durationP50Ms;
886
+ return {
887
+ value: value ?? 0
888
+ };
889
+ }
890
+ };
887
891
  }
888
892
  __name(agentRunsDurationProvider, "agentRunsDurationProvider");
889
893
  function agentRunsByAgentTableProvider() {
@@ -971,7 +975,7 @@ __name(agentToolStatsTableProvider, "agentToolStatsTableProvider");
971
975
  // src/agent-telescope.watcher.ts
972
976
  import { subscribe, unsubscribe } from "node:diagnostics_channel";
973
977
  import { AGENT_DIAGNOSTIC_EVENTS } from "@dudousxd/nestjs-agent-core";
974
- import { channelName } from "@dudousxd/nestjs-diagnostics";
978
+ import { channelName, claimDiagnostics } from "@dudousxd/nestjs-diagnostics";
975
979
  var AgentTelescopeWatcher = class {
976
980
  static {
977
981
  __name(this, "AgentTelescopeWatcher");
@@ -979,6 +983,7 @@ var AgentTelescopeWatcher = class {
979
983
  type = "agent";
980
984
  disposers = [];
981
985
  register(ctx) {
986
+ this.disposers.push(claimDiagnostics("agent", AGENT_DIAGNOSTIC_EVENTS));
982
987
  for (const event of AGENT_DIAGNOSTIC_EVENTS) {
983
988
  const channel = channelName("agent", event);
984
989
  const onMessage = /* @__PURE__ */ __name((message) => {
@@ -998,7 +1003,7 @@ var AgentTelescopeWatcher = class {
998
1003
  this.disposers.push(() => unsubscribe(channel, onMessage));
999
1004
  }
1000
1005
  }
1001
- /** Detach all channel subscriptions (e.g. on module destroy). */
1006
+ /** Detach all channel subscriptions and release the diagnostics claim (e.g. on module destroy). */
1002
1007
  dispose() {
1003
1008
  while (this.disposers.length) this.disposers.pop()?.();
1004
1009
  }
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../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":["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":["defineTelescopeExtension","col","key","label","href","undefined","link","agentDashboard","opts","id","panels","sections","title","cols","kind","data","provider","format","series","style","markers","columns","runHref","threadHref","TELESCOPE_STORAGE","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","AGENT_GOVERNANCE_QUERIES","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","subscribe","unsubscribe","AGENT_DIAGNOSTIC_EVENTS","channelName","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"]}
1
+ {"version":3,"sources":["../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":["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: 4,\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 // Two duration stats, not a `distribution` panel: RunMetrics carries only p50/p95 (no\n // raw samples to bucket), so a histogram here would be a permanently-empty box.\n {\n kind: 'stat',\n title: 'Duration p50',\n data: { provider: 'agent.runs.duration', query: { metric: 'p50' } },\n format: 'duration',\n },\n {\n kind: 'stat',\n title: 'Duration p95',\n data: { provider: 'agent.runs.duration', query: { metric: '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 // A deliberate SUBSET of the provider's row shape: the full 11-field row overflows the\n // card horizontally. Thread/actor/retries/errorCode detail lives in the standalone\n // agent dashboard; the provider keeps returning the full row for other consumers.\n columns: [\n { key: 'startedAt', label: 'Started' },\n col('runId', 'Run', opts.runHref),\n { key: 'agentName', label: 'Agent' },\n { key: 'status', label: 'Status' },\n { key: 'durationMs', label: 'Duration (ms)' },\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 * stat → run duration percentile, selected by `query.metric` (`'p95'` for p95, anything else —\n * including omitted — for p50), mirroring `durable.duration`'s stat shortcut. NOT a\n * `distribution` panel: `RunMetrics` exposes only the two percentiles (no raw per-run samples to\n * bucket into a histogram), so a distribution here would render as a permanently-empty box. A\n * `null` percentile (no settled runs in range) resolves to 0.\n */\nexport function agentRunsDurationProvider(): DataProvider {\n return {\n name: 'agent.runs.duration',\n async resolve(query, ctx) {\n const queries = resolveGovernanceQueries(ctx);\n const metrics = queries ? await queries.runMetrics(resolveRange(query)) : EMPTY_RUN_METRICS;\n const value = query?.metric === 'p95' ? metrics.durationP95Ms : metrics.durationP50Ms;\n return { value: value ?? 0 };\n },\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, claimDiagnostics } 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 point events on `ChannelRegistry['agent']`)\n * rather than a hand-written literal, so `run.failed`/`delegated`/`retrieved` are recorded and\n * tagged — filterable in the Telescope UI — like every other agent event.\n *\n * Coexists with `@dudousxd/nestjs-diagnostics-telescope`'s generic watcher: `register()` CLAIMS\n * every recorded key via `claimDiagnostics('agent', ...)` (diagnostics 0.7+), so the generic\n * bridge skips them at record time instead of duplicating each event as a `diagnostic` entry —\n * no `exclude` wiring needed anymore. `dispose()` releases the claim.\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 // Tell the generic diagnostics bridge these keys are recorded here as typed `agent` entries,\n // so it skips them (refcounted; released in dispose()).\n this.disposers.push(claimDiagnostics('agent', AGENT_DIAGNOSTIC_EVENTS));\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 and release the diagnostics claim (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":["defineTelescopeExtension","col","key","label","href","undefined","link","agentDashboard","opts","id","panels","sections","title","cols","kind","data","provider","format","series","style","query","metric","columns","runHref","threadHref","TELESCOPE_STORAGE","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","AGENT_GOVERNANCE_QUERIES","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","metric","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","subscribe","unsubscribe","AGENT_DIAGNOSTIC_EVENTS","channelName","claimDiagnostics","AgentTelescopeWatcher","type","disposers","register","ctx","push","claimDiagnostics","AGENT_DIAGNOSTIC_EVENTS","event","channel","channelName","onMessage","message","envelope","record","content","payload","tags","subscribe","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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dudousxd/nestjs-agent-telescope",
3
- "version": "0.4.0",
3
+ "version": "0.5.1",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/DavideCarvalho/nestjs-agent.git",
@@ -29,8 +29,8 @@
29
29
  "dist"
30
30
  ],
31
31
  "dependencies": {
32
- "@dudousxd/nestjs-diagnostics": "0.6.1",
33
- "@dudousxd/nestjs-agent-core": "0.6.0"
32
+ "@dudousxd/nestjs-diagnostics": "0.7.0",
33
+ "@dudousxd/nestjs-agent-core": "0.8.0"
34
34
  },
35
35
  "peerDependencies": {
36
36
  "@dudousxd/nestjs-telescope": ">=1.15.0"