UNPKG

zephyr-agent

Version:
191 lines (190 loc) • 9.26 kB
import "node:module"; import { createHash } from "node:crypto"; import { readFileSync, statSync } from "node:fs"; import { dirname, join } from "node:path"; const boundedRead = (filename)=>{ if (statSync(filename).size > 20971520) throw new Error('Metadata too large'); return readFileSync(filename, 'utf8'); }; const string = (value)=>'string' == typeof value && value.length > 0 && value.length <= 512; const count = (value)=>'number' == typeof value && Number.isSafeInteger(value) && value >= 0 ? value : void 0; function sanitizeUsage(raw) { if (raw?.scope !== 'session-cumulative') return; return { scope: 'session-cumulative', inputTokens: count(raw.inputTokens), cachedInputTokens: count(raw.cachedInputTokens), cacheWriteInputTokens: count(raw.cacheWriteInputTokens), outputTokens: count(raw.outputTokens), reasoningOutputTokens: count(raw.reasoningOutputTokens), totalTokens: count(raw.totalTokens), incomplete: Boolean(raw.incomplete), observedAt: string(raw.observedAt) ? raw.observedAt : void 0 }; } function finishedGrokUsage(row) { try { if (!row.transcriptPath) return {}; const directory = dirname(row.transcriptPath); const summary = JSON.parse(boundedRead(join(directory, 'summary.json'))); const ledger = JSON.parse(boundedRead(join(directory, 'usage.json'))); const updatedAt = Date.parse(ledger.updatedAt); const capturedAt = Date.parse(row.capturedAt); if (summary.info?.id !== row.session || summary.last_turn_summary_prompt_id !== row.turn || ledger.sessionId !== row.session || !Number.isFinite(updatedAt) || !Number.isFinite(capturedAt) || updatedAt < capturedAt) return {}; const raw = ledger.session; const usage = sanitizeUsage({ scope: 'session-cumulative', observedAt: ledger.updatedAt, inputTokens: raw.inputTokens, cachedInputTokens: raw.cachedReadTokens, cacheWriteInputTokens: raw.cacheCreationTokens, outputTokens: raw.outputTokens, reasoningOutputTokens: raw.reasoningTokens, totalTokens: raw.totalTokens, incomplete: Boolean(raw.usageIsIncomplete) }); return { usage, ...void 0 !== count(raw.costUsdTicks) ? { cost: { status: 'reported', currency: 'USD', usdTicks: raw.costUsdTicks, scope: 'session-cumulative', partial: Boolean(raw.costIsPartial), observedAt: ledger.updatedAt } } : {} }; } catch { return {}; } } function readSessionMetadata(gitDir) { const sessions = Object.create(null); const calls = new Map(); const transcripts = new Map(); try { const observations = boundedRead(join(gitDir, 'zephyr-attribution/events.jsonl')).split('\n').filter(Boolean).flatMap((line)=>{ try { return [ JSON.parse(line) ]; } catch { return []; } }); for (const row of observations){ if (1 !== row.schemaVersion || ![ 'codex', 'grok' ].includes(row.agent) || !string(row.session) || !string(row.turn) || !string(row.capturedAt)) continue; const key = createHash('sha256').update(JSON.stringify([ row.agent, row.session, row.turn ])).digest('hex'); let turns = transcripts.get(row.session); if ('codex' === row.agent && !turns && row.transcriptPath) { turns = new Map(); try { let current; let provider; let validSession = false; for (const line of boundedRead(row.transcriptPath).split('\n').filter(Boolean)){ const event = JSON.parse(line); const payload = event.payload; if ('session_meta' === event.type) { validSession = payload?.id === row.session; provider = string(payload?.model_provider) ? payload.model_provider : void 0; } if (!validSession) continue; if ('turn_context' === event.type && string(payload?.turn_id)) { current = payload.turn_id; turns.set(current, { provider, model: string(payload.model) ? payload.model : void 0, reasoningEffort: string(payload.effort) ? payload.effort : void 0 }); } const raw = payload?.info?.total_token_usage; if (current && 'event_msg' === event.type && payload?.type === 'token_count' && raw) { const turn = turns.get(current); turn.usage = { scope: 'session-cumulative', inputTokens: count(raw.input_tokens), cachedInputTokens: count(raw.cached_input_tokens), cacheWriteInputTokens: count(raw.cache_write_input_tokens), outputTokens: count(raw.output_tokens), reasoningOutputTokens: count(raw.reasoning_output_tokens), totalTokens: count(raw.total_tokens) }; } } if (!validSession) turns.clear(); } catch { turns.clear(); } transcripts.set(row.session, turns); } const previous = sessions[key]; sessions[key] = { ...previous, agent: row.agent, session: row.session, turn: row.turn, turnAssociation: 'active-prompt' === row.turnAssociation ? 'active-prompt' : previous?.turnAssociation ?? ('native-turn-id' === row.turnAssociation ? 'native-turn-id' : void 0), model: string(row.model) ? row.model : previous?.model, ...turns?.get(row.turn), harness: string(row.harness) ? row.harness : previous?.harness, promptInitiator: row.promptInitiator?.evidence === 'launcher-self-report' && string(row.promptInitiator.id) ? { id: row.promptInitiator.id, evidence: 'launcher-self-report' } : previous?.promptInitiator, capturedAt: row.capturedAt, ...'grok' === row.agent ? { provider: string(row.provider) ? row.provider : void 0, reasoningEffort: string(row.reasoningEffort) ? row.reasoningEffort : void 0, usage: sanitizeUsage(row.usage) } : {}, evidence: 'grok' === row.agent ? 'grok-hook-and-session' : turns?.has(row.turn) ? 'codex-hook-and-rollout' : 'codex-hook', cost: 'grok' === row.agent && row.reportedCost?.status === 'reported' && void 0 !== count(row.reportedCost.usdTicks) && 'USD' === row.reportedCost.currency && 'session-cumulative' === row.reportedCost.scope ? { status: 'reported', currency: 'USD', usdTicks: row.reportedCost.usdTicks, scope: 'session-cumulative', partial: Boolean(row.reportedCost.partial) || !row.reportedCost.observedAt || !Number.isFinite(Date.parse(row.reportedCost.observedAt)) || !Number.isFinite(Date.parse(row.capturedAt)) || Date.parse(row.reportedCost.observedAt) < Date.parse(row.capturedAt), observedAt: string(row.reportedCost.observedAt) ? row.reportedCost.observedAt : void 0 } : { status: 'unavailable', reason: 'No billed cost reported by the harness; token counters are not an invoice' } }; if ('grok' === row.agent) Object.assign(sessions[key], finishedGrokUsage(row)); if (string(row.toolCall)) calls.set(JSON.stringify([ row.agent, row.session, row.toolCall ]), key); } } catch {} return { sessions, calls }; } function sessionForOrigin(origin, metadata) { if ('ai' !== origin.kind || !origin.tool || !origin.session || !origin.toolCall) return; const key = metadata.calls.get(JSON.stringify([ origin.tool, origin.session, origin.toolCall ])); const session = key && metadata.sessions[key]; return session && session.model === origin.model ? { key, session } : void 0; } export { readSessionMetadata, sessionForOrigin }; //# sourceMappingURL=sessions.mjs.map