grix-connector 3.17.0 → 3.18.0
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 +28 -0
- package/dist/adapter/acp/acp-adapter.js +10 -10
- package/dist/adapter/acp/session-activity.js +1 -1
- package/dist/adapter/claude/claude-adapter.js +21 -21
- package/dist/adapter/claude/protocol-contract.js +1 -1
- package/dist/adapter/claude/skill-scanner.js +2 -2
- package/dist/adapter/codewhale/codewhale-adapter.js +2 -2
- package/dist/adapter/codex/codex-bridge.js +8 -8
- package/dist/adapter/codex/codex-trust.js +4 -4
- package/dist/adapter/codex/config-overrides.js +1 -0
- package/dist/adapter/codex/raw-capture-hook.js +1 -0
- package/dist/adapter/codex/session-activity.js +3 -3
- package/dist/adapter/opencode/opencode-adapter.js +4 -4
- package/dist/adapter/opencode/opencode-transport.js +4 -4
- package/dist/adapter/openhuman/openhuman-adapter.js +2 -2
- package/dist/adapter/pi/pi-adapter.js +4 -4
- package/dist/adapter/shared/tool-wire-payload.js +1 -0
- package/dist/audit/adapters/acp/kimi-audit-adapter.js +2 -2
- package/dist/audit/adapters/acp/reasonix-audit-adapter.js +1 -1
- package/dist/audit/adapters/claude/claude-audit-adapter.js +1 -1
- package/dist/audit/adapters/codex/codex-audit-adapter.js +1 -1
- package/dist/audit/adapters/pi/pi-audit-adapter.js +1 -1
- package/dist/audit/core/audit-options.js +1 -1
- package/dist/audit/core/audit-session-registry.js +3 -3
- package/dist/audit/core/replay-finalizer.js +1 -1
- package/dist/audit/core/tool-call-audit.js +1 -0
- package/dist/audit/integration/bridge-audit-controller.js +1 -1
- package/dist/audit/producer/ipc-audit-producer.js +1 -1
- package/dist/audit/query/audit-local-actions.js +1 -1
- package/dist/audit/query/audit-replay-query-service.js +1 -1
- package/dist/audit/raw-capture/adapter-hook.js +0 -0
- package/dist/audit/raw-capture/attribution.js +2 -0
- package/dist/audit/raw-capture/body-source.js +1 -0
- package/dist/audit/raw-capture/capture-relay.js +13 -0
- package/dist/audit/raw-capture/redaction.js +1 -0
- package/dist/audit/raw-capture/types.js +1 -0
- package/dist/audit/storage/file-audit-replay-store.js +2 -2
- package/dist/audit/worker/audit-recorder-worker-entry.js +1 -1
- package/dist/bridge/bridge.js +9 -9
- package/dist/bridge/send-controller.js +3 -3
- package/dist/core/aibot/binding-card-meta-cache.js +1 -0
- package/dist/core/aibot/client.js +2 -2
- package/dist/core/aibot/connection-handle.js +1 -1
- package/dist/core/aibot/types.js +1 -1
- package/dist/core/files/file-serve.js +2 -2
- package/dist/core/log/packet-log.js +2 -2
- package/dist/core/mcp/tools.js +1 -1
- package/dist/core/observability/sentry.js +1 -1
- package/dist/core/persistence/session-binding-store.js +1 -1
- package/dist/core/persistence/stop-result-outbox.js +2 -0
- package/dist/core/persistence/terminal-commit-token-store.js +2 -0
- package/dist/core/persistence/terminal-outbox.js +2 -0
- package/dist/core/provider-quota/index.js +1 -1
- package/dist/core/provider-quota/kiro.js +1 -1
- package/dist/core/provider-quota/openai-codex.js +2 -0
- package/dist/core/provider-quota/presentation.js +1 -1
- package/dist/core/provider-quota/providers.js +2 -2
- package/dist/default-skills/grix-agent-dispatch/SKILL.md +17 -14
- package/dist/default-skills/grix-audit-data/SKILL.md +99 -0
- package/dist/default-skills/grix-chat-state/SKILL.md +11 -3
- package/dist/default-skills/grix-query/SKILL.md +4 -2
- package/dist/default-skills/index.js +1 -1
- package/dist/grix.js +7 -6
- package/dist/kimi-plugins/grix-layer/SKILL.md +68 -0
- package/dist/kimi-plugins/grix-layer/SYSTEM.md +16 -0
- package/dist/kimi-plugins/grix-layer/kimi.plugin.json +10 -0
- package/dist/kimi-plugins/grix-layer/references/gateway-architecture.md +153 -0
- package/dist/kimi-plugins/grix-layer/scripts/gateway.mjs +31 -0
- package/dist/kimi-plugins/grix-layer/scripts/lib/architecture-map.mjs +305 -0
- package/dist/kimi-plugins/grix-layer/scripts/lib/downstream-client.mjs +133 -0
- package/dist/kimi-plugins/grix-layer/scripts/lib/navigation-service.mjs +762 -0
- package/dist/kimi-plugins/grix-layer/scripts/lib/normalizers.mjs +202 -0
- package/dist/kimi-plugins/grix-layer/scripts/lib/policy.mjs +78 -0
- package/dist/kimi-plugins/grix-layer/scripts/lib/response-budget.mjs +83 -0
- package/dist/kimi-plugins/grix-layer/scripts/lib/tool-server.mjs +106 -0
- package/dist/kimi-plugins/index.js +3 -0
- package/dist/manager-share-config.js +1 -1
- package/dist/manager.js +2 -2
- package/dist/mcp/stream-http/security.js +1 -1
- package/dist/protocol/event-mapper.js +1 -1
- package/dist/runtime/daemon-lock.js +2 -2
- package/dist/runtime/service-state.js +2 -2
- package/dist/service/log-diagnostics.js +5 -0
- package/dist/service/platform-adapter.js +20 -17
- package/dist/service/process-control.js +1 -1
- package/dist/service/service-manager.js +3 -4
- package/dist/service/service-paths.js +2 -1
- package/openclaw-plugin/index.js +110 -36
- package/openclaw-plugin/skills/grix-query/SKILL.md +6 -2
- package/package.json +8 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
import{basename as x}from"node:path";import{referenceCaptureContent as F}from"../../core/content-reference.js";import{collectClaudeTranscript as N}from"./claude-transcript-source.js";import{mergeClaudeMessageUsage as D}from"./claude-usage-merger.js";import{collectClaudeOtelEvidence as U,rawBodyLabel as L}from"./claude-otel-source.js";const z=Object.freeze({inputOutput:!0,tools:!0,subagents:!0,thinking:!0,rawProviderBody:!1});function R(r){return typeof r=="object"&&r!==null&&!Array.isArray(r)}function $(r,s){return typeof r!="string"?s:Number.isFinite(Date.parse(r))?r:s}function C(r){if(typeof r=="string")return r;try{return JSON.stringify(r)}catch{return String(r)}}function T(r){return r.options?.enabled===!0?r.options.capture:z}function B(r){return Object.fromEntries(Object.entries(r).filter(s=>typeof s[1]=="string"))}function k(r){const s=r.startedAt??r.job.startedAt,a=r.endedAt??r.job.endedAt,n=Date.parse(s),o=Date.parse(a);return{spanId:r.spanId,traceId:r.job.traceId,turnId:r.job.turnId,sessionId:r.job.sessionId,...r.parentSpanId?{parentSpanId:r.parentSpanId}:{},kind:r.kind,name:r.name,sequence:r.sequence,status:r.status??"completed",startedAt:s,endedAt:a,...Number.isFinite(n)&&Number.isFinite(o)?{durationMs:Math.max(0,o-n)}:{},inputRefs:[],outputRefs:[],provider:{provider:"claude",...r.nativeEventType?{nativeEventType:r.nativeEventType}:{},nativeIds:r.nativeIds??{},...r.rawAttributes?{rawAttributes:r.rawAttributes}:{}},provenance:{source:"provider_transcript",accuracy:"provider_reported"}}}function J(r){[...r].sort((a,n)=>{if(a.kind==="turn"&&n.kind!=="turn")return-1;if(n.kind==="turn"&&a.kind!=="turn")return 1;const o=Date.parse(a.startedAt),u=Date.parse(n.startedAt);return Number.isFinite(o)&&Number.isFinite(u)&&o!==u?o-u:a.sequence-n.sequence}).forEach((a,n)=>{a.sequence=n})}function G(r,s,a){const n=new Map,o=s.targetPromptId;if(!o)return n;for(const u of s.lines){if(u.promptId!==o||u.record.type!=="assistant")continue;const c=R(u.record.message)?u.record.message:void 0;if(!c){a.push({code:"claude_message_missing",message:`${u.sourcePath}:${u.sourceOffset} has no assistant message`});continue}const p=typeof c.id=="string"?c.id:void 0;if(!p){a.push({code:"claude_message_id_missing",message:`${u.sourcePath}:${u.sourceOffset} has no message.id`});continue}const l=$(u.record.timestamp,r.startedAt);let d=n.get(p);if(d?(d.endedAt=l,typeof u.record.requestId=="string"&&(d.requestId=u.record.requestId)):(d={messageId:p,requestId:typeof u.record.requestId=="string"?u.record.requestId:void 0,model:typeof c.model=="string"?c.model:void 0,sourcePath:u.sourcePath,isSubagent:u.isSubagent,promptId:o,startedAt:l,endedAt:l,samples:[],blocks:[]},n.set(p,d)),R(c.usage)&&d.samples.push({messageId:p,requestId:typeof u.record.requestId=="string"?u.record.requestId:void 0,raw:c.usage}),Array.isArray(c.content))for(const _ of c.content)R(_)&&d.blocks.push({block:_,line:u});else typeof c.content=="string"&&d.blocks.push({block:{type:"text",text:c.content},line:u})}return n}function H(r,s,a,n){if(s.targetPromptId)for(const o of s.lines){if(o.promptId!==s.targetPromptId||o.record.type!=="user")continue;const u=R(o.record.message)?o.record.message:void 0,c=Array.isArray(u?.content)?u.content:[];for(const p of c){if(!R(p)||p.type!=="tool_result")continue;const l=typeof p.tool_use_id=="string"?p.tool_use_id:void 0;if(!l){n.push({code:"claude_tool_result_id_missing",message:`${o.sourcePath}:${o.sourceOffset} tool result has no tool_use_id`});continue}const d=a.get(l);if(!d){n.push({code:"claude_tool_result_orphan",message:`Tool result ${l} has no matching tool_use`,providerIds:{toolCallId:l}});continue}d.result=p.content,d.endedAt=$(o.record.timestamp,r.endedAt)}}}function S(r,s,a){const n=[a.role,a.sourcePath??"",a.sourceOffset??"",a.value??""].join("\0");if(s.has(n))return s.get(n);const o=F(a);return s.set(n,o),r.push(a),o}function K(r){try{const s=JSON.parse(r);if(typeof s!="object"||s===null||Array.isArray(s))return;const a=s.system;return typeof a=="string"?a:Array.isArray(a)&&a.map(o=>typeof o=="string"?o:typeof o=="object"&&o!==null&&!Array.isArray(o)&&typeof o.text=="string"?String(o.text):"").join("")||void 0}catch{return}}function Q(r,s,a,n,o,u){const c=a.filter(t=>t.kind==="llm_request"),p=`claude:${r.turnId}:turn`;let l=a.reduce((t,f)=>Math.max(t,f.sequence),0)+1;const d=t=>({signal:t.signal,name:t.name,...t.observedAt?{observedAt:t.observedAt}:{},...t.traceId?{traceId:t.traceId}:{},...t.spanId?{spanId:t.spanId}:{},attributes:t.attributes}),_=t=>{const f=t.request?.eventSequence,y=t.response?.eventSequence??f,m=t.request?.querySource??t.response?.querySource;return f===void 0||y===void 0?[]:s.events.filter(v=>{const h=v.attributes["event.sequence"];return typeof h=="number"&&h>=f&&h<=y&&(m===void 0||v.attributes.query_source===void 0||v.attributes.query_source===m)})};for(const t of s.rawApiPairs){const f=t.response?.providerMessageId,y=f?c.find(i=>i.provider.nativeIds.messageId===f||i.provider.nativeIds.requestId===f):void 0,m=t.request?S(n,o,{role:"model_request",format:"json",value:t.request.value,sourcePath:t.request.sourcePath,captureLevel:"provider_exact"}):void 0,v=t.response?S(n,o,{role:"model_response",format:"json",value:t.response.value,sourcePath:t.response.sourcePath,captureLevel:"provider_exact"}):void 0,h=t.request?K(t.request.value):void 0,w=t.request&&h?S(n,o,{role:"system_prompt",format:"text",value:h,sourcePath:t.request.sourcePath,captureLevel:"provider_exact"}):void 0;if(y){m&&y.inputRefs.push(m),w&&y.inputRefs.push(w),v&&y.outputRefs.push(v),y.provider.rawAttributes={...y.provider.rawAttributes,rawApiRequestPath:t.request?.sourcePath,rawApiResponsePath:t.response?.sourcePath,querySource:t.request?.querySource??t.response?.querySource,otelEvents:[...Array.isArray(y.provider.rawAttributes?.otelEvents)?y.provider.rawAttributes.otelEvents:[],..._(t).map(d)]},(!m||!v)&&s.gaps.push({category:"raw_provider_body",reason:"correlation_failed",detail:f});continue}if(t.request&&!t.response&&t.request.querySource==="prompt_suggestion"){const i=L(t.request),e=k({spanId:`claude:${r.sessionId}:auxiliary:${i}`,job:r,parentSpanId:p,kind:"agent",name:"Claude auxiliary prompt suggestion",sequence:l++,nativeEventType:"api_request_body",nativeIds:{clientRequestBodyId:i},rawAttributes:{rawApiRequestPath:t.request.sourcePath,responseBodyPresentAtTurnClose:!1,querySource:t.request.querySource,otelEvents:_(t).map(d)}});m&&e.inputRefs.push(m),e.provenance={source:"provider_raw_body",accuracy:"provider_reported"},a.push(e);continue}if(t.request&&!t.response){const i=L(t.request),e=k({spanId:`claude:${r.sessionId}:retry:${i}`,job:r,parentSpanId:p,kind:"retry",name:"Claude API request attempt",sequence:l++,status:"failed",nativeEventType:"api_request_body",nativeIds:{clientRequestBodyId:i},rawAttributes:{rawApiRequestPath:t.request.sourcePath,responseBodyPresent:!1,querySource:t.request.querySource,otelEvents:_(t).map(d)}});m&&e.inputRefs.push(m),e.provenance={source:"provider_raw_body",accuracy:"provider_reported"},a.push(e),u.push({code:"claude_raw_api_response_missing",message:`Raw API request ${i} has no response body in this turn`,spanId:e.spanId}),s.gaps.push({category:"raw_provider_body",reason:"correlation_failed",detail:i});continue}u.push({code:"claude_raw_api_body_unmatched",message:`Raw API body pair could not be correlated to Claude message ${f??"<unknown>"}`}),s.gaps.push({category:"raw_provider_body",reason:"correlation_failed",detail:f??t.response?.sourcePath})}for(const t of s.events){const f=typeof t.attributes.request_id=="string"?t.attributes.request_id:typeof t.attributes["gen_ai.response.id"]=="string"?t.attributes["gen_ai.response.id"]:void 0,y=typeof t.attributes.tool_use_id=="string"?t.attributes.tool_use_id:typeof t.attributes["gen_ai.tool.call.id"]=="string"?t.attributes["gen_ai.tool.call.id"]:void 0,m=f?c.find(h=>h.provider.nativeIds.requestId===f||h.provider.nativeIds.messageId===f):y?a.find(h=>h.kind==="tool_call"&&h.provider.nativeIds.toolCallId===y):void 0;if(!m)continue;const v=Array.isArray(m.provider.rawAttributes?.otelEvents)?m.provider.rawAttributes.otelEvents:[];m.provider.rawAttributes={...m.provider.rawAttributes,otelEvents:[...v,{signal:t.signal,name:t.name,observedAt:t.observedAt,traceId:t.traceId,spanId:t.spanId,attributes:t.attributes}]}}}class j{provider="claude";async collect(s){const a=T(s),[n,o]=await Promise.all([N(s.boundary,a.subagents),U(s.boundary)]);return{transcript:n,otel:o}}async normalize(s,a){const n=a,o=n.transcript,u=T(s),c=[...o.anomalies,...n.otel.anomalies],p=[],l=[],d=new Map;let _=0;const t=`claude:${s.turnId}:turn`,f=k({spanId:t,job:s,kind:"turn",name:"Claude audited turn",sequence:_++,nativeEventType:"prompt",nativeIds:B({promptId:o.targetPromptId,providerSessionId:typeof s.boundary.providerSessionId=="string"?s.boundary.providerSessionId:void 0})});if(p.push(f),u.inputOutput&&s.input){const e=S(l,d,{...s.input,captureLevel:s.input.captureLevel??"runtime_exact"});e&&f.inputRefs.push(e)}if(u.inputOutput&&s.finalOutput){const e=S(l,d,{...s.finalOutput,captureLevel:s.finalOutput.captureLevel??"runtime_exact"});e&&f.outputRefs.push(e)}const y=G(s,o,c),m=[...new Set([...y.values()].filter(e=>e.isSubagent).map(e=>e.sourcePath))].sort((e,P)=>e.localeCompare(P)),v=new Map,h=new Map;for(const e of m){const P=`claude:${s.turnId}:subagent:${x(e)}`;v.set(e,P);const b=k({spanId:P,job:s,parentSpanId:t,kind:"subagent",name:x(e,".jsonl"),sequence:_++,nativeEventType:"subagent_transcript",nativeIds:{promptId:o.targetPromptId??"",agentId:x(e,".jsonl")},rawAttributes:{sourcePath:e}});h.set(e,b),p.push(b);const q=o.lines.find(I=>I.isSubagent&&I.sourcePath===e&&I.promptId===o.targetPromptId&&I.record.type==="user"&&R(I.record.message)),g=q&&R(q.record.message)?q.record.message:void 0;if(q&&g?.content!==void 0){const I=S(l,d,{role:"subagent_prompt",format:typeof g.content=="string"?"text":"json",value:C(g.content),sourcePath:q.sourcePath,sourceOffset:q.sourceOffset,sourceLength:q.sourceLength,captureLevel:"provider_exact"});I&&b.inputRefs.push(I)}}const w=new Map,i=new Map;for(const e of y.values()){const P=`claude:${s.sessionId}:${e.messageId}`;w.set(e.messageId,P);const b=D(e.messageId,e.samples);c.push(...b.anomalies.map(g=>({...g,spanId:P})));const q=k({spanId:P,job:s,parentSpanId:e.isSubagent?v.get(e.sourcePath)??t:t,kind:"llm_request",name:e.model??"Claude model request",sequence:_++,startedAt:e.startedAt,endedAt:e.endedAt,nativeEventType:"assistant",nativeIds:B({requestId:b.requestId??e.requestId,messageId:e.messageId,promptId:e.promptId,agentId:e.isSubagent?x(e.sourcePath,".jsonl"):void 0}),rawAttributes:{...e.model?{model:e.model}:{},sourcePath:e.sourcePath}});e.model&&(q.modelId=e.model),b.usage&&(q.usage=b.usage),p.push(q);for(const{block:g,line:I}of e.blocks){const O="provider_exact";if(g.type==="thinking"&&u.thinking&&typeof g.thinking=="string"){const A=S(l,d,{role:"thinking",format:"text",value:g.thinking,sourcePath:I.sourcePath,sourceOffset:I.sourceOffset,sourceLength:I.sourceLength,captureLevel:O});A&&q.outputRefs.push(A),A&&e.isSubagent&&h.get(e.sourcePath)?.outputRefs.push(A)}else if(g.type==="text"&&u.inputOutput&&typeof g.text=="string"){const A=S(l,d,{role:e.isSubagent?"subagent_result":"assistant_text",format:"text",value:g.text,sourcePath:I.sourcePath,sourceOffset:I.sourceOffset,sourceLength:I.sourceLength,captureLevel:O});A&&q.outputRefs.push(A),A&&e.isSubagent&&h.get(e.sourcePath)?.outputRefs.push(A)}else if(g.type==="tool_use"&&u.tools&&typeof g.id=="string"){const A=typeof g.name=="string"?g.name:"tool";i.has(g.id)||i.set(g.id,{toolCallId:g.id,name:A,parentMessageId:e.messageId,sourcePath:I.sourcePath,promptId:e.promptId,startedAt:e.endedAt,arguments:g.input});const E=S(l,d,{role:"tool_arguments",format:"json",value:C(g.input),sourcePath:I.sourcePath,sourceOffset:I.sourceOffset,sourceLength:I.sourceLength,captureLevel:O}),M=i.get(g.id);M&&E&&(M.argumentRef=E)}}}if(u.tools){H(s,o,i,c);for(const e of i.values()){const P=w.get(e.parentMessageId)??t,b=k({spanId:`claude:${s.sessionId}:tool:${e.toolCallId}`,job:s,parentSpanId:P,kind:"tool_call",name:e.name,sequence:_++,status:e.result===void 0?"running":"completed",startedAt:e.startedAt,endedAt:e.endedAt??s.endedAt,nativeEventType:"tool_use",nativeIds:{toolCallId:e.toolCallId,messageId:e.parentMessageId,promptId:e.promptId},rawAttributes:{sourcePath:e.sourcePath,hasResult:e.result!==void 0}});e.argumentRef&&b.inputRefs.push(e.argumentRef),e.result!==void 0&&(e.resultRef=S(l,d,{role:"tool_result",format:typeof e.result=="string"?"text":"json",value:C(e.result),sourcePath:e.sourcePath,captureLevel:"provider_exact"}),e.resultRef&&b.outputRefs.push(e.resultRef)),p.push(b)}}return(u.rawProviderBody||n.otel.events.length>0)&&Q(s,n.otel,p,l,d,c),J(p),{spans:p,contents:l,anomalies:c,collection:o,otel:n.otel,capture:u}}async correlate(s,a){return a}validate(s,a){const n=a,o=n.spans.filter(i=>i.kind==="llm_request"),u=n.spans.filter(i=>i.kind==="tool_call"),c=!n.capture.inputOutput||s.input!==void 0,p=n.contents.some(i=>i.role==="assistant_text"||i.role==="final_response")||s.finalOutput!==void 0,l=!n.capture.inputOutput||p,d=!n.capture.tools||u.every(i=>i.status==="completed"),_=n.collection.gaps.some(i=>i.category==="subagent_transcript"),t=!n.capture.subagents||!_,f=o.length>0&&o.every(i=>i.usage?.completeness==="complete"),y=o.length>0&&o.every(i=>i.inputRefs.some(e=>e.role==="model_request")&&i.outputRefs.some(e=>e.role==="model_response")),m=[...n.collection.gaps,...n.otel.gaps];n.capture.rawProviderBody&&!y&&!m.some(i=>i.category==="raw_provider_body")&&m.push({category:"raw_provider_body",reason:"source_log_missing",detail:"One or more Claude requests lack an exact request/response body pair"});const v=c&&l&&d&&t&&f&&(!n.capture.rawProviderBody||y)&&m.length===0,h=!n.collection.targetPromptId,w=o.length===0;return{status:h||w?"failed":v?"complete":"partial",inputComplete:c,outputComplete:l,toolCallsComplete:d,subagentsComplete:t,usageComplete:f,rawRequestsComplete:y,gaps:m}}}export{j as ClaudeAuditAdapter};
|
|
1
|
+
import{basename as $}from"node:path";import{referenceCaptureContent as z}from"../../core/content-reference.js";import{appendUniqueReference as G,assessToolCallCompleteness as J,deduplicateGaps as Q}from"../../core/tool-call-audit.js";import{collectClaudeTranscript as j}from"./claude-transcript-source.js";import{mergeClaudeMessageUsage as H}from"./claude-usage-merger.js";import{collectClaudeOtelEvidence as K,rawBodyLabel as D}from"./claude-otel-source.js";const V=Object.freeze({inputOutput:!0,tools:!0,subagents:!0,thinking:!0,rawProviderBody:!1});function x(r){return typeof r=="object"&&r!==null&&!Array.isArray(r)}function F(r,s){return typeof r!="string"?s:Number.isFinite(Date.parse(r))?r:s}function E(r){if(typeof r=="string")return r;try{const s=JSON.stringify(r);return s===void 0?"null":s}catch{return String(r)}}function N(r){return r.options?.enabled===!0?r.options.capture:V}function U(r){return Object.fromEntries(Object.entries(r).filter(s=>typeof s[1]=="string"))}function k(r){const s=r.startedAt??r.job.startedAt,a=r.endedAt??r.job.endedAt,n=Date.parse(s),o=Date.parse(a);return{spanId:r.spanId,traceId:r.job.traceId,turnId:r.job.turnId,sessionId:r.job.sessionId,...r.parentSpanId?{parentSpanId:r.parentSpanId}:{},kind:r.kind,name:r.name,sequence:r.sequence,status:r.status??"completed",startedAt:s,endedAt:a,...Number.isFinite(n)&&Number.isFinite(o)?{durationMs:Math.max(0,o-n)}:{},inputRefs:[],outputRefs:[],provider:{provider:"claude",...r.nativeEventType?{nativeEventType:r.nativeEventType}:{},nativeIds:r.nativeIds??{},...r.rawAttributes?{rawAttributes:r.rawAttributes}:{}},provenance:{source:"provider_transcript",accuracy:"provider_reported"}}}function W(r){[...r].sort((a,n)=>{if(a.kind==="turn"&&n.kind!=="turn")return-1;if(n.kind==="turn"&&a.kind!=="turn")return 1;const o=Date.parse(a.startedAt),u=Date.parse(n.startedAt);return Number.isFinite(o)&&Number.isFinite(u)&&o!==u?o-u:a.sequence-n.sequence}).forEach((a,n)=>{a.sequence=n})}function X(r,s,a){const n=new Map,o=s.targetPromptId;if(!o)return n;for(const u of s.lines){if(u.promptId!==o||u.record.type!=="assistant")continue;const p=x(u.record.message)?u.record.message:void 0;if(!p){a.push({code:"claude_message_missing",message:`${u.sourcePath}:${u.sourceOffset} has no assistant message`});continue}const l=typeof p.id=="string"?p.id:void 0;if(!l){a.push({code:"claude_message_id_missing",message:`${u.sourcePath}:${u.sourceOffset} has no message.id`});continue}const f=F(u.record.timestamp,r.startedAt);let d=n.get(l);if(d?(d.endedAt=f,typeof u.record.requestId=="string"&&(d.requestId=u.record.requestId)):(d={messageId:l,requestId:typeof u.record.requestId=="string"?u.record.requestId:void 0,model:typeof p.model=="string"?p.model:void 0,sourcePath:u.sourcePath,isSubagent:u.isSubagent,promptId:o,startedAt:f,endedAt:f,samples:[],blocks:[]},n.set(l,d)),x(p.usage)&&d.samples.push({messageId:l,requestId:typeof u.record.requestId=="string"?u.record.requestId:void 0,raw:p.usage}),Array.isArray(p.content))for(const b of p.content)x(b)&&d.blocks.push({block:b,line:u});else typeof p.content=="string"&&d.blocks.push({block:{type:"text",text:p.content},line:u})}return n}function Y(r,s,a,n){if(s.targetPromptId)for(const o of s.lines){if(o.promptId!==s.targetPromptId||o.record.type!=="user")continue;const u=x(o.record.message)?o.record.message:void 0,p=Array.isArray(u?.content)?u.content:[];for(const l of p){if(!x(l)||l.type!=="tool_result")continue;const f=typeof l.tool_use_id=="string"?l.tool_use_id:void 0;if(!f){n.push({code:"claude_tool_result_id_missing",message:`${o.sourcePath}:${o.sourceOffset} tool result has no tool_use_id`});continue}const d=a.get(f);if(!d){n.push({code:"claude_tool_result_orphan",message:`Tool result ${f} has no matching tool_use`,providerIds:{toolCallId:f}}),s.gaps.push({category:"tool_call",reason:"correlation_failed",detail:`${f}:orphan_result`});continue}d.result=Object.hasOwn(l,"content")?l.content??null:l,d.resultLine=o,d.failed=l.is_error===!0,d.endedAt=F(o.record.timestamp,r.endedAt)}}}function R(r,s,a){const n=[a.role,a.sourcePath??"",a.sourceOffset??"",a.value??""].join("\0");if(s.has(n))return s.get(n);const o=z(a);return s.set(n,o),r.push(a),o}function Z(r){try{const s=JSON.parse(r);if(typeof s!="object"||s===null||Array.isArray(s))return;const a=s.system;return typeof a=="string"?a:Array.isArray(a)&&a.map(o=>typeof o=="string"?o:typeof o=="object"&&o!==null&&!Array.isArray(o)&&typeof o.text=="string"?String(o.text):"").join("")||void 0}catch{return}}function ee(r,s,a,n,o,u){const p=a.filter(t=>t.kind==="llm_request"),l=`claude:${r.turnId}:turn`;let f=a.reduce((t,m)=>Math.max(t,m.sequence),0)+1;const d=t=>({signal:t.signal,name:t.name,...t.observedAt?{observedAt:t.observedAt}:{},...t.traceId?{traceId:t.traceId}:{},...t.spanId?{spanId:t.spanId}:{},attributes:t.attributes}),b=t=>{const m=t.request?.eventSequence,I=t.response?.eventSequence??m,g=t.request?.querySource??t.response?.querySource;return m===void 0||I===void 0?[]:s.events.filter(v=>{const h=v.attributes["event.sequence"];return typeof h=="number"&&h>=m&&h<=I&&(g===void 0||v.attributes.query_source===void 0||v.attributes.query_source===g)})};for(const t of s.rawApiPairs){const m=t.response?.providerMessageId,I=m?p.find(q=>q.provider.nativeIds.messageId===m||q.provider.nativeIds.requestId===m):void 0,g=t.request?R(n,o,{role:"model_request",format:"json",value:t.request.value,sourcePath:t.request.sourcePath,captureLevel:"provider_exact"}):void 0,v=t.response?R(n,o,{role:"model_response",format:"json",value:t.response.value,sourcePath:t.response.sourcePath,captureLevel:"provider_exact"}):void 0,h=t.request?Z(t.request.value):void 0,O=t.request&&h?R(n,o,{role:"system_prompt",format:"text",value:h,sourcePath:t.request.sourcePath,captureLevel:"provider_exact"}):void 0;if(I){g&&I.inputRefs.push(g),O&&I.inputRefs.push(O),v&&I.outputRefs.push(v),I.provider.rawAttributes={...I.provider.rawAttributes,rawApiRequestPath:t.request?.sourcePath,rawApiResponsePath:t.response?.sourcePath,querySource:t.request?.querySource??t.response?.querySource,otelEvents:[...Array.isArray(I.provider.rawAttributes?.otelEvents)?I.provider.rawAttributes.otelEvents:[],...b(t).map(d)]},(!g||!v)&&s.gaps.push({category:"raw_provider_body",reason:"correlation_failed",detail:m});continue}if(t.request&&!t.response&&t.request.querySource==="prompt_suggestion"){const q=D(t.request),c=k({spanId:`claude:${r.sessionId}:auxiliary:${q}`,job:r,parentSpanId:l,kind:"agent",name:"Claude auxiliary prompt suggestion",sequence:f++,nativeEventType:"api_request_body",nativeIds:{clientRequestBodyId:q},rawAttributes:{rawApiRequestPath:t.request.sourcePath,responseBodyPresentAtTurnClose:!1,querySource:t.request.querySource,otelEvents:b(t).map(d)}});g&&c.inputRefs.push(g),c.provenance={source:"provider_raw_body",accuracy:"provider_reported"},a.push(c);continue}if(t.request&&!t.response){const q=D(t.request),c=k({spanId:`claude:${r.sessionId}:retry:${q}`,job:r,parentSpanId:l,kind:"retry",name:"Claude API request attempt",sequence:f++,status:"failed",nativeEventType:"api_request_body",nativeIds:{clientRequestBodyId:q},rawAttributes:{rawApiRequestPath:t.request.sourcePath,responseBodyPresent:!1,querySource:t.request.querySource,otelEvents:b(t).map(d)}});g&&c.inputRefs.push(g),c.provenance={source:"provider_raw_body",accuracy:"provider_reported"},a.push(c),u.push({code:"claude_raw_api_response_missing",message:`Raw API request ${q} has no response body in this turn`,spanId:c.spanId}),s.gaps.push({category:"raw_provider_body",reason:"correlation_failed",detail:q});continue}u.push({code:"claude_raw_api_body_unmatched",message:`Raw API body pair could not be correlated to Claude message ${m??"<unknown>"}`}),s.gaps.push({category:"raw_provider_body",reason:"correlation_failed",detail:m??t.response?.sourcePath})}for(const t of s.events){const m=typeof t.attributes.request_id=="string"?t.attributes.request_id:typeof t.attributes["gen_ai.response.id"]=="string"?t.attributes["gen_ai.response.id"]:void 0,I=typeof t.attributes.tool_use_id=="string"?t.attributes.tool_use_id:typeof t.attributes["gen_ai.tool.call.id"]=="string"?t.attributes["gen_ai.tool.call.id"]:void 0,g=m?p.find(h=>h.provider.nativeIds.requestId===m||h.provider.nativeIds.messageId===m):I?a.find(h=>h.kind==="tool_call"&&h.provider.nativeIds.toolCallId===I):void 0;if(!g)continue;const v=Array.isArray(g.provider.rawAttributes?.otelEvents)?g.provider.rawAttributes.otelEvents:[];g.provider.rawAttributes={...g.provider.rawAttributes,otelEvents:[...v,{signal:t.signal,name:t.name,observedAt:t.observedAt,traceId:t.traceId,spanId:t.spanId,attributes:t.attributes}]}}}class ue{provider="claude";async collect(s){const a=N(s),[n,o]=await Promise.all([j(s.boundary,a.subagents),K(s.boundary)]);return{transcript:n,otel:o}}async normalize(s,a){const n=a,o=n.transcript,u=N(s),p=[...o.anomalies,...n.otel.anomalies],l=[],f=[],d=new Map;let b=0;const t=`claude:${s.turnId}:turn`,m=k({spanId:t,job:s,kind:"turn",name:"Claude audited turn",sequence:b++,nativeEventType:"prompt",nativeIds:U({promptId:o.targetPromptId,providerSessionId:typeof s.boundary.providerSessionId=="string"?s.boundary.providerSessionId:void 0})});if(l.push(m),u.inputOutput&&s.input){const e=R(f,d,{...s.input,captureLevel:s.input.captureLevel??"runtime_exact"});e&&m.inputRefs.push(e)}if(u.inputOutput&&s.finalOutput){const e=R(f,d,{...s.finalOutput,captureLevel:s.finalOutput.captureLevel??"runtime_exact"});e&&m.outputRefs.push(e)}const I=X(s,o,p),g=[...new Set([...I.values()].filter(e=>e.isSubagent).map(e=>e.sourcePath))].sort((e,w)=>e.localeCompare(w)),v=new Map,h=new Map;for(const e of g){const w=`claude:${s.turnId}:subagent:${$(e)}`;v.set(e,w);const A=k({spanId:w,job:s,parentSpanId:t,kind:"subagent",name:$(e,".jsonl"),sequence:b++,nativeEventType:"subagent_transcript",nativeIds:{promptId:o.targetPromptId??"",agentId:$(e,".jsonl")},rawAttributes:{sourcePath:e}});h.set(e,A),l.push(A);const _=o.lines.find(i=>i.isSubagent&&i.sourcePath===e&&i.promptId===o.targetPromptId&&i.record.type==="user"&&x(i.record.message)),S=_&&x(_.record.message)?_.record.message:void 0;if(_&&S?.content!==void 0){const i=R(f,d,{role:"subagent_prompt",format:typeof S.content=="string"?"text":"json",value:E(S.content),sourcePath:_.sourcePath,sourceOffset:_.sourceOffset,sourceLength:_.sourceLength,captureLevel:"provider_exact"});i&&A.inputRefs.push(i)}}const O=new Map,q=new Map,c=new Map;for(const e of I.values()){const w=`claude:${s.sessionId}:${e.messageId}`;O.set(e.messageId,w);const A=H(e.messageId,e.samples);p.push(...A.anomalies.map(S=>({...S,spanId:w})));const _=k({spanId:w,job:s,parentSpanId:e.isSubagent?v.get(e.sourcePath)??t:t,kind:"llm_request",name:e.model??"Claude model request",sequence:b++,startedAt:e.startedAt,endedAt:e.endedAt,nativeEventType:"assistant",nativeIds:U({requestId:A.requestId??e.requestId,messageId:e.messageId,promptId:e.promptId,agentId:e.isSubagent?$(e.sourcePath,".jsonl"):void 0}),rawAttributes:{...e.model?{model:e.model}:{},sourcePath:e.sourcePath}});q.set(e.messageId,_),e.model&&(_.modelId=e.model),A.usage&&(_.usage=A.usage),l.push(_);for(const[S,{block:i,line:y}]of e.blocks.entries()){const L="provider_exact";if(i.type==="thinking"&&u.thinking&&typeof i.thinking=="string"){const P=R(f,d,{role:"thinking",format:"text",value:i.thinking,sourcePath:y.sourcePath,sourceOffset:y.sourceOffset,sourceLength:y.sourceLength,captureLevel:L});P&&_.outputRefs.push(P),P&&e.isSubagent&&h.get(e.sourcePath)?.outputRefs.push(P)}else if(i.type==="text"&&u.inputOutput&&typeof i.text=="string"){const P=R(f,d,{role:e.isSubagent?"subagent_result":"assistant_text",format:"text",value:i.text,sourcePath:y.sourcePath,sourceOffset:y.sourceOffset,sourceLength:y.sourceLength,captureLevel:L});P&&_.outputRefs.push(P),P&&e.isSubagent&&h.get(e.sourcePath)?.outputRefs.push(P)}else if(i.type==="tool_use"&&u.tools){const P=typeof i.id=="string"&&i.id.length>0?i.id:void 0,C=P??`missing-id-${$(y.sourcePath)}-${y.sourceOffset}-${S}`,M=typeof i.name=="string"?i.name:"tool";P||(p.push({code:"claude_tool_call_id_missing",message:`${y.sourcePath}:${y.sourceOffset} tool_use has no id`,providerIds:{messageId:e.messageId}}),o.gaps.push({category:"tool_call",reason:"correlation_failed",detail:`${e.messageId}:missing_id`})),M==="tool"&&p.push({code:"claude_tool_name_missing",message:`${y.sourcePath}:${y.sourceOffset} tool_use has no name`,providerIds:{toolCallId:C}}),c.has(C)||c.set(C,{toolCallId:C,name:M,parentMessageId:e.messageId,sourcePath:y.sourcePath,promptId:e.promptId,startedAt:e.endedAt,...Object.hasOwn(i,"input")?{arguments:i.input}:{},syntheticToolCallId:!P});const T=Object.hasOwn(i,"input")?R(f,d,{role:"tool_arguments",format:"json",value:E(i.input),sourcePath:y.sourcePath,sourceOffset:y.sourceOffset,sourceLength:y.sourceLength,captureLevel:L}):void 0;Object.hasOwn(i,"input")||(p.push({code:"claude_tool_arguments_missing",message:`${y.sourcePath}:${y.sourceOffset} tool_use has no input`,providerIds:{toolCallId:C}}),o.gaps.push({category:"tool_arguments",reason:"correlation_failed",detail:C}));const B=c.get(C);B&&T&&(B.argumentRef=T)}}}if(u.tools){Y(s,o,c,p);for(const e of c.values()){const w=O.get(e.parentMessageId)??t,A=k({spanId:`claude:${s.sessionId}:tool:${e.toolCallId}`,job:s,parentSpanId:w,kind:"tool_call",name:e.name,sequence:b++,status:e.result===void 0?"running":"completed",startedAt:e.startedAt,endedAt:e.endedAt??s.endedAt,nativeEventType:"tool_use",nativeIds:{toolCallId:e.toolCallId,messageId:e.parentMessageId,promptId:e.promptId},rawAttributes:{sourcePath:e.sourcePath,hasResult:e.result!==void 0,...e.syntheticToolCallId?{syntheticToolCallId:!0}:{}}});if(e.failed&&(A.status="failed"),e.argumentRef&&A.inputRefs.push(e.argumentRef),e.result!==void 0){const _=e.resultLine;if(e.resultRef=R(f,d,{role:"tool_result",format:typeof e.result=="string"?"text":"json",value:E(e.result),sourcePath:_?.sourcePath??e.sourcePath,sourceOffset:_?.sourceOffset,sourceLength:_?.sourceLength,captureLevel:"provider_exact"}),e.resultRef&&A.outputRefs.push(e.resultRef),e.resultRef&&e.endedAt){const S=[...q.values()].filter(i=>i.spanId!==w&&Date.parse(i.startedAt)>=Date.parse(e.endedAt)).sort((i,y)=>Date.parse(i.startedAt)-Date.parse(y.startedAt)||i.sequence-y.sequence)[0];S&&G(S.inputRefs,e.resultRef)}}else p.push({code:"claude_tool_result_missing",message:`Tool call ${e.toolCallId} has no result in the audited boundary`,spanId:A.spanId,providerIds:{toolCallId:e.toolCallId}}),o.gaps.push({category:"tool_result",reason:"correlation_failed",detail:e.toolCallId});l.push(A)}}return(u.rawProviderBody||n.otel.events.length>0)&&ee(s,n.otel,l,f,d,p),W(l),{spans:l,contents:f,anomalies:p,collection:o,otel:n.otel,capture:u}}async correlate(s,a){return a}validate(s,a){const n=a,o=n.spans.filter(c=>c.kind==="llm_request"),u=n.spans.filter(c=>c.kind==="tool_call"),p=!n.capture.inputOutput||s.input!==void 0,l=n.contents.some(c=>c.role==="assistant_text"||c.role==="final_response")||s.finalOutput!==void 0,f=!n.capture.inputOutput||l,d=J(u,n.capture.tools),b=d.complete,t=n.collection.gaps.some(c=>c.category==="subagent_transcript"),m=!n.capture.subagents||!t,I=o.length>0&&o.every(c=>c.usage?.completeness==="complete"),g=o.length>0&&o.every(c=>c.inputRefs.some(e=>e.role==="model_request")&&c.outputRefs.some(e=>e.role==="model_response")),v=Q([...n.collection.gaps,...n.otel.gaps,...d.gaps]);n.capture.rawProviderBody&&!g&&!v.some(c=>c.category==="raw_provider_body")&&v.push({category:"raw_provider_body",reason:"source_log_missing",detail:"One or more Claude requests lack an exact request/response body pair"});const h=p&&f&&b&&m&&I&&(!n.capture.rawProviderBody||g)&&v.length===0,O=!n.collection.targetPromptId,q=o.length===0;return{status:O||q?"failed":h?"complete":"partial",inputComplete:p,outputComplete:f,toolCallsComplete:b,subagentsComplete:m,usageComplete:I,rawRequestsComplete:g,gaps:v}}}export{ue as ClaudeAuditAdapter};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{referenceCaptureContent as b}from"../../core/content-reference.js";import{InvalidCodexUsageError as L,normalizeCodexUsage as ne}from"../../core/usage.js";const re=new Set(["rawResponse/completed","codex/rawResponse/completed"]),se=new Set(["thread/tokenUsage/updated","codex/thread/tokenUsage/updated"]),N=new Set(["item/completed","codex/item/completed"]),W=new Set(["item/started","codex/item/started"]),oe=new Set(["rawResponseItem/completed","codex/rawResponseItem/completed"]),ae=new Set(["error","codex/error"]),ue=new Set(["thread/compacted","codex/thread/compacted"]),z=new Set(["commandExecution","fileChange","mcpToolCall","dynamicToolCall","webSearch","imageView","sleep","imageGeneration"]),G=new Set(["collabAgentToolCall","subAgentActivity"]),de=Object.freeze({inputOutput:!0,tools:!0,subagents:!0,thinking:!0,rawProviderBody:!1});function g(e){if(!(typeof e!="object"||e===null||Array.isArray(e)))return e}function p(e){return typeof e=="string"&&e.length>0?e:void 0}function w(e){return typeof e=="number"&&Number.isFinite(e)?e:void 0}function $(e,t,n){return e[t]??e[n]}function ie(e){return["totalTokens","total_tokens","inputTokens","input_tokens","cachedInputTokens","cached_input_tokens","cacheWriteInputTokens","cache_write_input_tokens","outputTokens","output_tokens","reasoningOutputTokens","reasoning_output_tokens"].some(t=>Object.hasOwn(e,t))}function ce(e){const t=g(e);if(!(!t||!ie(t)))return{total_tokens:$(t,"totalTokens","total_tokens"),input_tokens:$(t,"inputTokens","input_tokens"),cached_input_tokens:$(t,"cachedInputTokens","cached_input_tokens"),cache_write_input_tokens:$(t,"cacheWriteInputTokens","cache_write_input_tokens"),output_tokens:$(t,"outputTokens","output_tokens"),reasoning_output_tokens:$(t,"reasoningOutputTokens","reasoning_output_tokens")}}function V(e){return[e.input.total,e.input.cacheRead??"unknown",e.input.cacheWrite??"unknown",e.output.total,e.output.reasoning??"unknown"].join(":")}function H(e,t){return e.input.total!==t.input.total||e.output.total!==t.output.total?!1:[[e.input.cacheRead,t.input.cacheRead],[e.input.cacheWrite,t.input.cacheWrite],[e.output.reasoning,t.output.reasoning]].every(([r,o])=>r===null||o===null||r===o)}function x(e){let t=2166136261;for(let n=0;n<e.length;n+=1)t^=e.charCodeAt(n),t=Math.imul(t,16777619);return(t>>>0).toString(16).padStart(8,"0")}function M(e){const t=p(e);if(!(!t||Number.isNaN(Date.parse(t))))return t}function U(e){return e.options?.enabled===!0?e.options.capture:de}function C(e){if(typeof e=="string")return e;try{return JSON.stringify(e)}catch{return String(e)}}function k(e,t){const n=b(t);return e.push(t),n}function S(e,t){t&&(e.some(n=>n.contentId===t.contentId)||e.push(t))}function J(e){const t=ce(e);return t?{...ne(t),providerUsageRaw:e}:void 0}function pe(e){return{providerTurnId:p(e.boundary.providerTurnId)??p(e.boundary.turnId)??e.turnId,providerThreadId:p(e.boundary.providerThreadId)??p(e.boundary.threadId)}}function A(e,t){const n=p(e.turnId??e.turn_id);if(n&&n!==t.providerTurnId)return!1;const r=p(e.threadId??e.thread_id);return!(t.providerThreadId&&r&&r!==t.providerThreadId)}function O(e,t,n,r){e.push({code:t,message:n,providerIds:r})}function Y(e,t,n){try{const r=J(e);if(!r){O(n,"codex_usage_missing",`${t.nativeEventType} did not contain a usable usage payload`);return}return{...t,usage:r,providerUsageRaw:e,usageKey:V(r),reconciledWithTokenSnapshot:!1}}catch(r){if(r instanceof L){O(n,"codex_usage_invalid",r.message,t.responseId?{responseId:t.responseId}:void 0);return}throw r}}function Q(e){const t=g(e);if(!t)return{events:[]};const n=p(t.modelId);return{...n?{modelId:n}:{},events:Array.isArray(t.events)?t.events.filter(r=>{const o=g(r);return!!(o&&typeof o.method=="string"&&g(o.params))}):[],rolloutEntries:Array.isArray(t.rolloutEntries)?t.rolloutEntries:[]}}function le(e,t,n){const r=new Map;let o=0;for(const u of e){if(!re.has(u.method)||!A(u.params,t))continue;const a=p(u.params.turnId??u.params.turn_id)??t.providerTurnId,I=p(u.params.threadId??u.params.thread_id)??t.providerThreadId,d=p(u.params.responseId??u.params.response_id),s=Y(u.params.usage,{sequence:w(u.sequence)??o,observedAt:M(u.observedAt),providerTurnId:a,threadId:I,responseId:d,nativeEventType:u.method,source:"provider_raw_body"},n);if(o+=1,!s)continue;const i=d?`response:${d}`:`anonymous:${s.sequence}:${s.usageKey}`,m=r.get(i);if(m&&!H(m.usage,s.usage)){O(n,"codex_response_usage_conflict",`Response ${d??i} reported conflicting usage`,d?{responseId:d}:void 0);continue}m||r.set(i,s)}return[...r.values()].sort((u,a)=>u.sequence-a.sequence)}function X(e,t,n,r){const o=Y(e,n,r);if(!o)return;let u;try{const a=J(t);a&&(u=[n.threadId??"unknown-thread",n.providerTurnId,V(a)].join("|"))}catch(a){if(a instanceof L)O(r,"codex_total_snapshot_invalid",a.message);else throw a}return{...o,providerUsageRaw:{last:e,total:t},usage:{...o.usage,providerUsageRaw:{last:e,total:t}},snapshotKey:u}}function fe(e,t,n){const r=[];for(const o of e){if(!se.has(o.method)||!A(o.params,t))continue;const u=g(o.params.tokenUsage??o.params.token_usage);if(!u){O(n,"codex_usage_missing",`${o.method} did not contain tokenUsage`);continue}const a=p(o.params.turnId??o.params.turn_id)??t.providerTurnId,I=p(o.params.threadId??o.params.thread_id)??t.providerThreadId,d=X(u.last??u.last_token_usage,u.total??u.total_token_usage,{sequence:w(o.sequence)??r.length,observedAt:M(o.observedAt),providerTurnId:a,threadId:I,responseId:p(o.params.responseId??o.params.response_id),nativeEventType:o.method,source:"provider_event"},n);d&&r.push(d)}return r}function me(e,t,n,r){const o=[];return e.forEach((u,a)=>{const I=g(u),d=g(I?.payload);if(I?.type!=="event_msg"||d?.type!=="token_count")return;const s=g(d.info);if(!s)return;const i=X(s.last_token_usage??s.lastTokenUsage,s.total_token_usage??s.totalTokenUsage,{sequence:w(I?.sequence)??n+a,observedAt:M(I?.timestamp),providerTurnId:t.providerTurnId,threadId:t.providerThreadId,nativeEventType:"rollout/event_msg/token_count",source:"provider_transcript"},r);i&&o.push(i)}),o}function Ie(e){const t=new Set;return e.filter(n=>n.snapshotKey?t.has(n.snapshotKey)?!1:(t.add(n.snapshotKey),!0):!0)}function ve(e,t){const n=new Set(e),r=new Set(t);for(const o of t){const u=e.find(a=>!n.has(a)||o.responseId&&a.responseId&&o.responseId!==a.responseId?!1:a.providerTurnId===o.providerTurnId&&H(a.usage,o.usage));u&&(u.reconciledWithTokenSnapshot=!0,u.snapshotKey=o.snapshotKey,u.threadId??=o.threadId,u.providerUsageRaw={rawResponse:u.providerUsageRaw,tokenUsage:o.providerUsageRaw},u.usage={...u.usage,providerUsageRaw:u.providerUsageRaw},n.delete(u),r.delete(o))}return[...e,...t.filter(o=>r.has(o))].sort((o,u)=>o.sequence-u.sequence)}function he(e){if(e.responseId)return e.responseId;const t=e.snapshotKey??[e.threadId??"unknown-thread",e.providerTurnId,e.sequence,e.usageKey].join("|");return`codex-usage-${x(t)}`}function ge(e,t,n){const r=he(t),o={requestId:r,turnId:t.providerTurnId};t.threadId&&(o.threadId=t.threadId),t.responseId&&(o.responseId=t.responseId),t.snapshotKey&&(o.usageSnapshotId=x(t.snapshotKey));const u=t.observedAt??e.startedAt;return{spanId:`codex-llm-${x(`${e.traceId}|${r}`)}`,traceId:e.traceId,turnId:e.turnId,sessionId:e.sessionId,parentSpanId:`codex:${e.turnId}:turn`,kind:"llm_request",name:"codex response",sequence:t.sequence,status:"completed",startedAt:u,endedAt:u,...n?{modelId:n}:{},inputRefs:[],outputRefs:[],usage:t.usage,provider:{provider:"codex",nativeEventType:t.nativeEventType,nativeIds:o,rawAttributes:{usageSource:t.source,reconciledWithTokenSnapshot:t.reconciledWithTokenSnapshot}},provenance:{source:t.source,accuracy:"provider_reported"}}}function P(e,t){const n=w(e.params.completedAtMs);if(n!==void 0){const r=new Date(n);if(!Number.isNaN(r.getTime()))return r.toISOString()}return M(e.observedAt)??t.endedAt}function D(e,t){const n=w(e.params.startedAtMs);if(n!==void 0){const r=new Date(n);if(!Number.isNaN(r.getTime()))return r.toISOString()}return M(e.observedAt)??t}function Z(e){const t=p(e.status)?.toLowerCase();return t==="inprogress"||t==="in_progress"||t==="running"?"running":t==="failed"||t==="declined"||t==="error"||w(e.exitCode)!==void 0&&w(e.exitCode)!==0?"failed":t==="cancelled"||t==="canceled"?"cancelled":"completed"}function j(e){const t=p(e.type)??"tool";if(t==="mcpToolCall"){const n=p(e.server),r=p(e.tool);return[n,r].filter(Boolean).join("/")||t}return p(e.tool)??t}function ee(e){switch(p(e.type)){case"commandExecution":return p(e.command)?{format:"text",value:String(e.command)}:void 0;case"fileChange":return{format:"json",value:C(e.changes)};case"mcpToolCall":case"dynamicToolCall":return{format:"json",value:C(e.arguments)};case"webSearch":return p(e.query)?{format:"text",value:String(e.query)}:void 0;default:return{format:"json",value:C(e)}}}function _e(e){switch(p(e.type)){case"commandExecution":return typeof e.aggregatedOutput=="string"?{format:"text",value:e.aggregatedOutput}:void 0;case"fileChange":return{format:"json",value:C({status:e.status})};case"mcpToolCall":{const t=e.result??e.error;return t==null?void 0:{format:"json",value:C(t)}}case"dynamicToolCall":return e.contentItems===void 0||e.contentItems===null?void 0:{format:"json",value:C(e.contentItems)};default:return}}function ye(e,t,n,r,o){if(!U(e).tools)return[];const u=new Set,a=[],I=new Map;for(const d of t){if(!W.has(d.method)||!A(d.params,n))continue;const s=g(d.params.item),i=p(s?.id);i&&I.set(i,d)}for(const d of t){if(!N.has(d.method)||!A(d.params,n))continue;const s=g(d.params.item),i=p(s?.type);if(!s||!i||!z.has(i))continue;const m=p(s.id)??`sequence-${d.sequence}`;if(u.has(m))continue;u.add(m);const v=P(d,e),f=I.get(m),l=w(s.durationMs),h=Date.parse(v),c=f?D(f,v):l!==void 0&&Number.isFinite(h)?new Date(Math.max(0,h-l)).toISOString():v,q=Date.parse(v)-Date.parse(c),_=[...r].filter(E=>E.sequence<=d.sequence).sort((E,K)=>K.sequence-E.sequence)[0],y=[...r].filter(E=>E.sequence>d.sequence).sort((E,K)=>E.sequence-K.sequence)[0],T=_??y,R={spanId:`codex-tool-${x(`${e.traceId}|${m}`)}`,traceId:e.traceId,turnId:e.turnId,sessionId:e.sessionId,parentSpanId:T?.spanId??`codex:${e.turnId}:turn`,kind:"tool_call",name:j(s),sequence:d.sequence,status:Z(s),startedAt:c,endedAt:v,...Number.isFinite(q)?{durationMs:Math.max(0,q)}:l!==void 0?{durationMs:l}:{},inputRefs:[],outputRefs:[],provider:{provider:"codex",nativeEventType:d.method,nativeIds:{toolCallId:m,turnId:n.providerTurnId,...n.providerThreadId?{threadId:n.providerThreadId}:{}},rawAttributes:{itemType:i,auditEventSequence:d.sequence,startEventSequence:f?.sequence,...p(s.cwd)?{cwd:s.cwd}:{},...w(s.exitCode)!==void 0?{exitCode:s.exitCode}:{}}},provenance:{source:"provider_event",accuracy:"provider_reported"}},B=ee(s);B&&S(R.inputRefs,k(o,{role:"tool_arguments",...B,captureLevel:"provider_exact"}));const F=_e(s);F&&S(R.outputRefs,k(o,{role:"tool_result",...F,captureLevel:"provider_exact"})),a.push(R)}for(const[d,s]of I){if(u.has(d))continue;const i=g(s.params.item),m=p(i?.type);if(!i||!m||!z.has(m))continue;const v=D(s,e.startedAt),f=[...r].filter(c=>c.sequence<=s.sequence).sort((c,q)=>q.sequence-c.sequence)[0]??r[0],l={spanId:`codex-tool-${x(`${e.traceId}|${d}`)}`,traceId:e.traceId,turnId:e.turnId,sessionId:e.sessionId,parentSpanId:f?.spanId??`codex:${e.turnId}:turn`,kind:"tool_call",name:j(i),sequence:s.sequence,status:"running",startedAt:v,endedAt:e.endedAt,durationMs:Math.max(0,Date.parse(e.endedAt)-Date.parse(v)),inputRefs:[],outputRefs:[],provider:{provider:"codex",nativeEventType:s.method,nativeIds:{toolCallId:d,turnId:n.providerTurnId,...n.providerThreadId?{threadId:n.providerThreadId}:{}},rawAttributes:{itemType:m,auditEventSequence:s.sequence,hasCompletion:!1}},provenance:{source:"provider_event",accuracy:"provider_reported"}},h=ee(i);h&&S(l.inputRefs,k(o,{role:"tool_arguments",...h,captureLevel:"provider_exact"})),a.push(l)}return a}function Te(e,t,n,r,o){if(!U(e).subagents)return[];const u=[],a=new Set,I=new Map;for(const d of t){if(!W.has(d.method)||!A(d.params,n))continue;const s=g(d.params.item),i=p(s?.id);i&&I.set(i,d)}for(const d of t){if(!N.has(d.method)||!A(d.params,n))continue;const s=g(d.params.item),i=p(s?.type);if(!s||!i||!G.has(i))continue;const m=p(s.id)??`sequence-${d.sequence}`;if(a.has(m))continue;a.add(m);const v=[...r].filter(T=>T.sequence<=d.sequence).sort((T,R)=>R.sequence-T.sequence)[0],f=P(d,e),l=I.get(m),h=l?D(l,f):f,c=Date.parse(f)-Date.parse(h),q={spanId:`codex-subagent-${x(`${e.traceId}|${m}`)}`,traceId:e.traceId,turnId:e.turnId,sessionId:e.sessionId,parentSpanId:v?.spanId??`codex:${e.turnId}:turn`,kind:"subagent",name:p(s.tool)??i,sequence:d.sequence,status:Z(s),startedAt:h,endedAt:f,...Number.isFinite(c)?{durationMs:Math.max(0,c)}:{},inputRefs:[],outputRefs:[],provider:{provider:"codex",nativeEventType:d.method,nativeIds:{subagentCallId:m,turnId:n.providerTurnId,...n.providerThreadId?{threadId:n.providerThreadId}:{},...p(s.senderThreadId)?{senderThreadId:String(s.senderThreadId)}:{}},rawAttributes:{itemType:i,auditEventSequence:d.sequence,startEventSequence:l?.sequence,receiverThreadIds:s.receiverThreadIds,agentsStates:s.agentsStates,model:s.model,reasoningEffort:s.reasoningEffort}},provenance:{source:"provider_event",accuracy:"provider_reported"}},_=p(s.prompt);_&&S(q.inputRefs,k(o,{role:"subagent_prompt",format:"text",value:_,captureLevel:"provider_exact"}));const y=s.result??s.agentsStates??s.status;y!==void 0&&S(q.outputRefs,k(o,{role:"subagent_result",format:typeof y=="string"?"text":"json",value:C(y),captureLevel:"provider_exact"})),u.push(q)}for(const[d,s]of I){if(a.has(d))continue;const i=g(s.params.item),m=p(i?.type);if(!i||!m||!G.has(m))continue;const v=D(s,e.startedAt),f=[...r].filter(c=>c.sequence<=s.sequence).sort((c,q)=>q.sequence-c.sequence)[0]??r[0],l={spanId:`codex-subagent-${x(`${e.traceId}|${d}`)}`,traceId:e.traceId,turnId:e.turnId,sessionId:e.sessionId,parentSpanId:f?.spanId??`codex:${e.turnId}:turn`,kind:"subagent",name:p(i.tool)??m,sequence:s.sequence,status:"running",startedAt:v,endedAt:e.endedAt,durationMs:Math.max(0,Date.parse(e.endedAt)-Date.parse(v)),inputRefs:[],outputRefs:[],provider:{provider:"codex",nativeEventType:s.method,nativeIds:{subagentCallId:d,turnId:n.providerTurnId,...n.providerThreadId?{threadId:n.providerThreadId}:{},...p(i.senderThreadId)?{senderThreadId:String(i.senderThreadId)}:{}},rawAttributes:{itemType:m,auditEventSequence:s.sequence,hasCompletion:!1,receiverThreadIds:i.receiverThreadIds,model:i.model,reasoningEffort:i.reasoningEffort}},provenance:{source:"provider_event",accuracy:"provider_reported"}},h=p(i.prompt);h&&S(l.inputRefs,k(o,{role:"subagent_prompt",format:"text",value:h,captureLevel:"provider_exact"})),u.push(l)}return u}function qe(e,t,n,r,o){const u=[];for(const a of t){if(!A(a.params,n))continue;if(ae.has(a.method)&&a.params.willRetry===!0){const i=M(a.observedAt)??e.endedAt,m=g(a.params.error);u.push({spanId:`codex-retry-${x(`${e.traceId}|${a.sequence}`)}`,traceId:e.traceId,turnId:e.turnId,sessionId:e.sessionId,parentSpanId:`codex:${e.turnId}:turn`,kind:"retry",name:p(m?.message)??"Codex request retry",sequence:a.sequence,status:"completed",startedAt:i,endedAt:i,durationMs:0,inputRefs:[],outputRefs:[],provider:{provider:"codex",nativeEventType:a.method,nativeIds:{turnId:n.providerTurnId,...n.providerThreadId?{threadId:n.providerThreadId}:{}},rawAttributes:{error:a.params.error,willRetry:!0}},provenance:{source:"provider_event",accuracy:"provider_reported"}});continue}const I=g(a.params.item),d=N.has(a.method)&&I?.type==="contextCompaction";if(!ue.has(a.method)&&!d)continue;const s=P(a,e);u.push({spanId:`codex-compaction-${x(`${e.traceId}|${a.sequence}`)}`,traceId:e.traceId,turnId:e.turnId,sessionId:e.sessionId,parentSpanId:`codex:${e.turnId}:turn`,kind:"compaction",name:"Codex context compaction",sequence:a.sequence,status:"completed",startedAt:s,endedAt:s,durationMs:0,inputRefs:[],outputRefs:[],provider:{provider:"codex",nativeEventType:a.method,nativeIds:{turnId:n.providerTurnId,...n.providerThreadId?{threadId:n.providerThreadId}:{},...p(I?.id)?{itemId:String(I?.id)}:{}},rawAttributes:I?{item:I}:{params:a.params}},provenance:{source:"provider_event",accuracy:"provider_reported"}})}if(U(e).rawProviderBody)for(const a of t){if(!oe.has(a.method)||!A(a.params,n))continue;const I=k(o,{role:"model_response",format:"json",value:C(a.params.item),captureLevel:"provider_exact"}),d=[...r].filter(s=>s.sequence>=a.sequence).sort((s,i)=>s.sequence-i.sequence)[0]??r.at(-1);d&&S(d.outputRefs,I)}return u}function te(e){return typeof e.text=="string"&&e.text.length>0?e.text:Array.isArray(e.content)&&e.content.map(n=>{if(typeof n=="string")return n;const r=g(n);return p(r?.text)??""}).join("")||void 0}function we(e,t,n,r,o,u){const a=[...r].sort((f,l)=>f.sequence-l.sequence),I=t.filter(f=>N.has(f.method)&&A(f.params,n)&&g(f.params.item)).sort((f,l)=>f.sequence-l.sequence),d=U(e);let s=Number.NEGATIVE_INFINITY,i=1;const m=new Set;for(const[f,l]of a.entries()){const h=l.sequence,c=I.filter(_=>_.sequence>s&&_.sequence<=h);if(d.inputOutput)for(const _ of c){const y=g(_.params.item),T=p(y.type);if(T!=="userMessage"&&T!=="agentMessage")continue;const R=te(y);R&&S(T==="userMessage"?l.inputRefs:l.outputRefs,k(u,{role:T==="userMessage"?"user_input":"assistant_text",format:"text",value:R,captureLevel:"provider_exact"}))}if(d.thinking)for(const _ of c){const y=g(_.params.item);if(y.type!=="reasoning")continue;const T=te(y);T&&S(l.outputRefs,k(u,{role:"thinking",format:"text",value:T,captureLevel:"provider_exact"}))}d.inputOutput&&f===0&&l.inputRefs.length===0&&e.input&&S(l.inputRefs,b(e.input)),d.inputOutput&&f===a.length-1&&l.outputRefs.length===0&&e.finalOutput&&S(l.outputRefs,b(e.finalOutput)),l.sequence=i++;const q=o.filter(_=>{const y=w(_.provider.rawAttributes?.auditEventSequence);return y!==void 0&&y>s&&y<=h}).sort((_,y)=>w(_.provider.rawAttributes?.auditEventSequence)-w(y.provider.rawAttributes?.auditEventSequence));for(const _ of q)_.sequence=i++,m.add(_.spanId);s=h}const v=o.filter(f=>!m.has(f.spanId)).sort((f,l)=>f.sequence-l.sequence);for(const f of v)f.sequence=i++;for(const f of o){if(f.outputRefs.length===0)continue;const l=a.findIndex(c=>c.spanId===f.parentSpanId),h=l>=0?a[l+1]:void 0;if(h)for(const c of f.outputRefs)S(h.inputRefs,c)}}class ke{provider="codex";async collect(t){return Q(t.boundary.codexEvidence)}async normalize(t,n){const r=Q(n),o=pe(t),u=[],a=le(r.events,o,u),I=fe(r.events,o,u),d=me(r.rolloutEntries??[],o,r.events.length+1,u),s=Ie([...I,...d]),m=ve(a,s).map(c=>ge(t,c,r.modelId)),v=[],f=ye(t,r.events,o,m,v),l=Te(t,r.events,o,m,v),h=qe(t,r.events,o,m,v);return we(t,r.events,o,m,f,v),{spans:[...m,...f,...l,...h],contents:v,anomalies:u}}async correlate(t,n){return n}validate(t,n){const r=n.spans.filter(c=>c.kind==="llm_request"&&c.usage),o=n.anomalies.some(c=>c.code==="codex_usage_invalid"||c.code==="codex_total_snapshot_invalid"||c.code==="codex_response_usage_conflict"),u=r.length>0&&!o&&r.every(c=>c.usage?.completeness==="complete"),a=t.options?.enabled?t.options.capture:void 0,I=!a?.inputOutput||!!t.input,d=n.contents.some(c=>c.role==="assistant_text"||c.role==="model_response"||c.role==="final_response"),s=!a?.inputOutput||!!t.finalOutput||d,i=!a?.tools||n.spans.filter(c=>c.kind==="tool_call").every(c=>c.status!=="running"),m=n.spans.filter(c=>c.kind==="subagent"),v=!a?.subagents||m.every(c=>c.status!=="running"),f=!a?.rawProviderBody,l=[];return r.length===0&&l.push({category:"usage",reason:"provider_usage_missing",detail:"No Codex leaf request usage was found for the provider turn"}),r.length>0&&!u&&l.push({category:"provider_usage_cache_partition",reason:"provider_usage_missing",detail:"Codex reported request totals, but one or more cache or reasoning partitions were absent"}),a?.subagents&&!v&&l.push({category:"subagents",reason:"correlation_failed",detail:"One or more Codex collaboration items did not reach a terminal state"}),a?.rawProviderBody&&l.push({category:"raw_provider_body",reason:"raw_capture_disabled"}),{status:u&&I&&s&&i&&v&&f?"complete":"partial",inputComplete:I,outputComplete:s,toolCallsComplete:i,subagentsComplete:v,usageComplete:u,rawRequestsComplete:f,gaps:l}}}export{ke as CodexAuditAdapter};
|
|
1
|
+
import{referenceCaptureContent as K}from"../../core/content-reference.js";import{assessToolCallCompleteness as se,deduplicateGaps as oe}from"../../core/tool-call-audit.js";import{InvalidCodexUsageError as z,normalizeCodexUsage as ae}from"../../core/usage.js";import{cleanupRawApiCapture as de,loadRawApiCapture as ue}from"../../raw-capture/body-source.js";import{extractProviderResponseId as ie,extractRequestModel as ce,extractSystemPrompt as pe}from"../../raw-capture/attribution.js";const le=new Set(["rawResponse/completed","codex/rawResponse/completed"]),fe=new Set(["thread/tokenUsage/updated","codex/thread/tokenUsage/updated"]),P=new Set(["item/completed","codex/item/completed"]),H=new Set(["item/started","codex/item/started"]),me=new Set(["rawResponseItem/completed","codex/rawResponseItem/completed"]),Ie=new Set(["error","codex/error"]),ve=new Set(["thread/compacted","codex/thread/compacted"]),V=new Set(["commandExecution","fileChange","mcpToolCall","dynamicToolCall","webSearch","imageView","sleep","imageGeneration"]),G=new Set(["collabAgentToolCall","subAgentActivity"]),he=Object.freeze({inputOutput:!0,tools:!0,subagents:!0,thinking:!0,rawProviderBody:!1});function y(e){if(!(typeof e!="object"||e===null||Array.isArray(e)))return e}function I(e){return typeof e=="string"&&e.length>0?e:void 0}function T(e){return typeof e=="number"&&Number.isFinite(e)?e:void 0}function $(e,t,n){return e[t]??e[n]}function ge(e){return["totalTokens","total_tokens","inputTokens","input_tokens","cachedInputTokens","cached_input_tokens","cacheWriteInputTokens","cache_write_input_tokens","outputTokens","output_tokens","reasoningOutputTokens","reasoning_output_tokens"].some(t=>Object.hasOwn(e,t))}function _e(e){const t=y(e);if(!(!t||!ge(t)))return{total_tokens:$(t,"totalTokens","total_tokens"),input_tokens:$(t,"inputTokens","input_tokens"),cached_input_tokens:$(t,"cachedInputTokens","cached_input_tokens"),cache_write_input_tokens:$(t,"cacheWriteInputTokens","cache_write_input_tokens"),output_tokens:$(t,"outputTokens","output_tokens"),reasoning_output_tokens:$(t,"reasoningOutputTokens","reasoning_output_tokens")}}function J(e){return[e.input.total,e.input.cacheRead??"unknown",e.input.cacheWrite??"unknown",e.output.total,e.output.reasoning??"unknown"].join(":")}function Q(e,t){return e.input.total!==t.input.total||e.output.total!==t.output.total?!1:[[e.input.cacheRead,t.input.cacheRead],[e.input.cacheWrite,t.input.cacheWrite],[e.output.reasoning,t.output.reasoning]].every(([s,o])=>s===null||o===null||s===o)}function R(e){let t=2166136261;for(let n=0;n<e.length;n+=1)t^=e.charCodeAt(n),t=Math.imul(t,16777619);return(t>>>0).toString(16).padStart(8,"0")}function M(e){const t=I(e);if(!(!t||Number.isNaN(Date.parse(t))))return t}function O(e){return e.options?.enabled===!0?e.options.capture:he}function S(e){if(typeof e=="string")return e;try{const t=JSON.stringify(e);return t===void 0?"null":t}catch{return String(e)}}function A(e,t){const n=K(t);return e.push(t),n}function x(e,t){t&&(e.some(n=>n.contentId===t.contentId)||e.push(t))}function Y(e){const t=_e(e);return t?{...ae(t),providerUsageRaw:e}:void 0}function ye(e){return{providerTurnId:I(e.boundary.providerTurnId)??I(e.boundary.turnId)??e.turnId,providerThreadId:I(e.boundary.providerThreadId)??I(e.boundary.threadId)}}function C(e,t){const n=I(e.turnId??e.turn_id);if(n&&n!==t.providerTurnId)return!1;const s=I(e.threadId??e.thread_id);return!(t.providerThreadId&&s&&s!==t.providerThreadId)}function k(e,t,n,s){e.push({code:t,message:n,providerIds:s})}function X(e,t,n){try{const s=Y(e);if(!s){k(n,"codex_usage_missing",`${t.nativeEventType} did not contain a usable usage payload`);return}return{...t,usage:s,providerUsageRaw:e,usageKey:J(s),reconciledWithTokenSnapshot:!1}}catch(s){if(s instanceof z){k(n,"codex_usage_invalid",s.message,t.responseId?{responseId:t.responseId}:void 0);return}throw s}}function L(e){const t=y(e);if(!t)return{events:[]};const n=I(t.modelId);return{...n?{modelId:n}:{},events:Array.isArray(t.events)?t.events.filter(s=>{const o=y(s);return!!(o&&typeof o.method=="string"&&y(o.params))}):[],rolloutEntries:Array.isArray(t.rolloutEntries)?t.rolloutEntries:[],...y(t.rawApiCapture)&&Array.isArray(y(t.rawApiCapture)?.exchanges)?{rawApiCapture:t.rawApiCapture}:{}}}function Z(e){const t=e?.toLowerCase()??"";return t.includes("ndjson")?"text":t.includes("json")?"json":(t.includes("event-stream"),"text")}function we(e){return e.correlation.providerResponseId??(e.upstream.body.value===void 0?void 0:ie(e.upstream.body.value))}function qe(e,t,n,s){const o=t.correlation.providerRequestId,d=e.find(l=>!s.has(l.spanId)&&(n&&(l.provider.nativeIds.responseId===n||l.provider.nativeIds.requestId===n)||o&&(l.provider.nativeIds.requestId===o||l.provider.nativeIds.responseId===o)));if(d)return d;const u=e.filter(l=>!s.has(l.spanId));return u.length===1?u[0]:void 0}function xe(e,t,n,s,o){const d=t.completedAt??t.startedAt;return{spanId:`codex-raw-${R(`${e.traceId}|${t.exchangeId}`)}`,traceId:e.traceId,turnId:e.turnId,sessionId:e.sessionId,parentSpanId:`codex:${e.turnId}:turn`,kind:"llm_request",name:"codex provider request",sequence:n,status:t.status==="cancelled"?"cancelled":t.status==="failed"?"failed":"completed",startedAt:t.startedAt,endedAt:d,durationMs:Math.max(0,Date.parse(d)-Date.parse(t.startedAt)),...s?{modelId:s}:{},inputRefs:[],outputRefs:[],provider:{provider:"codex",nativeEventType:"provider_raw_api_exchange",nativeIds:{requestId:t.correlation.providerRequestId??t.exchangeId,exchangeId:t.exchangeId,...o?{responseId:o}:{}}},provenance:{source:"provider_raw_body",accuracy:"runtime_exact"}}}function Te(e,t,n,s,o){if(!t)return;if(t.status==="unavailable"){k(o,"codex_raw_api_capture_unavailable",t.unavailableReason??"Codex raw API capture is unavailable");return}for(const r of t.errors)k(o,"codex_raw_api_capture_partial",r);const d=n.filter(r=>r.kind==="llm_request"),u=new Set;let l=n.reduce((r,a)=>Math.max(r,a.sequence),0)+1;for(const r of t.exchanges){const a=r.downstream.body.value,i=r.upstream.body.value,c=we(r),g=a?ce(a):void 0,p=qe(d,r,c,u),f=d.filter(q=>!u.has(q.spanId)).length;!p&&f>1&&k(o,"codex_raw_api_correlation_ambiguous",`Raw API exchange ${r.exchangeId} has no stable request identifier`,{exchangeId:r.exchangeId});const v=p??xe(e,r,l++,g,c);n.includes(v)||n.push(v),u.add(v.spanId);const _=a===void 0?void 0:A(s,{role:"model_request",format:Z(r.downstream.body.contentType),value:a,sourcePath:r.downstream.body.sourcePath,captureLevel:"provider_exact"}),w=i===void 0?void 0:A(s,{role:"model_response",format:Z(r.upstream.body.contentType),value:i,sourcePath:r.upstream.body.sourcePath,captureLevel:"provider_exact"}),h=a?pe(a):void 0;h&&A(s,{role:"system_prompt",format:"json",value:h,sourcePath:r.downstream.body.sourcePath,captureLevel:"provider_exact"}),x(v.inputRefs,_),x(v.outputRefs,w),g&&!v.modelId&&(v.modelId=g),v.provider.nativeIds.exchangeId=r.exchangeId,c&&(v.provider.nativeIds.responseId=c),v.provider.rawAttributes={...v.provider.rawAttributes,rawApiExchange:{method:r.downstream.method,path:r.downstream.path,query:r.downstream.query,requestHeaders:r.downstream.redactedHeaders,responseStatus:r.upstream.statusCode,responseHeaders:r.upstream.redactedHeaders,requestSha256:r.downstream.body.sha256,responseSha256:r.upstream.body.sha256,requestBytes:r.downstream.body.bytes,responseBytes:r.upstream.body.bytes}},(!_||!w||r.errors.length>0)&&k(o,"codex_raw_api_capture_partial",`Raw API exchange ${r.exchangeId} is incomplete`,{exchangeId:r.exchangeId})}}function Ae(e,t,n){const s=new Map;let o=0;for(const d of e){if(!le.has(d.method)||!C(d.params,t))continue;const u=I(d.params.turnId??d.params.turn_id)??t.providerTurnId,l=I(d.params.threadId??d.params.thread_id)??t.providerThreadId,r=I(d.params.responseId??d.params.response_id),a=X(d.params.usage,{sequence:T(d.sequence)??o,observedAt:M(d.observedAt),providerTurnId:u,threadId:l,responseId:r,nativeEventType:d.method,source:"provider_raw_body"},n);if(o+=1,!a)continue;const i=r?`response:${r}`:`anonymous:${a.sequence}:${a.usageKey}`,c=s.get(i);if(c&&!Q(c.usage,a.usage)){k(n,"codex_response_usage_conflict",`Response ${r??i} reported conflicting usage`,r?{responseId:r}:void 0);continue}c||s.set(i,a)}return[...s.values()].sort((d,u)=>d.sequence-u.sequence)}function j(e,t,n,s){const o=X(e,n,s);if(!o)return;let d;try{const u=Y(t);u&&(d=[n.threadId??"unknown-thread",n.providerTurnId,J(u)].join("|"))}catch(u){if(u instanceof z)k(s,"codex_total_snapshot_invalid",u.message);else throw u}return{...o,providerUsageRaw:{last:e,total:t},usage:{...o.usage,providerUsageRaw:{last:e,total:t}},snapshotKey:d}}function Se(e,t,n){const s=[];for(const o of e){if(!fe.has(o.method)||!C(o.params,t))continue;const d=y(o.params.tokenUsage??o.params.token_usage);if(!d){k(n,"codex_usage_missing",`${o.method} did not contain tokenUsage`);continue}const u=I(o.params.turnId??o.params.turn_id)??t.providerTurnId,l=I(o.params.threadId??o.params.thread_id)??t.providerThreadId,r=j(d.last??d.last_token_usage,d.total??d.total_token_usage,{sequence:T(o.sequence)??s.length,observedAt:M(o.observedAt),providerTurnId:u,threadId:l,responseId:I(o.params.responseId??o.params.response_id),nativeEventType:o.method,source:"provider_event"},n);r&&s.push(r)}return s}function Re(e,t,n,s){const o=[];return e.forEach((d,u)=>{const l=y(d),r=y(l?.payload);if(l?.type!=="event_msg"||r?.type!=="token_count")return;const a=y(r.info);if(!a)return;const i=j(a.last_token_usage??a.lastTokenUsage,a.total_token_usage??a.totalTokenUsage,{sequence:T(l?.sequence)??n+u,observedAt:M(l?.timestamp),providerTurnId:t.providerTurnId,threadId:t.providerThreadId,nativeEventType:"rollout/event_msg/token_count",source:"provider_transcript"},s);i&&o.push(i)}),o}function Ce(e){const t=new Set;return e.filter(n=>n.snapshotKey?t.has(n.snapshotKey)?!1:(t.add(n.snapshotKey),!0):!0)}function ke(e,t){const n=new Set(e),s=new Set(t);for(const o of t){const d=e.find(u=>!n.has(u)||o.responseId&&u.responseId&&o.responseId!==u.responseId?!1:u.providerTurnId===o.providerTurnId&&Q(u.usage,o.usage));d&&(d.reconciledWithTokenSnapshot=!0,d.snapshotKey=o.snapshotKey,d.threadId??=o.threadId,d.providerUsageRaw={rawResponse:d.providerUsageRaw,tokenUsage:o.providerUsageRaw},d.usage={...d.usage,providerUsageRaw:d.providerUsageRaw},n.delete(d),s.delete(o))}return[...e,...t.filter(o=>s.has(o))].sort((o,d)=>o.sequence-d.sequence)}function Ee(e){if(e.responseId)return e.responseId;const t=e.snapshotKey??[e.threadId??"unknown-thread",e.providerTurnId,e.sequence,e.usageKey].join("|");return`codex-usage-${R(t)}`}function be(e,t,n){const s=Ee(t),o={requestId:s,turnId:t.providerTurnId};t.threadId&&(o.threadId=t.threadId),t.responseId&&(o.responseId=t.responseId),t.snapshotKey&&(o.usageSnapshotId=R(t.snapshotKey));const d=t.observedAt??e.startedAt;return{spanId:`codex-llm-${R(`${e.traceId}|${s}`)}`,traceId:e.traceId,turnId:e.turnId,sessionId:e.sessionId,parentSpanId:`codex:${e.turnId}:turn`,kind:"llm_request",name:"codex response",sequence:t.sequence,status:"completed",startedAt:d,endedAt:d,...n?{modelId:n}:{},inputRefs:[],outputRefs:[],usage:t.usage,provider:{provider:"codex",nativeEventType:t.nativeEventType,nativeIds:o,rawAttributes:{usageSource:t.source,reconciledWithTokenSnapshot:t.reconciledWithTokenSnapshot}},provenance:{source:t.source,accuracy:"provider_reported"}}}function B(e,t){const n=T(e.params.completedAtMs);if(n!==void 0){const s=new Date(n);if(!Number.isNaN(s.getTime()))return s.toISOString()}return M(e.observedAt)??t.endedAt}function N(e,t){const n=T(e.params.startedAtMs);if(n!==void 0){const s=new Date(n);if(!Number.isNaN(s.getTime()))return s.toISOString()}return M(e.observedAt)??t}function ee(e){const t=I(e.status)?.toLowerCase();return t==="inprogress"||t==="in_progress"||t==="running"?"running":t==="failed"||t==="declined"||t==="error"||T(e.exitCode)!==void 0&&T(e.exitCode)!==0?"failed":t==="cancelled"||t==="canceled"?"cancelled":"completed"}function te(e){const t=I(e.type)??"tool";if(t==="mcpToolCall"){const n=I(e.server),s=I(e.tool);return[n,s].filter(Boolean).join("/")||t}return I(e.tool)??t}function ne(e){switch(I(e.type)){case"commandExecution":return typeof e.command=="string"?{format:"text",value:String(e.command)}:void 0;case"fileChange":return Object.hasOwn(e,"changes")?{format:"json",value:S(e.changes)}:void 0;case"mcpToolCall":case"dynamicToolCall":return Object.hasOwn(e,"arguments")?{format:"json",value:S(e.arguments)}:void 0;case"webSearch":return typeof e.query=="string"?{format:"text",value:String(e.query)}:void 0;default:return{format:"json",value:S(e)}}}function $e(e){switch(I(e.type)){case"commandExecution":return typeof e.aggregatedOutput=="string"?{format:"text",value:e.aggregatedOutput}:e.status!==void 0||e.exitCode!==void 0?{format:"json",value:S({status:e.status,exitCode:e.exitCode})}:void 0;case"fileChange":return{format:"json",value:S({status:e.status})};case"mcpToolCall":return Object.hasOwn(e,"result")?{format:"json",value:S(e.result)}:Object.hasOwn(e,"error")?{format:"json",value:S(e.error)}:void 0;case"dynamicToolCall":return Object.hasOwn(e,"contentItems")?{format:"json",value:S(e.contentItems)}:void 0;default:return{format:"json",value:S(e)}}}function Me(e,t,n,s,o){if(!O(e).tools)return[];const d=new Set,u=[],l=new Map;for(const r of t){if(!H.has(r.method)||!C(r.params,n))continue;const a=y(r.params.item),i=I(a?.id);i&&l.set(i,r)}for(const r of t){if(!P.has(r.method)||!C(r.params,n))continue;const a=y(r.params.item),i=I(a?.type);if(!a||!i||!V.has(i))continue;const c=I(a.id)??`sequence-${r.sequence}`;if(d.has(c))continue;d.add(c);const g=B(r,e),p=l.get(c),f=T(a.durationMs),v=Date.parse(g),_=p?N(p,g):f!==void 0&&Number.isFinite(v)?new Date(Math.max(0,v-f)).toISOString():g,w=Date.parse(g)-Date.parse(_),h=Number.isFinite(w)&&w>0?w:f,q=[...s].filter(E=>E.sequence<=r.sequence).sort((E,D)=>D.sequence-E.sequence)[0],m=[...s].filter(E=>E.sequence>r.sequence).sort((E,D)=>E.sequence-D.sequence)[0],b=q??m,U={spanId:`codex-tool-${R(`${e.traceId}|${c}`)}`,traceId:e.traceId,turnId:e.turnId,sessionId:e.sessionId,parentSpanId:b?.spanId??`codex:${e.turnId}:turn`,kind:"tool_call",name:te(a),sequence:r.sequence,status:ee(a),startedAt:_,endedAt:g,...h!==void 0?{durationMs:Math.max(0,h)}:{},inputRefs:[],outputRefs:[],provider:{provider:"codex",nativeEventType:r.method,nativeIds:{toolCallId:c,turnId:n.providerTurnId,...n.providerThreadId?{threadId:n.providerThreadId}:{}},rawAttributes:{itemType:i,auditEventSequence:r.sequence,startEventSequence:p?.sequence,...I(a.cwd)?{cwd:a.cwd}:{},...T(a.exitCode)!==void 0?{exitCode:a.exitCode}:{}}},provenance:{source:"provider_event",accuracy:"provider_reported"}},F=ne(a);F&&x(U.inputRefs,A(o,{role:"tool_arguments",...F,captureLevel:"provider_exact"}));const W=$e(a);W&&x(U.outputRefs,A(o,{role:"tool_result",...W,captureLevel:"provider_exact"})),u.push(U)}for(const[r,a]of l){if(d.has(r))continue;const i=y(a.params.item),c=I(i?.type);if(!i||!c||!V.has(c))continue;const g=N(a,e.startedAt),p=[...s].filter(_=>_.sequence<=a.sequence).sort((_,w)=>w.sequence-_.sequence)[0]??s[0],f={spanId:`codex-tool-${R(`${e.traceId}|${r}`)}`,traceId:e.traceId,turnId:e.turnId,sessionId:e.sessionId,parentSpanId:p?.spanId??`codex:${e.turnId}:turn`,kind:"tool_call",name:te(i),sequence:a.sequence,status:"running",startedAt:g,endedAt:e.endedAt,durationMs:Math.max(0,Date.parse(e.endedAt)-Date.parse(g)),inputRefs:[],outputRefs:[],provider:{provider:"codex",nativeEventType:a.method,nativeIds:{toolCallId:r,turnId:n.providerTurnId,...n.providerThreadId?{threadId:n.providerThreadId}:{}},rawAttributes:{itemType:c,auditEventSequence:a.sequence,hasCompletion:!1}},provenance:{source:"provider_event",accuracy:"provider_reported"}},v=ne(i);v&&x(f.inputRefs,A(o,{role:"tool_arguments",...v,captureLevel:"provider_exact"})),u.push(f)}return u}function Oe(e,t,n,s,o){if(!O(e).subagents)return[];const d=[],u=new Set,l=new Map;for(const r of t){if(!H.has(r.method)||!C(r.params,n))continue;const a=y(r.params.item),i=I(a?.id);i&&l.set(i,r)}for(const r of t){if(!P.has(r.method)||!C(r.params,n))continue;const a=y(r.params.item),i=I(a?.type);if(!a||!i||!G.has(i))continue;const c=I(a.id)??`sequence-${r.sequence}`;if(u.has(c))continue;u.add(c);const g=[...s].filter(m=>m.sequence<=r.sequence).sort((m,b)=>b.sequence-m.sequence)[0],p=B(r,e),f=l.get(c),v=f?N(f,p):p,_=Date.parse(p)-Date.parse(v),w={spanId:`codex-subagent-${R(`${e.traceId}|${c}`)}`,traceId:e.traceId,turnId:e.turnId,sessionId:e.sessionId,parentSpanId:g?.spanId??`codex:${e.turnId}:turn`,kind:"subagent",name:I(a.tool)??i,sequence:r.sequence,status:ee(a),startedAt:v,endedAt:p,...Number.isFinite(_)?{durationMs:Math.max(0,_)}:{},inputRefs:[],outputRefs:[],provider:{provider:"codex",nativeEventType:r.method,nativeIds:{subagentCallId:c,turnId:n.providerTurnId,...n.providerThreadId?{threadId:n.providerThreadId}:{},...I(a.senderThreadId)?{senderThreadId:String(a.senderThreadId)}:{}},rawAttributes:{itemType:i,auditEventSequence:r.sequence,startEventSequence:f?.sequence,receiverThreadIds:a.receiverThreadIds,agentsStates:a.agentsStates,model:a.model,reasoningEffort:a.reasoningEffort}},provenance:{source:"provider_event",accuracy:"provider_reported"}},h=I(a.prompt);h&&x(w.inputRefs,A(o,{role:"subagent_prompt",format:"text",value:h,captureLevel:"provider_exact"}));const q=a.result??a.agentsStates??a.status;q!==void 0&&x(w.outputRefs,A(o,{role:"subagent_result",format:typeof q=="string"?"text":"json",value:S(q),captureLevel:"provider_exact"})),d.push(w)}for(const[r,a]of l){if(u.has(r))continue;const i=y(a.params.item),c=I(i?.type);if(!i||!c||!G.has(c))continue;const g=N(a,e.startedAt),p=[...s].filter(_=>_.sequence<=a.sequence).sort((_,w)=>w.sequence-_.sequence)[0]??s[0],f={spanId:`codex-subagent-${R(`${e.traceId}|${r}`)}`,traceId:e.traceId,turnId:e.turnId,sessionId:e.sessionId,parentSpanId:p?.spanId??`codex:${e.turnId}:turn`,kind:"subagent",name:I(i.tool)??c,sequence:a.sequence,status:"running",startedAt:g,endedAt:e.endedAt,durationMs:Math.max(0,Date.parse(e.endedAt)-Date.parse(g)),inputRefs:[],outputRefs:[],provider:{provider:"codex",nativeEventType:a.method,nativeIds:{subagentCallId:r,turnId:n.providerTurnId,...n.providerThreadId?{threadId:n.providerThreadId}:{},...I(i.senderThreadId)?{senderThreadId:String(i.senderThreadId)}:{}},rawAttributes:{itemType:c,auditEventSequence:a.sequence,hasCompletion:!1,receiverThreadIds:i.receiverThreadIds,model:i.model,reasoningEffort:i.reasoningEffort}},provenance:{source:"provider_event",accuracy:"provider_reported"}},v=I(i.prompt);v&&x(f.inputRefs,A(o,{role:"subagent_prompt",format:"text",value:v,captureLevel:"provider_exact"})),d.push(f)}return d}function Pe(e,t,n,s,o){const d=[];for(const u of t){if(!C(u.params,n))continue;if(Ie.has(u.method)&&u.params.willRetry===!0){const i=M(u.observedAt)??e.endedAt,c=y(u.params.error);d.push({spanId:`codex-retry-${R(`${e.traceId}|${u.sequence}`)}`,traceId:e.traceId,turnId:e.turnId,sessionId:e.sessionId,parentSpanId:`codex:${e.turnId}:turn`,kind:"retry",name:I(c?.message)??"Codex request retry",sequence:u.sequence,status:"completed",startedAt:i,endedAt:i,durationMs:0,inputRefs:[],outputRefs:[],provider:{provider:"codex",nativeEventType:u.method,nativeIds:{turnId:n.providerTurnId,...n.providerThreadId?{threadId:n.providerThreadId}:{}},rawAttributes:{error:u.params.error,willRetry:!0}},provenance:{source:"provider_event",accuracy:"provider_reported"}});continue}const l=y(u.params.item),r=P.has(u.method)&&l?.type==="contextCompaction";if(!ve.has(u.method)&&!r)continue;const a=B(u,e);d.push({spanId:`codex-compaction-${R(`${e.traceId}|${u.sequence}`)}`,traceId:e.traceId,turnId:e.turnId,sessionId:e.sessionId,parentSpanId:`codex:${e.turnId}:turn`,kind:"compaction",name:"Codex context compaction",sequence:u.sequence,status:"completed",startedAt:a,endedAt:a,durationMs:0,inputRefs:[],outputRefs:[],provider:{provider:"codex",nativeEventType:u.method,nativeIds:{turnId:n.providerTurnId,...n.providerThreadId?{threadId:n.providerThreadId}:{},...I(l?.id)?{itemId:String(l?.id)}:{}},rawAttributes:l?{item:l}:{params:u.params}},provenance:{source:"provider_event",accuracy:"provider_reported"}})}if(O(e).rawProviderBody)for(const u of t){if(!me.has(u.method)||!C(u.params,n))continue;const l=A(o,{role:"model_response",format:"json",value:S(u.params.item),captureLevel:"provider_exact"}),r=[...s].filter(a=>a.sequence>=u.sequence).sort((a,i)=>a.sequence-i.sequence)[0]??s.at(-1);r&&x(r.outputRefs,l)}return d}function re(e){return typeof e.text=="string"&&e.text.length>0?e.text:Array.isArray(e.content)&&e.content.map(n=>{if(typeof n=="string")return n;const s=y(n);return I(s?.text)??""}).join("")||void 0}function Ne(e,t,n,s,o,d){const u=[...s].sort((p,f)=>p.sequence-f.sequence),l=t.filter(p=>P.has(p.method)&&C(p.params,n)&&y(p.params.item)).sort((p,f)=>p.sequence-f.sequence),r=O(e);let a=Number.NEGATIVE_INFINITY,i=1;const c=new Set;for(const[p,f]of u.entries()){const v=f.sequence,_=l.filter(h=>h.sequence>a&&h.sequence<=v);if(r.inputOutput)for(const h of _){const q=y(h.params.item),m=I(q.type);if(m!=="userMessage"&&m!=="agentMessage")continue;const b=re(q);b&&x(m==="userMessage"?f.inputRefs:f.outputRefs,A(d,{role:m==="userMessage"?"user_input":"assistant_text",format:"text",value:b,captureLevel:"provider_exact"}))}if(r.thinking)for(const h of _){const q=y(h.params.item);if(q.type!=="reasoning")continue;const m=re(q);m&&x(f.outputRefs,A(d,{role:"thinking",format:"text",value:m,captureLevel:"provider_exact"}))}r.inputOutput&&p===0&&f.inputRefs.length===0&&e.input&&x(f.inputRefs,K(e.input)),r.inputOutput&&p===u.length-1&&f.outputRefs.length===0&&e.finalOutput&&x(f.outputRefs,K(e.finalOutput)),f.sequence=i++;const w=o.filter(h=>{const q=T(h.provider.rawAttributes?.auditEventSequence);return q!==void 0&&q>a&&q<=v}).sort((h,q)=>T(h.provider.rawAttributes?.auditEventSequence)-T(q.provider.rawAttributes?.auditEventSequence));for(const h of w)h.sequence=i++,c.add(h.spanId);a=v}const g=o.filter(p=>!c.has(p.spanId)).sort((p,f)=>p.sequence-f.sequence);for(const p of g)p.sequence=i++;for(const p of o){if(p.outputRefs.length===0)continue;const f=u.findIndex(_=>_.spanId===p.parentSpanId),v=f>=0?u[f+1]:void 0;if(v)for(const _ of p.outputRefs)x(v.inputRefs,_)}}class Fe{provider="codex";async collect(t){const n=L(t.boundary.codexEvidence),s=y(t.boundary.codexEvidence);return s?.rawApiCapture!==void 0&&(n.rawApiCapture=await ue(s.rawApiCapture)),n}async normalize(t,n){const s=L(n),o=ye(t),d=[],u=Ae(s.events,o,d),l=Se(s.events,o,d),r=Re(s.rolloutEntries??[],o,s.events.length+1,d),a=Ce([...l,...r]),c=ke(u,a).map(_=>be(t,_,s.modelId)),g=[],p=Me(t,s.events,o,c,g),f=Oe(t,s.events,o,c,g),v=Pe(t,s.events,o,c,g);return Ne(t,s.events,o,c,p,g),Te(t,s.rawApiCapture,c,g,d),{spans:[...c,...p,...f,...v],contents:g,anomalies:d}}async correlate(t,n){return n}validate(t,n){const s=n.spans.filter(m=>m.kind==="llm_request"&&m.usage),o=n.anomalies.some(m=>m.code==="codex_usage_invalid"||m.code==="codex_total_snapshot_invalid"||m.code==="codex_response_usage_conflict"),d=s.length>0&&!o&&s.every(m=>m.usage?.completeness==="complete"),u=O(t),l=!u.inputOutput||!!t.input,r=n.contents.some(m=>m.role==="assistant_text"||m.role==="model_response"||m.role==="final_response"),a=!u.inputOutput||!!t.finalOutput||r,i=se(n.spans,u.tools),c=i.complete,g=n.spans.filter(m=>m.kind==="subagent"),p=!u.subagents||g.every(m=>m.status!=="running"),f=n.contents.filter(m=>m.role==="model_request"&&m.value!==void 0).length,v=n.contents.filter(m=>m.role==="model_response"&&m.value!==void 0).length,_=n.anomalies.some(m=>m.code==="codex_raw_api_capture_unavailable"||m.code==="codex_raw_api_capture_partial"||m.code==="codex_raw_api_correlation_ambiguous"),w=!u.rawProviderBody||f>0&&v>=f&&!_,h=[];return s.length===0&&h.push({category:"usage",reason:"provider_usage_missing",detail:"No Codex leaf request usage was found for the provider turn"}),s.length>0&&!d&&h.push({category:"provider_usage_cache_partition",reason:"provider_usage_missing",detail:"Codex reported request totals, but one or more cache or reasoning partitions were absent"}),u.subagents&&!p&&h.push({category:"subagents",reason:"correlation_failed",detail:"One or more Codex collaboration items did not reach a terminal state"}),u.rawProviderBody&&(f===0?h.push({category:"raw_provider_body",reason:"raw_capture_disabled",detail:"Codex raw API capture did not produce a request body"}):w||h.push({category:"raw_provider_body",reason:"correlation_failed",detail:"One or more Codex raw API exchanges are incomplete"})),h.push(...i.gaps),{status:d&&l&&a&&c&&p&&w?"complete":"partial",inputComplete:l,outputComplete:a,toolCallsComplete:c,subagentsComplete:p,usageComplete:d,rawRequestsComplete:w,gaps:oe(h)}}async cleanup(t,n){const s=L(n).rawApiCapture;s&&await de(s)}}export{Fe as CodexAuditAdapter};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{referenceCaptureContent as
|
|
1
|
+
import{referenceCaptureContent as J}from"../../core/content-reference.js";import{assessToolCallCompleteness as Q,deduplicateGaps as V}from"../../core/tool-call-audit.js";import{InvalidPiUsageError as W,normalizePiUsage as X}from"../../core/usage.js";import{collectPiTranscript as Y}from"./pi-transcript-source.js";const Z=Object.freeze({inputOutput:!0,tools:!0,subagents:!0,thinking:!0,rawProviderBody:!1});function D(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function p(e){return typeof e=="string"&&e.length>0?e:void 0}function G(e,t){const n=p(e);return n&&Number.isFinite(Date.parse(n))?n:t}function B(e){if(typeof e=="string")return e;try{const t=JSON.stringify(e);return t===void 0?"null":t}catch{return String(e)}}function j(e){return e.options?.enabled===!0?e.options.capture:Z}function A(e,t,n){const r=[n.role,n.sourcePath??"",n.sourceOffset??"",n.value??""].join("\0");if(t.has(r))return t.get(r);const c=J(n);return t.set(r,c),e.push(n),c}function L(e){const t=e.startedAt??e.job.startedAt,n=e.endedAt??e.job.endedAt,r=Date.parse(t),c=Date.parse(n);return{spanId:e.spanId,traceId:e.job.traceId,turnId:e.job.turnId,sessionId:e.job.sessionId,...e.parentSpanId?{parentSpanId:e.parentSpanId}:{},kind:e.kind,name:e.name,sequence:e.sequence,status:e.status??"completed",startedAt:t,endedAt:n,...Number.isFinite(r)&&Number.isFinite(c)?{durationMs:Math.max(0,c-r)}:{},inputRefs:[],outputRefs:[],provider:{provider:"pi",nativeEventType:e.nativeEventType,nativeIds:Object.fromEntries(Object.entries(e.nativeIds??{}).filter(y=>typeof y[1]=="string")),...e.rawAttributes?{rawAttributes:e.rawAttributes}:{}},provenance:{source:"provider_transcript",accuracy:"provider_reported"}}}function U(e){return Array.isArray(e.content)?e.content.filter(D):[]}function ee(e){const t=U(e);if(t.length!==0)return t.every(n=>n.type==="text"&&typeof n.text=="string")?{format:"text",value:t.map(n=>String(n.text)).join("")}:{format:"json",value:B(e.content)}}function te(e){if(!Object.hasOwn(e,"content"))return;if(typeof e.content=="string")return{format:"text",value:e.content};const t=U(e);return t.length>0&&t.every(n=>n.type==="text"&&typeof n.text=="string")?{format:"text",value:t.map(n=>String(n.text)).join("")}:{format:"json",value:B(e.content)}}function P(e,t,n,r){return{role:t,format:n,value:r,sourcePath:e.sourcePath,sourceOffset:e.sourceOffset,sourceLength:e.sourceLength,captureLevel:"provider_exact"}}function h(e,t){t&&(e.some(n=>n.contentId===t.contentId&&n.role===t.role)||e.push(t))}class ae{provider="pi";async collect(t){return Y(t.boundary)}async normalize(t,n){const r=n,c=j(t),y=[...r.anomalies],l=[],m=new Map,O=[];let R=0;const S=`pi:${t.turnId}:turn`,w=L({job:t,spanId:S,kind:"turn",name:"Pi audited turn",sequence:R++,status:t.outcome==="completed"?"completed":t.outcome==="cancelled"?"cancelled":"failed",nativeEventType:"prompt",nativeIds:{platformEventId:p(t.boundary.platformEventId),providerSessionId:p(t.boundary.providerSessionId)}});O.push(w),c.inputOutput&&t.input&&h(w.inputRefs,A(l,m,{...t.input,captureLevel:t.input.captureLevel??"runtime_exact"})),c.inputOutput&&t.finalOutput&&h(w.outputRefs,A(l,m,{...t.finalOutput,captureLevel:t.finalOutput.captureLevel??"runtime_exact"}));let d=t.startedAt,I=[];const q=new Map;let M,F,_;for(const a of r.lines){const o=a.record,E=G(o.timestamp,d);if(o.type==="model_change"){M=p(o.modelId),F=p(o.provider),d=E;continue}if(o.type==="thinking_level_change"){_=p(o.thinkingLevel),d=E;continue}if(o.type==="custom_message"){if(c.inputOutput){const u=typeof o.content=="string"?o.content:B(o.content);h(I,A(l,m,P(a,"user_input",typeof o.content=="string"?"text":"json",u)))}d=E;continue}if(o.type==="compaction"||o.type==="branch_summary"){const u=p(o.id)??`offset-${a.sourceOffset}`,s=L({job:t,spanId:`pi:${t.sessionId}:compaction:${u}`,parentSpanId:S,kind:"compaction",name:o.type==="compaction"?"Pi context compaction":"Pi branch summary",sequence:R++,startedAt:E,endedAt:E,nativeEventType:o.type,nativeIds:{entryId:u,firstKeptEntryId:p(o.firstKeptEntryId),fromId:p(o.fromId)},rawAttributes:{tokensBefore:o.tokensBefore,details:o.details,fromHook:o.fromHook,sourcePath:a.sourcePath,sourceOffset:a.sourceOffset}}),v=p(o.summary);v&&(h(s.outputRefs,A(l,m,P(a,"model_response","text",v))),h(I,s.outputRefs[0])),O.push(s),d=E;continue}if(o.type!=="message"||!D(o.message))continue;const i=o.message,N=p(i.role),x=G(o.timestamp??i.timestamp,d),g=p(o.id)??`offset-${a.sourceOffset}`;if(N==="bashExecution"){if(c.tools){const u=p(i.command),s=typeof i.output=="string"?i.output:void 0,v=typeof i.exitCode=="number"?i.exitCode:void 0,f=i.cancelled===!0,C=L({job:t,spanId:`pi:${t.sessionId}:bash:${g}`,parentSpanId:S,kind:"tool_call",name:"bash",sequence:R++,status:f?"cancelled":v!==void 0&&v!==0?"failed":"completed",startedAt:x,endedAt:x,nativeEventType:"bashExecution",nativeIds:{messageId:g},rawAttributes:{exitCode:v,cancelled:f,truncated:i.truncated===!0,excludeFromContext:i.excludeFromContext===!0,fullOutputPath:i.fullOutputPath,sourcePath:a.sourcePath,sourceOffset:a.sourceOffset}});if(u&&h(C.inputRefs,A(l,m,P(a,"tool_arguments","text",u))),s!==void 0){const k=A(l,m,P(a,"tool_result","text",s));h(C.outputRefs,k),i.excludeFromContext!==!0&&h(I,k)}O.push(C)}d=x;continue}if(N==="user"){if(c.inputOutput){const u=ee(i);if(u){const s=A(l,m,P(a,"user_input",u.format,u.value));h(I,s)}}d=x;continue}if(N==="toolResult"){const u=p(i.toolCallId),s=u?q.get(u):void 0,v=te(i);let f;if(c.tools&&v&&(f=A(l,m,P(a,"tool_result",v.format,v.value)),h(I,f)),s){s.resultSeen=!0,s.span.endedAt=x;const C=Date.parse(s.span.startedAt),k=Date.parse(x);Number.isFinite(C)&&Number.isFinite(k)&&(s.span.durationMs=Math.max(0,k-C)),s.span.status=i.isError===!0?"failed":"completed",h(s.span.outputRefs,f),s.span.provider.rawAttributes&&(s.span.provider.rawAttributes.hasResult=!0,s.span.provider.rawAttributes.isError=i.isError===!0)}else c.tools&&(y.push({code:"pi_tool_result_without_call",message:`No tool call found for result ${u??g}`,providerIds:u?{toolCallId:u}:{messageId:g}}),r.gaps.push({category:"tool_call",reason:"correlation_failed",detail:`${u??g}:orphan_result`}));d=x;continue}if(N!=="assistant"){d=x;continue}const z=p(i.responseId),$=z??g,T=p(i.model)??M,H=p(i.provider)??F,b=L({job:t,spanId:`pi:${t.sessionId}:request:${$}`,parentSpanId:S,kind:"llm_request",name:T??"Pi model request",sequence:R++,startedAt:d,endedAt:x,nativeEventType:"message",nativeIds:{requestId:$,responseId:z,messageId:g},rawAttributes:{sourcePath:a.sourcePath,sourceOffset:a.sourceOffset,...H?{provider:H}:{},...T?{model:T}:{},..._?{thinkingLevel:_}:{},...typeof i.stopReason=="string"?{stopReason:i.stopReason}:{}}});if(T&&(b.modelId=T),b.inputRefs.push(...I),I=[],D(i.usage))try{b.usage=X(i.usage)}catch(u){y.push({code:"pi_provider_usage_invalid",message:u instanceof W?u.message:String(u),spanId:b.spanId,providerIds:{requestId:$}}),r.gaps.push({category:"provider_usage",reason:"provider_usage_missing",detail:$})}else r.gaps.push({category:"provider_usage",reason:"provider_usage_missing",detail:$});O.push(b);for(const[u,s]of U(i).entries()){if(s.type==="thinking"&&c.thinking){const K=p(s.thinking??s.text);K&&h(b.outputRefs,A(l,m,P(a,"thinking","text",K)));continue}if(s.type==="text"&&c.inputOutput&&typeof s.text=="string"){h(b.outputRefs,A(l,m,P(a,"assistant_text","text",s.text)));continue}if(s.type!=="toolCall"||!c.tools)continue;const v=p(s.id),f=v??`missing-id-${g}-${a.sourceOffset}-${u}`;v||(y.push({code:"pi_tool_call_id_missing",message:`Tool call in message ${g} has no id`,providerIds:{messageId:g}}),r.gaps.push({category:"tool_call",reason:"correlation_failed",detail:`${g}:missing_id`}));const C=p(s.name)??"tool";C==="tool"&&y.push({code:"pi_tool_name_missing",message:`Tool call ${f} has no name`,providerIds:{toolCallId:f,messageId:g}});const k=L({job:t,spanId:`pi:${t.sessionId}:tool:${f}`,parentSpanId:b.spanId,kind:"tool_call",name:C,sequence:R++,status:"running",startedAt:x,endedAt:t.endedAt,nativeEventType:"toolCall",nativeIds:{toolCallId:f,messageId:g,requestId:$},rawAttributes:{sourcePath:a.sourcePath,sourceOffset:a.sourceOffset,hasResult:!1,...v?{}:{syntheticToolCallId:!0}}});Object.hasOwn(s,"arguments")?h(k.inputRefs,A(l,m,P(a,"tool_arguments","json",B(s.arguments)))):(y.push({code:"pi_tool_arguments_missing",message:`Tool call ${f} has no arguments payload`,providerIds:{toolCallId:f,messageId:g}}),r.gaps.push({category:"tool_arguments",reason:"correlation_failed",detail:f})),O.push(k),q.set(f,{span:k,resultSeen:!1})}d=x}for(const[a,o]of q)o.resultSeen||(y.push({code:"pi_tool_result_missing",message:`Tool call ${a} has no result in the audited boundary`,spanId:o.span.spanId,providerIds:{toolCallId:a}}),r.gaps.push({category:"tool_result",reason:"correlation_failed",detail:a}));return{spans:O,contents:l,anomalies:y,collection:r,capture:c}}async correlate(t,n){return n}validate(t,n){const r=n,c=r.spans.filter(_=>_.kind==="llm_request"),y=r.spans.filter(_=>_.kind==="tool_call"),l=!r.capture.inputOutput||t.input!==void 0,m=!r.capture.inputOutput||t.finalOutput!==void 0||r.contents.some(_=>_.role==="assistant_text"),O=Q(y,r.capture.tools),R=O.complete,S=!0,w=c.length>0&&c.every(_=>_.usage?.completeness==="complete"),d=!1,I=V([...r.collection.gaps,...O.gaps]);r.capture.rawProviderBody&&I.push({category:"raw_provider_body",reason:"raw_capture_disabled",detail:"Pi transcript does not retain raw provider request bodies"});const q=l&&m&&R&&S&&w&&(!r.capture.rawProviderBody||d)&&I.length===0,M=r.collection.lines.length===0,F=c.length===0;return{status:M||F?"failed":q?"complete":"partial",inputComplete:l,outputComplete:m,toolCallsComplete:R,subagentsComplete:S,usageComplete:w,rawRequestsComplete:d,gaps:I}}}export{ae as PiAuditAdapter};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
function u(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function m(e,r,t){return e===void 0?{value:t}:typeof e!="boolean"?{error:`audit.${r} must be a boolean`}:{value:e}}function y(e,r,t){return e[r]??e[t]}function w(e){return e==="usage"?{inputOutput:!1,tools:!1,subagents:!0,thinking:!1,rawProviderBody:!1}:{inputOutput:!0,tools:!0,subagents:!0,thinking:!1,rawProviderBody:!1}}function l(e){if(!e.enabled)return Object.freeze({enabled:!1});const r=Object.freeze({...e.capture});return Object.freeze({enabled:!0,scope:e.scope,profile:e.profile,capture:r,...e.retentionDays===void 0?{}:{retentionDays:e.retentionDays}})}function j(e){if(!u(e))return{state:"absent"};const r=u(e.extra)?e.extra:void 0,t=e.audit??r?.audit;if(t===void 0)return{state:"absent"};if(!u(t))return{error:"audit must be an object"};if(typeof t.enabled!="boolean")return{error:"audit.enabled must be a boolean"};if(!t.enabled)return{state:"disabled",options:l({enabled:!1})};const i=t.scope??"session";if(i!=="session"&&i!=="turn")return{error:'audit.scope must be "session" or "turn"'};if(i==="turn")return{state:"enabled",options:l({enabled:!0,scope:"turn",profile:"
|
|
1
|
+
function u(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function m(e,r,t){return e===void 0?{value:t}:typeof e!="boolean"?{error:`audit.${r} must be a boolean`}:{value:e}}function y(e,r,t){return e[r]??e[t]}function w(e){return e==="usage"?{inputOutput:!1,tools:!1,subagents:!0,thinking:!1,rawProviderBody:!1}:{inputOutput:!0,tools:!0,subagents:!0,thinking:!1,rawProviderBody:!1}}function l(e){if(!e.enabled)return Object.freeze({enabled:!1});const r=Object.freeze({...e.capture});return Object.freeze({enabled:!0,scope:e.scope,profile:e.profile,capture:r,...e.retentionDays===void 0?{}:{retentionDays:e.retentionDays}})}function j(e){if(!u(e))return{state:"absent"};const r=u(e.extra)?e.extra:void 0,t=e.audit??r?.audit;if(t===void 0)return{state:"absent"};if(!u(t))return{error:"audit must be an object"};if(typeof t.enabled!="boolean")return{error:"audit.enabled must be a boolean"};if(!t.enabled)return{state:"disabled",options:l({enabled:!1})};const i=t.scope??"session";if(i!=="session"&&i!=="turn")return{error:'audit.scope must be "session" or "turn"'};if(i==="turn")return{state:"enabled",options:l({enabled:!0,scope:"turn",profile:"full",capture:{inputOutput:!0,tools:!0,subagents:!0,thinking:!1,rawProviderBody:!0}})};const o=t.profile??"replay";if(o!=="usage"&&o!=="replay"&&o!=="full")return{error:"audit.profile must be usage, replay, or full"};const c=w(o),s=t.capture;if(s!==void 0&&!u(s))return{error:"audit.capture must be an object"};const g=s??{},O=[["inputOutput","input_output"],["tools","tools"],["subagents","subagents"],["thinking","thinking"],["rawProviderBody","raw_provider_body"]],p={...c};for(const[d,b]of O){const f=m(y(g,d,b),`capture.${b}`,c[d]);if(f.error)return{error:f.error};p[d]=f.value}const n=y(t,"retentionDays","retention_days");let a;if(n!==void 0){if(typeof n!="number"||!Number.isInteger(n)||n<1||n>365)return{error:"audit.retention_days must be an integer between 1 and 365"};a=n}return{state:"enabled",options:l({enabled:!0,scope:"session",profile:o,capture:p,...a===void 0?{}:{retentionDays:a}})}}function k(e){if(!u(e))return e;const r={...e};if(delete r.audit,u(e.extra)&&Object.hasOwn(e.extra,"audit")){const t={...e.extra};delete t.audit,r.extra=t}return Object.keys(r).length===0?void 0:r}export{j as extractAuditOptions,l as freezeAuditOptions,k as stripAuditOptions};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{randomUUID as
|
|
2
|
-
${e.platformEventId}`,u=this.turnContexts.get(
|
|
3
|
-
`)&&this.turnContexts.delete(t);return this.sessions.delete(e)}clear(){this.sessions.clear(),this.turnContexts.clear()}}export{
|
|
1
|
+
import{randomUUID as x}from"node:crypto";import{freezeAuditOptions as v}from"./audit-options.js";class d extends Error{constructor(e,t){super(`Audit configuration conflict for session ${e}: ${t}`),this.name="AuditSessionConfigConflictError"}}class p extends Error{constructor(e){super(e),this.name="AuditSessionOptionsError"}}function b(i,e){return i.profile===e.profile&&i.scope===e.scope&&i.retentionDays===e.retentionDays&&i.capture.inputOutput===e.capture.inputOutput&&i.capture.tools===e.capture.tools&&i.capture.subagents===e.capture.subagents&&i.capture.thinking===e.capture.thinking&&i.capture.rawProviderBody===e.capture.rawProviderBody}function f(i){if(i.state!=="enabled"||!i.options?.enabled)throw new p("Enabled audit settings are missing");return i.options}class w{static MAX_TURN_CONTEXTS=256;sessions=new Map;turnContexts=new Map;adapterPreparationContexts=new Map;createAuditId;now;constructor(e={}){this.createAuditId=e.createAuditId??(()=>`audit-${x()}`),this.now=e.now??(()=>new Date().toISOString())}resolve(e){const{businessSessionId:t,provider:r,parsed:o}=e;if(o.error)throw new p(o.error);if(!o.state)throw new p("Audit settings have no parse state");const s=this.sessions.get(t);if(s&&s.provider!==r)throw new d(t,`provider changed from ${s.provider} to ${r}`);const n=this.adapterPreparationContexts.get(t);if(n&&n.provider!==r)throw new d(t,`provider changed from ${n.provider} to ${r}`);if(o.state==="absent"){if(s?.state==="enabled")return s.context;s||this.sessions.set(t,{state:"disabled",provider:r});return}if(o.state==="disabled"){if(s?.state==="enabled")throw new d(t,"auditing cannot be disabled after the session starts");s||this.sessions.set(t,{state:"disabled",provider:r});return}const a=f(o);if(s?.state==="disabled")throw new d(t,"auditing cannot be enabled after the session starts");if(s){if(!b(s.context.options,a))throw new d(t,"audit options changed after the session starts");return s.context}const c=v(a);if(!c.enabled)throw new p("Enabled audit settings normalized as disabled");const u=Object.freeze({auditId:this.createAuditId(),businessSessionId:t,provider:r,options:c,createdAt:this.now(),...e.providerSessionId===void 0?{}:{providerSessionId:e.providerSessionId}});return this.sessions.set(t,{state:"enabled",provider:r,context:u}),u}get(e){const t=this.sessions.get(e);return t?.state==="enabled"?t.context:void 0}getAdapterPreparation(e){return this.get(e)??this.adapterPreparationContexts.get(e)}prepareAdapter(e){const{businessSessionId:t,provider:r,parsed:o}=e;if(o.error)throw new p(o.error);const s=f(o);if(s.scope!=="turn")throw new p('Turn adapter preparation requires audit.scope "turn"');const n=this.sessions.get(t);if(n&&n.provider!==r)throw new d(t,`provider changed from ${n.provider} to ${r}`);if(n?.state==="enabled")return n.context;const a=this.adapterPreparationContexts.get(t);if(a&&a.provider!==r)throw new d(t,`provider changed from ${a.provider} to ${r}`);if(a)return a;const c=Object.freeze({auditId:this.createAuditId(),businessSessionId:t,provider:r,options:s,createdAt:this.now(),...e.providerSessionId===void 0?{}:{providerSessionId:e.providerSessionId}});return this.rememberAdapterPreparation(c),c}resolveTurn(e){const{businessSessionId:t,provider:r,parsed:o}=e;if(o.error)throw new p(o.error);if(o.state!=="enabled")throw new p("Turn-scoped audit requires enabled audit settings");const s=f(o);if(s.scope!=="turn")throw new p('Turn-scoped audit requires audit.scope "turn"');const n=this.sessions.get(t);if(n&&n.provider!==r)throw new d(t,`provider changed from ${n.provider} to ${r}`);if(n?.state==="enabled")return n.context;const a=this.adapterPreparationContexts.get(t);if(a&&a.provider!==r)throw new d(t,`provider changed from ${a.provider} to ${r}`);const c=`${t}
|
|
2
|
+
${e.platformEventId}`,u=this.turnContexts.get(c);if(u)return u;const h=Object.freeze({auditId:this.createAuditId(),businessSessionId:t,provider:r,options:s,createdAt:this.now(),...e.providerSessionId===void 0?{}:{providerSessionId:e.providerSessionId}});if(this.turnContexts.size>=w.MAX_TURN_CONTEXTS){const l=this.turnContexts.keys().next();l.done||this.turnContexts.delete(l.value)}return this.turnContexts.set(c,h),this.rememberAdapterPreparation(h),h}delete(e){for(const t of this.turnContexts.keys())t.startsWith(`${e}
|
|
3
|
+
`)&&this.turnContexts.delete(t);return this.adapterPreparationContexts.delete(e),this.sessions.delete(e)}clear(){this.sessions.clear(),this.turnContexts.clear(),this.adapterPreparationContexts.clear()}rememberAdapterPreparation(e){const t=e.businessSessionId;if(this.adapterPreparationContexts.has(t))this.adapterPreparationContexts.delete(t);else if(this.adapterPreparationContexts.size>=w.MAX_TURN_CONTEXTS){const r=this.adapterPreparationContexts.keys().next();r.done||this.adapterPreparationContexts.delete(r.value)}this.adapterPreparationContexts.set(t,e)}}export{d as AuditSessionConfigConflictError,p as AuditSessionOptionsError,w as AuditSessionRegistry};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{rollupUniqueRequestUsage as
|
|
1
|
+
import{rollupUniqueRequestUsage as g}from"./usage.js";import{contentReferenceKey as l,referenceCaptureContent as f}from"./content-reference.js";class w{adapters=new Map;register(e){if(this.adapters.has(e.provider))throw new Error(`Audit adapter already registered: ${e.provider}`);this.adapters.set(e.provider,e)}resolve(e){const r=this.adapters.get(e);if(!r)throw new Error(`Audit adapter not registered: ${e}`);return r}}class R{registry;store;constructor(e,r){this.registry=e,this.store=r}async finalize(e){const r=await this.store.get(e.auditId,e.turnId);if(r?.sourceJobId===e.jobId||r&&e.triggeredBy!=="late_event"&&e.triggeredBy!=="manual_reconcile")return r;const n=this.registry.resolve(e.provider),i=await n.collect(e),a=await n.normalize(e,i),d=await n.correlate(e,a),m=n.validate(e,d),u=y(e,d.spans),v=u.filter(s=>s.kind==="llm_request"&&s.usage).map(s=>({requestId:s.provider.nativeIds.requestId??s.provider.nativeIds.messageId??s.spanId,usage:s.usage})),o=e.options?.enabled?e.options.retentionDays:void 0,c=r?.retentionUntil??(o&&Number.isFinite(Date.parse(e.endedAt))?new Date(Date.parse(e.endedAt)+o*24*60*60*1e3).toISOString():void 0),p={schemaVersion:1,revision:(r?.revision??0)+1,sourceJobId:e.jobId,revisionTrigger:e.triggeredBy??"turn_closed",auditId:e.auditId,traceId:e.traceId,turnId:e.turnId,sessionId:e.sessionId,provider:e.provider,startedAt:e.startedAt,endedAt:e.endedAt,outcome:e.outcome,input:e.input,finalOutput:e.finalOutput,spans:u,contents:d.contents,usage:g(v,e.provider),quality:m,anomalies:d.anomalies,finalizedAt:new Date().toISOString(),...c?{retentionUntil:c}:{}};return await this.store.save(p,e.options),await n.cleanup?.(e,i).catch(()=>{}),p}}function y(t,e){const r=e.map(i=>({...i,inputRefs:[...i.inputRefs],outputRefs:[...i.outputRefs]}));let n=r.find(i=>i.kind==="turn");if(!n){const i=Date.parse(t.startedAt),a=Date.parse(t.endedAt);n={spanId:`${t.provider}:${t.turnId}:turn`,traceId:t.traceId,turnId:t.turnId,sessionId:t.sessionId,kind:"turn",name:`${t.provider} audited turn`,sequence:0,status:t.outcome==="completed"?"completed":t.outcome==="cancelled"?"cancelled":"failed",startedAt:t.startedAt,endedAt:t.endedAt,...Number.isFinite(i)&&Number.isFinite(a)?{durationMs:Math.max(0,a-i)}:{},inputRefs:[],outputRefs:[],provider:{provider:t.provider,nativeIds:{platformEventId:typeof t.boundary.platformEventId=="string"?t.boundary.platformEventId:t.turnId}},provenance:{source:"connector",accuracy:"runtime_exact"}},r.unshift(n)}return t.input&&I(n.inputRefs,f(t.input)),t.finalOutput&&I(n.outputRefs,f(t.finalOutput)),r}function I(t,e){if(!e)return;const r=l(e);t.some(n=>l(n)===r)||t.push(e)}export{w as AuditAdapterRegistry,R as ReplayFinalizer};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
function l(e){return e.inputRefs.some(t=>t.role==="tool_arguments")}function s(e){return e.outputRefs.some(t=>t.role==="tool_result")}function u(e,t){if(!t)return{complete:!0,gaps:[]};const o=[];for(const n of e){if(n.kind!=="tool_call")continue;const r=a(n);(!n.name.trim()||n.name==="tool")&&o.push({category:"tool_name",reason:"correlation_failed",detail:r}),l(n)||o.push({category:"tool_arguments",reason:"correlation_failed",detail:r}),n.status==="running"?o.push({category:"tool_result",reason:"correlation_failed",detail:`${r}:non_terminal`}):n.status!=="cancelled"&&!s(n)&&o.push({category:"tool_result",reason:"correlation_failed",detail:r})}return{complete:o.length===0,gaps:i(o)}}function a(e){return e.provider.nativeIds.toolCallId??e.provider.nativeIds.messageId??e.spanId}function c(e,t){t&&(e.some(o=>o.contentId===t.contentId&&o.role===t.role)||e.push(t))}function i(e){const t=new Set;return e.filter(o=>{const n=`${o.category}\0${o.reason}\0${o.detail??""}`;return t.has(n)?!1:(t.add(n),!0)})}export{c as appendUniqueReference,u as assessToolCallCompleteness,i as deduplicateGaps,l as hasToolArguments,s as hasToolResult,a as toolCallIdentity};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{AuditSessionConfigConflictError as l,AuditSessionOptionsError as p,AuditSessionRegistry as h}from"../core/audit-session-registry.js";import{AuditTurnLifecycle as g}from"../core/audit-turn-lifecycle.js";import{extractAuditOptions as I,stripAuditOptions as m}from"../core/audit-options.js";import{assertTurnScopeSupported as
|
|
1
|
+
import{AuditSessionConfigConflictError as l,AuditSessionOptionsError as p,AuditSessionRegistry as h}from"../core/audit-session-registry.js";import{AuditTurnLifecycle as g}from"../core/audit-turn-lifecycle.js";import{extractAuditOptions as I,stripAuditOptions as m}from"../core/audit-options.js";import{assertTurnScopeSupported as v,AuditPreparationFailedError as y,AuditTurnScopeUnsupportedError as S}from"../core/audit-state.js";import{AUDIT_ERROR_CODES as a}from"../core/types.js";class w{registry;lifecycle;onAuditState;outputs=new Map;recordingNotified=new Set;constructor(e,r={}){this.registry=r.registry??new h,this.onAuditState=r.onAuditState,this.lifecycle=r.lifecycle??new g(e,{listener:{onTurnAccepted:t=>{this.emitFromContext("accepted",t)},onTurnDispatched:(t,s)=>{this.recordingNotified.delete(t.platformEventId),s?this.emitFromContext("finalizing",t):this.emitFromContext("failed",t,{errorCode:a.queueFull,errorMessage:"Audit recorder queue rejected the replay job"})}}})}resolveSession(e){const r=I(e.extra),t=this.resolveParsedSession(e,r);return{parsed:r,session:t,sanitizedExtra:m(e.extra)}}getSession(e){return this.registry.get(e)}getAdapterPreparation(e){return this.registry.getAdapterPreparation(e)}startTurn(e){if(!e.session)return;const r=e.session.options.capture.inputOutput,t=r?{role:"user_input",format:"text",value:e.userInput,captureLevel:"runtime_exact"}:void 0,s=this.lifecycle.startTurn({session:e.session,platformEventId:e.eventId,...e.originMsgId===void 0?{}:{originMsgId:e.originMsgId},...e.startedAt===void 0?{}:{startedAt:e.startedAt},...t===void 0?{}:{input:t},boundary:{platformEventId:e.eventId,...e.originMsgId===void 0?{}:{originMsgId:e.originMsgId},...e.boundary}});if(s)return r&&!this.outputs.has(e.eventId)&&this.outputs.set(e.eventId,{chunks:new Map}),s}markRecording(e){if(this.recordingNotified.has(e))return;const r=this.lifecycle.getTurn(e);r&&(this.recordingNotified.add(e),this.emitFromContext("recording",r))}handleJobSettled(e,r){const t=typeof e.boundary.platformEventId=="string"?e.boundary.platformEventId:e.turnId;if(!this.lifecycle.ownsTurn(t))return;const s=typeof e.boundary.originMsgId=="string"?e.boundary.originMsgId:void 0,i={eventId:t,sessionId:e.sessionId,auditId:e.auditId,turnId:e.turnId,...s===void 0?{}:{msgId:s}};if(!r.ok){this.emit({...i,state:"failed",errorCode:a.finalizeFailed,...r.error===void 0?{}:{errorMessage:r.error}});return}const o=r.quality??"complete";this.emit({...i,state:o==="complete"?"ready":"partial",quality:o,...r.revision===void 0?{}:{revision:r.revision},...r.truncated===void 0?{}:{truncated:r.truncated}})}captureReply(e,r){const t=this.outputs.get(e);!t||!r||(t.reply=r)}captureStreamChunk(e,r,t){const s=this.outputs.get(e);!s||s.reply!==void 0||!t||s.chunks.has(r)||s.chunks.set(r,t)}captureUnsequencedStreamChunk(e,r){const t=this.outputs.get(e);if(!t||t.reply!==void 0||!r)return;const s=t.chunks.size===0?1:Math.max(...t.chunks.keys())+1;t.chunks.set(s,r)}markResponded(e,r,t,s){const i=this.outputs.get(e),o=i?.reply??(i?[...i.chunks.entries()].sort(([d],[f])=>d-f).map(([,d])=>d).join(""):""),u=i?o||(r==="responded"?"":t??""):"",c=this.lifecycle.markResponded({platformEventId:e,outcome:A(r),...u?{finalOutput:{role:"final_response",format:"text",value:u,captureLevel:"runtime_exact"}}:{},...s===void 0?{}:{boundary:s}});return this.outputs.delete(e),c}markAdapterClosed(e,r){return this.lifecycle.markAdapterClosed({platformEventId:e,...r===void 0?{}:{boundary:r}})}closeWithoutAdapter(e,r,t,s){this.markResponded(e,r,t,s),this.markAdapterClosed(e,{...s,adapterNotStarted:!0})}deleteSession(e){return this.registry.delete(e)}dispose(){this.outputs.clear(),this.recordingNotified.clear(),this.lifecycle.dispose(),this.registry.clear()}resolveParsedSession(e,r){if(r.state==="enabled"&&r.options?.enabled&&r.options.scope==="turn"){v(e.provider);try{if(!e.eventId){this.registry.prepareAdapter({businessSessionId:e.sessionId,provider:e.provider,parsed:r,...e.providerSessionId===void 0?{}:{providerSessionId:e.providerSessionId}});return}return this.registry.resolveTurn({businessSessionId:e.sessionId,platformEventId:e.eventId,provider:e.provider,parsed:r,...e.providerSessionId===void 0?{}:{providerSessionId:e.providerSessionId}})}catch(t){throw t instanceof p||t instanceof l||t instanceof S?t:new y(t instanceof Error?t.message:String(t))}}return this.registry.resolve({businessSessionId:e.sessionId,provider:e.provider,parsed:r,...e.providerSessionId===void 0?{}:{providerSessionId:e.providerSessionId}})}emitFromContext(e,r,t={}){this.emit({state:e,eventId:r.platformEventId,sessionId:r.sessionId,auditId:r.auditId,turnId:r.turnId,...r.originMsgId===void 0?{}:{msgId:r.originMsgId},...t})}emit(e){try{this.onAuditState?.(e)}catch{}}}function A(n){return n==="responded"?"completed":n==="canceled"?"cancelled":"failed"}export{w as BridgeAuditController};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{fork as c}from"node:child_process";import{randomUUID as o}from"node:crypto";import{fileURLToPath as f}from"node:url";import{AUDIT_RECORDER_PROTOCOL_VERSION as p,isAuditRecorderChildMessage as m}from"../worker/audit-recorder-ipc-protocol.js";const w=128,y=3,
|
|
1
|
+
import{fork as c}from"node:child_process";import{randomUUID as o}from"node:crypto";import{fileURLToPath as f}from"node:url";import{AUDIT_RECORDER_PROTOCOL_VERSION as p,isAuditRecorderChildMessage as m}from"../worker/audit-recorder-ipc-protocol.js";const w=128,y=3,k=1e3,v=5e3;class R{workerConfig;workerPath;maxQueueSize;maxDeliveryAttempts;restartDelayMs;onDiagnostic;jobSettledHandlers=new Set;queue=[];flushWaiters=new Map;child;childReady=!1;active;spawnScheduled=!1;restartTimer;workerFlushRequestId;shutdownWaiter;deliverySequence=0;accepting=!0;closing=!1;stopped=!1;stopPromise;constructor(e){this.maxQueueSize=n(e.maxQueueSize,w,"maxQueueSize"),this.maxDeliveryAttempts=n(e.maxDeliveryAttempts,y,"maxDeliveryAttempts"),this.restartDelayMs=g(e.restartDelayMs,k,"restartDelayMs"),this.workerConfig={...e.workerConfig},this.workerPath=e.workerPath??f(new URL("../worker/audit-recorder-worker-entry.js",import.meta.url)),this.onDiagnostic=e.onDiagnostic}get pendingCount(){return this.queue.length+(this.active?1:0)}addJobSettledHandler(e){this.jobSettledHandlers.add(e)}tryEnqueue(e){try{return!this.accepting||this.closing||this.stopped?!1:this.pendingCount>=this.maxQueueSize?(this.diagnostic({type:"queue_full",message:`Audit Recorder queue is full (${this.maxQueueSize})`,pendingCount:this.pendingCount,jobId:e.jobId}),!1):(this.deliverySequence+=1,this.queue.push({deliveryId:`${e.jobId}:${this.deliverySequence}`,job:e,attempts:0}),this.wakeWorker(),!0)}catch{return!1}}flush(e={}){try{if(this.stopped)return Promise.resolve(this.pendingCount===0);const t=a(e.timeoutMs),i=o(),r=new Promise(h=>{const d=setTimeout(()=>{const l=this.flushWaiters.get(i);l&&(this.flushWaiters.delete(i),l.resolve(!1))},t);d.unref?.(),this.flushWaiters.set(i,{resolve:h,timer:d})});return this.pendingCount>0&&this.wakeWorker(),this.settleFlushWaiters(),r}catch{return Promise.resolve(!1)}}stop(e={}){if(this.stopPromise)return this.stopPromise;this.accepting=!1;const t=a(e.timeoutMs);return this.stopPromise=this.performStop(t).catch(()=>!1),this.stopPromise}async performStop(e){const t=await this.flush({timeoutMs:e});this.closing=!0,this.clearRestartTimer();let i=t;return t&&this.child&&this.childReady?i=await this.requestWorkerStop(e):this.child&&(i=!1,this.terminateChild(this.child)),this.stopped=!0,this.childReady=!1,this.queue.length=0,this.active=void 0,this.resolveFlushWaiters(!1),this.child&&!i&&this.terminateChild(this.child),t&&i}wakeWorker(){this.pump(),this.scheduleWorker()}scheduleWorker(){this.stopped||this.closing||this.child||this.spawnScheduled||this.restartTimer||this.pendingCount===0||(this.spawnScheduled=!0,queueMicrotask(()=>{this.spawnScheduled=!1,this.ensureWorker()}))}ensureWorker(){if(this.stopped||this.closing||this.child||this.pendingCount===0)return;let e;try{e=c(this.workerPath,[],{stdio:["ignore","ignore","ignore","ipc"],serialization:"json"})}catch(t){this.diagnostic({type:"worker_error",message:u(t)}),this.scheduleRestart();return}this.child=e,this.childReady=!1,e.on("message",t=>{this.child===e&&this.handleChildMessage(t)}),e.once("error",t=>{this.workerUnavailable(e,"worker_error",u(t))}),e.once("exit",(t,i)=>{const r=i?`signal ${i}`:`exit code ${t??"unknown"}`;this.workerUnavailable(e,"worker_exit",r)}),e.once("disconnect",()=>{this.workerUnavailable(e,"worker_exit","IPC channel disconnected")}),this.sendToChild({type:"audit_recorder_initialize",protocolVersion:p,config:this.workerConfig})}handleChildMessage(e){if(m(e))switch(e.type){case"audit_recorder_ready":this.childReady=!0,this.pump(),this.settleFlushWaiters();return;case"audit_recorder_job_result":this.handleJobResult(e);return;case"audit_recorder_flushed":if(e.requestId!==this.workerFlushRequestId)return;this.workerFlushRequestId=void 0,this.resolveFlushWaiters(!0);return;case"audit_recorder_stopped":if(e.requestId!==this.shutdownWaiter?.requestId)return;this.shutdownWaiter.acknowledged=!0;return;case"audit_recorder_fatal":{const t=this.child;this.diagnostic({type:"worker_fatal",message:e.error}),t&&(this.workerUnavailable(t,"worker_fatal",e.error),this.terminateChild(t));return}}}handleJobResult(e){const t=this.active;!t||t.deliveryId!==e.deliveryId||(this.active=void 0,e.ok?this.settle(t.job,{ok:!0,...e.revision===void 0?{}:{revision:e.revision},...e.quality===void 0?{}:{quality:e.quality},...e.truncated===void 0?{}:{truncated:e.truncated}}):(this.diagnostic({type:"job_failed",message:e.error??"Audit replay finalization failed",jobId:t.job.jobId,deliveryId:t.deliveryId}),e.retryable&&t.attempts<this.maxDeliveryAttempts?this.queue.unshift(t):e.retryable?this.dropDelivery(t,e.error??"retry limit reached"):this.settle(t.job,{ok:!1,error:e.error??"Audit replay finalization failed"})),this.pump(),this.settleFlushWaiters())}pump(){if(!this.child||!this.childReady||this.active||this.stopped||this.closing)return;const e=this.queue.shift();if(!e){this.settleFlushWaiters();return}if(e.attempts+=1,this.active=e,!this.sendToChild({type:"audit_recorder_job",deliveryId:e.deliveryId,job:e.job})){const t=this.child;t&&(this.workerUnavailable(t,"worker_error","Unable to send audit job to Recorder"),this.terminateChild(t))}}settleFlushWaiters(){if(this.flushWaiters.size===0||this.pendingCount>0)return;if(!this.child||!this.childReady){this.resolveFlushWaiters(!0);return}if(this.workerFlushRequestId)return;const e=o();if(this.workerFlushRequestId=e,!this.sendToChild({type:"audit_recorder_flush",requestId:e})){this.workerFlushRequestId=void 0;const t=this.child;t?(this.workerUnavailable(t,"worker_error","Unable to flush audit Recorder"),this.terminateChild(t)):this.resolveFlushWaiters(!0)}}resolveFlushWaiters(e){for(const[t,i]of this.flushWaiters)clearTimeout(i.timer),this.flushWaiters.delete(t),i.resolve(e)}requestWorkerStop(e){const t=this.child;if(!t||!this.childReady)return Promise.resolve(!0);const i=o();return new Promise(r=>{const h=setTimeout(()=>{this.shutdownWaiter?.requestId===i&&(this.shutdownWaiter=void 0,this.terminateChild(t),r(!1))},e);h.unref?.(),this.shutdownWaiter={requestId:i,acknowledged:!1,resolve:r,timer:h},this.sendToChild({type:"audit_recorder_stop",requestId:i})||(clearTimeout(h),this.shutdownWaiter=void 0,this.terminateChild(t),r(!1))})}sendToChild(e){const t=this.child;if(!t?.connected)return!1;try{return t.send(e,i=>{!i||this.child!==t||(this.workerUnavailable(t,"worker_error",i.message),this.terminateChild(t))}),!0}catch{return!1}}workerUnavailable(e,t,i){if(this.child!==e)return;if(this.child=void 0,this.childReady=!1,this.workerFlushRequestId=void 0,this.active){const h=this.active;this.active=void 0,h.attempts<this.maxDeliveryAttempts?this.queue.unshift(h):this.dropDelivery(h,i)}t!=="worker_fatal"&&this.diagnostic({type:t,message:i});const r=this.shutdownWaiter;r&&(clearTimeout(r.timer),this.shutdownWaiter=void 0,r.resolve(r.acknowledged)),this.pendingCount>0&&!this.closing&&!this.stopped?this.scheduleRestart():this.settleFlushWaiters()}scheduleRestart(){this.restartTimer||this.child||this.stopped||this.closing||this.pendingCount===0||(this.restartTimer=setTimeout(()=>{this.restartTimer=void 0,this.scheduleWorker()},this.restartDelayMs),this.restartTimer.unref?.())}clearRestartTimer(){this.restartTimer&&(clearTimeout(this.restartTimer),this.restartTimer=void 0)}dropDelivery(e,t){this.diagnostic({type:"job_dropped",message:t,jobId:e.job.jobId,deliveryId:e.deliveryId}),this.settle(e.job,{ok:!1,error:t})}settle(e,t){for(const i of this.jobSettledHandlers)try{i(e,t)}catch{}}terminateChild(e){try{e.kill("SIGTERM")}catch{}}diagnostic(e){try{this.onDiagnostic?.(e)}catch{}}}function n(s,e,t){const i=s??e;if(!Number.isSafeInteger(i)||i<=0)throw new Error(`${t} must be a positive integer`);return i}function g(s,e,t){const i=s??e;if(!Number.isSafeInteger(i)||i<0)throw new Error(`${t} must be a non-negative integer`);return i}function a(s){return n(s,v,"timeoutMs")}function u(s){return s instanceof Error?s.message:typeof s=="string"?s:"Unknown Recorder process error"}export{R as IpcAuditProducer};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createHmac as x,randomBytes as B,timingSafeEqual as L}from"node:crypto";import{LOCAL_ACTION_TYPES as v}from"../../adapter/claude/protocol-contract.js";import{AUDIT_LOCAL_ACTION_ERROR_CODES as F,AUDIT_LOCAL_ACTION_TYPES as P}from"../../core/aibot/types.js";import{AuditContentCorruptError as D,AuditContentNotFoundError as V}from"../storage/file-audit-replay-store.js";const j=100,z=200,S=131072,$=4,E=1,H=B(32),o=F;class ot{query;constructor(e){this.query=e}async handle(e,n){try{switch(e){case v.auditGetManifest:return{status:"ok",result:await this.getManifest(n)};case v.auditListSpans:return{status:"ok",result:await this.listSpans(n)};case v.auditGetContentChunk:return{status:"ok",result:await this.getContentChunk(n)};default:return p(o.invalidParams,"Unsupported audit local action")}}catch(r){return Z(r)}}async getManifest(e){const n=A(e),{view:r,revision:a}=await this.resolveView(n),{replay:i}=r;return{audit_id:i.auditId,turn_id:i.turnId,revision:a,session_id:i.sessionId,provider:i.provider,...k(r.timeline)?{model_id:k(r.timeline)}:{},status:i.outcome,started_at:i.startedAt,completed_at:i.finalizedAt,quality:J(i),truncated:K(i),statistics:X(r.statistics.totalUsage,r.statistics),has_spans:r.timeline.length>0,content_refs:T(i).map(b)}}async listSpans(e){const n=C(e),r=A(n),a=g(n.limit,{defaultValue:j,min:1,max:z,field:"limit"}),{view:i,revision:d}=await this.resolveView(r),u=R(n.cursor,{kind:"spans",auditId:i.replay.auditId,turnId:i.replay.turnId,revision:d});if(u>i.timeline.length)throw new s(o.cursorInvalid,"Audit cursor is out of range");const c=i.timeline.slice(u,u+a).map(G),l=u+c.length,f=l<i.timeline.length;return{items:c,next_cursor:f?N({kind:"spans",auditId:i.replay.auditId,turnId:i.replay.turnId,revision:d,position:l}):null,has_more:f}}async getContentChunk(e){const n=C(e),r=A(n),a=h(n.content_id,"content_id"),i=g(n.max_bytes,{defaultValue:S,min:$,max:S,field:"max_bytes"}),{view:d,revision:u}=await this.resolveView(r),l=T(d.replay).find(U=>U.contentId===a);if(!l)throw new s(o.contentForbidden,"Requested content does not belong to this audit turn");const f=a,y=R(n.cursor,{kind:"content",auditId:d.replay.auditId,turnId:d.replay.turnId,revision:u,contentId:a,etag:f}),m=await this.query.readContentChunk(a,y,i);if(m.totalBytes!==l.byteSize)throw new s(o.contentCorrupt,"Audit content size does not match its manifest");const _=Q(m.bytes);if(m.bytes.length>0&&_.length===0)throw new s(o.contentCorrupt,"Audit content is not valid UTF-8");const I=y+_.length,w=I===m.totalBytes;if(I>m.totalBytes||!w&&_.length===0)throw new s(o.contentCorrupt,"Audit content range is corrupt");return{content_id:a,mime:l.mimeType??O(l.format),encoding:"utf-8",value:W(_),byte_start:y,byte_end:I,total_bytes:m.totalBytes,next_cursor:w?null:N({kind:"content",auditId:d.replay.auditId,turnId:d.replay.turnId,revision:u,position:I,contentId:a,etag:f}),eof:w,etag:f,revision:u}}async resolveView(e){const n=e.revision===void 0?await this.query.getTurn(e.auditId,e.turnId):await this.query.getTurnRevision(e.auditId,e.turnId,e.revision);if(!n)throw new s(e.revision===void 0?o.notFound:o.revisionNotFound,e.revision===void 0?"Audit turn was not found":"Audit turn revision was not found");if(n.replay.sessionId!==e.sessionId)throw new s(o.notFound,"Audit turn was not found for this session");return{view:n,revision:n.replay.revision}}}function it(t){return P.includes(t)}class s extends Error{code;constructor(e,n){super(n),this.code=e,this.name="AuditLocalActionError"}}function A(t){const e=C(t);return{sessionId:h(e.session_id,"session_id"),auditId:h(e.audit_id,"audit_id"),turnId:h(e.turn_id,"turn_id"),...e.revision===void 0?{}:{revision:g(e.revision,{min:1,max:Number.MAX_SAFE_INTEGER,field:"revision"})}}}function C(t){if(!t||typeof t!="object"||Array.isArray(t))throw new s(o.invalidParams,"Audit parameters must be an object");return t}function h(t,e){if(typeof t!="string")throw new s(o.invalidParams,`${e} is required`);const n=t.trim();if(!n||n.length>512)throw new s(o.invalidParams,`${e} is invalid`);return n}function g(t,e){if(t===void 0){if(e.defaultValue!==void 0)return e.defaultValue;throw new s(o.invalidParams,`${e.field} is required`)}if(typeof t!="number"||!Number.isSafeInteger(t)||t<e.min||t>e.max)throw new s(o.invalidParams,`${e.field} is invalid`);return t}function R(t,e){if(t==null||t==="")return 0;if(typeof t!="string"||t.length>4096)throw new s(o.cursorInvalid,"Audit cursor is invalid");const[n,r,...a]=t.split(".");if(!n||!r||a.length>0)throw new s(o.cursorInvalid,"Audit cursor is invalid");const i=M(n);if(!Y(r,i))throw new s(o.cursorInvalid,"Audit cursor is invalid");let d;try{d=JSON.parse(Buffer.from(n,"base64url").toString("utf8"))}catch{throw new s(o.cursorInvalid,"Audit cursor is invalid")}if(!d||typeof d!="object"||Array.isArray(d))throw new s(o.cursorInvalid,"Audit cursor is invalid");const u=d,c=u.position;if(u.v!==E||u.kind!==e.kind||u.auditId!==e.auditId||u.turnId!==e.turnId||u.revision!==e.revision||u.contentId!==e.contentId||u.etag!==e.etag||typeof c!="number"||!Number.isSafeInteger(c)||c<0)throw new s(o.cursorInvalid,"Audit cursor is invalid");return c}function N(t){const e=Buffer.from(JSON.stringify({v:E,...t}),"utf8").toString("base64url");return`${e}.${M(e)}`}function M(t){return x("sha256",H).update(t).digest("base64url")}function Y(t,e){const n=Buffer.from(t,"utf8"),r=Buffer.from(e,"utf8");return n.length===r.length&&L(n,r)}function T(t){const e=[t.input?.reference,t.finalOutput?.reference,...t.contents.map(r=>r.reference),...t.spans.flatMap(r=>[...r.inputRefs,...r.outputRefs])].filter(r=>r!==void 0),n=new Map;for(const r of e)n.has(r.contentId)||n.set(r.contentId,r);return[...n.values()].sort((r,a)=>r.contentId.localeCompare(a.contentId)||r.role.localeCompare(a.role))}function b(t){return{content_id:t.contentId,kind:t.role,mime:t.mimeType??O(t.format),bytes:t.byteSize,...t.charCount===void 0?{}:{chars:t.charCount}}}function G(t){return{span_id:t.spanId,trace_id:t.traceId,turn_id:t.turnId,session_id:t.sessionId,...t.parentSpanId?{parent_span_id:t.parentSpanId}:{},kind:t.kind,name:t.name,sequence:t.sequence,status:t.status,started_at:t.startedAt,...t.endedAt?{ended_at:t.endedAt}:{},...t.durationMs===void 0?{}:{duration_ms:t.durationMs},...t.modelId?{model_id:t.modelId}:{},input_refs:t.inputRefs.map(b),output_refs:t.outputRefs.map(b),...t.usage?{usage:q(t.usage)}:{},provider:{provider:t.provider.provider,...t.provider.nativeEventType?{native_event_type:t.provider.nativeEventType}:{},native_ids:{...t.provider.nativeIds}},provenance:{...t.provenance}}}function k(t){return t.find(e=>e.kind==="llm_request"&&e.modelId)?.modelId}function X(t,e){return{span_count:e.spanCount,span_counts:e.spanCounts.map(n=>({...n})),llm_request_count:e.llmRequestCount,tool_call_count:e.toolCallCount,subagent_call_count:e.subagentCallCount,llm_requests:e.llmRequests.map(n=>({span_id:n.spanId,name:n.name,sequence:n.sequence,started_at:n.startedAt,...n.endedAt?{ended_at:n.endedAt}:{},...n.durationMs===void 0?{}:{duration_ms:n.durationMs},status:n.status,...n.usage?{usage:q(n.usage)}:{}})),total_usage:q(t)}}function q(t){return{input:{...t.input},output:{...t.output},total_processed:t.totalProcessed,request_count:t.requestCount,accuracy:t.accuracy,completeness:t.completeness,provider:t.provider,normalization:{...t.normalization}}}function J(t){return{status:t.quality.status,input_complete:t.quality.inputComplete,output_complete:t.quality.outputComplete,tool_calls_complete:t.quality.toolCallsComplete,subagents_complete:t.quality.subagentsComplete,usage_complete:t.quality.usageComplete,raw_requests_complete:t.quality.rawRequestsComplete,gaps:t.quality.gaps.map(e=>({category:e.category,reason:e.reason}))}}function K(t){return T(t).some(e=>e.truncated)}function O(t){switch(t){case"json":return"application/json";case"jsonl":return"application/x-ndjson";case"binary":return"application/octet-stream";case"text":return"text/plain; charset=utf-8"}}function Q(t){for(let e=t.length;e>=0;e-=1){const n=t.subarray(0,e);try{return new TextDecoder("utf-8",{fatal:!0}).decode(n),n}catch{}}return Buffer.alloc(0)}function W(t){try{return new TextDecoder("utf-8",{fatal:!0}).decode(t)}catch{throw new s(o.contentCorrupt,"Audit content is not valid UTF-8")}}function Z(t){return t instanceof s?p(t.code,t.message):t instanceof V?p(o.contentNotFound,"Audit content was not found"):t instanceof D?p(o.contentCorrupt,"Audit content is corrupt"):p(o.internal,"Audit request could not be completed")}function p(t,e){return{status:"failed",errorCode:t,errorMsg:e.slice(0,256)}}export{ot as AuditLocalActionHandler,j as DEFAULT_AUDIT_SPAN_LIMIT,S as MAX_AUDIT_CONTENT_CHUNK_BYTES,z as MAX_AUDIT_SPAN_LIMIT,it as isAuditLocalActionType};
|
|
1
|
+
import{createHmac as H,randomBytes as J,timingSafeEqual as X}from"node:crypto";import{LOCAL_ACTION_TYPES as q}from"../../adapter/claude/protocol-contract.js";import{AUDIT_LOCAL_ACTION_ERROR_CODES as K,AUDIT_LOCAL_ACTION_TYPES as W}from"../../core/aibot/types.js";import{AuditContentCorruptError as Q,AuditContentNotFoundError as Z}from"../storage/file-audit-replay-store.js";import{analyzeRawProviderRequest as tt}from"../raw-capture/attribution.js";const P=100,B=200,U=131072,et=4,D=1,nt=J(32),d=K,z=new Set(["system_prompt","model_request","model_response"]);class ht{query;constructor(e){this.query=e}async handle(e,n){try{switch(e){case q.auditGetManifest:return{status:"ok",result:await this.getManifest(n)};case q.auditListSpans:return{status:"ok",result:await this.listSpans(n)};case q.auditListToolCalls:return{status:"ok",result:await this.listToolCalls(n)};case q.auditGetContentChunk:return{status:"ok",result:await this.getContentChunk(n)};default:return b(d.invalidParams,"Unsupported audit local action")}}catch(o){return _t(o)}}async getManifest(e){const n=T(e),{view:o,revision:r}=await this.resolveView(n),{replay:s}=o,c=E(s),u=$(s);return{audit_id:s.auditId,turn_id:s.turnId,revision:r,session_id:s.sessionId,provider:s.provider,...V(o.timeline)?{model_id:V(o.timeline)}:{},status:s.outcome,started_at:s.startedAt,completed_at:s.finalizedAt,quality:it(s,u),raw_api_capture:u,truncated:at(s),statistics:st(o.statistics.totalUsage,o.statistics,await ut(o.timeline,s,o.statistics.totalUsage,this.query)),has_spans:o.timeline.length>0,content_refs:c.map(g)}}async listSpans(e){const n=k(e),o=T(n),r=S(n.limit,{defaultValue:P,min:1,max:B,field:"limit"}),{view:s,revision:c}=await this.resolveView(o),u=N(n.cursor,{kind:"spans",auditId:s.replay.auditId,turnId:s.replay.turnId,revision:c});if(u>s.timeline.length)throw new p(d.cursorInvalid,"Audit cursor is out of range");const l=s.timeline.slice(u,u+r).map(rt),f=u+l.length,a=f<s.timeline.length;return{items:l,next_cursor:a?O({kind:"spans",auditId:s.replay.auditId,turnId:s.replay.turnId,revision:c,position:f}):null,has_more:a}}async listToolCalls(e){const n=k(e),o=T(n),r=S(n.limit,{defaultValue:P,min:1,max:B,field:"limit"}),{view:s,revision:c}=await this.resolveView(o),u=s.statistics.toolCalls,l=N(n.cursor,{kind:"tool_calls",auditId:s.replay.auditId,turnId:s.replay.turnId,revision:c});if(l>u.length)throw new p(d.cursorInvalid,"Audit cursor is out of range");const f=u.slice(l,l+r).map(j),a=l+f.length,y=a<u.length;return{items:f,next_cursor:y?O({kind:"tool_calls",auditId:s.replay.auditId,turnId:s.replay.turnId,revision:c,position:a}):null,has_more:y,total:u.length}}async getContentChunk(e){const n=k(e),o=T(n),r=R(n.content_id,"content_id"),s=S(n.max_bytes,{defaultValue:U,min:et,max:U,field:"max_bytes"}),{view:c,revision:u}=await this.resolveView(o),f=E(c.replay).find(x=>x.contentId===r);if(!f)throw new p(d.contentForbidden,"Requested content does not belong to this audit turn");const a=r,y=N(n.cursor,{kind:"content",auditId:c.replay.auditId,turnId:c.replay.turnId,revision:u,contentId:r,etag:a}),I=await this.query.readContentChunk(r,y,s);if(I.totalBytes!==f.byteSize)throw new p(d.contentCorrupt,"Audit content size does not match its manifest");const w=ct(I.bytes);if(I.bytes.length>0&&w.length===0)throw new p(d.contentCorrupt,"Audit content is not valid UTF-8");const v=y+w.length,C=v===I.totalBytes;if(v>I.totalBytes||!C&&w.length===0)throw new p(d.contentCorrupt,"Audit content range is corrupt");return{content_id:r,mime:f.mimeType??G(f.format),encoding:"utf-8",value:lt(w),byte_start:y,byte_end:v,total_bytes:I.totalBytes,next_cursor:C?null:O({kind:"content",auditId:c.replay.auditId,turnId:c.replay.turnId,revision:u,position:v,contentId:r,etag:a}),eof:C,etag:a,revision:u}}async resolveView(e){const n=e.revision===void 0?await this.query.getTurn(e.auditId,e.turnId):await this.query.getTurnRevision(e.auditId,e.turnId,e.revision);if(!n)throw new p(e.revision===void 0?d.notFound:d.revisionNotFound,e.revision===void 0?"Audit turn was not found":"Audit turn revision was not found");if(n.replay.sessionId!==e.sessionId)throw new p(d.notFound,"Audit turn was not found for this session");return{view:n,revision:n.replay.revision}}}function It(t){return W.includes(t)}class p extends Error{code;constructor(e,n){super(n),this.code=e,this.name="AuditLocalActionError"}}function T(t){const e=k(t);return{sessionId:R(e.session_id,"session_id"),auditId:R(e.audit_id,"audit_id"),turnId:R(e.turn_id,"turn_id"),...e.revision===void 0?{}:{revision:S(e.revision,{min:1,max:Number.MAX_SAFE_INTEGER,field:"revision"})}}}function k(t){if(!t||typeof t!="object"||Array.isArray(t))throw new p(d.invalidParams,"Audit parameters must be an object");return t}function R(t,e){if(typeof t!="string")throw new p(d.invalidParams,`${e} is required`);const n=t.trim();if(!n||n.length>512)throw new p(d.invalidParams,`${e} is invalid`);return n}function S(t,e){if(t===void 0){if(e.defaultValue!==void 0)return e.defaultValue;throw new p(d.invalidParams,`${e.field} is required`)}if(typeof t!="number"||!Number.isSafeInteger(t)||t<e.min||t>e.max)throw new p(d.invalidParams,`${e.field} is invalid`);return t}function N(t,e){if(t==null||t==="")return 0;if(typeof t!="string"||t.length>4096)throw new p(d.cursorInvalid,"Audit cursor is invalid");const[n,o,...r]=t.split(".");if(!n||!o||r.length>0)throw new p(d.cursorInvalid,"Audit cursor is invalid");const s=F(n);if(!ot(o,s))throw new p(d.cursorInvalid,"Audit cursor is invalid");let c;try{c=JSON.parse(Buffer.from(n,"base64url").toString("utf8"))}catch{throw new p(d.cursorInvalid,"Audit cursor is invalid")}if(!c||typeof c!="object"||Array.isArray(c))throw new p(d.cursorInvalid,"Audit cursor is invalid");const u=c,l=u.position;if(u.v!==D||u.kind!==e.kind||u.auditId!==e.auditId||u.turnId!==e.turnId||u.revision!==e.revision||u.contentId!==e.contentId||u.etag!==e.etag||typeof l!="number"||!Number.isSafeInteger(l)||l<0)throw new p(d.cursorInvalid,"Audit cursor is invalid");return l}function O(t){const e=Buffer.from(JSON.stringify({v:D,...t}),"utf8").toString("base64url");return`${e}.${F(e)}`}function F(t){return H("sha256",nt).update(t).digest("base64url")}function ot(t,e){const n=Buffer.from(t,"utf8"),o=Buffer.from(e,"utf8");return n.length===o.length&&X(n,o)}function E(t){const e=[t.input?.reference,t.finalOutput?.reference,...t.contents.map(o=>o.reference),...t.spans.flatMap(o=>[...o.inputRefs,...o.outputRefs])].filter(o=>o!==void 0),n=new Map;for(const o of e)n.has(o.contentId)||n.set(o.contentId,o);return[...n.values()].sort((o,r)=>o.contentId.localeCompare(r.contentId)||o.role.localeCompare(r.role))}function g(t){return{content_id:t.contentId,kind:t.role,mime:t.mimeType??G(t.format),bytes:t.byteSize,...t.charCount===void 0?{}:{chars:t.charCount},estimated_tokens:Y(t),capture_level:t.captureLevel}}function rt(t){return{span_id:t.spanId,trace_id:t.traceId,turn_id:t.turnId,session_id:t.sessionId,...t.parentSpanId?{parent_span_id:t.parentSpanId}:{},kind:t.kind,name:t.name,sequence:t.sequence,status:t.status,started_at:t.startedAt,...t.endedAt?{ended_at:t.endedAt}:{},...t.durationMs===void 0?{}:{duration_ms:t.durationMs},...t.modelId?{model_id:t.modelId}:{},input_refs:t.inputRefs.map(g),output_refs:t.outputRefs.map(g),...t.usage?{usage:L(t.usage)}:{},provider:{provider:t.provider.provider,...t.provider.nativeEventType?{native_event_type:t.provider.nativeEventType}:{},native_ids:{...t.provider.nativeIds}},provenance:{...t.provenance}}}function V(t){return t.find(e=>e.kind==="llm_request"&&e.modelId)?.modelId}function st(t,e,n){const o=e.toolCalls.slice(0,P);return{span_count:e.spanCount,span_counts:e.spanCounts.map(r=>({...r})),llm_request_count:e.llmRequestCount,tool_call_count:e.toolCallCount,tool_calls_complete_count:e.toolCallsCompleteCount,tool_call_status_counts:{...e.toolCallStatusCounts},tool_calls_returned_count:o.length,tool_calls_has_more:o.length<e.toolCalls.length,subagent_call_count:e.subagentCallCount,llm_requests:e.llmRequests.map(r=>({span_id:r.spanId,name:r.name,sequence:r.sequence,started_at:r.startedAt,...r.endedAt?{ended_at:r.endedAt}:{},...r.durationMs===void 0?{}:{duration_ms:r.durationMs},status:r.status,...r.usage?{usage:L(r.usage)}:{}})),tool_calls:o.map(j),input_token_attribution:n,total_usage:L(t)}}function j(t){return{span_id:t.spanId,...t.parentSpanId?{parent_span_id:t.parentSpanId}:{},name:t.name,sequence:t.sequence,started_at:t.startedAt,...t.endedAt?{ended_at:t.endedAt}:{},...t.durationMs===void 0?{}:{duration_ms:t.durationMs},status:t.status,...t.toolCallId?{tool_call_id:t.toolCallId}:{},...t.nativeEventType?{native_event_type:t.nativeEventType}:{},arguments_complete:t.argumentsComplete,result_complete:t.resultComplete,capture_complete:t.captureComplete,input_refs:t.inputRefs.map(g),output_refs:t.outputRefs.map(g)}}function L(t){return{input:{...t.input},output:{...t.output},total_processed:t.totalProcessed,request_count:t.requestCount,accuracy:t.accuracy,completeness:t.completeness,provider:t.provider,normalization:{...t.normalization}}}function it(t,e=$(t)){return{status:t.quality.status,input_complete:t.quality.inputComplete,output_complete:t.quality.outputComplete,tool_calls_complete:t.quality.toolCallsComplete,subagents_complete:t.quality.subagentsComplete,usage_complete:t.quality.usageComplete,raw_requests_complete:t.quality.rawRequestsComplete,raw_requests_requested:e.requested,raw_requests_available:e.available,raw_requests_status:e.status,raw_request_capture:e,gaps:t.quality.gaps.map(n=>({category:n.category,reason:n.reason}))}}function at(t){return E(t).some(e=>e.truncated)}function $(t){const e=[t.input,t.finalOutput,...t.contents].filter(a=>a!==void 0&&z.has(a.role)),n=E(t).filter(a=>z.has(a.role)),o=t.quality.gaps.filter(a=>a.category==="raw_provider_body"),r=e.length>0||o.length>0||!t.quality.rawRequestsComplete,s=n.length>0,c=e.filter(a=>!a.reference).length,u=n.filter(a=>a.role==="model_request").length,l=n.filter(a=>a.role==="model_response").length,f=r?t.quality.rawRequestsComplete&&s?"complete":s?"partial":"unavailable":"not_requested";return{requested:r,available:s,status:f,stored_ref_count:n.length,exchange_count:Math.max(u,l),stored_request_count:u,stored_response_count:l,omitted_count:c,...o.length===0?{}:{gaps:o.map(a=>({category:a.category,reason:a.reason,...a.detail?{detail:a.detail}:{}}))}}}async function ut(t,e,n,o){const r=dt(t,e),s=new Map;for(const i of r){const _=s.get(i.role)??{role:i.role,refs:0,bytes:0,estimatedTokens:0,captureLevels:new Set};_.refs+=1,_.bytes+=i.byteSize,_.estimatedTokens+=Y(i),_.captureLevels.add(i.captureLevel),s.set(i.role,_)}const c=[...s.values()].reduce((i,_)=>i+_.estimatedTokens,0),u=[...s.values()].reduce((i,_)=>i+_.bytes,0),l=n.input.total,f=r.filter(i=>i.role==="model_request"&&i.captureLevel==="provider_exact"),a=new Map;let y=0,I=0,w=0;for(const i of f)try{const _=await o.readContent(i.contentId),m=tt(_.value);y+=m.requestBytes,I+=m.estimatedTokens,m.parsed&&(w+=1);for(const h of m.bySource){const A=a.get(h.source)??{bytes:0,estimatedTokens:0,requests:0};A.bytes+=h.bytes,A.estimatedTokens+=h.estimatedTokens,A.requests+=1,a.set(h.source,A)}}catch{}const v=f.length>0&&a.size>0,C=v?I:c,x=v?y:u,M=[...a.entries()].sort(([i],[_])=>i.localeCompare(_)).map(([i,_])=>({source:i,..._,allocatedProviderInputTokens:0,allocationRemainder:0}));if(v&&y>0){let i=0;for(const m of M){const h=l*m.bytes/y;m.allocatedProviderInputTokens=Math.floor(h),m.allocationRemainder=h-m.allocatedProviderInputTokens,i+=m.allocatedProviderInputTokens}const _=[...M].sort((m,h)=>h.allocationRemainder-m.allocationRemainder||m.source.localeCompare(h.source));for(let m=0;i<l&&_.length>0;m+=1)_[m%_.length].allocatedProviderInputTokens+=1,i+=1}return{accuracy:v?"estimated_from_provider_exact_request":"estimated_from_captured_content_refs",provider_reported_input_tokens:l,provider_reported_uncached_input_tokens:n.input.uncached,provider_reported_cache_read_tokens:n.input.cacheRead,provider_reported_cache_write_tokens:n.input.cacheWrite,captured_input_ref_count:r.length,captured_input_bytes:x,captured_input_estimated_tokens:C,provider_exact_request_count:f.length,parsed_provider_request_count:w,token_estimation_method:"utf8_bytes_divided_by_4",provider_input_token_delta_vs_byte_estimate:l-C,unattributed_provider_input_tokens:v?0:Math.max(0,l-C),...v?{source_token_allocation_accuracy:"proportional_estimate_reconciled_to_provider_total",by_source:M.map(i=>({source:i.source,requests:i.requests,bytes:i.bytes,estimated_tokens_from_bytes:i.estimatedTokens,allocated_provider_input_tokens:i.allocatedProviderInputTokens}))}:{},by_role:[...s.values()].sort((i,_)=>i.role.localeCompare(_.role)).map(i=>({role:i.role,refs:i.refs,bytes:i.bytes,estimated_tokens:i.estimatedTokens,capture_levels:[...i.captureLevels].sort()})),note:v?"Source allocations are proportional estimates derived from captured provider request JSON and reconciled to the provider total; they are not tokenizer-exact.":"Provider input includes runtime context that may not be captured as replay content, such as system/developer instructions, tool schemas, and adapter-added context."}}function dt(t,e){const n=new Map,o=r=>{!r||n.has(r.contentId)||n.set(r.contentId,r)};for(const r of t)if(r.kind==="llm_request")for(const s of r.inputRefs)o(s);return o(e.input?.reference),[...n.values()]}function Y(t){return t.estimatedTokens!==void 0?t.estimatedTokens:t.byteSize<=0?0:Math.max(1,Math.ceil(t.byteSize/4))}function G(t){switch(t){case"json":return"application/json";case"jsonl":return"application/x-ndjson";case"binary":return"application/octet-stream";case"text":return"text/plain; charset=utf-8"}}function ct(t){for(let e=t.length;e>=0;e-=1){const n=t.subarray(0,e);try{return new TextDecoder("utf-8",{fatal:!0}).decode(n),n}catch{}}return Buffer.alloc(0)}function lt(t){try{return new TextDecoder("utf-8",{fatal:!0}).decode(t)}catch{throw new p(d.contentCorrupt,"Audit content is not valid UTF-8")}}function _t(t){return t instanceof p?b(t.code,t.message):t instanceof Z?b(d.contentNotFound,"Audit content was not found"):t instanceof Q?b(d.contentCorrupt,"Audit content is corrupt"):b(d.internal,"Audit request could not be completed")}function b(t,e){return{status:"failed",errorCode:t,errorMsg:e.slice(0,256)}}export{ht as AuditLocalActionHandler,P as DEFAULT_AUDIT_SPAN_LIMIT,U as MAX_AUDIT_CONTENT_CHUNK_BYTES,B as MAX_AUDIT_SPAN_LIMIT,It as isAuditLocalActionType};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
class
|
|
1
|
+
import{hasToolArguments as f,hasToolResult as C}from"../core/tool-call-audit.js";class w{store;constructor(t){this.store=t}async getTurn(t,o){const a=await this.store.get(t,o);return a?c(a):void 0}async getTurnRevision(t,o,a){const r=await this.store.getRevision(t,o,a);return r?c(r):void 0}async findByAuditId(t){return(await this.store.findByAuditId(t)).map(c)}async findByTurnId(t){return(await this.store.findByTurnId(t)).map(c)}async readContent(t){return{contentId:t,value:await this.store.readContent(t)}}async readContentChunk(t,o,a){const r=await this.store.readContentChunk(t,o,a);return{contentId:t,...r}}}function c(s){const t=p(s.spans);return{replay:s,timeline:t,tree:I(t),statistics:g(s,t)}}function p(s){return[...s].sort(h)}function I(s){const t=p(s),o=new Map;for(const e of t)o.set(e.spanId,(o.get(e.spanId)??0)+1);const a=new Map,r=new Map,d=t.map(e=>{const u={span:e,children:[]};return o.get(e.spanId)===1&&(a.set(e.spanId,e),r.set(e.spanId,u)),u}),n=[];for(const e of d){const{span:u}=e,l=u.parentSpanId,i=l?r.get(l):void 0;o.get(u.spanId)===1&&i!==void 0&&!y(u,a)?i.children.push(e):n.push(e)}return n}function g(s,t=p(s.spans)){const o=new Map;for(const n of t){const e=`${n.kind}\0${n.name}`,u=o.get(e);u?u.count+=1:o.set(e,{kind:n.kind,name:n.name,count:1})}const a=t.filter(n=>n.kind==="llm_request").map(n=>({spanId:n.spanId,name:n.name,sequence:n.sequence,startedAt:n.startedAt,endedAt:n.endedAt,durationMs:n.durationMs,status:n.status,usage:n.usage})),r=t.filter(n=>n.kind==="tool_call").map(n=>{const e=f(n),u=n.status==="cancelled"||n.status!=="running"&&C(n);return{spanId:n.spanId,parentSpanId:n.parentSpanId,name:n.name,sequence:n.sequence,startedAt:n.startedAt,endedAt:n.endedAt,durationMs:n.durationMs,status:n.status,toolCallId:n.provider.nativeIds.toolCallId??n.provider.nativeIds.messageId,nativeEventType:n.provider.nativeEventType,inputRefs:n.inputRefs.filter(l=>l.role==="tool_arguments"),outputRefs:n.outputRefs.filter(l=>l.role==="tool_result"),argumentsComplete:e,resultComplete:u,captureComplete:!!(n.name.trim()&&n.name!=="tool"&&e&&u)}}),d={running:0,completed:0,failed:0,cancelled:0};for(const n of r)d[n.status]+=1;return{spanCount:t.length,spanCounts:[...o.values()].sort((n,e)=>n.kind.localeCompare(e.kind)||n.name.localeCompare(e.name)),llmRequestCount:a.length,toolCallCount:r.length,subagentCallCount:t.filter(n=>n.kind==="subagent").length,llmRequests:a,toolCalls:r,toolCallsCompleteCount:r.filter(n=>n.captureComplete).length,toolCallStatusCounts:d,totalUsage:s.usage}}function h(s,t){return s.sequence-t.sequence||s.startedAt.localeCompare(t.startedAt)||s.spanId.localeCompare(t.spanId)}function y(s,t){const o=new Set([s.spanId]);let a=s.parentSpanId;for(;a;){if(o.has(a))return!0;o.add(a),a=t.get(a)?.parentSpanId}return!1}export{w as AuditReplayQueryService,g as buildReplayStatistics,c as buildReplayView,I as buildSpanTree,p as buildTimeline};
|
|
File without changes
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
function u(t){return t!==null&&typeof t=="object"&&!Array.isArray(t)?t:void 0}function h(t){if(typeof t=="string")return Buffer.byteLength(t,"utf8");try{return Buffer.byteLength(JSON.stringify(t)??"","utf8")}catch{return Buffer.byteLength(String(t),"utf8")}}function g(t){return t<=0?0:Math.ceil(t/4)}function x(t){if(typeof t=="string")return t;if(!Array.isArray(t))return;const r=t.flatMap(n=>{if(typeof n=="string")return[n];const e=u(n);if(!e)return[];const s=e.text??e.content??e.input_text;return typeof s=="string"?[s]:[]});return r.length>0?r.join(`
|
|
2
|
+
`):void 0}function p(t){return String(t.role??t.type??"").toLowerCase()}function _(t,r,n){const e=p(t);return e==="system"||e==="developer"?"system_or_developer":e==="function_call_output"||e==="tool"||e==="tool_result"?"tool_result":e==="assistant"||e==="output_text"?"assistant_history":e==="user"||e==="input_text"||e==="message"?r===n?"user_input":"conversation_history":"adapter_context"}function c(t,r,n){const e=h(n);if(e===0)return;const s=t.get(r)??{bytes:0,estimatedTokens:0};s.bytes+=e,s.estimatedTokens=Math.floor(s.bytes/4),t.set(r,s)}function b(t,r){let n=-1;for(let e=0;e<r.length;e+=1){const s=u(r[e]);if(!s)continue;const o=p(s);(o==="user"||o==="input_text"||o==="message")&&(n=e)}for(let e=0;e<r.length;e+=1){const s=u(r[e]);if(!s){c(t,"adapter_context",r[e]);continue}c(t,_(s,e,n),s)}}function k(t){const r=Buffer.byteLength(t,"utf8"),n=g(r);let e;try{e=JSON.parse(t)}catch{return{requestBytes:r,estimatedTokens:n,parsed:!1,bySource:[{source:"unknown",bytes:r,estimatedTokens:n}]}}const s=u(e);if(!s)return{requestBytes:r,estimatedTokens:n,parsed:!0,bySource:[{source:"unknown",bytes:r,estimatedTokens:n}]};const o=new Map;s.instructions!==void 0&&c(o,"system_or_developer",s.instructions),s.developer!==void 0&&c(o,"system_or_developer",s.developer),s.tools!==void 0&&c(o,"tool_schema",s.tools);const i=s.input??s.messages;Array.isArray(i)?b(o,i):i!==void 0&&c(o,"user_input",i);const f=[...o.values()].reduce((d,a)=>d+a.bytes,0),m=[...o.values()].reduce((d,a)=>d+a.estimatedTokens,0),y=Math.max(0,r-f),l=Math.max(0,n-m);return(y>0||l>0)&&o.set("unknown",{bytes:y,estimatedTokens:l}),{requestBytes:r,estimatedTokens:n,parsed:!0,bySource:[...o.entries()].map(([d,a])=>({source:d,...a}))}}function S(t){let r;try{r=JSON.parse(t)}catch{return}const n=u(r);if(!n)return;const e=[];n.instructions!==void 0&&e.push({source:"instructions",value:n.instructions}),n.developer!==void 0&&e.push({source:"developer",value:n.developer});const s=n.input??n.messages;if(Array.isArray(s))for(const o of s){const i=u(o);if(!i)continue;const f=p(i);f!=="system"&&f!=="developer"||e.push({source:f,value:x(i.content??i.text)??i})}return e.length>0?JSON.stringify(e):void 0}function w(t){try{const n=u(JSON.parse(t))?.model;return typeof n=="string"&&n?n:void 0}catch{return}}function v(t){const r=[];try{r.push(JSON.parse(t))}catch{for(const n of t.split(/\r?\n/)){const e=n.startsWith("data:")?n.slice(5).trim():n.trim();if(!(!e||e==="[DONE]"))try{r.push(JSON.parse(e))}catch{}}}for(const n of r.reverse()){const e=u(n),o=u(e?.response)?.id??e?.id??e?.response_id;if(typeof o=="string"&&o)return o}}export{k as analyzeRawProviderRequest,g as estimateTokensFromBytes,v as extractProviderResponseId,w as extractRequestModel,S as extractSystemPrompt};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{createHash as d}from"node:crypto";import{readFile as p,stat as l,unlink as f}from"node:fs/promises";import{resolve as n,sep as m}from"node:path";import{brotliDecompressSync as h,gunzipSync as w,inflateSync as y}from"node:zlib";const c=64*1024*1024,a=64*1024*1024;function g(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)?e:void 0}function _(e,t){const s=n(t),r=n(e);return r===s||r.startsWith(`${s}${m}`)}function P(e){const t=g(e);return!!(t&&t.requested===!0&&(t.status==="complete"||t.status==="partial"||t.status==="unavailable")&&Array.isArray(t.exchanges))}function b(e,t){const s=(t??"").split(",").map(o=>o.trim().toLowerCase()).filter(o=>o&&o!=="identity");let r=e;for(const o of s.reverse()){if(o==="gzip"||o==="x-gzip")r=w(r,{maxOutputLength:a});else if(o==="deflate")r=y(r,{maxOutputLength:a});else if(o==="br")r=h(r,{maxOutputLength:a});else throw new Error(`unsupported content encoding: ${o}`);if(r.byteLength>a)throw new Error(`decoded source exceeds ${a} bytes`)}return r}async function i(e,t,s){if(!e.complete||!e.sourcePath||!t)return{...e};if(!_(e.sourcePath,t))return s.push("raw_capture_source_outside_spool"),{...e,complete:!1,error:"source_outside_spool",sourcePath:void 0};try{const r=await l(e.sourcePath);if(r.size>c)throw new Error(`source exceeds ${c} bytes`);if(r.size!==e.bytes)throw new Error(`source size ${r.size} does not match ${e.bytes}`);const o=await p(e.sourcePath),u=d("sha256").update(o).digest("hex");if(e.sha256&&u!==e.sha256)throw new Error("source sha256 mismatch");return{...e,value:b(o,e.contentEncoding).toString("utf8")}}catch(r){const o=r instanceof Error?r.message:String(r);return s.push(`raw_capture_source_unreadable:${o}`),{...e,complete:!1,error:o}}}async function E(e,t,s){const[r,o]=await Promise.all([i(e.downstream.body,t,s),i(e.upstream.body,t,s)]);return{...e,downstream:{...e.downstream,body:r},upstream:{...e.upstream,body:o}}}async function $(e){if(!P(e))return{status:"unavailable",exchanges:[],errors:["raw_capture_boundary_invalid"],unavailableReason:"raw_capture_boundary_invalid"};const t=[],s=typeof e.spoolDirectory=="string"?e.spoolDirectory:void 0,r=await Promise.all(e.exchanges.map(o=>E(o,s,t)));return{status:t.length>0&&e.status==="complete"?"partial":e.status,exchanges:r,...s?{spoolDirectory:s}:{},...e.unavailableReason?{unavailableReason:e.unavailableReason}:{},errors:t}}async function z(e){const t=new Set;for(const s of e.exchanges)s.downstream.body.sourcePath&&t.add(s.downstream.body.sourcePath),s.upstream.body.sourcePath&&t.add(s.upstream.body.sourcePath);await Promise.all([...t].map(s=>f(s).catch(()=>{})))}export{z as cleanupRawApiCapture,$ as loadRawApiCapture};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import{createHash as x,randomBytes as T,randomUUID as H}from"node:crypto";import{createServer as U}from"node:http";import{request as W}from"node:http";import{request as $}from"node:https";import{PassThrough as L}from"node:stream";import{ProxyAgent as D}from"proxy-agent";import{WebSocket as P,WebSocketServer as N}from"ws";import{chmod as Y,mkdir as q,rmdir as M,unlink as X}from"node:fs/promises";import{createWriteStream as j}from"node:fs";import{join as _}from"node:path";import{redactHeaders as S,redactQuery as k,safeTargetBaseUrl as z}from"./redaction.js";const F=64*1024*1024,G=5e3,K=15e3,A="127.0.0.1",B=new Set(["connection","keep-alive","proxy-authenticate","proxy-authorization","te","trailer","transfer-encoding","upgrade"]);function I(a){return x("sha256").update(a).digest("hex").slice(0,24)}function Q(a){const e=a["content-type"];return Array.isArray(e)?e[0]:e}function J(a){const e=a["content-encoding"];return Array.isArray(e)?e[0]:e}function V(a,e){const t={};for(const[r,n]of Object.entries(a)){const o=r.toLowerCase();n===void 0||B.has(o)||o==="host"||(t[o]=n)}return t.host=e.host,t}function Z(a){return{HTTP_PROXY:a?.HTTP_PROXY??a?.http_proxy,HTTPS_PROXY:a?.HTTPS_PROXY??a?.https_proxy,ALL_PROXY:a?.ALL_PROXY??a?.all_proxy,NO_PROXY:a?.NO_PROXY??a?.no_proxy}}function ee(a,e){if(!e?.trim())return!1;const t=a.port||(a.protocol==="https:"?"443":"80"),r=a.hostname.toLowerCase();return e.split(",").some(n=>{const o=n.trim().toLowerCase();if(!o)return!1;if(o==="*")return!0;const[s,i]=o.split(":",2);if(i&&i!==t)return!1;const d=s.replace(/^\./,"");return r===d||r.endsWith(`.${d}`)})}function te(a,e){const t=new URL(a);return ee(t,e.NO_PROXY)?"":(t.protocol==="https:"?e.HTTPS_PROXY??e.ALL_PROXY??e.HTTP_PROXY:e.HTTP_PROXY??e.ALL_PROXY)??""}function re(a){const e={};for(const[t,r]of Object.entries(a)){const n=t.toLowerCase();r===void 0||B.has(n)||(e[n]=r)}return e}function O(a,e,t){const r=new URL(a.toString()),n=r.pathname.replace(/\/+$/,""),o=e.startsWith("/")?e:`/${e}`;r.pathname=`${n}${o}`||"/";const s=new URLSearchParams(t.startsWith("?")?t.slice(1):t);for(const[i,d]of s)r.searchParams.append(i,d);return r}function oe(a){const e=new URL(a.toString());return e.protocol=a.protocol==="https:"?"wss:":"ws:",e}function ne(a){const e=a["sec-websocket-protocol"];return(Array.isArray(e)?e.join(","):e??"").split(",").map(r=>r.trim()).filter(Boolean)}function se(a){const e={};for(const[t,r]of Object.entries(a)){const n=t.toLowerCase();r===void 0||B.has(n)||n==="host"||n.startsWith("sec-websocket-")||(e[n]=r)}return e}function ie(a,e){if(e)for(const[t,r]of Object.entries(e)){const n=t.toLowerCase();if(!(r===void 0||B.has(n)||n==="content-length"||n.startsWith("sec-websocket-")))for(const o of Array.isArray(r)?r:[r])a.push(`${n}: ${o}`)}}function C(a){return Buffer.isBuffer(a)?a:a instanceof ArrayBuffer?Buffer.from(a):Buffer.concat(a)}function ae(a,e){if(e)return{terminal:!1};try{const t=JSON.parse(a.toString("utf8")),n=(t.response!==null&&typeof t.response=="object"&&!Array.isArray(t.response)?t.response:void 0)?.id??t.id??t.response_id,o=typeof t.type=="string"?t.type:"";return{terminal:o==="response.completed"||o==="response.failed"||o==="response.cancelled"||o==="response.incomplete"||o==="error",...typeof n=="string"&&n?{responseId:n}:{}}}catch{return{terminal:!1}}}function ce(a){return structuredClone(a)}class ve{options;targetBaseUrl;maxBodyBytes;token=T(24).toString("hex");exchangesByEvent=new Map;pendingByEvent=new Map;transportAgent;websocketResponseHeaders=new WeakMap;websocketResponseProtocols=new WeakMap;upstreamWebSockets=new Set;server;websocketServer;listenPort;activeEventId;activeAuditId;spoolDirectory;constructor(e){if(this.options=e,this.targetBaseUrl=new URL(e.targetBaseUrl),this.targetBaseUrl.protocol!=="http:"&&this.targetBaseUrl.protocol!=="https:")throw new Error("Raw API capture target must use HTTP or HTTPS");if(this.maxBodyBytes=e.maxBodyBytes??F,!Number.isSafeInteger(this.maxBodyBytes)||this.maxBodyBytes<=0)throw new Error("Raw API capture maxBodyBytes must be positive");this.spoolDirectory=_(e.spoolRootDir,I(e.auditId),I(e.sessionId),T(8).toString("hex"));const t=Z(e.transportEnv??process.env);this.transportAgent=new D({getProxyForUrl:r=>te(r,t)})}get baseUrl(){if(this.listenPort===void 0)throw new Error("Raw API capture relay has not started");return`http://${A}:${this.listenPort}/${this.token}`}async start(){if(this.server)return this;await q(this.spoolDirectory,{recursive:!0,mode:448}),await Y(this.spoolDirectory,448);const e=U((n,o)=>{this.handleRequest(n,o).catch(s=>{if(!o.headersSent){o.writeHead(502,{"content-type":"text/plain; charset=utf-8"}),o.end("Provider request failed");return}o.destroy(s instanceof Error?s:new Error(String(s)))})}),t=new N({noServer:!0,perMessageDeflate:!0,handleProtocols:(n,o)=>{const s=this.websocketResponseProtocols.get(o);return s&&n.has(s)?s:n.values().next().value??!1}});t.on("headers",(n,o)=>{ie(n,this.websocketResponseHeaders.get(o))}),e.on("upgrade",(n,o,s)=>{this.handleWebSocketUpgrade(t,n,o,s).catch(i=>{o.destroyed||o.end(`HTTP/1.1 502 Bad Gateway\r
|
|
2
|
+
Connection: close\r
|
|
3
|
+
Content-Length: 0\r
|
|
4
|
+
\r
|
|
5
|
+
`),o.destroy(i instanceof Error?i:new Error(String(i)))})}),e.on("clientError",(n,o)=>{o.end(`HTTP/1.1 400 Bad Request\r
|
|
6
|
+
\r
|
|
7
|
+
`)}),await new Promise((n,o)=>{e.once("error",o),e.listen(0,A,()=>{e.off("error",o),n()})});const r=e.address();if(!r||typeof r=="string")throw e.close(),new Error("Raw API capture relay failed to resolve listen port");return this.server=e,this.websocketServer=t,this.listenPort=r.port,this}beginEvent(e,t){const r=e.trim();r&&(this.activeEventId=r,this.activeAuditId=t?.trim()||this.options.auditId,this.exchangesByEvent.has(r)||this.exchangesByEvent.set(r,[]))}async completeEvent(e,t=G){if(!Number.isSafeInteger(t)||t<=0)throw new Error("Raw API capture settle timeout must be positive");this.activeEventId===e&&(this.activeEventId=void 0,this.activeAuditId=void 0);const r=[...this.pendingByEvent.get(e)??[]];if(r.length===0)return;let n;const o=await Promise.race([Promise.allSettled(r).then(()=>!1),new Promise(s=>{n=setTimeout(()=>s(!0),t)})]);if(n&&clearTimeout(n),!!o)for(const s of this.exchangesByEvent.get(e)??[])s.status==="running"&&(s.errors.includes("capture_settle_timeout")||s.errors.push("capture_settle_timeout"))}takeEvent(e){const t=this.exchangesByEvent.get(e)??[];this.exchangesByEvent.delete(e),this.activeEventId===e&&(this.activeEventId=void 0,this.activeAuditId=void 0);const r=t.map(ce);return{requested:!0,status:r.length>0&&r.every(o=>o.status==="completed"&&o.errors.length===0&&o.downstream.body.complete&&o.upstream.body.complete&&!!o.downstream.body.sourcePath&&!!o.upstream.body.sourcePath)?"complete":"partial",spoolDirectory:this.spoolDirectory,exchanges:r}}async stop(){const e=this.server,t=this.websocketServer;this.server=void 0,this.websocketServer=void 0,this.listenPort=void 0;for(const r of this.upstreamWebSockets)r.terminate();this.upstreamWebSockets.clear();for(const r of t?.clients??[])r.terminate();t?.close(),e&&await new Promise(r=>{e.close(()=>r()),e.closeAllConnections?.()}),await Promise.allSettled([...this.pendingByEvent.values()].flatMap(r=>[...r])),this.transportAgent.destroy();try{await M(this.spoolDirectory)}catch{}}async handleWebSocketUpgrade(e,t,r,n){const o=new URL(t.url??"/","http://localhost"),s=`/${this.token}`;if(o.pathname!==s&&!o.pathname.startsWith(`${s}/`)){r.end(`HTTP/1.1 404 Not Found\r
|
|
8
|
+
Connection: close\r
|
|
9
|
+
Content-Length: 0\r
|
|
10
|
+
\r
|
|
11
|
+
`);return}const i=o.pathname.slice(s.length)||"/",d=oe(O(this.targetBaseUrl,i,o.search)),c=ne(t.headers),l=new P(d,c,{agent:this.transportAgent,followRedirects:!0,handshakeTimeout:K,headers:se(t.headers),perMessageDeflate:!0});this.upstreamWebSockets.add(l),await new Promise((h,p)=>{let f=!1,m=!1,b=!1,y={};const v=u=>{f||(f=!0,this.upstreamWebSockets.delete(l),p(u))},g=()=>{f||!m||!b||(f=!0,l.off("error",v),l.protocol&&this.websocketResponseProtocols.set(t,l.protocol),e.handleUpgrade(t,r,n,u=>{e.emit("connection",u,t),this.wireWebSocketConnection(u,l,t,i,o.search,y)}),h())};r.once("close",()=>{f||l.terminate()}),l.once("upgrade",u=>{y=u.headers,this.websocketResponseHeaders.set(t,u.headers),b=!0,g()}),l.once("unexpected-response",(u,w)=>{f||(f=!0,this.upstreamWebSockets.delete(l),this.forwardUnexpectedWebSocketResponse(w,r),h())}),l.once("error",v),l.once("open",()=>{m=!0,g()})})}forwardUnexpectedWebSocketResponse(e,t){if(t.destroyed){e.destroy();return}const r=e.statusCode??502,n=e.statusMessage??"Bad Gateway",o=[`HTTP/1.1 ${r} ${n}`];for(const[s,i]of Object.entries(e.headers)){const d=s.toLowerCase();if(!(i===void 0||B.has(d)||d==="content-length"))for(const c of Array.isArray(i)?i:[i])o.push(`${d}: ${c}`)}o.push("connection: close","",""),t.write(o.join(`\r
|
|
12
|
+
`)),e.pipe(t)}wireWebSocketConnection(e,t,r,n,o,s){let i;const d=(c,l)=>{const h=i;i=void 0,h&&h.finalize(c,l)};e.on("message",(c,l)=>{const h=C(c);i&&d("failed","websocket_request_overlap"),i=this.beginWebSocketExchange(r,n,o,h,l,s),t.send(c,{binary:l},p=>{p&&d("failed",`upstream_websocket_send_failed:${p.message}`)})}),t.on("message",(c,l)=>{const h=C(c),p=i;if(p){p.responseCapture.write(l?h:Buffer.concat([h,Buffer.from(`
|
|
13
|
+
`)]));const f=ae(h,l);f.responseId&&(p.exchange.correlation.providerResponseId=f.responseId),f.terminal&&(i=void 0,p.finalize("completed"))}e.send(c,{binary:l},f=>{f&&d("cancelled",`downstream_websocket_send_failed:${f.message}`)})}),e.once("close",()=>{this.closeWebSocket(t),d("cancelled","downstream_websocket_closed")}),t.once("close",()=>{this.upstreamWebSockets.delete(t),this.closeWebSocket(e),d("cancelled","upstream_websocket_closed")}),e.once("error",c=>{d("failed",`downstream_websocket_failed:${c.message}`)}),t.once("error",c=>{d("failed",`upstream_websocket_failed:${c.message}`)})}closeWebSocket(e){(e.readyState===P.OPEN||e.readyState===P.CONNECTING)&&e.close()}beginWebSocketExchange(e,t,r,n,o,s){const i=this.activeEventId;if(!i)return;const d=this.createExchange(i,this.activeAuditId??this.options.auditId,e,t,r);d.downstream.method="WEBSOCKET",d.upstream.statusCode=101,d.upstream.redactedHeaders=S(s);const c=this.createWritableBodyCapture(_(this.spoolDirectory,`${d.exchangeId}.request.body`),o?"application/octet-stream":"application/json",d.errors),l=this.createWritableBodyCapture(_(this.spoolDirectory,`${d.exchangeId}.response.body`),"application/x-ndjson; charset=utf-8",d.errors);d.downstream.body=c.body,d.upstream.body=l.body,c.write(n),c.end();let h=!1,p;const f=new Promise(y=>{p=y}),m=this.pendingByEvent.get(i)??new Set;return m.add(f),this.pendingByEvent.set(i,m),f.finally(()=>{m.delete(f),m.size===0&&this.pendingByEvent.delete(i)}),{eventId:i,exchange:d,requestCapture:c,responseCapture:l,done:f,finalize:async(y,v)=>{h||(h=!0,v&&!d.errors.includes(v)&&d.errors.push(v),y==="completed"?l.end():(c.dispose(),l.dispose()),await Promise.all([c.done,l.done]),d.status=y,d.completedAt=new Date().toISOString(),p?.(),p=void 0)}}}createWritableBodyCapture(e,t,r){const n=new L,o=this.captureBody(n,e,{"content-type":t},r);let s=!1;return{...o,write(i){s||n.write(i)},end(){s||(s=!0,n.end())},dispose(){if(s){o.dispose();return}s=!0,n.destroy(),o.dispose()}}}async handleRequest(e,t){const r=new URL(e.url??"/","http://localhost"),n=`/${this.token}`;if(r.pathname!==n&&!r.pathname.startsWith(`${n}/`)){t.writeHead(404,{"content-type":"text/plain; charset=utf-8"}),t.end("Not found");return}const o=r.pathname.slice(n.length)||"/",s=O(this.targetBaseUrl,o,r.search),i=this.activeEventId,d=this.activeAuditId,c=i?this.createExchange(i,d??this.options.auditId,e,o,r.search):void 0,l=c?this.captureBody(e,_(this.spoolDirectory,`${c.exchangeId}.request.body`),e.headers,c.errors):void 0;c&&l&&(c.downstream.body=l.body);let h,p,f=!1,m;const b=new Promise(u=>{m=u});if(i&&c){const u=this.pendingByEvent.get(i)??new Set;u.add(b),this.pendingByEvent.set(i,u),b.finally(()=>{u.delete(b),u.size===0&&this.pendingByEvent.delete(i)})}const y=async(u,w)=>{!c||f||(f=!0,w&&!c.errors.includes(w)&&c.errors.push(w),u!=="completed"&&(l?.dispose(),h?.dispose()),await Promise.all([l?.done,h?.done]),c.status=u,c.completedAt=new Date().toISOString(),m?.(),m=void 0)},g=(s.protocol==="https:"?$:W)(s,{method:e.method??"GET",headers:V(e.headers,s),agent:this.transportAgent});g.once("response",u=>{if(p=u,c){c.upstream.statusCode=u.statusCode,c.upstream.redactedHeaders=S(u.headers);const w=[u.headers["x-request-id"],u.headers["openai-request-id"],u.headers["x-openai-request-id"],u.headers["request-id"]].find(E=>typeof E=="string");typeof w=="string"&&(c.correlation.providerRequestId=w),h=this.captureBody(u,_(this.spoolDirectory,`${c.exchangeId}.response.body`),u.headers,c.errors),c.upstream.body=h.body,u.once("end",()=>{t.writableEnded||t.end(),y("completed")}),u.once("aborted",()=>{const E=y("cancelled","upstream_response_aborted");t.destroyed||t.destroy(new Error("Provider response aborted"))}),u.once("error",E=>{const R=y("failed",`upstream_response_failed:${E.message}`);t.destroyed||t.destroy(E)})}t.writeHead(u.statusCode??502,u.statusMessage,re(u.headers)),u.pipe(t,{end:!c})}),g.once("error",u=>{y("failed",`upstream_request_failed:${u.message}`),t.headersSent||t.writeHead(502,{"content-type":"text/plain; charset=utf-8"}),t.writableEnded||t.end("Provider request failed")}),e.once("aborted",()=>{g.destroy(),y("cancelled","downstream_request_aborted")}),t.once("close",()=>{t.writableFinished||!c||f||(g.destroy(),p?.destroy(),y("cancelled","downstream_response_closed"))}),e.pipe(g)}createExchange(e,t,r,n,o){const s=H(),i={exchangeId:s,auditId:t,sessionId:this.options.sessionId,eventId:e,provider:this.options.provider,startedAt:new Date().toISOString(),status:"running",downstream:{method:r.method??"GET",path:n,...k(o)?{query:k(o)}:{},redactedHeaders:S(r.headers),body:{bytes:0,complete:!1}},upstream:{targetBaseUrl:z(this.targetBaseUrl),redactedHeaders:{},body:{bytes:0,complete:!1}},correlation:{requestId:s},errors:[]},d=this.exchangesByEvent.get(e)??[];return d.push(i),this.exchangesByEvent.set(e,d),i}captureBody(e,t,r,n){const o=x("sha256"),s={sourcePath:t,bytes:0,contentType:Q(r),contentEncoding:J(r),complete:!1};let i=j(t,{flags:"wx",mode:384}),d=!1,c=!1,l;const h=new Promise(f=>{l=f}),p=f=>{d||(d=!0,s.error=f,s.complete=!1,delete s.sourcePath,n.push(f),i?.destroy(),i=void 0,X(t).catch(()=>{}),l?.(),l=void 0)};return i.once("error",f=>{p(`body_write_failed:${f.message}`)}),i.once("finish",()=>{d||(s.complete=!0),l?.(),l=void 0}),e.on("data",f=>{const m=Buffer.isBuffer(f)?f:Buffer.from(f);if(o.update(m),s.bytes+=m.byteLength,!d){if(s.bytes>this.maxBodyBytes){p(`body_limit_exceeded:${this.maxBodyBytes}`);return}i?.write(m)}}),e.once("end",()=>{s.sha256=o.digest("hex"),!d&&i?.end()}),e.once("error",f=>{p(`body_stream_failed:${f.message}`)}),{body:s,done:h,dispose(){c||(c=!0,!s.complete&&!d&&p("body_capture_incomplete"))}}}}function Ee(a){return{requested:!0,status:"unavailable",exchanges:[],unavailableReason:a}}export{ve as RawApiCaptureRelay,Ee as unavailableRawApiCaptureBoundary};
|