@agimon-ai/doompi-log 0.0.1-alpha.13 → 0.0.1-alpha.15
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/README.md +12 -19
- package/dist/adapters/node/metricsSource.cjs +2 -0
- package/dist/adapters/node/metricsSource.cjs.map +1 -0
- package/dist/adapters/node/metricsSource.d.cts +14 -0
- package/dist/adapters/node/metricsSource.d.cts.map +1 -0
- package/dist/adapters/node/metricsSource.d.mts +14 -0
- package/dist/adapters/node/metricsSource.d.mts.map +1 -0
- package/dist/adapters/node/metricsSource.mjs.map +1 -0
- package/dist/adapters/pi/extension.cjs +1 -1
- package/dist/adapters/pi/extension.cjs.map +1 -1
- package/dist/adapters/pi/extension.d.cts +4 -3
- package/dist/adapters/pi/extension.d.cts.map +1 -1
- package/dist/adapters/pi/extension.d.mts +4 -3
- package/dist/adapters/pi/extension.d.mts.map +1 -1
- package/dist/adapters/pi/extension.mjs +1 -1
- package/dist/adapters/pi/extension.mjs.map +1 -1
- package/dist/extension.d.cts +1 -1
- package/dist/extension.d.mts +1 -1
- package/dist/extensions/pi.cjs +1 -2
- package/dist/extensions/pi.d.cts +2 -4
- package/dist/extensions/pi.d.mts +2 -5
- package/dist/extensions/pi.mjs +1 -2
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.mts +2 -2
- package/dist/index.mjs +1 -1
- package/dist/metrics.d.cts +1 -1
- package/dist/metrics.d.mts +1 -1
- package/dist/metricsSource.cjs +1 -1
- package/dist/metricsSource.d.cts +3 -2
- package/dist/metricsSource.d.mts +3 -2
- package/dist/metricsSource.mjs +1 -1
- package/dist/tui/logMetricsOverlay.cjs +2 -0
- package/dist/tui/logMetricsOverlay.cjs.map +1 -0
- package/dist/tui/logMetricsOverlay.d.cts +71 -0
- package/dist/tui/logMetricsOverlay.d.cts.map +1 -0
- package/dist/tui/logMetricsOverlay.d.mts +71 -0
- package/dist/tui/logMetricsOverlay.d.mts.map +1 -0
- package/dist/tui/logMetricsOverlay.mjs +2 -0
- package/dist/tui/logMetricsOverlay.mjs.map +1 -0
- package/dist/tui/metricsOverlay.cjs +1 -2
- package/dist/tui/metricsOverlay.d.cts +2 -71
- package/dist/tui/metricsOverlay.d.mts +2 -71
- package/dist/tui/metricsOverlay.mjs +1 -2
- package/dist/types/metricsSource.d.cts +16 -0
- package/dist/types/metricsSource.d.cts.map +1 -0
- package/dist/types/metricsSource.d.mts +16 -0
- package/dist/types/metricsSource.d.mts.map +1 -0
- package/package.json +5 -5
- package/dist/extensions/pi.cjs.map +0 -1
- package/dist/extensions/pi.d.cts.map +0 -1
- package/dist/extensions/pi.d.mts.map +0 -1
- package/dist/extensions/pi.mjs.map +0 -1
- package/dist/services/metricsSource.cjs +0 -2
- package/dist/services/metricsSource.cjs.map +0 -1
- package/dist/services/metricsSource.d.cts +0 -25
- package/dist/services/metricsSource.d.cts.map +0 -1
- package/dist/services/metricsSource.d.mts +0 -25
- package/dist/services/metricsSource.d.mts.map +0 -1
- package/dist/services/metricsSource.mjs.map +0 -1
- package/dist/tui/metricsOverlay.cjs.map +0 -1
- package/dist/tui/metricsOverlay.d.cts.map +0 -1
- package/dist/tui/metricsOverlay.d.mts.map +0 -1
- package/dist/tui/metricsOverlay.mjs.map +0 -1
- /package/dist/{services → adapters/node}/metricsSource.mjs +0 -0
package/README.md
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
# @agimon-ai/doompi-log
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
**If the agent emits telemetry, you should be able to see it.**
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
This package turns Doompi's LogSink records into session-local metrics and a terminal
|
|
6
|
+
overlay. Counters and spans stay useful to the person running the session instead of
|
|
7
|
+
disappearing into a database nobody opens.
|
|
6
8
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
installed on its own.
|
|
9
|
+
This is part of [Doompi](https://www.npmjs.com/package/@agimon-ai/doompi). Most users get
|
|
10
|
+
it with the distribution.
|
|
10
11
|
|
|
11
12
|
## Install
|
|
12
13
|
|
|
@@ -16,25 +17,17 @@ npm install @agimon-ai/doompi-log
|
|
|
16
17
|
|
|
17
18
|
## How it loads
|
|
18
19
|
|
|
19
|
-
Doompi loads
|
|
20
|
-
`.doom/modes.yaml
|
|
21
|
-
|
|
22
|
-
Extension entry: `@agimon-ai/doompi-log/extensions/pi`
|
|
20
|
+
Doompi loads the log viewer as core. It is not a layer and does not appear in
|
|
21
|
+
`.doom/modes.yaml`. The bare package name follows its Pi manifest and loads the Pi adapter.
|
|
23
22
|
|
|
24
23
|
## Leader
|
|
25
24
|
|
|
26
|
-
`SPC h l` opens
|
|
25
|
+
`SPC h l` opens the Log Metrics overlay for the current session.
|
|
27
26
|
|
|
28
|
-
##
|
|
27
|
+
## Public API
|
|
29
28
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
| `@agimon-ai/doompi-log` |
|
|
33
|
-
| `@agimon-ai/doompi-log/extension` |
|
|
34
|
-
| `@agimon-ai/doompi-log/extensions/pi` |
|
|
35
|
-
| `@agimon-ai/doompi-log/metrics` |
|
|
36
|
-
| `@agimon-ai/doompi-log/metricsSource` |
|
|
37
|
-
| `@agimon-ai/doompi-log/tui/metricsOverlay` |
|
|
29
|
+
The package exports the extension, metrics source, overlay, and Pi adapter through declared
|
|
30
|
+
subpaths. See `package.json` for the complete list.
|
|
38
31
|
|
|
39
32
|
## License
|
|
40
33
|
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
const e=require("../../_virtual/_rolldown/runtime.cjs");let t=require("node:child_process"),n=require("node:module"),r=require("node:path");r=e.__toESM(r,1);let i=require("@agimon-ai/log-sink-mcp");const a=`total-tokens`;function o(){let e=(0,n.createRequire)(require("url").pathToFileURL(__filename).href).resolve(`@agimon-ai/log-sink-mcp/package.json`);return r.default.join(r.default.dirname(e),`dist`,`cli.mjs`)}function s(e){return new URLSearchParams({groupBy:e.groupBy,period:e.period,sort:a,limit:String(e.limit),toolLimit:`1`}).toString()}async function c(e,t,n){let r=await n(`${e}/api/metrics?${s(t)}`,{signal:AbortSignal.timeout(5e3)});if(!r.ok)throw Error(`sink responded ${r.status}`);let i=await r.json();if(i.error||!Array.isArray(i.timeline))throw Error(i.error??`sink is an older version`);return i}function l(e){return new Promise((n,r)=>{(0,t.execFile)(process.execPath,[o(),`logs`,`metrics`,`--group-by`,e.groupBy,`--period`,e.period,`--sort`,a,`--limit`,String(e.limit),`--tool-limit`,`1`],{timeout:3e4,maxBuffer:33554432},(e,t,i)=>{if(e){r(Error(i.trim()||e.message));return}try{n(JSON.parse(t))}catch{r(Error(`metrics CLI returned unparsable output`))}})})}function u(e={}){let t=e.fetchImpl??globalThis.fetch,n=e.cliRunner??l,r,a,o=async()=>{if(a!==void 0)return a??void 0;try{a=(await(0,i.resolveLogSinkPort)({env:e.env,cwd:e.cwd,healthCheck:!0}))?.endpoint??null}catch{a=null}return a??void 0};return{lastTransport:()=>r,async query(e){let i=await o();if(i&&t)try{let n=await c(i,e,t);return r=`http`,n}catch{a=null}let s=await n(e);return r=`cli`,s}}}exports.createMetricsSource=u;
|
|
2
|
+
//# sourceMappingURL=metricsSource.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"metricsSource.cjs","names":["createRequire","path","resolveLogSinkPort"],"sources":["../../../src/adapters/node/metricsSource.ts"],"sourcesContent":["/**\n * Historical metrics access for the `SPC h l` overlay.\n *\n * Two transports, in order: the running sink's HTTP API, then the installed\n * CLI as a subprocess. The sink daemon is long-lived and often lags the\n * installed package, so a daemon that rejects newer query parameters is treated\n * as unavailable rather than fatal. The reader exported by log-sink-mcp is\n * deliberately not used in-process: better-sqlite3 is synchronous and a\n * one-day window blocks for seconds, which would freeze the TUI.\n */\nimport { execFile } from 'node:child_process';\nimport { createRequire } from 'node:module';\nimport path from 'node:path';\nimport type { LogMetricsReport } from '@agimon-ai/log-sink-mcp';\nimport { resolveLogSinkPort } from '@agimon-ai/log-sink-mcp';\nimport type { MetricsQueryParams, MetricsSource, MetricsTransport } from '../../types/metricsSource.ts';\n\nconst PACKAGE_NAME = '@agimon-ai/log-sink-mcp';\nconst HTTP_TIMEOUT_MS = 5000;\nconst CLI_TIMEOUT_MS = 30000;\n/** A day of dev telemetry is already ~140k records; keep the payload bounded. */\nconst MAX_CLI_BUFFER = 32 * 1024 * 1024;\nconst TOOL_LIMIT = '1';\n/** The panel ranks consumers, so ask for the biggest rather than the most recent. */\nconst TOKEN_SORT = 'total-tokens';\n\nexport interface MetricsSourceOptions {\n env?: NodeJS.ProcessEnv;\n cwd?: string;\n /** Overrides transport discovery in tests. */\n fetchImpl?: typeof fetch;\n cliRunner?: (params: MetricsQueryParams) => Promise<LogMetricsReport>;\n}\n\nfunction cliEntryPoint(): string {\n const require = createRequire(import.meta.url);\n // The published bin is CJS; the ESM build sits beside it and starts faster.\n const packageJson = require.resolve(`${PACKAGE_NAME}/package.json`);\n return path.join(path.dirname(packageJson), 'dist', 'cli.mjs');\n}\n\nfunction searchParams(params: MetricsQueryParams): string {\n return new URLSearchParams({\n groupBy: params.groupBy,\n period: params.period,\n sort: TOKEN_SORT,\n limit: String(params.limit),\n toolLimit: TOOL_LIMIT,\n }).toString();\n}\n\nasync function queryHttp(\n endpoint: string,\n params: MetricsQueryParams,\n fetchImpl: typeof fetch,\n): Promise<LogMetricsReport> {\n const response = await fetchImpl(`${endpoint}/api/metrics?${searchParams(params)}`, {\n signal: AbortSignal.timeout(HTTP_TIMEOUT_MS),\n });\n if (!response.ok) throw new Error(`sink responded ${response.status}`);\n\n const body = (await response.json()) as LogMetricsReport & { error?: string };\n // An older daemon rejects unknown group-by values and omits the timeline.\n if (body.error || !Array.isArray(body.timeline)) throw new Error(body.error ?? 'sink is an older version');\n return body;\n}\n\nfunction runCli(params: MetricsQueryParams): Promise<LogMetricsReport> {\n return new Promise((resolve, reject) => {\n execFile(\n process.execPath,\n [\n cliEntryPoint(),\n 'logs',\n 'metrics',\n '--group-by',\n params.groupBy,\n '--period',\n params.period,\n '--sort',\n TOKEN_SORT,\n '--limit',\n String(params.limit),\n '--tool-limit',\n TOOL_LIMIT,\n ],\n { timeout: CLI_TIMEOUT_MS, maxBuffer: MAX_CLI_BUFFER },\n (error, stdout, stderr) => {\n if (error) {\n reject(new Error(stderr.trim() || error.message));\n return;\n }\n try {\n resolve(JSON.parse(stdout) as LogMetricsReport);\n } catch {\n reject(new Error('metrics CLI returned unparsable output'));\n }\n },\n );\n });\n}\n\nexport function createMetricsSource(options: MetricsSourceOptions = {}): MetricsSource {\n const fetchImpl = options.fetchImpl ?? globalThis.fetch;\n const cliRunner = options.cliRunner ?? runCli;\n let transport: MetricsTransport | undefined;\n let endpoint: string | undefined | null;\n\n const resolveEndpoint = async (): Promise<string | undefined> => {\n if (endpoint !== undefined) return endpoint ?? undefined;\n try {\n const resolved = await resolveLogSinkPort({ env: options.env, cwd: options.cwd, healthCheck: true });\n endpoint = resolved?.endpoint ?? null;\n } catch {\n endpoint = null;\n }\n return endpoint ?? undefined;\n };\n\n return {\n lastTransport: () => transport,\n async query(params) {\n const httpEndpoint = await resolveEndpoint();\n if (httpEndpoint && fetchImpl) {\n try {\n const report = await queryHttp(httpEndpoint, params, fetchImpl);\n transport = 'http';\n return report;\n } catch {\n // A stale or unhealthy daemon must not hide data the CLI can still read.\n endpoint = null;\n }\n }\n\n const report = await cliRunner(params);\n transport = 'cli';\n return report;\n },\n };\n}\n"],"mappings":"sMAiBA,MAOM,EAAa,eAUnB,SAAS,GAAwB,CAG/B,IAAM,GAAA,EAFUA,EAAAA,cAAAA,CAAAA,QAAAA,KAAAA,CAAAA,CAAAA,cAAAA,UAAAA,CAAAA,CAAAA,IAEU,CAAC,CAAC,QAAQ,sCAA8B,EAClE,OAAOC,EAAAA,QAAK,KAAKA,EAAAA,QAAK,QAAQ,CAAW,EAAG,OAAQ,SAAS,CAC/D,CAEA,SAAS,EAAa,EAAoC,CACxD,OAAO,IAAI,gBAAgB,CACzB,QAAS,EAAO,QAChB,OAAQ,EAAO,OACf,KAAM,EACN,MAAO,OAAO,EAAO,KAAK,EAC1B,UAAW,GACb,CAAC,CAAC,CAAC,SAAS,CACd,CAEA,eAAe,EACb,EACA,EACA,EAC2B,CAC3B,IAAM,EAAW,MAAM,EAAU,GAAG,EAAS,eAAe,EAAa,CAAM,IAAK,CAClF,OAAQ,YAAY,QAAQ,GAAe,CAC7C,CAAC,EACD,GAAI,CAAC,EAAS,GAAI,MAAU,MAAM,kBAAkB,EAAS,QAAQ,EAErE,IAAM,EAAQ,MAAM,EAAS,KAAK,EAElC,GAAI,EAAK,OAAS,CAAC,MAAM,QAAQ,EAAK,QAAQ,EAAG,MAAU,MAAM,EAAK,OAAS,0BAA0B,EACzG,OAAO,CACT,CAEA,SAAS,EAAO,EAAuD,CACrE,OAAO,IAAI,SAAS,EAAS,IAAW,EACtC,EAAA,EAAA,SAAA,CACE,QAAQ,SACR,CACE,EAAc,EACd,OACA,UACA,aACA,EAAO,QACP,WACA,EAAO,OACP,SACA,EACA,UACA,OAAO,EAAO,KAAK,EACnB,eACA,GACF,EACA,CAAE,QAAS,IAAgB,UAAW,QAAe,GACpD,EAAO,EAAQ,IAAW,CACzB,GAAI,EAAO,CACT,EAAW,MAAM,EAAO,KAAK,GAAK,EAAM,OAAO,CAAC,EAChD,MACF,CACA,GAAI,CACF,EAAQ,KAAK,MAAM,CAAM,CAAqB,CAChD,MAAQ,CACN,EAAW,MAAM,wCAAwC,CAAC,CAC5D,CACF,CACF,CACF,CAAC,CACH,CAEA,SAAgB,EAAoB,EAAgC,CAAC,EAAkB,CACrF,IAAM,EAAY,EAAQ,WAAa,WAAW,MAC5C,EAAY,EAAQ,WAAa,EACnC,EACA,EAEE,EAAkB,SAAyC,CAC/D,GAAI,IAAa,IAAA,GAAW,OAAO,GAAY,IAAA,GAC/C,GAAI,CAEF,GAAW,MAAA,EADYC,EAAAA,mBAAAA,CAAmB,CAAE,IAAK,EAAQ,IAAK,IAAK,EAAQ,IAAK,YAAa,EAAK,CAAC,EAAA,EAC9E,UAAY,IACnC,MAAQ,CACN,EAAW,IACb,CACA,OAAO,GAAY,IAAA,EACrB,EAEA,MAAO,CACL,kBAAqB,EACrB,MAAM,MAAM,EAAQ,CAClB,IAAM,EAAe,MAAM,EAAgB,EAC3C,GAAI,GAAgB,EAClB,GAAI,CACF,IAAM,EAAS,MAAM,EAAU,EAAc,EAAQ,CAAS,EAE9D,MADA,GAAY,OACL,CACT,MAAQ,CAEN,EAAW,IACb,CAGF,IAAM,EAAS,MAAM,EAAU,CAAM,EAErC,MADA,GAAY,MACL,CACT,CACF,CACF"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { MetricsQueryParams, MetricsSource } from "../../types/metricsSource.cjs";
|
|
2
|
+
import { LogMetricsReport } from "@agimon-ai/log-sink-mcp";
|
|
3
|
+
//#region src/adapters/node/metricsSource.d.ts
|
|
4
|
+
interface MetricsSourceOptions {
|
|
5
|
+
env?: NodeJS.ProcessEnv;
|
|
6
|
+
cwd?: string;
|
|
7
|
+
/** Overrides transport discovery in tests. */
|
|
8
|
+
fetchImpl?: typeof fetch;
|
|
9
|
+
cliRunner?: (params: MetricsQueryParams) => Promise<LogMetricsReport>;
|
|
10
|
+
}
|
|
11
|
+
declare function createMetricsSource(options?: MetricsSourceOptions): MetricsSource;
|
|
12
|
+
//#endregion
|
|
13
|
+
export { MetricsSourceOptions, createMetricsSource };
|
|
14
|
+
//# sourceMappingURL=metricsSource.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"metricsSource.d.cts","names":[],"sources":["../../../src/adapters/node/metricsSource.ts"],"mappings":";;;UA0BiB;EACf,MAAM,OAAO;EACb;;EAEA,mBAAmB;EACnB,aAAa,QAAQ,uBAAuB,QAAQ;;iBAuEtC,oBAAoB,UAAS,uBAA4B"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { MetricsQueryParams, MetricsSource } from "../../types/metricsSource.mjs";
|
|
2
|
+
import { LogMetricsReport } from "@agimon-ai/log-sink-mcp";
|
|
3
|
+
//#region src/adapters/node/metricsSource.d.ts
|
|
4
|
+
interface MetricsSourceOptions {
|
|
5
|
+
env?: NodeJS.ProcessEnv;
|
|
6
|
+
cwd?: string;
|
|
7
|
+
/** Overrides transport discovery in tests. */
|
|
8
|
+
fetchImpl?: typeof fetch;
|
|
9
|
+
cliRunner?: (params: MetricsQueryParams) => Promise<LogMetricsReport>;
|
|
10
|
+
}
|
|
11
|
+
declare function createMetricsSource(options?: MetricsSourceOptions): MetricsSource;
|
|
12
|
+
//#endregion
|
|
13
|
+
export { MetricsSourceOptions, createMetricsSource };
|
|
14
|
+
//# sourceMappingURL=metricsSource.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"metricsSource.d.mts","names":[],"sources":["../../../src/adapters/node/metricsSource.ts"],"mappings":";;;UA0BiB;EACf,MAAM,OAAO;EACb;;EAEA,mBAAmB;EACnB,aAAa,QAAQ,uBAAuB,QAAQ;;iBAuEtC,oBAAoB,UAAS,uBAA4B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"metricsSource.mjs","names":[],"sources":["../../../src/adapters/node/metricsSource.ts"],"sourcesContent":["/**\n * Historical metrics access for the `SPC h l` overlay.\n *\n * Two transports, in order: the running sink's HTTP API, then the installed\n * CLI as a subprocess. The sink daemon is long-lived and often lags the\n * installed package, so a daemon that rejects newer query parameters is treated\n * as unavailable rather than fatal. The reader exported by log-sink-mcp is\n * deliberately not used in-process: better-sqlite3 is synchronous and a\n * one-day window blocks for seconds, which would freeze the TUI.\n */\nimport { execFile } from 'node:child_process';\nimport { createRequire } from 'node:module';\nimport path from 'node:path';\nimport type { LogMetricsReport } from '@agimon-ai/log-sink-mcp';\nimport { resolveLogSinkPort } from '@agimon-ai/log-sink-mcp';\nimport type { MetricsQueryParams, MetricsSource, MetricsTransport } from '../../types/metricsSource.ts';\n\nconst PACKAGE_NAME = '@agimon-ai/log-sink-mcp';\nconst HTTP_TIMEOUT_MS = 5000;\nconst CLI_TIMEOUT_MS = 30000;\n/** A day of dev telemetry is already ~140k records; keep the payload bounded. */\nconst MAX_CLI_BUFFER = 32 * 1024 * 1024;\nconst TOOL_LIMIT = '1';\n/** The panel ranks consumers, so ask for the biggest rather than the most recent. */\nconst TOKEN_SORT = 'total-tokens';\n\nexport interface MetricsSourceOptions {\n env?: NodeJS.ProcessEnv;\n cwd?: string;\n /** Overrides transport discovery in tests. */\n fetchImpl?: typeof fetch;\n cliRunner?: (params: MetricsQueryParams) => Promise<LogMetricsReport>;\n}\n\nfunction cliEntryPoint(): string {\n const require = createRequire(import.meta.url);\n // The published bin is CJS; the ESM build sits beside it and starts faster.\n const packageJson = require.resolve(`${PACKAGE_NAME}/package.json`);\n return path.join(path.dirname(packageJson), 'dist', 'cli.mjs');\n}\n\nfunction searchParams(params: MetricsQueryParams): string {\n return new URLSearchParams({\n groupBy: params.groupBy,\n period: params.period,\n sort: TOKEN_SORT,\n limit: String(params.limit),\n toolLimit: TOOL_LIMIT,\n }).toString();\n}\n\nasync function queryHttp(\n endpoint: string,\n params: MetricsQueryParams,\n fetchImpl: typeof fetch,\n): Promise<LogMetricsReport> {\n const response = await fetchImpl(`${endpoint}/api/metrics?${searchParams(params)}`, {\n signal: AbortSignal.timeout(HTTP_TIMEOUT_MS),\n });\n if (!response.ok) throw new Error(`sink responded ${response.status}`);\n\n const body = (await response.json()) as LogMetricsReport & { error?: string };\n // An older daemon rejects unknown group-by values and omits the timeline.\n if (body.error || !Array.isArray(body.timeline)) throw new Error(body.error ?? 'sink is an older version');\n return body;\n}\n\nfunction runCli(params: MetricsQueryParams): Promise<LogMetricsReport> {\n return new Promise((resolve, reject) => {\n execFile(\n process.execPath,\n [\n cliEntryPoint(),\n 'logs',\n 'metrics',\n '--group-by',\n params.groupBy,\n '--period',\n params.period,\n '--sort',\n TOKEN_SORT,\n '--limit',\n String(params.limit),\n '--tool-limit',\n TOOL_LIMIT,\n ],\n { timeout: CLI_TIMEOUT_MS, maxBuffer: MAX_CLI_BUFFER },\n (error, stdout, stderr) => {\n if (error) {\n reject(new Error(stderr.trim() || error.message));\n return;\n }\n try {\n resolve(JSON.parse(stdout) as LogMetricsReport);\n } catch {\n reject(new Error('metrics CLI returned unparsable output'));\n }\n },\n );\n });\n}\n\nexport function createMetricsSource(options: MetricsSourceOptions = {}): MetricsSource {\n const fetchImpl = options.fetchImpl ?? globalThis.fetch;\n const cliRunner = options.cliRunner ?? runCli;\n let transport: MetricsTransport | undefined;\n let endpoint: string | undefined | null;\n\n const resolveEndpoint = async (): Promise<string | undefined> => {\n if (endpoint !== undefined) return endpoint ?? undefined;\n try {\n const resolved = await resolveLogSinkPort({ env: options.env, cwd: options.cwd, healthCheck: true });\n endpoint = resolved?.endpoint ?? null;\n } catch {\n endpoint = null;\n }\n return endpoint ?? undefined;\n };\n\n return {\n lastTransport: () => transport,\n async query(params) {\n const httpEndpoint = await resolveEndpoint();\n if (httpEndpoint && fetchImpl) {\n try {\n const report = await queryHttp(httpEndpoint, params, fetchImpl);\n transport = 'http';\n return report;\n } catch {\n // A stale or unhealthy daemon must not hide data the CLI can still read.\n endpoint = null;\n }\n }\n\n const report = await cliRunner(params);\n transport = 'cli';\n return report;\n },\n };\n}\n"],"mappings":"gLAiBA,MAOM,EAAa,eAUnB,SAAS,GAAwB,CAG/B,IAAM,EAFU,EAAc,YAAY,GAEhB,CAAC,CAAC,QAAQ,sCAA8B,EAClE,OAAO,EAAK,KAAK,EAAK,QAAQ,CAAW,EAAG,OAAQ,SAAS,CAC/D,CAEA,SAAS,EAAa,EAAoC,CACxD,OAAO,IAAI,gBAAgB,CACzB,QAAS,EAAO,QAChB,OAAQ,EAAO,OACf,KAAM,EACN,MAAO,OAAO,EAAO,KAAK,EAC1B,UAAW,GACb,CAAC,CAAC,CAAC,SAAS,CACd,CAEA,eAAe,EACb,EACA,EACA,EAC2B,CAC3B,IAAM,EAAW,MAAM,EAAU,GAAG,EAAS,eAAe,EAAa,CAAM,IAAK,CAClF,OAAQ,YAAY,QAAQ,GAAe,CAC7C,CAAC,EACD,GAAI,CAAC,EAAS,GAAI,MAAU,MAAM,kBAAkB,EAAS,QAAQ,EAErE,IAAM,EAAQ,MAAM,EAAS,KAAK,EAElC,GAAI,EAAK,OAAS,CAAC,MAAM,QAAQ,EAAK,QAAQ,EAAG,MAAU,MAAM,EAAK,OAAS,0BAA0B,EACzG,OAAO,CACT,CAEA,SAAS,EAAO,EAAuD,CACrE,OAAO,IAAI,SAAS,EAAS,IAAW,CACtC,EACE,QAAQ,SACR,CACE,EAAc,EACd,OACA,UACA,aACA,EAAO,QACP,WACA,EAAO,OACP,SACA,EACA,UACA,OAAO,EAAO,KAAK,EACnB,eACA,GACF,EACA,CAAE,QAAS,IAAgB,UAAW,QAAe,GACpD,EAAO,EAAQ,IAAW,CACzB,GAAI,EAAO,CACT,EAAW,MAAM,EAAO,KAAK,GAAK,EAAM,OAAO,CAAC,EAChD,MACF,CACA,GAAI,CACF,EAAQ,KAAK,MAAM,CAAM,CAAqB,CAChD,MAAQ,CACN,EAAW,MAAM,wCAAwC,CAAC,CAC5D,CACF,CACF,CACF,CAAC,CACH,CAEA,SAAgB,EAAoB,EAAgC,CAAC,EAAkB,CACrF,IAAM,EAAY,EAAQ,WAAa,WAAW,MAC5C,EAAY,EAAQ,WAAa,EACnC,EACA,EAEE,EAAkB,SAAyC,CAC/D,GAAI,IAAa,IAAA,GAAW,OAAO,GAAY,IAAA,GAC/C,GAAI,CAEF,GAAW,MADY,EAAmB,CAAE,IAAK,EAAQ,IAAK,IAAK,EAAQ,IAAK,YAAa,EAAK,CAAC,EAAA,EAC9E,UAAY,IACnC,MAAQ,CACN,EAAW,IACb,CACA,OAAO,GAAY,IAAA,EACrB,EAEA,MAAO,CACL,kBAAqB,EACrB,MAAM,MAAM,EAAQ,CAClB,IAAM,EAAe,MAAM,EAAgB,EAC3C,GAAI,GAAgB,EAClB,GAAI,CACF,IAAM,EAAS,MAAM,EAAU,EAAc,EAAQ,CAAS,EAE9D,MADA,GAAY,OACL,CACT,MAAQ,CAEN,EAAW,IACb,CAGF,IAAM,EAAS,MAAM,EAAU,CAAM,EAErC,MADA,GAAY,MACL,CACT,CACF,CACF"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const e=require("../../services/metrics.cjs"),t=require("../../
|
|
1
|
+
const e=require("../../services/metrics.cjs"),t=require("../../tui/logMetricsOverlay.cjs"),n=require("../node/metricsSource.cjs");let r=require("@agimon-ai/doompi-extension-contracts/leader"),i=require("@agimon-ai/doompi-telemetry");const a=`log-metrics`,o=new Set([`error`,`aborted`]);function s(e){return e===`1`||e?.toLowerCase()===`true`||e?.toLowerCase()===`yes`}function c(e){let t={"pi.mode":e.mode,"pi.session.id":e.sessionManager.getSessionId()};return e.thinkingLevel&&(t[`pi.thinking_level`]=e.thinkingLevel),e.model&&(t[`gen_ai.provider.name`]=e.model.provider,t[`gen_ai.request.model`]=e.model.id),t}function l(e){if(e.role!==`assistant`)return;let t={"gen_ai.response.model":e.responseModel??e.model,"gen_ai.response.finish_reasons":e.stopReason,"gen_ai.usage.input_tokens":e.usage.input,"gen_ai.usage.output_tokens":e.usage.output,"gen_ai.usage.cache_read_tokens":e.usage.cacheRead,"gen_ai.usage.cache_write_tokens":e.usage.cacheWrite,"gen_ai.usage.total_tokens":e.usage.totalTokens,"gen_ai.usage.cost":e.usage.cost.total};return e.usage.reasoning!==void 0&&(t[`gen_ai.usage.reasoning_tokens`]=e.usage.reasoning),t}function u(e){if(e.role!==`assistant`)return{"error.type":`AgentError`,outcome:`error`};let t=e.stopReason===`aborted`;return{"error.type":`ProviderError`,"error.code":e.stopReason,outcome:t?`aborted`:`error`}}function d(e){return{service:e.serviceName,backend:e.backend,endpoint:e.endpoint??`none`,endpointSource:e.endpointSource,traces:e.traces,redaction:!0,fileFallback:e.fileFallback}}function f(e={}){return function(t){let n=e.env??process.env,r=e.metrics,a=new Map,f,p,m=async(e,t,n)=>{p&&(e===`debug`?await p.recordDebug(t,n):e===`warn`?await p.recordWarning(t,void 0,n):e===`error`?await p.recordError(t,void 0,n):await p.recordEvent(t,n))},h=t=>(p??=(0,i.createDoomTelemetry)({serviceName:e.serviceName??`pi`,packageName:`@agimon-ai/doompi-log`,cwd:t.cwd,env:n,allowFileFallback:e.allowFileFallback,telemetryFactory:e.telemetryFactory,warn:e.onDiagnostic,enableLogs:!0,enableTraces:n.AGENT_OTEL_TRACES===void 0||s(n.AGENT_OTEL_TRACES),onRecord:e=>r?.record(e.event,e.attributes),onStatus:t=>e.onSinkStatus?.(d(t))}),e.onSinkStatus?.(d(p.status())),p);t.on(`session_start`,async(e,t)=>{h(t),await m(`info`,`pi.session.started`,{...c(t),"pi.session.reason":e.reason,"pi.session.previous":e.previousSessionFile!==void 0})}),t.on(`before_agent_start`,async(e,t)=>{h(t),await m(`info`,`pi.user_prompt`,{...c(t),"pi.user_message.length":e.prompt.length,"pi.user_message.image_count":e.images?.length??0})}),t.on(`agent_start`,async(e,t)=>{f=Date.now(),h(t),await m(`info`,`pi.agent.started`,c(t))}),t.on(`turn_start`,async(e,t)=>{h(t),await m(`debug`,`pi.turn.started`,{...c(t),"pi.turn.index":e.turnIndex})}),t.on(`turn_end`,async(e,t)=>{h(t);let n=l(e.message);if(await m(`info`,`pi.turn.finished`,{...c(t),"pi.turn.index":e.turnIndex,"pi.tool_result.count":e.toolResults.length,...n}),e.message.role===`assistant`&&o.has(e.message.stopReason)&&await m(e.message.stopReason===`aborted`?`warn`:`error`,`pi.turn.failed`,{...c(t),"pi.turn.index":e.turnIndex,...u(e.message),...n}),n)for(let r of e.toolResults)await m(`debug`,`pi.tool_token_sample`,{...c(t),...n,"tool.name":r.toolName,token_attribution:`toolCallTurn`})}),t.on(`tool_execution_start`,async(e,t)=>{a.set(e.toolCallId,Date.now()),h(t),await m(`debug`,`pi.tool_call`,{...c(t),"tool.name":e.toolName,"tool.call.id":e.toolCallId})}),t.on(`tool_execution_end`,async(e,t)=>{let n=a.get(e.toolCallId);a.delete(e.toolCallId),h(t),await m(`info`,`pi.tool_result`,{...c(t),success:!e.isError,"tool.name":e.toolName,"tool.call.id":e.toolCallId,"tool.result.error":e.isError,...n===void 0?{}:{"tool.duration_ms":Date.now()-n}})}),t.on(`after_provider_response`,async(e,t)=>{h(t);let n={...c(t),"http.response.status_code":e.status};e.status>=400?await m(`error`,`pi.api_error`,n):await m(`debug`,`pi.api_response`,n)}),t.on(`model_select`,async(e,t)=>{h(t),await m(`info`,`pi.model.selected`,{...c(t),"pi.model.source":e.source,"gen_ai.provider.name":e.model.provider,"gen_ai.request.model":e.model.id})}),t.on(`agent_end`,async(e,t)=>{h(t),await m(`info`,`pi.agent.finished`,{...c(t),"pi.message.count":e.messages.length,...f===void 0?{}:{"pi.agent.duration_ms":Date.now()-f}}),f=void 0,await p?.flush()}),t.on(`agent_settled`,async(e,t)=>{h(t),await m(`debug`,`pi.agent.settled`,c(t))}),t.on(`session_shutdown`,async(e,t)=>{h(t),await m(`info`,`pi.session.finished`,{...c(t),"pi.session.reason":e.reason}),await p?.shutdown()})}}function p(e,t={}){return(0,r.registerDoomLeaderContribution)(e,{source:t.source??`@agimon-ai/doompi-log`,bindings:[{id:`log.metrics`,path:[{key:`h`,label:`help`,order:70},{key:`l`,label:`logs`,detail:`telemetry`}],command:{name:a}}]})}async function m(e,n,r){await e.ui.custom((e,i,a,o)=>new t.LogMetricsOverlayComponent(e,i,n,o,r),{overlay:!0,overlayOptions:{anchor:`top-left`,width:`100%`,maxHeight:`100%`,margin:0}})}function h(t={}){return function(r){let i=t.env??process.env,o=new e.LogMetricsAggregator,c=t.metricsSource??n.createMetricsSource({env:i}),l,u;f({...t,metrics:o,onDiagnostic:e=>{u=e,t.onDiagnostic?t.onDiagnostic(e):i.AGENT_OTEL_DIAGNOSTICS===`stderr`&&process.emitWarning(e)},onSinkStatus:e=>{l=e,t.onSinkStatus?.(e)}})(r),p(r,{source:t.leaderSource}),r.registerCommand(a,{description:`Show session-local log metrics`,handler:async(e,t)=>{await m(t,()=>({disabled:s(i.AGENT_TELEMETRY_DISABLED)||s(i.OTEL_SDK_DISABLED),snapshot:o.snapshot(),sink:l,transport:c.lastTransport(),lastDiagnostic:u}),c.query)}})}}const g=h();exports.createDoomLogExtension=h,exports.createPiTelemetryExtension=f,exports.doomLogExtension=g,exports.openLogMetricsOverlay=m,exports.registerLogMetricsLeaderBinding=p;
|
|
2
2
|
//# sourceMappingURL=extension.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"extension.cjs","names":["createDoomTelemetry","registerDoomLeaderContribution","LogMetricsOverlayComponent","LogMetricsAggregator","createMetricsSource"],"sources":["../../../src/adapters/pi/extension.ts"],"sourcesContent":["/**\n * Pi telemetry wiring for the Doom harness.\n *\n * This extension deliberately emits metadata-only records. Prompt, message,\n * tool payload, file path, diagnostic text, exception, and stack data never\n * cross the shared telemetry boundary.\n */\n\nimport { registerDoomLeaderContribution } from '@agimon-ai/doompi-extension-contracts/leader';\nimport { createDoomTelemetry, type DoomTelemetry, type DoomTelemetryOptions } from '@agimon-ai/doompi-telemetry';\nimport type { ExtensionAPI, ExtensionContext, TurnEndEvent } from '@earendil-works/pi-coding-agent';\nimport { LogMetricsAggregator, type LogMetricsRecorder } from '../../services/metrics.ts';\nimport { createMetricsSource, type MetricsQuery, type MetricsSource } from '../../services/metricsSource.ts';\nimport { LogMetricsOverlayComponent, type LogMetricsView, type SinkStatus } from '../../tui/metricsOverlay.ts';\n\nconst SERVICE_NAME = 'pi';\nconst PACKAGE_NAME = '@agimon-ai/doompi-log';\n/** Opt back into stderr diagnostics when debugging outside a live TUI. */\nconst DIAGNOSTICS_STDERR = 'stderr';\nconst LEADER_SOURCE = '@agimon-ai/doompi-log';\nconst LOG_METRICS_COMMAND = 'log-metrics';\nconst LOG_METRICS_DESCRIPTION = 'Show session-local log metrics';\nconst HELP_GROUP_ORDER = 70;\nconst NO_ENDPOINT = 'none';\nconst API_ERROR_STATUS = 400;\nconst FAILURE_STOP_REASONS = new Set(['error', 'aborted']);\n\ntype TelemetryFactory = NonNullable<DoomTelemetryOptions['telemetryFactory']>;\ntype TelemetryAttributes = Record<string, string | number | boolean>;\ntype RecordLevel = 'debug' | 'info' | 'warn' | 'error';\n\nexport interface PiTelemetryExtensionOptions {\n allowFileFallback?: boolean;\n /** Overrides the telemetry service identity. */\n serviceName?: string;\n /** Overrides the leader contribution owner. */\n leaderSource?: string;\n env?: NodeJS.ProcessEnv;\n telemetryFactory?: TelemetryFactory;\n /** Receives every sanitized record, whether or not a sink is live. */\n metrics?: LogMetricsRecorder;\n /** Called once the sink backend is resolved, so the overlay can report it. */\n onSinkStatus?: (status: SinkStatus | undefined) => void;\n /** Overrides the sink-history transport; injected in tests. */\n metricsSource?: MetricsSource;\n /** Receives telemetry lifecycle failures without writing into the TUI. */\n onDiagnostic?: (message: string) => void;\n}\n\nfunction isEnabled(value: string | undefined): boolean {\n return value === '1' || value?.toLowerCase() === 'true' || value?.toLowerCase() === 'yes';\n}\n\nfunction contextAttributes(ctx: ExtensionContext): TelemetryAttributes {\n const attributes: TelemetryAttributes = {\n 'pi.mode': ctx.mode,\n 'pi.session.id': ctx.sessionManager.getSessionId(),\n };\n if (ctx.thinkingLevel) attributes['pi.thinking_level'] = ctx.thinkingLevel;\n if (ctx.model) {\n attributes['gen_ai.provider.name'] = ctx.model.provider;\n attributes['gen_ai.request.model'] = ctx.model.id;\n }\n return attributes;\n}\n\nfunction usageAttributes(message: TurnEndEvent['message']): TelemetryAttributes | undefined {\n if (message.role !== 'assistant') return undefined;\n const attributes: TelemetryAttributes = {\n 'gen_ai.response.model': message.responseModel ?? message.model,\n 'gen_ai.response.finish_reasons': message.stopReason,\n 'gen_ai.usage.input_tokens': message.usage.input,\n 'gen_ai.usage.output_tokens': message.usage.output,\n 'gen_ai.usage.cache_read_tokens': message.usage.cacheRead,\n 'gen_ai.usage.cache_write_tokens': message.usage.cacheWrite,\n 'gen_ai.usage.total_tokens': message.usage.totalTokens,\n 'gen_ai.usage.cost': message.usage.cost.total,\n };\n if (message.usage.reasoning !== undefined) attributes['gen_ai.usage.reasoning_tokens'] = message.usage.reasoning;\n return attributes;\n}\n\nfunction failureAttributes(message: TurnEndEvent['message']): TelemetryAttributes {\n if (message.role !== 'assistant') return { 'error.type': 'AgentError', outcome: 'error' };\n const aborted = message.stopReason === 'aborted';\n return {\n 'error.type': 'ProviderError',\n 'error.code': message.stopReason,\n outcome: aborted ? 'aborted' : 'error',\n };\n}\n\nfunction statusFromTelemetry(status: ReturnType<DoomTelemetry['status']>): SinkStatus {\n return {\n service: status.serviceName,\n backend: status.backend,\n endpoint: status.endpoint ?? NO_ENDPOINT,\n endpointSource: status.endpointSource,\n traces: status.traces,\n redaction: true,\n fileFallback: status.fileFallback,\n };\n}\n\nexport function createPiTelemetryExtension(options: PiTelemetryExtensionOptions = {}) {\n return function registerPiTelemetry(pi: ExtensionAPI): void {\n const env = options.env ?? process.env;\n const metrics = options.metrics;\n const toolStartedAt = new Map<string, number>();\n let agentStartedAt: number | undefined;\n let telemetry: DoomTelemetry | undefined;\n\n const emit = async (level: RecordLevel, name: string, attributes: TelemetryAttributes): Promise<void> => {\n if (!telemetry) return;\n if (level === 'debug') await telemetry.recordDebug(name, attributes);\n else if (level === 'warn') await telemetry.recordWarning(name, undefined, attributes);\n else if (level === 'error') await telemetry.recordError(name, undefined, attributes);\n else await telemetry.recordEvent(name, attributes);\n };\n\n const getTelemetry = (ctx: ExtensionContext): DoomTelemetry => {\n telemetry ??= createDoomTelemetry({\n serviceName: options.serviceName ?? SERVICE_NAME,\n packageName: PACKAGE_NAME,\n cwd: ctx.cwd,\n env,\n allowFileFallback: options.allowFileFallback,\n telemetryFactory: options.telemetryFactory,\n warn: options.onDiagnostic,\n enableLogs: true,\n enableTraces: env.AGENT_OTEL_TRACES === undefined || isEnabled(env.AGENT_OTEL_TRACES),\n onRecord: (record) => metrics?.record(record.event, record.attributes),\n onStatus: (status) => options.onSinkStatus?.(statusFromTelemetry(status)),\n });\n options.onSinkStatus?.(statusFromTelemetry(telemetry.status()));\n return telemetry;\n };\n\n pi.on('session_start', async (event, ctx) => {\n getTelemetry(ctx);\n await emit('info', 'pi.session.started', {\n ...contextAttributes(ctx),\n 'pi.session.reason': event.reason,\n 'pi.session.previous': event.previousSessionFile !== undefined,\n });\n });\n\n pi.on('before_agent_start', async (event, ctx) => {\n getTelemetry(ctx);\n await emit('info', 'pi.user_prompt', {\n ...contextAttributes(ctx),\n 'pi.user_message.length': event.prompt.length,\n 'pi.user_message.image_count': event.images?.length ?? 0,\n });\n });\n\n pi.on('agent_start', async (_event, ctx) => {\n agentStartedAt = Date.now();\n getTelemetry(ctx);\n await emit('info', 'pi.agent.started', contextAttributes(ctx));\n });\n\n pi.on('turn_start', async (event, ctx) => {\n getTelemetry(ctx);\n await emit('debug', 'pi.turn.started', {\n ...contextAttributes(ctx),\n 'pi.turn.index': event.turnIndex,\n });\n });\n\n pi.on('turn_end', async (event, ctx) => {\n getTelemetry(ctx);\n const usage = usageAttributes(event.message);\n await emit('info', 'pi.turn.finished', {\n ...contextAttributes(ctx),\n 'pi.turn.index': event.turnIndex,\n 'pi.tool_result.count': event.toolResults.length,\n ...usage,\n });\n if (event.message.role === 'assistant' && FAILURE_STOP_REASONS.has(event.message.stopReason)) {\n await emit(event.message.stopReason === 'aborted' ? 'warn' : 'error', 'pi.turn.failed', {\n ...contextAttributes(ctx),\n 'pi.turn.index': event.turnIndex,\n ...failureAttributes(event.message),\n ...usage,\n });\n }\n if (!usage) return;\n for (const result of event.toolResults) {\n await emit('debug', 'pi.tool_token_sample', {\n ...contextAttributes(ctx),\n ...usage,\n 'tool.name': result.toolName,\n token_attribution: 'toolCallTurn',\n });\n }\n });\n\n pi.on('tool_execution_start', async (event, ctx) => {\n toolStartedAt.set(event.toolCallId, Date.now());\n getTelemetry(ctx);\n await emit('debug', 'pi.tool_call', {\n ...contextAttributes(ctx),\n 'tool.name': event.toolName,\n 'tool.call.id': event.toolCallId,\n });\n });\n\n pi.on('tool_execution_end', async (event, ctx) => {\n const startedAt = toolStartedAt.get(event.toolCallId);\n toolStartedAt.delete(event.toolCallId);\n getTelemetry(ctx);\n await emit('info', 'pi.tool_result', {\n ...contextAttributes(ctx),\n success: !event.isError,\n 'tool.name': event.toolName,\n 'tool.call.id': event.toolCallId,\n 'tool.result.error': event.isError,\n ...(startedAt === undefined ? {} : { 'tool.duration_ms': Date.now() - startedAt }),\n });\n });\n\n pi.on('after_provider_response', async (event, ctx) => {\n getTelemetry(ctx);\n const attributes = {\n ...contextAttributes(ctx),\n 'http.response.status_code': event.status,\n };\n if (event.status >= API_ERROR_STATUS) await emit('error', 'pi.api_error', attributes);\n else await emit('debug', 'pi.api_response', attributes);\n });\n\n pi.on('model_select', async (event, ctx) => {\n getTelemetry(ctx);\n await emit('info', 'pi.model.selected', {\n ...contextAttributes(ctx),\n 'pi.model.source': event.source,\n 'gen_ai.provider.name': event.model.provider,\n 'gen_ai.request.model': event.model.id,\n });\n });\n\n pi.on('agent_end', async (event, ctx) => {\n getTelemetry(ctx);\n await emit('info', 'pi.agent.finished', {\n ...contextAttributes(ctx),\n 'pi.message.count': event.messages.length,\n ...(agentStartedAt === undefined ? {} : { 'pi.agent.duration_ms': Date.now() - agentStartedAt }),\n });\n agentStartedAt = undefined;\n await telemetry?.flush();\n });\n\n pi.on('agent_settled', async (_event, ctx) => {\n getTelemetry(ctx);\n await emit('debug', 'pi.agent.settled', contextAttributes(ctx));\n });\n\n pi.on('session_shutdown', async (event, ctx) => {\n getTelemetry(ctx);\n await emit('info', 'pi.session.finished', {\n ...contextAttributes(ctx),\n 'pi.session.reason': event.reason,\n });\n await telemetry?.shutdown();\n });\n };\n}\n\nexport function registerLogMetricsLeaderBinding(\n pi: Pick<ExtensionAPI, 'events' | 'on'>,\n options: { source?: string } = {},\n): () => void {\n return registerDoomLeaderContribution(pi, {\n source: options.source ?? LEADER_SOURCE,\n bindings: [\n {\n id: 'log.metrics',\n path: [\n { key: 'h', label: 'help', order: HELP_GROUP_ORDER },\n { key: 'l', label: 'logs', detail: 'telemetry' },\n ],\n command: { name: LOG_METRICS_COMMAND },\n },\n ],\n });\n}\n\nexport async function openLogMetricsOverlay(\n ctx: ExtensionContext,\n getView: () => LogMetricsView,\n query?: MetricsQuery,\n): Promise<void> {\n await ctx.ui.custom<undefined>(\n (tui, theme, _keybindings, done) => new LogMetricsOverlayComponent(tui, theme, getView, done, query),\n {\n overlay: true,\n overlayOptions: {\n anchor: 'top-left',\n width: '100%',\n maxHeight: '100%',\n margin: 0,\n },\n },\n );\n}\n\nexport function createDoomLogExtension(options: PiTelemetryExtensionOptions = {}) {\n return function registerDoomLog(pi: ExtensionAPI): void {\n const env = options.env ?? process.env;\n const metrics = new LogMetricsAggregator();\n const metricsSource = options.metricsSource ?? createMetricsSource({ env });\n let sink: SinkStatus | undefined;\n let lastDiagnostic: string | undefined;\n\n createPiTelemetryExtension({\n ...options,\n metrics,\n // Always supply a sink so doom-telemetry never falls back to\n // process.emitWarning, which writes raw stderr over the TUI frame.\n // Diagnostics surface in the Log Metrics overlay instead.\n onDiagnostic: (message) => {\n lastDiagnostic = message;\n if (options.onDiagnostic) options.onDiagnostic(message);\n else if (env.AGENT_OTEL_DIAGNOSTICS === DIAGNOSTICS_STDERR) process.emitWarning(message);\n },\n onSinkStatus: (status) => {\n sink = status;\n options.onSinkStatus?.(status);\n },\n })(pi);\n\n registerLogMetricsLeaderBinding(pi, { source: options.leaderSource });\n pi.registerCommand(LOG_METRICS_COMMAND, {\n description: LOG_METRICS_DESCRIPTION,\n handler: async (_args, ctx) => {\n await openLogMetricsOverlay(\n ctx,\n () => ({\n disabled: isEnabled(env.AGENT_TELEMETRY_DISABLED) || isEnabled(env.OTEL_SDK_DISABLED),\n snapshot: metrics.snapshot(),\n sink,\n transport: metricsSource.lastTransport(),\n lastDiagnostic,\n }),\n metricsSource.query,\n );\n },\n });\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"extension.cjs","names":["createDoomTelemetry","registerDoomLeaderContribution","LogMetricsOverlayComponent","LogMetricsAggregator","createMetricsSource"],"sources":["../../../src/adapters/pi/extension.ts"],"sourcesContent":["/**\n * Pi telemetry wiring for the Doom harness.\n *\n * This extension deliberately emits metadata-only records. Prompt, message,\n * tool payload, file path, diagnostic text, exception, and stack data never\n * cross the shared telemetry boundary.\n */\n\nimport { registerDoomLeaderContribution } from '@agimon-ai/doompi-extension-contracts/leader';\nimport { createDoomTelemetry, type DoomTelemetry, type DoomTelemetryOptions } from '@agimon-ai/doompi-telemetry';\nimport type { ExtensionAPI, ExtensionContext, TurnEndEvent } from '@earendil-works/pi-coding-agent';\nimport { LogMetricsAggregator, type LogMetricsRecorder } from '../../services/metrics.ts';\nimport { LogMetricsOverlayComponent, type LogMetricsView, type SinkStatus } from '../../tui/logMetricsOverlay.ts';\nimport type { MetricsQuery, MetricsSource } from '../../types/metricsSource.ts';\nimport { createMetricsSource } from '../node/metricsSource.ts';\n\nconst SERVICE_NAME = 'pi';\nconst PACKAGE_NAME = '@agimon-ai/doompi-log';\n/** Opt back into stderr diagnostics when debugging outside a live TUI. */\nconst DIAGNOSTICS_STDERR = 'stderr';\nconst LEADER_SOURCE = '@agimon-ai/doompi-log';\nconst LOG_METRICS_COMMAND = 'log-metrics';\nconst LOG_METRICS_DESCRIPTION = 'Show session-local log metrics';\nconst HELP_GROUP_ORDER = 70;\nconst NO_ENDPOINT = 'none';\nconst API_ERROR_STATUS = 400;\nconst FAILURE_STOP_REASONS = new Set(['error', 'aborted']);\n\ntype TelemetryFactory = NonNullable<DoomTelemetryOptions['telemetryFactory']>;\ntype TelemetryAttributes = Record<string, string | number | boolean>;\ntype RecordLevel = 'debug' | 'info' | 'warn' | 'error';\n\nexport interface PiTelemetryExtensionOptions {\n allowFileFallback?: boolean;\n /** Overrides the telemetry service identity. */\n serviceName?: string;\n /** Overrides the leader contribution owner. */\n leaderSource?: string;\n env?: NodeJS.ProcessEnv;\n telemetryFactory?: TelemetryFactory;\n /** Receives every sanitized record, whether or not a sink is live. */\n metrics?: LogMetricsRecorder;\n /** Called once the sink backend is resolved, so the overlay can report it. */\n onSinkStatus?: (status: SinkStatus | undefined) => void;\n /** Overrides the sink-history transport; injected in tests. */\n metricsSource?: MetricsSource;\n /** Receives telemetry lifecycle failures without writing into the TUI. */\n onDiagnostic?: (message: string) => void;\n}\n\nfunction isEnabled(value: string | undefined): boolean {\n return value === '1' || value?.toLowerCase() === 'true' || value?.toLowerCase() === 'yes';\n}\n\nfunction contextAttributes(ctx: ExtensionContext): TelemetryAttributes {\n const attributes: TelemetryAttributes = {\n 'pi.mode': ctx.mode,\n 'pi.session.id': ctx.sessionManager.getSessionId(),\n };\n if (ctx.thinkingLevel) attributes['pi.thinking_level'] = ctx.thinkingLevel;\n if (ctx.model) {\n attributes['gen_ai.provider.name'] = ctx.model.provider;\n attributes['gen_ai.request.model'] = ctx.model.id;\n }\n return attributes;\n}\n\nfunction usageAttributes(message: TurnEndEvent['message']): TelemetryAttributes | undefined {\n if (message.role !== 'assistant') return undefined;\n const attributes: TelemetryAttributes = {\n 'gen_ai.response.model': message.responseModel ?? message.model,\n 'gen_ai.response.finish_reasons': message.stopReason,\n 'gen_ai.usage.input_tokens': message.usage.input,\n 'gen_ai.usage.output_tokens': message.usage.output,\n 'gen_ai.usage.cache_read_tokens': message.usage.cacheRead,\n 'gen_ai.usage.cache_write_tokens': message.usage.cacheWrite,\n 'gen_ai.usage.total_tokens': message.usage.totalTokens,\n 'gen_ai.usage.cost': message.usage.cost.total,\n };\n if (message.usage.reasoning !== undefined) attributes['gen_ai.usage.reasoning_tokens'] = message.usage.reasoning;\n return attributes;\n}\n\nfunction failureAttributes(message: TurnEndEvent['message']): TelemetryAttributes {\n if (message.role !== 'assistant') return { 'error.type': 'AgentError', outcome: 'error' };\n const aborted = message.stopReason === 'aborted';\n return {\n 'error.type': 'ProviderError',\n 'error.code': message.stopReason,\n outcome: aborted ? 'aborted' : 'error',\n };\n}\n\nfunction statusFromTelemetry(status: ReturnType<DoomTelemetry['status']>): SinkStatus {\n return {\n service: status.serviceName,\n backend: status.backend,\n endpoint: status.endpoint ?? NO_ENDPOINT,\n endpointSource: status.endpointSource,\n traces: status.traces,\n redaction: true,\n fileFallback: status.fileFallback,\n };\n}\n\nexport function createPiTelemetryExtension(options: PiTelemetryExtensionOptions = {}) {\n return function registerPiTelemetry(pi: ExtensionAPI): void {\n const env = options.env ?? process.env;\n const metrics = options.metrics;\n const toolStartedAt = new Map<string, number>();\n let agentStartedAt: number | undefined;\n let telemetry: DoomTelemetry | undefined;\n\n const emit = async (level: RecordLevel, name: string, attributes: TelemetryAttributes): Promise<void> => {\n if (!telemetry) return;\n if (level === 'debug') await telemetry.recordDebug(name, attributes);\n else if (level === 'warn') await telemetry.recordWarning(name, undefined, attributes);\n else if (level === 'error') await telemetry.recordError(name, undefined, attributes);\n else await telemetry.recordEvent(name, attributes);\n };\n\n const getTelemetry = (ctx: ExtensionContext): DoomTelemetry => {\n telemetry ??= createDoomTelemetry({\n serviceName: options.serviceName ?? SERVICE_NAME,\n packageName: PACKAGE_NAME,\n cwd: ctx.cwd,\n env,\n allowFileFallback: options.allowFileFallback,\n telemetryFactory: options.telemetryFactory,\n warn: options.onDiagnostic,\n enableLogs: true,\n enableTraces: env.AGENT_OTEL_TRACES === undefined || isEnabled(env.AGENT_OTEL_TRACES),\n onRecord: (record) => metrics?.record(record.event, record.attributes),\n onStatus: (status) => options.onSinkStatus?.(statusFromTelemetry(status)),\n });\n options.onSinkStatus?.(statusFromTelemetry(telemetry.status()));\n return telemetry;\n };\n\n pi.on('session_start', async (event, ctx) => {\n getTelemetry(ctx);\n await emit('info', 'pi.session.started', {\n ...contextAttributes(ctx),\n 'pi.session.reason': event.reason,\n 'pi.session.previous': event.previousSessionFile !== undefined,\n });\n });\n\n pi.on('before_agent_start', async (event, ctx) => {\n getTelemetry(ctx);\n await emit('info', 'pi.user_prompt', {\n ...contextAttributes(ctx),\n 'pi.user_message.length': event.prompt.length,\n 'pi.user_message.image_count': event.images?.length ?? 0,\n });\n });\n\n pi.on('agent_start', async (_event, ctx) => {\n agentStartedAt = Date.now();\n getTelemetry(ctx);\n await emit('info', 'pi.agent.started', contextAttributes(ctx));\n });\n\n pi.on('turn_start', async (event, ctx) => {\n getTelemetry(ctx);\n await emit('debug', 'pi.turn.started', {\n ...contextAttributes(ctx),\n 'pi.turn.index': event.turnIndex,\n });\n });\n\n pi.on('turn_end', async (event, ctx) => {\n getTelemetry(ctx);\n const usage = usageAttributes(event.message);\n await emit('info', 'pi.turn.finished', {\n ...contextAttributes(ctx),\n 'pi.turn.index': event.turnIndex,\n 'pi.tool_result.count': event.toolResults.length,\n ...usage,\n });\n if (event.message.role === 'assistant' && FAILURE_STOP_REASONS.has(event.message.stopReason)) {\n await emit(event.message.stopReason === 'aborted' ? 'warn' : 'error', 'pi.turn.failed', {\n ...contextAttributes(ctx),\n 'pi.turn.index': event.turnIndex,\n ...failureAttributes(event.message),\n ...usage,\n });\n }\n if (!usage) return;\n for (const result of event.toolResults) {\n await emit('debug', 'pi.tool_token_sample', {\n ...contextAttributes(ctx),\n ...usage,\n 'tool.name': result.toolName,\n token_attribution: 'toolCallTurn',\n });\n }\n });\n\n pi.on('tool_execution_start', async (event, ctx) => {\n toolStartedAt.set(event.toolCallId, Date.now());\n getTelemetry(ctx);\n await emit('debug', 'pi.tool_call', {\n ...contextAttributes(ctx),\n 'tool.name': event.toolName,\n 'tool.call.id': event.toolCallId,\n });\n });\n\n pi.on('tool_execution_end', async (event, ctx) => {\n const startedAt = toolStartedAt.get(event.toolCallId);\n toolStartedAt.delete(event.toolCallId);\n getTelemetry(ctx);\n await emit('info', 'pi.tool_result', {\n ...contextAttributes(ctx),\n success: !event.isError,\n 'tool.name': event.toolName,\n 'tool.call.id': event.toolCallId,\n 'tool.result.error': event.isError,\n ...(startedAt === undefined ? {} : { 'tool.duration_ms': Date.now() - startedAt }),\n });\n });\n\n pi.on('after_provider_response', async (event, ctx) => {\n getTelemetry(ctx);\n const attributes = {\n ...contextAttributes(ctx),\n 'http.response.status_code': event.status,\n };\n if (event.status >= API_ERROR_STATUS) await emit('error', 'pi.api_error', attributes);\n else await emit('debug', 'pi.api_response', attributes);\n });\n\n pi.on('model_select', async (event, ctx) => {\n getTelemetry(ctx);\n await emit('info', 'pi.model.selected', {\n ...contextAttributes(ctx),\n 'pi.model.source': event.source,\n 'gen_ai.provider.name': event.model.provider,\n 'gen_ai.request.model': event.model.id,\n });\n });\n\n pi.on('agent_end', async (event, ctx) => {\n getTelemetry(ctx);\n await emit('info', 'pi.agent.finished', {\n ...contextAttributes(ctx),\n 'pi.message.count': event.messages.length,\n ...(agentStartedAt === undefined ? {} : { 'pi.agent.duration_ms': Date.now() - agentStartedAt }),\n });\n agentStartedAt = undefined;\n await telemetry?.flush();\n });\n\n pi.on('agent_settled', async (_event, ctx) => {\n getTelemetry(ctx);\n await emit('debug', 'pi.agent.settled', contextAttributes(ctx));\n });\n\n pi.on('session_shutdown', async (event, ctx) => {\n getTelemetry(ctx);\n await emit('info', 'pi.session.finished', {\n ...contextAttributes(ctx),\n 'pi.session.reason': event.reason,\n });\n await telemetry?.shutdown();\n });\n };\n}\n\nexport function registerLogMetricsLeaderBinding(\n pi: Pick<ExtensionAPI, 'events' | 'on'>,\n options: { source?: string } = {},\n): () => void {\n return registerDoomLeaderContribution(pi, {\n source: options.source ?? LEADER_SOURCE,\n bindings: [\n {\n id: 'log.metrics',\n path: [\n { key: 'h', label: 'help', order: HELP_GROUP_ORDER },\n { key: 'l', label: 'logs', detail: 'telemetry' },\n ],\n command: { name: LOG_METRICS_COMMAND },\n },\n ],\n });\n}\n\nexport async function openLogMetricsOverlay(\n ctx: ExtensionContext,\n getView: () => LogMetricsView,\n query?: MetricsQuery,\n): Promise<void> {\n await ctx.ui.custom<undefined>(\n (tui, theme, _keybindings, done) => new LogMetricsOverlayComponent(tui, theme, getView, done, query),\n {\n overlay: true,\n overlayOptions: {\n anchor: 'top-left',\n width: '100%',\n maxHeight: '100%',\n margin: 0,\n },\n },\n );\n}\n\nexport function createDoomLogExtension(options: PiTelemetryExtensionOptions = {}) {\n return function registerDoomLog(pi: ExtensionAPI): void {\n const env = options.env ?? process.env;\n const metrics = new LogMetricsAggregator();\n const metricsSource = options.metricsSource ?? createMetricsSource({ env });\n let sink: SinkStatus | undefined;\n let lastDiagnostic: string | undefined;\n\n createPiTelemetryExtension({\n ...options,\n metrics,\n // Always supply a sink so doom-telemetry never falls back to\n // process.emitWarning, which writes raw stderr over the TUI frame.\n // Diagnostics surface in the Log Metrics overlay instead.\n onDiagnostic: (message) => {\n lastDiagnostic = message;\n if (options.onDiagnostic) options.onDiagnostic(message);\n else if (env.AGENT_OTEL_DIAGNOSTICS === DIAGNOSTICS_STDERR) process.emitWarning(message);\n },\n onSinkStatus: (status) => {\n sink = status;\n options.onSinkStatus?.(status);\n },\n })(pi);\n\n registerLogMetricsLeaderBinding(pi, { source: options.leaderSource });\n pi.registerCommand(LOG_METRICS_COMMAND, {\n description: LOG_METRICS_DESCRIPTION,\n handler: async (_args, ctx) => {\n await openLogMetricsOverlay(\n ctx,\n () => ({\n disabled: isEnabled(env.AGENT_TELEMETRY_DISABLED) || isEnabled(env.OTEL_SDK_DISABLED),\n snapshot: metrics.snapshot(),\n sink,\n transport: metricsSource.lastTransport(),\n lastDiagnostic,\n }),\n metricsSource.query,\n );\n },\n });\n };\n}\n\nexport const doomLogExtension = createDoomLogExtension();\n"],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { LogMetricsRecorder } from "../../services/metrics.cjs";
|
|
2
|
-
import { MetricsQuery, MetricsSource } from "../../
|
|
3
|
-
import { LogMetricsView, SinkStatus } from "../../tui/
|
|
2
|
+
import { MetricsQuery, MetricsSource } from "../../types/metricsSource.cjs";
|
|
3
|
+
import { LogMetricsView, SinkStatus } from "../../tui/logMetricsOverlay.cjs";
|
|
4
4
|
import { DoomTelemetryOptions } from "@agimon-ai/doompi-telemetry";
|
|
5
5
|
import { ExtensionAPI, ExtensionContext } from "@earendil-works/pi-coding-agent";
|
|
6
6
|
//#region src/adapters/pi/extension.d.ts
|
|
@@ -28,6 +28,7 @@ declare function registerLogMetricsLeaderBinding(pi: Pick<ExtensionAPI, 'events'
|
|
|
28
28
|
}): () => void;
|
|
29
29
|
declare function openLogMetricsOverlay(ctx: ExtensionContext, getView: () => LogMetricsView, query?: MetricsQuery): Promise<void>;
|
|
30
30
|
declare function createDoomLogExtension(options?: PiTelemetryExtensionOptions): (pi: ExtensionAPI) => void;
|
|
31
|
+
declare const doomLogExtension: (pi: ExtensionAPI) => void;
|
|
31
32
|
//#endregion
|
|
32
|
-
export { PiTelemetryExtensionOptions, createDoomLogExtension, createPiTelemetryExtension, openLogMetricsOverlay, registerLogMetricsLeaderBinding };
|
|
33
|
+
export { PiTelemetryExtensionOptions, createDoomLogExtension, createPiTelemetryExtension, doomLogExtension, openLogMetricsOverlay, registerLogMetricsLeaderBinding };
|
|
33
34
|
//# sourceMappingURL=extension.d.cts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"extension.d.cts","names":[],"sources":["../../../src/adapters/pi/extension.ts"],"mappings":";;;;;;
|
|
1
|
+
{"version":3,"file":"extension.d.cts","names":[],"sources":["../../../src/adapters/pi/extension.ts"],"mappings":";;;;;;KA4BK,mBAAmB,YAAY;UAInB;EACf;;EAEA;;EAEA;EACA,MAAM,OAAO;EACb,mBAAmB;;EAEnB,UAAU;;EAEV,gBAAgB,QAAQ;;EAExB,gBAAgB;;EAEhB,gBAAgB;;iBA0DF,2BAA2B,UAAS,+BACd,IAAI;iBAoK1B,gCACd,IAAI,KAAK,gCACT;EAAW;;iBAiBS,sBACpB,KAAK,kBACL,eAAe,gBACf,QAAQ,eACP;iBAea,uBAAuB,UAAS,+BACd,IAAI;cA4CzB,mBAAgB,IA5CS"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { LogMetricsRecorder } from "../../services/metrics.mjs";
|
|
2
|
-
import { MetricsQuery, MetricsSource } from "../../
|
|
3
|
-
import { LogMetricsView, SinkStatus } from "../../tui/
|
|
2
|
+
import { MetricsQuery, MetricsSource } from "../../types/metricsSource.mjs";
|
|
3
|
+
import { LogMetricsView, SinkStatus } from "../../tui/logMetricsOverlay.mjs";
|
|
4
4
|
import { DoomTelemetryOptions } from "@agimon-ai/doompi-telemetry";
|
|
5
5
|
import { ExtensionAPI, ExtensionContext } from "@earendil-works/pi-coding-agent";
|
|
6
6
|
//#region src/adapters/pi/extension.d.ts
|
|
@@ -28,6 +28,7 @@ declare function registerLogMetricsLeaderBinding(pi: Pick<ExtensionAPI, 'events'
|
|
|
28
28
|
}): () => void;
|
|
29
29
|
declare function openLogMetricsOverlay(ctx: ExtensionContext, getView: () => LogMetricsView, query?: MetricsQuery): Promise<void>;
|
|
30
30
|
declare function createDoomLogExtension(options?: PiTelemetryExtensionOptions): (pi: ExtensionAPI) => void;
|
|
31
|
+
declare const doomLogExtension: (pi: ExtensionAPI) => void;
|
|
31
32
|
//#endregion
|
|
32
|
-
export { PiTelemetryExtensionOptions, createDoomLogExtension, createPiTelemetryExtension, openLogMetricsOverlay, registerLogMetricsLeaderBinding };
|
|
33
|
+
export { PiTelemetryExtensionOptions, createDoomLogExtension, createPiTelemetryExtension, doomLogExtension, openLogMetricsOverlay, registerLogMetricsLeaderBinding };
|
|
33
34
|
//# sourceMappingURL=extension.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"extension.d.mts","names":[],"sources":["../../../src/adapters/pi/extension.ts"],"mappings":";;;;;;
|
|
1
|
+
{"version":3,"file":"extension.d.mts","names":[],"sources":["../../../src/adapters/pi/extension.ts"],"mappings":";;;;;;KA4BK,mBAAmB,YAAY;UAInB;EACf;;EAEA;;EAEA;EACA,MAAM,OAAO;EACb,mBAAmB;;EAEnB,UAAU;;EAEV,gBAAgB,QAAQ;;EAExB,gBAAgB;;EAEhB,gBAAgB;;iBA0DF,2BAA2B,UAAS,+BACd,IAAI;iBAoK1B,gCACd,IAAI,KAAK,gCACT;EAAW;;iBAiBS,sBACpB,KAAK,kBACL,eAAe,gBACf,QAAQ,eACP;iBAea,uBAAuB,UAAS,+BACd,IAAI;cA4CzB,mBAAgB,IA5CS"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{LogMetricsAggregator as e}from"../../services/metrics.mjs";import{
|
|
1
|
+
import{LogMetricsAggregator as e}from"../../services/metrics.mjs";import{LogMetricsOverlayComponent as t}from"../../tui/logMetricsOverlay.mjs";import{createMetricsSource as n}from"../node/metricsSource.mjs";import{registerDoomLeaderContribution as r}from"@agimon-ai/doompi-extension-contracts/leader";import{createDoomTelemetry as i}from"@agimon-ai/doompi-telemetry";const a=`log-metrics`,o=new Set([`error`,`aborted`]);function s(e){return e===`1`||e?.toLowerCase()===`true`||e?.toLowerCase()===`yes`}function c(e){let t={"pi.mode":e.mode,"pi.session.id":e.sessionManager.getSessionId()};return e.thinkingLevel&&(t[`pi.thinking_level`]=e.thinkingLevel),e.model&&(t[`gen_ai.provider.name`]=e.model.provider,t[`gen_ai.request.model`]=e.model.id),t}function l(e){if(e.role!==`assistant`)return;let t={"gen_ai.response.model":e.responseModel??e.model,"gen_ai.response.finish_reasons":e.stopReason,"gen_ai.usage.input_tokens":e.usage.input,"gen_ai.usage.output_tokens":e.usage.output,"gen_ai.usage.cache_read_tokens":e.usage.cacheRead,"gen_ai.usage.cache_write_tokens":e.usage.cacheWrite,"gen_ai.usage.total_tokens":e.usage.totalTokens,"gen_ai.usage.cost":e.usage.cost.total};return e.usage.reasoning!==void 0&&(t[`gen_ai.usage.reasoning_tokens`]=e.usage.reasoning),t}function u(e){if(e.role!==`assistant`)return{"error.type":`AgentError`,outcome:`error`};let t=e.stopReason===`aborted`;return{"error.type":`ProviderError`,"error.code":e.stopReason,outcome:t?`aborted`:`error`}}function d(e){return{service:e.serviceName,backend:e.backend,endpoint:e.endpoint??`none`,endpointSource:e.endpointSource,traces:e.traces,redaction:!0,fileFallback:e.fileFallback}}function f(e={}){return function(t){let n=e.env??process.env,r=e.metrics,a=new Map,f,p,m=async(e,t,n)=>{p&&(e===`debug`?await p.recordDebug(t,n):e===`warn`?await p.recordWarning(t,void 0,n):e===`error`?await p.recordError(t,void 0,n):await p.recordEvent(t,n))},h=t=>(p??=i({serviceName:e.serviceName??`pi`,packageName:`@agimon-ai/doompi-log`,cwd:t.cwd,env:n,allowFileFallback:e.allowFileFallback,telemetryFactory:e.telemetryFactory,warn:e.onDiagnostic,enableLogs:!0,enableTraces:n.AGENT_OTEL_TRACES===void 0||s(n.AGENT_OTEL_TRACES),onRecord:e=>r?.record(e.event,e.attributes),onStatus:t=>e.onSinkStatus?.(d(t))}),e.onSinkStatus?.(d(p.status())),p);t.on(`session_start`,async(e,t)=>{h(t),await m(`info`,`pi.session.started`,{...c(t),"pi.session.reason":e.reason,"pi.session.previous":e.previousSessionFile!==void 0})}),t.on(`before_agent_start`,async(e,t)=>{h(t),await m(`info`,`pi.user_prompt`,{...c(t),"pi.user_message.length":e.prompt.length,"pi.user_message.image_count":e.images?.length??0})}),t.on(`agent_start`,async(e,t)=>{f=Date.now(),h(t),await m(`info`,`pi.agent.started`,c(t))}),t.on(`turn_start`,async(e,t)=>{h(t),await m(`debug`,`pi.turn.started`,{...c(t),"pi.turn.index":e.turnIndex})}),t.on(`turn_end`,async(e,t)=>{h(t);let n=l(e.message);if(await m(`info`,`pi.turn.finished`,{...c(t),"pi.turn.index":e.turnIndex,"pi.tool_result.count":e.toolResults.length,...n}),e.message.role===`assistant`&&o.has(e.message.stopReason)&&await m(e.message.stopReason===`aborted`?`warn`:`error`,`pi.turn.failed`,{...c(t),"pi.turn.index":e.turnIndex,...u(e.message),...n}),n)for(let r of e.toolResults)await m(`debug`,`pi.tool_token_sample`,{...c(t),...n,"tool.name":r.toolName,token_attribution:`toolCallTurn`})}),t.on(`tool_execution_start`,async(e,t)=>{a.set(e.toolCallId,Date.now()),h(t),await m(`debug`,`pi.tool_call`,{...c(t),"tool.name":e.toolName,"tool.call.id":e.toolCallId})}),t.on(`tool_execution_end`,async(e,t)=>{let n=a.get(e.toolCallId);a.delete(e.toolCallId),h(t),await m(`info`,`pi.tool_result`,{...c(t),success:!e.isError,"tool.name":e.toolName,"tool.call.id":e.toolCallId,"tool.result.error":e.isError,...n===void 0?{}:{"tool.duration_ms":Date.now()-n}})}),t.on(`after_provider_response`,async(e,t)=>{h(t);let n={...c(t),"http.response.status_code":e.status};e.status>=400?await m(`error`,`pi.api_error`,n):await m(`debug`,`pi.api_response`,n)}),t.on(`model_select`,async(e,t)=>{h(t),await m(`info`,`pi.model.selected`,{...c(t),"pi.model.source":e.source,"gen_ai.provider.name":e.model.provider,"gen_ai.request.model":e.model.id})}),t.on(`agent_end`,async(e,t)=>{h(t),await m(`info`,`pi.agent.finished`,{...c(t),"pi.message.count":e.messages.length,...f===void 0?{}:{"pi.agent.duration_ms":Date.now()-f}}),f=void 0,await p?.flush()}),t.on(`agent_settled`,async(e,t)=>{h(t),await m(`debug`,`pi.agent.settled`,c(t))}),t.on(`session_shutdown`,async(e,t)=>{h(t),await m(`info`,`pi.session.finished`,{...c(t),"pi.session.reason":e.reason}),await p?.shutdown()})}}function p(e,t={}){return r(e,{source:t.source??`@agimon-ai/doompi-log`,bindings:[{id:`log.metrics`,path:[{key:`h`,label:`help`,order:70},{key:`l`,label:`logs`,detail:`telemetry`}],command:{name:a}}]})}async function m(e,n,r){await e.ui.custom((e,i,a,o)=>new t(e,i,n,o,r),{overlay:!0,overlayOptions:{anchor:`top-left`,width:`100%`,maxHeight:`100%`,margin:0}})}function h(t={}){return function(r){let i=t.env??process.env,o=new e,c=t.metricsSource??n({env:i}),l,u;f({...t,metrics:o,onDiagnostic:e=>{u=e,t.onDiagnostic?t.onDiagnostic(e):i.AGENT_OTEL_DIAGNOSTICS===`stderr`&&process.emitWarning(e)},onSinkStatus:e=>{l=e,t.onSinkStatus?.(e)}})(r),p(r,{source:t.leaderSource}),r.registerCommand(a,{description:`Show session-local log metrics`,handler:async(e,t)=>{await m(t,()=>({disabled:s(i.AGENT_TELEMETRY_DISABLED)||s(i.OTEL_SDK_DISABLED),snapshot:o.snapshot(),sink:l,transport:c.lastTransport(),lastDiagnostic:u}),c.query)}})}}const g=h();export{h as createDoomLogExtension,f as createPiTelemetryExtension,g as doomLogExtension,m as openLogMetricsOverlay,p as registerLogMetricsLeaderBinding};
|
|
2
2
|
//# sourceMappingURL=extension.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"extension.mjs","names":[],"sources":["../../../src/adapters/pi/extension.ts"],"sourcesContent":["/**\n * Pi telemetry wiring for the Doom harness.\n *\n * This extension deliberately emits metadata-only records. Prompt, message,\n * tool payload, file path, diagnostic text, exception, and stack data never\n * cross the shared telemetry boundary.\n */\n\nimport { registerDoomLeaderContribution } from '@agimon-ai/doompi-extension-contracts/leader';\nimport { createDoomTelemetry, type DoomTelemetry, type DoomTelemetryOptions } from '@agimon-ai/doompi-telemetry';\nimport type { ExtensionAPI, ExtensionContext, TurnEndEvent } from '@earendil-works/pi-coding-agent';\nimport { LogMetricsAggregator, type LogMetricsRecorder } from '../../services/metrics.ts';\nimport { createMetricsSource, type MetricsQuery, type MetricsSource } from '../../services/metricsSource.ts';\nimport { LogMetricsOverlayComponent, type LogMetricsView, type SinkStatus } from '../../tui/metricsOverlay.ts';\n\nconst SERVICE_NAME = 'pi';\nconst PACKAGE_NAME = '@agimon-ai/doompi-log';\n/** Opt back into stderr diagnostics when debugging outside a live TUI. */\nconst DIAGNOSTICS_STDERR = 'stderr';\nconst LEADER_SOURCE = '@agimon-ai/doompi-log';\nconst LOG_METRICS_COMMAND = 'log-metrics';\nconst LOG_METRICS_DESCRIPTION = 'Show session-local log metrics';\nconst HELP_GROUP_ORDER = 70;\nconst NO_ENDPOINT = 'none';\nconst API_ERROR_STATUS = 400;\nconst FAILURE_STOP_REASONS = new Set(['error', 'aborted']);\n\ntype TelemetryFactory = NonNullable<DoomTelemetryOptions['telemetryFactory']>;\ntype TelemetryAttributes = Record<string, string | number | boolean>;\ntype RecordLevel = 'debug' | 'info' | 'warn' | 'error';\n\nexport interface PiTelemetryExtensionOptions {\n allowFileFallback?: boolean;\n /** Overrides the telemetry service identity. */\n serviceName?: string;\n /** Overrides the leader contribution owner. */\n leaderSource?: string;\n env?: NodeJS.ProcessEnv;\n telemetryFactory?: TelemetryFactory;\n /** Receives every sanitized record, whether or not a sink is live. */\n metrics?: LogMetricsRecorder;\n /** Called once the sink backend is resolved, so the overlay can report it. */\n onSinkStatus?: (status: SinkStatus | undefined) => void;\n /** Overrides the sink-history transport; injected in tests. */\n metricsSource?: MetricsSource;\n /** Receives telemetry lifecycle failures without writing into the TUI. */\n onDiagnostic?: (message: string) => void;\n}\n\nfunction isEnabled(value: string | undefined): boolean {\n return value === '1' || value?.toLowerCase() === 'true' || value?.toLowerCase() === 'yes';\n}\n\nfunction contextAttributes(ctx: ExtensionContext): TelemetryAttributes {\n const attributes: TelemetryAttributes = {\n 'pi.mode': ctx.mode,\n 'pi.session.id': ctx.sessionManager.getSessionId(),\n };\n if (ctx.thinkingLevel) attributes['pi.thinking_level'] = ctx.thinkingLevel;\n if (ctx.model) {\n attributes['gen_ai.provider.name'] = ctx.model.provider;\n attributes['gen_ai.request.model'] = ctx.model.id;\n }\n return attributes;\n}\n\nfunction usageAttributes(message: TurnEndEvent['message']): TelemetryAttributes | undefined {\n if (message.role !== 'assistant') return undefined;\n const attributes: TelemetryAttributes = {\n 'gen_ai.response.model': message.responseModel ?? message.model,\n 'gen_ai.response.finish_reasons': message.stopReason,\n 'gen_ai.usage.input_tokens': message.usage.input,\n 'gen_ai.usage.output_tokens': message.usage.output,\n 'gen_ai.usage.cache_read_tokens': message.usage.cacheRead,\n 'gen_ai.usage.cache_write_tokens': message.usage.cacheWrite,\n 'gen_ai.usage.total_tokens': message.usage.totalTokens,\n 'gen_ai.usage.cost': message.usage.cost.total,\n };\n if (message.usage.reasoning !== undefined) attributes['gen_ai.usage.reasoning_tokens'] = message.usage.reasoning;\n return attributes;\n}\n\nfunction failureAttributes(message: TurnEndEvent['message']): TelemetryAttributes {\n if (message.role !== 'assistant') return { 'error.type': 'AgentError', outcome: 'error' };\n const aborted = message.stopReason === 'aborted';\n return {\n 'error.type': 'ProviderError',\n 'error.code': message.stopReason,\n outcome: aborted ? 'aborted' : 'error',\n };\n}\n\nfunction statusFromTelemetry(status: ReturnType<DoomTelemetry['status']>): SinkStatus {\n return {\n service: status.serviceName,\n backend: status.backend,\n endpoint: status.endpoint ?? NO_ENDPOINT,\n endpointSource: status.endpointSource,\n traces: status.traces,\n redaction: true,\n fileFallback: status.fileFallback,\n };\n}\n\nexport function createPiTelemetryExtension(options: PiTelemetryExtensionOptions = {}) {\n return function registerPiTelemetry(pi: ExtensionAPI): void {\n const env = options.env ?? process.env;\n const metrics = options.metrics;\n const toolStartedAt = new Map<string, number>();\n let agentStartedAt: number | undefined;\n let telemetry: DoomTelemetry | undefined;\n\n const emit = async (level: RecordLevel, name: string, attributes: TelemetryAttributes): Promise<void> => {\n if (!telemetry) return;\n if (level === 'debug') await telemetry.recordDebug(name, attributes);\n else if (level === 'warn') await telemetry.recordWarning(name, undefined, attributes);\n else if (level === 'error') await telemetry.recordError(name, undefined, attributes);\n else await telemetry.recordEvent(name, attributes);\n };\n\n const getTelemetry = (ctx: ExtensionContext): DoomTelemetry => {\n telemetry ??= createDoomTelemetry({\n serviceName: options.serviceName ?? SERVICE_NAME,\n packageName: PACKAGE_NAME,\n cwd: ctx.cwd,\n env,\n allowFileFallback: options.allowFileFallback,\n telemetryFactory: options.telemetryFactory,\n warn: options.onDiagnostic,\n enableLogs: true,\n enableTraces: env.AGENT_OTEL_TRACES === undefined || isEnabled(env.AGENT_OTEL_TRACES),\n onRecord: (record) => metrics?.record(record.event, record.attributes),\n onStatus: (status) => options.onSinkStatus?.(statusFromTelemetry(status)),\n });\n options.onSinkStatus?.(statusFromTelemetry(telemetry.status()));\n return telemetry;\n };\n\n pi.on('session_start', async (event, ctx) => {\n getTelemetry(ctx);\n await emit('info', 'pi.session.started', {\n ...contextAttributes(ctx),\n 'pi.session.reason': event.reason,\n 'pi.session.previous': event.previousSessionFile !== undefined,\n });\n });\n\n pi.on('before_agent_start', async (event, ctx) => {\n getTelemetry(ctx);\n await emit('info', 'pi.user_prompt', {\n ...contextAttributes(ctx),\n 'pi.user_message.length': event.prompt.length,\n 'pi.user_message.image_count': event.images?.length ?? 0,\n });\n });\n\n pi.on('agent_start', async (_event, ctx) => {\n agentStartedAt = Date.now();\n getTelemetry(ctx);\n await emit('info', 'pi.agent.started', contextAttributes(ctx));\n });\n\n pi.on('turn_start', async (event, ctx) => {\n getTelemetry(ctx);\n await emit('debug', 'pi.turn.started', {\n ...contextAttributes(ctx),\n 'pi.turn.index': event.turnIndex,\n });\n });\n\n pi.on('turn_end', async (event, ctx) => {\n getTelemetry(ctx);\n const usage = usageAttributes(event.message);\n await emit('info', 'pi.turn.finished', {\n ...contextAttributes(ctx),\n 'pi.turn.index': event.turnIndex,\n 'pi.tool_result.count': event.toolResults.length,\n ...usage,\n });\n if (event.message.role === 'assistant' && FAILURE_STOP_REASONS.has(event.message.stopReason)) {\n await emit(event.message.stopReason === 'aborted' ? 'warn' : 'error', 'pi.turn.failed', {\n ...contextAttributes(ctx),\n 'pi.turn.index': event.turnIndex,\n ...failureAttributes(event.message),\n ...usage,\n });\n }\n if (!usage) return;\n for (const result of event.toolResults) {\n await emit('debug', 'pi.tool_token_sample', {\n ...contextAttributes(ctx),\n ...usage,\n 'tool.name': result.toolName,\n token_attribution: 'toolCallTurn',\n });\n }\n });\n\n pi.on('tool_execution_start', async (event, ctx) => {\n toolStartedAt.set(event.toolCallId, Date.now());\n getTelemetry(ctx);\n await emit('debug', 'pi.tool_call', {\n ...contextAttributes(ctx),\n 'tool.name': event.toolName,\n 'tool.call.id': event.toolCallId,\n });\n });\n\n pi.on('tool_execution_end', async (event, ctx) => {\n const startedAt = toolStartedAt.get(event.toolCallId);\n toolStartedAt.delete(event.toolCallId);\n getTelemetry(ctx);\n await emit('info', 'pi.tool_result', {\n ...contextAttributes(ctx),\n success: !event.isError,\n 'tool.name': event.toolName,\n 'tool.call.id': event.toolCallId,\n 'tool.result.error': event.isError,\n ...(startedAt === undefined ? {} : { 'tool.duration_ms': Date.now() - startedAt }),\n });\n });\n\n pi.on('after_provider_response', async (event, ctx) => {\n getTelemetry(ctx);\n const attributes = {\n ...contextAttributes(ctx),\n 'http.response.status_code': event.status,\n };\n if (event.status >= API_ERROR_STATUS) await emit('error', 'pi.api_error', attributes);\n else await emit('debug', 'pi.api_response', attributes);\n });\n\n pi.on('model_select', async (event, ctx) => {\n getTelemetry(ctx);\n await emit('info', 'pi.model.selected', {\n ...contextAttributes(ctx),\n 'pi.model.source': event.source,\n 'gen_ai.provider.name': event.model.provider,\n 'gen_ai.request.model': event.model.id,\n });\n });\n\n pi.on('agent_end', async (event, ctx) => {\n getTelemetry(ctx);\n await emit('info', 'pi.agent.finished', {\n ...contextAttributes(ctx),\n 'pi.message.count': event.messages.length,\n ...(agentStartedAt === undefined ? {} : { 'pi.agent.duration_ms': Date.now() - agentStartedAt }),\n });\n agentStartedAt = undefined;\n await telemetry?.flush();\n });\n\n pi.on('agent_settled', async (_event, ctx) => {\n getTelemetry(ctx);\n await emit('debug', 'pi.agent.settled', contextAttributes(ctx));\n });\n\n pi.on('session_shutdown', async (event, ctx) => {\n getTelemetry(ctx);\n await emit('info', 'pi.session.finished', {\n ...contextAttributes(ctx),\n 'pi.session.reason': event.reason,\n });\n await telemetry?.shutdown();\n });\n };\n}\n\nexport function registerLogMetricsLeaderBinding(\n pi: Pick<ExtensionAPI, 'events' | 'on'>,\n options: { source?: string } = {},\n): () => void {\n return registerDoomLeaderContribution(pi, {\n source: options.source ?? LEADER_SOURCE,\n bindings: [\n {\n id: 'log.metrics',\n path: [\n { key: 'h', label: 'help', order: HELP_GROUP_ORDER },\n { key: 'l', label: 'logs', detail: 'telemetry' },\n ],\n command: { name: LOG_METRICS_COMMAND },\n },\n ],\n });\n}\n\nexport async function openLogMetricsOverlay(\n ctx: ExtensionContext,\n getView: () => LogMetricsView,\n query?: MetricsQuery,\n): Promise<void> {\n await ctx.ui.custom<undefined>(\n (tui, theme, _keybindings, done) => new LogMetricsOverlayComponent(tui, theme, getView, done, query),\n {\n overlay: true,\n overlayOptions: {\n anchor: 'top-left',\n width: '100%',\n maxHeight: '100%',\n margin: 0,\n },\n },\n );\n}\n\nexport function createDoomLogExtension(options: PiTelemetryExtensionOptions = {}) {\n return function registerDoomLog(pi: ExtensionAPI): void {\n const env = options.env ?? process.env;\n const metrics = new LogMetricsAggregator();\n const metricsSource = options.metricsSource ?? createMetricsSource({ env });\n let sink: SinkStatus | undefined;\n let lastDiagnostic: string | undefined;\n\n createPiTelemetryExtension({\n ...options,\n metrics,\n // Always supply a sink so doom-telemetry never falls back to\n // process.emitWarning, which writes raw stderr over the TUI frame.\n // Diagnostics surface in the Log Metrics overlay instead.\n onDiagnostic: (message) => {\n lastDiagnostic = message;\n if (options.onDiagnostic) options.onDiagnostic(message);\n else if (env.AGENT_OTEL_DIAGNOSTICS === DIAGNOSTICS_STDERR) process.emitWarning(message);\n },\n onSinkStatus: (status) => {\n sink = status;\n options.onSinkStatus?.(status);\n },\n })(pi);\n\n registerLogMetricsLeaderBinding(pi, { source: options.leaderSource });\n pi.registerCommand(LOG_METRICS_COMMAND, {\n description: LOG_METRICS_DESCRIPTION,\n handler: async (_args, ctx) => {\n await openLogMetricsOverlay(\n ctx,\n () => ({\n disabled: isEnabled(env.AGENT_TELEMETRY_DISABLED) || isEnabled(env.OTEL_SDK_DISABLED),\n snapshot: metrics.snapshot(),\n sink,\n transport: metricsSource.lastTransport(),\n lastDiagnostic,\n }),\n metricsSource.query,\n );\n },\n });\n };\n}\n"],"mappings":"mXAeA,MAKM,EAAsB,cAKtB,EAAuB,IAAI,IAAI,CAAC,QAAS,SAAS,CAAC,EAwBzD,SAAS,EAAU,EAAoC,CACrD,OAAO,IAAU,KAAO,GAAO,YAAY,IAAM,QAAU,GAAO,YAAY,IAAM,KACtF,CAEA,SAAS,EAAkB,EAA4C,CACrE,IAAM,EAAkC,CACtC,UAAW,EAAI,KACf,gBAAiB,EAAI,eAAe,aAAa,CACnD,EAMA,OALI,EAAI,gBAAe,EAAW,qBAAuB,EAAI,eACzD,EAAI,QACN,EAAW,wBAA0B,EAAI,MAAM,SAC/C,EAAW,wBAA0B,EAAI,MAAM,IAE1C,CACT,CAEA,SAAS,EAAgB,EAAmE,CAC1F,GAAI,EAAQ,OAAS,YAAa,OAClC,IAAM,EAAkC,CACtC,wBAAyB,EAAQ,eAAiB,EAAQ,MAC1D,iCAAkC,EAAQ,WAC1C,4BAA6B,EAAQ,MAAM,MAC3C,6BAA8B,EAAQ,MAAM,OAC5C,iCAAkC,EAAQ,MAAM,UAChD,kCAAmC,EAAQ,MAAM,WACjD,4BAA6B,EAAQ,MAAM,YAC3C,oBAAqB,EAAQ,MAAM,KAAK,KAC1C,EAEA,OADI,EAAQ,MAAM,YAAc,IAAA,KAAW,EAAW,iCAAmC,EAAQ,MAAM,WAChG,CACT,CAEA,SAAS,EAAkB,EAAuD,CAChF,GAAI,EAAQ,OAAS,YAAa,MAAO,CAAE,aAAc,aAAc,QAAS,OAAQ,EACxF,IAAM,EAAU,EAAQ,aAAe,UACvC,MAAO,CACL,aAAc,gBACd,aAAc,EAAQ,WACtB,QAAS,EAAU,UAAY,OACjC,CACF,CAEA,SAAS,EAAoB,EAAyD,CACpF,MAAO,CACL,QAAS,EAAO,YAChB,QAAS,EAAO,QAChB,SAAU,EAAO,UAAY,OAC7B,eAAgB,EAAO,eACvB,OAAQ,EAAO,OACf,UAAW,GACX,aAAc,EAAO,YACvB,CACF,CAEA,SAAgB,EAA2B,EAAuC,CAAC,EAAG,CACpF,OAAO,SAA6B,EAAwB,CAC1D,IAAM,EAAM,EAAQ,KAAO,QAAQ,IAC7B,EAAU,EAAQ,QAClB,EAAgB,IAAI,IACtB,EACA,EAEE,EAAO,MAAO,EAAoB,EAAc,IAAmD,CAClG,IACD,IAAU,QAAS,MAAM,EAAU,YAAY,EAAM,CAAU,EAC1D,IAAU,OAAQ,MAAM,EAAU,cAAc,EAAM,IAAA,GAAW,CAAU,EAC3E,IAAU,QAAS,MAAM,EAAU,YAAY,EAAM,IAAA,GAAW,CAAU,EAC9E,MAAM,EAAU,YAAY,EAAM,CAAU,EACnD,EAEM,EAAgB,IACpB,IAAc,EAAoB,CAChC,YAAa,EAAQ,aAAe,KACpC,YAAa,wBACb,IAAK,EAAI,IACT,MACA,kBAAmB,EAAQ,kBAC3B,iBAAkB,EAAQ,iBAC1B,KAAM,EAAQ,aACd,WAAY,GACZ,aAAc,EAAI,oBAAsB,IAAA,IAAa,EAAU,EAAI,iBAAiB,EACpF,SAAW,GAAW,GAAS,OAAO,EAAO,MAAO,EAAO,UAAU,EACrE,SAAW,GAAW,EAAQ,eAAe,EAAoB,CAAM,CAAC,CAC1E,CAAC,EACD,EAAQ,eAAe,EAAoB,EAAU,OAAO,CAAC,CAAC,EACvD,GAGT,EAAG,GAAG,gBAAiB,MAAO,EAAO,IAAQ,CAC3C,EAAa,CAAG,EAChB,MAAM,EAAK,OAAQ,qBAAsB,CACvC,GAAG,EAAkB,CAAG,EACxB,oBAAqB,EAAM,OAC3B,sBAAuB,EAAM,sBAAwB,IAAA,EACvD,CAAC,CACH,CAAC,EAED,EAAG,GAAG,qBAAsB,MAAO,EAAO,IAAQ,CAChD,EAAa,CAAG,EAChB,MAAM,EAAK,OAAQ,iBAAkB,CACnC,GAAG,EAAkB,CAAG,EACxB,yBAA0B,EAAM,OAAO,OACvC,8BAA+B,EAAM,QAAQ,QAAU,CACzD,CAAC,CACH,CAAC,EAED,EAAG,GAAG,cAAe,MAAO,EAAQ,IAAQ,CAC1C,EAAiB,KAAK,IAAI,EAC1B,EAAa,CAAG,EAChB,MAAM,EAAK,OAAQ,mBAAoB,EAAkB,CAAG,CAAC,CAC/D,CAAC,EAED,EAAG,GAAG,aAAc,MAAO,EAAO,IAAQ,CACxC,EAAa,CAAG,EAChB,MAAM,EAAK,QAAS,kBAAmB,CACrC,GAAG,EAAkB,CAAG,EACxB,gBAAiB,EAAM,SACzB,CAAC,CACH,CAAC,EAED,EAAG,GAAG,WAAY,MAAO,EAAO,IAAQ,CACtC,EAAa,CAAG,EAChB,IAAM,EAAQ,EAAgB,EAAM,OAAO,EAC3C,SAAM,EAAK,OAAQ,mBAAoB,CACrC,GAAG,EAAkB,CAAG,EACxB,gBAAiB,EAAM,UACvB,uBAAwB,EAAM,YAAY,OAC1C,GAAG,CACL,CAAC,EACG,EAAM,QAAQ,OAAS,aAAe,EAAqB,IAAI,EAAM,QAAQ,UAAU,GACzF,MAAM,EAAK,EAAM,QAAQ,aAAe,UAAY,OAAS,QAAS,iBAAkB,CACtF,GAAG,EAAkB,CAAG,EACxB,gBAAiB,EAAM,UACvB,GAAG,EAAkB,EAAM,OAAO,EAClC,GAAG,CACL,CAAC,EAEE,EACL,IAAK,IAAM,KAAU,EAAM,YACzB,MAAM,EAAK,QAAS,uBAAwB,CAC1C,GAAG,EAAkB,CAAG,EACxB,GAAG,EACH,YAAa,EAAO,SACpB,kBAAmB,cACrB,CAAC,CAEL,CAAC,EAED,EAAG,GAAG,uBAAwB,MAAO,EAAO,IAAQ,CAClD,EAAc,IAAI,EAAM,WAAY,KAAK,IAAI,CAAC,EAC9C,EAAa,CAAG,EAChB,MAAM,EAAK,QAAS,eAAgB,CAClC,GAAG,EAAkB,CAAG,EACxB,YAAa,EAAM,SACnB,eAAgB,EAAM,UACxB,CAAC,CACH,CAAC,EAED,EAAG,GAAG,qBAAsB,MAAO,EAAO,IAAQ,CAChD,IAAM,EAAY,EAAc,IAAI,EAAM,UAAU,EACpD,EAAc,OAAO,EAAM,UAAU,EACrC,EAAa,CAAG,EAChB,MAAM,EAAK,OAAQ,iBAAkB,CACnC,GAAG,EAAkB,CAAG,EACxB,QAAS,CAAC,EAAM,QAChB,YAAa,EAAM,SACnB,eAAgB,EAAM,WACtB,oBAAqB,EAAM,QAC3B,GAAI,IAAc,IAAA,GAAY,CAAC,EAAI,CAAE,mBAAoB,KAAK,IAAI,EAAI,CAAU,CAClF,CAAC,CACH,CAAC,EAED,EAAG,GAAG,0BAA2B,MAAO,EAAO,IAAQ,CACrD,EAAa,CAAG,EAChB,IAAM,EAAa,CACjB,GAAG,EAAkB,CAAG,EACxB,4BAA6B,EAAM,MACrC,EACI,EAAM,QAAU,IAAkB,MAAM,EAAK,QAAS,eAAgB,CAAU,EAC/E,MAAM,EAAK,QAAS,kBAAmB,CAAU,CACxD,CAAC,EAED,EAAG,GAAG,eAAgB,MAAO,EAAO,IAAQ,CAC1C,EAAa,CAAG,EAChB,MAAM,EAAK,OAAQ,oBAAqB,CACtC,GAAG,EAAkB,CAAG,EACxB,kBAAmB,EAAM,OACzB,uBAAwB,EAAM,MAAM,SACpC,uBAAwB,EAAM,MAAM,EACtC,CAAC,CACH,CAAC,EAED,EAAG,GAAG,YAAa,MAAO,EAAO,IAAQ,CACvC,EAAa,CAAG,EAChB,MAAM,EAAK,OAAQ,oBAAqB,CACtC,GAAG,EAAkB,CAAG,EACxB,mBAAoB,EAAM,SAAS,OACnC,GAAI,IAAmB,IAAA,GAAY,CAAC,EAAI,CAAE,uBAAwB,KAAK,IAAI,EAAI,CAAe,CAChG,CAAC,EACD,EAAiB,IAAA,GACjB,MAAM,GAAW,MAAM,CACzB,CAAC,EAED,EAAG,GAAG,gBAAiB,MAAO,EAAQ,IAAQ,CAC5C,EAAa,CAAG,EAChB,MAAM,EAAK,QAAS,mBAAoB,EAAkB,CAAG,CAAC,CAChE,CAAC,EAED,EAAG,GAAG,mBAAoB,MAAO,EAAO,IAAQ,CAC9C,EAAa,CAAG,EAChB,MAAM,EAAK,OAAQ,sBAAuB,CACxC,GAAG,EAAkB,CAAG,EACxB,oBAAqB,EAAM,MAC7B,CAAC,EACD,MAAM,GAAW,SAAS,CAC5B,CAAC,CACH,CACF,CAEA,SAAgB,EACd,EACA,EAA+B,CAAC,EACpB,CACZ,OAAO,EAA+B,EAAI,CACxC,OAAQ,EAAQ,QAAU,wBAC1B,SAAU,CACR,CACE,GAAI,cACJ,KAAM,CACJ,CAAE,IAAK,IAAK,MAAO,OAAQ,MAAO,EAAiB,EACnD,CAAE,IAAK,IAAK,MAAO,OAAQ,OAAQ,WAAY,CACjD,EACA,QAAS,CAAE,KAAM,CAAoB,CACvC,CACF,CACF,CAAC,CACH,CAEA,eAAsB,EACpB,EACA,EACA,EACe,CACf,MAAM,EAAI,GAAG,QACV,EAAK,EAAO,EAAc,IAAS,IAAI,EAA2B,EAAK,EAAO,EAAS,EAAM,CAAK,EACnG,CACE,QAAS,GACT,eAAgB,CACd,OAAQ,WACR,MAAO,OACP,UAAW,OACX,OAAQ,CACV,CACF,CACF,CACF,CAEA,SAAgB,EAAuB,EAAuC,CAAC,EAAG,CAChF,OAAO,SAAyB,EAAwB,CACtD,IAAM,EAAM,EAAQ,KAAO,QAAQ,IAC7B,EAAU,IAAI,EACd,EAAgB,EAAQ,eAAiB,EAAoB,CAAE,KAAI,CAAC,EACtE,EACA,EAEJ,EAA2B,CACzB,GAAG,EACH,UAIA,aAAe,GAAY,CACzB,EAAiB,EACb,EAAQ,aAAc,EAAQ,aAAa,CAAO,EAC7C,EAAI,yBAA2B,UAAoB,QAAQ,YAAY,CAAO,CACzF,EACA,aAAe,GAAW,CACxB,EAAO,EACP,EAAQ,eAAe,CAAM,CAC/B,CACF,CAAC,CAAC,CAAC,CAAE,EAEL,EAAgC,EAAI,CAAE,OAAQ,EAAQ,YAAa,CAAC,EACpE,EAAG,gBAAgB,EAAqB,CACtC,YAAa,iCACb,QAAS,MAAO,EAAO,IAAQ,CAC7B,MAAM,EACJ,OACO,CACL,SAAU,EAAU,EAAI,wBAAwB,GAAK,EAAU,EAAI,iBAAiB,EACpF,SAAU,EAAQ,SAAS,EAC3B,OACA,UAAW,EAAc,cAAc,EACvC,gBACF,GACA,EAAc,KAChB,CACF,CACF,CAAC,CACH,CACF"}
|
|
1
|
+
{"version":3,"file":"extension.mjs","names":[],"sources":["../../../src/adapters/pi/extension.ts"],"sourcesContent":["/**\n * Pi telemetry wiring for the Doom harness.\n *\n * This extension deliberately emits metadata-only records. Prompt, message,\n * tool payload, file path, diagnostic text, exception, and stack data never\n * cross the shared telemetry boundary.\n */\n\nimport { registerDoomLeaderContribution } from '@agimon-ai/doompi-extension-contracts/leader';\nimport { createDoomTelemetry, type DoomTelemetry, type DoomTelemetryOptions } from '@agimon-ai/doompi-telemetry';\nimport type { ExtensionAPI, ExtensionContext, TurnEndEvent } from '@earendil-works/pi-coding-agent';\nimport { LogMetricsAggregator, type LogMetricsRecorder } from '../../services/metrics.ts';\nimport { LogMetricsOverlayComponent, type LogMetricsView, type SinkStatus } from '../../tui/logMetricsOverlay.ts';\nimport type { MetricsQuery, MetricsSource } from '../../types/metricsSource.ts';\nimport { createMetricsSource } from '../node/metricsSource.ts';\n\nconst SERVICE_NAME = 'pi';\nconst PACKAGE_NAME = '@agimon-ai/doompi-log';\n/** Opt back into stderr diagnostics when debugging outside a live TUI. */\nconst DIAGNOSTICS_STDERR = 'stderr';\nconst LEADER_SOURCE = '@agimon-ai/doompi-log';\nconst LOG_METRICS_COMMAND = 'log-metrics';\nconst LOG_METRICS_DESCRIPTION = 'Show session-local log metrics';\nconst HELP_GROUP_ORDER = 70;\nconst NO_ENDPOINT = 'none';\nconst API_ERROR_STATUS = 400;\nconst FAILURE_STOP_REASONS = new Set(['error', 'aborted']);\n\ntype TelemetryFactory = NonNullable<DoomTelemetryOptions['telemetryFactory']>;\ntype TelemetryAttributes = Record<string, string | number | boolean>;\ntype RecordLevel = 'debug' | 'info' | 'warn' | 'error';\n\nexport interface PiTelemetryExtensionOptions {\n allowFileFallback?: boolean;\n /** Overrides the telemetry service identity. */\n serviceName?: string;\n /** Overrides the leader contribution owner. */\n leaderSource?: string;\n env?: NodeJS.ProcessEnv;\n telemetryFactory?: TelemetryFactory;\n /** Receives every sanitized record, whether or not a sink is live. */\n metrics?: LogMetricsRecorder;\n /** Called once the sink backend is resolved, so the overlay can report it. */\n onSinkStatus?: (status: SinkStatus | undefined) => void;\n /** Overrides the sink-history transport; injected in tests. */\n metricsSource?: MetricsSource;\n /** Receives telemetry lifecycle failures without writing into the TUI. */\n onDiagnostic?: (message: string) => void;\n}\n\nfunction isEnabled(value: string | undefined): boolean {\n return value === '1' || value?.toLowerCase() === 'true' || value?.toLowerCase() === 'yes';\n}\n\nfunction contextAttributes(ctx: ExtensionContext): TelemetryAttributes {\n const attributes: TelemetryAttributes = {\n 'pi.mode': ctx.mode,\n 'pi.session.id': ctx.sessionManager.getSessionId(),\n };\n if (ctx.thinkingLevel) attributes['pi.thinking_level'] = ctx.thinkingLevel;\n if (ctx.model) {\n attributes['gen_ai.provider.name'] = ctx.model.provider;\n attributes['gen_ai.request.model'] = ctx.model.id;\n }\n return attributes;\n}\n\nfunction usageAttributes(message: TurnEndEvent['message']): TelemetryAttributes | undefined {\n if (message.role !== 'assistant') return undefined;\n const attributes: TelemetryAttributes = {\n 'gen_ai.response.model': message.responseModel ?? message.model,\n 'gen_ai.response.finish_reasons': message.stopReason,\n 'gen_ai.usage.input_tokens': message.usage.input,\n 'gen_ai.usage.output_tokens': message.usage.output,\n 'gen_ai.usage.cache_read_tokens': message.usage.cacheRead,\n 'gen_ai.usage.cache_write_tokens': message.usage.cacheWrite,\n 'gen_ai.usage.total_tokens': message.usage.totalTokens,\n 'gen_ai.usage.cost': message.usage.cost.total,\n };\n if (message.usage.reasoning !== undefined) attributes['gen_ai.usage.reasoning_tokens'] = message.usage.reasoning;\n return attributes;\n}\n\nfunction failureAttributes(message: TurnEndEvent['message']): TelemetryAttributes {\n if (message.role !== 'assistant') return { 'error.type': 'AgentError', outcome: 'error' };\n const aborted = message.stopReason === 'aborted';\n return {\n 'error.type': 'ProviderError',\n 'error.code': message.stopReason,\n outcome: aborted ? 'aborted' : 'error',\n };\n}\n\nfunction statusFromTelemetry(status: ReturnType<DoomTelemetry['status']>): SinkStatus {\n return {\n service: status.serviceName,\n backend: status.backend,\n endpoint: status.endpoint ?? NO_ENDPOINT,\n endpointSource: status.endpointSource,\n traces: status.traces,\n redaction: true,\n fileFallback: status.fileFallback,\n };\n}\n\nexport function createPiTelemetryExtension(options: PiTelemetryExtensionOptions = {}) {\n return function registerPiTelemetry(pi: ExtensionAPI): void {\n const env = options.env ?? process.env;\n const metrics = options.metrics;\n const toolStartedAt = new Map<string, number>();\n let agentStartedAt: number | undefined;\n let telemetry: DoomTelemetry | undefined;\n\n const emit = async (level: RecordLevel, name: string, attributes: TelemetryAttributes): Promise<void> => {\n if (!telemetry) return;\n if (level === 'debug') await telemetry.recordDebug(name, attributes);\n else if (level === 'warn') await telemetry.recordWarning(name, undefined, attributes);\n else if (level === 'error') await telemetry.recordError(name, undefined, attributes);\n else await telemetry.recordEvent(name, attributes);\n };\n\n const getTelemetry = (ctx: ExtensionContext): DoomTelemetry => {\n telemetry ??= createDoomTelemetry({\n serviceName: options.serviceName ?? SERVICE_NAME,\n packageName: PACKAGE_NAME,\n cwd: ctx.cwd,\n env,\n allowFileFallback: options.allowFileFallback,\n telemetryFactory: options.telemetryFactory,\n warn: options.onDiagnostic,\n enableLogs: true,\n enableTraces: env.AGENT_OTEL_TRACES === undefined || isEnabled(env.AGENT_OTEL_TRACES),\n onRecord: (record) => metrics?.record(record.event, record.attributes),\n onStatus: (status) => options.onSinkStatus?.(statusFromTelemetry(status)),\n });\n options.onSinkStatus?.(statusFromTelemetry(telemetry.status()));\n return telemetry;\n };\n\n pi.on('session_start', async (event, ctx) => {\n getTelemetry(ctx);\n await emit('info', 'pi.session.started', {\n ...contextAttributes(ctx),\n 'pi.session.reason': event.reason,\n 'pi.session.previous': event.previousSessionFile !== undefined,\n });\n });\n\n pi.on('before_agent_start', async (event, ctx) => {\n getTelemetry(ctx);\n await emit('info', 'pi.user_prompt', {\n ...contextAttributes(ctx),\n 'pi.user_message.length': event.prompt.length,\n 'pi.user_message.image_count': event.images?.length ?? 0,\n });\n });\n\n pi.on('agent_start', async (_event, ctx) => {\n agentStartedAt = Date.now();\n getTelemetry(ctx);\n await emit('info', 'pi.agent.started', contextAttributes(ctx));\n });\n\n pi.on('turn_start', async (event, ctx) => {\n getTelemetry(ctx);\n await emit('debug', 'pi.turn.started', {\n ...contextAttributes(ctx),\n 'pi.turn.index': event.turnIndex,\n });\n });\n\n pi.on('turn_end', async (event, ctx) => {\n getTelemetry(ctx);\n const usage = usageAttributes(event.message);\n await emit('info', 'pi.turn.finished', {\n ...contextAttributes(ctx),\n 'pi.turn.index': event.turnIndex,\n 'pi.tool_result.count': event.toolResults.length,\n ...usage,\n });\n if (event.message.role === 'assistant' && FAILURE_STOP_REASONS.has(event.message.stopReason)) {\n await emit(event.message.stopReason === 'aborted' ? 'warn' : 'error', 'pi.turn.failed', {\n ...contextAttributes(ctx),\n 'pi.turn.index': event.turnIndex,\n ...failureAttributes(event.message),\n ...usage,\n });\n }\n if (!usage) return;\n for (const result of event.toolResults) {\n await emit('debug', 'pi.tool_token_sample', {\n ...contextAttributes(ctx),\n ...usage,\n 'tool.name': result.toolName,\n token_attribution: 'toolCallTurn',\n });\n }\n });\n\n pi.on('tool_execution_start', async (event, ctx) => {\n toolStartedAt.set(event.toolCallId, Date.now());\n getTelemetry(ctx);\n await emit('debug', 'pi.tool_call', {\n ...contextAttributes(ctx),\n 'tool.name': event.toolName,\n 'tool.call.id': event.toolCallId,\n });\n });\n\n pi.on('tool_execution_end', async (event, ctx) => {\n const startedAt = toolStartedAt.get(event.toolCallId);\n toolStartedAt.delete(event.toolCallId);\n getTelemetry(ctx);\n await emit('info', 'pi.tool_result', {\n ...contextAttributes(ctx),\n success: !event.isError,\n 'tool.name': event.toolName,\n 'tool.call.id': event.toolCallId,\n 'tool.result.error': event.isError,\n ...(startedAt === undefined ? {} : { 'tool.duration_ms': Date.now() - startedAt }),\n });\n });\n\n pi.on('after_provider_response', async (event, ctx) => {\n getTelemetry(ctx);\n const attributes = {\n ...contextAttributes(ctx),\n 'http.response.status_code': event.status,\n };\n if (event.status >= API_ERROR_STATUS) await emit('error', 'pi.api_error', attributes);\n else await emit('debug', 'pi.api_response', attributes);\n });\n\n pi.on('model_select', async (event, ctx) => {\n getTelemetry(ctx);\n await emit('info', 'pi.model.selected', {\n ...contextAttributes(ctx),\n 'pi.model.source': event.source,\n 'gen_ai.provider.name': event.model.provider,\n 'gen_ai.request.model': event.model.id,\n });\n });\n\n pi.on('agent_end', async (event, ctx) => {\n getTelemetry(ctx);\n await emit('info', 'pi.agent.finished', {\n ...contextAttributes(ctx),\n 'pi.message.count': event.messages.length,\n ...(agentStartedAt === undefined ? {} : { 'pi.agent.duration_ms': Date.now() - agentStartedAt }),\n });\n agentStartedAt = undefined;\n await telemetry?.flush();\n });\n\n pi.on('agent_settled', async (_event, ctx) => {\n getTelemetry(ctx);\n await emit('debug', 'pi.agent.settled', contextAttributes(ctx));\n });\n\n pi.on('session_shutdown', async (event, ctx) => {\n getTelemetry(ctx);\n await emit('info', 'pi.session.finished', {\n ...contextAttributes(ctx),\n 'pi.session.reason': event.reason,\n });\n await telemetry?.shutdown();\n });\n };\n}\n\nexport function registerLogMetricsLeaderBinding(\n pi: Pick<ExtensionAPI, 'events' | 'on'>,\n options: { source?: string } = {},\n): () => void {\n return registerDoomLeaderContribution(pi, {\n source: options.source ?? LEADER_SOURCE,\n bindings: [\n {\n id: 'log.metrics',\n path: [\n { key: 'h', label: 'help', order: HELP_GROUP_ORDER },\n { key: 'l', label: 'logs', detail: 'telemetry' },\n ],\n command: { name: LOG_METRICS_COMMAND },\n },\n ],\n });\n}\n\nexport async function openLogMetricsOverlay(\n ctx: ExtensionContext,\n getView: () => LogMetricsView,\n query?: MetricsQuery,\n): Promise<void> {\n await ctx.ui.custom<undefined>(\n (tui, theme, _keybindings, done) => new LogMetricsOverlayComponent(tui, theme, getView, done, query),\n {\n overlay: true,\n overlayOptions: {\n anchor: 'top-left',\n width: '100%',\n maxHeight: '100%',\n margin: 0,\n },\n },\n );\n}\n\nexport function createDoomLogExtension(options: PiTelemetryExtensionOptions = {}) {\n return function registerDoomLog(pi: ExtensionAPI): void {\n const env = options.env ?? process.env;\n const metrics = new LogMetricsAggregator();\n const metricsSource = options.metricsSource ?? createMetricsSource({ env });\n let sink: SinkStatus | undefined;\n let lastDiagnostic: string | undefined;\n\n createPiTelemetryExtension({\n ...options,\n metrics,\n // Always supply a sink so doom-telemetry never falls back to\n // process.emitWarning, which writes raw stderr over the TUI frame.\n // Diagnostics surface in the Log Metrics overlay instead.\n onDiagnostic: (message) => {\n lastDiagnostic = message;\n if (options.onDiagnostic) options.onDiagnostic(message);\n else if (env.AGENT_OTEL_DIAGNOSTICS === DIAGNOSTICS_STDERR) process.emitWarning(message);\n },\n onSinkStatus: (status) => {\n sink = status;\n options.onSinkStatus?.(status);\n },\n })(pi);\n\n registerLogMetricsLeaderBinding(pi, { source: options.leaderSource });\n pi.registerCommand(LOG_METRICS_COMMAND, {\n description: LOG_METRICS_DESCRIPTION,\n handler: async (_args, ctx) => {\n await openLogMetricsOverlay(\n ctx,\n () => ({\n disabled: isEnabled(env.AGENT_TELEMETRY_DISABLED) || isEnabled(env.OTEL_SDK_DISABLED),\n snapshot: metrics.snapshot(),\n sink,\n transport: metricsSource.lastTransport(),\n lastDiagnostic,\n }),\n metricsSource.query,\n );\n },\n });\n };\n}\n\nexport const doomLogExtension = createDoomLogExtension();\n"],"mappings":"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"}
|
package/dist/extension.d.cts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { PiTelemetryExtensionOptions, createDoomLogExtension, createPiTelemetryExtension, openLogMetricsOverlay, registerLogMetricsLeaderBinding } from "./adapters/pi/extension.cjs";
|
|
2
|
-
export { PiTelemetryExtensionOptions, createDoomLogExtension, createPiTelemetryExtension, openLogMetricsOverlay, registerLogMetricsLeaderBinding };
|
|
2
|
+
export { type PiTelemetryExtensionOptions, createDoomLogExtension, createPiTelemetryExtension, openLogMetricsOverlay, registerLogMetricsLeaderBinding };
|
package/dist/extension.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { PiTelemetryExtensionOptions, createDoomLogExtension, createPiTelemetryExtension, openLogMetricsOverlay, registerLogMetricsLeaderBinding } from "./adapters/pi/extension.mjs";
|
|
2
|
-
export { PiTelemetryExtensionOptions, createDoomLogExtension, createPiTelemetryExtension, openLogMetricsOverlay, registerLogMetricsLeaderBinding };
|
|
2
|
+
export { type PiTelemetryExtensionOptions, createDoomLogExtension, createPiTelemetryExtension, openLogMetricsOverlay, registerLogMetricsLeaderBinding };
|
package/dist/extensions/pi.cjs
CHANGED
|
@@ -1,2 +1 @@
|
|
|
1
|
-
|
|
2
|
-
//# sourceMappingURL=pi.cjs.map
|
|
1
|
+
const e=require("../adapters/pi/extension.cjs");module.exports=e.doomLogExtension;
|
package/dist/extensions/pi.d.cts
CHANGED
|
@@ -1,4 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
export = _default;
|
|
4
|
-
//# sourceMappingURL=pi.d.cts.map
|
|
1
|
+
import { doomLogExtension } from "../adapters/pi/extension.cjs";
|
|
2
|
+
export = doomLogExtension;
|
package/dist/extensions/pi.d.mts
CHANGED
|
@@ -1,5 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
//#endregion
|
|
4
|
-
export { _default as default };
|
|
5
|
-
//# sourceMappingURL=pi.d.mts.map
|
|
1
|
+
import { doomLogExtension } from "../adapters/pi/extension.mjs";
|
|
2
|
+
export { doomLogExtension as default };
|
package/dist/extensions/pi.mjs
CHANGED
|
@@ -1,2 +1 @@
|
|
|
1
|
-
import{
|
|
2
|
-
//# sourceMappingURL=pi.mjs.map
|
|
1
|
+
import{doomLogExtension as e}from"../adapters/pi/extension.mjs";export{e as default};
|
package/dist/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./services/metrics.cjs"),t=require("./tui/
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./services/metrics.cjs"),t=require("./tui/logMetricsOverlay.cjs"),n=require("./adapters/pi/extension.cjs");exports.API_ERROR_RECORD=e.API_ERROR_RECORD,exports.LogMetricsAggregator=e.LogMetricsAggregator,exports.LogMetricsOverlayComponent=t.LogMetricsOverlayComponent,exports.MAX_RETAINED_STATE_PER_TOOL=e.MAX_RETAINED_STATE_PER_TOOL,exports.TOOL_RESULT_RECORD=e.TOOL_RESULT_RECORD,exports.TURN_FINISHED_RECORD=e.TURN_FINISHED_RECORD,exports.createDoomLogExtension=n.createDoomLogExtension,exports.createPiTelemetryExtension=n.createPiTelemetryExtension,exports.openLogMetricsOverlay=n.openLogMetricsOverlay,exports.registerLogMetricsLeaderBinding=n.registerLogMetricsLeaderBinding;
|
package/dist/index.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { API_ERROR_RECORD, LogMetricsAggregator, LogMetricsAggregatorOptions, LogMetricsError, LogMetricsEventCount, LogMetricsOperationDuration, LogMetricsRecorder, LogMetricsSnapshot, LogMetricsTokenTotals, LogMetricsToolLatency, MAX_RETAINED_STATE_PER_TOOL, TOOL_RESULT_RECORD, TURN_FINISHED_RECORD } from "./services/metrics.cjs";
|
|
2
|
-
import { LogMetricsOverlayComponent, LogMetricsView, SinkStatus } from "./tui/
|
|
2
|
+
import { LogMetricsOverlayComponent, LogMetricsView, SinkStatus } from "./tui/logMetricsOverlay.cjs";
|
|
3
3
|
import { PiTelemetryExtensionOptions, createDoomLogExtension, createPiTelemetryExtension, openLogMetricsOverlay, registerLogMetricsLeaderBinding } from "./adapters/pi/extension.cjs";
|
|
4
|
-
export { API_ERROR_RECORD, LogMetricsAggregator, LogMetricsAggregatorOptions, LogMetricsError, LogMetricsEventCount, LogMetricsOperationDuration, LogMetricsOverlayComponent, LogMetricsRecorder, LogMetricsSnapshot, LogMetricsTokenTotals, LogMetricsToolLatency, LogMetricsView, MAX_RETAINED_STATE_PER_TOOL, type PiTelemetryExtensionOptions, SinkStatus, TOOL_RESULT_RECORD, TURN_FINISHED_RECORD, createDoomLogExtension, createPiTelemetryExtension, openLogMetricsOverlay, registerLogMetricsLeaderBinding };
|
|
4
|
+
export { API_ERROR_RECORD, LogMetricsAggregator, type LogMetricsAggregatorOptions, type LogMetricsError, type LogMetricsEventCount, type LogMetricsOperationDuration, LogMetricsOverlayComponent, type LogMetricsRecorder, type LogMetricsSnapshot, type LogMetricsTokenTotals, type LogMetricsToolLatency, type LogMetricsView, MAX_RETAINED_STATE_PER_TOOL, type PiTelemetryExtensionOptions, type SinkStatus, TOOL_RESULT_RECORD, TURN_FINISHED_RECORD, createDoomLogExtension, createPiTelemetryExtension, openLogMetricsOverlay, registerLogMetricsLeaderBinding };
|
package/dist/index.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { API_ERROR_RECORD, LogMetricsAggregator, LogMetricsAggregatorOptions, LogMetricsError, LogMetricsEventCount, LogMetricsOperationDuration, LogMetricsRecorder, LogMetricsSnapshot, LogMetricsTokenTotals, LogMetricsToolLatency, MAX_RETAINED_STATE_PER_TOOL, TOOL_RESULT_RECORD, TURN_FINISHED_RECORD } from "./services/metrics.mjs";
|
|
2
|
-
import { LogMetricsOverlayComponent, LogMetricsView, SinkStatus } from "./tui/
|
|
2
|
+
import { LogMetricsOverlayComponent, LogMetricsView, SinkStatus } from "./tui/logMetricsOverlay.mjs";
|
|
3
3
|
import { PiTelemetryExtensionOptions, createDoomLogExtension, createPiTelemetryExtension, openLogMetricsOverlay, registerLogMetricsLeaderBinding } from "./adapters/pi/extension.mjs";
|
|
4
|
-
export { API_ERROR_RECORD, LogMetricsAggregator, LogMetricsAggregatorOptions, LogMetricsError, LogMetricsEventCount, LogMetricsOperationDuration, LogMetricsOverlayComponent, LogMetricsRecorder, LogMetricsSnapshot, LogMetricsTokenTotals, LogMetricsToolLatency, LogMetricsView, MAX_RETAINED_STATE_PER_TOOL, type PiTelemetryExtensionOptions, SinkStatus, TOOL_RESULT_RECORD, TURN_FINISHED_RECORD, createDoomLogExtension, createPiTelemetryExtension, openLogMetricsOverlay, registerLogMetricsLeaderBinding };
|
|
4
|
+
export { API_ERROR_RECORD, LogMetricsAggregator, type LogMetricsAggregatorOptions, type LogMetricsError, type LogMetricsEventCount, type LogMetricsOperationDuration, LogMetricsOverlayComponent, type LogMetricsRecorder, type LogMetricsSnapshot, type LogMetricsTokenTotals, type LogMetricsToolLatency, type LogMetricsView, MAX_RETAINED_STATE_PER_TOOL, type PiTelemetryExtensionOptions, type SinkStatus, TOOL_RESULT_RECORD, TURN_FINISHED_RECORD, createDoomLogExtension, createPiTelemetryExtension, openLogMetricsOverlay, registerLogMetricsLeaderBinding };
|
package/dist/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{API_ERROR_RECORD as e,LogMetricsAggregator as t,MAX_RETAINED_STATE_PER_TOOL as n,TOOL_RESULT_RECORD as r,TURN_FINISHED_RECORD as i}from"./services/metrics.mjs";import{LogMetricsOverlayComponent as a}from"./tui/
|
|
1
|
+
import{API_ERROR_RECORD as e,LogMetricsAggregator as t,MAX_RETAINED_STATE_PER_TOOL as n,TOOL_RESULT_RECORD as r,TURN_FINISHED_RECORD as i}from"./services/metrics.mjs";import{LogMetricsOverlayComponent as a}from"./tui/logMetricsOverlay.mjs";import{createDoomLogExtension as o,createPiTelemetryExtension as s,openLogMetricsOverlay as c,registerLogMetricsLeaderBinding as l}from"./adapters/pi/extension.mjs";export{e as API_ERROR_RECORD,t as LogMetricsAggregator,a as LogMetricsOverlayComponent,n as MAX_RETAINED_STATE_PER_TOOL,r as TOOL_RESULT_RECORD,i as TURN_FINISHED_RECORD,o as createDoomLogExtension,s as createPiTelemetryExtension,c as openLogMetricsOverlay,l as registerLogMetricsLeaderBinding};
|
package/dist/metrics.d.cts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { API_ERROR_RECORD, LogMetricsAggregator, LogMetricsAggregatorOptions, LogMetricsError, LogMetricsEventCount, LogMetricsOperationDuration, LogMetricsRecorder, LogMetricsSnapshot, LogMetricsTokenTotals, LogMetricsToolLatency, MAX_RETAINED_STATE_PER_TOOL, TOOL_RESULT_RECORD, TURN_FINISHED_RECORD } from "./services/metrics.cjs";
|
|
2
|
-
export { API_ERROR_RECORD, LogMetricsAggregator, LogMetricsAggregatorOptions, LogMetricsError, LogMetricsEventCount, LogMetricsOperationDuration, LogMetricsRecorder, LogMetricsSnapshot, LogMetricsTokenTotals, LogMetricsToolLatency, MAX_RETAINED_STATE_PER_TOOL, TOOL_RESULT_RECORD, TURN_FINISHED_RECORD };
|
|
2
|
+
export { API_ERROR_RECORD, LogMetricsAggregator, type LogMetricsAggregatorOptions, type LogMetricsError, type LogMetricsEventCount, type LogMetricsOperationDuration, type LogMetricsRecorder, type LogMetricsSnapshot, type LogMetricsTokenTotals, type LogMetricsToolLatency, MAX_RETAINED_STATE_PER_TOOL, TOOL_RESULT_RECORD, TURN_FINISHED_RECORD };
|
package/dist/metrics.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { API_ERROR_RECORD, LogMetricsAggregator, LogMetricsAggregatorOptions, LogMetricsError, LogMetricsEventCount, LogMetricsOperationDuration, LogMetricsRecorder, LogMetricsSnapshot, LogMetricsTokenTotals, LogMetricsToolLatency, MAX_RETAINED_STATE_PER_TOOL, TOOL_RESULT_RECORD, TURN_FINISHED_RECORD } from "./services/metrics.mjs";
|
|
2
|
-
export { API_ERROR_RECORD, LogMetricsAggregator, LogMetricsAggregatorOptions, LogMetricsError, LogMetricsEventCount, LogMetricsOperationDuration, LogMetricsRecorder, LogMetricsSnapshot, LogMetricsTokenTotals, LogMetricsToolLatency, MAX_RETAINED_STATE_PER_TOOL, TOOL_RESULT_RECORD, TURN_FINISHED_RECORD };
|
|
2
|
+
export { API_ERROR_RECORD, LogMetricsAggregator, type LogMetricsAggregatorOptions, type LogMetricsError, type LogMetricsEventCount, type LogMetricsOperationDuration, type LogMetricsRecorder, type LogMetricsSnapshot, type LogMetricsTokenTotals, type LogMetricsToolLatency, MAX_RETAINED_STATE_PER_TOOL, TOOL_RESULT_RECORD, TURN_FINISHED_RECORD };
|
package/dist/metricsSource.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./adapters/node/metricsSource.cjs");exports.createMetricsSource=e.createMetricsSource;
|
package/dist/metricsSource.d.cts
CHANGED
|
@@ -1,2 +1,3 @@
|
|
|
1
|
-
import { MetricsQuery, MetricsQueryParams, MetricsSource,
|
|
2
|
-
|
|
1
|
+
import { MetricsQuery, MetricsQueryParams, MetricsSource, MetricsTransport } from "./types/metricsSource.cjs";
|
|
2
|
+
import { MetricsSourceOptions, createMetricsSource } from "./adapters/node/metricsSource.cjs";
|
|
3
|
+
export { type MetricsQuery, type MetricsQueryParams, type MetricsSource, type MetricsSourceOptions, type MetricsTransport, createMetricsSource };
|
package/dist/metricsSource.d.mts
CHANGED
|
@@ -1,2 +1,3 @@
|
|
|
1
|
-
import { MetricsQuery, MetricsQueryParams, MetricsSource,
|
|
2
|
-
|
|
1
|
+
import { MetricsQuery, MetricsQueryParams, MetricsSource, MetricsTransport } from "./types/metricsSource.mjs";
|
|
2
|
+
import { MetricsSourceOptions, createMetricsSource } from "./adapters/node/metricsSource.mjs";
|
|
3
|
+
export { type MetricsQuery, type MetricsQueryParams, type MetricsSource, type MetricsSourceOptions, type MetricsTransport, createMetricsSource };
|
package/dist/metricsSource.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createMetricsSource as e}from"./
|
|
1
|
+
import{createMetricsSource as e}from"./adapters/node/metricsSource.mjs";export{e as createMetricsSource};
|