@agimon-ai/log-sink-mcp 0.25.0 → 0.25.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.cjs +1 -1
- package/dist/cli.mjs +1 -1
- package/dist/extensions/pi.cjs +1 -1
- package/dist/extensions/pi.mjs +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.mjs +1 -1
- package/dist/piTelemetry-BYKSOd4F.cjs +2 -0
- package/dist/piTelemetry-BYKSOd4F.cjs.map +1 -0
- package/dist/piTelemetry-Dlhhs5sx.mjs +2 -0
- package/dist/piTelemetry-Dlhhs5sx.mjs.map +1 -0
- package/dist/{stdio-Gb0mj6eo.cjs → stdio-QFR4qcFs.cjs} +2 -2
- package/dist/stdio-QFR4qcFs.cjs.map +1 -0
- package/dist/{stdio-DaqaONHT.mjs → stdio-kDI4sBvK.mjs} +2 -2
- package/dist/stdio-kDI4sBvK.mjs.map +1 -0
- package/package.json +4 -4
- package/dist/piTelemetry-BPQgGDpj.mjs +0 -2
- package/dist/piTelemetry-BPQgGDpj.mjs.map +0 -1
- package/dist/piTelemetry-P-o6KRQk.cjs +0 -2
- package/dist/piTelemetry-P-o6KRQk.cjs.map +0 -1
- package/dist/stdio-DaqaONHT.mjs.map +0 -1
- package/dist/stdio-Gb0mj6eo.cjs.map +0 -1
package/dist/cli.cjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
const e=require(`./node-9pwprHry.cjs`),t=require(`./stdio-
|
|
2
|
+
const e=require(`./node-9pwprHry.cjs`),t=require(`./stdio-QFR4qcFs.cjs`);let n=require(`zod`),r=require(`node:fs`),i=require(`node:fs/promises`);i=e.u(i,1);let a=require(`node:path`),o=require(`node:url`),s=require(`@agimon-ai/foundation-port-registry`),c=require(`@agimon-ai/foundation-process-registry`),l=require(`commander`),u=require(`@hono/node-server`),d=require(`node:crypto`),f=require(`hono`),p=require(`hono/cors`),m=require(`hono-rate-limiter`),h=require(`hono/html`),g=require(`hono/jsx/jsx-runtime`);function _(e){return e.option(`--config <path>`,`Path to .logsink.yaml`).option(`--global`,`Use the global log-sink instance`).option(`--instance <scope>`,`Force log-sink instance: local or global`)}function v(e){let t=e.instance?.trim();if(e.global&&t&&t.toLowerCase()!==`global`)throw Error(`Use either --global or --instance local, not both`);return e.global?`global`:t}function y(t,n=e.s){t.config&&(process.env.LOG_SINK_CONFIG=t.config);let r=v(t);return r&&(process.env.LOG_SINK_INSTANCE=r),e.c({configPath:t.config,packageName:n})}const b=[`error`,`fatal`];function x(e){let t=e.trim();if(!t)return null;try{return JSON.parse(t)}catch{return null}}function S(e){if(e==null)return`unknown`;if(typeof e==`string`)return e;try{return JSON.stringify(e,null,2)}catch{return String(e)}}function C(e){return e.hook_event_name===`PostToolUseFailure`?`Current tool failure:\n- Tool: ${e.tool_name??`unknown tool`}\n- Error: ${S(e.error)}`:null}function w(e,t,n){let r=new Map;for(let t of e){let e=`${t.service}::${t.level}::${t.error_type??``}::${t.error_message??t.message}`,i=new Date(Number(t.created_at)).toISOString();r.has(e)||r.set(e,{key:e,count:0,service:t.service,level:t.level,errorType:t.error_type,errorMessage:t.error_message,message:t.message,firstSeen:i,lastSeen:i,traceIds:new Set,examples:[]});let a=r.get(e);a.count+=1,a.lastSeen=i,t.trace_id&&a.traceIds.add(t.trace_id),a.examples.length<n&&a.examples.push({id:t.id,timestamp:i,traceId:t.trace_id})}return Array.from(r.values()).sort((e,t)=>t.count-e.count||t.lastSeen.localeCompare(e.lastSeen)).slice(0,t)}function ee(e,t,n,r){let i=w(e,n,r),a=[];a.push(`Recent log errors (${e.length} new):`),t.tool_name&&a.push(`- Triggered after tool: ${t.tool_name}`);for(let[e,t]of i.entries()){a.push(`${e+1}. ${t.service} [${t.level}] x${t.count} ${t.errorType?`(${t.errorType}) `:``}${t.errorMessage??t.message}`),a.push(` First seen: ${t.firstSeen}`),a.push(` Last seen: ${t.lastSeen}`),t.traceIds.size>0&&a.push(` Trace IDs: ${Array.from(t.traceIds).slice(0,3).join(`, `)}`);for(let e of t.examples)a.push(` Example: ${e.timestamp} id=${e.id}${e.traceId?` trace=${e.traceId}`:``}`)}if(t.hook_event_name===`PostToolUseFailure`){let e=C(t);e&&a.push(``,e)}return a.join(`
|
|
3
3
|
`)}function te(t){if(t.session_id?.trim())return(0,s.normalizeRepositoryPath)(e.l(t.cwd?.trim()||process.cwd()))}async function ne(t,n){let i=v(n);if(n.dbPath){let e=i===`global`?`global`:`local`;return(0,r.existsSync)(n.dbPath)?{dbPath:n.dbPath,scope:e}:void 0}let a={...process.env};n.config&&(a.LOG_SINK_CONFIG=n.config),i&&(a.LOG_SINK_INSTANCE=i);let o=e.c({configPath:n.config,cwd:t.cwd??process.cwd(),env:a,packageName:e.s}),c=new s.PortRegistryService(a.PORT_REGISTRY_PATH??s.DEFAULT_REGISTRY_PATH);try{let e=await c.getPort({repositoryPath:o.repositoryPath,serviceName:`log-sink-mcp-http`,serviceType:`tool`,environment:a.NODE_ENV||`development`}),t=e.record?.metadata?.dbPath;if(e.success&&typeof t==`string`&&t&&(0,r.existsSync)(t))return{dbPath:t,scope:o.scope}}catch{}return(0,r.existsSync)(o.dbPath)?{dbPath:o.dbPath,scope:o.scope}:void 0}async function re(e,t,n,r,i,a){let o=e.getSqliteClient(),s=Date.now()-n*60*1e3,c=``;if(t){let e=o.prepare(`
|
|
4
4
|
SELECT id, created_at
|
|
5
5
|
FROM logs
|
package/dist/cli.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{a as e,c as t,d as n,f as r,i,l as a,n as o,o as s,p as c,r as l,s as u,t as d,u as f}from"./stdio-
|
|
2
|
+
import{a as e,c as t,d as n,f as r,i,l as a,n as o,o as s,p as c,r as l,s as u,t as d,u as f}from"./stdio-kDI4sBvK.mjs";import{d as p,f as m,p as h,u as g}from"./node-Bv2snZci.mjs";import{z as _}from"zod";import{existsSync as v,readFileSync as y}from"node:fs";import*as b from"node:fs/promises";import{dirname as x,join as ee}from"node:path";import{fileURLToPath as te}from"node:url";import{DEFAULT_PORT_RANGE as S,DEFAULT_REGISTRY_PATH as ne,PortRegistryService as re,normalizeRepositoryPath as ie}from"@agimon-ai/foundation-port-registry";import{createProcessLease as C,resolveSiblingRegistryPath as w}from"@agimon-ai/foundation-process-registry";import{Command as T,InvalidArgumentError as E}from"commander";import{serve as ae}from"@hono/node-server";import{createHash as oe}from"node:crypto";import{Hono as D}from"hono";import{cors as se}from"hono/cors";import{rateLimiter as ce}from"hono-rate-limiter";import{raw as le}from"hono/html";import{jsx as O,jsxs as k}from"hono/jsx/jsx-runtime";function A(e){return e.option(`--config <path>`,`Path to .logsink.yaml`).option(`--global`,`Use the global log-sink instance`).option(`--instance <scope>`,`Force log-sink instance: local or global`)}function j(e){let t=e.instance?.trim();if(e.global&&t&&t.toLowerCase()!==`global`)throw Error(`Use either --global or --instance local, not both`);return e.global?`global`:t}function M(e,t=p){e.config&&(process.env.LOG_SINK_CONFIG=e.config);let n=j(e);return n&&(process.env.LOG_SINK_INSTANCE=n),m({configPath:e.config,packageName:t})}const ue=[`error`,`fatal`];function de(e){let t=e.trim();if(!t)return null;try{return JSON.parse(t)}catch{return null}}function fe(e){if(e==null)return`unknown`;if(typeof e==`string`)return e;try{return JSON.stringify(e,null,2)}catch{return String(e)}}function pe(e){return e.hook_event_name===`PostToolUseFailure`?`Current tool failure:\n- Tool: ${e.tool_name??`unknown tool`}\n- Error: ${fe(e.error)}`:null}function me(e,t,n){let r=new Map;for(let t of e){let e=`${t.service}::${t.level}::${t.error_type??``}::${t.error_message??t.message}`,i=new Date(Number(t.created_at)).toISOString();r.has(e)||r.set(e,{key:e,count:0,service:t.service,level:t.level,errorType:t.error_type,errorMessage:t.error_message,message:t.message,firstSeen:i,lastSeen:i,traceIds:new Set,examples:[]});let a=r.get(e);a.count+=1,a.lastSeen=i,t.trace_id&&a.traceIds.add(t.trace_id),a.examples.length<n&&a.examples.push({id:t.id,timestamp:i,traceId:t.trace_id})}return Array.from(r.values()).sort((e,t)=>t.count-e.count||t.lastSeen.localeCompare(e.lastSeen)).slice(0,t)}function he(e,t,n,r){let i=me(e,n,r),a=[];a.push(`Recent log errors (${e.length} new):`),t.tool_name&&a.push(`- Triggered after tool: ${t.tool_name}`);for(let[e,t]of i.entries()){a.push(`${e+1}. ${t.service} [${t.level}] x${t.count} ${t.errorType?`(${t.errorType}) `:``}${t.errorMessage??t.message}`),a.push(` First seen: ${t.firstSeen}`),a.push(` Last seen: ${t.lastSeen}`),t.traceIds.size>0&&a.push(` Trace IDs: ${Array.from(t.traceIds).slice(0,3).join(`, `)}`);for(let e of t.examples)a.push(` Example: ${e.timestamp} id=${e.id}${e.traceId?` trace=${e.traceId}`:``}`)}if(t.hook_event_name===`PostToolUseFailure`){let e=pe(t);e&&a.push(``,e)}return a.join(`
|
|
3
3
|
`)}function ge(e){if(e.session_id?.trim())return ie(h(e.cwd?.trim()||process.cwd()))}async function _e(e,t){let n=j(t);if(t.dbPath){let e=n===`global`?`global`:`local`;return v(t.dbPath)?{dbPath:t.dbPath,scope:e}:void 0}let r={...process.env};t.config&&(r.LOG_SINK_CONFIG=t.config),n&&(r.LOG_SINK_INSTANCE=n);let i=m({configPath:t.config,cwd:e.cwd??process.cwd(),env:r,packageName:p}),a=new re(r.PORT_REGISTRY_PATH??ne);try{let e=await a.getPort({repositoryPath:i.repositoryPath,serviceName:`log-sink-mcp-http`,serviceType:`tool`,environment:r.NODE_ENV||`development`}),t=e.record?.metadata?.dbPath;if(e.success&&typeof t==`string`&&t&&v(t))return{dbPath:t,scope:i.scope}}catch{}return v(i.dbPath)?{dbPath:i.dbPath,scope:i.scope}:void 0}async function ve(e,t,n,r,i,a){let o=e.getSqliteClient(),s=Date.now()-n*60*1e3,c=``;if(t){let e=o.prepare(`
|
|
4
4
|
SELECT id, created_at
|
|
5
5
|
FROM logs
|
package/dist/extensions/pi.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var e=require(`../piTelemetry-
|
|
1
|
+
var e=require(`../piTelemetry-BYKSOd4F.cjs`).t();module.exports=e;
|
|
2
2
|
//# sourceMappingURL=pi.cjs.map
|
package/dist/extensions/pi.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{t as e}from"../piTelemetry-
|
|
1
|
+
import{t as e}from"../piTelemetry-Dlhhs5sx.mjs";var t=e();export{t as default};
|
|
2
2
|
//# sourceMappingURL=pi.mjs.map
|
package/dist/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./node-9pwprHry.cjs`),t=require(`./stdio-
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./node-9pwprHry.cjs`),t=require(`./stdio-QFR4qcFs.cjs`),n=require(`./piTelemetry-BYKSOd4F.cjs`);let r=require(`@opentelemetry/api`),i=require(`@opentelemetry/api-logs`);exports.SpanKind=r.SpanKind,exports.SpanStatusCode=r.SpanStatusCode,exports.StdioTransportHandler=t.t,exports.createNodeTelemetry=e.t,exports.createPiTelemetryExtension=n.t,exports.createServer=t.n,exports.getLogSinkOtelEndpoint=e.n,exports.log=i.logs,exports.resolveLogSinkOtelEndpoint=e.a,exports.resolveLogSinkPort=e.o,exports.resolveNodeTelemetryEndpoints=e.r,exports.trace=r.trace;
|
package/dist/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{n as e,t}from"./stdio-
|
|
1
|
+
import{n as e,t}from"./stdio-kDI4sBvK.mjs";import{a as n,c as r,i,l as a,n as o,o as s,r as c,t as l,u}from"./node-Bv2snZci.mjs";import{t as d}from"./piTelemetry-Dlhhs5sx.mjs";export{l as SpanKind,o as SpanStatusCode,t as StdioTransportHandler,c as createNodeTelemetry,d as createPiTelemetryExtension,e as createServer,i as getLogSinkOtelEndpoint,n as log,a as resolveLogSinkOtelEndpoint,u as resolveLogSinkPort,s as resolveNodeTelemetryEndpoints,r as trace};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
const e=require(`./node-9pwprHry.cjs`);function t(e){return e===`1`||e?.toLowerCase()===`true`||e?.toLowerCase()===`yes`}function n(e){try{return JSON.stringify(e)}catch{return`[unserializable]`}}function r(e,t){console.warn(`[log-sink-mcp pi telemetry] ${e} failed: ${t instanceof Error?t.message:String(t)}`)}function i(e){let t={"pi.cwd":e.cwd,"pi.mode":e.mode,"pi.session.id":e.sessionManager.getSessionId()};e.thinkingLevel&&(t[`pi.thinking_level`]=e.thinkingLevel);let n=e.sessionManager.getSessionFile();return n&&(t[`pi.session.file`]=n),e.model&&(t[`gen_ai.provider.name`]=e.model.provider,t[`gen_ai.request.model`]=e.model.id),t}function a(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 o(e){let t={"x-agent":`pi`},n=e.AGENT_SESSION_ID??e.PI_SESSION_ID;return n&&(t[`x-agent-session-id`]=n),e.AGENT_PARENT_SESSION_ID&&(t[`x-agent-parent-session-id`]=e.AGENT_PARENT_SESSION_ID),t}function s(s={}){return function(c){let l=s.env??process.env,u=s.telemetryFactory??e.t,d=l.AGENT_OTEL_REDACT===`0`,f=new Map,p,m,h=e=>l.AGENT_TELEMETRY_DISABLED===`1`?Promise.resolve(void 0):(m??=u({serviceName:`pi`,packageName:`@agimon-ai/log-sink-mcp`,cwd:e.cwd,env:l,discoverEndpoint:!0,enableLogs:!0,enableTraces:t(l.AGENT_OTEL_TRACES),headers:o(l)}).then(async e=>{let n=s.allowFileFallback||t(l.LOG_SINK_PI_FILE_FALLBACK);if(e.backend!==`file`||n)return e;await e.shutdown().catch(e=>r(`File fallback shutdown`,e))}).catch(e=>{r(`Initialization`,e)}),m);c.on(`session_start`,async(e,t)=>{(await h(t))?.logger.info(`pi.session.started`,{attributes:{...i(t),"pi.session.reason":e.reason}})}),c.on(`before_agent_start`,async(e,t)=>{(await h(t))?.logger.info(`pi.user_prompt`,{attributes:{...i(t),"pi.user_message.length":e.prompt.length,"pi.user_message.image_count":e.images?.length??0,...d?{"user.prompt":e.prompt}:{}}})}),c.on(`agent_start`,async(e,t)=>{p=Date.now(),(await h(t))?.logger.info(`pi.agent.started`,{attributes:i(t)})}),c.on(`turn_start`,async(e,t)=>{(await h(t))?.logger.debug(`pi.turn.started`,{attributes:{...i(t),"pi.turn.index":e.turnIndex}})}),c.on(`turn_end`,async(e,t)=>{let n=await h(t),r=a(e.message);if(n?.logger.info(`pi.turn.finished`,{attributes:{...i(t),"pi.turn.index":e.turnIndex,"pi.tool_result.count":e.toolResults.length,...r}}),r)for(let a of e.toolResults)n?.logger.debug(`pi.tool_token_sample`,{attributes:{...i(t),...r,"tool.name":a.toolName,token_attribution:`toolCallTurn`}})}),c.on(`tool_execution_start`,async(e,t)=>{f.set(e.toolCallId,Date.now()),(await h(t))?.logger.debug(`pi.tool_call`,{attributes:{...i(t),"tool.name":e.toolName,"tool.call.id":e.toolCallId,...d?{"tool.input":n(e.args)}:{}}})}),c.on(`tool_execution_end`,async(e,t)=>{let r=f.get(e.toolCallId);f.delete(e.toolCallId),(await h(t))?.logger.info(`pi.tool_result`,{attributes:{...i(t),success:!e.isError,tool_name:e.toolName,"tool.name":e.toolName,"tool.call.id":e.toolCallId,"tool.result.error":e.isError,...r===void 0?{}:{"tool.duration_ms":Date.now()-r},...d?{"tool.result":n(e.result)}:{}}})}),c.on(`after_provider_response`,async(e,t)=>{let n=await h(t),r={attributes:{...i(t),status_code:e.status,"http.response.status_code":e.status}};e.status>=400?n?.logger.error(`pi.api_error`,r):n?.logger.debug(`pi.api_response`,r)}),c.on(`model_select`,async(e,t)=>{(await h(t))?.logger.info(`pi.model.selected`,{attributes:{...i(t),"pi.model.source":e.source,"gen_ai.provider.name":e.model.provider,"gen_ai.request.model":e.model.id}})}),c.on(`agent_end`,async(e,t)=>{let n=await h(t);n?.logger.info(`pi.agent.finished`,{attributes:{...i(t),"pi.message.count":e.messages.length,...p===void 0?{}:{"pi.agent.duration_ms":Date.now()-p}}}),p=void 0,await n?.flush().catch(e=>r(`Flush`,e))}),c.on(`agent_settled`,async(e,t)=>{(await h(t))?.logger.debug(`pi.agent.settled`,{attributes:i(t)})}),c.on(`session_shutdown`,async(e,t)=>{let n=await h(t);n?.logger.info(`pi.session.finished`,{attributes:{...i(t),"pi.session.reason":e.reason}}),await n?.shutdown().catch(e=>r(`Shutdown`,e))})}}Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return s}});
|
|
2
|
+
//# sourceMappingURL=piTelemetry-BYKSOd4F.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"piTelemetry-BYKSOd4F.cjs","names":["createNodeTelemetry"],"sources":["../src/extensions/piTelemetry.ts"],"sourcesContent":["import type { ExtensionAPI, ExtensionContext, TurnEndEvent } from '@earendil-works/pi-coding-agent';\nimport { createNodeTelemetry, type NodeTelemetryHandle, type NodeTelemetryOptions } from '../telemetry/node.js';\n\nconst SERVICE_NAME = 'pi';\nconst PACKAGE_NAME = '@agimon-ai/log-sink-mcp';\n\ntype TelemetryFactory = (options: NodeTelemetryOptions) => Promise<NodeTelemetryHandle>;\n\nexport interface PiTelemetryExtensionOptions {\n allowFileFallback?: boolean;\n env?: NodeJS.ProcessEnv;\n telemetryFactory?: TelemetryFactory;\n}\n\nfunction isEnabled(value: string | undefined): boolean {\n return value === '1' || value?.toLowerCase() === 'true' || value?.toLowerCase() === 'yes';\n}\n\nfunction serialize(value: unknown): string {\n try {\n return JSON.stringify(value);\n } catch {\n return '[unserializable]';\n }\n}\n\nfunction reportFailure(operation: string, error: unknown): void {\n console.warn(\n `[log-sink-mcp pi telemetry] ${operation} failed: ${error instanceof Error ? error.message : String(error)}`,\n );\n}\n\nfunction contextAttributes(ctx: ExtensionContext): Record<string, string | number | boolean> {\n const attributes: Record<string, string | number | boolean> = {\n 'pi.cwd': ctx.cwd,\n 'pi.mode': ctx.mode,\n 'pi.session.id': ctx.sessionManager.getSessionId(),\n };\n\n if (ctx.thinkingLevel) attributes['pi.thinking_level'] = ctx.thinkingLevel;\n const sessionFile = ctx.sessionManager.getSessionFile();\n if (sessionFile) attributes['pi.session.file'] = sessionFile;\n if (ctx.model) {\n attributes['gen_ai.provider.name'] = ctx.model.provider;\n attributes['gen_ai.request.model'] = ctx.model.id;\n }\n\n return attributes;\n}\n\n/**\n * Token accounting for one turn.\n *\n * Returns nothing when the turn carries no usage, which is what lets a caller\n * skip emitting a record the metrics aggregator would only discard.\n */\nfunction usageAttributes(message: TurnEndEvent['message']): Record<string, string | number> | undefined {\n if (message.role !== 'assistant') return undefined;\n\n const attributes: Record<string, string | number> = {\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\n return attributes;\n}\n\nfunction telemetryHeaders(env: NodeJS.ProcessEnv): Record<string, string> {\n const headers: Record<string, string> = { 'x-agent': SERVICE_NAME };\n const sessionId = env.AGENT_SESSION_ID ?? env.PI_SESSION_ID;\n if (sessionId) headers['x-agent-session-id'] = sessionId;\n if (env.AGENT_PARENT_SESSION_ID) headers['x-agent-parent-session-id'] = env.AGENT_PARENT_SESSION_ID;\n return headers;\n}\n\nexport function createPiTelemetryExtension(options: PiTelemetryExtensionOptions = {}) {\n return function registerPiTelemetry(pi: ExtensionAPI): void {\n const env = options.env ?? process.env;\n const telemetryFactory = options.telemetryFactory ?? createNodeTelemetry;\n const includeSensitiveDetails = env.AGENT_OTEL_REDACT === '0';\n const toolStartedAt = new Map<string, number>();\n let agentStartedAt: number | undefined;\n let telemetryPromise: Promise<NodeTelemetryHandle | undefined> | undefined;\n\n const getTelemetry = (ctx: ExtensionContext): Promise<NodeTelemetryHandle | undefined> => {\n if (env.AGENT_TELEMETRY_DISABLED === '1') return Promise.resolve(undefined);\n\n telemetryPromise ??= telemetryFactory({\n serviceName: SERVICE_NAME,\n packageName: PACKAGE_NAME,\n cwd: ctx.cwd,\n env,\n discoverEndpoint: true,\n enableLogs: true,\n enableTraces: isEnabled(env.AGENT_OTEL_TRACES),\n headers: telemetryHeaders(env),\n })\n .then(async (telemetry) => {\n const allowFileFallback = options.allowFileFallback || isEnabled(env.LOG_SINK_PI_FILE_FALLBACK);\n if (telemetry.backend !== 'file' || allowFileFallback) return telemetry;\n\n await telemetry.shutdown().catch((error: unknown) => reportFailure('File fallback shutdown', error));\n return undefined;\n })\n .catch((error: unknown) => {\n reportFailure('Initialization', error);\n return undefined;\n });\n return telemetryPromise;\n };\n\n pi.on('session_start', async (event, ctx) => {\n const telemetry = await getTelemetry(ctx);\n telemetry?.logger.info('pi.session.started', {\n attributes: {\n ...contextAttributes(ctx),\n 'pi.session.reason': event.reason,\n },\n });\n });\n\n pi.on('before_agent_start', async (event, ctx) => {\n const telemetry = await getTelemetry(ctx);\n telemetry?.logger.info('pi.user_prompt', {\n attributes: {\n ...contextAttributes(ctx),\n 'pi.user_message.length': event.prompt.length,\n 'pi.user_message.image_count': event.images?.length ?? 0,\n ...(includeSensitiveDetails ? { 'user.prompt': event.prompt } : {}),\n },\n });\n });\n\n pi.on('agent_start', async (_event, ctx) => {\n agentStartedAt = Date.now();\n const telemetry = await getTelemetry(ctx);\n telemetry?.logger.info('pi.agent.started', {\n attributes: contextAttributes(ctx),\n });\n });\n\n pi.on('turn_start', async (event, ctx) => {\n const telemetry = await getTelemetry(ctx);\n telemetry?.logger.debug('pi.turn.started', {\n attributes: {\n ...contextAttributes(ctx),\n 'pi.turn.index': event.turnIndex,\n },\n });\n });\n\n pi.on('turn_end', async (event, ctx) => {\n const telemetry = await getTelemetry(ctx);\n const usage = usageAttributes(event.message);\n telemetry?.logger.info('pi.turn.finished', {\n attributes: {\n ...contextAttributes(ctx),\n 'pi.turn.index': event.turnIndex,\n 'pi.tool_result.count': event.toolResults.length,\n ...usage,\n },\n });\n\n // One sample per tool call, carrying the usage of the turn that issued\n // it, so the percentiles answer \"how large is the context when this tool\n // runs\". A turn calling several tools emits a sample each: the metric is\n // a distribution per tool, not a sum, so the repetition is the point.\n if (!usage) return;\n for (const result of event.toolResults) {\n telemetry?.logger.debug('pi.tool_token_sample', {\n attributes: {\n ...contextAttributes(ctx),\n ...usage,\n 'tool.name': result.toolName,\n token_attribution: 'toolCallTurn',\n },\n });\n }\n });\n\n pi.on('tool_execution_start', async (event, ctx) => {\n toolStartedAt.set(event.toolCallId, Date.now());\n const telemetry = await getTelemetry(ctx);\n telemetry?.logger.debug('pi.tool_call', {\n attributes: {\n ...contextAttributes(ctx),\n 'tool.name': event.toolName,\n 'tool.call.id': event.toolCallId,\n ...(includeSensitiveDetails ? { 'tool.input': serialize(event.args) } : {}),\n },\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 const telemetry = await getTelemetry(ctx);\n telemetry?.logger.info('pi.tool_result', {\n attributes: {\n ...contextAttributes(ctx),\n success: !event.isError,\n tool_name: event.toolName,\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 ...(includeSensitiveDetails ? { 'tool.result': serialize(event.result) } : {}),\n },\n });\n });\n\n pi.on('after_provider_response', async (event, ctx) => {\n const telemetry = await getTelemetry(ctx);\n const options = {\n attributes: {\n ...contextAttributes(ctx),\n status_code: event.status,\n 'http.response.status_code': event.status,\n },\n };\n if (event.status >= 400) telemetry?.logger.error('pi.api_error', options);\n else telemetry?.logger.debug('pi.api_response', options);\n });\n\n pi.on('model_select', async (event, ctx) => {\n const telemetry = await getTelemetry(ctx);\n telemetry?.logger.info('pi.model.selected', {\n attributes: {\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\n pi.on('agent_end', async (event, ctx) => {\n const telemetry = await getTelemetry(ctx);\n telemetry?.logger.info('pi.agent.finished', {\n attributes: {\n ...contextAttributes(ctx),\n 'pi.message.count': event.messages.length,\n ...(agentStartedAt === undefined ? {} : { 'pi.agent.duration_ms': Date.now() - agentStartedAt }),\n },\n });\n agentStartedAt = undefined;\n await telemetry?.flush().catch((error: unknown) => reportFailure('Flush', error));\n });\n\n pi.on('agent_settled', async (_event, ctx) => {\n const telemetry = await getTelemetry(ctx);\n telemetry?.logger.debug('pi.agent.settled', {\n attributes: contextAttributes(ctx),\n });\n });\n\n pi.on('session_shutdown', async (event, ctx) => {\n const telemetry = await getTelemetry(ctx);\n telemetry?.logger.info('pi.session.finished', {\n attributes: {\n ...contextAttributes(ctx),\n 'pi.session.reason': event.reason,\n },\n });\n await telemetry?.shutdown().catch((error: unknown) => reportFailure('Shutdown', error));\n });\n };\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{r as e}from"./node-Bv2snZci.mjs";function t(e){return e===`1`||e?.toLowerCase()===`true`||e?.toLowerCase()===`yes`}function n(e){try{return JSON.stringify(e)}catch{return`[unserializable]`}}function r(e,t){console.warn(`[log-sink-mcp pi telemetry] ${e} failed: ${t instanceof Error?t.message:String(t)}`)}function i(e){let t={"pi.cwd":e.cwd,"pi.mode":e.mode,"pi.session.id":e.sessionManager.getSessionId()};e.thinkingLevel&&(t[`pi.thinking_level`]=e.thinkingLevel);let n=e.sessionManager.getSessionFile();return n&&(t[`pi.session.file`]=n),e.model&&(t[`gen_ai.provider.name`]=e.model.provider,t[`gen_ai.request.model`]=e.model.id),t}function a(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 o(e){let t={"x-agent":`pi`},n=e.AGENT_SESSION_ID??e.PI_SESSION_ID;return n&&(t[`x-agent-session-id`]=n),e.AGENT_PARENT_SESSION_ID&&(t[`x-agent-parent-session-id`]=e.AGENT_PARENT_SESSION_ID),t}function s(s={}){return function(c){let l=s.env??process.env,u=s.telemetryFactory??e,d=l.AGENT_OTEL_REDACT===`0`,f=new Map,p,m,h=e=>l.AGENT_TELEMETRY_DISABLED===`1`?Promise.resolve(void 0):(m??=u({serviceName:`pi`,packageName:`@agimon-ai/log-sink-mcp`,cwd:e.cwd,env:l,discoverEndpoint:!0,enableLogs:!0,enableTraces:t(l.AGENT_OTEL_TRACES),headers:o(l)}).then(async e=>{let n=s.allowFileFallback||t(l.LOG_SINK_PI_FILE_FALLBACK);if(e.backend!==`file`||n)return e;await e.shutdown().catch(e=>r(`File fallback shutdown`,e))}).catch(e=>{r(`Initialization`,e)}),m);c.on(`session_start`,async(e,t)=>{(await h(t))?.logger.info(`pi.session.started`,{attributes:{...i(t),"pi.session.reason":e.reason}})}),c.on(`before_agent_start`,async(e,t)=>{(await h(t))?.logger.info(`pi.user_prompt`,{attributes:{...i(t),"pi.user_message.length":e.prompt.length,"pi.user_message.image_count":e.images?.length??0,...d?{"user.prompt":e.prompt}:{}}})}),c.on(`agent_start`,async(e,t)=>{p=Date.now(),(await h(t))?.logger.info(`pi.agent.started`,{attributes:i(t)})}),c.on(`turn_start`,async(e,t)=>{(await h(t))?.logger.debug(`pi.turn.started`,{attributes:{...i(t),"pi.turn.index":e.turnIndex}})}),c.on(`turn_end`,async(e,t)=>{let n=await h(t),r=a(e.message);if(n?.logger.info(`pi.turn.finished`,{attributes:{...i(t),"pi.turn.index":e.turnIndex,"pi.tool_result.count":e.toolResults.length,...r}}),r)for(let a of e.toolResults)n?.logger.debug(`pi.tool_token_sample`,{attributes:{...i(t),...r,"tool.name":a.toolName,token_attribution:`toolCallTurn`}})}),c.on(`tool_execution_start`,async(e,t)=>{f.set(e.toolCallId,Date.now()),(await h(t))?.logger.debug(`pi.tool_call`,{attributes:{...i(t),"tool.name":e.toolName,"tool.call.id":e.toolCallId,...d?{"tool.input":n(e.args)}:{}}})}),c.on(`tool_execution_end`,async(e,t)=>{let r=f.get(e.toolCallId);f.delete(e.toolCallId),(await h(t))?.logger.info(`pi.tool_result`,{attributes:{...i(t),success:!e.isError,tool_name:e.toolName,"tool.name":e.toolName,"tool.call.id":e.toolCallId,"tool.result.error":e.isError,...r===void 0?{}:{"tool.duration_ms":Date.now()-r},...d?{"tool.result":n(e.result)}:{}}})}),c.on(`after_provider_response`,async(e,t)=>{let n=await h(t),r={attributes:{...i(t),status_code:e.status,"http.response.status_code":e.status}};e.status>=400?n?.logger.error(`pi.api_error`,r):n?.logger.debug(`pi.api_response`,r)}),c.on(`model_select`,async(e,t)=>{(await h(t))?.logger.info(`pi.model.selected`,{attributes:{...i(t),"pi.model.source":e.source,"gen_ai.provider.name":e.model.provider,"gen_ai.request.model":e.model.id}})}),c.on(`agent_end`,async(e,t)=>{let n=await h(t);n?.logger.info(`pi.agent.finished`,{attributes:{...i(t),"pi.message.count":e.messages.length,...p===void 0?{}:{"pi.agent.duration_ms":Date.now()-p}}}),p=void 0,await n?.flush().catch(e=>r(`Flush`,e))}),c.on(`agent_settled`,async(e,t)=>{(await h(t))?.logger.debug(`pi.agent.settled`,{attributes:i(t)})}),c.on(`session_shutdown`,async(e,t)=>{let n=await h(t);n?.logger.info(`pi.session.finished`,{attributes:{...i(t),"pi.session.reason":e.reason}}),await n?.shutdown().catch(e=>r(`Shutdown`,e))})}}export{s as t};
|
|
2
|
+
//# sourceMappingURL=piTelemetry-Dlhhs5sx.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"piTelemetry-Dlhhs5sx.mjs","names":[],"sources":["../src/extensions/piTelemetry.ts"],"sourcesContent":["import type { ExtensionAPI, ExtensionContext, TurnEndEvent } from '@earendil-works/pi-coding-agent';\nimport { createNodeTelemetry, type NodeTelemetryHandle, type NodeTelemetryOptions } from '../telemetry/node.js';\n\nconst SERVICE_NAME = 'pi';\nconst PACKAGE_NAME = '@agimon-ai/log-sink-mcp';\n\ntype TelemetryFactory = (options: NodeTelemetryOptions) => Promise<NodeTelemetryHandle>;\n\nexport interface PiTelemetryExtensionOptions {\n allowFileFallback?: boolean;\n env?: NodeJS.ProcessEnv;\n telemetryFactory?: TelemetryFactory;\n}\n\nfunction isEnabled(value: string | undefined): boolean {\n return value === '1' || value?.toLowerCase() === 'true' || value?.toLowerCase() === 'yes';\n}\n\nfunction serialize(value: unknown): string {\n try {\n return JSON.stringify(value);\n } catch {\n return '[unserializable]';\n }\n}\n\nfunction reportFailure(operation: string, error: unknown): void {\n console.warn(\n `[log-sink-mcp pi telemetry] ${operation} failed: ${error instanceof Error ? error.message : String(error)}`,\n );\n}\n\nfunction contextAttributes(ctx: ExtensionContext): Record<string, string | number | boolean> {\n const attributes: Record<string, string | number | boolean> = {\n 'pi.cwd': ctx.cwd,\n 'pi.mode': ctx.mode,\n 'pi.session.id': ctx.sessionManager.getSessionId(),\n };\n\n if (ctx.thinkingLevel) attributes['pi.thinking_level'] = ctx.thinkingLevel;\n const sessionFile = ctx.sessionManager.getSessionFile();\n if (sessionFile) attributes['pi.session.file'] = sessionFile;\n if (ctx.model) {\n attributes['gen_ai.provider.name'] = ctx.model.provider;\n attributes['gen_ai.request.model'] = ctx.model.id;\n }\n\n return attributes;\n}\n\n/**\n * Token accounting for one turn.\n *\n * Returns nothing when the turn carries no usage, which is what lets a caller\n * skip emitting a record the metrics aggregator would only discard.\n */\nfunction usageAttributes(message: TurnEndEvent['message']): Record<string, string | number> | undefined {\n if (message.role !== 'assistant') return undefined;\n\n const attributes: Record<string, string | number> = {\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\n return attributes;\n}\n\nfunction telemetryHeaders(env: NodeJS.ProcessEnv): Record<string, string> {\n const headers: Record<string, string> = { 'x-agent': SERVICE_NAME };\n const sessionId = env.AGENT_SESSION_ID ?? env.PI_SESSION_ID;\n if (sessionId) headers['x-agent-session-id'] = sessionId;\n if (env.AGENT_PARENT_SESSION_ID) headers['x-agent-parent-session-id'] = env.AGENT_PARENT_SESSION_ID;\n return headers;\n}\n\nexport function createPiTelemetryExtension(options: PiTelemetryExtensionOptions = {}) {\n return function registerPiTelemetry(pi: ExtensionAPI): void {\n const env = options.env ?? process.env;\n const telemetryFactory = options.telemetryFactory ?? createNodeTelemetry;\n const includeSensitiveDetails = env.AGENT_OTEL_REDACT === '0';\n const toolStartedAt = new Map<string, number>();\n let agentStartedAt: number | undefined;\n let telemetryPromise: Promise<NodeTelemetryHandle | undefined> | undefined;\n\n const getTelemetry = (ctx: ExtensionContext): Promise<NodeTelemetryHandle | undefined> => {\n if (env.AGENT_TELEMETRY_DISABLED === '1') return Promise.resolve(undefined);\n\n telemetryPromise ??= telemetryFactory({\n serviceName: SERVICE_NAME,\n packageName: PACKAGE_NAME,\n cwd: ctx.cwd,\n env,\n discoverEndpoint: true,\n enableLogs: true,\n enableTraces: isEnabled(env.AGENT_OTEL_TRACES),\n headers: telemetryHeaders(env),\n })\n .then(async (telemetry) => {\n const allowFileFallback = options.allowFileFallback || isEnabled(env.LOG_SINK_PI_FILE_FALLBACK);\n if (telemetry.backend !== 'file' || allowFileFallback) return telemetry;\n\n await telemetry.shutdown().catch((error: unknown) => reportFailure('File fallback shutdown', error));\n return undefined;\n })\n .catch((error: unknown) => {\n reportFailure('Initialization', error);\n return undefined;\n });\n return telemetryPromise;\n };\n\n pi.on('session_start', async (event, ctx) => {\n const telemetry = await getTelemetry(ctx);\n telemetry?.logger.info('pi.session.started', {\n attributes: {\n ...contextAttributes(ctx),\n 'pi.session.reason': event.reason,\n },\n });\n });\n\n pi.on('before_agent_start', async (event, ctx) => {\n const telemetry = await getTelemetry(ctx);\n telemetry?.logger.info('pi.user_prompt', {\n attributes: {\n ...contextAttributes(ctx),\n 'pi.user_message.length': event.prompt.length,\n 'pi.user_message.image_count': event.images?.length ?? 0,\n ...(includeSensitiveDetails ? { 'user.prompt': event.prompt } : {}),\n },\n });\n });\n\n pi.on('agent_start', async (_event, ctx) => {\n agentStartedAt = Date.now();\n const telemetry = await getTelemetry(ctx);\n telemetry?.logger.info('pi.agent.started', {\n attributes: contextAttributes(ctx),\n });\n });\n\n pi.on('turn_start', async (event, ctx) => {\n const telemetry = await getTelemetry(ctx);\n telemetry?.logger.debug('pi.turn.started', {\n attributes: {\n ...contextAttributes(ctx),\n 'pi.turn.index': event.turnIndex,\n },\n });\n });\n\n pi.on('turn_end', async (event, ctx) => {\n const telemetry = await getTelemetry(ctx);\n const usage = usageAttributes(event.message);\n telemetry?.logger.info('pi.turn.finished', {\n attributes: {\n ...contextAttributes(ctx),\n 'pi.turn.index': event.turnIndex,\n 'pi.tool_result.count': event.toolResults.length,\n ...usage,\n },\n });\n\n // One sample per tool call, carrying the usage of the turn that issued\n // it, so the percentiles answer \"how large is the context when this tool\n // runs\". A turn calling several tools emits a sample each: the metric is\n // a distribution per tool, not a sum, so the repetition is the point.\n if (!usage) return;\n for (const result of event.toolResults) {\n telemetry?.logger.debug('pi.tool_token_sample', {\n attributes: {\n ...contextAttributes(ctx),\n ...usage,\n 'tool.name': result.toolName,\n token_attribution: 'toolCallTurn',\n },\n });\n }\n });\n\n pi.on('tool_execution_start', async (event, ctx) => {\n toolStartedAt.set(event.toolCallId, Date.now());\n const telemetry = await getTelemetry(ctx);\n telemetry?.logger.debug('pi.tool_call', {\n attributes: {\n ...contextAttributes(ctx),\n 'tool.name': event.toolName,\n 'tool.call.id': event.toolCallId,\n ...(includeSensitiveDetails ? { 'tool.input': serialize(event.args) } : {}),\n },\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 const telemetry = await getTelemetry(ctx);\n telemetry?.logger.info('pi.tool_result', {\n attributes: {\n ...contextAttributes(ctx),\n success: !event.isError,\n tool_name: event.toolName,\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 ...(includeSensitiveDetails ? { 'tool.result': serialize(event.result) } : {}),\n },\n });\n });\n\n pi.on('after_provider_response', async (event, ctx) => {\n const telemetry = await getTelemetry(ctx);\n const options = {\n attributes: {\n ...contextAttributes(ctx),\n status_code: event.status,\n 'http.response.status_code': event.status,\n },\n };\n if (event.status >= 400) telemetry?.logger.error('pi.api_error', options);\n else telemetry?.logger.debug('pi.api_response', options);\n });\n\n pi.on('model_select', async (event, ctx) => {\n const telemetry = await getTelemetry(ctx);\n telemetry?.logger.info('pi.model.selected', {\n attributes: {\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\n pi.on('agent_end', async (event, ctx) => {\n const telemetry = await getTelemetry(ctx);\n telemetry?.logger.info('pi.agent.finished', {\n attributes: {\n ...contextAttributes(ctx),\n 'pi.message.count': event.messages.length,\n ...(agentStartedAt === undefined ? {} : { 'pi.agent.duration_ms': Date.now() - agentStartedAt }),\n },\n });\n agentStartedAt = undefined;\n await telemetry?.flush().catch((error: unknown) => reportFailure('Flush', error));\n });\n\n pi.on('agent_settled', async (_event, ctx) => {\n const telemetry = await getTelemetry(ctx);\n telemetry?.logger.debug('pi.agent.settled', {\n attributes: contextAttributes(ctx),\n });\n });\n\n pi.on('session_shutdown', async (event, ctx) => {\n const telemetry = await getTelemetry(ctx);\n telemetry?.logger.info('pi.session.finished', {\n attributes: {\n ...contextAttributes(ctx),\n 'pi.session.reason': event.reason,\n },\n });\n await telemetry?.shutdown().catch((error: unknown) => reportFailure('Shutdown', error));\n });\n };\n}\n"],"mappings":"wCAcA,SAAS,EAAU,EAAoC,CACrD,OAAO,IAAU,KAAO,GAAO,aAAa,GAAK,QAAU,GAAO,aAAa,GAAK,MAGtF,SAAS,EAAU,EAAwB,CACzC,GAAI,CACF,OAAO,KAAK,UAAU,EAAM,MACtB,CACN,MAAO,oBAIX,SAAS,EAAc,EAAmB,EAAsB,CAC9D,QAAQ,KACN,+BAA+B,EAAU,WAAW,aAAiB,MAAQ,EAAM,QAAU,OAAO,EAAM,GAC3G,CAGH,SAAS,EAAkB,EAAkE,CAC3F,IAAM,EAAwD,CAC5D,SAAU,EAAI,IACd,UAAW,EAAI,KACf,gBAAiB,EAAI,eAAe,cAAc,CACnD,CAEG,EAAI,gBAAe,EAAW,qBAAuB,EAAI,eAC7D,IAAM,EAAc,EAAI,eAAe,gBAAgB,CAOvD,OANI,IAAa,EAAW,mBAAqB,GAC7C,EAAI,QACN,EAAW,wBAA0B,EAAI,MAAM,SAC/C,EAAW,wBAA0B,EAAI,MAAM,IAG1C,EAST,SAAS,EAAgB,EAA+E,CACtG,GAAI,EAAQ,OAAS,YAAa,OAElC,IAAM,EAA8C,CAClD,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,MACzC,CAGD,OAFI,EAAQ,MAAM,YAAc,IAAA,KAAW,EAAW,iCAAmC,EAAQ,MAAM,WAEhG,EAGT,SAAS,EAAiB,EAAgD,CACxE,IAAM,EAAkC,CAAE,UAAW,KAAc,CAC7D,EAAY,EAAI,kBAAoB,EAAI,cAG9C,OAFI,IAAW,EAAQ,sBAAwB,GAC3C,EAAI,0BAAyB,EAAQ,6BAA+B,EAAI,yBACrE,EAGT,SAAgB,EAA2B,EAAuC,EAAE,CAAE,CACpF,OAAO,SAA6B,EAAwB,CAC1D,IAAM,EAAM,EAAQ,KAAO,QAAQ,IAC7B,EAAmB,EAAQ,kBAAoB,EAC/C,EAA0B,EAAI,oBAAsB,IACpD,EAAgB,IAAI,IACtB,EACA,EAEE,EAAgB,GAChB,EAAI,2BAA6B,IAAY,QAAQ,QAAQ,IAAA,GAAU,EAE3E,IAAqB,EAAiB,CACpC,YAAa,KACb,YAAa,0BACb,IAAK,EAAI,IACT,MACA,iBAAkB,GAClB,WAAY,GACZ,aAAc,EAAU,EAAI,kBAAkB,CAC9C,QAAS,EAAiB,EAAI,CAC/B,CAAC,CACC,KAAK,KAAO,IAAc,CACzB,IAAM,EAAoB,EAAQ,mBAAqB,EAAU,EAAI,0BAA0B,CAC/F,GAAI,EAAU,UAAY,QAAU,EAAmB,OAAO,EAE9D,MAAM,EAAU,UAAU,CAAC,MAAO,GAAmB,EAAc,yBAA0B,EAAM,CAAC,EAEpG,CACD,MAAO,GAAmB,CACzB,EAAc,iBAAkB,EAAM,EAEtC,CACG,GAGT,EAAG,GAAG,gBAAiB,MAAO,EAAO,IAAQ,EAE3C,MADwB,EAAa,EAAI,GAC9B,OAAO,KAAK,qBAAsB,CAC3C,WAAY,CACV,GAAG,EAAkB,EAAI,CACzB,oBAAqB,EAAM,OAC5B,CACF,CAAC,EACF,CAEF,EAAG,GAAG,qBAAsB,MAAO,EAAO,IAAQ,EAEhD,MADwB,EAAa,EAAI,GAC9B,OAAO,KAAK,iBAAkB,CACvC,WAAY,CACV,GAAG,EAAkB,EAAI,CACzB,yBAA0B,EAAM,OAAO,OACvC,8BAA+B,EAAM,QAAQ,QAAU,EACvD,GAAI,EAA0B,CAAE,cAAe,EAAM,OAAQ,CAAG,EAAE,CACnE,CACF,CAAC,EACF,CAEF,EAAG,GAAG,cAAe,MAAO,EAAQ,IAAQ,CAC1C,EAAiB,KAAK,KAAK,EAE3B,MADwB,EAAa,EAAI,GAC9B,OAAO,KAAK,mBAAoB,CACzC,WAAY,EAAkB,EAAI,CACnC,CAAC,EACF,CAEF,EAAG,GAAG,aAAc,MAAO,EAAO,IAAQ,EAExC,MADwB,EAAa,EAAI,GAC9B,OAAO,MAAM,kBAAmB,CACzC,WAAY,CACV,GAAG,EAAkB,EAAI,CACzB,gBAAiB,EAAM,UACxB,CACF,CAAC,EACF,CAEF,EAAG,GAAG,WAAY,MAAO,EAAO,IAAQ,CACtC,IAAM,EAAY,MAAM,EAAa,EAAI,CACnC,EAAQ,EAAgB,EAAM,QAAQ,CAC5C,MAAW,OAAO,KAAK,mBAAoB,CACzC,WAAY,CACV,GAAG,EAAkB,EAAI,CACzB,gBAAiB,EAAM,UACvB,uBAAwB,EAAM,YAAY,OAC1C,GAAG,EACJ,CACF,CAAC,CAMG,EACL,IAAK,IAAM,KAAU,EAAM,YACzB,GAAW,OAAO,MAAM,uBAAwB,CAC9C,WAAY,CACV,GAAG,EAAkB,EAAI,CACzB,GAAG,EACH,YAAa,EAAO,SACpB,kBAAmB,eACpB,CACF,CAAC,EAEJ,CAEF,EAAG,GAAG,uBAAwB,MAAO,EAAO,IAAQ,CAClD,EAAc,IAAI,EAAM,WAAY,KAAK,KAAK,CAAC,EAE/C,MADwB,EAAa,EAAI,GAC9B,OAAO,MAAM,eAAgB,CACtC,WAAY,CACV,GAAG,EAAkB,EAAI,CACzB,YAAa,EAAM,SACnB,eAAgB,EAAM,WACtB,GAAI,EAA0B,CAAE,aAAc,EAAU,EAAM,KAAK,CAAE,CAAG,EAAE,CAC3E,CACF,CAAC,EACF,CAEF,EAAG,GAAG,qBAAsB,MAAO,EAAO,IAAQ,CAChD,IAAM,EAAY,EAAc,IAAI,EAAM,WAAW,CACrD,EAAc,OAAO,EAAM,WAAW,EAEtC,MADwB,EAAa,EAAI,GAC9B,OAAO,KAAK,iBAAkB,CACvC,WAAY,CACV,GAAG,EAAkB,EAAI,CACzB,QAAS,CAAC,EAAM,QAChB,UAAW,EAAM,SACjB,YAAa,EAAM,SACnB,eAAgB,EAAM,WACtB,oBAAqB,EAAM,QAC3B,GAAI,IAAc,IAAA,GAAY,EAAE,CAAG,CAAE,mBAAoB,KAAK,KAAK,CAAG,EAAW,CACjF,GAAI,EAA0B,CAAE,cAAe,EAAU,EAAM,OAAO,CAAE,CAAG,EAAE,CAC9E,CACF,CAAC,EACF,CAEF,EAAG,GAAG,0BAA2B,MAAO,EAAO,IAAQ,CACrD,IAAM,EAAY,MAAM,EAAa,EAAI,CACnC,EAAU,CACd,WAAY,CACV,GAAG,EAAkB,EAAI,CACzB,YAAa,EAAM,OACnB,4BAA6B,EAAM,OACpC,CACF,CACG,EAAM,QAAU,IAAK,GAAW,OAAO,MAAM,eAAgB,EAAQ,CACpE,GAAW,OAAO,MAAM,kBAAmB,EAAQ,EACxD,CAEF,EAAG,GAAG,eAAgB,MAAO,EAAO,IAAQ,EAE1C,MADwB,EAAa,EAAI,GAC9B,OAAO,KAAK,oBAAqB,CAC1C,WAAY,CACV,GAAG,EAAkB,EAAI,CACzB,kBAAmB,EAAM,OACzB,uBAAwB,EAAM,MAAM,SACpC,uBAAwB,EAAM,MAAM,GACrC,CACF,CAAC,EACF,CAEF,EAAG,GAAG,YAAa,MAAO,EAAO,IAAQ,CACvC,IAAM,EAAY,MAAM,EAAa,EAAI,CACzC,GAAW,OAAO,KAAK,oBAAqB,CAC1C,WAAY,CACV,GAAG,EAAkB,EAAI,CACzB,mBAAoB,EAAM,SAAS,OACnC,GAAI,IAAmB,IAAA,GAAY,EAAE,CAAG,CAAE,uBAAwB,KAAK,KAAK,CAAG,EAAgB,CAChG,CACF,CAAC,CACF,EAAiB,IAAA,GACjB,MAAM,GAAW,OAAO,CAAC,MAAO,GAAmB,EAAc,QAAS,EAAM,CAAC,EACjF,CAEF,EAAG,GAAG,gBAAiB,MAAO,EAAQ,IAAQ,EAE5C,MADwB,EAAa,EAAI,GAC9B,OAAO,MAAM,mBAAoB,CAC1C,WAAY,EAAkB,EAAI,CACnC,CAAC,EACF,CAEF,EAAG,GAAG,mBAAoB,MAAO,EAAO,IAAQ,CAC9C,IAAM,EAAY,MAAM,EAAa,EAAI,CACzC,GAAW,OAAO,KAAK,sBAAuB,CAC5C,WAAY,CACV,GAAG,EAAkB,EAAI,CACzB,oBAAqB,EAAM,OAC5B,CACF,CAAC,CACF,MAAM,GAAW,UAAU,CAAC,MAAO,GAAmB,EAAc,WAAY,EAAM,CAAC,EACvF"}
|
|
@@ -70,7 +70,7 @@ const e=require(`./node-9pwprHry.cjs`);let t=require(`@agimon-ai/foundation-vali
|
|
|
70
70
|
ORDER BY timestamp ${o}
|
|
71
71
|
LIMIT ?
|
|
72
72
|
OFFSET ?
|
|
73
|
-
`).all(...c,r,i)).map(e=>this.mapRow(e)),total:Number(l[0]?.count??0)}}catch(e){throw Error(`Failed to query logs: ${e instanceof Error?e.message:String(e)}`,{cause:e})}}};M=w([(0,a.injectable)(),C(0,(0,a.inject)(y.LogStorageService)),S(`design:paramtypes`,[Object])],M);const ne=[`gen_ai.usage.input_tokens`,`gen_ai.usage.prompt_tokens`,`llm.usage.input_tokens`,`input_tokens`,`prompt_tokens`,`usage.input_tokens`,`usage.prompt_tokens`,`response.usage.input_tokens`,`response.usage.prompt_tokens`,`usageMetadata.promptTokenCount`,`promptTokenCount`],re=[`gen_ai.usage.output_tokens`,`gen_ai.usage.completion_tokens`,`llm.usage.output_tokens`,`output_tokens`,`completion_tokens`,`usage.output_tokens`,`usage.completion_tokens`,`response.usage.output_tokens`,`response.usage.completion_tokens`,`usageMetadata.candidatesTokenCount`,`candidatesTokenCount`],ie=[`gen_ai.usage.total_tokens`,`llm.usage.total_tokens`,`total_tokens`,`usage.total_tokens`,`response.usage.total_tokens`,`usageMetadata.totalTokenCount`,`totalTokenCount`],ae=[`gen_ai.usage.cache_read.input_tokens`,`gen_ai.usage.cache_creation.input_tokens`,`input_tokens_details.cached_tokens`,`usage.input_tokens_details.cached_tokens`,`response.usage.input_tokens_details.cached_tokens`,`usage.metadata.cached_tokens`,`metadata.cached_tokens`,`cached_tokens`],oe=[`gen_ai.usage.reasoning.output_tokens`,`output_tokens_details.reasoning_tokens`,`usage.output_tokens_details.reasoning_tokens`,`response.usage.output_tokens_details.reasoning_tokens`,`usage.metadata.reasoning_tokens`,`metadata.reasoning_tokens`,`reasoning_tokens`],se=[`model_proxy.model`,`gen_ai.response.model`,`gen_ai.request.model`,`llm.response.model`,`llm.request.model`,`response.model`,`model`,`modelVersion`,`requestedModel`],ce=[`model_proxy.provider`,`gen_ai.system`,`llm.provider`,`provider`,`provider_name`,`model_provider`];function N(e){if(typeof e!=`string`)return e;let t=e.trim();if(!t||t[0]!==`{`&&t[0]!==`[`)return e;try{return JSON.parse(t)}catch{return e}}function le(e,t){let n=N(e);if(!n||typeof n!=`object`||Array.isArray(n))return;let r=n[t];if(r!==void 0)return N(r);let i=n;for(let e of t.split(`.`))if(i=N(i),!i||typeof i!=`object`||Array.isArray(i)||(i=i[e],i===void 0))return;return N(i)}function ue(e,t){for(let n of t){let t=le(e,n);if(t!=null&&t!==``)return t}}function de(e){if(typeof e==`number`&&Number.isFinite(e))return Math.max(0,e);if(typeof e==`bigint`)return Number(e);if(typeof e==`string`){let t=Number(e);if(Number.isFinite(t))return Math.max(0,t)}return null}function P(e,t){return de(ue(e,t))}function fe(e,t){let n=ue(e,t);return typeof n==`string`&&n.trim().length>0?n.trim():typeof n==`number`||typeof n==`boolean`?String(n):null}function pe(e){let t=P(e,ne),n=P(e,re),r=P(e,ie),i=P(e,ae),a=P(e,oe),o=t??0,s=n??0;return{inputTokens:o,outputTokens:s,totalTokens:r??o+s,cachedInputTokens:i??0,reasoningOutputTokens:a??0,hasUsage:t!==null||n!==null||r!==null||i!==null||a!==null}}function me(e){return{model:fe(e,se),provider:fe(e,ce)}}function he(e){let t=e.toLowerCase();return t.includes(`gen_ai.usage`)||t.includes(`llm.usage`)||/(^|[._-])(input|output|prompt|completion|total|cached|reasoning|candidates?)_?tokens?($|[._-])/.test(t)||/(^|[._-])(prompt|candidates|total)tokencount($|[._-])/.test(t)}function ge(e){return de(e)!==null}function _e(e){return e}function ve(e){if(!e)return{};try{let t=JSON.parse(e);return t&&typeof t==`object`&&!Array.isArray(t)?t:{}}catch{return{}}}function ye(e){let t=pe(e);return{inputTokens:t.inputTokens,outputTokens:t.outputTokens,totalTokens:t.totalTokens,cachedInputTokens:t.cachedInputTokens,reasoningOutputTokens:t.reasoningOutputTokens,usageEventCount:+!!t.hasUsage,hasUsage:t.hasUsage}}function F(){return{inputTokens:0,outputTokens:0,totalTokens:0,cachedInputTokens:0,reasoningOutputTokens:0,usageEventCount:0}}function be(e,t){e.inputTokens+=t.inputTokens,e.outputTokens+=t.outputTokens,e.totalTokens+=t.totalTokens,e.cachedInputTokens+=t.cachedInputTokens,e.reasoningOutputTokens+=t.reasoningOutputTokens,e.usageEventCount+=t.usageEventCount}function I(e,t){t&&(e[t]=(e[t]??0)+1)}function L(e){return e?(Array.isArray(e)?e:[e]).flatMap(e=>e.split(`,`)).map(e=>e.trim()).filter(e=>e.length>0):[]}function xe(e,t){return t.length===0||e!==null&&t.includes(e)}function Se(e){return Math.round(e*100)/100}function R(e,t){if(e.length===0)return 0;let n=[...e].sort((e,t)=>e-t);return n[Math.min(n.length-1,Math.max(0,Math.ceil(n.length*t)-1))]??0}function Ce(e){let t=e.map(e=>e.inputTokens),n=e.map(e=>e.outputTokens),r=e.map(e=>e.totalTokens),i=e=>e.reduce((e,t)=>e+t,0),a=e=>e.length===0?0:Se(i(e)/e.length);return{samples:e.length,avgInputTokens:a(t),p50InputTokens:R(t,.5),p90InputTokens:R(t,.9),avgOutputTokens:a(n),p50OutputTokens:R(n,.5),p90OutputTokens:R(n,.9),avgTotalTokens:a(r),p50TotalTokens:R(r,.5),p90TotalTokens:R(r,.9)}}function we(e,t){return t===0?100:Se(e/t*100)}function Te(e){return e.endsWith(`.tool_token_sample`)}function z(e,...t){for(let n of t){let t=e[n];if(typeof t==`string`&&t.trim().length>0)return t.trim();if(typeof t==`number`||typeof t==`boolean`)return String(t)}return null}function Ee(e){let t=e.metadata,n=e.raw.message??``,r=z(t,`error_type`)??e.raw.error_type,i=t.success,a=t[`tool.result.error`],o=i===!1||i===`false`||a===!0||a===`true`,s=z(t,`decision`),c=z(t,`browse_tool.error.category`);return c===`caller_validation`||c===`caller_execution`?`caller_error`:c===`spec_failure`?`expected_failure`:c===`page_state`?`page_state`:c===`infrastructure_failure`?`infrastructure_failure`:n.includes(`api_error`)?`api_error`:n.includes(`api_retries_exhausted`)?`api_retries_exhausted`:n.includes(`api_refusal`)?`api_refusal`:(n.includes(`tool_result`)||n.includes(`tool error`))&&o?`tool_failure`:n.includes(`tool_decision`)&&s===`reject`?`tool_rejected`:e.raw.level===`error`||e.raw.level===`fatal`||r?`log_error`:null}function De(e,t){return e.message!==`Selected LLM provider`&&e.message!==`LLM provider attempt failed`?null:z(t,`tool`)}function Oe(e){return e.trim().toLowerCase().replace(/[^a-z0-9]+/g,` `)}function ke(e,t){let n=t===`job`?`workflow.job.finished`:`workflow.run.finished`;if(e.raw.message!==n)return!1;let r=t===`job`?`workflow.job.outcome`:`workflow.outcome`;return z(e.metadata,r)===`failed`}let B=class{constructor(e){this.storage=e}async getMetrics(e={},t={}){await this.storage.ensureInitialized();let n=this.storage.getSqliteClient(),r=L(e.model),i=L(e.provider),{whereSql:a,params:o}=this.buildWhereClause(e),s=_e(n.prepare(`
|
|
73
|
+
`).all(...c,r,i)).map(e=>this.mapRow(e)),total:Number(l[0]?.count??0)}}catch(e){throw Error(`Failed to query logs: ${e instanceof Error?e.message:String(e)}`,{cause:e})}}};M=w([(0,a.injectable)(),C(0,(0,a.inject)(y.LogStorageService)),S(`design:paramtypes`,[Object])],M);const ne=[`gen_ai.usage.input_tokens`,`gen_ai.usage.prompt_tokens`,`llm.usage.input_tokens`,`input_tokens`,`prompt_tokens`,`usage.input_tokens`,`usage.prompt_tokens`,`response.usage.input_tokens`,`response.usage.prompt_tokens`,`usageMetadata.promptTokenCount`,`promptTokenCount`],re=[`gen_ai.usage.output_tokens`,`gen_ai.usage.completion_tokens`,`llm.usage.output_tokens`,`output_tokens`,`completion_tokens`,`usage.output_tokens`,`usage.completion_tokens`,`response.usage.output_tokens`,`response.usage.completion_tokens`,`usageMetadata.candidatesTokenCount`,`candidatesTokenCount`],ie=[`gen_ai.usage.total_tokens`,`llm.usage.total_tokens`,`total_tokens`,`usage.total_tokens`,`response.usage.total_tokens`,`usageMetadata.totalTokenCount`,`totalTokenCount`],ae=[`gen_ai.usage.cache_read.input_tokens`,`gen_ai.usage.cache_read_tokens`,`gen_ai.usage.cache_creation.input_tokens`,`gen_ai.usage.cache_write_tokens`,`input_tokens_details.cached_tokens`,`usage.input_tokens_details.cached_tokens`,`response.usage.input_tokens_details.cached_tokens`,`usage.metadata.cached_tokens`,`metadata.cached_tokens`,`cached_tokens`],oe=[`gen_ai.usage.reasoning.output_tokens`,`gen_ai.usage.reasoning_tokens`,`output_tokens_details.reasoning_tokens`,`usage.output_tokens_details.reasoning_tokens`,`response.usage.output_tokens_details.reasoning_tokens`,`usage.metadata.reasoning_tokens`,`metadata.reasoning_tokens`,`reasoning_tokens`],se=[`model_proxy.model`,`gen_ai.response.model`,`gen_ai.request.model`,`llm.response.model`,`llm.request.model`,`response.model`,`model`,`modelVersion`,`requestedModel`],ce=[`model_proxy.provider`,`gen_ai.system`,`llm.provider`,`provider`,`provider_name`,`model_provider`];function N(e){if(typeof e!=`string`)return e;let t=e.trim();if(!t||t[0]!==`{`&&t[0]!==`[`)return e;try{return JSON.parse(t)}catch{return e}}function le(e,t){let n=N(e);if(!n||typeof n!=`object`||Array.isArray(n))return;let r=n[t];if(r!==void 0)return N(r);let i=n;for(let e of t.split(`.`))if(i=N(i),!i||typeof i!=`object`||Array.isArray(i)||(i=i[e],i===void 0))return;return N(i)}function ue(e,t){for(let n of t){let t=le(e,n);if(t!=null&&t!==``)return t}}function de(e){if(typeof e==`number`&&Number.isFinite(e))return Math.max(0,e);if(typeof e==`bigint`)return Number(e);if(typeof e==`string`){let t=Number(e);if(Number.isFinite(t))return Math.max(0,t)}return null}function P(e,t){return de(ue(e,t))}function fe(e,t){let n=ue(e,t);return typeof n==`string`&&n.trim().length>0?n.trim():typeof n==`number`||typeof n==`boolean`?String(n):null}function pe(e){let t=P(e,ne),n=P(e,re),r=P(e,ie),i=P(e,ae),a=P(e,oe),o=t??0,s=n??0;return{inputTokens:o,outputTokens:s,totalTokens:r??o+s,cachedInputTokens:i??0,reasoningOutputTokens:a??0,hasUsage:t!==null||n!==null||r!==null||i!==null||a!==null}}function me(e){return{model:fe(e,se),provider:fe(e,ce)}}function he(e){let t=e.toLowerCase();return t.includes(`gen_ai.usage`)||t.includes(`llm.usage`)||/(^|[._-])(input|output|prompt|completion|total|cached|reasoning|candidates?)_?tokens?($|[._-])/.test(t)||/(^|[._-])(prompt|candidates|total)tokencount($|[._-])/.test(t)}function ge(e){return de(e)!==null}function _e(e){return e}function ve(e){if(!e)return{};try{let t=JSON.parse(e);return t&&typeof t==`object`&&!Array.isArray(t)?t:{}}catch{return{}}}function ye(e){let t=pe(e);return{inputTokens:t.inputTokens,outputTokens:t.outputTokens,totalTokens:t.totalTokens,cachedInputTokens:t.cachedInputTokens,reasoningOutputTokens:t.reasoningOutputTokens,usageEventCount:+!!t.hasUsage,hasUsage:t.hasUsage}}function F(){return{inputTokens:0,outputTokens:0,totalTokens:0,cachedInputTokens:0,reasoningOutputTokens:0,usageEventCount:0}}function be(e,t){e.inputTokens+=t.inputTokens,e.outputTokens+=t.outputTokens,e.totalTokens+=t.totalTokens,e.cachedInputTokens+=t.cachedInputTokens,e.reasoningOutputTokens+=t.reasoningOutputTokens,e.usageEventCount+=t.usageEventCount}function I(e,t){t&&(e[t]=(e[t]??0)+1)}function L(e){return e?(Array.isArray(e)?e:[e]).flatMap(e=>e.split(`,`)).map(e=>e.trim()).filter(e=>e.length>0):[]}function xe(e,t){return t.length===0||e!==null&&t.includes(e)}function Se(e){return Math.round(e*100)/100}function R(e,t){if(e.length===0)return 0;let n=[...e].sort((e,t)=>e-t);return n[Math.min(n.length-1,Math.max(0,Math.ceil(n.length*t)-1))]??0}function Ce(e){let t=e.map(e=>e.inputTokens),n=e.map(e=>e.outputTokens),r=e.map(e=>e.totalTokens),i=e=>e.reduce((e,t)=>e+t,0),a=e=>e.length===0?0:Se(i(e)/e.length);return{samples:e.length,avgInputTokens:a(t),p50InputTokens:R(t,.5),p90InputTokens:R(t,.9),avgOutputTokens:a(n),p50OutputTokens:R(n,.5),p90OutputTokens:R(n,.9),avgTotalTokens:a(r),p50TotalTokens:R(r,.5),p90TotalTokens:R(r,.9)}}function we(e,t){return t===0?100:Se(e/t*100)}function Te(e){return e.endsWith(`.tool_token_sample`)}function z(e,...t){for(let n of t){let t=e[n];if(typeof t==`string`&&t.trim().length>0)return t.trim();if(typeof t==`number`||typeof t==`boolean`)return String(t)}return null}function Ee(e){let t=e.metadata,n=e.raw.message??``,r=z(t,`error_type`)??e.raw.error_type,i=t.success,a=t[`tool.result.error`],o=i===!1||i===`false`||a===!0||a===`true`,s=z(t,`decision`),c=z(t,`browse_tool.error.category`);return c===`caller_validation`||c===`caller_execution`?`caller_error`:c===`spec_failure`?`expected_failure`:c===`page_state`?`page_state`:c===`infrastructure_failure`?`infrastructure_failure`:n.includes(`api_error`)?`api_error`:n.includes(`api_retries_exhausted`)?`api_retries_exhausted`:n.includes(`api_refusal`)?`api_refusal`:(n.includes(`tool_result`)||n.includes(`tool error`))&&o?`tool_failure`:n.includes(`tool_decision`)&&s===`reject`?`tool_rejected`:e.raw.level===`error`||e.raw.level===`fatal`||r?`log_error`:null}function De(e,t){return e.message!==`Selected LLM provider`&&e.message!==`LLM provider attempt failed`?null:z(t,`tool`)}function Oe(e){return e.trim().toLowerCase().replace(/[^a-z0-9]+/g,` `)}function ke(e,t){let n=t===`job`?`workflow.job.finished`:`workflow.run.finished`;if(e.raw.message!==n)return!1;let r=t===`job`?`workflow.job.outcome`:`workflow.outcome`;return z(e.metadata,r)===`failed`}let B=class{constructor(e){this.storage=e}async getMetrics(e={},t={}){await this.storage.ensureInitialized();let n=this.storage.getSqliteClient(),r=L(e.model),i=L(e.provider),{whereSql:a,params:o}=this.buildWhereClause(e),s=_e(n.prepare(`
|
|
74
74
|
SELECT
|
|
75
75
|
id, timestamp, level, message, service, metadata, error_type, error_message,
|
|
76
76
|
session_id, workflow_run_id, workflow_name, job_name, job_id, agent_name,
|
|
@@ -318,4 +318,4 @@ const e=require(`./node-9pwprHry.cjs`);let t=require(`@agimon-ai/foundation-vali
|
|
|
318
318
|
LIMIT ?
|
|
319
319
|
OFFSET ?
|
|
320
320
|
`,d=r.prepare(l).get(...s);return{results:Re(r.prepare(u).all(a,...s,n,c)).map(e=>this.mapRow(e)),total:Number(d.total??0)}}catch(r){let i=await this.searchService.searchLogsPaginated(e,t,n);return console.warn(`Semantic search unavailable, falling back to FTS: ${r instanceof Error?r.message:String(r)}`),{results:i.results.map(e=>this.mapFallbackRow(e)),total:i.total}}}};K=w([(0,a.injectable)(),C(0,(0,a.inject)(y.LogStorageService)),C(1,(0,a.inject)(y.LogSearchService)),C(2,(0,a.inject)(y.EmbeddingService)),S(`design:paramtypes`,[Object,Object,Object])],K);const ze=new a.ContainerModule(e=>{e.bind(y.LogStorageService).to(W).inSingletonScope(),e.bind(y.EmbeddingService).to(E).inSingletonScope(),e.bind(y.LogQueryService).to(M).inSingletonScope(),e.bind(y.LogMetricsService).to(B).inSingletonScope(),e.bind(y.LogSearchService).to(U).inSingletonScope(),e.bind(y.SemanticSearchService).to(K).inSingletonScope(),e.bind(y.LogRetentionService).to(V).inSingletonScope(),e.bind(y.HttpServerHealthCheck).to(D).inSingletonScope(),e.bind(y.HttpServerManager).to(k).inSingletonScope()});function Be(){let e=new a.Container;e.load(ze);let t=e.get(y.LogStorageService);if(x()){let n=e.get(y.EmbeddingService);t.setEmbeddingWriter(e=>n.indexLogs(e))}return e}const q=i.z.object({sessionId:i.z.string().optional().describe(`Agent session id to scope the analysis to one agent launch`),workflowRunId:i.z.string().optional().describe(`Workflow run id to scope to all jobs of one workflow run`),workflowName:i.z.string().optional().describe(`Workflow name to scope to all runs of a workflow type`),jobName:i.z.string().optional().describe(`Workflow job name to scope to a single job`),jobId:i.z.string().optional().describe(`Workflow job execution id to scope by`),agentName:i.z.string().optional().describe(`Agent identity to scope by`),workflowRunKey:i.z.string().optional().describe(`Workflow run key to scope by`),workflowWorkspace:i.z.string().optional().describe(`Workflow workspace to scope by`),stepName:i.z.string().optional().describe(`Workflow step name to scope by`),phase:i.z.string().optional().describe(`Workflow phase to scope by`),service:i.z.union([i.z.string(),i.z.array(i.z.string())]).optional().describe(`Agent/service name(s) to scope by (e.g. claude-code, codex)`),startTime:i.z.string().optional().describe(`Start time for the analysis window (ISO 8601 format)`),endTime:i.z.string().optional().describe(`End time for the analysis window (ISO 8601 format)`),limit:i.z.number().min(1).max(1e3).optional().default(100).describe(`Maximum number of issue samples to return`),scanLimit:i.z.number().min(1).max(1e5).optional().default(5e4).describe(`Maximum matching log records to scan; the response reports when this truncates the window`)});var Ve=class e{static TOOL_NAME=`analyze_agent_issues`;queryService;constructor(e){this.queryService=e.get(y.LogQueryService)}getInputSchema(){return q}getDefinition(){return{name:e.TOOL_NAME,description:`Detect and aggregate agent-run problems (failed tool calls, API errors, refusals, retries exhausted, rejected tools, error logs) for reviewing agent performance and improving the repo harness. Filter by session id, workflow run id, workflow name, job name, or agent/service. Returns counts by category/tool/error-type plus sample issues with the tool, input, and error context needed to diagnose them.`,inputSchema:i.z.toJSONSchema(q,{reused:`inline`})}}async execute(e){try{let t=q.parse(e),n=await this.queryService.analyzeAgentIssues({sessionId:t.sessionId,workflowRunId:t.workflowRunId,workflowName:t.workflowName,jobName:t.jobName,jobId:t.jobId,agentName:t.agentName,workflowRunKey:t.workflowRunKey,workflowWorkspace:t.workflowWorkspace,stepName:t.stepName,phase:t.phase,service:t.service,startTime:t.startTime?new Date(t.startTime):void 0,endTime:t.endTime?new Date(t.endTime):void 0},{sampleLimit:t.limit,scanLimit:t.scanLimit});return{content:[{type:`text`,text:JSON.stringify({...n,issues:n.issues.map(e=>({...e,timestamp:e.timestamp.toISOString()}))},null,2)}]}}catch(e){return{content:[{type:`text`,text:`Error analyzing agent issues: ${e instanceof Error?e.message:`Unknown error`}`}],isError:!0}}}};const J=i.z.object({startTime:i.z.string().optional().describe(`Start time for statistics (ISO 8601 format)`),endTime:i.z.string().optional().describe(`End time for statistics (ISO 8601 format)`),groupBy:i.z.enum([`level`,`service`,`both`,`agent`,`workflow`,`job`,`signal`]).optional().default(`both`).describe(`Dimension used to group statistics.`),signalType:i.z.enum([`log`,`span`,`all`]).optional().default(`log`).describe(`Count log records by default, span records, or 'all' signals.`)});var Y=class e{static TOOL_NAME=`get_log_stats`;queryService;constructor(e){this.queryService=e.get(y.LogQueryService)}getInputSchema(){return J}getDefinition(){return{name:e.TOOL_NAME,description:`Get aggregate log statistics including counts by level, service, or both. Useful for dashboards and monitoring.`,inputSchema:i.z.toJSONSchema(J,{reused:`inline`})}}async execute(e){try{let t=J.parse(e),n;(t.startTime||t.endTime)&&(n={start:t.startTime?new Date(t.startTime):new Date(0),end:t.endTime?new Date(t.endTime):new Date});let r=await this.queryService.getStatistics(n,t.groupBy,t.signalType);return{content:[{type:`text`,text:JSON.stringify({timeRange:n,groupBy:t.groupBy,signalType:t.signalType,totalEntries:r.reduce((e,t)=>e+t.count,0),statistics:r.map(e=>({service:e.service,level:e.level,count:e.count,value:t.groupBy===`level`?e.level:e.service}))},null,2)}]}}catch(e){return{content:[{type:`text`,text:`Error getting log stats: ${e instanceof Error?e.message:`Unknown error`}`}],isError:!0}}}};const He=i.z.object({});var Ue=class e{static TOOL_NAME=`get_services`;queryService;constructor(e){this.queryService=e.get(y.LogQueryService)}getInputSchema(){return He}getDefinition(){return{name:e.TOOL_NAME,description:`List all active services that have sent logs. Returns service names sorted alphabetically.`,inputSchema:i.z.toJSONSchema(He,{reused:`inline`})}}async execute(e){try{let e=await this.queryService.getActiveServices();return{content:[{type:`text`,text:JSON.stringify({count:e.length,services:e.sort()},null,2)}]}}catch(e){return{content:[{type:`text`,text:`Error getting services: ${e instanceof Error?e.message:`Unknown error`}`}],isError:!0}}}};const X=i.z.object({traceId:i.z.string().describe(`OTEL trace ID (32 hex characters)`)});var We=class e{static TOOL_NAME=`get_trace_timeline`;queryService;constructor(e){this.queryService=e.get(y.LogQueryService)}getInputSchema(){return X}getDefinition(){return{name:e.TOOL_NAME,description:`Reconstruct the chronological timeline of a distributed trace. Returns all spans in order with timing, service hops, and log messages.`,inputSchema:i.z.toJSONSchema(X,{reused:`inline`})}}async execute(e){try{let t=X.parse(e),n=await this.queryService.getTraceTimeline(t.traceId);return{content:[{type:`text`,text:JSON.stringify({traceId:t.traceId,count:n.length,timeline:n.map(e=>({timestamp:e.timestamp.toISOString(),service:e.service,spanId:e.spanId,parentSpanId:e.parentSpanId,level:e.level,message:e.message,duration:e.duration}))},null,2)}]}}catch(e){return{content:[{type:`text`,text:`Error getting trace timeline: ${e instanceof Error?e.message:`Unknown error`}`}],isError:!0}}}};let Ge=function(e){return e.TRACE=`trace`,e.DEBUG=`debug`,e.INFO=`info`,e.WARN=`warn`,e.ERROR=`error`,e.FATAL=`fatal`,e}({});const Ke=i.z.enum([`trace`,`debug`,`info`,`warn`,`error`,`fatal`]),qe=i.z.enum([`fts`,`semantic`,`hybrid`]),Z=i.z.object({searchQuery:i.z.string().optional().describe(`Text to search for. Common punctuation such as hyphens is escaped safely; quoted phrases, prefix matching with *, and boolean operators AND/OR/NOT are supported.`),query:i.z.string().optional().describe(`Alias for searchQuery. Use this for full-text search while also applying structured filters.`),mode:qe.optional().default(`hybrid`).describe(`Search strategy to use`),service:i.z.union([i.z.string(),i.z.array(i.z.string())]).optional().describe(`Service name(s) to filter by`),level:i.z.union([Ke,i.z.array(Ke)]).optional().describe(`Log level(s) to filter by`),traceId:i.z.string().optional().describe(`Trace ID to filter by (OTEL format: 32 hex characters)`),spanId:i.z.string().optional().describe(`Span ID to filter by`),errorType:i.z.string().optional().describe(`Error type to filter by`),sessionId:i.z.string().optional().describe(`Agent session id to filter by`),workflowRunId:i.z.string().optional().describe(`Workflow run id to filter by`),workflowName:i.z.string().optional().describe(`Workflow name to filter by`),jobName:i.z.string().optional().describe(`Workflow job name to filter by`),jobId:i.z.string().optional().describe(`Workflow job execution id to filter by`),agentName:i.z.string().optional().describe(`Agent name to filter by`),parentSessionId:i.z.string().optional().describe(`Parent agent session id to filter by`),workflowRunKey:i.z.string().optional().describe(`Stable workflow run key to filter by`),workflowId:i.z.string().optional().describe(`Workflow file id to filter by`),workflowWorkspace:i.z.string().optional().describe(`Workflow workspace to filter by`),stepName:i.z.string().optional().describe(`Workflow step name to filter by`),phase:i.z.string().optional().describe(`Workflow phase to filter by`),signalType:i.z.enum([`log`,`span`]).optional().describe(`Telemetry signal type to filter by`),startTime:i.z.string().optional().describe(`Start time for log range (ISO 8601 format)`),endTime:i.z.string().optional().describe(`End time for log range (ISO 8601 format)`),limit:i.z.number().min(1).max(1e3).optional().default(100).describe(`Maximum number of search results to return`)});var Je=class e{static TOOL_NAME=`search_logs`;queryService;searchService;semanticSearchService;constructor(e){this.queryService=e.get(y.LogQueryService),this.searchService=e.get(y.LogSearchService),this.semanticSearchService=e.get(y.SemanticSearchService)}getInputSchema(){return Z}getDefinition(){return{name:e.TOOL_NAME,description:`Search and query log entries. Supports structured filters such as level, service, trace/session/workflow fields, time range, and optional full-text query using FTS5, local semantic embeddings, or both.`,inputSchema:i.z.toJSONSchema(Z,{reused:`inline`})}}async execute(e){try{let t=Z.parse(e),n=this.buildFilters(t),r=this.getSearchQuery(t),i=t.mode??`hybrid`,a=r?await this.searchByText(r,n,i,t.limit):await this.queryByFilters(n,t.limit);return{content:[{type:`text`,text:JSON.stringify({mode:r?i:`filter`,count:a.length,query:r,filters:Object.keys(n).length>0?this.serializeFilters(n):void 0,results:a.map(e=>this.serializeResult(e,!!r))},null,2)}]}}catch(e){return{content:[{type:`text`,text:`Error searching logs: ${e instanceof Error?e.message:`Unknown error`}`}],isError:!0}}}buildFilters(e){let t={};return e.service&&(t.service=e.service),e.level&&(t.level=e.level),e.traceId&&(t.traceId=e.traceId),e.spanId&&(t.spanId=e.spanId),e.errorType&&(t.errorType=e.errorType),e.sessionId&&(t.sessionId=e.sessionId),e.workflowRunId&&(t.workflowRunId=e.workflowRunId),e.workflowName&&(t.workflowName=e.workflowName),e.jobName&&(t.jobName=e.jobName),e.jobId&&(t.jobId=e.jobId),e.agentName&&(t.agentName=e.agentName),e.parentSessionId&&(t.parentSessionId=e.parentSessionId),e.workflowRunKey&&(t.workflowRunKey=e.workflowRunKey),e.workflowId&&(t.workflowId=e.workflowId),e.workflowWorkspace&&(t.workflowWorkspace=e.workflowWorkspace),e.stepName&&(t.stepName=e.stepName),e.phase&&(t.phase=e.phase),e.signalType&&(t.signalType=e.signalType),e.startTime&&(t.startTime=this.parseDate(e.startTime,`startTime`)),e.endTime&&(t.endTime=this.parseDate(e.endTime,`endTime`)),t}getSearchQuery(e){return(e.searchQuery??e.query)?.trim()||void 0}parseDate(e,t){let n=new Date(e);if(Number.isNaN(n.getTime()))throw Error(`Invalid ${t}: expected ISO 8601 timestamp`);return n}async queryByFilters(e,t){let n=Object.keys(e).length>0,r=!!(e.sessionId||e.workflowRunId||e.workflowName||e.jobName||e.traceId||e.spanId||e.startTime||e.endTime||e.service&&!e.level);return(await this.queryService.queryLogs({...e,level:n?e.level:[`info`,`warn`,`error`,`fatal`],order:r?`asc`:`desc`,limit:t})).logs}async searchByText(e,t,n,r){return n===`semantic`?this.semanticSearchService.searchLogs(e,t,r):n===`fts`?this.searchService.searchLogs(e,t,r):this.searchHybrid(e,t,r)}serializeFilters(e){return Object.fromEntries(Object.entries(e).map(([e,t])=>[e,t instanceof Date?t.toISOString():t]))}serializeResult(e,t){let n=typeof e.score==`number`?e.score:typeof e.rank==`number`?this.getFallbackScore(e.rank):void 0;return{...t?{score:n,rank:e.rank,distance:e.distance,sources:e.sources}:{},id:e.id,timestamp:e.timestamp.toISOString(),level:e.level,message:e.message,service:e.service,traceId:e.traceId,spanId:e.spanId,parentSpanId:e.parentSpanId,hostname:e.hostname,pid:e.pid,metadata:e.metadata,errorType:e.errorType,errorMessage:e.errorMessage,errorStack:e.errorStack,sessionId:e.sessionId,workflowRunId:e.workflowRunId,workflowName:e.workflowName,jobName:e.jobName,jobId:e.jobId,agentName:e.agentName,parentSessionId:e.parentSessionId,workflowRunKey:e.workflowRunKey,workflowId:e.workflowId,workflowWorkspace:e.workflowWorkspace,stepName:e.stepName,phase:e.phase,signalType:e.signalType,durationMs:e.durationMs}}getFallbackScore(e){return 1/(1+Math.max(0,Math.abs(e)))}async searchHybrid(e,t,n){let r=Math.max(n*2,50),i=this.searchService.searchLogs(e,t,r),a=await this.semanticSearchService.isAvailable(),o=await i;if(!a)return o;let s=await this.semanticSearchService.searchLogs(e,t,r),c=new Map;return o.forEach((e,t)=>{c.set(e.id,{result:e,score:.65*(1/(1+t)),rank:e.rank,sources:new Set([`fts`])})}),s.forEach((e,t)=>{let n=c.get(e.id),r=.35*(1/(1+t));n?(n.score+=r,n.sources.add(`semantic`),n.distance=e.distance,n.result={...n.result,...e}):c.set(e.id,{result:e,score:r,distance:e.distance,sources:new Set([`semantic`])})}),Array.from(c.values()).sort((e,t)=>t.score-e.score).slice(0,n).map(e=>({...e.result,score:e.score,sources:Array.from(e.sources),rank:e.rank,distance:e.distance}))}};const Q=`@agimon-ai/log-sink-mcp`;let Ye;function Xe(){return Ye??=e.t({serviceName:Q,workspaceRoot:process.cwd(),discoverEndpoint:!1}),Ye}async function $(e,t,n){let r=await Xe();return r.runInSpan(e,{attributes:t},async()=>{try{return await n()}catch(n){throw r.logger.error(`${e} failed`,{attributes:t,exception:n}),n}})}function Ze(e){let a=new n.Server({name:`log-sink-mcp`,version:`0.1.0`},{capabilities:{tools:{}}}),o=e??Be(),s=[new Je(o),new Ve(o),new We(o),new Y(o),new Ue(o)],c=new Map(s.map(e=>[e.getDefinition().name,e]));return a.setRequestHandler(r.ListToolsRequestSchema,async()=>$(`mcp.server.list_tools`,{"mcp.service":Q},async()=>({tools:s.map(e=>e.getDefinition())}))),a.setRequestHandler(r.CallToolRequestSchema,async e=>{let{name:n,arguments:r}=e.params;return $(`mcp.server.call_tool`,{"mcp.service":Q,"mcp.tool.name":n},async()=>{let e=c.get(n);if(!e)return{content:[{type:`text`,text:`Unknown tool: ${n}`}],isError:!0};let a=(0,t.coerceArgs)(r??{},e.getInputSchema());try{return await e.execute(a)}catch(r){return r instanceof i.z.ZodError?{content:[{type:`text`,text:(0,t.formatZodError)(r,{schemaName:n,schema:e.getInputSchema()})}],isError:!0}:{content:[{type:`text`,text:`Error executing tool ${n}: ${r instanceof Error?r.message:String(r)}`}],isError:!0}}})}),a}var Qe=class{server;transport=null;constructor(e){this.server=e}async start(){this.transport=new v.StdioServerTransport,await this.server.connect(this.transport)}async stop(){this.transport&&=(await this.transport.close(),null)}};Object.defineProperty(exports,`a`,{enumerable:!0,get:function(){return We}}),Object.defineProperty(exports,`c`,{enumerable:!0,get:function(){return Ve}}),Object.defineProperty(exports,`d`,{enumerable:!0,get:function(){return he}}),Object.defineProperty(exports,`f`,{enumerable:!0,get:function(){return ge}}),Object.defineProperty(exports,`i`,{enumerable:!0,get:function(){return Ge}}),Object.defineProperty(exports,`l`,{enumerable:!0,get:function(){return Be}}),Object.defineProperty(exports,`n`,{enumerable:!0,get:function(){return Ze}}),Object.defineProperty(exports,`o`,{enumerable:!0,get:function(){return Ue}}),Object.defineProperty(exports,`p`,{enumerable:!0,get:function(){return y}}),Object.defineProperty(exports,`r`,{enumerable:!0,get:function(){return Je}}),Object.defineProperty(exports,`s`,{enumerable:!0,get:function(){return Y}}),Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return Qe}}),Object.defineProperty(exports,`u`,{enumerable:!0,get:function(){return W}});
|
|
321
|
-
//# sourceMappingURL=stdio-
|
|
321
|
+
//# sourceMappingURL=stdio-QFR4qcFs.cjs.map
|