grix-connector 3.16.0 → 3.17.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/dist/adapter/acp/acp-adapter.js +14 -14
- package/dist/adapter/claude/claude-adapter.js +20 -19
- package/dist/adapter/claude/protocol-contract.js +1 -1
- package/dist/adapter/codewhale/codewhale-adapter.js +2 -2
- package/dist/adapter/codex/codex-bridge.js +10 -10
- package/dist/adapter/codex/session-activity.js +3 -1
- package/dist/adapter/cursor/cursor-adapter.js +5 -5
- package/dist/adapter/opencode/opencode-adapter.js +3 -3
- package/dist/adapter/openhuman/openhuman-adapter.js +3 -3
- package/dist/adapter/pi/pi-adapter.js +5 -5
- package/dist/audit/adapters/acp/acp-audit-adapter.js +1 -0
- package/dist/audit/adapters/acp/generic-acp-audit-adapter.js +2 -0
- package/dist/audit/adapters/acp/kimi-audit-adapter.js +2 -0
- package/dist/audit/adapters/acp/reasonix-audit-adapter.js +1 -0
- package/dist/audit/adapters/acp/reasonix-transcript-source.js +1 -0
- package/dist/audit/adapters/claude/claude-audit-adapter.js +1 -0
- package/dist/audit/adapters/claude/claude-otel-source.js +2 -0
- package/dist/audit/adapters/claude/claude-transcript-source.js +1 -0
- package/dist/audit/adapters/claude/claude-usage-merger.js +1 -0
- package/dist/audit/adapters/codewhale/codewhale-audit-adapter.js +1 -0
- package/dist/audit/adapters/codex/codex-audit-adapter.js +1 -0
- package/dist/audit/adapters/cursor/cursor-audit-adapter.js +1 -0
- package/dist/audit/adapters/opencode/opencode-audit-adapter.js +1 -0
- package/dist/audit/adapters/pi/pi-audit-adapter.js +1 -0
- package/dist/audit/adapters/pi/pi-transcript-source.js +1 -0
- package/dist/audit/core/audit-options.js +1 -0
- package/dist/audit/core/audit-session-registry.js +3 -0
- package/dist/audit/core/audit-state.js +1 -0
- package/dist/audit/core/audit-turn-lifecycle.js +1 -0
- package/dist/audit/core/content-reference.js +1 -0
- package/dist/audit/core/replay-finalizer.js +1 -0
- package/dist/audit/core/types.js +1 -0
- package/dist/audit/core/usage.js +1 -0
- package/dist/audit/integration/bridge-audit-controller.js +1 -0
- package/dist/audit/producer/audit-producer.js +1 -0
- package/dist/audit/producer/ipc-audit-producer.js +1 -0
- package/dist/audit/query/audit-local-actions.js +1 -0
- package/dist/audit/query/audit-replay-query-service.js +1 -0
- package/dist/audit/runtime/default-audit-recorder.js +1 -0
- package/dist/audit/storage/file-audit-replay-store.js +2 -0
- package/dist/audit/worker/audit-recorder-ipc-protocol.js +1 -0
- package/dist/audit/worker/audit-recorder-worker-entry.js +1 -0
- package/dist/audit/worker/audit-recorder-worker.js +1 -0
- package/dist/bridge/bridge.js +10 -10
- package/dist/core/aibot/client.js +2 -2
- package/dist/core/aibot/connection-handle.js +1 -1
- package/dist/core/aibot/types.js +1 -0
- package/dist/core/config/provider-env.js +1 -1
- package/dist/core/mcp/internal-api-server.js +1 -1
- package/dist/core/observability/sentry.js +1 -1
- package/dist/core/proxy/compat/kiro-cw/eventstream.js +1 -0
- package/dist/core/proxy/compat/kiro-cw/index.js +1 -0
- package/dist/core/proxy/compat/kiro-cw/request-builder.js +3 -0
- package/dist/core/proxy/compat/kiro-cw/server.js +7 -0
- package/dist/core/proxy/compat/kiro-cw/stream-converter.js +5 -0
- package/dist/core/proxy/index.js +1 -1
- package/dist/core/proxy/kiro-relay.js +2 -0
- package/dist/core/proxy/relay-credential.js +1 -1
- package/dist/grix.js +1 -1
- package/dist/manager.js +2 -2
- package/dist/mcp/stream-http/security.js +1 -1
- package/dist/service/platform-adapter.js +4 -1
- package/package.json +8 -1
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{readFile as S,readdir as B,stat as L}from"node:fs/promises";import{homedir as O}from"node:os";import{basename as V,join as b}from"node:path";import{referenceCaptureContent as H}from"../../core/content-reference.js";const K=Object.freeze({inputOutput:!0,tools:!0,subagents:!1,thinking:!0,rawProviderBody:!1});function p(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function f(e){return typeof e=="string"&&e.length>0?e:void 0}function q(e){return typeof e=="number"&&Number.isFinite(e)&&e>=0?e:void 0}function Q(e){return e.options?.enabled===!0?e.options.capture:K}function C(e){if(typeof e=="number"&&Number.isFinite(e)){const n=e>1e10?e:e*1e3;return new Date(n).toISOString()}if(typeof e=="string"&&Number.isFinite(Date.parse(e)))return new Date(e).toISOString()}function U(e,n){if(!e)return!1;const r=Date.parse(e);return r>=Date.parse(n.startedAt)-5e3&&r<=Date.parse(n.endedAt)+3e4}function N(e){return typeof e=="string"?e:Array.isArray(e)?e.map(n=>typeof n=="string"?n:p(n)?f(n.text)??f(n.data)??"":"").join(""):""}function W(e,n){const r=p(e.message)?e.message:{};return(Array.isArray(r.parts)?r.parts:[]).filter(s=>p(s)&&s.thought===!0===n).map(s=>p(s)?f(s.text)??"":"").join("")}function F(e,n){const r=n.input?.value?.trim();if(r)for(let t=e.length-1;t>=0;t--){const s=e[t];if(s.type==="user"&&JSON.stringify(s).includes(r))return t}for(let t=e.length-1;t>=0;t--){const s=e[t];if(s.type==="user"&&U(C(s.timestamp),n))return t}return-1}async function J(e){return(await S(e,"utf8")).split(`
|
|
2
|
+
`).flatMap(r=>{if(!r.trim())return[];try{const t=JSON.parse(r);return p(t)?[t]:[]}catch{return[]}})}async function X(e,n,r){const t=b(O(),".qwen","projects",r.replace(/[/\\]/g,"-"),"chats",`${n}.jsonl`);try{await L(t)}catch{return{records:[]}}const s=await J(t),c=F(s,e);if(c<0)return{records:[],sourcePath:t};const u=s.slice(c+1),i=u.findIndex(o=>o.type==="user");return{records:(i>=0?u.slice(0,i):u).flatMap((o,m)=>{if(o.type!=="assistant"||!p(o.usageMetadata))return[];const d=o.usageMetadata,v=q(d.promptTokenCount),y=q(d.candidatesTokenCount),I=q(d.cachedContentTokenCount)??0,A=q(d.thoughtsTokenCount);if(v===void 0||y===void 0)return[];const w=C(o.timestamp)??e.endedAt,h=f(o.model);return[{requestId:f(o.uuid)??`qwen-${m}`,model:h??"qwen",...h?{modelId:h}:{},endedAt:w,output:W(o,!1),thinking:W(o,!0),sourcePath:t,raw:o,inputTotal:v,outputTotal:y,uncached:Math.max(0,v-I),cacheRead:I,cacheWrite:null,reasoning:A??null,visible:A===void 0?null:Math.max(0,y-A),requestCount:1}]}),sourcePath:t}}async function Y(e,n){const r=b(O(),".gemini","tmp",V(n),"chats");try{const t=await B(r),s=e.slice(0,8),c=t.filter(i=>i.startsWith("session-")&&i.includes(s)&&(i.endsWith(".json")||i.endsWith(".jsonl")));return(await Promise.all(c.map(async i=>{const _=b(r,i);return{sourcePath:_,modifiedAt:(await L(_)).mtimeMs}}))).sort((i,_)=>_.modifiedAt-i.modifiedAt)[0]?.sourcePath}catch{return}}async function Z(e,n,r){const t=await Y(n,r);if(!t)return{records:[]};const s=t.endsWith(".jsonl")?await J(t):await(async()=>{const o=JSON.parse(await S(t,"utf8"));return Array.isArray(o)?o.filter(p):p(o)&&Array.isArray(o.messages)?o.messages.filter(p):[]})(),c=F(s,e);if(c<0)return{records:[],sourcePath:t};const u=s.slice(c+1),i=u.findIndex(o=>o.type==="user");return{records:(i>=0?u.slice(0,i):u).flatMap((o,m)=>{if(o.type!=="gemini"||!p(o.tokens))return[];const d=o.tokens,v=q(d.input),y=q(d.output),I=q(d.thoughts)??0,A=q(d.cached)??0;if(v===void 0||y===void 0)return[];const w=f(o.model);return[{requestId:f(o.id)??`gemini-${m}`,model:w??"gemini",...w?{modelId:w}:{},endedAt:C(o.timestamp)??e.endedAt,output:N(o.content),thinking:Array.isArray(o.thoughts)?o.thoughts.map(h=>p(h)?f(h.description)??"":"").join(""):void 0,sourcePath:t,raw:o,inputTotal:v,outputTotal:y+I,uncached:Math.max(0,v-A),cacheRead:A,cacheWrite:null,reasoning:I,visible:y,requestCount:1}]}),sourcePath:t}}async function j(e,n){const r=b(O(),".kiro","sessions","cli",`${n}.json`);let t;try{t=JSON.parse(await S(r,"utf8"))}catch{return{records:[]}}const s=p(t)?t:{},c=p(s.session_state)?s.session_state:{},u=p(c.conversation_metadata)?c.conversation_metadata:{},i=p(c.rts_model_state)?c.rts_model_state:{},_=p(i.model_info)?i.model_info:{};return{records:(Array.isArray(u.user_turn_metadatas)?u.user_turn_metadatas.filter(p):[]).flatMap((m,d)=>{const v=C(m.end_timestamp),y=p(m.result)?m.result:{},I=p(y.Ok)?y.Ok:{},A=q(m.input_token_count),w=q(m.output_token_count);if(!U(v,e)||A===void 0||w===void 0)return[];const h=f(_.model_id);return[{requestId:f(I.id)??`kiro-turn-${d}`,model:h??"kiro",...h?{modelId:h}:{},endedAt:v,output:N(I.content),sourcePath:r,raw:m,inputTotal:A,outputTotal:w,uncached:null,cacheRead:null,cacheWrite:null,reasoning:null,visible:null,requestCount:Math.max(1,q(m.total_request_count)??1)}]}),sourcePath:r}}async function ee(e){const n=String(e.boundary.agentType??"").toLowerCase(),r=f(e.boundary.providerSessionId),t=f(e.boundary.cwd);return r?n==="qwen"&&t?X(e,r,t):n==="gemini"&&t?Z(e,r,t):n==="kiro"?j(e,r):{records:[]}:{records:[]}}function R(e,n,r){const t=[r.role,r.sourcePath??"",r.value??""].join("\0");if(n.has(t))return n.get(t);const s=H(r);return n.set(t,s),e.push(r),s}function k(e,n){n&&!e.some(r=>r.contentId===n.contentId)&&e.push(n)}function M(e){const n=e.startedAt??e.job.startedAt,r=e.endedAt??e.job.endedAt,t=Date.parse(n),s=Date.parse(r);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:n,endedAt:r,...Number.isFinite(t)&&Number.isFinite(s)?{durationMs:Math.max(0,s-t)}:{},inputRefs:[],outputRefs:[],provider:{provider:"acp",nativeEventType:e.nativeEventType,nativeIds:Object.fromEntries(Object.entries(e.nativeIds??{}).filter(c=>typeof c[1]=="string")),...e.rawAttributes?{rawAttributes:e.rawAttributes}:{}},provenance:{source:"provider_event",accuracy:"provider_reported"}}}function te(e){const n=e.uncached!==null&&e.cacheRead!==null&&e.cacheWrite!==null;return{input:{total:e.inputTotal,uncached:e.uncached,cacheRead:e.cacheRead,cacheWrite:e.cacheWrite,other:n?0:null},output:{total:e.outputTotal,reasoning:e.reasoning,visible:e.visible},totalProcessed:e.inputTotal+e.outputTotal,requestCount:e.requestCount,accuracy:"provider_reported",completeness:n?"complete":"partial",provider:"acp",providerUsageRaw:e.raw,normalization:{adapter:"generic-acp-native-session",version:1,formula:"provider input total + provider output total; available cache/reasoning dimensions remain explicit, unavailable dimensions are null"}}}function ne(e){[...e].sort((r,t)=>r.kind==="turn"?-1:t.kind==="turn"?1:Date.parse(r.startedAt)-Date.parse(t.startedAt)||r.sequence-t.sequence).forEach((r,t)=>{r.sequence=t})}class ie{provider="acp";async collect(n){const r={events:[],usageRecords:[],sourcePaths:[],anomalies:[],gaps:[]},t=p(n.boundary.acpEvidence)?n.boundary.acpEvidence:void 0;if(t&&Array.isArray(t.events))for(const s of t.events){if(!p(s)||!p(s.event)||typeof s.sequence!="number"||typeof s.observedAt!="string"){r.anomalies.push({code:"acp_audit_event_malformed",message:"ACP evidence row is malformed"}),r.gaps.push({category:"acp_event",reason:"correlation_failed"});continue}r.events.push({sequence:s.sequence,observedAt:s.observedAt,event:s.event})}r.events.sort((s,c)=>s.sequence-c.sequence);try{const s=await ee(n);r.usageRecords=s.records,s.sourcePath&&r.sourcePaths.push(s.sourcePath)}catch(s){r.anomalies.push({code:"acp_native_usage_source_unreadable",message:s instanceof Error?s.message:String(s)})}return r}async normalize(n,r){const t=r,s=Q(n),c=[],u=[],i=new Map;let _=0;const x=f(n.boundary.agentType)??"ACP",o=`acp:${n.turnId}:turn`,m=M({job:n,spanId:o,kind:"turn",name:`${x} audited turn`,sequence:_++,status:n.outcome==="completed"?"completed":n.outcome==="cancelled"?"cancelled":"failed",nativeEventType:"acp_turn",nativeIds:{providerSessionId:f(n.boundary.providerSessionId)}});c.push(m);const d=s.inputOutput&&n.input?R(u,i,{...n.input,captureLevel:n.input.captureLevel??"runtime_exact"}):void 0;k(m.inputRefs,d),s.inputOutput&&n.finalOutput&&k(m.outputRefs,R(u,i,{...n.finalOutput,captureLevel:n.finalOutput.captureLevel??"runtime_exact"}));const v=[],y=t.usageRecords.length>0?t.usageRecords:[{requestId:`${x}-${n.turnId}`,model:x,endedAt:n.endedAt,sourcePath:"",raw:{},inputTotal:0,outputTotal:0,uncached:null,cacheRead:null,cacheWrite:null,reasoning:null,visible:null,requestCount:1}];for(const[l,a]of y.entries()){const g=M({job:n,spanId:`acp:${n.sessionId}:request:${a.requestId}`,parentSpanId:o,kind:"llm_request",name:a.model,sequence:_++,startedAt:a.startedAt??(l===0?n.startedAt:y[l-1].endedAt),endedAt:a.endedAt,nativeEventType:"native_session_usage",nativeIds:{requestId:a.requestId,providerSessionId:f(n.boundary.providerSessionId)},rawAttributes:{sourcePath:a.sourcePath,nativeUsage:a.raw}});a.modelId&&(g.modelId=a.modelId),l===0&&k(g.inputRefs,d),t.usageRecords.length>0&&(g.usage=te(a)),s.inputOutput&&a.output&&k(g.outputRefs,R(u,i,{role:"assistant_text",format:"text",value:a.output,sourcePath:a.sourcePath,captureLevel:"provider_exact"})),s.thinking&&a.thinking&&k(g.outputRefs,R(u,i,{role:"thinking",format:"text",value:a.thinking,sourcePath:a.sourcePath,captureLevel:"provider_exact"})),s.rawProviderBody&&t.usageRecords.length>0&&k(g.outputRefs,R(u,i,{role:"model_response",format:"json",value:JSON.stringify(a.raw),sourcePath:a.sourcePath,captureLevel:"provider_exact"})),c.push(g),v.push(g)}t.usageRecords.length===0&&t.gaps.push({category:"provider_usage",reason:"provider_usage_missing",detail:`${x} native session usage is unavailable`});const I=new Map,A=new Map;for(const l of t.events){const a=f(l.event.toolCallId);a&&(l.event.type==="tool_use"&&I.set(a,l),l.event.type==="tool_result"&&A.set(a,l))}if(s.tools)for(const[l,a]of I){const g=A.get(l),z=[...v].reverse().find(T=>Date.parse(T.startedAt)<=Date.parse(a.observedAt))??v[0],P=M({job:n,spanId:`acp:${n.sessionId}:tool:${l}`,parentSpanId:z?.spanId??o,kind:"tool_call",name:f(a.event.toolName)??"tool",sequence:_++,status:g?"completed":"running",startedAt:a.observedAt,endedAt:g?.observedAt??n.endedAt,nativeEventType:"tool_use",nativeIds:{toolCallId:l},rawAttributes:{toolUseEvent:a.event,...g?{toolResultEvent:g.event}:{}}}),D=f(a.event.toolInput);D&&k(P.inputRefs,R(u,i,{role:"tool_arguments",format:"json",value:D,captureLevel:"runtime_exact"}));const E=f(g?.event.toolOutput)??f(g?.event.content);if(E){const T=R(u,i,{role:"tool_result",format:"text",value:E,captureLevel:"runtime_exact"});k(P.outputRefs,T);const $=v.find(G=>Date.parse(G.startedAt)>=Date.parse(g.observedAt));$&&k($.inputRefs,T)}c.push(P)}const w=t.events.filter(l=>l.event.type==="text").map(l=>f(l.event.content)??"").join(""),h=v.at(-1);if(s.inputOutput&&w&&h&&!h.outputRefs.some(l=>l.role==="assistant_text")&&k(h.outputRefs,R(u,i,{role:"assistant_text",format:"text",value:w,captureLevel:"runtime_exact"})),s.thinking&&h){const l=t.events.filter(a=>a.event.type==="thinking").map(a=>f(a.event.content)??"").join("");l&&k(h.outputRefs,R(u,i,{role:"thinking",format:"text",value:l,captureLevel:"runtime_exact"}))}return ne(c),{spans:c,contents:u,anomalies:t.anomalies,collection:t,capture:s}}async correlate(n,r){return r}validate(n,r){const t=r,s=t.spans.filter(d=>d.kind==="llm_request"),c=t.spans.filter(d=>d.kind==="tool_call"),u=!t.capture.inputOutput||n.input!==void 0,i=!t.capture.inputOutput||n.finalOutput!==void 0||s.some(d=>d.outputRefs.length>0),_=!t.capture.tools||c.every(d=>d.status!=="running"),x=s.length>0&&s.every(d=>d.usage?.completeness==="complete"),o=[...t.collection.gaps];t.capture.rawProviderBody&&o.push({category:"raw_provider_body",reason:"raw_capture_disabled",detail:"Generic ACP exposes agent events/native session records, not raw model HTTP bodies"});const m=u&&i&&_&&x&&o.length===0;return{status:s.length===0?"failed":m?"complete":"partial",inputComplete:u,outputComplete:i,toolCallsComplete:_,subagentsComplete:!0,usageComplete:x,rawRequestsComplete:!1,gaps:o}}}export{ie as GenericAcpAuditAdapter};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{readFile as Y,readdir as G,stat as ne}from"node:fs/promises";import{homedir as re}from"node:os";import{basename as se,dirname as J,join as q}from"node:path";import{referenceCaptureContent as Q}from"../../core/content-reference.js";const oe=Object.freeze({inputOutput:!0,tools:!0,subagents:!0,thinking:!0,rawProviderBody:!1});function R(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function d(e){return typeof e=="string"&&e.length>0?e:void 0}function B(e){return typeof e=="number"&&Number.isFinite(e)&&e>=0?e:void 0}function z(e){if(typeof e=="string")return e;try{return JSON.stringify(e)}catch{return String(e)}}function X(e){return e.options?.enabled===!0?e.options.capture:oe}function v(e,t){if(typeof e=="number"&&Number.isFinite(e)){const n=e>1e10?e:e*1e3,r=new Date(n);if(!Number.isNaN(r.getTime()))return r.toISOString()}return typeof e=="string"&&!Number.isNaN(Date.parse(e))?new Date(e).toISOString():t}function Z(e){return typeof e=="string"?e:Array.isArray(e)?e.map(t=>typeof t=="string"?t:R(t)?d(t.text)??d(t.think)??d(t.data)??"":"").join(""):""}function L(e){return e.record.type==="context.append_loop_event"&&R(e.record.event)?e.record.event:void 0}function ie(e,t){const n=Date.parse(v(e,""));return Number.isFinite(n)&&n>=Date.parse(t.startedAt)-5e3&&n<=Date.parse(t.endedAt)+3e4}async function j(e){const t=await Y(e,"utf8"),n=[];let r=0;for(const s of t.split(`
|
|
2
|
+
`)){const i=Buffer.byteLength(s);if(s.trim())try{const o=JSON.parse(s);R(o)&&n.push({record:o,sourcePath:e,sourceOffset:r,sourceLength:i})}catch{}r+=i+1}return n}function ae(e,t){const n=t.input?.value?.trim();let r=-1;if(n)for(let i=e.length-1;i>=0;i-=1){const o=e[i].record;if(o.type==="turn.prompt"&&Z(o.input).trim()===n){r=i;break}}if(r<0&&(r=e.findIndex(i=>i.record.type==="turn.prompt"&&ie(i.record.time,t))),r<0)return{lines:[],startIndex:r};const s=e.findIndex((i,o)=>o>r&&i.record.type==="turn.prompt");return{lines:e.slice(r,s<0?void 0:s),startIndex:r}}function ce(e){const t=d(e);if(!(!t||se(t)!==t||t==="."||t===".."))return t}async function de(e){const t=d(e.boundary.kimiWirePath);if(t)return J(J(J(t)));const n=ce(e.boundary.providerSessionId);if(!n)return;const r=q(d(process.env.KIMI_CODE_HOME)??q(re(),".kimi-code"),"sessions");let s;try{s=await G(r,{withFileTypes:!0})}catch{return}const i=[];for(const o of s){if(!o.isDirectory())continue;const u=q(r,o.name,n),f=q(u,"agents","main","wire.jsonl");try{const _=await ne(f);let I=!1;const m=d(e.boundary.cwd);if(m)try{const y=JSON.parse(await Y(q(u,"state.json"),"utf8"));I=R(y)&&(y.workDir===m||y.cwd===m)}catch{}i.push({path:u,cwdMatches:I,modifiedAt:_.mtimeMs})}catch{}}return i.sort((o,u)=>Number(u.cwdMatches)-Number(o.cwdMatches)||u.modifiedAt-o.modifiedAt),i[0]?.path}async function ue(e,t,n){const s=d(t.boundary.kimiWirePath)??q(e,"agents","main","wire.jsonl"),i=await j(s),o=ae(i,t),u=o.lines.at(-1)?.sourceOffset??Number.POSITIVE_INFINITY,f=i.filter(O=>O.record.type==="config.update"&&O.sourceOffset<=u),_=i.filter(O=>O.record.type==="llm.tools_snapshot"),I=o.lines.length>0?{agentId:"main",sourcePath:s,lines:o.lines}:void 0,m=[s],y=[];let h=!0;if(!n.subagents)return{main:I,subagents:y,configRecords:f,toolSnapshots:_,sourcePaths:m,subagentDiscoveryComplete:h};const p=q(e,"agents");try{const O=await G(p,{withFileTypes:!0}),U=o.lines[0]?.record.time,W=o.lines.at(-1)?.record.time,H=Date.parse(v(U,t.startedAt)),C=Date.parse(v(W,t.endedAt));for(const D of O){if(!D.isDirectory()||D.name==="main")continue;const c=q(p,D.name,"wire.jsonl");try{const l=(await j(c)).filter(A=>{const g=Date.parse(v(A.record.time,""));return Number.isFinite(g)&&g>=H-5e3&&g<=C+3e4});l.length>0&&(y.push({agentId:D.name,sourcePath:c,lines:l}),m.push(c))}catch{h=!1}}}catch{h=!1}return{main:I,subagents:y,configRecords:f,toolSnapshots:_,sourcePaths:m,subagentDiscoveryComplete:h}}function k(e,t,n){const r=[n.role,n.sourcePath??"",n.sourceOffset??"",n.value??""].join("\0");if(t.has(r))return t.get(r);const s=Q(n);return t.set(r,s),e.push(n),s}function w(e,t){t&&!e.some(n=>n.contentId===t.contentId)&&e.push(t)}function T(e,t,n,r,s="provider_exact"){return{role:t,format:n,value:r,sourcePath:e.sourcePath,sourceOffset:e.sourceOffset,sourceLength:e.sourceLength,captureLevel:s}}function N(e){const t=e.endedAt,n=Date.parse(e.startedAt),r=t?Date.parse(t):Number.NaN;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:e.startedAt,...t?{endedAt:t}:{},...Number.isFinite(n)&&Number.isFinite(r)?{durationMs:Math.max(0,r-n)}:{},inputRefs:[],outputRefs:[],provider:{provider:"acp",nativeEventType:e.nativeEventType,nativeIds:Object.fromEntries(Object.entries(e.nativeIds??{}).filter(s=>typeof s[1]=="string")),...e.rawAttributes?{rawAttributes:e.rawAttributes}:{}},provenance:{source:"provider_transcript",accuracy:"provider_reported"}}}function pe(e){if(!R(e))return;const t=B(e.inputOther),n=B(e.inputCacheRead),r=B(e.inputCacheCreation),s=B(e.output);if(t===void 0||n===void 0||r===void 0||s===void 0)return;const i=t+n+r;return{input:{total:i,uncached:t,cacheRead:n,cacheWrite:r,other:0},output:{total:s,reasoning:null,visible:null},totalProcessed:i+s,requestCount:1,accuracy:"provider_reported",completeness:"complete",provider:"acp",providerUsageRaw:e,normalization:{adapter:"kimi",version:1,formula:"input=inputOther+inputCacheRead+inputCacheCreation; output=output"}}}function le(e){const t=[],n=new Map,r=new Map;let s;for(const i of e){const o=L(i);if(o?.type==="step.begin"){const u=d(o.uuid)??`offset-${i.sourceOffset}`;s={stepUuid:u,turnId:d(o.turnId),step:B(o.step),begin:i,requests:[],parts:[],toolCalls:[]},t.push(s),n.set(u,s);continue}if(i.record.type==="llm.request"){s?.requests.push(i);continue}if(o?.type==="step.end"){const u=n.get(d(o.uuid)??"")??s;u&&(u.end=i),u===s&&(s=void 0);continue}if(o?.type==="content.part"){(n.get(d(o.stepUuid)??"")??s)?.parts.push(i);continue}if(o?.type==="tool.call"){const u=d(o.toolCallId);(n.get(d(o.stepUuid)??"")??s)?.toolCalls.push(i),u&&r.set(u,{line:i,event:o});continue}if(o?.type==="tool.result"){const u=d(o.toolCallId),f=u?r.get(u):void 0;f&&(f.result=i)}}return{steps:t,tools:r}}function ee(e,t){return e.configRecords.filter(n=>t===void 0||n.sourcePath!==t.sourcePath||n.sourceOffset<=t.sourceOffset).at(-1)?.record}function fe(e,t){const n=d(e.record.toolsHash),r=n?t.toolSnapshots.find(i=>i.record.hash===n)?.record:void 0,s=ee(t,e);return{...e.record,...e.record.systemPrompt===void 0&&s?.systemPrompt!==void 0?{systemPrompt:s.systemPrompt}:{},...r?{tools:r.tools}:{}}}function me(e){const t=R(e.result)?e.result:{},n=d(t.output);return{format:n?"text":"json",value:n??z(e.result),failed:t.isError===!0||t.error!==void 0}}function te(e,t,n,r,s,i,o,u,f,_,I){const m=v(n.lines[0]?.record.time,e.startedAt),y=v(n.lines.at(-1)?.record.time,e.endedAt),h=n.lines.find(c=>c.record.type==="turn.prompt");let p,O=_,U;if(I&&(p=N({job:e,spanId:`kimi:${e.sessionId}:subagent:${n.agentId}`,parentSpanId:_,kind:"subagent",name:`Kimi subagent ${n.agentId}`,sequence:f.value++,startedAt:m,endedAt:y,nativeEventType:"agent/wire.jsonl",nativeIds:{agentId:n.agentId,providerSessionId:d(e.boundary.providerSessionId)},rawAttributes:{sourcePath:n.sourcePath}}),o.push(p),O=p.spanId),r.inputOutput&&h){const c=Z(h.record.input);c&&(U=k(s,i,T(h,I?"subagent_prompt":"user_input","text",c)),w(I?p.inputRefs:o[0].inputRefs,U))}const{steps:W,tools:H}=le(n.lines),C=[];for(const[c,a]of W.entries()){const l=a.requests.at(-1)??a.begin,A=l.record,g=a.end?L(a.end):void 0,S=d(g?.messageId)??a.stepUuid,$=d(A.model),M=$??"kimi",F=v(a.begin.record.time,m),V=a.end?v(a.end.record.time,y):y,P=N({job:e,spanId:`kimi:${e.sessionId}:${n.agentId}:request:${S}`,parentSpanId:O,kind:"llm_request",name:M,sequence:f.value++,status:a.end?"completed":"running",startedAt:F,endedAt:V,nativeEventType:"llm.request",nativeIds:{requestId:S,stepUuid:a.stepUuid,providerTurnId:a.turnId,responseId:d(g?.messageId),traceId:d(g?.traceId)},rawAttributes:{sourcePath:l.sourcePath,sourceOffset:l.sourceOffset,provider:A.provider,modelAlias:A.modelAlias,finishReason:g?.finishReason,providerFinishReason:g?.providerFinishReason,rawFinishReason:g?.rawFinishReason,llmFirstTokenLatencyMs:g?.llmFirstTokenLatencyMs,llmStreamDurationMs:g?.llmStreamDurationMs,attemptCount:Math.max(1,a.requests.length)}});$&&(P.modelId=$),P.usage=pe(g?.usage),P.usage||t.gaps.push({category:"provider_usage",reason:"provider_usage_missing",detail:`${n.agentId}:${S}`}),c===0&&(I?w(P.inputRefs,U):e.input&&w(P.inputRefs,Q(e.input))),r.rawProviderBody&&l.record.type==="llm.request"&&w(P.inputRefs,k(s,i,T(l,"model_request","json",z(fe(l,t)),"reconstructed")));for(const x of a.parts){const E=L(x),b=R(E?.part)?E.part:void 0;if(b){if(b.type==="think"&&r.thinking){const K=d(b.think)??d(b.text);K&&w(P.outputRefs,k(s,i,T(x,"thinking","text",K)))}if(b.type==="text"&&r.inputOutput){const K=d(b.text);K&&w(P.outputRefs,k(s,i,T(x,"assistant_text","text",K)))}}}r.rawProviderBody&&a.end&&w(P.outputRefs,k(s,i,T(a.end,"model_response","json",z({parts:a.parts.map(x=>L(x)?.part),stepEnd:g}),"reconstructed"))),o.push(P),C.push(P);for(let x=0;x<a.requests.length-1;x+=1){const E=a.requests[x],b=a.requests[x+1];o.push(N({job:e,spanId:`kimi:${e.sessionId}:${n.agentId}:retry:${a.stepUuid}:${x+1}`,parentSpanId:P.spanId,kind:"retry",name:`Kimi request retry ${x+1}`,sequence:f.value++,startedAt:v(E.record.time,F),endedAt:v(b.record.time,V),nativeEventType:"llm.request",nativeIds:{stepUuid:a.stepUuid,attempt:d(E.record.attempt)??String(x+1)},rawAttributes:{projection:E.record.projection,request:E.record}}))}}if(r.tools)for(const[c,a]of H){const l=a.event,A=a.result?L(a.result):void 0,g=C.find(M=>M.provider.nativeIds.stepUuid===d(l.stepUuid))??C.at(-1),S=A?me(A):void 0,$=N({job:e,spanId:`kimi:${e.sessionId}:${n.agentId}:tool:${c}`,parentSpanId:g?.spanId??O,kind:"tool_call",name:d(l.name)??"tool",sequence:f.value++,status:S?S.failed?"failed":"completed":"running",startedAt:v(a.line.record.time,m),endedAt:a.result?v(a.result.record.time,y):y,nativeEventType:"context.append_loop_event/tool.call",nativeIds:{toolCallId:c,stepUuid:d(l.stepUuid),providerTurnId:d(l.turnId),traceId:d(l.traceId??A?.traceId)},rawAttributes:{description:l.description,display:l.display,extras:l.extras,hasResult:!!A}});if(w($.inputRefs,k(s,i,T(a.line,"tool_arguments","json",z(l.args)))),S&&a.result){const M=k(s,i,T(a.result,"tool_result",S.format,S.value));w($.outputRefs,M);const F=g?C.indexOf(g):-1;F>=0&&w(C[F+1]?.inputRefs??[],M)}else t.gaps.push({category:"tool_result",reason:"correlation_failed",detail:`${n.agentId}:${c}`});o.push($)}for(const c of n.lines)if(c.record.type==="permission.record_approval_result"){const a=R(c.record.result)?c.record.result:{},l=d(a.decision)??"unknown";o.push(N({job:e,spanId:`kimi:${e.sessionId}:${n.agentId}:permission:${c.sourceOffset}`,parentSpanId:O,kind:"permission",name:d(c.record.toolName)??"Kimi tool approval",sequence:f.value++,status:l==="approved"?"completed":"cancelled",startedAt:v(c.record.time,m),endedAt:v(c.record.time,m),nativeEventType:"permission.record_approval_result",nativeIds:{toolCallId:d(c.record.toolCallId),providerTurnId:d(c.record.turnId)},rawAttributes:{action:c.record.action,result:c.record.result}}))}const D=[];for(const c of n.lines){if(c.record.type==="full_compaction.begin"){D.push(c);continue}if(c.record.type!=="full_compaction.complete"&&c.record.type!=="full_compaction.cancel"&&c.record.type!=="micro_compaction.apply")continue;const a=c.record.type==="micro_compaction.apply"?c:D.shift()??c;o.push(N({job:e,spanId:`kimi:${e.sessionId}:${n.agentId}:compaction:${a.sourceOffset}`,parentSpanId:O,kind:"compaction",name:c.record.type==="micro_compaction.apply"?"Kimi micro compaction":"Kimi full compaction",sequence:f.value++,status:c.record.type==="full_compaction.cancel"?"cancelled":"completed",startedAt:v(a.record.time,m),endedAt:v(c.record.time,y),nativeEventType:c.record.type,rawAttributes:{begin:a.record,completion:c.record}}))}if(I&&p&&C.flatMap(a=>a.outputRefs).filter(a=>a.role==="assistant_text").length>0){const a=n.lines.flatMap(l=>{const A=L(l),g=R(A?.part)?A.part:void 0;return g?.type==="text"&&typeof g.text=="string"?[g.text]:[]}).join("");a&&w(p.outputRefs,k(s,i,{role:"subagent_result",format:"text",value:a,sourcePath:n.sourcePath,captureLevel:"provider_exact"}))}W.length===0&&u.push({code:"kimi_llm_step_missing",message:`No Kimi model step was found for agent ${n.agentId}`,providerIds:{agentId:n.agentId}})}class ve{provider="acp";async collect(t){const n=X(t),r=[],s=[],i=await de(t);if(!i)return{subagents:[],configRecords:[],toolSnapshots:[],sourcePaths:[],anomalies:s,gaps:[{category:"provider_transcript",reason:"source_log_missing",detail:"Kimi session directory could not be located"}],subagentDiscoveryComplete:!1};try{const o=await ue(i,t,n);return o.main||r.push({category:"provider_transcript",reason:"correlation_failed",detail:"Kimi wire.jsonl was found, but the audited turn prompt was not correlated"}),n.subagents&&!o.subagentDiscoveryComplete&&r.push({category:"subagents",reason:"source_log_missing",detail:"One or more Kimi subagent wire logs could not be enumerated or read"}),{...o,anomalies:s,gaps:r}}catch(o){return{subagents:[],configRecords:[],toolSnapshots:[],sourcePaths:[],anomalies:[{code:"kimi_wire_read_failed",message:String(o)}],gaps:[{category:"provider_transcript",reason:"source_log_missing",detail:String(o)}],subagentDiscoveryComplete:!1}}}async normalize(t,n){const r=n,s=X(t),i=[],o=new Map,u=[],f=[...r.anomalies],_={value:0},I=`kimi:${t.turnId}:turn`,m=N({job:t,spanId:I,kind:"turn",name:"Kimi audited turn",sequence:_.value++,status:t.outcome==="completed"?"completed":t.outcome==="cancelled"?"cancelled":"failed",startedAt:t.startedAt,endedAt:t.endedAt,nativeEventType:"turn.prompt",nativeIds:{providerSessionId:d(t.boundary.providerSessionId),platformEventId:d(t.boundary.platformEventId)}});u.push(m),s.inputOutput&&t.input&&w(m.inputRefs,k(i,o,{...t.input,captureLevel:t.input.captureLevel??"runtime_exact"})),s.inputOutput&&t.finalOutput&&w(m.outputRefs,k(i,o,{...t.finalOutput,captureLevel:t.finalOutput.captureLevel??"runtime_exact"}));const y=ee(r);if(s.rawProviderBody&&y){const h=d(y.systemPrompt??y.system_prompt),p=r.configRecords.at(-1);h&&p&&w(m.inputRefs,k(i,o,T(p,"system_prompt","text",h)))}r.main&&te(t,r,r.main,s,i,o,u,f,_,I,!1);for(const h of r.subagents)te(t,r,h,s,i,o,u,f,_,I,!0);return u.sort((h,p)=>Date.parse(h.startedAt)-Date.parse(p.startedAt)||h.sequence-p.sequence),u.forEach((h,p)=>{h.sequence=p}),{spans:u,contents:i,anomalies:f,collection:r,capture:s}}async correlate(t,n){return n}validate(t,n){const r=n,s=r.spans.filter(p=>p.kind==="llm_request"),i=r.spans.filter(p=>p.kind==="tool_call"),o=!r.capture.inputOutput||t.input!==void 0||r.contents.some(p=>p.role==="user_input"),u=!r.capture.inputOutput||t.finalOutput!==void 0||r.contents.some(p=>p.role==="assistant_text"),f=!r.capture.tools||i.every(p=>p.status!=="running"),_=!r.capture.subagents||r.collection.subagentDiscoveryComplete,I=s.length>0&&s.every(p=>p.usage?.completeness==="complete"),m=!1,y=[...r.collection.gaps];r.capture.rawProviderBody&&y.push({category:"raw_provider_body",reason:"raw_capture_disabled",detail:"Kimi wire.jsonl reconstructs logical requests and responses but does not retain raw HTTP bodies"});const h=o&&u&&f&&_&&I&&(!r.capture.rawProviderBody||m)&&y.length===0;return{status:!r.collection.main||s.length===0?"failed":h?"complete":"partial",inputComplete:o,outputComplete:u,toolCallsComplete:f,subagentsComplete:_,usageComplete:I,rawRequestsComplete:m,gaps:y}}}export{ve as KimiAuditAdapter};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{referenceCaptureContent as N}from"../../core/content-reference.js";import{InvalidReasonixUsageError as F,normalizeReasonixUsage as z}from"../../core/usage.js";import{collectReasonixTranscript as B}from"./reasonix-transcript-source.js";const H=Object.freeze({inputOutput:!0,tools:!0,subagents:!0,thinking:!0,rawProviderBody:!1});function V(t){return typeof t=="object"&&t!==null&&!Array.isArray(t)}function u(t){return typeof t=="string"&&t.length>0?t:void 0}function E(t,e){const s=u(t);return s&&Number.isFinite(Date.parse(s))?s:e}function G(t){return t.options?.enabled===!0?t.options.capture:H}function S(t,e,s,n){return{role:e,format:s,value:n,sourcePath:t.sourcePath,sourceOffset:t.sourceOffset,sourceLength:t.sourceLength,captureLevel:"provider_exact"}}function R(t,e,s){const n=[s.role,s.sourcePath??"",s.sourceOffset??"",s.value??""].join("\0");if(e.has(n))return e.get(n);const o=N(s);return e.set(n,o),t.push(s),o}function A(t,e){e&&(t.some(s=>s.contentId===e.contentId)||t.push(e))}function b(t){const e=t.startedAt??t.job.startedAt,s=t.endedAt??t.job.endedAt,n=Date.parse(e),o=Date.parse(s);return{spanId:t.spanId,traceId:t.job.traceId,turnId:t.job.turnId,sessionId:t.job.sessionId,...t.parentSpanId?{parentSpanId:t.parentSpanId}:{},kind:t.kind,name:t.name,sequence:t.sequence,status:t.status??"completed",startedAt:e,endedAt:s,...Number.isFinite(n)&&Number.isFinite(o)?{durationMs:Math.max(0,o-n)}:{},inputRefs:[],outputRefs:[],provider:{provider:"acp",nativeEventType:t.nativeEventType,nativeIds:Object.fromEntries(Object.entries(t.nativeIds??{}).filter(h=>typeof h[1]=="string")),...t.rawAttributes?{rawAttributes:t.rawAttributes}:{}},provenance:{source:"provider_transcript",accuracy:"provider_reported"}}}class W{provider="acp";async collect(e){return B(e.boundary)}async normalize(e,s){const n=s,o=G(e),h=[...n.anomalies],f=[],m=new Map,g=[];let q=0;const y=`reasonix:${e.turnId}:turn`,x=b({job:e,spanId:y,kind:"turn",name:"Reasonix audited turn",sequence:q++,status:e.outcome==="completed"?"completed":e.outcome==="cancelled"?"cancelled":"failed",nativeEventType:"acp_turn",nativeIds:{platformEventId:u(e.boundary.platformEventId),providerSessionId:u(e.boundary.providerSessionId)}});g.push(x);let c;o.inputOutput&&e.input&&(c=R(f,m,{...e.input,captureLevel:e.input.captureLevel??"runtime_exact"}),A(x.inputRefs,c)),o.inputOutput&&e.finalOutput&&A(x.outputRefs,R(f,m,{...e.finalOutput,captureLevel:e.finalOutput.captureLevel??"runtime_exact"}));const D=n.acpEvents.filter(({event:r})=>r.type==="tool_use"),U=new Map(n.acpEvents.filter(({event:r})=>r.type==="tool_result"&&typeof r.toolCallId=="string").map(r=>[String(r.event.toolCallId),r]));let M=0,O=e.startedAt,k,T=c?[c]:[];for(const r of n.lines){const a=r.record,i=u(a.role),p=E(a.ts,O);if(i==="assistant_final"){const v=typeof a.turn=="number"?String(a.turn):`offset-${r.sourceOffset}`,l=`reasonix-${v}-${r.sourceOffset}`,I=u(a.model),d=b({job:e,spanId:`reasonix:${e.sessionId}:request:${l}`,parentSpanId:y,kind:"llm_request",name:I??"Reasonix model request",sequence:q++,startedAt:O,endedAt:p,nativeEventType:i,nativeIds:{requestId:l,providerTurn:v,providerSessionId:u(e.boundary.providerSessionId)},rawAttributes:{sourcePath:r.sourcePath,sourceOffset:r.sourceOffset,...I?{model:I}:{}}});I&&(d.modelId=I);for(const _ of T)A(d.inputRefs,_);if(T=[],V(a.usage))try{d.usage=z(a.usage)}catch(_){h.push({code:"reasonix_provider_usage_invalid",message:_ instanceof F?_.message:String(_),spanId:d.spanId,providerIds:{requestId:l}}),n.gaps.push({category:"provider_usage",reason:"provider_usage_missing",detail:l})}else n.gaps.push({category:"provider_usage",reason:"provider_usage_missing",detail:l});const C=u(a.content);o.inputOutput&&C&&A(d.outputRefs,R(f,m,S(r,"assistant_text","text",C))),g.push(d),k=d,O=p;continue}if(i==="tool"&&o.tools){const v=D[M++],l=u(v?.event.toolCallId)??`offset-${r.sourceOffset}`,I=u(a.tool)??u(v?.event.toolName)??"tool",d=U.get(l),C=E(v?.observedAt,O),_=E(d?.observedAt,p),w=b({job:e,spanId:`reasonix:${e.sessionId}:tool:${l}`,parentSpanId:k?.spanId??y,kind:"tool_call",name:I,sequence:q++,status:a.error?"failed":"completed",startedAt:C,endedAt:_,nativeEventType:i,nativeIds:{toolCallId:l,requestId:k?.provider.nativeIds.requestId},rawAttributes:{sourcePath:r.sourcePath,sourceOffset:r.sourceOffset}}),P=u(a.args)??u(v?.event.toolInput);P&&A(w.inputRefs,R(f,m,S(r,"tool_arguments","json",P)));const $=u(a.content)??u(d?.event.toolOutput)??u(d?.event.content);if($){const L=R(f,m,S(r,"tool_result","text",$));A(w.outputRefs,L),A(T,L)}g.push(w),O=p;continue}O=p}if(o.thinking){const r=g.filter(i=>i.kind==="llm_request").sort((i,p)=>Date.parse(i.endedAt??e.endedAt)-Date.parse(p.endedAt??e.endedAt)),a=new Map;for(const i of n.acpEvents){if(i.event.type!=="thinking")continue;const p=u(i.event.content);if(!p)continue;const v=Date.parse(i.observedAt),l=r.find(I=>{const d=Date.parse(I.endedAt??e.endedAt);return!Number.isFinite(v)||!Number.isFinite(d)||v<=d})??r.at(-1);l&&a.set(l.spanId,`${a.get(l.spanId)??""}${p}`)}for(const i of r){const p=a.get(i.spanId);p&&A(i.outputRefs,R(f,m,{role:"thinking",format:"text",value:p,captureLevel:"runtime_exact"}))}}return{spans:g,contents:f,anomalies:h,collection:n,capture:o}}async correlate(e,s){return s}validate(e,s){const n=s,o=n.spans.filter(c=>c.kind==="llm_request"),h=n.spans.filter(c=>c.kind==="tool_call"),f=!n.capture.inputOutput||e.input!==void 0,m=!n.capture.inputOutput||e.finalOutput!==void 0||n.contents.some(c=>c.role==="assistant_text"),g=!n.capture.tools||h.every(c=>c.status!=="running"),q=o.length>0&&o.every(c=>c.usage?.completeness==="complete"),y=[...n.collection.gaps];n.capture.rawProviderBody&&y.push({category:"raw_provider_body",reason:"raw_capture_disabled",detail:"Reasonix transcript does not retain raw provider HTTP bodies"});const x=f&&m&&g&&q&&y.length===0;return{status:n.collection.lines.length===0||o.length===0?"failed":x?"complete":"partial",inputComplete:f,outputComplete:m,toolCallsComplete:g,subagentsComplete:!0,usageComplete:q,rawRequestsComplete:!1,gaps:y}}}export{W as ReasonixAuditAdapter};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{open as y,stat as b}from"node:fs/promises";function u(s){return typeof s=="object"&&s!==null&&!Array.isArray(s)}function m(s,e){return typeof s=="number"&&Number.isSafeInteger(s)&&s>=0?s:e}function v(s,e){const r=u(s.acpEvidence)?s.acpEvidence:void 0;if(!(!r||!Array.isArray(r.events))){for(const t of r.events){if(!u(t)||!u(t.event)||typeof t.sequence!="number"||typeof t.observedAt!="string"){e.anomalies.push({code:"reasonix_acp_event_malformed",message:"ACP evidence row is missing sequence, observedAt, or event"}),e.gaps.push({category:"acp_event",reason:"correlation_failed"});continue}e.acpEvents.push({sequence:t.sequence,observedAt:t.observedAt,event:t.event})}e.acpEvents.sort((t,a)=>t.sequence-a.sequence)}}async function x(s){const e=typeof s.transcriptPath=="string"?s.transcriptPath:void 0,r={lines:[],acpEvents:[],anomalies:[],gaps:[],sourcePaths:e?[e]:[]};if(v(s,r),!e)return r.anomalies.push({code:"reasonix_transcript_path_missing",message:"boundary.transcriptPath is required"}),r.gaps.push({category:"main_transcript",reason:"source_log_missing",detail:"boundary.transcriptPath is missing"}),r;try{const t=await b(e),a=m(s.transcriptStartOffset,0),d=typeof s.transcriptEndOffset=="number"?m(s.transcriptEndOffset,t.size):t.size;if(a>t.size)return r.anomalies.push({code:"reasonix_transcript_boundary_out_of_range",message:`${e}: start ${a} exceeds size ${t.size}`}),r.gaps.push({category:"main_transcript",reason:"correlation_failed",detail:`${e}:${a}-${d}`}),r;const p=a,f=Math.min(Math.max(d,p),t.size)-p;if(f===0)return r;const h=await y(e,"r");let n;try{n=Buffer.allocUnsafe(f);const{bytesRead:o}=await h.read(n,0,f,p);n=n.subarray(0,o)}finally{await h.close()}let c=0;for(;c<n.length;){const o=n.indexOf(10,c),_=o===-1?n.length:o+1,l=n.subarray(c,o===-1?n.length:o),g=p+c;if(c=_,l.length!==0)try{const i=JSON.parse(l.toString("utf8"));if(!u(i))throw new Error("JSONL row is not an object");r.lines.push({record:i,sourcePath:e,sourceOffset:g,sourceLength:l.length})}catch(i){r.anomalies.push({code:"reasonix_transcript_row_malformed",message:`${e}:${g}: ${i instanceof Error?i.message:String(i)}`}),r.gaps.push({category:"transcript_row",reason:"correlation_failed",detail:`${e}:${g}`})}}}catch(t){r.anomalies.push({code:"reasonix_transcript_source_unreadable",message:`${e}: ${t instanceof Error?t.message:String(t)}`}),r.gaps.push({category:"main_transcript",reason:"source_log_missing",detail:e})}return r}export{x as collectReasonixTranscript};
|
|
@@ -0,0 +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};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{open as M,readFile as O,stat as q}from"node:fs/promises";import{basename as B,resolve as h,sep as T}from"node:path";const V=32*1024*1024,L=128*1024*1024;function _(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function $(e,s){return typeof e=="number"&&Number.isSafeInteger(e)&&e>=0?e:s}function f(e){return typeof e=="string"&&e.length>0?e:void 0}function E(e){const s=_(e)?e:void 0;if(!s)return e;for(const n of["stringValue","boolValue","intValue","doubleValue","bytesValue"])if(Object.hasOwn(s,n)){const u=s[n];if(n==="intValue"&&typeof u=="string"){const i=Number(u);return Number.isSafeInteger(i)?i:u}return u}const c=_(s.arrayValue)&&Array.isArray(s.arrayValue.values)?s.arrayValue.values.map(E):void 0;return c||e}function R(e){return Array.isArray(e)?Object.fromEntries(e.flatMap(s=>{const c=_(s)?s:void 0,n=f(c?.key);return n?[[n,E(c?.value)]]:[]})):{}}async function G(e,s,c,n){const u=[],i=[],y=[];try{const r=await q(e),p=Math.min(s,r.size),g=Math.min(Math.max(c??r.size,p),r.size);if(g===p)return y.push({category:n,reason:"source_log_missing",detail:`${e} contained no events in the audited boundary`}),{payloads:u,anomalies:i,gaps:y};const a=await M(e,"r");let l;try{l=Buffer.allocUnsafe(g-p);const{bytesRead:t}=await a.read(l,0,l.length,p);l=l.subarray(0,t)}finally{await a.close()}for(const[t,o]of l.toString("utf8").split(`
|
|
2
|
+
`).entries())if(o.trim())try{const d=JSON.parse(o);if(!_(d))throw new Error("OTLP JSONL row is not an object");u.push(d)}catch(d){i.push({code:"claude_otel_row_malformed",message:`${e}:row-${t+1}: ${d instanceof Error?d.message:String(d)}`}),y.push({category:n,reason:"correlation_failed",detail:`${e}:row-${t+1}`})}}catch(r){i.push({code:"claude_otel_source_unreadable",message:`${e}: ${r instanceof Error?r.message:String(r)}`}),y.push({category:n,reason:"source_log_missing",detail:e})}return{payloads:u,anomalies:i,gaps:y}}function P(e){const s=_(e.payload)?e.payload:e,c=f(e.observedAt),n=[],u=Array.isArray(s.resourceLogs)?s.resourceLogs:[];for(const i of u){const y=_(i)&&Array.isArray(i.scopeLogs)?i.scopeLogs:[];for(const r of y){const p=_(r)&&Array.isArray(r.logRecords)?r.logRecords:[];for(const g of p){const a=_(g)?g:void 0;if(!a)continue;const l=R(a.attributes),t=E(a.body),o=f(l["event.name"])??f(t)??"claude_code.event";n.push({signal:"logs",name:o.startsWith("claude_code.")?o:`claude_code.${o}`,observedAt:f(l["event.timestamp"])??c,traceId:f(a.traceId),spanId:f(a.spanId),attributes:l})}}}return n}function X(e){const s=_(e.payload)?e.payload:e,c=f(e.observedAt),n=[],u=Array.isArray(s.resourceSpans)?s.resourceSpans:[];for(const i of u){const y=_(i)&&Array.isArray(i.scopeSpans)?i.scopeSpans:[];for(const r of y){const p=_(r)&&Array.isArray(r.spans)?r.spans:[];for(const g of p){const a=_(g)?g:void 0;a&&n.push({signal:"traces",name:f(a.name)??"claude_code.span",observedAt:c,traceId:f(a.traceId),spanId:f(a.spanId),parentSpanId:f(a.parentSpanId),attributes:R(a.attributes)})}}}return n}function k(e,s){if(!s)return!0;const c=h(s),n=h(e);return n===c||n.startsWith(`${c}${T}`)}async function F(e,s,c,n,u){const i=Array.isArray(e.rawApiBodyPaths)?e.rawApiBodyPaths.filter(t=>typeof t=="string"&&t.length>0):[],y=f(e.rawApiBodyDirectory),r=new Map;for(const t of s){const o=f(t.attributes.body_ref);o&&r.set(h(o),t)}const p=[];let g=0;for(const t of i){if(!k(t,y)){c.push({code:"claude_raw_api_body_outside_boundary",message:`Raw API body is outside the configured evidence directory: ${t}`}),n.push({category:"raw_provider_body",reason:"correlation_failed",detail:t});continue}const o=t.endsWith(".request.json")?"request":t.endsWith(".response.json")?"response":void 0;if(o)try{const d=await q(t);if(g+=d.size,d.size>V||g>L)throw new Error("raw API body capture limit exceeded");const m=await O(t,"utf8");let b,v;try{const A=JSON.parse(m);if(o==="response")b=_(A)?f(A.id):void 0;else if(_(A)&&Array.isArray(A.messages)){const I=A.messages.at(-1),N=_(I)?I.content:void 0;typeof N=="string"&&N.startsWith("[SUGGESTION MODE:")&&(v="prompt_suggestion")}}catch{}const w=r.get(h(t)),S=w?.attributes["event.sequence"];p.push({kind:o,sourcePath:t,value:m,providerMessageId:b,querySource:f(w?.attributes.query_source)??v,eventSequence:typeof S=="number"&&Number.isSafeInteger(S)?S:void 0}),u.push(t)}catch(d){c.push({code:"claude_raw_api_body_unreadable",message:`${t}: ${d instanceof Error?d.message:String(d)}`}),n.push({category:"raw_provider_body",reason:"source_log_missing",detail:t})}}p.sort((t,o)=>(t.eventSequence??Number.MAX_SAFE_INTEGER)-(o.eventSequence??Number.MAX_SAFE_INTEGER));const a=[],l=new Map;for(const t of p){const o=t.querySource??"<unknown>";if(t.kind==="request"){const m=l.get(o)??[];m.push(t),l.set(o,m);continue}let d=l.get(o)??[];d.length===0&&o==="<unknown>"&&(d=[...l.values()].filter(m=>m.length>0).sort((m,b)=>(m.at(-1)?.eventSequence??Number.MAX_SAFE_INTEGER)-(b.at(-1)?.eventSequence??Number.MAX_SAFE_INTEGER)).at(-1)??[]),a.push({request:d.pop(),response:t})}for(const t of l.values())a.push(...t.map(o=>({request:o})));return a.sort((t,o)=>(t.request?.eventSequence??t.response?.eventSequence??Number.MAX_SAFE_INTEGER)-(o.request?.eventSequence??o.response?.eventSequence??Number.MAX_SAFE_INTEGER)),a}async function x(e){const s=[],c=[],n=[],u=[];for(const y of["logs","traces"]){const r=y==="logs"?"Logs":"Traces",p=f(e[`otel${r}Path`]);if(!p)continue;n.push(p);const g=await G(p,$(e[`otel${r}StartOffset`],0),typeof e[`otel${r}EndOffset`]=="number"?$(e[`otel${r}EndOffset`],0):void 0,`otel_${y}`);s.push(...g.anomalies),c.push(...g.gaps);for(const a of g.payloads)u.push(...y==="logs"?P(a):X(a))}const i=await F(e,u,s,c,n);return{events:u,rawApiPairs:i,anomalies:s,gaps:c,sourcePaths:n}}function z(e){return B(e.sourcePath)}export{x as collectClaudeOtelEvidence,z as rawBodyLabel};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{open as x,readdir as S,stat as P}from"node:fs/promises";import{basename as b,join as E}from"node:path";function m(t,r){return typeof t=="number"&&Number.isSafeInteger(t)&&t>=0?t:r}function h(t){return typeof t=="object"&&t!==null&&!Array.isArray(t)}async function I(t,r,s,n){const p=[],a=[],e=[];try{const o=await P(t),u=Math.min(r,o.size),c=Math.min(Math.max(s??o.size,u),o.size)-u;if(c===0)return{lines:p,anomalies:a,gaps:e};const l=await x(t,"r");let i;try{i=Buffer.allocUnsafe(c);const{bytesRead:d}=await l.read(i,0,c,u);i=i.subarray(0,d)}finally{await l.close()}let g=0,O;for(;g<i.length;){const d=i.indexOf(10,g),$=d===-1?i.length:d+1,y=i.subarray(g,d===-1?i.length:d),w=u+g;if(g=$,y.length!==0)try{const f=JSON.parse(y.toString("utf8"));if(!h(f))throw new Error("JSONL row is not an object");typeof f.promptId=="string"&&f.promptId.length>0&&(O=f.promptId),p.push({record:f,sourcePath:t,sourceOffset:w,sourceLength:y.length,isSubagent:n,promptId:O})}catch(f){a.push({code:"claude_transcript_row_malformed",message:`${t}:${w}: ${f instanceof Error?f.message:String(f)}`}),e.push({category:"transcript_row",reason:"correlation_failed",detail:`${t}:${w}`})}}}catch(o){a.push({code:"claude_transcript_source_unreadable",message:`${t}: ${o instanceof Error?o.message:String(o)}`}),e.push({category:n?"subagent_transcript":"main_transcript",reason:"source_log_missing",detail:t})}return{lines:p,anomalies:a,gaps:e}}async function R(t){const r=[];async function s(n){const p=await S(n,{withFileTypes:!0});for(const a of p){const e=E(n,a.name);a.isDirectory()?await s(e):a.isFile()&&/^agent-.*\.jsonl$/u.test(b(a.name))&&r.push(e)}}return await s(t),r.sort((n,p)=>n.localeCompare(p))}function j(t){for(const r of t){const{record:s}=r;if(s.type!=="user"||typeof s.promptId!="string")continue;const n=h(s.origin)?s.origin:void 0;if(n?.kind==="channel"&&n.server==="grix")return s.promptId}}function z(t){if(typeof t=="number")return{startOffset:m(t,0)};if(!h(t))return{startOffset:0};const r=m(t.endOffset,-1);return{startOffset:m(t.startOffset,0),endOffset:r>=0?r:void 0}}async function F(t,r){const s=typeof t.transcriptPath=="string"?t.transcriptPath:void 0;if(!s)return{lines:[],anomalies:[{code:"claude_transcript_path_missing",message:"boundary.transcriptPath is required"}],gaps:[{category:"main_transcript",reason:"source_log_missing",detail:"boundary.transcriptPath is missing"}],sourcePaths:[]};const n=await I(s,m(t.transcriptStartOffset,0),typeof t.transcriptEndOffset=="number"?m(t.transcriptEndOffset,0):void 0,!1),a=(typeof t.promptId=="string"?t.promptId:void 0)??j(n.lines),e={targetPromptId:a,lines:[...n.lines],anomalies:[...n.anomalies],gaps:[...n.gaps],sourcePaths:[s]};a||(e.anomalies.push({code:"claude_prompt_id_missing",message:"Unable to identify the audited prompt from the transcript boundary"}),e.gaps.push({category:"prompt_correlation",reason:"correlation_failed"}));const o=typeof t.subagentRoot=="string"?t.subagentRoot:void 0;if(!r||!o)return e;let u;try{u=await R(o)}catch(c){return e.anomalies.push({code:"claude_subagent_root_unreadable",message:`${o}: ${c instanceof Error?c.message:String(c)}`}),e.gaps.push({category:"subagent_transcript",reason:"source_log_missing",detail:o}),e}const _=h(t.subagentOffsets)?t.subagentOffsets:{};for(const c of u){const l=z(_[c]??_[b(c)]),i=await I(c,l.startOffset,l.endOffset,!0);e.sourcePaths.push(c),e.lines.push(...i.lines),e.anomalies.push(...i.anomalies),e.gaps.push(...i.gaps)}return e}export{F as collectClaudeTranscript};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{normalizeClaudeUsage as l}from"../../core/usage.js";function a(n,o){const e=n[o];return typeof e=="number"&&Number.isFinite(e)&&e>=0?e:void 0}function d(n,o){const e=n[o];return e===void 0?0:typeof e=="number"&&Number.isFinite(e)&&e>=0?e:void 0}function m(n){const o=a(n,"input_tokens"),e=a(n,"output_tokens"),i=d(n,"cache_read_input_tokens"),s=d(n,"cache_creation_input_tokens");if(!(o===void 0||e===void 0||i===void 0||s===void 0))return{input_tokens:o,output_tokens:e,cache_read_input_tokens:i,cache_creation_input_tokens:s}}function h(n,o){const e=[],i=[];for(const t of o){const r=m(t.raw);if(!r){e.push({code:"claude_usage_invalid",message:`Message ${n} contains missing, negative, or non-numeric core usage`,providerIds:{messageId:n,...t.requestId?{requestId:t.requestId}:{}}});continue}i.push({normalized:r,sample:t})}if(i.length===0)return e.push({code:"claude_usage_missing",message:`Message ${n} has no valid provider usage sample`,providerIds:{messageId:n}}),{anomalies:e};const s=i[0].normalized,c=i.some(({normalized:t})=>t.input_tokens!==s.input_tokens||t.cache_read_input_tokens!==s.cache_read_input_tokens||t.cache_creation_input_tokens!==s.cache_creation_input_tokens);c&&e.push({code:"claude_usage_dimension_conflict",message:`Message ${n} reports conflicting input/cache token dimensions`,providerIds:{messageId:n}});const p=Math.max(...i.map(({normalized:t})=>t.output_tokens)),_={...s,output_tokens:p},u=l(_);u.providerUsageRaw=o.map(t=>t.raw),(c||e.length>0)&&(u.completeness="partial");const f=[...o].reverse().find(t=>t.requestId)?.requestId;return{usage:u,requestId:f,anomalies:e}}export{h as mergeClaudeMessageUsage};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{referenceCaptureContent as W}from"../../core/content-reference.js";import{InvalidCodeWhaleUsageError as D,normalizeCodeWhaleUsage as F}from"../../core/usage.js";const U=Object.freeze({inputOutput:!0,tools:!0,subagents:!0,thinking:!0,rawProviderBody:!1});function y(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function v(e){return typeof e=="string"&&e.length>0?e:void 0}function P(e){return e.options?.enabled===!0?e.options.capture:U}function A(e,t){return e.some(n=>n.role===t.role&&n.value===t.value&&n.sourceOffset===t.sourceOffset)?W(t):(e.push(t),W(t))}function g(e,t){t&&(e.some(n=>n.contentId===t.contentId)||e.push(t))}function k(e){if(typeof e=="string")return e;try{return JSON.stringify(e)}catch{return String(e)}}function R(e){const t=e.startedAt??e.job.startedAt,n=e.endedAt??e.job.endedAt,s=Date.parse(t),a=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(s)&&Number.isFinite(a)?{durationMs:Math.max(0,a-s)}:{},inputRefs:[],outputRefs:[],provider:{provider:"codewhale",nativeEventType:e.nativeEventType,nativeIds:Object.fromEntries(Object.entries(e.nativeIds??{}).filter(i=>typeof i[1]=="string")),...e.rawAttributes?{rawAttributes:e.rawAttributes}:{}},provenance:{source:"provider_event",accuracy:"provider_reported"}}}class H{provider="codewhale";async collect(t){const n={events:[],anomalies:[],gaps:[]},s=y(t.boundary.codeWhaleEvidence)?t.boundary.codeWhaleEvidence:void 0;if(!s||!Array.isArray(s.events))return n.anomalies.push({code:"codewhale_stream_evidence_missing",message:"boundary.codeWhaleEvidence.events is required"}),n.gaps.push({category:"provider_event_stream",reason:"source_log_missing"}),n;for(const a of s.events){if(!y(a)||typeof a.sequence!="number"||typeof a.observedAt!="string"||typeof a.rawLine!="string"||!y(a.event)){n.anomalies.push({code:"codewhale_stream_event_malformed",message:"stream-json evidence row is malformed"}),n.gaps.push({category:"provider_event_stream",reason:"correlation_failed"});continue}n.events.push({sequence:a.sequence,observedAt:a.observedAt,rawLine:a.rawLine,event:a.event})}return n.events.sort((a,i)=>a.sequence-i.sequence),n}async normalize(t,n){const s=n,a=P(t),i=[...s.anomalies],l=[],c=[];let _=0;const m=v(t.boundary.providerSessionId),w=`codewhale:${t.turnId}:turn`,f=R({job:t,spanId:w,kind:"turn",name:"CodeWhale audited turn",sequence:_++,status:t.outcome==="completed"?"completed":t.outcome==="cancelled"?"cancelled":"failed",nativeEventType:"exec",nativeIds:{platformEventId:v(t.boundary.platformEventId),providerSessionId:m}});c.push(f);let r;a.inputOutput&&t.input&&(r=A(l,{...t.input,captureLevel:t.input.captureLevel??"runtime_exact"}),g(f.inputRefs,r)),a.inputOutput&&t.finalOutput&&g(f.outputRefs,A(l,{...t.finalOutput,captureLevel:t.finalOutput.captureLevel??"runtime_exact"}));const C=s.events.filter(o=>o.event.type==="metadata"&&y(o.event.meta));C.length>1&&i.push({code:"codewhale_multiple_metadata_events",message:`Expected one aggregate metadata event, found ${C.length}; last event used`});const S=C.at(-1),h=y(S?.event.meta)?S.event.meta:void 0,b=v(h?.model),M=b??"CodeWhale model request",I=m?`${m}:${t.turnId}`:`codewhale:${t.turnId}`,p=R({job:t,spanId:`codewhale:${t.sessionId}:request:${I}`,parentSpanId:w,kind:"llm_request",name:M,sequence:_++,nativeEventType:"metadata",nativeIds:{requestId:I,providerSessionId:m},rawAttributes:{usageScope:"turn_aggregate",internalRequestCountAvailable:!1,...h?{metadata:h}:{}}});if(b&&(p.modelId=b),g(p.inputRefs,r),h)try{p.usage=F(h),s.gaps.push({category:"provider_usage_cache_partition",reason:"provider_usage_missing",detail:"CodeWhale stream-json reports input/output totals but no cache read/write partition"})}catch(o){i.push({code:"codewhale_provider_usage_invalid",message:o instanceof D?o.message:String(o),spanId:p.spanId,providerIds:{requestId:I}}),s.gaps.push({category:"provider_usage",reason:"provider_usage_missing",detail:I})}else s.gaps.push({category:"provider_usage",reason:"provider_usage_missing",detail:"CodeWhale metadata event missing"});c.push(p);const $=s.events.filter(o=>o.event.type==="content").map(o=>v(o.event.content)??"").join("");a.inputOutput&&$&&g(p.outputRefs,A(l,{role:"assistant_text",format:"text",value:$,captureLevel:"provider_exact"}));const E=new Map;for(const o of s.events){const u=o.event;if(u.type==="tool_use"&&a.tools){const O=v(u.id)??`sequence-${o.sequence}`,N=v(u.name)??"tool",x=R({job:t,spanId:`codewhale:${t.sessionId}:tool:${O}`,parentSpanId:p.spanId,kind:"tool_call",name:N,sequence:_++,status:"running",startedAt:o.observedAt,endedAt:t.endedAt,nativeEventType:"tool_use",nativeIds:{toolCallId:O,requestId:I},rawAttributes:{hasResult:!1}});g(x.inputRefs,A(l,{role:"tool_arguments",format:"json",value:k(u.input??{}),captureLevel:"provider_exact"})),E.set(O,x),c.push(x);continue}if(u.type!=="tool_result"||!a.tools)continue;const q=v(u.id),d=q?E.get(q):void 0;if(!d){i.push({code:"codewhale_tool_result_without_call",message:`No tool_use found for ${q??`sequence-${o.sequence}`}`}),s.gaps.push({category:"tool_result",reason:"correlation_failed",detail:q});continue}d.status=u.status==="error"?"failed":"completed",d.endedAt=o.observedAt;const L=Date.parse(d.startedAt),T=Date.parse(o.observedAt);Number.isFinite(L)&&Number.isFinite(T)&&(d.durationMs=Math.max(0,T-L)),d.provider.rawAttributes&&(d.provider.rawAttributes.hasResult=!0,d.provider.rawAttributes.status=u.status),g(d.outputRefs,A(l,{role:"tool_result",format:typeof u.output=="string"?"text":"json",value:k(u.output??""),captureLevel:"provider_exact"}))}for(const[o,u]of E)u.status==="running"&&(i.push({code:"codewhale_tool_result_missing",message:`Tool call ${o} has no result`,spanId:u.spanId,providerIds:{toolCallId:o}}),s.gaps.push({category:"tool_result",reason:"correlation_failed",detail:o}));return{spans:c,contents:l,anomalies:i,collection:s,capture:a}}async correlate(t,n){return n}validate(t,n){const s=n,a=s.spans.filter(r=>r.kind==="llm_request"),i=s.spans.filter(r=>r.kind==="tool_call"),l=!s.capture.inputOutput||t.input!==void 0,c=!s.capture.inputOutput||t.finalOutput!==void 0||s.contents.some(r=>r.role==="assistant_text"),_=!s.capture.tools||i.every(r=>r.status!=="running"),m=a.some(r=>r.usage!==void 0),w=!1,f=[...s.collection.gaps];return s.capture.rawProviderBody&&f.push({category:"raw_provider_body",reason:"raw_capture_disabled",detail:"CodeWhale stream-json does not retain raw provider HTTP bodies"}),{status:s.collection.events.length===0||!m?c?"partial":"failed":"partial",inputComplete:l,outputComplete:c,toolCallsComplete:_,subagentsComplete:!0,usageComplete:w,rawRequestsComplete:!1,gaps:f}}}export{H as CodeWhaleAuditAdapter};
|
|
@@ -0,0 +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};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{referenceCaptureContent as q}from"../../core/content-reference.js";const x=Object.freeze({inputOutput:!0,tools:!0,subagents:!1,thinking:!0,rawProviderBody:!1});function g(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function c(e){return typeof e=="string"&&e.length>0?e:void 0}function A(e){return typeof e=="number"&&Number.isFinite(e)&&e>=0?e:void 0}function b(e){return e.options?.enabled===!0?e.options.capture:x}function I(e,t,o){const n=[o.role,o.sourcePath??"",o.value??""].join("\0");if(t.has(n))return t.get(n);const s=q(o);return t.set(n,s),e.push(o),s}function y(e,t){t&&!e.some(o=>o.contentId===t.contentId)&&e.push(t)}function C(e){const t=e.startedAt??e.job.startedAt,o=e.endedAt??e.job.endedAt,n=Date.parse(t),s=Date.parse(o);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:o,...Number.isFinite(n)&&Number.isFinite(s)?{durationMs:Math.max(0,s-n)}:{},inputRefs:[],outputRefs:[],provider:{provider:"cursor",nativeEventType:e.nativeEventType,nativeIds:Object.fromEntries(Object.entries(e.nativeIds??{}).filter(u=>typeof u[1]=="string")),...e.rawAttributes?{rawAttributes:e.rawAttributes}:{}},provenance:{source:"provider_event",accuracy:"provider_reported"}}}function O(e){const t=A(e.inputTokens),o=A(e.outputTokens),n=A(e.cacheReadTokens),s=A(e.cacheWriteTokens);if(t===void 0||o===void 0||n===void 0||s===void 0)return;const u=t+n+s;return{input:{total:u,uncached:t,cacheRead:n,cacheWrite:s,other:0},output:{total:o,reasoning:null,visible:null},totalProcessed:u+o,requestCount:1,accuracy:"provider_reported",completeness:"complete",provider:"cursor",providerUsageRaw:e,normalization:{adapter:"cursor-stream-json",version:1,formula:"inputTokens + cacheReadTokens + cacheWriteTokens + outputTokens"}}}function R(e){const t=g(e.tool_call)?e.tool_call:g(e.toolCall)?e.toolCall:void 0;if(t){const[o,n]=Object.entries(t)[0]??[];if(o){const s=g(n)?n:{},u=o.replace(/ToolCall$/i,"");return{name:u?`${u[0]?.toUpperCase()??""}${u.slice(1)}`:"tool",input:s.args??s.arguments,output:s.result??s.output}}}return{name:c(e.name)??c(e.tool_name)??"tool",input:e.args??e.tool_input,output:e.result??e.output??e.tool_output}}function w(e){const t=new Map;for(const o of e){const n=o.event,s=c(n.type);if(s!=="tool_call"&&s!=="tool_result")continue;const u=c(n.call_id)??c(n.callId);if(!u)continue;const i=R(n),l=t.get(u),d=String(n.subtype??"").toLowerCase(),m=["failed","error","errored","rejected"].includes(d),p=m||["completed","canceled","cancelled"].includes(d)||s==="tool_result",a=l??{callId:u,name:i.name,startedAt:o.observedAt,status:"running",rawEvents:[]};a.name=i.name||a.name,i.input!==void 0&&(a.input=i.input),i.output!==void 0&&(a.output=i.output),a.rawEvents.push(n),p&&(a.endedAt=o.observedAt,a.status=m?"failed":d==="canceled"||d==="cancelled"?"cancelled":"completed"),t.set(u,a)}return[...t.values()]}function T(e){if(typeof e.result=="string")return e.result;if(typeof e.message=="string")return e.message;if(g(e.message)){if(typeof e.message.content=="string")return e.message.content;if(typeof e.message.text=="string")return e.message.text}return c(e.text)??c(e.content)}class S{provider="cursor";async collect(t){const o={events:[],anomalies:[],gaps:[]},n=g(t.boundary.cursorEvidence)?t.boundary.cursorEvidence:void 0;if(!n||!Array.isArray(n.events))return o.gaps.push({category:"cursor_event",reason:"source_log_missing",detail:"boundary.cursorEvidence.events is missing"}),o;for(const s of n.events){if(!g(s)||!g(s.event)||typeof s.sequence!="number"||typeof s.observedAt!="string"){o.anomalies.push({code:"cursor_audit_event_malformed",message:"Cursor evidence row is malformed"}),o.gaps.push({category:"cursor_event",reason:"correlation_failed"});continue}o.events.push({sequence:s.sequence,observedAt:s.observedAt,event:s.event})}return o.events.sort((s,u)=>s.sequence-u.sequence),o}async normalize(t,o){const n=o,s=b(t),u=[],i=new Map,l=[];let d=0;const m=`cursor:${t.turnId}:turn`,p=C({job:t,spanId:m,kind:"turn",name:"Cursor audited turn",sequence:d++,status:t.outcome==="completed"?"completed":t.outcome==="cancelled"?"cancelled":"failed",nativeEventType:"stream_json_turn",nativeIds:{providerSessionId:c(t.boundary.providerSessionId)}});l.push(p),s.inputOutput&&t.input&&y(p.inputRefs,I(u,i,{...t.input,captureLevel:t.input.captureLevel??"runtime_exact"})),s.inputOutput&&t.finalOutput&&y(p.outputRefs,I(u,i,{...t.finalOutput,captureLevel:t.finalOutput.captureLevel??"runtime_exact"}));const a=[...n.events].reverse().find(r=>r.event.type==="result"),v=n.events.find(r=>r.event.type==="system"&&r.event.subtype==="init"),h=c(v?.event.model),f=C({job:t,spanId:`cursor:${t.sessionId}:request:${c(a?.event.request_id)??t.turnId}`,parentSpanId:m,kind:"llm_request",name:h??"Cursor model request",sequence:d++,status:a?.event.is_error===!0?"failed":"completed",startedAt:v?.observedAt??t.startedAt,endedAt:a?.observedAt??t.endedAt,nativeEventType:"result",nativeIds:{requestId:c(a?.event.request_id),providerSessionId:c(a?.event.session_id)??c(t.boundary.providerSessionId)},rawAttributes:a?{resultEvent:a.event}:void 0});h&&(f.modelId=h),s.inputOutput&&t.input&&y(f.inputRefs,q(t.input));const k=g(a?.event.usage)?O(a.event.usage):void 0;if(k?f.usage=k:n.gaps.push({category:"provider_usage",reason:"provider_usage_missing",detail:f.spanId}),s.inputOutput&&a){const r=T(a.event);r&&y(f.outputRefs,I(u,i,{role:"assistant_text",format:"text",value:r,captureLevel:"provider_exact"})),s.rawProviderBody&&y(f.outputRefs,I(u,i,{role:"model_response",format:"json",value:JSON.stringify(a.event),captureLevel:"provider_exact"}))}if(s.thinking){const r=n.events.filter(_=>_.event.type==="thinking").map(_=>T(_.event)??"").join("");r&&y(f.outputRefs,I(u,i,{role:"thinking",format:"text",value:r,captureLevel:"provider_exact"}))}if(l.push(f),s.tools)for(const r of w(n.events)){const _=C({job:t,spanId:`cursor:${t.sessionId}:tool:${r.callId}`,parentSpanId:f.spanId,kind:"tool_call",name:r.name,sequence:d++,status:r.status,startedAt:r.startedAt,endedAt:r.endedAt??t.endedAt,nativeEventType:"tool_call",nativeIds:{toolCallId:r.callId},rawAttributes:{events:r.rawEvents}});r.input!==void 0&&y(_.inputRefs,I(u,i,{role:"tool_arguments",format:"json",value:typeof r.input=="string"?r.input:JSON.stringify(r.input),captureLevel:"provider_exact"})),r.output!==void 0&&y(_.outputRefs,I(u,i,{role:"tool_result",format:typeof r.output=="string"?"text":"json",value:typeof r.output=="string"?r.output:JSON.stringify(r.output),captureLevel:"provider_exact"})),l.push(_)}return{spans:l,contents:u,anomalies:n.anomalies,collection:n,capture:s}}async correlate(t,o){return o}validate(t,o){const n=o,s=n.spans.find(v=>v.kind==="llm_request"),u=n.spans.filter(v=>v.kind==="tool_call"),i=!n.capture.inputOutput||t.input!==void 0,l=!n.capture.inputOutput||t.finalOutput!==void 0||!!s?.outputRefs.length,d=!n.capture.tools||u.every(v=>v.status!=="running"),m=s?.usage?.completeness==="complete",p=[...n.collection.gaps];n.capture.rawProviderBody&&p.push({category:"raw_provider_body",reason:"raw_capture_disabled",detail:"Cursor CLI exposes stream-json events, not raw model HTTP bodies"});const a=i&&l&&d&&m&&p.length===0;return{status:n.collection.events.length===0?"failed":a?"complete":"partial",inputComplete:i,outputComplete:l,toolCallsComplete:d,subagentsComplete:!0,usageComplete:m,rawRequestsComplete:!1,gaps:p}}}export{S as CursorAuditAdapter};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{referenceCaptureContent as P}from"../../core/content-reference.js";const F=Object.freeze({inputOutput:!0,tools:!0,subagents:!1,thinking:!0,rawProviderBody:!1});function I(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function f(e){return typeof e=="string"&&e.length>0?e:void 0}function O(e){return typeof e=="number"&&Number.isFinite(e)&&e>=0?e:void 0}function z(e){return e.options?.enabled===!0?e.options.capture:F}function S(e,t,o){const r=[o.role,o.value??""].join("\0");if(t.has(r))return t.get(r);const n=P(o);return t.set(r,n),e.push(o),n}function A(e,t){t&&!e.some(o=>o.contentId===t.contentId)&&e.push(t)}function C(e,t){return typeof e=="number"&&Number.isFinite(e)?new Date(e).toISOString():typeof e=="string"&&Number.isFinite(Date.parse(e))?e:t}function k(e){const t=e.startedAt??e.job.startedAt,o=e.endedAt??e.job.endedAt,r=Date.parse(t),n=Date.parse(o);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:o,...Number.isFinite(r)&&Number.isFinite(n)?{durationMs:Math.max(0,n-r)}:{},inputRefs:[],outputRefs:[],provider:{provider:"opencode",nativeEventType:e.nativeEventType,nativeIds:Object.fromEntries(Object.entries(e.nativeIds??{}).filter(p=>typeof p[1]=="string")),...e.rawAttributes?{rawAttributes:e.rawAttributes}:{}},provenance:{source:"provider_event",accuracy:"provider_reported"}}}function B(e){const t=O(e.input),o=O(e.output),r=O(e.reasoning),n=O(e.total),p=I(e.cache)?e.cache:{},u=O(p.read),l=O(p.write);if(t===void 0||o===void 0||r===void 0||n===void 0||u===void 0||l===void 0)return;const y=t+u+l,g=n===y+o+r,_=n===y+o&&r<=o;if(!g&&!_)return;const q=g?o+r:o,d=g?o:o-r;return{input:{total:y,uncached:t,cacheRead:u,cacheWrite:l,other:0},output:{total:q,reasoning:r,visible:d},totalProcessed:n,requestCount:1,accuracy:"provider_reported",completeness:"complete",provider:"opencode",providerUsageRaw:e,normalization:{adapter:"opencode-sse",version:1,formula:g?"input + cache.read + cache.write + output + reasoning":"input + cache.read + cache.write + output; reasoning is an output subset"}}}class U{provider="opencode";async collect(t){const o={events:[],anomalies:[],gaps:[]},r=I(t.boundary.openCodeEvidence)?t.boundary.openCodeEvidence:void 0;if(!r||!Array.isArray(r.events))return o.gaps.push({category:"opencode_event",reason:"source_log_missing",detail:"boundary.openCodeEvidence.events is missing"}),o;for(const n of r.events){if(!I(n)||!I(n.event)||typeof n.sequence!="number"||typeof n.observedAt!="string"){o.anomalies.push({code:"opencode_audit_event_malformed",message:"OpenCode evidence row is malformed"}),o.gaps.push({category:"opencode_event",reason:"correlation_failed"});continue}o.events.push({sequence:n.sequence,observedAt:n.observedAt,event:n.event})}return o.events.sort((n,p)=>n.sequence-p.sequence),o}async normalize(t,o){const r=o,n=z(t),p=[],u=[],l=new Map;let y=0;const g=`opencode:${t.turnId}:turn`,_=k({job:t,spanId:g,kind:"turn",name:"OpenCode audited turn",sequence:y++,status:t.outcome==="completed"?"completed":t.outcome==="cancelled"?"cancelled":"failed",nativeEventType:"sse_turn",nativeIds:{providerSessionId:f(t.boundary.providerSessionId)}});p.push(_);const q=n.inputOutput&&t.input?S(u,l,{...t.input,captureLevel:t.input.captureLevel??"runtime_exact"}):void 0;A(_.inputRefs,q),n.inputOutput&&t.finalOutput&&A(_.outputRefs,S(u,l,{...t.finalOutput,captureLevel:t.finalOutput.captureLevel??"runtime_exact"}));const d=new Map,R=new Map;for(const a of r.events){if(a.event.type==="message.updated"&&I(a.event.info)){const s=a.event.info;if(s.role!=="assistant")continue;const c=f(s.id);if(!c)continue;const h=d.get(c);d.set(c,{firstSequence:h?.firstSequence??a.sequence,item:a,info:s})}if(a.event.type==="message.part.updated"&&I(a.event.part)){const s=f(a.event.part.id);s&&R.set(s,{sequence:a.sequence,item:a,part:a.event.part})}}const L=[...d.values()].sort((a,s)=>a.firstSequence-s.firstSequence),D=new Map;let E=q?[q]:[];for(const a of L){const s=a.info,c=f(s.id),h=I(s.time)?s.time:{},m=f(s.modelID),v=k({job:t,spanId:`opencode:${t.sessionId}:request:${c}`,parentSpanId:g,kind:"llm_request",name:[f(s.providerID),m].filter(Boolean).join("/")||"OpenCode model request",sequence:y++,status:s.error?"failed":"completed",startedAt:C(h.created,a.item.observedAt),endedAt:C(h.completed,a.item.observedAt),nativeEventType:"message.updated",nativeIds:{messageId:c,providerSessionId:f(s.sessionID)??f(t.boundary.providerSessionId)},rawAttributes:{message:s}});m&&(v.modelId=m);for(const i of E)A(v.inputRefs,i);E=[],I(s.tokens)&&(v.usage=B(s.tokens)),v.usage||r.gaps.push({category:"provider_usage",reason:"provider_usage_missing",detail:c});const x=[...R.values()].filter(({part:i})=>i.messageID===c).sort((i,b)=>i.sequence-b.sequence);for(const{part:i}of x)n.inputOutput&&i.type==="text"&&typeof i.text=="string"&&i.text&&A(v.outputRefs,S(u,l,{role:"assistant_text",format:"text",value:i.text,captureLevel:"provider_exact"})),n.thinking&&i.type==="reasoning"&&typeof i.text=="string"&&i.text&&A(v.outputRefs,S(u,l,{role:"thinking",format:"text",value:i.text,captureLevel:"provider_exact"}));n.rawProviderBody&&A(v.outputRefs,S(u,l,{role:"model_response",format:"json",value:JSON.stringify(s),captureLevel:"provider_exact"})),p.push(v),D.set(c,v)}if(n.tools){const a=[...R.values()].filter(({part:s})=>s.type==="tool").sort((s,c)=>s.sequence-c.sequence);for(const{part:s,item:c}of a){const h=f(s.callID)??f(s.id);if(!h||!I(s.state))continue;const m=s.state,v=f(m.status)??"pending",x=I(m.time)?m.time:{},i=k({job:t,spanId:`opencode:${t.sessionId}:tool:${h}`,parentSpanId:D.get(f(s.messageID)??"")?.spanId??g,kind:"tool_call",name:f(s.tool)??"tool",sequence:y++,status:v==="completed"?"completed":v==="error"?"failed":"running",startedAt:C(x.start,c.observedAt),endedAt:C(x.end,c.observedAt),nativeEventType:"message.part.updated",nativeIds:{toolCallId:h,messageId:f(s.messageID)},rawAttributes:{part:s}});m.input!==void 0&&A(i.inputRefs,S(u,l,{role:"tool_arguments",format:"json",value:typeof m.input=="string"?m.input:JSON.stringify(m.input),captureLevel:"provider_exact"}));const b=m.output??m.error;if(b!==void 0){const w=S(u,l,{role:"tool_result",format:typeof b=="string"?"text":"json",value:typeof b=="string"?b:JSON.stringify(b),captureLevel:"provider_exact"});if(A(i.outputRefs,w),w){const N=Date.parse(i.endedAt??c.observedAt),T=p.find(M=>M.kind==="llm_request"&&Date.parse(M.startedAt)>=N);T&&A(T.inputRefs,w)}}p.push(i)}}return{spans:p,contents:u,anomalies:r.anomalies,collection:r,capture:n}}async correlate(t,o){return o}validate(t,o){const r=o,n=r.spans.filter(d=>d.kind==="llm_request"),p=r.spans.filter(d=>d.kind==="tool_call"),u=!r.capture.inputOutput||t.input!==void 0,l=!r.capture.inputOutput||t.finalOutput!==void 0||n.some(d=>d.outputRefs.length>0),y=!r.capture.tools||p.every(d=>d.status!=="running"),g=n.length>0&&n.every(d=>d.usage?.completeness==="complete"),_=[...r.collection.gaps];r.capture.rawProviderBody&&_.push({category:"raw_provider_body",reason:"raw_capture_disabled",detail:"OpenCode exposes provider-normalized SSE events, not raw HTTP bodies"});const q=u&&l&&y&&g&&_.length===0;return{status:r.collection.events.length===0||n.length===0?"failed":q?"complete":"partial",inputComplete:u,outputComplete:l,toolCallsComplete:y,subagentsComplete:!0,usageComplete:g,rawRequestsComplete:!1,gaps:_}}}export{U as OpenCodeAuditAdapter};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{referenceCaptureContent as V}from"../../core/content-reference.js";import{InvalidPiUsageError as G,normalizePiUsage as Q}from"../../core/usage.js";import{collectPiTranscript as W}from"./pi-transcript-source.js";const X=Object.freeze({inputOutput:!0,tools:!0,subagents:!0,thinking:!0,rawProviderBody:!1});function B(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function p(e){return typeof e=="string"&&e.length>0?e:void 0}function H(e,t){const o=p(e);return o&&Number.isFinite(Date.parse(o))?o:t}function D(e){if(typeof e=="string")return e;try{return JSON.stringify(e)}catch{return String(e)}}function Y(e){return e.options?.enabled===!0?e.options.capture:X}function I(e,t,o){const r=[o.role,o.sourcePath??"",o.sourceOffset??"",o.value??""].join("\0");if(t.has(r))return t.get(r);const c=V(o);return t.set(r,c),e.push(o),c}function L(e){const t=e.startedAt??e.job.startedAt,o=e.endedAt??e.job.endedAt,r=Date.parse(t),c=Date.parse(o);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:o,...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(_=>typeof _[1]=="string")),...e.rawAttributes?{rawAttributes:e.rawAttributes}:{}},provenance:{source:"provider_transcript",accuracy:"provider_reported"}}}function K(e){return Array.isArray(e.content)?e.content.filter(B):[]}function J(e){const t=K(e);if(t.length!==0)return t.every(o=>o.type==="text"&&typeof o.text=="string")?{format:"text",value:t.map(o=>String(o.text)).join("")}:{format:"json",value:D(e.content)}}function C(e,t,o,r){return{role:t,format:o,value:r,sourcePath:e.sourcePath,sourceOffset:e.sourceOffset,sourceLength:e.sourceLength,captureLevel:"provider_exact"}}function m(e,t){t&&(e.some(o=>o.contentId===t.contentId&&o.role===t.role)||e.push(t))}class te{provider="pi";async collect(t){return W(t.boundary)}async normalize(t,o){const r=o,c=Y(t),_=[...r.anomalies],l=[],f=new Map,A=[];let P=0;const S=`pi:${t.turnId}:turn`,b=L({job:t,spanId:S,kind:"turn",name:"Pi audited turn",sequence:P++,status:t.outcome==="completed"?"completed":t.outcome==="cancelled"?"cancelled":"failed",nativeEventType:"prompt",nativeIds:{platformEventId:p(t.boundary.platformEventId),providerSessionId:p(t.boundary.providerSessionId)}});A.push(b),c.inputOutput&&t.input&&m(b.inputRefs,I(l,f,{...t.input,captureLevel:t.input.captureLevel??"runtime_exact"})),c.inputOutput&&t.finalOutput&&m(b.outputRefs,I(l,f,{...t.finalOutput,captureLevel:t.finalOutput.captureLevel??"runtime_exact"}));let d=t.startedAt,x=[];const w=new Map;let M,g,N;for(const a of r.lines){const s=a.record,E=H(s.timestamp,d);if(s.type==="model_change"){M=p(s.modelId),g=p(s.provider),d=E;continue}if(s.type==="thinking_level_change"){N=p(s.thinkingLevel),d=E;continue}if(s.type==="custom_message"){if(c.inputOutput){const n=typeof s.content=="string"?s.content:D(s.content);m(x,I(l,f,C(a,"user_input",typeof s.content=="string"?"text":"json",n)))}d=E;continue}if(s.type==="compaction"||s.type==="branch_summary"){const n=p(s.id)??`offset-${a.sourceOffset}`,u=L({job:t,spanId:`pi:${t.sessionId}:compaction:${n}`,parentSpanId:S,kind:"compaction",name:s.type==="compaction"?"Pi context compaction":"Pi branch summary",sequence:P++,startedAt:E,endedAt:E,nativeEventType:s.type,nativeIds:{entryId:n,firstKeptEntryId:p(s.firstKeptEntryId),fromId:p(s.fromId)},rawAttributes:{tokensBefore:s.tokensBefore,details:s.details,fromHook:s.fromHook,sourcePath:a.sourcePath,sourceOffset:a.sourceOffset}}),v=p(s.summary);v&&(m(u.outputRefs,I(l,f,C(a,"model_response","text",v))),m(x,u.outputRefs[0])),A.push(u),d=E;continue}if(s.type!=="message"||!B(s.message))continue;const i=s.message,F=p(i.role),h=H(s.timestamp??i.timestamp,d),O=p(s.id)??`offset-${a.sourceOffset}`;if(F==="bashExecution"){if(c.tools){const n=p(i.command),u=p(i.output),v=typeof i.exitCode=="number"?i.exitCode:void 0,y=i.cancelled===!0,k=L({job:t,spanId:`pi:${t.sessionId}:bash:${O}`,parentSpanId:S,kind:"tool_call",name:"bash",sequence:P++,status:y?"cancelled":v!==void 0&&v!==0?"failed":"completed",startedAt:h,endedAt:h,nativeEventType:"bashExecution",nativeIds:{messageId:O},rawAttributes:{exitCode:v,cancelled:y,truncated:i.truncated===!0,excludeFromContext:i.excludeFromContext===!0,fullOutputPath:i.fullOutputPath,sourcePath:a.sourcePath,sourceOffset:a.sourceOffset}});if(n&&m(k.inputRefs,I(l,f,C(a,"tool_arguments","text",n))),u){const $=I(l,f,C(a,"tool_result","text",u));m(k.outputRefs,$),i.excludeFromContext!==!0&&m(x,$)}A.push(k)}d=h;continue}if(F==="user"){if(c.inputOutput){const n=J(i);if(n){const u=I(l,f,C(a,"user_input",n.format,n.value));m(x,u)}}d=h;continue}if(F==="toolResult"){const n=p(i.toolCallId),u=n?w.get(n):void 0,v=J(i);let y;if(c.tools&&v&&(y=I(l,f,C(a,"tool_result",v.format,v.value)),m(x,y)),u){u.resultSeen=!0,u.span.endedAt=h;const k=Date.parse(u.span.startedAt),$=Date.parse(h);Number.isFinite(k)&&Number.isFinite($)&&(u.span.durationMs=Math.max(0,$-k)),u.span.status=i.isError===!0?"failed":"completed",m(u.span.outputRefs,y),u.span.provider.rawAttributes&&(u.span.provider.rawAttributes.hasResult=!0,u.span.provider.rawAttributes.isError=i.isError===!0)}else c.tools&&_.push({code:"pi_tool_result_without_call",message:`No tool call found for result ${n??O}`,providerIds:n?{toolCallId:n}:{messageId:O}});d=h;continue}if(F!=="assistant"){d=h;continue}const U=p(i.responseId),q=U??O,T=p(i.model)??M,z=p(i.provider)??g,R=L({job:t,spanId:`pi:${t.sessionId}:request:${q}`,parentSpanId:S,kind:"llm_request",name:T??"Pi model request",sequence:P++,startedAt:d,endedAt:h,nativeEventType:"message",nativeIds:{requestId:q,responseId:U,messageId:O},rawAttributes:{sourcePath:a.sourcePath,sourceOffset:a.sourceOffset,...z?{provider:z}:{},...T?{model:T}:{},...N?{thinkingLevel:N}:{},...typeof i.stopReason=="string"?{stopReason:i.stopReason}:{}}});if(T&&(R.modelId=T),R.inputRefs.push(...x),x=[],B(i.usage))try{R.usage=Q(i.usage)}catch(n){_.push({code:"pi_provider_usage_invalid",message:n instanceof G?n.message:String(n),spanId:R.spanId,providerIds:{requestId:q}}),r.gaps.push({category:"provider_usage",reason:"provider_usage_missing",detail:q})}else r.gaps.push({category:"provider_usage",reason:"provider_usage_missing",detail:q});A.push(R);for(const n of K(i)){if(n.type==="thinking"&&c.thinking){const k=p(n.thinking??n.text);k&&m(R.outputRefs,I(l,f,C(a,"thinking","text",k)));continue}if(n.type==="text"&&c.inputOutput&&typeof n.text=="string"){m(R.outputRefs,I(l,f,C(a,"assistant_text","text",n.text)));continue}if(n.type!=="toolCall"||!c.tools)continue;const u=p(n.id);if(!u){_.push({code:"pi_tool_call_id_missing",message:`Tool call in message ${O} has no id`,providerIds:{messageId:O}});continue}const v=p(n.name)??"tool",y=L({job:t,spanId:`pi:${t.sessionId}:tool:${u}`,parentSpanId:R.spanId,kind:"tool_call",name:v,sequence:P++,status:"running",startedAt:h,endedAt:t.endedAt,nativeEventType:"toolCall",nativeIds:{toolCallId:u,messageId:O,requestId:q},rawAttributes:{sourcePath:a.sourcePath,sourceOffset:a.sourceOffset,hasResult:!1}});m(y.inputRefs,I(l,f,C(a,"tool_arguments","json",D(n.arguments)))),A.push(y),w.set(u,{span:y,resultSeen:!1})}d=h}for(const[a,s]of w)s.resultSeen||(_.push({code:"pi_tool_result_missing",message:`Tool call ${a} has no result in the audited boundary`,spanId:s.span.spanId,providerIds:{toolCallId:a}}),r.gaps.push({category:"tool_result",reason:"correlation_failed",detail:a}));return{spans:A,contents:l,anomalies:_,collection:r,capture:c}}async correlate(t,o){return o}validate(t,o){const r=o,c=r.spans.filter(g=>g.kind==="llm_request"),_=r.spans.filter(g=>g.kind==="tool_call"),l=!r.capture.inputOutput||t.input!==void 0,f=!r.capture.inputOutput||t.finalOutput!==void 0||r.contents.some(g=>g.role==="assistant_text"),A=!r.capture.tools||_.every(g=>g.status!=="running"),P=!0,S=c.length>0&&c.every(g=>g.usage?.completeness==="complete"),b=!1,d=[...r.collection.gaps];r.capture.rawProviderBody&&d.push({category:"raw_provider_body",reason:"raw_capture_disabled",detail:"Pi transcript does not retain raw provider request bodies"});const x=l&&f&&A&&P&&S&&(!r.capture.rawProviderBody||b)&&d.length===0,w=r.collection.lines.length===0,M=c.length===0;return{status:w||M?"failed":x?"complete":"partial",inputComplete:l,outputComplete:f,toolCallsComplete:A,subagentsComplete:P,usageComplete:S,rawRequestsComplete:b,gaps:d}}}export{te as PiAuditAdapter};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{open as _,stat as y}from"node:fs/promises";function $(t){return typeof t=="object"&&t!==null&&!Array.isArray(t)}function h(t,r){return typeof t=="number"&&Number.isSafeInteger(t)&&t>=0?t:r}async function P(t){const r=typeof t.transcriptPath=="string"?t.transcriptPath:void 0;if(!r)return{lines:[],anomalies:[{code:"pi_transcript_path_missing",message:"boundary.transcriptPath is required"}],gaps:[{category:"main_transcript",reason:"source_log_missing",detail:"boundary.transcriptPath is missing"}],sourcePaths:[]};const e={lines:[],anomalies:[],gaps:[],sourcePaths:[r]};try{const s=await y(r),c=h(t.transcriptStartOffset,0),g=typeof t.transcriptEndOffset=="number"?h(t.transcriptEndOffset,s.size):s.size;if(c>s.size)return e.anomalies.push({code:"pi_transcript_boundary_out_of_range",message:`${r}: start ${c} exceeds size ${s.size}`}),e.gaps.push({category:"main_transcript",reason:"correlation_failed",detail:`${r}:${c}-${g}`}),e;const p=c,f=Math.min(Math.max(g,p),s.size)-p;if(f===0)return e;const d=await _(r,"r");let n;try{n=Buffer.allocUnsafe(f);const{bytesRead:a}=await d.read(n,0,f,p);n=n.subarray(0,a)}finally{await d.close()}let o=0;for(;o<n.length;){const a=n.indexOf(10,o),m=a===-1?n.length:a+1,u=n.subarray(o,a===-1?n.length:a),l=p+o;if(o=m,u.length!==0)try{const i=JSON.parse(u.toString("utf8"));if(!$(i))throw new Error("JSONL row is not an object");e.lines.push({record:i,sourcePath:r,sourceOffset:l,sourceLength:u.length})}catch(i){e.anomalies.push({code:"pi_transcript_row_malformed",message:`${r}:${l}: ${i instanceof Error?i.message:String(i)}`}),e.gaps.push({category:"transcript_row",reason:"correlation_failed",detail:`${r}:${l}`})}}}catch(s){e.anomalies.push({code:"pi_transcript_source_unreadable",message:`${r}: ${s instanceof Error?s.message:String(s)}`}),e.gaps.push({category:"main_transcript",reason:"source_log_missing",detail:r})}return e}export{P as collectPiTranscript};
|
|
@@ -0,0 +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:"replay",capture:{inputOutput:!0,tools:!0,subagents:!0,thinking:!1,rawProviderBody:!1}})};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};
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import{randomUUID as w}from"node:crypto";import{freezeAuditOptions as b}from"./audit-options.js";class c extends Error{constructor(e,t){super(`Audit configuration conflict for session ${e}: ${t}`),this.name="AuditSessionConfigConflictError"}}class d extends Error{constructor(e){super(e),this.name="AuditSessionOptionsError"}}function x(n,e){return n.profile===e.profile&&n.scope===e.scope&&n.retentionDays===e.retentionDays&&n.capture.inputOutput===e.capture.inputOutput&&n.capture.tools===e.capture.tools&&n.capture.subagents===e.capture.subagents&&n.capture.thinking===e.capture.thinking&&n.capture.rawProviderBody===e.capture.rawProviderBody}function h(n){if(n.state!=="enabled"||!n.options?.enabled)throw new d("Enabled audit settings are missing");return n.options}class l{static MAX_TURN_CONTEXTS=256;sessions=new Map;turnContexts=new Map;createAuditId;now;constructor(e={}){this.createAuditId=e.createAuditId??(()=>`audit-${w()}`),this.now=e.now??(()=>new Date().toISOString())}resolve(e){const{businessSessionId:t,provider:o,parsed:r}=e;if(r.error)throw new d(r.error);if(!r.state)throw new d("Audit settings have no parse state");const s=this.sessions.get(t);if(s&&s.provider!==o)throw new c(t,`provider changed from ${s.provider} to ${o}`);if(r.state==="absent"){if(s?.state==="enabled")return s.context;s||this.sessions.set(t,{state:"disabled",provider:o});return}if(r.state==="disabled"){if(s?.state==="enabled")throw new c(t,"auditing cannot be disabled after the session starts");s||this.sessions.set(t,{state:"disabled",provider:o});return}const i=h(r);if(s?.state==="disabled")throw new c(t,"auditing cannot be enabled after the session starts");if(s){if(!x(s.context.options,i))throw new c(t,"audit options changed after the session starts");return s.context}const a=b(i);if(!a.enabled)throw new d("Enabled audit settings normalized as disabled");const u=Object.freeze({auditId:this.createAuditId(),businessSessionId:t,provider:o,options:a,createdAt:this.now(),...e.providerSessionId===void 0?{}:{providerSessionId:e.providerSessionId}});return this.sessions.set(t,{state:"enabled",provider:o,context:u}),u}get(e){const t=this.sessions.get(e);return t?.state==="enabled"?t.context:void 0}resolveTurn(e){const{businessSessionId:t,provider:o,parsed:r}=e;if(r.error)throw new d(r.error);if(r.state!=="enabled")throw new d("Turn-scoped audit requires enabled audit settings");const s=h(r);if(s.scope!=="turn")throw new d('Turn-scoped audit requires audit.scope "turn"');const i=this.sessions.get(t);if(i&&i.provider!==o)throw new c(t,`provider changed from ${i.provider} to ${o}`);if(i?.state==="enabled")return i.context;const a=`${t}
|
|
2
|
+
${e.platformEventId}`,u=this.turnContexts.get(a);if(u)return u;const p=Object.freeze({auditId:this.createAuditId(),businessSessionId:t,provider:o,options:s,createdAt:this.now(),...e.providerSessionId===void 0?{}:{providerSessionId:e.providerSessionId}});if(this.turnContexts.size>=l.MAX_TURN_CONTEXTS){const f=this.turnContexts.keys().next();f.done||this.turnContexts.delete(f.value)}return this.turnContexts.set(a,p),p}delete(e){for(const t of this.turnContexts.keys())t.startsWith(`${e}
|
|
3
|
+
`)&&this.turnContexts.delete(t);return this.sessions.delete(e)}clear(){this.sessions.clear(),this.turnContexts.clear()}}export{c as AuditSessionConfigConflictError,d as AuditSessionOptionsError,l as AuditSessionRegistry};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{AUDIT_ERROR_CODES as d}from"./types.js";const u=new Set(["claude","codex","acp","pi","codewhale","cursor","opencode"]);class s extends Error{code=d.turnScopeUnsupported;constructor(r){super(`Turn-scoped audit is not supported for provider ${r}`),this.name="AuditTurnScopeUnsupportedError"}}class t extends Error{code=d.preparationFailed;constructor(r){super(`Audit turn preparation failed: ${r}`),this.name="AuditPreparationFailedError"}}function a(e){if(!u.has(e))throw new s(e)}function o(e,r){return{event_id:e.eventId,session_id:e.sessionId,state:e.state,...e.msgId===void 0?{}:{msg_id:e.msgId},...e.auditId===void 0?{}:{audit_id:e.auditId},...e.turnId===void 0?{}:{turn_id:e.turnId},...e.revision===void 0?{}:{revision:e.revision},...e.quality===void 0?{}:{quality:e.quality},...e.truncated===void 0?{}:{truncated:e.truncated},...e.errorCode===void 0?{}:{error_code:e.errorCode},...e.errorMessage===void 0?{}:{error_message:e.errorMessage},updated_at:r}}export{t as AuditPreparationFailedError,s as AuditTurnScopeUnsupportedError,u as TURN_SCOPE_SUPPORTED_PROVIDERS,a as assertTurnScopeSupported,o as buildAuditStatePayload};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{randomUUID as n}from"node:crypto";import{safeTryEnqueueAudit as c}from"../producer/audit-producer.js";const a=2e3,l=256;class h{producer;turns=new Map;completedTurns=new Map;closeWaitMs;createId;now;setTimer;clearTimer;listener;constructor(e,t={}){this.producer=e,this.closeWaitMs=t.closeWaitMs??a,this.createId=t.createId??(s=>`${s}-${n()}`),this.now=t.now??(()=>new Date().toISOString()),this.setTimer=t.setTimer??((s,o)=>setTimeout(s,o)),this.clearTimer=t.clearTimer??(s=>clearTimeout(s)),this.listener=t.listener}startTurn(e){if(!e.session)return;const t=this.turns.get(e.platformEventId);if(t)return t.context;const s=this.completedTurns.get(e.platformEventId);if(s)return s;const o=Object.freeze({auditId:e.session.auditId,traceId:this.createId("trace"),turnId:this.createId("turn"),platformEventId:e.platformEventId,sessionId:e.session.businessSessionId,...e.originMsgId===void 0?{}:{originMsgId:e.originMsgId},startedAt:e.startedAt??this.now()});return this.turns.set(e.platformEventId,{session:e.session,context:o,...e.input===void 0?{}:{input:e.input},boundary:{...e.boundary},dispatchAttempted:!1}),this.notify(()=>this.listener?.onTurnAccepted?.(o)),o}getTurn(e){return this.turns.get(e)?.context}ownsTurn(e){return this.turns.has(e)||this.completedTurns.has(e)}markResponded(e){const t=this.turns.get(e.platformEventId);return t?(t.responded||(t.responded={outcome:e.outcome,endedAt:e.endedAt??this.now(),...e.finalOutput===void 0?{}:{finalOutput:e.finalOutput},...e.boundary===void 0?{}:{boundary:{...e.boundary}}}),this.closeOrWait(t),!0):!1}markAdapterClosed(e){const t=this.turns.get(e.platformEventId);return t?(t.adapterClosed||(t.adapterClosed={...e.outcome===void 0?{}:{outcome:e.outcome},endedAt:e.endedAt??this.now(),...e.boundary===void 0?{}:{boundary:{...e.boundary}}}),this.closeOrWait(t),!0):!1}dispose(){for(const e of this.turns.values())e.closeTimer&&this.clearTimer(e.closeTimer);this.turns.clear(),this.completedTurns.clear()}closeOrWait(e){if(!e.dispatchAttempted){if(e.responded&&e.adapterClosed){this.dispatch(e);return}e.closeTimer||(e.closeTimer=this.setTimer(()=>{e.closeTimer=void 0,this.dispatch(e)},this.closeWaitMs))}}dispatch(e){if(e.dispatchAttempted)return;e.dispatchAttempted=!0,e.closeTimer&&(this.clearTimer(e.closeTimer),e.closeTimer=void 0);const t=!!(e.responded&&e.adapterClosed),s=t?[]:e.responded?["adapter_closed"]:["responded"],o=e.adapterClosed?.endedAt??e.responded?.endedAt??this.now(),d=e.responded?.outcome??e.adapterClosed?.outcome??"failed",r={schemaVersion:1,jobId:this.createId("job"),auditId:e.context.auditId,traceId:e.context.traceId,turnId:e.context.turnId,sessionId:e.context.sessionId,provider:e.session.provider,startedAt:e.context.startedAt,endedAt:o,outcome:d,...e.input===void 0?{}:{input:e.input},...e.responded?.finalOutput===void 0?{}:{finalOutput:e.responded.finalOutput},boundary:{...e.boundary,...e.responded?.boundary,...e.adapterClosed?.boundary,auditLifecycle:{completeness:t?"complete":"partial",missingSignals:s}},options:e.session.options},i=c(this.producer,r);this.turns.delete(e.context.platformEventId),this.rememberCompleted(e.context),this.notify(()=>this.listener?.onTurnDispatched?.(e.context,i))}rememberCompleted(e){if(this.completedTurns.size>=l){const t=this.completedTurns.keys().next();t.done||this.completedTurns.delete(t.value)}this.completedTurns.set(e.platformEventId,e)}notify(e){try{e()}catch{}}}export{h as AuditTurnLifecycle};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{createHash as t}from"node:crypto";function a(e){if(e.value===void 0)return;const r=Buffer.from(e.value,"utf8");return{contentId:t("sha256").update(r).digest("hex"),role:e.role,format:e.format,byteSize:r.byteLength,charCount:[...e.value].length,encrypted:!1,truncated:!1,redacted:!1,captureLevel:e.captureLevel??"reconstructed"}}function n(e){return`${e.role}\0${e.contentId}`}export{n as contentReferenceKey,a as referenceCaptureContent};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{rollupUniqueRequestUsage as m}from"./usage.js";import{contentReferenceKey as c,referenceCaptureContent as p}from"./content-reference.js";class A{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 h{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),s=await n.collect(e),d=await n.normalize(e,s),a=await n.correlate(e,d),f=n.validate(e,a),u=v(e,a.spans),I=u.filter(i=>i.kind==="llm_request"&&i.usage).map(i=>({requestId:i.provider.nativeIds.requestId??i.provider.nativeIds.messageId??i.spanId,usage:i.usage})),o={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:a.contents,usage:m(I,e.provider),quality:f,anomalies:a.anomalies,finalizedAt:new Date().toISOString()};return await this.store.save(o,e.options),o}}function v(t,e){const r=e.map(s=>({...s,inputRefs:[...s.inputRefs],outputRefs:[...s.outputRefs]}));let n=r.find(s=>s.kind==="turn");if(!n){const s=Date.parse(t.startedAt),d=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(s)&&Number.isFinite(d)?{durationMs:Math.max(0,d-s)}:{},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&&l(n.inputRefs,p(t.input)),t.finalOutput&&l(n.outputRefs,p(t.finalOutput)),r}function l(t,e){if(!e)return;const r=c(e);t.some(n=>c(n)===r)||t.push(e)}export{A as AuditAdapterRegistry,h as ReplayFinalizer};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const i={configInvalid:"audit_config_invalid",configConflict:"audit_config_conflict",providerUnsupported:"audit_provider_unsupported",turnScopeUnsupported:"audit_turn_scope_unsupported",preparationFailed:"audit_preparation_failed",queueFull:"audit_queue_full",finalizeFailed:"audit_finalize_failed"};export{i as AUDIT_ERROR_CODES};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
class s extends Error{constructor(t){super(`Invalid Codex usage: ${t}`),this.name="InvalidCodexUsageError"}}class v extends Error{constructor(t){super(`Invalid Pi usage: ${t}`),this.name="InvalidPiUsageError"}}class k extends Error{constructor(t){super(`Invalid Reasonix usage: ${t}`),this.name="InvalidReasonixUsageError"}}class q extends Error{constructor(t){super(`Invalid CodeWhale usage: ${t}`),this.name="InvalidCodeWhaleUsageError"}}function h(e){return typeof e=="number"&&Number.isFinite(e)&&e>0?e:0}function p(e,t){if(t==null)return null;if(typeof t!="number"||!Number.isFinite(t)||t<0)throw new s(`${e} must be a non-negative finite number`);return t}function m(e,t){if(typeof t!="number"||!Number.isFinite(t)||t<0)throw new v(`${e} must be a non-negative finite number`);return t}function _(e,t){if(typeof t!="number"||!Number.isFinite(t)||t<0)throw new k(`${e} must be a non-negative finite number`);return t}function f(e,t){if(typeof t!="number"||!Number.isFinite(t)||t<0)throw new q(`${e} must be a non-negative finite number`);return t}function C(e){const t=h(e.input_tokens),a=h(e.cache_read_input_tokens),n=h(e.cache_creation_input_tokens),r=h(e.output_tokens),u=t+a+n;return{input:{total:u,uncached:t,cacheRead:a,cacheWrite:n,other:0},output:{total:r,reasoning:null,visible:null},totalProcessed:u+r,requestCount:1,accuracy:"provider_reported",completeness:"complete",provider:"claude",providerUsageRaw:e,normalization:{adapter:"claude",version:1,formula:"input_tokens + cache_read_input_tokens + cache_creation_input_tokens + output_tokens"}}}function N(e){const t=p("total_tokens",e.total_tokens),a=p("input_tokens",e.input_tokens),n=p("cached_input_tokens",e.cached_input_tokens),r=p("cache_write_input_tokens",e.cache_write_input_tokens)??0,u=p("output_tokens",e.output_tokens),c=p("reasoning_output_tokens",e.reasoning_output_tokens),o=a??0,i=u??0;if(n!==null&&n>o)throw new s("cached_input_tokens cannot exceed input_tokens");if(r!==null&&r>o)throw new s("cache_write_input_tokens cannot exceed input_tokens");if(n!==null&&r!==null&&n+r>o)throw new s("cached_input_tokens + cache_write_input_tokens cannot exceed input_tokens");if(c!==null&&c>i)throw new s("reasoning_output_tokens cannot exceed output_tokens");if(t!==null&&t!==o+i)throw new s("total_tokens must equal input_tokens + output_tokens");const g=n!==null,b=g?o-n-r:null,R=g?0:o-(r??0)-(n??0),U=c===null?null:i-c,w=a!==null&&u!==null&&n!==null&&c!==null;return{input:{total:o,uncached:b,cacheRead:n,cacheWrite:r,other:R},output:{total:i,reasoning:c,visible:U},totalProcessed:o+i,requestCount:1,accuracy:"provider_reported",completeness:w?"complete":"partial",provider:"codex",providerUsageRaw:e,normalization:{adapter:"codex",version:2,formula:"input_tokens + output_tokens; cache read/write partition input; reasoning is an output subset"}}}function I(e){const t=m("input",e.input),a=m("cacheRead",e.cacheRead),n=m("cacheWrite",e.cacheWrite),r=m("output",e.output),u=m("totalTokens",e.totalTokens),c=t+a+n,o=c+r;if(u!==o)throw new v("totalTokens must equal input + cacheRead + cacheWrite + output");return{input:{total:c,uncached:t,cacheRead:a,cacheWrite:n,other:0},output:{total:r,reasoning:null,visible:null},totalProcessed:u,requestCount:1,accuracy:"provider_reported",completeness:"complete",provider:"pi",providerUsageRaw:e,normalization:{adapter:"pi",version:1,formula:"input + cacheRead + cacheWrite + output"}}}function T(e){const t=_("prompt_tokens",e.prompt_tokens),a=_("completion_tokens",e.completion_tokens),n=_("total_tokens",e.total_tokens),r=_("prompt_cache_hit_tokens",e.prompt_cache_hit_tokens),u=_("prompt_cache_miss_tokens",e.prompt_cache_miss_tokens);if(r+u!==t)throw new k("prompt_tokens must equal prompt_cache_hit_tokens + prompt_cache_miss_tokens");if(t+a!==n)throw new k("total_tokens must equal prompt_tokens + completion_tokens");return{input:{total:t,uncached:u,cacheRead:r,cacheWrite:0,other:0},output:{total:a,reasoning:null,visible:null},totalProcessed:n,requestCount:1,accuracy:"provider_reported",completeness:"complete",provider:"acp",providerUsageRaw:e,normalization:{adapter:"reasonix",version:1,formula:"prompt_tokens = cache hit + cache miss; total_tokens = prompt_tokens + completion_tokens"}}}function z(e){const t=f("input_tokens",e.input_tokens),a=f("output_tokens",e.output_tokens);return{input:{total:t,uncached:null,cacheRead:null,cacheWrite:null,other:t},output:{total:a,reasoning:null,visible:null},totalProcessed:t+a,requestCount:1,accuracy:"provider_reported",completeness:"partial",provider:"codewhale",providerUsageRaw:e,normalization:{adapter:"codewhale",version:1,formula:"input_tokens + output_tokens; cache partition unavailable from stream-json"}}}function l(e){return e.some(t=>t===null)?null:e.reduce((t,a)=>t+(a??0),0)}function x(e){return e.includes("estimated")?"estimated":e.includes("reconciled")?"reconciled":"provider_reported"}function d(e,t){return e===null?t:t===null?e:Math.max(e,t)}function W(e,t){const a=Math.max(e.input.total,t.input.total),n=Math.max(e.output.total,t.output.total);return{...e,input:{total:a,uncached:d(e.input.uncached,t.input.uncached),cacheRead:d(e.input.cacheRead,t.input.cacheRead),cacheWrite:d(e.input.cacheWrite,t.input.cacheWrite),other:d(e.input.other,t.input.other)},output:{total:n,reasoning:d(e.output.reasoning,t.output.reasoning),visible:d(e.output.visible,t.output.visible)},totalProcessed:a+n,accuracy:x([e.accuracy,t.accuracy]),completeness:e.completeness==="complete"&&t.completeness==="complete"?"complete":"partial",providerUsageRaw:[e.providerUsageRaw,t.providerUsageRaw]}}function y(e){return{input:{total:0,uncached:0,cacheRead:0,cacheWrite:0,other:0},output:{total:0,reasoning:null,visible:null},totalProcessed:0,requestCount:0,accuracy:"provider_reported",completeness:"partial",provider:e,providerUsageRaw:[],normalization:{adapter:e,version:1,formula:"sum of unique leaf requests"}}}function P(e,t="claude"){if(e.length===0)return y(t);const a=new Map;for(const o of e){const i=a.get(o.requestId);a.set(o.requestId,i?W(i,o.usage):o.usage)}const n=[...a.values()],r=n[0].provider,u=n.reduce((o,i)=>o+i.input.total,0),c=n.reduce((o,i)=>o+i.output.total,0);return{input:{total:u,uncached:l(n.map(o=>o.input.uncached)),cacheRead:l(n.map(o=>o.input.cacheRead)),cacheWrite:l(n.map(o=>o.input.cacheWrite)),other:l(n.map(o=>o.input.other))},output:{total:c,reasoning:l(n.map(o=>o.output.reasoning)),visible:l(n.map(o=>o.output.visible))},totalProcessed:u+c,requestCount:n.length,accuracy:x(n.map(o=>o.accuracy)),completeness:n.every(o=>o.completeness==="complete")?"complete":"partial",provider:r,providerUsageRaw:n.map(o=>o.providerUsageRaw),normalization:{adapter:r,version:1,formula:"sum of unique leaf requests"}}}export{q as InvalidCodeWhaleUsageError,s as InvalidCodexUsageError,v as InvalidPiUsageError,k as InvalidReasonixUsageError,y as emptyNormalizedUsage,C as normalizeClaudeUsage,z as normalizeCodeWhaleUsage,N as normalizeCodexUsage,I as normalizePiUsage,T as normalizeReasonixUsage,P as rollupUniqueRequestUsage};
|
|
@@ -0,0 +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 y,AuditPreparationFailedError as v,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,i)=>{this.recordingNotified.delete(t.platformEventId),i?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)}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,i=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(i)return r&&!this.outputs.has(e.eventId)&&this.outputs.set(e.eventId,{chunks:new Map}),i}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 i=typeof e.boundary.originMsgId=="string"?e.boundary.originMsgId:void 0,s={eventId:t,sessionId:e.sessionId,auditId:e.auditId,turnId:e.turnId,...i===void 0?{}:{msgId:i}};if(!r.ok){this.emit({...s,state:"failed",errorCode:a.finalizeFailed,...r.error===void 0?{}:{errorMessage:r.error}});return}const n=r.quality??"complete";this.emit({...s,state:n==="complete"?"ready":"partial",quality:n,...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 i=this.outputs.get(e);!i||i.reply!==void 0||!t||i.chunks.has(r)||i.chunks.set(r,t)}captureUnsequencedStreamChunk(e,r){const t=this.outputs.get(e);if(!t||t.reply!==void 0||!r)return;const i=t.chunks.size===0?1:Math.max(...t.chunks.keys())+1;t.chunks.set(i,r)}markResponded(e,r,t,i){const s=this.outputs.get(e),n=s?.reply??(s?[...s.chunks.entries()].sort(([d],[f])=>d-f).map(([,d])=>d).join(""):""),u=s?n||(r==="responded"?"":t??""):"",c=this.lifecycle.markResponded({platformEventId:e,outcome:A(r),...u?{finalOutput:{role:"final_response",format:"text",value:u,captureLevel:"runtime_exact"}}:{},...i===void 0?{}:{boundary:i}});return this.outputs.delete(e),c}markAdapterClosed(e,r){return this.lifecycle.markAdapterClosed({platformEventId:e,...r===void 0?{}:{boundary:r}})}closeWithoutAdapter(e,r,t,i){this.markResponded(e,r,t,i),this.markAdapterClosed(e,{...i,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"){if(!e.eventId)return;y(e.provider);try{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 v(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(o){return o==="responded"?"completed":o==="canceled"?"cancelled":"failed"}export{w as BridgeAuditController};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
function r(e){return typeof e.addJobSettledHandler=="function"}function u(e,t){try{return e.tryEnqueue(t)!==!1}catch{return!1}}class n{tryEnqueue(t){return!1}}export{n as NoopAuditProducer,r as isSettlableAuditProducer,u as safeTryEnqueueAudit};
|
|
@@ -0,0 +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,v=1e3,k=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,v,"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.scheduleWorker(),!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.scheduleWorker(),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}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,k,"timeoutMs")}function u(s){return s instanceof Error?s.message:typeof s=="string"?s:"Unknown Recorder process error"}export{R as IpcAuditProducer};
|
|
@@ -0,0 +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};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
class I{store;constructor(n){this.store=n}async getTurn(n,a){const s=await this.store.get(n,a);return s?i(s):void 0}async getTurnRevision(n,a,s){const t=await this.store.getRevision(n,a,s);return t?i(t):void 0}async findByAuditId(n){return(await this.store.findByAuditId(n)).map(i)}async findByTurnId(n){return(await this.store.findByTurnId(n)).map(i)}async readContent(n){return{contentId:n,value:await this.store.readContent(n)}}async readContentChunk(n,a,s){const t=await this.store.readContentChunk(n,a,s);return{contentId:n,...t}}}function i(e){const n=c(e.spans);return{replay:e,timeline:n,tree:f(n),statistics:C(e,n)}}function c(e){return[...e].sort(h)}function f(e){const n=c(e),a=new Map;for(const o of n)a.set(o.spanId,(a.get(o.spanId)??0)+1);const s=new Map,t=new Map,r=n.map(o=>{const u={span:o,children:[]};return a.get(o.spanId)===1&&(s.set(o.spanId,o),t.set(o.spanId,u)),u}),d=[];for(const o of r){const{span:u}=o,l=u.parentSpanId,p=l?t.get(l):void 0;a.get(u.spanId)===1&&p!==void 0&&!g(u,s)?p.children.push(o):d.push(o)}return d}function C(e,n=c(e.spans)){const a=new Map;for(const t of n){const r=`${t.kind}\0${t.name}`,d=a.get(r);d?d.count+=1:a.set(r,{kind:t.kind,name:t.name,count:1})}const s=n.filter(t=>t.kind==="llm_request").map(t=>({spanId:t.spanId,name:t.name,sequence:t.sequence,startedAt:t.startedAt,endedAt:t.endedAt,durationMs:t.durationMs,status:t.status,usage:t.usage}));return{spanCount:n.length,spanCounts:[...a.values()].sort((t,r)=>t.kind.localeCompare(r.kind)||t.name.localeCompare(r.name)),llmRequestCount:s.length,toolCallCount:n.filter(t=>t.kind==="tool_call").length,subagentCallCount:n.filter(t=>t.kind==="subagent").length,llmRequests:s,totalUsage:e.usage}}function h(e,n){return e.sequence-n.sequence||e.startedAt.localeCompare(n.startedAt)||e.spanId.localeCompare(n.spanId)}function g(e,n){const a=new Set([e.spanId]);let s=e.parentSpanId;for(;s;){if(a.has(s))return!0;a.add(s),s=n.get(s)?.parentSpanId}return!1}export{I as AuditReplayQueryService,C as buildReplayStatistics,i as buildReplayView,f as buildSpanTree,c as buildTimeline};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{join as o}from"node:path";import{GRIX_PATHS as a,log as r}from"../../core/log/index.js";import{IpcAuditProducer as d}from"../producer/ipc-audit-producer.js";const u=128;function l(n){return n??o(a.data,"audit-replay")}class c{options;queued=[];maxPendingJobs;onDiagnostic;jobSettledHandlers=new Set;delegate;initialization;accepting=!0;constructor(e){this.options=e;const t=e.maxPendingJobs??u;if(!Number.isSafeInteger(t)||t<=0)throw new Error("maxPendingJobs must be a positive integer");this.maxPendingJobs=t,this.onDiagnostic=e.onDiagnostic}get pendingCount(){return this.queued.length+(this.delegate?.pendingCount??0)}addJobSettledHandler(e){this.jobSettledHandlers.add(e),this.delegate?.addJobSettledHandler?.(e)}tryEnqueue(e){try{return this.accepting?this.delegate?this.delegate.tryEnqueue(e)!==!1:this.queued.length>=this.maxPendingJobs?(this.diagnostic(`Deferred audit queue is full (${this.maxPendingJobs}); dropped ${e.jobId}`),!1):(this.queued.push(e),queueMicrotask(()=>{this.ensureDelegate()}),!0):!1}catch{return!1}}async flush(e={}){const t=this.delegate??await this.ensureDelegate();return t?t.flush(e):this.queued.length===0}async stop(e={}){this.accepting=!1;const t=this.delegate??(this.queued.length>0?await this.ensureDelegate():void 0);if(!t){const i=this.queued.length===0;return this.queued.length=0,i}return t.stop(e)}ensureDelegate(){return this.delegate?Promise.resolve(this.delegate):this.initialization?this.initialization:(this.initialization=this.options.initialize().then(e=>{this.delegate=e;for(const i of this.jobSettledHandlers)e.addJobSettledHandler?.(i);const t=this.queued.splice(0);for(const i of t)e.tryEnqueue(i)===!1&&(this.diagnostic(`Audit Recorder rejected deferred job ${i.jobId}`),this.settle(i,{ok:!1,error:"Audit Recorder rejected the replay job"}));return e}).catch(e=>{const t=e instanceof Error?e.message:String(e);this.diagnostic(`Audit Recorder initialization failed: ${t}`);const i=this.queued.splice(0);for(const s of i)this.settle(s,{ok:!1,error:`Audit Recorder initialization failed: ${t}`})}).finally(()=>{this.initialization=void 0}),this.initialization)}diagnostic(e){try{this.onDiagnostic?.(e)}catch{}}settle(e,t){for(const i of this.jobSettledHandlers)try{i(e,t)}catch{}}}function m(n={}){const e=l(n.storageRootDir);return new c({maxPendingJobs:n.maxPendingJobs,onDiagnostic:t=>r.warn("audit-recorder",t),initialize:async()=>new d({maxQueueSize:n.maxPendingJobs,workerConfig:{storageRootDir:e,maxWorkerQueueSize:n.maxWorkerQueueSize},onDiagnostic:t=>{r.warn("audit-recorder",`${t.type}: ${t.message}`)}})})}export{c as DeferredAuditProducer,m as createDefaultAuditProducer,l as resolveDefaultAuditStorageRootDir};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{createHash as J,randomUUID as k}from"node:crypto";import{access as z,open as K,mkdir as R,readFile as p,readdir as L,rename as U,rm as q,writeFile as H}from"node:fs/promises";import{basename as V,dirname as G,join as d,relative as Q,resolve as C,sep as D}from"node:path";import{contentReferenceKey as b}from"../core/content-reference.js";const _=/^[a-f0-9]{64}$/,S=Object.freeze({inputOutput:!1,tools:!1,subagents:!1,thinking:!1,rawProviderBody:!1});class j extends Error{constructor(){super("Audit content blob was not found"),this.name="AuditContentNotFoundError"}}class I extends Error{constructor(t="Audit content blob is corrupt"){super(t),this.name="AuditContentCorruptError"}}function X(i){return i?.enabled?{...i.capture}:{...S}}class st{rootDir;resolveCapturePolicy;constructor(t){if(!t.rootDir.trim())throw new Error("Audit replay rootDir is required");this.rootDir=C(t.rootDir),this.resolveCapturePolicy=t.resolveCapturePolicy}async save(t,e){const r=e?X(e):this.resolveCapturePolicy?await this.resolveCapturePolicy(t):S;await this.saveReplay(t,r)}async saveReplay(t,e){await this.ensureRoot();const r=await this.get(t.auditId,t.turnId);if(r?.sourceJobId===t.sourceJobId)return r;if(r&&t.revisionTrigger==="turn_closed")throw new Error("Audit replay revision trigger conflict: turn_closed cannot replace an existing revision");const n=(r?.revision??0)+1;if(t.revision!==n)throw new Error(`Audit replay revision conflict: expected ${n}, received ${t.revision}`);const o=t.input?await this.storeContent(t.input,e):void 0,s=t.finalOutput?await this.storeContent(t.finalOutput,e):void 0,a=[];for(const c of t.contents)a.push(await this.storeContent(c,e));const u=new Map([o?.reference,s?.reference,...a.map(c=>c.reference)].filter(c=>c!==void 0).map(c=>[b(c),c])),l={...t,input:o,finalOutput:s,contents:a,spans:t.spans.map(c=>({...c,inputRefs:c.inputRefs.flatMap(v=>{const m=u.get(b(v));return m?[m]:[]}),outputRefs:c.outputRefs.flatMap(v=>{const m=u.get(b(v));return m?[m]:[]})}))},P=y(l),g=h(P),B=f(t.auditId),T=f(t.turnId),x=d(this.rootDir,"replays",B,T,`${g}.json`);await this.writeImmutable(x,P);const A=this.manifestPath(t.auditId,t.turnId),E={schemaVersion:1,auditId:t.auditId,turnId:t.turnId,sessionId:t.sessionId,revision:t.revision,replayPath:this.relativePath(x),replaySha256:g,contentIds:tt(l),committedAt:new Date().toISOString()},F=this.turnIndexPath(t.turnId,t.auditId),W={schemaVersion:1,auditId:t.auditId,turnId:t.turnId,manifestPath:this.relativePath(A)};return await this.atomicWrite(F,y(W)),await this.writeImmutable(this.revisionManifestPath(t.auditId,t.turnId,t.revision),y(E)),await this.atomicWrite(A,y(E)),l}async get(t,e){const r=await this.readManifest(this.manifestPath(t,e));if(r){if(r.auditId!==t||r.turnId!==e)throw new Error("Audit replay manifest identifier mismatch");return this.readReplay(r)}}async getRevision(t,e,r){if(!Number.isSafeInteger(r)||r<=0)throw new Error("Audit replay revision must be a positive integer");const n=await this.readManifest(this.revisionManifestPath(t,e,r));if(n){if(n.auditId!==t||n.turnId!==e||n.revision!==r)throw new Error("Audit replay revision manifest mismatch");return this.readReplay(n)}}async findByAuditId(t){const e=d(this.rootDir,"manifests","by-audit",f(t)),r=await N(e),n=[];for(const o of r.filter(s=>s.endsWith(".json")).sort()){const s=await this.readManifest(d(e,o));!s||s.auditId!==t||n.push(await this.readReplay(s))}return O(n)}async findByTurnId(t){const e=d(this.rootDir,"indexes","by-turn",f(t)),r=await N(e),n=[];for(const o of r.filter(s=>s.endsWith(".json")).sort()){const s=await this.readIndex(d(e,o));if(!s||s.turnId!==t)continue;const a=this.resolveStoredPath(s.manifestPath),u=await this.readManifest(a);!u||u.auditId!==s.auditId||u.turnId!==t||n.push(await this.readReplay(u))}return O(n)}async readContent(t){if(!_.test(t))throw new Error("Invalid audit content id");const e=await p(this.blobPath(t));if(h(e)!==t)throw new Error("Audit blob content hash mismatch");return e.toString("utf8")}async readContentChunk(t,e,r){if(!_.test(t))throw new Error("Invalid audit content id");if(!Number.isSafeInteger(e)||e<0)throw new Error("Audit content byteStart must be a non-negative integer");if(!Number.isSafeInteger(r)||r<=0)throw new Error("Audit content maxBytes must be a positive integer");let n;try{n=await K(this.blobPath(t),"r")}catch(o){throw w(o)?new j:o}try{const o=await n.stat();if(!o.isFile())throw new I;const s=o.size;if(e>s)throw new I("Audit content cursor exceeds blob size");const a=Math.min(r,s-e),u=Buffer.allocUnsafe(a);if(a===0)return{bytes:u,totalBytes:s};const{bytesRead:l}=await n.read(u,0,a,e);if(l!==a)throw new I("Audit content blob ended unexpectedly");return{bytes:u,totalBytes:s}}catch(o){throw w(o)?new j:o}finally{await n.close()}}async ensureRoot(){await R(this.rootDir,{recursive:!0,mode:448})}async storeContent(t,e){const{value:r,...n}=t;if(t.value===void 0)return{...n,omittedReason:"value_missing"};if(!Y(t.role,e))return{...n,captureLevel:"metadata_only",omittedReason:"capture_disabled"};const o=Buffer.from(t.value,"utf8"),s=h(o),a=this.blobPath(s);await this.storePlaintextBlob(a,s,o);const u={contentId:s,role:t.role,format:t.format,mimeType:Z(t.format),byteSize:o.byteLength,charCount:[...t.value].length,encrypted:!1,truncated:!1,redacted:!1,captureLevel:t.captureLevel??"reconstructed",storagePath:this.relativePath(a)};return{...n,reference:u}}async storePlaintextBlob(t,e,r){if(await $(t)){const n=await p(t);if(h(n)===e)return}await this.atomicWrite(t,r)}async writeImmutable(t,e){await $(t)||await this.atomicWrite(t,e)}async atomicWrite(t,e){const r=G(t);await R(r,{recursive:!0,mode:448});const n=d(r,`.${V(t)}.${process.pid}.${k()}.tmp`);try{await H(n,e,{mode:384,flag:"wx"}),await U(n,t)}finally{await q(n,{force:!0})}}manifestPath(t,e){return d(this.rootDir,"manifests","by-audit",f(t),`${f(e)}.json`)}revisionManifestPath(t,e,r){return d(this.rootDir,"manifests","revisions",f(t),f(e),`${r}.json`)}turnIndexPath(t,e){return d(this.rootDir,"indexes","by-turn",f(t),`${f(e)}.json`)}blobPath(t){return d(this.rootDir,"blobs","sha256",t.slice(0,2),`${t}.blob`)}relativePath(t){return Q(this.rootDir,t).split(D).join("/")}resolveStoredPath(t){const e=C(this.rootDir,t);if(e!==this.rootDir&&!e.startsWith(`${this.rootDir}${D}`))throw new Error("Audit replay path escapes the storage root");return e}async readManifest(t){const e=await M(t);if(e)return e}async readIndex(t){const e=await M(t);if(e)return e}async readReplay(t){const e=this.resolveStoredPath(t.replayPath),r=await p(e);if(h(r)!==t.replaySha256)throw new Error("Audit replay document hash mismatch");const n=JSON.parse(r.toString("utf8"));if(n.auditId!==t.auditId||n.turnId!==t.turnId||n.revision!==t.revision)throw new Error("Audit replay document identifier mismatch");return n}}function Y(i,t){switch(i){case"user_input":case"assistant_text":case"final_response":return t.inputOutput;case"tool_arguments":case"tool_result":return t.tools;case"subagent_prompt":case"subagent_result":return t.subagents;case"thinking":return t.thinking;case"system_prompt":case"model_request":case"model_response":return t.rawProviderBody}}function Z(i){switch(i){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 tt(i){const t=[i.input?.reference?.contentId,i.finalOutput?.reference?.contentId,...i.contents.map(e=>e.reference?.contentId)].filter(e=>e!==void 0);return[...new Set(t)].sort()}function O(i){return i.sort((t,e)=>t.startedAt.localeCompare(e.startedAt)||t.auditId.localeCompare(e.auditId)||t.turnId.localeCompare(e.turnId))}function y(i){return Buffer.from(`${JSON.stringify(i,null,2)}
|
|
2
|
+
`,"utf8")}function h(i){return J("sha256").update(i).digest("hex")}function f(i){return h(Buffer.from(i,"utf8"))}async function $(i){try{return await z(i),!0}catch(t){if(w(t))return!1;throw t}}async function N(i){try{return await L(i)}catch(t){if(w(t))return[];throw t}}async function M(i){try{return JSON.parse(await p(i,"utf8"))}catch(t){if(w(t))return;throw t}}function w(i){return typeof i=="object"&&i!==null&&"code"in i&&i.code==="ENOENT"}export{I as AuditContentCorruptError,j as AuditContentNotFoundError,st as FileAuditReplayStore,X as capturePolicyFromAuditOptions};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const o=3;function i(r){if(!e(r)||typeof r.type!="string")return!1;switch(r.type){case"audit_recorder_initialize":return r.protocolVersion===3&&t(r.config);case"audit_recorder_job":return typeof r.deliveryId=="string"&&e(r.job);case"audit_recorder_flush":case"audit_recorder_stop":return typeof r.requestId=="string";default:return!1}}function n(r){if(!e(r)||typeof r.type!="string")return!1;switch(r.type){case"audit_recorder_ready":return r.protocolVersion===3;case"audit_recorder_job_result":return typeof r.deliveryId=="string"&&typeof r.ok=="boolean"&&typeof r.retryable=="boolean"&&(r.error===void 0||typeof r.error=="string")&&(r.revision===void 0||typeof r.revision=="number"&&Number.isSafeInteger(r.revision)&&r.revision>0)&&(r.quality===void 0||r.quality==="complete"||r.quality==="partial"||r.quality==="metadata_only"||r.quality==="failed")&&(r.truncated===void 0||typeof r.truncated=="boolean");case"audit_recorder_flushed":case"audit_recorder_stopped":return typeof r.requestId=="string";case"audit_recorder_fatal":return typeof r.error=="string";default:return!1}}function t(r){return e(r)?typeof r.storageRootDir=="string"&&(r.maxWorkerQueueSize===void 0||typeof r.maxWorkerQueueSize=="number"&&Number.isSafeInteger(r.maxWorkerQueueSize)&&r.maxWorkerQueueSize>0):!1}function e(r){return typeof r=="object"&&r!==null&&!Array.isArray(r)}export{o as AUDIT_RECORDER_PROTOCOL_VERSION,n as isAuditRecorderChildMessage,i as isAuditRecorderParentMessage};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{AuditAdapterRegistry as n,ReplayFinalizer as d}from"../core/replay-finalizer.js";import{ClaudeAuditAdapter as s}from"../adapters/claude/claude-audit-adapter.js";import{CodexAuditAdapter as c}from"../adapters/codex/codex-audit-adapter.js";import{PiAuditAdapter as p}from"../adapters/pi/pi-audit-adapter.js";import{AcpAuditAdapter as a}from"../adapters/acp/acp-audit-adapter.js";import{CodeWhaleAuditAdapter as u}from"../adapters/codewhale/codewhale-audit-adapter.js";import{CursorAuditAdapter as f}from"../adapters/cursor/cursor-audit-adapter.js";import{OpenCodeAuditAdapter as m}from"../adapters/opencode/opencode-audit-adapter.js";import{FileAuditReplayStore as A}from"../storage/file-audit-replay-store.js";import{AUDIT_RECORDER_PROTOCOL_VERSION as w,isAuditRecorderParentMessage as R}from"./audit-recorder-ipc-protocol.js";import{AuditRecorderWorker as g}from"./audit-recorder-worker.js";function l(e){if(!e.storageRootDir.trim())throw new Error("Recorder storageRootDir is required");const t=new A({rootDir:e.storageRootDir}),r=new n;return r.register(new s),r.register(new c),r.register(new p),r.register(new a),r.register(new u),r.register(new f),r.register(new m),new d(r,t)}function o(e){if(!(!process.connected||typeof process.send!="function"))try{process.send(e,()=>{})}catch{}}let i;process.on("message",e=>{if(R(e)){if(e.type==="audit_recorder_initialize"){if(i)return;try{i=new g({finalizer:l(e.config),maxQueueSize:e.config.maxWorkerQueueSize,send:o,onStopped:()=>{setImmediate(()=>{process.connected&&process.disconnect?.()})}}),o({type:"audit_recorder_ready",protocolVersion:w})}catch(t){o({type:"audit_recorder_fatal",error:t instanceof Error?t.message:String(t)}),setImmediate(()=>{process.connected&&process.disconnect?.()})}return}i?.handle(e)}}),process.on("disconnect",()=>{process.exitCode=0});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
class n{finalizer;sendMessage;maxQueueSize;onStopped;queue=[];flushRequests=[];processing=!1;accepting=!0;stopRequestId;stopped=!1;constructor(e){const t=e.maxQueueSize??16;if(!Number.isSafeInteger(t)||t<=0)throw new Error("Recorder worker maxQueueSize must be a positive integer");this.finalizer=e.finalizer,this.sendMessage=e.send,this.maxQueueSize=t,this.onStopped=e.onStopped}handle(e){if(!this.stopped)switch(e.type){case"audit_recorder_job":this.enqueue(e.deliveryId,e.job);return;case"audit_recorder_flush":this.flushRequests.push(e.requestId),this.settleIdleRequests();return;case"audit_recorder_stop":this.accepting=!1,this.stopRequestId??=e.requestId,this.settleIdleRequests();return;case"audit_recorder_initialize":return}}enqueue(e,t){if(!this.accepting){this.safeSend({type:"audit_recorder_job_result",deliveryId:e,ok:!1,retryable:!0,error:"Recorder worker is stopping"});return}if(this.queue.length+(this.processing?1:0)>=this.maxQueueSize){this.safeSend({type:"audit_recorder_job_result",deliveryId:e,ok:!1,retryable:!0,error:"Recorder worker queue is full"});return}this.queue.push({deliveryId:e,job:t}),this.pump()}pump(){if(this.processing||this.stopped)return;const e=this.queue.shift();if(!e){this.settleIdleRequests();return}this.processing=!0,this.finalizer.finalize(e.job).then(t=>{this.safeSend({type:"audit_recorder_job_result",deliveryId:e.deliveryId,ok:!0,retryable:!1,revision:t.revision,quality:t.quality.status,truncated:i(t)})}).catch(t=>{this.safeSend({type:"audit_recorder_job_result",deliveryId:e.deliveryId,ok:!1,retryable:!1,error:r(t)})}).finally(()=>{this.processing=!1,this.pump()})}settleIdleRequests(){if(!(this.processing||this.queue.length>0||this.stopped)){for(const e of this.flushRequests.splice(0))this.safeSend({type:"audit_recorder_flushed",requestId:e});if(this.stopRequestId){this.stopped=!0,this.safeSend({type:"audit_recorder_stopped",requestId:this.stopRequestId});try{this.onStopped?.()}catch{}}}}safeSend(e){try{this.sendMessage(e)}catch{}}}function r(s){return s instanceof Error?s.message:typeof s=="string"?s:"Unknown audit replay finalization failure"}function i(s){return s.spans.some(e=>e.inputRefs.some(t=>t.truncated)||e.outputRefs.some(t=>t.truncated))}export{n as AuditRecorderWorker};
|