@narumitw/pi-langfuse 0.50.0 → 0.50.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/README.md +109 -51
- package/dist/chunks/runtime-NX5HM7IU.ts +218 -0
- package/dist/chunks/runtime-NX5HM7IU.ts.map +7 -0
- package/dist/index.ts +1478 -0
- package/dist/index.ts.map +7 -0
- package/package.json +12 -8
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/config.ts", "../src/sanitizer.ts", "../src/tracing.ts", "../src/langfuse.ts"],
|
|
4
|
+
"sourcesContent": ["import { randomUUID } from \"node:crypto\";\nimport { chmod, mkdir, readFile, rename, rm, stat, writeFile } from \"node:fs/promises\";\nimport { dirname, join } from \"node:path\";\nimport { getAgentDir } from \"@earendil-works/pi-coding-agent\";\n\nconst CONFIG_FILE_NAME = \"pi-langfuse.json\";\nexport const DEFAULT_BASE_URL = \"https://us.cloud.langfuse.com\";\n\nexport interface LangfuseConfig {\n\tpublicKey: string;\n\tsecretKey: string;\n\tbaseUrl: string;\n\tenvironment?: string;\n\trelease?: string;\n\tuserId?: string;\n\tcaptureContent: boolean;\n}\n\nexport type LangfuseConfigPatch = Partial<LangfuseConfig>;\n\nexport type LangfuseConfigResult =\n\t| { ok: true; config: LangfuseConfig; path: string; warnings: string[] }\n\t| { ok: false; path: string; warnings: string[]; reason: string };\n\nexport function langfuseConfigPath(): string {\n\treturn join(getAgentDir(), CONFIG_FILE_NAME);\n}\n\nconst configSaveQueues = new Map<string, Promise<void>>();\n\nexport async function waitForLangfuseConfigWrites(path = langfuseConfigPath()): Promise<void> {\n\tawait configSaveQueues.get(path);\n}\n\nexport function writeLangfuseConfig(\n\tpatch: LangfuseConfigPatch,\n\tpath = langfuseConfigPath(),\n): Promise<LangfuseConfig> {\n\tconst previous = configSaveQueues.get(path) ?? Promise.resolve();\n\tconst operation = previous.then(() => writeLangfuseConfigNow(patch, path));\n\tconst tail = operation.then(\n\t\t() => undefined,\n\t\t() => undefined,\n\t);\n\tconfigSaveQueues.set(path, tail);\n\tvoid tail.then(() => {\n\t\tif (configSaveQueues.get(path) === tail) configSaveQueues.delete(path);\n\t});\n\treturn operation;\n}\n\nasync function writeLangfuseConfigNow(\n\tpatch: LangfuseConfigPatch,\n\tpath: string,\n): Promise<LangfuseConfig> {\n\tconst currentDocument = await readLangfuseDocumentForUpdate(path);\n\tconst normalized = normalizeLangfuseConfig({ ...currentDocument, ...patch });\n\tif (!normalized.ok) throw new Error(normalized.reason);\n\tconst {\n\t\tpublicKey: _publicKey,\n\t\tsecretKey: _secretKey,\n\t\tbaseUrl: _baseUrl,\n\t\tenvironment: _environment,\n\t\trelease: _release,\n\t\tuserId: _userId,\n\t\tcaptureContent: _captureContent,\n\t\t...unknownFields\n\t} = currentDocument;\n\tconst nextDocument = { ...unknownFields, ...normalized.config };\n\n\tawait mkdir(dirname(path), { recursive: true, mode: 0o700 });\n\tconst tempPath = `${path}.${process.pid}.${randomUUID()}.tmp`;\n\ttry {\n\t\tawait writeFile(tempPath, `${JSON.stringify(nextDocument, null, 2)}\\n`, {\n\t\t\tencoding: \"utf8\",\n\t\t\tmode: 0o600,\n\t\t});\n\t\tawait chmod(tempPath, 0o600);\n\t\tawait rename(tempPath, path);\n\t\treturn normalized.config;\n\t} catch (error) {\n\t\tawait rm(tempPath, { force: true }).catch(() => undefined);\n\t\tthrow error;\n\t}\n}\n\nasync function readLangfuseDocumentForUpdate(path: string): Promise<Record<string, unknown>> {\n\tlet parsed: unknown;\n\ttry {\n\t\tparsed = JSON.parse(await readFile(path, \"utf8\")) as unknown;\n\t} catch (error) {\n\t\tif (isNodeError(error) && error.code === \"ENOENT\") return {};\n\t\tthrow new Error(\n\t\t\t`Cannot update ${CONFIG_FILE_NAME} because the existing file is malformed or unreadable; repair it first.`,\n\t\t);\n\t}\n\tconst normalized = normalizeLangfuseConfig(parsed);\n\tif (!normalized.ok) {\n\t\tthrow new Error(\n\t\t\t`Cannot update ${CONFIG_FILE_NAME} because the existing file has invalid recognized fields; repair it first.`,\n\t\t);\n\t}\n\treturn { ...(parsed as Record<string, unknown>) };\n}\n\nexport async function loadLangfuseConfig(\n\tpath = langfuseConfigPath(),\n): Promise<LangfuseConfigResult> {\n\tawait configSaveQueues.get(path);\n\tconst warnings: string[] = [];\n\tconst permissionFailure = await ensurePrivatePermissions(path, warnings);\n\tif (permissionFailure) {\n\t\treturn {\n\t\t\tok: false,\n\t\t\tpath,\n\t\t\twarnings,\n\t\t\treason: `Refusing to load credentials: ${permissionFailure}`,\n\t\t};\n\t}\n\n\tlet text: string;\n\ttry {\n\t\ttext = await readFile(path, \"utf8\");\n\t} catch (error) {\n\t\tif (isNodeError(error) && error.code === \"ENOENT\") {\n\t\t\treturn { ok: false, path, warnings, reason: `Configuration file not found: ${path}` };\n\t\t}\n\t\treturn {\n\t\t\tok: false,\n\t\t\tpath,\n\t\t\twarnings,\n\t\t\treason: `Failed to read ${path}: ${formatError(error)}`,\n\t\t};\n\t}\n\n\tlet parsed: unknown;\n\ttry {\n\t\tparsed = JSON.parse(text) as unknown;\n\t} catch {\n\t\treturn {\n\t\t\tok: false,\n\t\t\tpath,\n\t\t\twarnings,\n\t\t\treason: `Failed to parse ${path} as JSON; repair the file before retrying.`,\n\t\t};\n\t}\n\n\tconst normalized = normalizeLangfuseConfig(parsed);\n\tif (!normalized.ok) return { ok: false, path, warnings, reason: normalized.reason };\n\treturn { ok: true, config: normalized.config, path, warnings };\n}\n\nexport function normalizeLangfuseConfig(\n\tvalue: unknown,\n): { ok: true; config: LangfuseConfig } | { ok: false; reason: string } {\n\tif (!value || typeof value !== \"object\" || Array.isArray(value)) {\n\t\treturn { ok: false, reason: \"pi-langfuse.json must contain a JSON object.\" };\n\t}\n\tconst input = value as Record<string, unknown>;\n\tconst publicKey = normalizeString(input.publicKey);\n\tconst secretKey = normalizeString(input.secretKey);\n\tif (!publicKey) {\n\t\treturn { ok: false, reason: \"pi-langfuse.json requires a literal publicKey string.\" };\n\t}\n\tif (!secretKey) {\n\t\treturn { ok: false, reason: \"pi-langfuse.json requires a literal secretKey string.\" };\n\t}\n\tif (isInterpolation(publicKey)) {\n\t\treturn {\n\t\t\tok: false,\n\t\t\treason:\n\t\t\t\t\"pi-langfuse.json publicKey must be literal; environment and command interpolation are not supported.\",\n\t\t};\n\t}\n\tif (isInterpolation(secretKey)) {\n\t\treturn {\n\t\t\tok: false,\n\t\t\treason:\n\t\t\t\t\"pi-langfuse.json secretKey must be literal; environment and command interpolation are not supported.\",\n\t\t};\n\t}\n\n\tconst rawBaseUrl =\n\t\tinput.baseUrl === undefined ? DEFAULT_BASE_URL : normalizeString(input.baseUrl);\n\tif (!rawBaseUrl) {\n\t\treturn { ok: false, reason: \"pi-langfuse.json baseUrl must be a non-empty string.\" };\n\t}\n\tconst baseUrl = normalizeBaseUrl(rawBaseUrl);\n\tif (!baseUrl) {\n\t\treturn {\n\t\t\tok: false,\n\t\t\treason:\n\t\t\t\t\"pi-langfuse.json baseUrl must use HTTP or HTTPS without credentials, a query, or a fragment.\",\n\t\t};\n\t}\n\n\tif (input.captureContent !== undefined && typeof input.captureContent !== \"boolean\") {\n\t\treturn { ok: false, reason: \"pi-langfuse.json captureContent must be a boolean.\" };\n\t}\n\tconst environment = optionalString(input.environment, \"environment\");\n\tif (!environment.ok) return environment;\n\tif (\n\t\tenvironment.value &&\n\t\t(environment.value.length > 40 || !/^(?!langfuse)[a-z0-9_-]+$/u.test(environment.value))\n\t) {\n\t\treturn {\n\t\t\tok: false,\n\t\t\treason:\n\t\t\t\t\"pi-langfuse.json environment must be at most 40 lowercase letters, numbers, hyphens, or underscores and must not start with langfuse.\",\n\t\t};\n\t}\n\tconst release = optionalString(input.release, \"release\");\n\tif (!release.ok) return release;\n\tconst userId = optionalString(input.userId, \"userId\");\n\tif (!userId.ok) return userId;\n\tif (userId.value && userId.value.length > 200) {\n\t\treturn { ok: false, reason: \"pi-langfuse.json userId must be at most 200 characters.\" };\n\t}\n\n\treturn {\n\t\tok: true,\n\t\tconfig: {\n\t\t\tpublicKey,\n\t\t\tsecretKey,\n\t\t\tbaseUrl,\n\t\t\t...(environment.value ? { environment: environment.value } : {}),\n\t\t\t...(release.value ? { release: release.value } : {}),\n\t\t\t...(userId.value ? { userId: userId.value } : {}),\n\t\t\tcaptureContent: input.captureContent ?? true,\n\t\t},\n\t};\n}\n\nasync function ensurePrivatePermissions(\n\tpath: string,\n\twarnings: string[],\n): Promise<string | undefined> {\n\ttry {\n\t\tconst file = await stat(path);\n\t\tif ((file.mode & 0o777) !== 0o600) {\n\t\t\tawait chmod(path, 0o600);\n\t\t\tconst repaired = await stat(path);\n\t\t\tif ((repaired.mode & 0o777) !== 0o600) {\n\t\t\t\tthrow new Error(`permissions remained ${(repaired.mode & 0o777).toString(8)}`);\n\t\t\t}\n\t\t\twarnings.push(`Restricted ${path} permissions to 0600.`);\n\t\t}\n\t} catch (error) {\n\t\tif (isNodeError(error) && error.code === \"ENOENT\") return undefined;\n\t\tconst failure = `Failed to enforce 0600 permissions for ${path}: ${formatError(error)}`;\n\t\twarnings.push(failure);\n\t\treturn failure;\n\t}\n\treturn undefined;\n}\n\nfunction normalizeBaseUrl(value: string): string | undefined {\n\ttry {\n\t\tconst url = new URL(value);\n\t\tif (url.protocol !== \"http:\" && url.protocol !== \"https:\") return undefined;\n\t\tif (url.username || url.password || url.search || url.hash) return undefined;\n\t\treturn url.toString().replace(/\\/+$/, \"\");\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\nfunction optionalString(\n\tvalue: unknown,\n\tname: string,\n): { ok: true; value?: string } | { ok: false; reason: string } {\n\tif (value === undefined) return { ok: true };\n\tconst normalized = normalizeString(value);\n\treturn normalized\n\t\t? { ok: true, value: normalized }\n\t\t: { ok: false, reason: `pi-langfuse.json ${name} must be a non-empty string.` };\n}\n\nfunction normalizeString(value: unknown): string | undefined {\n\treturn typeof value === \"string\" && value.trim() ? value.trim() : undefined;\n}\n\nfunction isInterpolation(value: string): boolean {\n\treturn value.startsWith(\"$\") || value.startsWith(\"!\");\n}\n\nfunction isNodeError(error: unknown): error is NodeJS.ErrnoException {\n\treturn error instanceof Error && \"code\" in error;\n}\n\nfunction formatError(error: unknown): string {\n\treturn error instanceof Error ? error.message : String(error);\n}\n", "export const MAX_CAPTURE_BYTES = 64 * 1024;\nconst MAX_STRING_LENGTH = 50_000;\nconst MAX_COLLECTION_LENGTH = 200;\nconst MAX_DEPTH = 12;\nconst TRUNCATED = \"[truncated: content budget exceeded]\";\nconst BASE64_DATA_URI = /data:[^,\\s\"'`]*;base64,[^\\s\"'`]*/gi;\nconst BASE64_DATA_URI_OMITTED = \"[base64 data URI omitted]\";\nconst OPAQUE_SIGNATURE_KEYS = new Set([\"thinkingSignature\", \"textSignature\", \"thoughtSignature\"]);\n\nexport function sanitizeTraceValue(value: unknown): unknown {\n\tconst budget = { remaining: MAX_CAPTURE_BYTES };\n\tconst sanitized = sanitize(value, new WeakSet<object>(), 0, budget);\n\treturn serializedBytes(sanitized) <= MAX_CAPTURE_BYTES ? sanitized : TRUNCATED;\n}\n\nfunction sanitize(\n\tvalue: unknown,\n\tactive: WeakSet<object>,\n\tdepth: number,\n\tbudget: { remaining: number },\n): unknown {\n\tif (budget.remaining <= byteLength(TRUNCATED)) return TRUNCATED;\n\tif (value === null || typeof value === \"number\" || typeof value === \"boolean\") {\n\t\treturn consume(value, budget);\n\t}\n\tif (typeof value === \"string\") {\n\t\tconst bounded = truncateString(value, Math.min(MAX_STRING_LENGTH, budget.remaining));\n\t\tconst redacted = bounded.replace(BASE64_DATA_URI, BASE64_DATA_URI_OMITTED);\n\t\treturn consume(redacted, budget);\n\t}\n\tif (typeof value === \"bigint\") return consume(value.toString(), budget);\n\tif (typeof value === \"undefined\" || typeof value === \"function\" || typeof value === \"symbol\") {\n\t\treturn undefined;\n\t}\n\tif (value instanceof Date) {\n\t\treturn consume(Number.isNaN(value.getTime()) ? \"[invalid date]\" : value.toISOString(), budget);\n\t}\n\tif (value instanceof Error) {\n\t\treturn sanitize({ name: value.name, message: value.message }, active, depth, budget);\n\t}\n\tif (depth >= MAX_DEPTH) return consume(\"[maximum depth reached]\", budget);\n\tif (active.has(value)) return consume(\"[circular]\", budget);\n\tactive.add(value);\n\n\tlet result: unknown;\n\tif (Array.isArray(value)) {\n\t\tconst items: unknown[] = [];\n\t\tfor (const item of value.slice(0, MAX_COLLECTION_LENGTH)) {\n\t\t\tif (budget.remaining <= byteLength(TRUNCATED)) break;\n\t\t\titems.push(sanitize(item, active, depth + 1, budget));\n\t\t}\n\t\tif (items.length < value.length) items.push(`[${value.length - items.length} items omitted]`);\n\t\tresult = items;\n\t} else {\n\t\tconst record = value as Record<string, unknown>;\n\t\tconst output: Record<string, unknown> = {};\n\t\tconst objectType = readProperty(record, \"type\").value;\n\t\tconst redactData = objectType === \"image\" || objectType === \"base64\";\n\t\tlet visited = 0;\n\t\tlet processed = 0;\n\t\tlet omitted = false;\n\t\ttry {\n\t\t\tfor (const key in record) {\n\t\t\t\tif (visited >= MAX_COLLECTION_LENGTH || budget.remaining <= byteLength(TRUNCATED)) {\n\t\t\t\t\tomitted = true;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tvisited += 1;\n\t\t\t\tif (!Object.hasOwn(record, key) || OPAQUE_SIGNATURE_KEYS.has(key)) continue;\n\t\t\t\tconst keyBudget = Math.min(MAX_STRING_LENGTH, Math.max(0, budget.remaining - 4));\n\t\t\t\tif (key.length > keyBudget) {\n\t\t\t\t\tomitted = true;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tconst keyBytes = byteLength(key);\n\t\t\t\tif (keyBytes > keyBudget) {\n\t\t\t\t\tomitted = true;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tbudget.remaining -= keyBytes + 4;\n\t\t\t\tconst property = readProperty(record, key);\n\t\t\t\tif (redactData && key === \"data\") {\n\t\t\t\t\toutput[key] = consume(\"[base64 omitted]\", budget);\n\t\t\t\t} else if (!property.ok) output[key] = consume(\"[unreadable property]\", budget);\n\t\t\t\telse output[key] = sanitize(property.value, active, depth + 1, budget);\n\t\t\t\tprocessed += 1;\n\t\t\t}\n\t\t} catch {\n\t\t\tif (processed === 0) {\n\t\t\t\tactive.delete(value);\n\t\t\t\treturn consume(\"[unreadable object]\", budget);\n\t\t\t}\n\t\t\tomitted = true;\n\t\t}\n\t\tif (omitted) output.$truncated = \"additional object entries omitted\";\n\t\tresult = output;\n\t}\n\tactive.delete(value);\n\treturn result;\n}\n\nfunction readProperty(\n\trecord: Record<string, unknown>,\n\tkey: string,\n): { ok: true; value: unknown } | { ok: false; value?: undefined } {\n\ttry {\n\t\treturn { ok: true, value: record[key] };\n\t} catch {\n\t\treturn { ok: false };\n\t}\n}\n\nfunction consume<T>(value: T, budget: { remaining: number }): T | string {\n\tconst size = serializedBytes(value);\n\tif (size > budget.remaining) {\n\t\tbudget.remaining -= byteLength(TRUNCATED);\n\t\treturn TRUNCATED;\n\t}\n\tbudget.remaining -= size;\n\treturn value;\n}\n\nfunction truncateString(value: string, maxBytes: number): string {\n\tconst boundedPrefix = value.slice(0, maxBytes);\n\tif (boundedPrefix.length === value.length && byteLength(boundedPrefix) <= maxBytes) {\n\t\treturn boundedPrefix;\n\t}\n\tconst suffix = \"\u2026 [truncated]\";\n\tconst target = Math.max(0, maxBytes - byteLength(suffix) - 2);\n\tlet bytes = 0;\n\tlet output = \"\";\n\tfor (const character of boundedPrefix) {\n\t\tconst size = byteLength(character);\n\t\tif (bytes + size > target) break;\n\t\toutput += character;\n\t\tbytes += size;\n\t}\n\treturn `${output}${suffix}`;\n}\n\nfunction serializedBytes(value: unknown): number {\n\treturn byteLength(JSON.stringify(value) ?? \"null\");\n}\n\nfunction byteLength(value: string): number {\n\treturn Buffer.byteLength(value, \"utf8\");\n}\n", "import { sanitizeTraceValue } from \"./sanitizer.js\";\n\nexport { MAX_CAPTURE_BYTES, sanitizeTraceValue } from \"./sanitizer.js\";\n\nexport const TRACE_SCHEMA_VERSION = \"2\";\nconst MAX_HEADER_VALUE_LENGTH = 1_024;\nconst CONTENT_DISABLED = \"[content capture disabled]\";\nconst ALLOWED_RESPONSE_HEADERS = new Set([\n\t\"anthropic-ratelimit-requests-limit\",\n\t\"anthropic-ratelimit-requests-remaining\",\n\t\"anthropic-ratelimit-requests-reset\",\n\t\"anthropic-ratelimit-tokens-limit\",\n\t\"anthropic-ratelimit-tokens-remaining\",\n\t\"anthropic-ratelimit-tokens-reset\",\n\t\"cf-ray\",\n\t\"openai-request-id\",\n\t\"request-id\",\n\t\"retry-after\",\n\t\"x-amzn-requestid\",\n\t\"x-request-id\",\n\t\"x-ratelimit-limit-requests\",\n\t\"x-ratelimit-limit-tokens\",\n\t\"x-ratelimit-remaining-requests\",\n\t\"x-ratelimit-remaining-tokens\",\n\t\"x-ratelimit-reset-requests\",\n\t\"x-ratelimit-reset-tokens\",\n]);\n\nexport interface ObservationAttributes {\n\tinput?: unknown;\n\toutput?: unknown;\n\tmetadata?: Record<string, unknown>;\n\tlevel?: \"DEBUG\" | \"DEFAULT\" | \"WARNING\" | \"ERROR\";\n\tstatusMessage?: string;\n\tcompletionStartTime?: Date;\n\tmodel?: string;\n\tmodelParameters?: Record<string, string | number>;\n\tusageDetails?: Record<string, number>;\n\tcostDetails?: Record<string, number>;\n\tversion?: string;\n\tname?: string;\n\tsessionId?: string;\n\tuserId?: string;\n\ttags?: string[];\n}\n\nexport interface Observation {\n\tupdate(attributes: ObservationAttributes): Observation;\n\tupdateTrace?(attributes: ObservationAttributes): Observation;\n\tend(endTime?: number): Observation;\n}\n\nexport type ObservationType = \"agent\" | \"generation\" | \"span\" | \"tool\";\n\nexport interface TraceBackend {\n\tstart(\n\t\tname: string,\n\t\tattributes: ObservationAttributes,\n\t\toptions: { asType: ObservationType; parent?: Observation },\n\t): Observation;\n\tforceFlush(): Promise<void>;\n\tshutdown(): Promise<void>;\n}\n\ninterface RecorderContext {\n\tsessionId: string;\n\tuserId?: string;\n\tcwd: string;\n\tmode: string;\n\tcaptureContent: boolean;\n}\n\ninterface ModelDescriptor {\n\tprovider?: string;\n\tid?: string;\n\tapi?: string;\n}\n\nexport interface GitMetadata {\n\tbranch?: string;\n\tcommit?: string;\n\tdetached: boolean;\n}\n\nexport interface ContextSnapshot {\n\tleafId?: string | null;\n\tcontextUsage?: {\n\t\ttokens: number | null;\n\t\tcontextWindow: number;\n\t\tpercent: number | null;\n\t};\n}\n\ninterface BeginAgentInput {\n\tprompt: unknown;\n\timages?: unknown;\n\tmodel?: ModelDescriptor;\n\tgit?: GitMetadata;\n\tsnapshot?: ContextSnapshot;\n}\n\ninterface AttemptInput {\n\treason?: string;\n}\n\ninterface GenerationInput {\n\tpayload?: unknown;\n\tpayloadStage?: \"before_provider_request\";\n\tmodel?: ModelDescriptor;\n\tthinkingLevel?: string;\n}\n\ninterface AssistantMessage {\n\trole: string;\n\tcontent?: unknown;\n\tprovider?: string;\n\tapi?: string;\n\tmodel?: string;\n\tresponseModel?: string;\n\tresponseId?: string;\n\tusage?: {\n\t\tinput?: number;\n\t\toutput?: number;\n\t\tcacheRead?: number;\n\t\tcacheWrite?: number;\n\t\tcacheWrite1h?: number;\n\t\treasoning?: number;\n\t\ttotalTokens?: number;\n\t\tcost?: {\n\t\t\tinput?: number;\n\t\t\toutput?: number;\n\t\t\tcacheRead?: number;\n\t\t\tcacheWrite?: number;\n\t\t\ttotal?: number;\n\t\t};\n\t};\n\tstopReason?: string;\n\terrorMessage?: string;\n}\n\ninterface ToolResult {\n\tcontent?: unknown;\n\tdetails?: unknown;\n\tisError?: boolean;\n}\n\ninterface TurnResult {\n\tmessage: { role: string; stopReason?: string; errorMessage?: string };\n\ttoolResultCount: number;\n}\n\ninterface CompactionStart {\n\treason: string;\n\twillRetry: boolean;\n\ttokensBefore?: number;\n\tmessagesToSummarize: number;\n\tturnPrefixMessages: number;\n\tbranchEntries: number;\n\tisSplitTurn: boolean;\n}\n\ninterface CompactionFinish {\n\treason: string;\n\twillRetry: boolean;\n\tfromExtension: boolean;\n\ttokensBefore?: number;\n\tdetails?: unknown;\n\tusage?: {\n\t\tinput?: number;\n\t\toutput?: number;\n\t\tcacheRead?: number;\n\t\tcacheWrite?: number;\n\t\ttotalTokens?: number;\n\t\tcost?: {\n\t\t\tinput?: number;\n\t\t\toutput?: number;\n\t\t\tcacheRead?: number;\n\t\t\tcacheWrite?: number;\n\t\t\ttotal?: number;\n\t\t};\n\t};\n}\n\ntype Outcome = \"success\" | \"error\" | \"aborted\" | \"length\" | \"interrupted\";\n\ninterface GenerationState {\n\tobservation: Observation;\n\tendTime?: number;\n\tcompletionStartTime?: number;\n\trequestMetadata: Record<string, unknown>;\n\tstatuses: number[];\n\theaders: Record<string, string>;\n}\n\ninterface ToolState {\n\tobservation: Observation;\n\tstartedAt: number;\n\tprogressUpdates: number;\n\tfirstProgressAt?: number;\n}\n\ninterface CompactionState {\n\tobservation: Observation;\n}\n\ninterface Counters {\n\tattempts: number;\n\tturns: number;\n\tgenerations: number;\n\ttools: number;\n\ttoolErrors: number;\n\tcompactions: number;\n\trecoveredErrors: number;\n\tfailedAttempts: number;\n}\n\nexport class TraceRecorder {\n\tprivate root: Observation | undefined;\n\tprivate attempt: Observation | undefined;\n\tprivate attemptIndex: number | undefined;\n\tprivate turn: Observation | undefined;\n\tprivate turnIndex: number | undefined;\n\tprivate generation: GenerationState | undefined;\n\tprivate readonly tools = new Map<string, ToolState>();\n\tprivate readonly duplicateToolIds = new Set<string>();\n\tprivate compaction: CompactionState | undefined;\n\tprivate lastOutput: unknown;\n\tprivate lastAssistant: AssistantMessage | undefined;\n\tprivate lastAttemptOutcome: Outcome | undefined;\n\tprivate unresolvedToolErrors = 0;\n\tprivate startSnapshot: ContextSnapshot | undefined;\n\tprivate counters: Counters = emptyCounters();\n\n\tconstructor(\n\t\tprivate readonly backend: TraceBackend,\n\t\tprivate readonly context: RecorderContext,\n\t) {}\n\n\tprivate startObservation(\n\t\tname: string,\n\t\tattributes: ObservationAttributes,\n\t\toptions: { asType: ObservationType; parent?: Observation },\n\t): Observation {\n\t\tconst { sessionId, userId } = this.context;\n\t\treturn this.backend.start(\n\t\t\tname,\n\t\t\t{ ...attributes, sessionId, ...(userId ? { userId } : {}) },\n\t\t\toptions,\n\t\t);\n\t}\n\n\thasActiveTrace(): boolean {\n\t\treturn this.root !== undefined;\n\t}\n\n\thasActiveAttempt(): boolean {\n\t\treturn this.attempt !== undefined;\n\t}\n\n\tbeginAgent(input: BeginAgentInput): void {\n\t\tif (this.root) this.closeActiveTrace(\"Interrupted by a new Pi run.\", undefined, \"interrupted\");\n\n\t\tthis.lastOutput = undefined;\n\t\tthis.lastAssistant = undefined;\n\t\tthis.lastAttemptOutcome = undefined;\n\t\tthis.unresolvedToolErrors = 0;\n\t\tthis.duplicateToolIds.clear();\n\t\tthis.startSnapshot = input.snapshot;\n\t\tthis.counters = emptyCounters();\n\t\tconst traceInput = this.capture({\n\t\t\tprompt: input.prompt,\n\t\t\t...(hasItems(input.images) ? { images: input.images } : {}),\n\t\t});\n\t\tconst metadata: Record<string, unknown> = {\n\t\t\t\"pi.cwd\": this.context.cwd,\n\t\t\t...(input.git?.branch ? { \"pi.git.branch\": input.git.branch } : {}),\n\t\t\t...(input.git?.commit ? { \"pi.git.commit\": input.git.commit } : {}),\n\t\t\t...(input.git ? { \"pi.git.detached\": input.git.detached } : {}),\n\t\t\t\"pi.mode\": this.context.mode,\n\t\t\t...(input.model?.id ? { \"pi.model\": input.model.id } : {}),\n\t\t\t...(input.model?.provider ? { \"pi.provider\": input.model.provider } : {}),\n\t\t\t\"pi.session.id\": this.context.sessionId,\n\t\t\t\"pi.trace.schema_version\": Number(TRACE_SCHEMA_VERSION),\n\t\t\t...snapshotMetadata(\"start\", input.snapshot),\n\t\t};\n\t\tconst attributes = { input: traceInput, metadata, version: TRACE_SCHEMA_VERSION };\n\t\tconst gitTag = input.git?.branch\n\t\t\t? `branch:${input.git.branch}`\n\t\t\t: input.git?.detached\n\t\t\t\t? \"git:detached\"\n\t\t\t\t: undefined;\n\n\t\tthis.root = this.startObservation(\"pi.agent\", attributes, { asType: \"agent\" });\n\t\tthis.root.updateTrace?.({\n\t\t\tname: \"pi.trace\",\n\t\t\tsessionId: this.context.sessionId,\n\t\t\t...(this.context.userId ? { userId: this.context.userId } : {}),\n\t\t\tversion: TRACE_SCHEMA_VERSION,\n\t\t\tinput: traceInput,\n\t\t\tmetadata,\n\t\t\ttags: [\"pi\", ...(gitTag ? [gitTag] : [])],\n\t\t});\n\t}\n\n\tbeginAttempt(input: AttemptInput = {}): void {\n\t\tif (!this.root) return;\n\t\tif (this.attempt) {\n\t\t\tthis.closeAttempt(undefined, \"Interrupted by the next Pi attempt.\", \"interrupted\");\n\t\t}\n\t\tconst index = this.counters.attempts;\n\t\tthis.counters.attempts += 1;\n\t\tthis.lastAssistant = undefined;\n\t\tthis.unresolvedToolErrors = 0;\n\t\tthis.attemptIndex = index;\n\t\tthis.attempt = this.startObservation(\n\t\t\t\"pi.attempt\",\n\t\t\t{\n\t\t\t\tmetadata: {\n\t\t\t\t\t\"pi.attempt.index\": index,\n\t\t\t\t\t...(input.reason ? { \"pi.attempt.reason\": input.reason } : {}),\n\t\t\t\t},\n\t\t\t\tversion: TRACE_SCHEMA_VERSION,\n\t\t\t},\n\t\t\t{ asType: \"span\", parent: this.root },\n\t\t);\n\t}\n\n\tfinishAttempt(message?: AssistantMessage): void {\n\t\tif (message?.role === \"assistant\") this.finishAssistant(message);\n\t\tif (!this.attempt) return;\n\t\tconst outcome = this.unresolvedToolErrors > 0 ? \"error\" : classifyOutcome(message);\n\t\tthis.closeAttempt(\n\t\t\tmessage,\n\t\t\tthis.unresolvedToolErrors > 0 ? \"Pi attempt ended after a tool failure.\" : undefined,\n\t\t\toutcome,\n\t\t);\n\t}\n\n\tbeginTurn(turnIndex: number): void {\n\t\tif (!this.root) return;\n\t\tif (this.turn) this.closeTurn(\"Interrupted by the next Pi turn.\", \"ERROR\");\n\t\tthis.counters.turns += 1;\n\t\tthis.turnIndex = turnIndex;\n\t\tthis.turn = this.startObservation(\n\t\t\t\"pi.turn\",\n\t\t\t{ metadata: { \"pi.turn.index\": turnIndex }, version: TRACE_SCHEMA_VERSION },\n\t\t\t{ asType: \"span\", parent: this.attempt ?? this.root },\n\t\t);\n\t}\n\n\tfinishTurn(turnIndex: number, result: TurnResult): void {\n\t\tif (!this.turn) return;\n\t\tthis.closeGeneration(\"Turn ended without a finalized assistant message.\");\n\t\tthis.closeTools(\"Tool span ended when the Pi turn finished.\");\n\n\t\tconst mismatched = this.turnIndex !== turnIndex;\n\t\tconst outcome = classifyOutcome(result.message);\n\t\tthis.turn.update({\n\t\t\tmetadata: {\n\t\t\t\t\"pi.turn.index\": this.turnIndex ?? turnIndex,\n\t\t\t\t\"pi.turn.tool_result_count\": result.toolResultCount,\n\t\t\t\t...(result.message.stopReason ? { \"pi.turn.stop_reason\": result.message.stopReason } : {}),\n\t\t\t},\n\t\t\t...(mismatched && outcome === \"success\"\n\t\t\t\t? {\n\t\t\t\t\t\tlevel: \"WARNING\" as const,\n\t\t\t\t\t\tstatusMessage: `Turn ${turnIndex} ended while turn ${this.turnIndex} was active.`,\n\t\t\t\t\t}\n\t\t\t\t: severityForOutcome(outcome, result.message.errorMessage)),\n\t\t});\n\t\tthis.turn.end();\n\t\tthis.turn = undefined;\n\t\tthis.turnIndex = undefined;\n\t}\n\n\tbeginGeneration(input: GenerationInput = {}): void {\n\t\tif (!this.root) return;\n\t\tthis.closeGeneration(\"Interrupted by the next provider request.\");\n\t\tif (this.unresolvedToolErrors > 0) {\n\t\t\tthis.counters.recoveredErrors += this.unresolvedToolErrors;\n\t\t\tthis.unresolvedToolErrors = 0;\n\t\t}\n\t\tthis.counters.generations += 1;\n\t\tconst requestMetadata: Record<string, unknown> = {\n\t\t\t...(input.payloadStage ? { \"pi.request.payload_stage\": input.payloadStage } : {}),\n\t\t\t...(input.model?.provider ? { \"pi.request.provider\": input.model.provider } : {}),\n\t\t\t...(input.model?.id ? { \"pi.request.model\": input.model.id } : {}),\n\t\t\t...(input.model?.api ? { \"pi.request.api\": input.model.api } : {}),\n\t\t\t...(input.thinkingLevel ? { \"pi.request.thinking_level\": input.thinkingLevel } : {}),\n\t\t};\n\t\tconst observation = this.startObservation(\n\t\t\t\"pi.llm\",\n\t\t\t{\n\t\t\t\t...(input.payload !== undefined ? { input: this.capture(input.payload) } : {}),\n\t\t\t\t...(input.model?.id ? { model: input.model.id } : {}),\n\t\t\t\t...(input.thinkingLevel\n\t\t\t\t\t? { modelParameters: { thinking_level: input.thinkingLevel } }\n\t\t\t\t\t: {}),\n\t\t\t\t...(Object.keys(requestMetadata).length > 0 ? { metadata: requestMetadata } : {}),\n\t\t\t\tversion: TRACE_SCHEMA_VERSION,\n\t\t\t},\n\t\t\t{ asType: \"generation\", parent: this.turn ?? this.attempt ?? this.root },\n\t\t);\n\t\tthis.generation = {\n\t\t\tobservation,\n\t\t\trequestMetadata,\n\t\t\tstatuses: [],\n\t\t\theaders: {},\n\t\t};\n\t}\n\n\trecordProviderResponse(status: number, headers: Record<string, string> = {}): void {\n\t\tif (!this.generation) return;\n\t\tthis.generation.statuses.push(status);\n\t\tObject.assign(this.generation.headers, allowlistedResponseHeaders(headers));\n\t}\n\n\tmarkGenerationFirstOutput(timestamp = Date.now()): void {\n\t\tif (this.generation && this.generation.completionStartTime === undefined) {\n\t\t\tthis.generation.completionStartTime = timestamp;\n\t\t}\n\t}\n\n\tmarkGenerationEnd(endTime = Date.now()): void {\n\t\tif (this.generation && this.generation.endTime === undefined) {\n\t\t\tthis.generation.endTime = endTime;\n\t\t}\n\t}\n\n\tfinishAssistant(message: AssistantMessage): void {\n\t\tif (message.role !== \"assistant\") return;\n\t\tthis.lastAssistant = message;\n\t\tthis.lastOutput = this.capture(message.content);\n\t\tif (!this.generation) return;\n\n\t\tconst state = this.generation;\n\t\tconst usageDetails = numericRecord({\n\t\t\tinput: message.usage?.input,\n\t\t\toutput: message.usage?.output,\n\t\t\tcache_read_input_tokens: message.usage?.cacheRead,\n\t\t\tcache_creation_input_tokens: message.usage?.cacheWrite,\n\t\t\ttotal: message.usage?.totalTokens,\n\t\t});\n\t\tconst costDetails = positiveNumericRecord({\n\t\t\tinput: message.usage?.cost?.input,\n\t\t\toutput: message.usage?.cost?.output,\n\t\t\tcache_read: message.usage?.cost?.cacheRead,\n\t\t\tcache_write: message.usage?.cost?.cacheWrite,\n\t\t\ttotal: message.usage?.cost?.total,\n\t\t});\n\t\tconst outcome = classifyOutcome(message);\n\t\tconst responseModel = message.responseModel ?? message.model;\n\t\tconst httpMetadata = generationHttpMetadata(state);\n\t\tconst recoveredStatuses = state.statuses.filter((status) => status >= 400).length;\n\t\tif (outcome === \"success\" && recoveredStatuses > 0) {\n\t\t\tthis.counters.recoveredErrors += recoveredStatuses;\n\t\t}\n\t\tstate.observation.update({\n\t\t\toutput: this.lastOutput,\n\t\t\t...(state.completionStartTime !== undefined\n\t\t\t\t? { completionStartTime: new Date(state.completionStartTime) }\n\t\t\t\t: {}),\n\t\t\t...(responseModel ? { model: responseModel } : {}),\n\t\t\t...(Object.keys(usageDetails).length > 0 ? { usageDetails } : {}),\n\t\t\t...(Object.keys(costDetails).length > 0 ? { costDetails } : {}),\n\t\t\tmetadata: {\n\t\t\t\t...state.requestMetadata,\n\t\t\t\t...httpMetadata,\n\t\t\t\t...(message.provider\n\t\t\t\t\t? { \"pi.provider\": message.provider, \"pi.response.provider\": message.provider }\n\t\t\t\t\t: {}),\n\t\t\t\t...(message.api ? { \"pi.response.api\": message.api } : {}),\n\t\t\t\t...(responseModel ? { \"pi.response.model\": responseModel } : {}),\n\t\t\t\t...(message.responseId ? { \"pi.response.id\": message.responseId } : {}),\n\t\t\t\t...(message.responseModel && message.model && message.responseModel !== message.model\n\t\t\t\t\t? { \"pi.requested_model\": message.model }\n\t\t\t\t\t: {}),\n\t\t\t\t...(message.stopReason ? { \"pi.stop_reason\": message.stopReason } : {}),\n\t\t\t\t...(finiteNumber(message.usage?.reasoning)\n\t\t\t\t\t? { \"pi.usage.reasoning_tokens\": message.usage.reasoning }\n\t\t\t\t\t: {}),\n\t\t\t\t...(finiteNumber(message.usage?.cacheWrite1h)\n\t\t\t\t\t? { \"pi.usage.cache_write_1h_tokens\": message.usage.cacheWrite1h }\n\t\t\t\t\t: {}),\n\t\t\t},\n\t\t\t...severityForOutcome(outcome, message.errorMessage),\n\t\t});\n\t\tstate.observation.end(state.endTime);\n\t\tthis.generation = undefined;\n\t}\n\n\tbeginTool(toolCallId: string, toolName: string, args?: unknown, startedAt = Date.now()): void {\n\t\tif (!this.root) return;\n\t\tthis.counters.tools += 1;\n\t\tif (this.duplicateToolIds.has(toolCallId)) {\n\t\t\tthis.counters.toolErrors += 1;\n\t\t\tconst duplicate = this.startToolObservation(toolCallId, toolName, args);\n\t\t\tduplicate.update({\n\t\t\t\tlevel: \"ERROR\",\n\t\t\t\tstatusMessage: \"Duplicate tool call ID cannot be correlated safely.\",\n\t\t\t});\n\t\t\tduplicate.end();\n\t\t\treturn;\n\t\t}\n\n\t\tconst existing = this.tools.get(toolCallId);\n\t\tif (existing) {\n\t\t\texisting.observation.update({\n\t\t\t\tlevel: \"ERROR\",\n\t\t\t\tstatusMessage: \"Duplicate tool execution started.\",\n\t\t\t});\n\t\t\texisting.observation.end();\n\t\t\tthis.tools.delete(toolCallId);\n\t\t\tthis.counters.toolErrors += 2;\n\t\t\tconst duplicate = this.startToolObservation(toolCallId, toolName, args);\n\t\t\tduplicate.update({\n\t\t\t\tlevel: \"ERROR\",\n\t\t\t\tstatusMessage: \"Duplicate tool call ID cannot be correlated safely.\",\n\t\t\t});\n\t\t\tduplicate.end();\n\t\t\tthis.duplicateToolIds.add(toolCallId);\n\t\t\treturn;\n\t\t}\n\n\t\tthis.tools.set(toolCallId, {\n\t\t\tobservation: this.startToolObservation(toolCallId, toolName, args),\n\t\t\tstartedAt,\n\t\t\tprogressUpdates: 0,\n\t\t});\n\t}\n\n\trecordToolInput(toolCallId: string, input: unknown): void {\n\t\tif (input === undefined || this.duplicateToolIds.has(toolCallId)) return;\n\t\tthis.tools.get(toolCallId)?.observation.update({ input: this.capture(input) });\n\t}\n\n\trecordToolProgress(toolCallId: string, timestamp = Date.now()): void {\n\t\tconst tool = this.tools.get(toolCallId);\n\t\tif (!tool) return;\n\t\ttool.progressUpdates += 1;\n\t\ttool.firstProgressAt ??= timestamp;\n\t}\n\n\tfinishTool(toolCallId: string, result: ToolResult): void {\n\t\tif (this.duplicateToolIds.has(toolCallId)) return;\n\t\tconst tool = this.tools.get(toolCallId);\n\t\tif (!tool) return;\n\t\tif (result.isError) {\n\t\t\tthis.counters.toolErrors += 1;\n\t\t\tthis.unresolvedToolErrors += 1;\n\t\t}\n\t\ttool.observation.update({\n\t\t\toutput: this.capture({ content: result.content, details: result.details }),\n\t\t\tmetadata: {\n\t\t\t\t\"pi.tool.progress_update_count\": tool.progressUpdates,\n\t\t\t\t...(tool.firstProgressAt !== undefined\n\t\t\t\t\t? {\n\t\t\t\t\t\t\t\"pi.tool.time_to_first_progress_ms\": Math.max(\n\t\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\t\ttool.firstProgressAt - tool.startedAt,\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t}\n\t\t\t\t\t: {}),\n\t\t\t},\n\t\t\t...(result.isError\n\t\t\t\t? { level: \"ERROR\" as const, statusMessage: \"Pi tool execution failed.\" }\n\t\t\t\t: {}),\n\t\t});\n\t\ttool.observation.end();\n\t\tthis.tools.delete(toolCallId);\n\t}\n\n\tbeginCompaction(input: CompactionStart): void {\n\t\tif (!this.root) return;\n\t\tthis.closeCompaction(\"Interrupted by another Pi compaction.\");\n\t\tthis.counters.compactions += 1;\n\t\tthis.compaction = {\n\t\t\tobservation: this.startObservation(\n\t\t\t\t\"pi.compaction\",\n\t\t\t\t{\n\t\t\t\t\tmetadata: {\n\t\t\t\t\t\t\"pi.compaction.reason\": input.reason,\n\t\t\t\t\t\t\"pi.compaction.will_retry\": input.willRetry,\n\t\t\t\t\t\t...(finiteNumber(input.tokensBefore)\n\t\t\t\t\t\t\t? { \"pi.compaction.tokens_before\": input.tokensBefore }\n\t\t\t\t\t\t\t: {}),\n\t\t\t\t\t\t\"pi.compaction.messages_to_summarize\": input.messagesToSummarize,\n\t\t\t\t\t\t\"pi.compaction.turn_prefix_messages\": input.turnPrefixMessages,\n\t\t\t\t\t\t\"pi.compaction.branch_entries\": input.branchEntries,\n\t\t\t\t\t\t\"pi.compaction.is_split_turn\": input.isSplitTurn,\n\t\t\t\t\t},\n\t\t\t\t\tversion: TRACE_SCHEMA_VERSION,\n\t\t\t\t},\n\t\t\t\t{ asType: \"span\", parent: this.root },\n\t\t\t),\n\t\t};\n\t}\n\n\tfinishCompaction(input: CompactionFinish): void {\n\t\tif (!this.compaction) return;\n\t\tconst details = structuralCompactionDetails(input.details);\n\t\tconst usage = numericRecord({\n\t\t\tinput: input.usage?.input,\n\t\t\toutput: input.usage?.output,\n\t\t\tcache_read: input.usage?.cacheRead,\n\t\t\tcache_write: input.usage?.cacheWrite,\n\t\t\ttotal: input.usage?.totalTokens,\n\t\t});\n\t\tconst cost = positiveNumericRecord({\n\t\t\tinput: input.usage?.cost?.input,\n\t\t\toutput: input.usage?.cost?.output,\n\t\t\tcache_read: input.usage?.cost?.cacheRead,\n\t\t\tcache_write: input.usage?.cost?.cacheWrite,\n\t\t\ttotal: input.usage?.cost?.total,\n\t\t});\n\t\tthis.compaction.observation.update({\n\t\t\tmetadata: {\n\t\t\t\t\"pi.compaction.reason\": input.reason,\n\t\t\t\t\"pi.compaction.will_retry\": input.willRetry,\n\t\t\t\t\"pi.compaction.from_extension\": input.fromExtension,\n\t\t\t\t...(finiteNumber(input.tokensBefore)\n\t\t\t\t\t? { \"pi.compaction.tokens_before\": input.tokensBefore }\n\t\t\t\t\t: {}),\n\t\t\t\t...details,\n\t\t\t\t...prefixRecord(\"pi.compaction.usage\", usage),\n\t\t\t\t...prefixRecord(\"pi.compaction.cost\", cost),\n\t\t\t},\n\t\t});\n\t\tthis.compaction.observation.end();\n\t\tthis.compaction = undefined;\n\t}\n\n\tsettle(snapshot?: ContextSnapshot): void {\n\t\tthis.closeActiveTrace(undefined, snapshot);\n\t}\n\n\tinterrupt(statusMessage: string, snapshot?: ContextSnapshot): void {\n\t\tthis.closeActiveTrace(statusMessage, snapshot, \"interrupted\");\n\t}\n\n\tasync flush(): Promise<void> {\n\t\tawait this.backend.forceFlush();\n\t}\n\n\tasync shutdown(snapshot?: ContextSnapshot): Promise<void> {\n\t\tthis.closeActiveTrace(\"Pi shut down before the active trace settled.\", snapshot, \"interrupted\");\n\t\tawait this.backend.shutdown();\n\t}\n\n\tprivate closeActiveTrace(\n\t\tstatusMessage?: string,\n\t\tsnapshot?: ContextSnapshot,\n\t\tforcedOutcome?: Outcome,\n\t): void {\n\t\tthis.closeTurn(statusMessage ?? \"Pi turn ended when the agent run settled.\");\n\t\tthis.closeAttempt(undefined, statusMessage, forcedOutcome ?? \"interrupted\");\n\t\tthis.closeCompaction(statusMessage ?? \"Pi compaction ended when the agent run settled.\");\n\n\t\tif (!this.root) return;\n\t\tconst baseOutcome =\n\t\t\tforcedOutcome ?? this.lastAttemptOutcome ?? classifyOutcome(this.lastAssistant);\n\t\tconst recoveredErrorCount =\n\t\t\tthis.counters.recoveredErrors +\n\t\t\t(baseOutcome === \"success\" ? this.counters.failedAttempts : 0);\n\t\tconst traceOutcome =\n\t\t\tbaseOutcome === \"success\" && recoveredErrorCount > 0 ? \"recovered_success\" : baseOutcome;\n\t\tconst finalMetadata: Record<string, unknown> = {\n\t\t\t\"pi.trace.schema_version\": Number(TRACE_SCHEMA_VERSION),\n\t\t\t\"pi.trace.outcome\": traceOutcome,\n\t\t\t...(this.lastAssistant?.stopReason\n\t\t\t\t? { \"pi.trace.stop_reason\": this.lastAssistant.stopReason }\n\t\t\t\t: {}),\n\t\t\t\"pi.trace.attempt_count\": this.counters.attempts,\n\t\t\t\"pi.trace.turn_count\": this.counters.turns,\n\t\t\t\"pi.trace.generation_count\": this.counters.generations,\n\t\t\t\"pi.trace.tool_count\": this.counters.tools,\n\t\t\t\"pi.trace.tool_error_count\": this.counters.toolErrors,\n\t\t\t\"pi.trace.compaction_count\": this.counters.compactions,\n\t\t\t\"pi.trace.recovered_error_count\": recoveredErrorCount,\n\t\t\t...snapshotMetadata(\"start\", this.startSnapshot),\n\t\t\t...snapshotMetadata(\"end\", snapshot),\n\t\t};\n\t\tconst finalAttributes: ObservationAttributes = {\n\t\t\t...(this.lastOutput !== undefined ? { output: this.lastOutput } : {}),\n\t\t\tmetadata: finalMetadata,\n\t\t\t...severityForOutcome(baseOutcome, statusMessage ?? this.lastAssistant?.errorMessage),\n\t\t};\n\t\tthis.root.update(finalAttributes);\n\t\tthis.root.updateTrace?.({\n\t\t\t...(this.lastOutput !== undefined ? { output: this.lastOutput } : {}),\n\t\t\tmetadata: finalMetadata,\n\t\t\tversion: TRACE_SCHEMA_VERSION,\n\t\t});\n\t\tthis.root.end();\n\t\tthis.root = undefined;\n\t\tthis.lastOutput = undefined;\n\t\tthis.lastAssistant = undefined;\n\t\tthis.lastAttemptOutcome = undefined;\n\t\tthis.unresolvedToolErrors = 0;\n\t\tthis.duplicateToolIds.clear();\n\t\tthis.startSnapshot = undefined;\n\t}\n\n\tprivate closeAttempt(\n\t\tmessage?: AssistantMessage,\n\t\tstatusMessage?: string,\n\t\tforcedOutcome?: Outcome,\n\t): void {\n\t\tif (!this.attempt) return;\n\t\tthis.closeTurn(statusMessage ?? \"Pi turn ended when the attempt finished.\");\n\t\tconst outcome = forcedOutcome ?? classifyOutcome(message);\n\t\tif (outcome === \"error\") this.counters.failedAttempts += 1;\n\t\tthis.lastAttemptOutcome = outcome;\n\t\tthis.attempt.update({\n\t\t\t...(message?.content !== undefined ? { output: this.capture(message.content) } : {}),\n\t\t\tmetadata: {\n\t\t\t\t\"pi.attempt.index\": this.attemptIndex ?? Math.max(0, this.counters.attempts - 1),\n\t\t\t\t\"pi.attempt.outcome\": outcome,\n\t\t\t\t...(message?.stopReason ? { \"pi.attempt.stop_reason\": message.stopReason } : {}),\n\t\t\t},\n\t\t\t...severityForOutcome(outcome, statusMessage ?? message?.errorMessage),\n\t\t});\n\t\tthis.attempt.end();\n\t\tthis.attempt = undefined;\n\t\tthis.attemptIndex = undefined;\n\t\tthis.unresolvedToolErrors = 0;\n\t}\n\n\tprivate startToolObservation(toolCallId: string, toolName: string, args?: unknown): Observation {\n\t\treturn this.startObservation(\n\t\t\t`pi.tool.${toolName}`,\n\t\t\t{\n\t\t\t\t...(args !== undefined ? { input: this.capture(args) } : {}),\n\t\t\t\tmetadata: { \"pi.tool.call_id\": toolCallId, \"pi.tool.name\": toolName },\n\t\t\t\tversion: TRACE_SCHEMA_VERSION,\n\t\t\t},\n\t\t\t{ asType: \"tool\", parent: this.turn ?? this.attempt ?? this.root },\n\t\t);\n\t}\n\n\tprivate closeTurn(statusMessage: string, generationLevel: \"ERROR\" | \"WARNING\" = \"WARNING\"): void {\n\t\tthis.closeGeneration(statusMessage, generationLevel);\n\t\tthis.closeTools(statusMessage);\n\t\tif (!this.turn) return;\n\t\tthis.turn.update({ level: \"WARNING\", statusMessage });\n\t\tthis.turn.end();\n\t\tthis.turn = undefined;\n\t\tthis.turnIndex = undefined;\n\t}\n\n\tprivate closeTools(statusMessage: string): void {\n\t\tfor (const tool of this.tools.values()) {\n\t\t\ttool.observation.update({\n\t\t\t\tlevel: \"WARNING\",\n\t\t\t\tstatusMessage,\n\t\t\t\tmetadata: {\n\t\t\t\t\t\"pi.tool.progress_update_count\": tool.progressUpdates,\n\t\t\t\t\t...(tool.firstProgressAt !== undefined\n\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\t\"pi.tool.time_to_first_progress_ms\": Math.max(\n\t\t\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\t\t\ttool.firstProgressAt - tool.startedAt,\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t: {}),\n\t\t\t\t},\n\t\t\t});\n\t\t\ttool.observation.end();\n\t\t}\n\t\tthis.tools.clear();\n\t}\n\n\tprivate closeGeneration(statusMessage: string, level: \"ERROR\" | \"WARNING\" = \"ERROR\"): void {\n\t\tif (!this.generation) return;\n\t\tthis.generation.observation.update({\n\t\t\tlevel,\n\t\t\tstatusMessage,\n\t\t\tmetadata: {\n\t\t\t\t...this.generation.requestMetadata,\n\t\t\t\t...generationHttpMetadata(this.generation),\n\t\t\t},\n\t\t});\n\t\tthis.generation.observation.end(this.generation.endTime);\n\t\tthis.generation = undefined;\n\t}\n\n\tprivate closeCompaction(statusMessage: string): void {\n\t\tif (!this.compaction) return;\n\t\tthis.compaction.observation.update({ level: \"WARNING\", statusMessage });\n\t\tthis.compaction.observation.end();\n\t\tthis.compaction = undefined;\n\t}\n\n\tprivate capture(value: unknown): unknown {\n\t\treturn this.context.captureContent ? sanitizeTraceValue(value) : CONTENT_DISABLED;\n\t}\n}\n\nfunction generationHttpMetadata(state: GenerationState): Record<string, unknown> {\n\tconst finalStatus = state.statuses.at(-1);\n\treturn {\n\t\t...(state.statuses.length > 0\n\t\t\t? {\n\t\t\t\t\t\"http.response.status_codes\": [...state.statuses],\n\t\t\t\t\t\"http.response.status_code\": finalStatus,\n\t\t\t\t\t\"http.response.attempt_count\": state.statuses.length,\n\t\t\t\t\t\"http.response.retry_count\": Math.max(0, state.statuses.length - 1),\n\t\t\t\t}\n\t\t\t: {}),\n\t\t...(Object.keys(state.headers).length > 0\n\t\t\t? { \"http.response.headers\": { ...state.headers } }\n\t\t\t: {}),\n\t};\n}\n\nfunction allowlistedResponseHeaders(headers: Record<string, string>): Record<string, string> {\n\tconst output: Record<string, string> = {};\n\tfor (const [rawName, rawValue] of Object.entries(headers)) {\n\t\tconst name = rawName.toLowerCase();\n\t\tif (!ALLOWED_RESPONSE_HEADERS.has(name) || typeof rawValue !== \"string\") continue;\n\t\toutput[name] = truncateString(rawValue, MAX_HEADER_VALUE_LENGTH);\n\t}\n\treturn output;\n}\n\nfunction structuralCompactionDetails(details: unknown): Record<string, unknown> {\n\tif (!details || typeof details !== \"object\" || Array.isArray(details)) return {};\n\tconst record = details as Record<string, unknown>;\n\treturn {\n\t\t...(Array.isArray(record.readFiles)\n\t\t\t? { \"pi.compaction.read_file_count\": record.readFiles.length }\n\t\t\t: {}),\n\t\t...(Array.isArray(record.modifiedFiles)\n\t\t\t? { \"pi.compaction.modified_file_count\": record.modifiedFiles.length }\n\t\t\t: {}),\n\t};\n}\n\nfunction snapshotMetadata(prefix: string, snapshot?: ContextSnapshot): Record<string, unknown> {\n\tif (!snapshot) return {};\n\treturn {\n\t\t...(snapshot.leafId ? { [`pi.trace.${prefix}_leaf_id`]: snapshot.leafId } : {}),\n\t\t...(snapshot.contextUsage\n\t\t\t? {\n\t\t\t\t\t...(finiteNumber(snapshot.contextUsage.tokens)\n\t\t\t\t\t\t? { [`pi.trace.${prefix}_context_tokens`]: snapshot.contextUsage.tokens }\n\t\t\t\t\t\t: {}),\n\t\t\t\t\t[`pi.trace.${prefix}_context_window`]: snapshot.contextUsage.contextWindow,\n\t\t\t\t\t...(finiteNumber(snapshot.contextUsage.percent)\n\t\t\t\t\t\t? { [`pi.trace.${prefix}_context_percent`]: snapshot.contextUsage.percent }\n\t\t\t\t\t\t: {}),\n\t\t\t\t}\n\t\t\t: {}),\n\t};\n}\n\nfunction classifyOutcome(message?: {\n\trole?: string;\n\tstopReason?: string;\n\terrorMessage?: string;\n}): Outcome {\n\tif (message?.role !== \"assistant\") return \"interrupted\";\n\tif (message.stopReason === \"error\" || message.errorMessage) return \"error\";\n\tif (message.stopReason === \"aborted\") return \"aborted\";\n\tif (message.stopReason === \"length\") return \"length\";\n\treturn \"success\";\n}\n\nfunction severityForOutcome(\n\toutcome: Outcome,\n\tstatusMessage?: string,\n): Pick<ObservationAttributes, \"level\" | \"statusMessage\"> {\n\tif (outcome === \"success\") return {};\n\tif (outcome === \"error\") {\n\t\treturn {\n\t\t\tlevel: \"ERROR\",\n\t\t\tstatusMessage: statusMessage ?? \"The Pi operation failed.\",\n\t\t};\n\t}\n\treturn {\n\t\tlevel: \"WARNING\",\n\t\tstatusMessage:\n\t\t\tstatusMessage ??\n\t\t\t(outcome === \"aborted\"\n\t\t\t\t? \"The Pi operation was aborted.\"\n\t\t\t\t: outcome === \"length\"\n\t\t\t\t\t? \"The model reached its output limit.\"\n\t\t\t\t\t: \"The Pi operation was interrupted.\"),\n\t};\n}\n\nfunction prefixRecord(prefix: string, values: Record<string, number>): Record<string, number> {\n\treturn Object.fromEntries(\n\t\tObject.entries(values).map(([key, value]) => [`${prefix}.${key}`, value]),\n\t);\n}\n\nfunction truncateString(value: string, maxBytes: number): string {\n\tconst boundedPrefix = value.slice(0, maxBytes);\n\tif (boundedPrefix.length === value.length && byteLength(boundedPrefix) <= maxBytes) {\n\t\treturn boundedPrefix;\n\t}\n\tconst suffix = \"\u2026 [truncated]\";\n\tconst target = Math.max(0, maxBytes - byteLength(suffix) - 2);\n\tlet bytes = 0;\n\tlet output = \"\";\n\tfor (const character of boundedPrefix) {\n\t\tconst size = byteLength(character);\n\t\tif (bytes + size > target) break;\n\t\toutput += character;\n\t\tbytes += size;\n\t}\n\treturn `${output}${suffix}`;\n}\n\nfunction byteLength(value: string): number {\n\treturn Buffer.byteLength(value, \"utf8\");\n}\n\nfunction numericRecord(values: Record<string, number | undefined>): Record<string, number> {\n\treturn Object.fromEntries(\n\t\tObject.entries(values).filter((entry): entry is [string, number] => finiteNumber(entry[1])),\n\t);\n}\n\nfunction positiveNumericRecord(values: Record<string, number | undefined>): Record<string, number> {\n\treturn Object.fromEntries(\n\t\tObject.entries(values).filter(\n\t\t\t(entry): entry is [string, number] => finiteNumber(entry[1]) && entry[1] > 0,\n\t\t),\n\t);\n}\n\nfunction finiteNumber(value: unknown): value is number {\n\treturn typeof value === \"number\" && Number.isFinite(value);\n}\n\nfunction hasItems(value: unknown): boolean {\n\treturn Array.isArray(value) ? value.length > 0 : value !== undefined;\n}\n\nfunction emptyCounters(): Counters {\n\treturn {\n\t\tattempts: 0,\n\t\tturns: 0,\n\t\tgenerations: 0,\n\t\ttools: 0,\n\t\ttoolErrors: 0,\n\t\tcompactions: 0,\n\t\trecoveredErrors: 0,\n\t\tfailedAttempts: 0,\n\t};\n}\n", "import type {\n\tExtensionAPI,\n\tExtensionCommandContext,\n\tExtensionContext,\n} from \"@earendil-works/pi-coding-agent\";\nimport {\n\tDEFAULT_BASE_URL,\n\ttype LangfuseConfig,\n\ttype LangfuseConfigPatch,\n\ttype LangfuseConfigResult,\n\tloadLangfuseConfig,\n\tnormalizeLangfuseConfig,\n\twriteLangfuseConfig,\n} from \"./config.js\";\nimport {\n\ttype ContextSnapshot,\n\ttype GitMetadata,\n\ttype TraceBackend,\n\tTraceRecorder,\n} from \"./tracing.js\";\n\ninterface ExtensionDependencies {\n\tloadConfig(path?: string): Promise<LangfuseConfigResult>;\n\twriteConfig(config: LangfuseConfigPatch, path?: string): Promise<unknown>;\n\tcreateBackend(config: LangfuseConfig): Promise<TraceBackend>;\n\tresolveGitMetadata(cwd: string): Promise<GitMetadata | undefined>;\n}\n\nconst FLUSH_ACTION = \"Flush completed traces for this session\";\nconst SET_UP_ACTION = \"Set up Langfuse for this Pi agent directory (restart required)\";\nconst UPDATE_ACTION = \"Update Langfuse for this Pi agent directory (restart required)\";\nconst HELP_ACTION = \"Show setup and privacy help\";\n\nexport function createLangfuseExtension(\n\tdependencies: Partial<ExtensionDependencies> = {},\n): (pi: ExtensionAPI) => void {\n\tconst loadConfig = dependencies.loadConfig ?? loadLangfuseConfig;\n\tconst writeConfig = dependencies.writeConfig ?? writeLangfuseConfig;\n\tconst createBackend =\n\t\tdependencies.createBackend ??\n\t\t(async (config) => {\n\t\t\tconst { createProductionBackend } = await import(\"./runtime.js\");\n\t\t\treturn createProductionBackend(config);\n\t\t});\n\n\treturn function langfuse(pi: ExtensionAPI) {\n\t\tconst resolveGit =\n\t\t\tdependencies.resolveGitMetadata ??\n\t\t\t((cwd: string) =>\n\t\t\t\tresolveGitMetadata((command, args, options) => pi.exec(command, args, options), cwd));\n\t\tlet recorder: TraceRecorder | undefined;\n\t\tlet activeConfig: LangfuseConfig | undefined;\n\t\tlet configPath: string | undefined;\n\t\tlet initializationError: string | undefined;\n\t\tlet hasStoredConfig = false;\n\t\tlet configurationNotice: string | undefined;\n\t\tlet sessionGeneration = 0;\n\t\tlet menuController = new AbortController();\n\t\tlet configWriteQueue = Promise.resolve();\n\t\tlet nextAttemptReason: string | undefined;\n\n\t\tasync function showLangfuseMenu(ctx: ExtensionCommandContext) {\n\t\t\tif (!ctx.hasUI) {\n\t\t\t\tctx.ui.notify(\n\t\t\t\t\tformatNonInteractiveStatus(activeConfig, configPath, initializationError),\n\t\t\t\t\t\"warning\",\n\t\t\t\t);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst menuGeneration = sessionGeneration;\n\t\t\tconst menuSignal = menuController.signal;\n\t\t\tconst isCurrent = () => menuGeneration === sessionGeneration && !menuSignal.aborted;\n\t\t\tconst { defineMenu, runMenu } = await import(\"@narumitw/pi-tui-kit\");\n\t\t\tif (!isCurrent()) return;\n\t\t\ttype Screen = \"main\";\n\t\t\ttype Action = \"flush\" | \"configure\" | \"help\";\n\t\t\tconst menu = defineMenu<undefined, Screen, Action>({\n\t\t\t\tstart: \"main\",\n\t\t\t\tscreens: {\n\t\t\t\t\tmain: () => ({\n\t\t\t\t\t\tkind: \"actions\",\n\t\t\t\t\t\ttitle: \"Langfuse\",\n\t\t\t\t\t\tlines: formatMenuTitle(\n\t\t\t\t\t\t\tactiveConfig,\n\t\t\t\t\t\t\tconfigPath,\n\t\t\t\t\t\t\tinitializationError,\n\t\t\t\t\t\t\tconfigurationNotice,\n\t\t\t\t\t\t)\n\t\t\t\t\t\t\t.split(\"\\n\")\n\t\t\t\t\t\t\t.slice(1),\n\t\t\t\t\t\titems: [\n\t\t\t\t\t\t\t...(recorder ? [{ id: \"flush\", label: FLUSH_ACTION, action: \"flush\" as const }] : []),\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tid: \"configure\",\n\t\t\t\t\t\t\t\tlabel: hasStoredConfig ? UPDATE_ACTION : SET_UP_ACTION,\n\t\t\t\t\t\t\t\taction: \"configure\",\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{ id: \"help\", label: HELP_ACTION, action: \"help\" },\n\t\t\t\t\t\t],\n\t\t\t\t\t\thint: \"close\",\n\t\t\t\t\t}),\n\t\t\t\t},\n\t\t\t\tactions: {\n\t\t\t\t\tflush: async () => {\n\t\t\t\t\t\tconst menuRecorder = recorder;\n\t\t\t\t\t\tconst menuConfig = activeConfig;\n\t\t\t\t\t\tif (!menuRecorder) {\n\t\t\t\t\t\t\tctx.ui.notify(\"Langfuse tracing is not enabled for this session.\", \"warning\");\n\t\t\t\t\t\t\treturn { kind: \"close\" };\n\t\t\t\t\t\t}\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tawait menuRecorder.flush();\n\t\t\t\t\t\t\tif (menuGeneration !== sessionGeneration) return { kind: \"close\" };\n\t\t\t\t\t\t\tctx.ui.notify(\"Langfuse traces flushed for this session.\", \"info\");\n\t\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\t\tif (menuGeneration !== sessionGeneration) return { kind: \"close\" };\n\t\t\t\t\t\t\tctx.ui.notify(`Langfuse flush failed: ${formatError(error, menuConfig)}`, \"error\");\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn { kind: \"close\" };\n\t\t\t\t\t},\n\t\t\t\t\tconfigure: async () => {\n\t\t\t\t\t\tconst loaded = await loadConfig(configPath);\n\t\t\t\t\t\tif (menuGeneration !== sessionGeneration) return { kind: \"close\" };\n\t\t\t\t\t\tconfigPath = loaded.path;\n\t\t\t\t\t\tconst next = await promptForConfig(\n\t\t\t\t\t\t\tctx,\n\t\t\t\t\t\t\tloaded.ok ? loaded.config : undefined,\n\t\t\t\t\t\t\t() => menuGeneration === sessionGeneration,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tif (!next || menuGeneration !== sessionGeneration) return { kind: \"close\" };\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tconst write = configWriteQueue.then(() => writeConfig(next, loaded.path));\n\t\t\t\t\t\t\tconfigWriteQueue = write.then(\n\t\t\t\t\t\t\t\t() => undefined,\n\t\t\t\t\t\t\t\t() => undefined,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tawait write;\n\t\t\t\t\t\t\tif (menuGeneration !== sessionGeneration) return { kind: \"close\" };\n\t\t\t\t\t\t\thasStoredConfig = true;\n\t\t\t\t\t\t\tconfigurationNotice =\n\t\t\t\t\t\t\t\t\"Saved; restart each Pi process to use it in subsequent sessions.\";\n\t\t\t\t\t\t\tctx.ui.notify(\n\t\t\t\t\t\t\t\t`Saved Langfuse config to ${loaded.path} for this Pi agent directory. Restart each Pi process to apply it to subsequent sessions.`,\n\t\t\t\t\t\t\t\t\"info\",\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\t\tif (menuGeneration !== sessionGeneration) return { kind: \"close\" };\n\t\t\t\t\t\t\tctx.ui.notify(`Failed to save Langfuse config: ${formatError(error, next)}`, \"error\");\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn { kind: \"close\" };\n\t\t\t\t\t},\n\t\t\t\t\thelp: async () => {\n\t\t\t\t\t\tctx.ui.notify(formatHelp(configPath), \"info\");\n\t\t\t\t\t\treturn { kind: \"close\" };\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t});\n\t\t\tawait runMenu(ctx, menu, {\n\t\t\t\tgetState: () => undefined,\n\t\t\t\tsignal: menuSignal,\n\t\t\t\tisCurrent,\n\t\t\t});\n\t\t}\n\n\t\tpi.registerCommand(\"langfuse\", {\n\t\t\tdescription: \"Open interactive Langfuse tracing controls\",\n\t\t\thandler: async (_args, ctx) => showLangfuseMenu(ctx),\n\t\t});\n\n\t\tpi.on(\"session_start\", async (_event, ctx) => {\n\t\t\tconst generation = ++sessionGeneration;\n\t\t\tmenuController.abort(new DOMException(\"Langfuse session replaced\", \"AbortError\"));\n\t\t\tmenuController = new AbortController();\n\t\t\trecorder = undefined;\n\t\t\tactiveConfig = undefined;\n\t\t\tconfigPath = undefined;\n\t\t\tinitializationError = undefined;\n\t\t\thasStoredConfig = false;\n\t\t\tconfigurationNotice = undefined;\n\t\t\tnextAttemptReason = undefined;\n\n\t\t\tawait configWriteQueue;\n\t\t\tif (generation !== sessionGeneration) return;\n\t\t\tconst result = await loadConfig();\n\t\t\tif (generation !== sessionGeneration) return;\n\t\t\tconfigPath = result.path;\n\t\t\tfor (const warning of result.warnings) ctx.ui.notify(warning, \"warning\");\n\t\t\tif (!result.ok) {\n\t\t\t\tinitializationError = formatConfigError(result);\n\t\t\t\tctx.ui.notify(initializationError, \"warning\");\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\thasStoredConfig = true;\n\t\t\ttry {\n\t\t\t\tconst backend = await createBackend(result.config);\n\t\t\t\tif (generation !== sessionGeneration) {\n\t\t\t\t\tawait backend.shutdown().catch(() => undefined);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tactiveConfig = result.config;\n\t\t\t\trecorder = new TraceRecorder(backend, {\n\t\t\t\t\tsessionId: ctx.sessionManager.getSessionId(),\n\t\t\t\t\t...(result.config.userId ? { userId: result.config.userId } : {}),\n\t\t\t\t\tcwd: ctx.cwd,\n\t\t\t\t\tmode: ctx.mode,\n\t\t\t\t\tcaptureContent: result.config.captureContent,\n\t\t\t\t});\n\t\t\t} catch (error) {\n\t\t\t\tif (generation !== sessionGeneration) return;\n\t\t\t\tinitializationError = `Langfuse tracing could not start: ${formatError(error, result.config)}`;\n\t\t\t\tctx.ui.notify(initializationError, \"warning\");\n\t\t\t}\n\t\t});\n\n\t\tpi.on(\"before_agent_start\", async (event, ctx) => {\n\t\t\tnextAttemptReason = undefined;\n\t\t\tconst activeRecorder = recorder;\n\t\t\tif (!activeRecorder) return;\n\t\t\tconst git = await resolveGit(ctx.cwd).catch(() => undefined);\n\t\t\tif (recorder !== activeRecorder) return;\n\t\t\tactiveRecorder.beginAgent({\n\t\t\t\tprompt: event.prompt,\n\t\t\t\timages: event.images,\n\t\t\t\tmodel: ctx.model\n\t\t\t\t\t? { provider: ctx.model.provider, id: ctx.model.id, api: ctx.model.api }\n\t\t\t\t\t: undefined,\n\t\t\t\tgit,\n\t\t\t\tsnapshot: contextSnapshot(ctx),\n\t\t\t});\n\t\t});\n\n\t\tpi.on(\"agent_start\", () => {\n\t\t\tif (!recorder) return;\n\t\t\trecorder.beginAttempt(nextAttemptReason ? { reason: nextAttemptReason } : undefined);\n\t\t\tnextAttemptReason = undefined;\n\t\t});\n\n\t\tpi.on(\"turn_start\", (event, ctx) => {\n\t\t\tif (!recorder) return;\n\t\t\tensureActiveRun(recorder, ctx);\n\t\t\trecorder.beginTurn(event.turnIndex);\n\t\t});\n\n\t\tpi.on(\"before_provider_request\", (event, ctx) => {\n\t\t\tif (!recorder) return;\n\t\t\tensureActiveRun(recorder, ctx);\n\t\t\trecorder.beginGeneration({\n\t\t\t\tpayload: event.payload,\n\t\t\t\tpayloadStage: \"before_provider_request\",\n\t\t\t\tmodel: ctx.model\n\t\t\t\t\t? { provider: ctx.model.provider, id: ctx.model.id, api: ctx.model.api }\n\t\t\t\t\t: undefined,\n\t\t\t\tthinkingLevel: pi.getThinkingLevel(),\n\t\t\t});\n\t\t});\n\n\t\tpi.on(\"after_provider_response\", (event) => {\n\t\t\trecorder?.recordProviderResponse(event.status, event.headers);\n\t\t});\n\n\t\tpi.on(\"message_update\", (event) => {\n\t\t\tif (isRealOutputDelta(event.assistantMessageEvent)) recorder?.markGenerationFirstOutput();\n\t\t});\n\n\t\tpi.on(\"message_end\", (event) => {\n\t\t\tif (event.message.role === \"assistant\") recorder?.markGenerationEnd();\n\t\t});\n\n\t\tpi.on(\"turn_end\", (event) => {\n\t\t\tif (event.message.role === \"assistant\") recorder?.finishAssistant(event.message);\n\t\t\trecorder?.finishTurn(event.turnIndex, {\n\t\t\t\tmessage: event.message,\n\t\t\t\ttoolResultCount: event.toolResults.length,\n\t\t\t});\n\t\t});\n\n\t\tpi.on(\"tool_execution_start\", (event) => {\n\t\t\trecorder?.beginTool(event.toolCallId, event.toolName, event.args);\n\t\t});\n\n\t\tpi.on(\"tool_execution_update\", (event) => {\n\t\t\trecorder?.recordToolProgress(event.toolCallId);\n\t\t});\n\n\t\tpi.on(\"tool_result\", (event) => {\n\t\t\trecorder?.recordToolInput(event.toolCallId, event.input);\n\t\t});\n\n\t\tpi.on(\"tool_execution_end\", (event) => {\n\t\t\trecorder?.finishTool(event.toolCallId, {\n\t\t\t\tcontent: event.result.content,\n\t\t\t\tdetails: event.result.details,\n\t\t\t\tisError: event.isError,\n\t\t\t});\n\t\t});\n\n\t\tpi.on(\"agent_end\", (event) => {\n\t\t\tconst message = findLastAssistant(event.messages);\n\t\t\trecorder?.finishAttempt(message);\n\t\t});\n\n\t\tpi.on(\"session_before_compact\", (event) => {\n\t\t\trecorder?.beginCompaction({\n\t\t\t\treason: event.reason,\n\t\t\t\twillRetry: event.willRetry,\n\t\t\t\ttokensBefore: event.preparation.tokensBefore,\n\t\t\t\tmessagesToSummarize: event.preparation.messagesToSummarize.length,\n\t\t\t\tturnPrefixMessages: event.preparation.turnPrefixMessages.length,\n\t\t\t\tbranchEntries: event.branchEntries.length,\n\t\t\t\tisSplitTurn: event.preparation.isSplitTurn,\n\t\t\t});\n\t\t});\n\n\t\tpi.on(\"session_compact\", (event) => {\n\t\t\tconst entry = event.compactionEntry as typeof event.compactionEntry & {\n\t\t\t\tusage?: Parameters<TraceRecorder[\"finishCompaction\"]>[0][\"usage\"];\n\t\t\t};\n\t\t\trecorder?.finishCompaction({\n\t\t\t\treason: event.reason,\n\t\t\t\twillRetry: event.willRetry,\n\t\t\t\tfromExtension: event.fromExtension,\n\t\t\t\ttokensBefore: entry.tokensBefore,\n\t\t\t\tdetails: entry.details,\n\t\t\t\tusage: entry.usage,\n\t\t\t});\n\t\t\tif (event.willRetry && recorder?.hasActiveTrace()) nextAttemptReason = \"post_compaction\";\n\t\t});\n\n\t\tpi.on(\"agent_settled\", (_event, ctx) => {\n\t\t\trecorder?.settle(contextSnapshot(ctx));\n\t\t\tnextAttemptReason = undefined;\n\t\t});\n\n\t\tpi.on(\"session_shutdown\", async (event, ctx) => {\n\t\t\tconst generation = ++sessionGeneration;\n\t\t\tmenuController.abort(new DOMException(\"Langfuse session shut down\", \"AbortError\"));\n\t\t\tconst activeRecorder = recorder;\n\t\t\tconst shutdownConfig = activeConfig;\n\t\t\tconst pendingConfigWrite = configWriteQueue;\n\t\t\tconst shutdownSnapshot = activeRecorder ? contextSnapshot(ctx) : undefined;\n\t\t\trecorder = undefined;\n\t\t\tactiveConfig = undefined;\n\t\t\tawait pendingConfigWrite;\n\t\t\tif (!activeRecorder) return;\n\t\t\ttry {\n\t\t\t\tif (event.reason === \"quit\") await activeRecorder.shutdown(shutdownSnapshot);\n\t\t\t\telse {\n\t\t\t\t\tactiveRecorder.interrupt(\n\t\t\t\t\t\t`Pi session ended before settlement (${event.reason}).`,\n\t\t\t\t\t\tshutdownSnapshot,\n\t\t\t\t\t);\n\t\t\t\t\tawait activeRecorder.flush();\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\tif (generation !== sessionGeneration) return;\n\t\t\t\tctx.ui.notify(\n\t\t\t\t\t`Langfuse shutdown export failed: ${formatError(error, shutdownConfig)}`,\n\t\t\t\t\t\"error\",\n\t\t\t\t);\n\t\t\t}\n\t\t});\n\t};\n}\n\nfunction ensureActiveRun(recorder: TraceRecorder, ctx: ExtensionContext): void {\n\tif (!recorder.hasActiveTrace()) {\n\t\trecorder.beginAgent({\n\t\t\tprompt: \"[automatic continuation]\",\n\t\t\tmodel: ctx.model\n\t\t\t\t? { provider: ctx.model.provider, id: ctx.model.id, api: ctx.model.api }\n\t\t\t\t: undefined,\n\t\t\tsnapshot: contextSnapshot(ctx),\n\t\t});\n\t}\n\tif (!recorder.hasActiveAttempt()) recorder.beginAttempt();\n}\n\nfunction contextSnapshot(ctx: ExtensionContext): ContextSnapshot {\n\treturn {\n\t\tleafId:\n\t\t\ttypeof ctx.sessionManager.getLeafId === \"function\"\n\t\t\t\t? ctx.sessionManager.getLeafId()\n\t\t\t\t: undefined,\n\t\tcontextUsage: ctx.getContextUsage(),\n\t};\n}\n\nfunction findLastAssistant<T extends { role?: string }>(messages: readonly T[]): T | undefined {\n\tfor (let index = messages.length - 1; index >= 0; index -= 1) {\n\t\tconst message = messages[index];\n\t\tif (message?.role === \"assistant\") return message;\n\t}\n\treturn undefined;\n}\n\nfunction isRealOutputDelta(event: { type: string; delta?: unknown }): boolean {\n\treturn (\n\t\t(event.type === \"text_delta\" ||\n\t\t\tevent.type === \"thinking_delta\" ||\n\t\t\tevent.type === \"toolcall_delta\") &&\n\t\ttypeof event.delta === \"string\" &&\n\t\tevent.delta.length > 0\n\t);\n}\n\nconst GIT_LOOKUP_TIMEOUT_MS = 1_000;\nconst MAX_GIT_BRANCH_LENGTH = 256;\n\ntype GitExecutor = ExtensionAPI[\"exec\"];\n\nexport async function resolveGitMetadata(\n\texec: GitExecutor,\n\tcwd: string,\n): Promise<GitMetadata | undefined> {\n\tconst [branchResult, commit] = await Promise.all([\n\t\tresolveGitBranch(exec, cwd),\n\t\tresolveGitCommit(exec, cwd),\n\t]);\n\tif (!branchResult.resolved) return undefined;\n\tif (branchResult.branch) {\n\t\treturn {\n\t\t\tbranch: branchResult.branch,\n\t\t\t...(commit ? { commit } : {}),\n\t\t\tdetached: false,\n\t\t};\n\t}\n\treturn commit ? { commit, detached: true } : undefined;\n}\n\nasync function resolveGitBranch(\n\texec: GitExecutor,\n\tcwd: string,\n): Promise<{ resolved: boolean; branch?: string }> {\n\ttry {\n\t\tconst result = await exec(\"git\", [\"symbolic-ref\", \"--quiet\", \"--short\", \"HEAD\"], {\n\t\t\tcwd,\n\t\t\ttimeout: GIT_LOOKUP_TIMEOUT_MS,\n\t\t});\n\t\tif (result.killed) return { resolved: false };\n\t\tif (result.code === 1) return { resolved: true };\n\t\tif (result.code !== 0) return { resolved: false };\n\t\tconst branch = normalizeGitBranch(result.stdout);\n\t\treturn branch ? { resolved: true, branch } : { resolved: false };\n\t} catch {\n\t\treturn { resolved: false };\n\t}\n}\n\nasync function resolveGitCommit(exec: GitExecutor, cwd: string): Promise<string | undefined> {\n\ttry {\n\t\tconst result = await exec(\"git\", [\"rev-parse\", \"--verify\", \"--short=12\", \"HEAD\"], {\n\t\t\tcwd,\n\t\t\ttimeout: GIT_LOOKUP_TIMEOUT_MS,\n\t\t});\n\t\tif (result.code !== 0 || result.killed) return undefined;\n\t\tconst commit = result.stdout.trim();\n\t\treturn /^[0-9a-f]{4,64}$/iu.test(commit) ? commit.toLowerCase() : undefined;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\nfunction normalizeGitBranch(value: string): string | undefined {\n\tconst branch = value.trim();\n\tif (!branch || branch.length > MAX_GIT_BRANCH_LENGTH) return undefined;\n\tfor (const character of branch) {\n\t\tconst code = character.codePointAt(0) ?? 0;\n\t\tif (code <= 31 || code === 127) return undefined;\n\t}\n\treturn branch;\n}\n\nasync function promptForConfig(\n\tctx: ExtensionCommandContext,\n\tcurrent: LangfuseConfig | undefined,\n\tisCurrent: () => boolean,\n): Promise<LangfuseConfigPatch | undefined> {\n\tconst secretKey = await ctx.ui.input(\"Langfuse secret key (leave blank to keep existing):\");\n\tif (!isCurrent()) return undefined;\n\tif (secretKey === undefined) {\n\t\tctx.ui.notify(\"Cancelled\", \"info\");\n\t\treturn undefined;\n\t}\n\tconst publicKey = await ctx.ui.input(\"Langfuse public key (leave blank to keep existing):\");\n\tif (!isCurrent()) return undefined;\n\tif (publicKey === undefined) {\n\t\tctx.ui.notify(\"Cancelled\", \"info\");\n\t\treturn undefined;\n\t}\n\tconst baseUrl = await ctx.ui.input(\n\t\t`Langfuse base URL (leave blank for default ${DEFAULT_BASE_URL}):`,\n\t\tDEFAULT_BASE_URL,\n\t);\n\tif (!isCurrent()) return undefined;\n\tif (baseUrl === undefined) {\n\t\tctx.ui.notify(\"Cancelled\", \"info\");\n\t\treturn undefined;\n\t}\n\n\tconst patch: LangfuseConfigPatch = {\n\t\t...(publicKey.trim() ? { publicKey: publicKey.trim() } : {}),\n\t\t...(secretKey.trim() ? { secretKey: secretKey.trim() } : {}),\n\t\tbaseUrl: baseUrl.trim() || DEFAULT_BASE_URL,\n\t};\n\tconst normalized = normalizeLangfuseConfig({ ...current, ...patch });\n\tif (!normalized.ok) {\n\t\tctx.ui.notify(`Invalid Langfuse config: ${normalized.reason}`, \"error\");\n\t\treturn undefined;\n\t}\n\treturn patch;\n}\n\nfunction formatMenuTitle(\n\tactiveConfig: LangfuseConfig | undefined,\n\tconfigPath: string | undefined,\n\tinitializationError: string | undefined,\n\tconfigurationNotice: string | undefined,\n): string {\n\tconst lines = [\n\t\t\"Langfuse\",\n\t\t\"\",\n\t\t\"Current session:\",\n\t\t` Tracing: ${activeConfig ? \"enabled\" : \"disabled\"}`,\n\t];\n\tif (activeConfig) {\n\t\tlines.push(\n\t\t\t` Endpoint: ${activeConfig.baseUrl}`,\n\t\t\t` Content capture: ${activeConfig.captureContent ? \"enabled\" : \"disabled\"}`,\n\t\t);\n\t} else if (configurationNotice) {\n\t\tlines.push(\" State: tracing remains disabled until Pi restarts.\");\n\t} else if (initializationError) {\n\t\tlines.push(` Reason: ${initializationError}`);\n\t}\n\tlines.push(\n\t\t\"\",\n\t\t\"Agent-directory configuration:\",\n\t\t` Configuration: ${configPath ?? \"unknown\"}`,\n\t\t\" Scope: this Pi agent directory; restart each Pi process to apply changes.\",\n\t);\n\tif (configurationNotice) lines.push(` Pending: ${configurationNotice}`);\n\tlines.push(\"\", \"What do you want to do?\");\n\treturn lines.join(\"\\n\");\n}\n\nfunction formatNonInteractiveStatus(\n\tactiveConfig: LangfuseConfig | undefined,\n\tconfigPath: string | undefined,\n\tinitializationError: string | undefined,\n): string {\n\treturn [\n\t\t\"/langfuse requires interactive UI.\",\n\t\t`Current session tracing: ${activeConfig ? \"enabled\" : \"disabled\"}`,\n\t\t...(activeConfig\n\t\t\t? [\n\t\t\t\t\t`Endpoint: ${activeConfig.baseUrl}`,\n\t\t\t\t\t`Content capture: ${activeConfig.captureContent ? \"enabled\" : \"disabled\"}`,\n\t\t\t\t]\n\t\t\t: initializationError\n\t\t\t\t? [`Reason: ${initializationError}`]\n\t\t\t\t: []),\n\t\t`Configuration: ${configPath ?? \"unknown\"}`,\n\t\t\"Edit the private config manually, then restart each Pi process to apply it to subsequent sessions.\",\n\t].join(\"\\n\");\n}\n\nfunction formatHelp(configPath: string | undefined): string {\n\treturn [\n\t\t\"Langfuse setup and privacy:\",\n\t\t\"Run /langfuse in interactive Pi to manage tracing for the current session.\",\n\t\t`Configuration: ${configPath ?? \"pi-langfuse.json\"}`,\n\t\t\"The file belongs to this Pi agent directory; restart each Pi process after changing it.\",\n\t\t\"Trace content may contain prompts, responses, tool arguments, tool results, and source code.\",\n\t\t\"Git branch, commit, cwd, model, and usage remain in metadata when content capture is disabled.\",\n\t\t'Use \"captureContent\": false in the private config to export metadata only.',\n\t].join(\"\\n\");\n}\n\nfunction formatConfigError(result: Extract<LangfuseConfigResult, { ok: false }>): string {\n\tconst setupHint = result.reason.startsWith(\"Configuration file not found:\")\n\t\t? \" Run /langfuse and choose Set up Langfuse.\"\n\t\t: \"\";\n\treturn `Langfuse tracing is disabled: ${result.reason}${setupHint}`;\n}\n\nfunction formatError(error: unknown, config?: LangfuseConfigPatch): string {\n\tlet message = error instanceof Error ? error.message : String(error);\n\tconst secrets = [config?.publicKey, config?.secretKey]\n\t\t.filter((secret): secret is string => Boolean(secret))\n\t\t.sort((left, right) => right.length - left.length);\n\tfor (const secret of secrets) {\n\t\tmessage = message.split(secret).join(\"[LANGFUSE_KEY_REDACTED]\");\n\t}\n\treturn message;\n}\n\nexport default createLangfuseExtension();\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["truncateString", "byteLength", "formatError"]
|
|
7
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@narumitw/pi-langfuse",
|
|
3
|
-
"version": "0.50.
|
|
3
|
+
"version": "0.50.2",
|
|
4
4
|
"description": "Pi extension that traces LLM generations and tool activity to Langfuse.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -15,19 +15,22 @@
|
|
|
15
15
|
],
|
|
16
16
|
"files": [
|
|
17
17
|
"src",
|
|
18
|
+
"dist",
|
|
18
19
|
"README.md",
|
|
19
20
|
"LICENSE"
|
|
20
21
|
],
|
|
21
22
|
"pi": {
|
|
22
23
|
"extensions": [
|
|
23
|
-
"./
|
|
24
|
+
"./dist/index.ts"
|
|
24
25
|
]
|
|
25
26
|
},
|
|
26
27
|
"piExtension": {
|
|
27
28
|
"lifecycle": "stable"
|
|
28
29
|
},
|
|
29
30
|
"scripts": {
|
|
30
|
-
"
|
|
31
|
+
"build": "node scripts/build-runtime.mjs",
|
|
32
|
+
"prepack": "npm run build",
|
|
33
|
+
"check": "npm run build && biome check .",
|
|
31
34
|
"format": "biome check --write .",
|
|
32
35
|
"typecheck": "tsc --noEmit"
|
|
33
36
|
},
|
|
@@ -35,15 +38,16 @@
|
|
|
35
38
|
"@earendil-works/pi-coding-agent": "*"
|
|
36
39
|
},
|
|
37
40
|
"devDependencies": {
|
|
38
|
-
"@biomejs/biome": "2.5.
|
|
41
|
+
"@biomejs/biome": "2.5.9",
|
|
39
42
|
"@earendil-works/pi-coding-agent": "0.84.2",
|
|
40
43
|
"@types/node": "26.2.0",
|
|
41
|
-
"typescript": "7.0.2"
|
|
44
|
+
"typescript": "7.0.2",
|
|
45
|
+
"esbuild": "0.28.2"
|
|
42
46
|
},
|
|
43
47
|
"dependencies": {
|
|
44
|
-
"@langfuse/otel": "^5.10.
|
|
45
|
-
"@langfuse/tracing": "^5.10.
|
|
46
|
-
"@narumitw/pi-tui-kit": "^0.
|
|
48
|
+
"@langfuse/otel": "^5.10.1",
|
|
49
|
+
"@langfuse/tracing": "^5.10.1",
|
|
50
|
+
"@narumitw/pi-tui-kit": "^0.56.0",
|
|
47
51
|
"@opentelemetry/api": "^1.9.1",
|
|
48
52
|
"@opentelemetry/exporter-trace-otlp-http": "^0.221.0",
|
|
49
53
|
"@opentelemetry/sdk-trace-base": "^2.10.0",
|