grix-connector 3.19.0 → 3.19.1
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/claude/claude-adapter.js +21 -21
- package/dist/adapter/opencode/opencode-adapter.js +3 -3
- package/dist/audit/adapters/codex/codex-audit-adapter.js +1 -1
- package/dist/bridge/bridge.js +2 -2
- package/dist/core/proxy/proxy-manager.js +4 -4
- package/dist/grix.js +1 -1
- package/dist/mcp/stream-http/security.js +1 -1
- package/package.json +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import{EventEmitter as S}from"node:events";import{stat as A}from"node:fs/promises";import{existsSync as E,mkdirSync as C,readFileSync as P,writeFileSync as b}from"node:fs";import{join as g,resolve as $,dirname as _}from"node:path";import{homedir as
|
|
2
|
-
`,"utf8"),n.info("opencode-adapter",`MCP config injected into ${s}`);const r=g(t,"opencode","skills"),a=L(r);a.length>0&&n.info("opencode-adapter",`Synced connector skills to ${r}: [${a.join(", ")}]`)}catch(e){n.warn("opencode-adapter",`Failed to inject MCP tools (non-fatal): ${e instanceof Error?e.message:String(e)}`)}}async handleLocalAction(e){const{action_type:t}=e;return t==="exec_approve"||t==="exec_reject"||t==="permission_approve"||t==="permission_reject"?this.handlePermissionAction(e):{handled:!1,kind:""}}bindSession(e,t){if(n.info("opencode-adapter",`bindSession: ${e} \u2192 ${t}`),!this.sessions.has(e))this.sessions.set(e,{ocSessionId:"",cwd:t});else{const s=this.sessions.get(e);s.cwd=t}}async spawnAndWait(e,t){const s=this.resolveCwd();try{if(!(await A(s)).isDirectory())throw new Error(`Bound path is not a directory: ${s}`)}catch(i){throw String(i?.code??"")==="ENOENT"?new Error(`Bound directory does not exist: ${s}. Please rebind with /grix open <valid-directory>.`):i}return new Promise((i,o)=>{const r=this.config.command||"opencode",d=[...this.config.args??["serve"],`--hostname=${e}`,`--port=${t}`],h={...process.env,...this.config.env},m=J({model:this.options.model,permissionPolicy:this.options.permissionPolicy,provider:this.options.provider});m&&(h.OPENCODE_CONFIG_CONTENT=JSON.stringify(m));const p=
|
|
3
|
-
`)){const I=u.match(/opencode server listening on (https?:\/\/[^\s]+)/);if(I){clearTimeout(v),l=!0,this.alive=!0,i(I[1]);return}}}),this.process.stderr?.on("data",c=>{const u=c.toString().trim();u&&n.info("opencode-adapter",`[stderr] ${u}`)}),this.process.on("error",c=>{n.error("opencode-adapter",`Spawn error: ${c.message}`),clearTimeout(v),this.alive=!1,this.transport.disconnect(),this.activeRun&&(this.callbacks.sendEventResult(this.activeRun.eventId,"failed",`Spawn error: ${c.message}`),this.clearRun()),l?this.stopped||this.emit("exit",1):(l=!0,o(c))}),this.process.on("exit",c=>{n.info("opencode-adapter",`Process exited (code=${c})`),clearTimeout(v),this.alive=!1,this.transport.disconnect(),this.stopComposing(),this.stopIdleTimer(),this.stopTextFlush(),this.activeRun&&(this.callbacks.sendEventResult(this.activeRun.eventId,"failed",`Process exited (code=${c})`),this.clearRun()),l?this.stopped||this.emit("exit",c??1):(l=!0,o(new Error(`opencode serve exited with code ${c}`)))})})}async ensureOcSession(e){const t=this.sessions.get(e),s=this.getSessionCwd(e);if(await this.transport.useDirectory(s),t?.ocSessionId)try{return await this.transport.getSession(t.ocSessionId,s),t.ocSessionId}catch{n.warn("opencode-adapter",`OC session ${t.ocSessionId} gone, creating new`),t.ocSessionId=""}const i=this.options.bindingStore?.getAcpSessionId(e);if(i)try{return await this.transport.getSession(i,s),this.sessions.set(e,{ocSessionId:i,cwd:s}),n.info("opencode-adapter",`Resumed OC session ${i} for aibot=${e}`),i}catch{n.warn("opencode-adapter",`Persisted OC session ${i} gone, creating new`)}const o=await this.transport.createSession({title:`grix-${e.slice(-8)}`},s);return this.sessions.set(e,{ocSessionId:o.id,cwd:s}),this.options.bindingStore?.setAcpSessionId(e,o.id),n.info("opencode-adapter",`Created OC session ${o.id} for aibot=${e}`),o.id}async sendOcPrompt(e,t){const s=this.getSessionCwd(e),i=await this.ensureOcSession(e);this.activeRun&&(this.activeRun.ocSessionId=i,this.activeRun.cwd=s),await this.transport.sendPromptAsync(i,{parts:[{type:"text",text:t}]},s)}handleSseEvent(e){if(!this.stopped){if(this.lastSseAt=Date.now(),this.updateToolInFlight(e),this.resetIdleTimer(),this.activeRun){const t=this.auditCaptures.get(this.activeRun.eventId);t&&t.push({sequence:t.length,observedAt:new Date().toISOString(),event:structuredClone(e)})}switch(e.type){case"message.part.updated":{if(!this.activeRun)break;const t=e.part,s=e.delta;if(t.type==="text"){const i=s||t.text;i&&this.acceptAssistantPartText(t.messageID,"text",i)}else t.type==="reasoning"?s&&this.acceptAssistantPartText(t.messageID,"reasoning",s):t.type==="tool"&&this.handleToolPartUpdate(t,s);break}case"message.updated":{if(!this.activeRun)break;const t=e.info;if(this.rememberMessageRole(t),t.role==="assistant"){const s=t;this.callbacks.sendUpdateBindingCard(this.activeRun.sessionId,"composing",this.activeRun.cwd,{model_provider:s.providerID,model_id:s.modelID}),s.error&&n.warn("opencode-adapter",`Message error: ${JSON.stringify(s.error)}`)}break}case"session.idle":{if(!this.activeRun)break;e.sessionID===this.activeRun.ocSessionId&&(this.flushTextBuffer(),this.finishRun("responded"));break}case"session.status":{if(!this.activeRun)break;e.sessionID===this.activeRun.ocSessionId&&e.status.type==="idle"&&(this.flushTextBuffer(),this.finishRun("responded"));break}case"session.error":{if(!this.activeRun)break;const t=e.error,s=t?typeof t=="object"&&"message"in t?t.message:JSON.stringify(t):"unknown session error";n.error("opencode-adapter",`Session error: ${s}`),this.flushTextBuffer(),this.finishRun("failed",s);break}case"permission.updated":{this.handlePermission(e.permission);break}case"session.created":case"session.updated":case"session.deleted":case"session.compacted":case"session.diff":case"file.edited":case"server.connected":break;case"server.instance.disposed":{n.warn("opencode-adapter",`Server instance disposed: ${e.directory}`),this.alive=!1,this.transport.disconnect(),this.activeRun&&(this.flushTextBuffer(),this.callbacks.sendEventResult(this.activeRun.eventId,"failed","server instance disposed"),this.clearRun()),this.stopped||this.emit("exit",-1);break}default:break}}}updateToolInFlight(e){if(e.type!=="message.part.updated")return;const t=e.part;if(t?.type!=="tool"||!t.callID)return;const s=t.state?.status;s==="pending"||s==="running"?this.toolCallsInFlight.add(t.callID):(s==="completed"||s==="error")&&this.toolCallsInFlight.delete(t.callID)}rememberMessageRole(e){const t=typeof e.id=="string"?e.id.trim():"";t&&(e.role!=="user"&&e.role!=="assistant"||(this.messageRoles.set(t,e.role),this.flushOrDropPendingParts(t,e.role)))}acceptAssistantPartText(e,t,s){if(!this.activeRun||!s)return;const i=typeof e=="string"?e.trim():"";if(!i)return;const o=this.messageRoles.get(i);if(o==="user")return;if(o==="assistant"){this.emitAssistantPartChunk(t,s);return}const r=this.pendingPartChunks.get(i)??[];r.push({kind:t,value:s}),this.pendingPartChunks.set(i,r)}flushOrDropPendingParts(e,t){const s=this.pendingPartChunks.get(e);if(this.pendingPartChunks.delete(e),!(!s||s.length===0)&&t==="assistant")for(const i of s)this.emitAssistantPartChunk(i.kind,i.value)}emitAssistantPartChunk(e,t){if(!(!this.activeRun||!t)){if(e==="reasoning"){this.callbacks.sendThinking(this.activeRun.eventId,this.activeRun.sessionId,t);return}this.appendText(t)}}clearMessageRoleState(){this.messageRoles.clear(),this.pendingPartChunks.clear()}handleToolPartUpdate(e,t){if(!this.activeRun)return;const s=e.state;switch(s.status){case"pending":case"running":{this.sendToolUseOnce(e,s.input);break}case"completed":{this.sendToolUseOnce(e,s.input);break}case"error":{this.sendToolUseOnce(e,s.input),this.callbacks.sendToolResult(this.activeRun.eventId,this.activeRun.sessionId,e.tool,"(failed)");break}}}sendToolUseOnce(e,t){!this.activeRun||this.toolCardsSent.has(e.callID)||(this.flushTextBuffer(),this.toolCardsSent.add(e.callID),this.callbacks.sendToolUse(this.activeRun.eventId,this.activeRun.sessionId,e.tool,H(t??{})))}handlePermission(e){if(!this.activeRun)return;const{eventId:t,sessionId:s,ocSessionId:i}=this.activeRun;if(this.options.permissionPolicy==="fullAuto"){this.transport.respondPermission(i,e.id,"always",this.activeRun.cwd).catch(r=>{n.warn("opencode-adapter",`Auto-approve failed: ${r}`)});return}this.stopIdleTimer(),this.pendingPermissions.set(t,{permissionId:e.id,ocSessionId:i,cwd:this.activeRun.cwd});const o=JSON.stringify(e.metadata??{});this.callbacks.sendToolUse(t,s,e.type,o)}handlePermissionAction(e){if(!this.activeRun)return{handled:!1,kind:""};const t=this.pendingPermissions.get(this.activeRun.eventId);if(!t)return{handled:!1,kind:""};const{permissionId:s,ocSessionId:i,cwd:o}=t,a=e.action_type==="exec_approve"||e.action_type==="permission_approve"?"once":"reject";return this.pendingPermissions.delete(this.activeRun.eventId),this.transport.respondPermission(i,s,a,o).then(()=>{n.info("opencode-adapter",`Permission ${a}: ${s}`),this.resetIdleTimer()}).catch(d=>{n.warn("opencode-adapter",`Permission response failed: ${d}`)}),{handled:!0,kind:"permission"}}startRun(e,t,s=!1){this.activeRun={eventId:e,sessionId:t,ocSessionId:"",cwd:this.getSessionCwd(t),chunkSeq:0,clientMsgId:`oc_${++this.clientMsgSeq}_${Date.now()}`,textBuffer:"",flushTimer:null},this.toolCardsSent.clear(),s&&this.auditCaptures.set(e,[]),this.lastSseAt=Date.now(),this.livenessExtendStartAt=void 0}finishRun(e,t){const s=this.activeRun;if(!s)return;if(this.completedEvents.add(s.eventId),this.completedEvents.size>Q){const a=[...this.completedEvents].slice(-500);this.completedEvents=new Set(a)}this.snapshotAuditBoundary(s),this.activeRun=null,this.toolCallsInFlight.clear(),this.toolCardsSent.clear(),this.livenessExtendStartAt=void 0,this.clearMessageRoleState(),this.stopComposing(),this.stopIdleTimer();const i=++s.chunkSeq,o=s.clientMsgId;e==="failed"&&t&&this.callbacks.sendRunError(s.eventId,s.sessionId,t);const r=()=>{this.callbacks.sendFinalStreamChunkReliable?this.callbacks.sendFinalStreamChunkReliable(s.eventId,s.sessionId,o).then(()=>{this.callbacks.sendEventResult(s.eventId,e,t)}).catch(a=>{const d=e==="responded"?"failed":e,h=e==="responded"?`final output delivery failed: ${a instanceof Error?a.message:String(a)}`:t;this.callbacks.sendEventResult(s.eventId,d,h)}):(this.callbacks.sendStreamChunk(s.eventId,s.sessionId,"",i,!0,o),this.callbacks.sendEventResult(s.eventId,e,t))};if(s.textBuffer){this.stopTextFlush();for(const a of T(s.textBuffer))s.chunkSeq++,this.callbacks.sendStreamChunk(s.eventId,s.sessionId,a,s.chunkSeq,!1,s.clientMsgId);s.textBuffer=""}r(),this.emit("eventDone",s.eventId)}clearRun(){this.activeRun?.flushTimer&&clearTimeout(this.activeRun.flushTimer);const e=this.activeRun?.eventId;this.activeRun&&this.snapshotAuditBoundary(this.activeRun),this.activeRun=null,this.toolCallsInFlight.clear(),this.toolCardsSent.clear(),this.livenessExtendStartAt=void 0,this.clearMessageRoleState(),this.stopIdleTimer(),e&&this.emit("eventDone",e)}snapshotAuditBoundary(e){const t=this.auditCaptures.get(e.eventId);t&&(this.completedAuditBoundaries.set(e.eventId,{adapterType:"opencode",providerSessionId:e.ocSessionId||void 0,openCodeEvidence:{events:t}}),this.auditCaptures.delete(e.eventId))}appendText(e){if(this.activeRun){if(this.activeRun.textBuffer+=e,this.activeRun.textBuffer.length>=z){this.flushTextBuffer();return}this.scheduleTextFlush()}}scheduleTextFlush(){!this.activeRun||this.activeRun.flushTimer||(this.activeRun.flushTimer=setTimeout(()=>{this.activeRun&&(this.activeRun.flushTimer=null),this.flushTextBuffer()},q))}flushTextBuffer(){if(this.stopTextFlush(),!(!this.activeRun||!this.activeRun.textBuffer)){for(const e of T(this.activeRun.textBuffer))this.activeRun.chunkSeq++,this.callbacks.sendStreamChunk(this.activeRun.eventId,this.activeRun.sessionId,e,this.activeRun.chunkSeq,!1,this.activeRun.clientMsgId);this.activeRun.textBuffer=""}}stopTextFlush(){this.activeRun?.flushTimer&&(clearTimeout(this.activeRun.flushTimer),this.activeRun.flushTimer=null)}startComposing(e){}stopComposing(){}shouldExtendByLiveness(){if(!this.activeRun)return!1;const e=this.process?.pid;if(!this.alive||!e||!k(e))return!1;const t=Date.now(),s=this.lastSseAt>0?t-this.lastSseAt:Number.POSITIVE_INFINITY;if(s<W)return this.livenessExtendStartAt=t,n.info("opencode-adapter",`Liveness check: fresh SSE for ${this.activeRun.eventId} (sseAge=${s}ms, toolsInFlight=${this.toolCallsInFlight.size}), extending`),!0;const o=this.livenessExtendStartAt??t;return this.livenessExtendStartAt===void 0&&(this.livenessExtendStartAt=o),t-o>x?(n.warn("opencode-adapter",`Liveness extension budget exhausted for ${this.activeRun.eventId} (no progress for ${Math.round((t-o)/6e4)}min), allowing idle fail`),!1):(n.info("opencode-adapter",`Liveness check: turn in progress for ${this.activeRun.eventId} (toolsInFlight=${this.toolCallsInFlight.size}, sseAge=${Number.isFinite(s)?`${s}ms`:"n/a"}), extending`),!0)}resetIdleTimer(){this.stopIdleTimer(),!(this.stopped||!this.activeRun)&&(this.idleTimer=setTimeout(()=>{if(this.stopped||!this.activeRun)return;if(this.pendingPermissions.has(this.activeRun.eventId)&&this.shouldExtendByLiveness()){n.info("opencode-adapter",`Idle timeout skipped: pendingPermissions for ${this.activeRun.eventId}, resetting timer`),this.resetIdleTimer();return}if(this.shouldExtendByLiveness()){this.resetIdleTimer();return}const e=this.process?.pid,s=!!(this.alive&&e&&k(e))?`liveness budget exhausted after ${x/6e4}min`:"process not alive";n.error("opencode-adapter",`Idle timeout (${s}, toolsInFlight=${this.toolCallsInFlight.size}) \u2014 emitting exit for respawn`),this.flushTextBuffer(),this.activeRun&&(this.callbacks.sendEventResult(this.activeRun.eventId,"failed",`idle timeout: ${s}`),this.clearRun()),this.emit("exit",-1)},V))}stopIdleTimer(){this.idleTimer&&(clearTimeout(this.idleTimer),this.idleTimer=null)}resolveCwd(){const e=this.options.aibotSessionId?this.options.bindingStore?.get(this.options.aibotSessionId)?.cwd:void 0;if(e)return e;const t=(this.config.options??{}).cwd;return typeof t=="string"&&t?t:process.cwd()}getSessionCwd(e){return this.sessions.get(e)?.cwd??this.options.bindingStore?.get(e)?.cwd??this.resolveCwd()}buildPromptText(e){let t=e.text;return e.contextMessages&&e.contextMessages.length>0&&(t=e.contextMessages.map(i=>`[context] ${i.senderId}: ${i.content}`).join(`
|
|
1
|
+
import{EventEmitter as S}from"node:events";import{stat as A}from"node:fs/promises";import{existsSync as E,mkdirSync as C,readFileSync as P,writeFileSync as b}from"node:fs";import{join as g,resolve as $,dirname as _}from"node:path";import{homedir as O}from"node:os";import{fileURLToPath as F}from"node:url";import{resolveCommandPath as M,spawnCommand as B,killProcessGroup as w,hasChildProcesses as D}from"../../core/runtime/spawn.js";import{InternalApiServer as N}from"../../core/mcp/internal-api-server.js";import{IdentityInjector as j}from"../shared/identity-injector.js";import{syncDefaultSkillsToDir as L}from"../../default-skills/index.js";import{buildSimpleProbeReport as U}from"../shared/probe-util.js";import{compactToolInputForWire as H}from"../shared/tool-wire-payload.js";import{buildOpencodeConfigContent as J}from"./opencode-config.js";import{OpenCodeTransport as G}from"./opencode-transport.js";import{log as n}from"../../core/log/index.js";import{splitTextForAibotProtocol as T}from"../../core/protocol/index.js";class X extends S{adapterSessionId;constructor(e){super(),this.adapterSessionId=e}emitError(e){if(this.listenerCount("error")===0){n.warn("opencode-adapter",`Prompt handle error (no listeners): ${e.message}`);return}this.emit("error",e)}async cancel(){}}const q=200,z=2e3,V=12e4,W=90*1e3,x=1800*1e3,y=3e4,K="127.0.0.1",Y=0,Q=1e3;function k(f){try{return process.kill(f,0),!0}catch(e){return e.code==="EPERM"}}class me extends S{type="opencode";config;callbacks;options;identity;process=null;transport=new G;alive=!1;stopped=!1;internalApi=null;sessions=new Map;activeRun=null;completedEvents=new Set;clientMsgSeq=0;auditCaptures=new Map;completedAuditBoundaries=new Map;idleTimer=null;lastSseAt=0;livenessExtendStartAt;toolCallsInFlight=new Set;toolCardsSent=new Set;messageRoles=new Map;pendingPartChunks=new Map;pendingPermissions=new Map;permissionHandler=null;constructor(e,t,s){super(),this.config=e,this.callbacks=t,this.options=s??{},this.identity=new j("opencode-adapter",t.getAgentProfile)}onAgentProfileChanged(){this.identity.onProfileChanged()}async start(){await this.startInternalApiAndInjectMcp();const e=this.options.hostname??K,t=this.options.port??Y,s=await this.spawnAndWait(e,t),i=this.resolveCwd();await this.transport.connect(s,i),this.transport.on("event",o=>this.handleSseEvent(o)),n.info("opencode-adapter",`Ready (pid=${this.process?.pid}, url=${s})`)}async stop(){if(this.stopped=!0,this.alive=!1,this.stopComposing(),this.stopIdleTimer(),this.stopTextFlush(),this.transport.disconnect(),this.internalApi&&(await this.internalApi.stop(),this.internalApi=null),this.process){const e=this.process;try{w(e,"SIGTERM")}catch{}const t=setTimeout(()=>{try{w(e,"SIGKILL")}catch{}},5e3);e.on("exit",()=>clearTimeout(t)),this.process=null}}isAlive(){return this.alive}async createSession(e){const t=e.cwd??this.resolveCwd();await this.transport.useDirectory(t);const s=await this.transport.createSession({title:`grix-${Date.now()}`},t);return this.sessions.set(s.id,{ocSessionId:s.id,cwd:t}),n.info("opencode-adapter",`Created OC session ${s.id} for cwd=${t}`),s.id}async resumeSession(e,t){const s=this.sessions.get(e);if(s?.ocSessionId)try{await this.transport.useDirectory(s.cwd),await this.transport.getSession(s.ocSessionId,s.cwd)}catch{n.warn("opencode-adapter",`OC session ${s.ocSessionId} gone, will create new on next prompt`),s.ocSessionId=""}}async destroySession(e){const t=this.sessions.get(e),s=t?t.ocSessionId:e;if(s)try{await this.transport.deleteSession(s,t?.cwd)}catch{}this.sessions.delete(e),this.identity.forgetSession(e)}sendPrompt(e){const t=new X(e.adapterSessionId);return this.sendOcPrompt(e.adapterSessionId,this.buildPromptText(e)).catch(s=>{t.emitError(s instanceof Error?s:new Error(String(s)))}),t}async cancel(e){if(this.activeRun)try{await this.transport.abortSession(this.activeRun.ocSessionId,this.activeRun.cwd)}catch{}}deliverInboundEvent(e){const{event_id:t,session_id:s,content:i}=e;if(this.completedEvents.has(t)){n.info("opencode-adapter",`Dropping duplicate event ${t}`),this.callbacks.sendEventAck(t,s),this.callbacks.sendEventResult(t,"responded");return}if(!this.alive){n.warn("opencode-adapter",`Dropping event ${t}: process not alive`),this.callbacks.sendEventAck(t,s),this.callbacks.sendEventResult(t,"failed","Agent process not running");return}this.activeRun&&this.activeRun.eventId!==t&&(n.info("opencode-adapter",`steer: ${this.activeRun.eventId} -> ${t}`),this.flushTextBuffer(),this.callbacks.sendEventResult(this.activeRun.eventId,"canceled","steered to new event"),this.clearRun()),n.info("opencode-adapter",`prompt: event=${t} session=${s}`),this.callbacks.sendEventAck(t,s),this.startRun(t,s,e.audit?.enabled===!0),this.startComposing(s),this.resetIdleTimer();const o=this.buildPromptTextFromEvent(e);this.sendOcPrompt(s,o).catch(r=>{n.error("opencode-adapter",`prompt_async failed: ${r}`),this.finishRun("failed",String(r))})}deliverStopEvent(e,t){this.activeRun&&this.activeRun.eventId===e&&(n.info("opencode-adapter",`stop: event=${e}`),this.transport.abortSession(this.activeRun.ocSessionId,this.activeRun.cwd).catch(()=>{}),this.flushTextBuffer(),this.finishRun("canceled","stopped by user"))}setPermissionHandler(e){this.permissionHandler=e}async ping(e){return this.transport.healthCheck()}getStatus(){return{alive:this.alive,busy:this.activeRun!==null,sessions:this.sessions.size}}getActiveEventIds(){return this.activeRun?[this.activeRun.eventId]:[]}takeAuditBoundary(e){const t=this.completedAuditBoundaries.get(e);return t&&this.completedAuditBoundaries.delete(e),t}clearActiveEventForShutdown(){this.stopIdleTimer(),this.stopTextFlush(),this.activeRun&&this.snapshotAuditBoundary(this.activeRun),this.activeRun=null}getMcpConfig(){if(!this.internalApi)return null;const e=$(F(import.meta.url),"../../../mcp/acp-mcp-server.js");return{name:"grix-connector-tools",command:process.execPath,args:[e,"--api-url",this.internalApi.url]}}async hasBackgroundWork(){const e=this.process?.pid;return e?D(e,[e]):!1}async probe(e){const t=this.getStatus();return U(this.config.command||"opencode",{alive:t.alive,busy:t.busy,started:!!this.process},e)}async startInternalApiAndInjectMcp(){try{this.internalApi=new N,this.internalApi.setInvokeHandler(async(d,h,m,p)=>this.callbacks.agentInvoke(d,h,p)),await this.internalApi.start(0),n.info("opencode-adapter",`Internal API started at ${this.internalApi.url}`);const e=this.getMcpConfig(),t=process.env.XDG_CONFIG_HOME||g(O(),".config"),s=g(t,"opencode","opencode.json");C(_(s),{recursive:!0});let i={};try{E(s)&&(i=JSON.parse(P(s,"utf8")))}catch{}const o=i.mcp&&typeof i.mcp=="object"?i.mcp:{};o[e.name]={type:"local",command:[e.command,...e.args??[]],enabled:!0},i.mcp=o,b(s,`${JSON.stringify(i,null,2)}
|
|
2
|
+
`,"utf8"),n.info("opencode-adapter",`MCP config injected into ${s}`);const r=g(t,"opencode","skills"),a=L(r);a.length>0&&n.info("opencode-adapter",`Synced connector skills to ${r}: [${a.join(", ")}]`)}catch(e){n.warn("opencode-adapter",`Failed to inject MCP tools (non-fatal): ${e instanceof Error?e.message:String(e)}`)}}async handleLocalAction(e){const{action_type:t}=e;return t==="exec_approve"||t==="exec_reject"||t==="permission_approve"||t==="permission_reject"?this.handlePermissionAction(e):{handled:!1,kind:""}}bindSession(e,t){if(n.info("opencode-adapter",`bindSession: ${e} \u2192 ${t}`),!this.sessions.has(e))this.sessions.set(e,{ocSessionId:"",cwd:t});else{const s=this.sessions.get(e);s.cwd=t}}async spawnAndWait(e,t){const s=this.resolveCwd();try{if(!(await A(s)).isDirectory())throw new Error(`Bound path is not a directory: ${s}`)}catch(i){throw String(i?.code??"")==="ENOENT"?new Error(`Bound directory does not exist: ${s}. Please rebind with /grix open <valid-directory>.`):i}return new Promise((i,o)=>{const r=this.config.command||"opencode",d=[...this.config.args??["serve"],`--hostname=${e}`,`--port=${t}`],h={...process.env,...this.config.env},m=J({model:this.options.model,permissionPolicy:this.options.permissionPolicy,provider:this.options.provider});m&&(h.OPENCODE_CONFIG_CONTENT=JSON.stringify(m));const p=M(r,typeof h.PATH=="string"?h.PATH:void 0);n.info("opencode-adapter",`Spawning: ${p} ${d.join(" ")} (cwd=${s})`),this.process=B(p,d,{env:h,cwd:s}).process;let R="",l=!1;const v=setTimeout(()=>{l||(l=!0,o(new Error(`opencode serve did not start after ${y/1e3}s`)))},y);this.process.stdout?.on("data",c=>{if(R+=c.toString(),!l)for(const u of R.split(`
|
|
3
|
+
`)){const I=u.match(/opencode server listening on (https?:\/\/[^\s]+)/);if(I){clearTimeout(v),l=!0,this.alive=!0,i(I[1]);return}}}),this.process.stderr?.on("data",c=>{const u=c.toString().trim();u&&n.info("opencode-adapter",`[stderr] ${u}`)}),this.process.on("error",c=>{n.error("opencode-adapter",`Spawn error: ${c.message}`),clearTimeout(v),this.alive=!1,this.transport.disconnect(),this.activeRun&&(this.callbacks.sendEventResult(this.activeRun.eventId,"failed",`Spawn error: ${c.message}`),this.clearRun()),l?this.stopped||this.emit("exit",1):(l=!0,o(c))}),this.process.on("exit",c=>{n.info("opencode-adapter",`Process exited (code=${c})`),clearTimeout(v),this.alive=!1,this.transport.disconnect(),this.stopComposing(),this.stopIdleTimer(),this.stopTextFlush(),this.activeRun&&(this.callbacks.sendEventResult(this.activeRun.eventId,"failed",`Process exited (code=${c})`),this.clearRun()),l?this.stopped||this.emit("exit",c??1):(l=!0,o(new Error(`opencode serve exited with code ${c}`)))})})}async ensureOcSession(e){const t=this.sessions.get(e),s=this.getSessionCwd(e);if(await this.transport.useDirectory(s),t?.ocSessionId)try{return await this.transport.getSession(t.ocSessionId,s),t.ocSessionId}catch{n.warn("opencode-adapter",`OC session ${t.ocSessionId} gone, creating new`),t.ocSessionId=""}const i=this.options.bindingStore?.getAcpSessionId(e);if(i)try{return await this.transport.getSession(i,s),this.sessions.set(e,{ocSessionId:i,cwd:s}),n.info("opencode-adapter",`Resumed OC session ${i} for aibot=${e}`),i}catch{n.warn("opencode-adapter",`Persisted OC session ${i} gone, creating new`)}const o=await this.transport.createSession({title:`grix-${e.slice(-8)}`},s);return this.sessions.set(e,{ocSessionId:o.id,cwd:s}),this.options.bindingStore?.setAcpSessionId(e,o.id),n.info("opencode-adapter",`Created OC session ${o.id} for aibot=${e}`),o.id}async sendOcPrompt(e,t){const s=this.getSessionCwd(e),i=await this.ensureOcSession(e);this.activeRun&&(this.activeRun.ocSessionId=i,this.activeRun.cwd=s),await this.transport.sendPromptAsync(i,{parts:[{type:"text",text:t}]},s)}handleSseEvent(e){if(!this.stopped){if(this.lastSseAt=Date.now(),this.updateToolInFlight(e),this.resetIdleTimer(),this.activeRun){const t=this.auditCaptures.get(this.activeRun.eventId);t&&t.push({sequence:t.length,observedAt:new Date().toISOString(),event:structuredClone(e)})}switch(e.type){case"message.part.updated":{if(!this.activeRun)break;const t=e.part,s=e.delta;if(t.type==="text"){const i=s||t.text;i&&this.acceptAssistantPartText(t.messageID,"text",i)}else t.type==="reasoning"?s&&this.acceptAssistantPartText(t.messageID,"reasoning",s):t.type==="tool"&&this.handleToolPartUpdate(t,s);break}case"message.updated":{if(!this.activeRun)break;const t=e.info;if(this.rememberMessageRole(t),t.role==="assistant"){const s=t;this.callbacks.sendUpdateBindingCard(this.activeRun.sessionId,"composing",this.activeRun.cwd,{model_provider:s.providerID,model_id:s.modelID}),s.error&&n.warn("opencode-adapter",`Message error: ${JSON.stringify(s.error)}`);const i=this.activeRun.ocSessionId;i&&s.sessionID===i&&(s.error?(this.flushTextBuffer(),this.finishRun("failed",s.error.message||s.error.type)):s.time?.completed&&s.finish!=="tool-calls"&&(this.flushTextBuffer(),this.finishRun("responded")))}break}case"session.idle":{if(!this.activeRun)break;e.sessionID===this.activeRun.ocSessionId&&(this.flushTextBuffer(),this.finishRun("responded"));break}case"session.status":{if(!this.activeRun)break;e.sessionID===this.activeRun.ocSessionId&&e.status.type==="idle"&&(this.flushTextBuffer(),this.finishRun("responded"));break}case"session.error":{if(!this.activeRun)break;const t=e.error,s=t?typeof t=="object"&&"message"in t?t.message:JSON.stringify(t):"unknown session error";n.error("opencode-adapter",`Session error: ${s}`),this.flushTextBuffer(),this.finishRun("failed",s);break}case"permission.updated":{this.handlePermission(e.permission);break}case"session.created":case"session.updated":case"session.deleted":case"session.compacted":case"session.diff":case"file.edited":case"server.connected":break;case"server.instance.disposed":{n.warn("opencode-adapter",`Server instance disposed: ${e.directory}`),this.alive=!1,this.transport.disconnect(),this.activeRun&&(this.flushTextBuffer(),this.callbacks.sendEventResult(this.activeRun.eventId,"failed","server instance disposed"),this.clearRun()),this.stopped||this.emit("exit",-1);break}default:break}}}updateToolInFlight(e){if(e.type!=="message.part.updated")return;const t=e.part;if(t?.type!=="tool"||!t.callID)return;const s=t.state?.status;s==="pending"||s==="running"?this.toolCallsInFlight.add(t.callID):(s==="completed"||s==="error")&&this.toolCallsInFlight.delete(t.callID)}rememberMessageRole(e){const t=typeof e.id=="string"?e.id.trim():"";t&&(e.role!=="user"&&e.role!=="assistant"||(this.messageRoles.set(t,e.role),this.flushOrDropPendingParts(t,e.role)))}acceptAssistantPartText(e,t,s){if(!this.activeRun||!s)return;const i=typeof e=="string"?e.trim():"";if(!i)return;const o=this.messageRoles.get(i);if(o==="user")return;if(o==="assistant"){this.emitAssistantPartChunk(t,s);return}const r=this.pendingPartChunks.get(i)??[];r.push({kind:t,value:s}),this.pendingPartChunks.set(i,r)}flushOrDropPendingParts(e,t){const s=this.pendingPartChunks.get(e);if(this.pendingPartChunks.delete(e),!(!s||s.length===0)&&t==="assistant")for(const i of s)this.emitAssistantPartChunk(i.kind,i.value)}emitAssistantPartChunk(e,t){if(!(!this.activeRun||!t)){if(e==="reasoning"){this.callbacks.sendThinking(this.activeRun.eventId,this.activeRun.sessionId,t);return}this.appendText(t)}}clearMessageRoleState(){this.messageRoles.clear(),this.pendingPartChunks.clear()}handleToolPartUpdate(e,t){if(!this.activeRun)return;const s=e.state;switch(s.status){case"pending":case"running":{this.sendToolUseOnce(e,s.input);break}case"completed":{this.sendToolUseOnce(e,s.input);break}case"error":{this.sendToolUseOnce(e,s.input),this.callbacks.sendToolResult(this.activeRun.eventId,this.activeRun.sessionId,e.tool,"(failed)");break}}}sendToolUseOnce(e,t){!this.activeRun||this.toolCardsSent.has(e.callID)||(this.flushTextBuffer(),this.toolCardsSent.add(e.callID),this.callbacks.sendToolUse(this.activeRun.eventId,this.activeRun.sessionId,e.tool,H(t??{})))}handlePermission(e){if(!this.activeRun)return;const{eventId:t,sessionId:s,ocSessionId:i}=this.activeRun;if(this.options.permissionPolicy==="fullAuto"){this.transport.respondPermission(i,e.id,"always",this.activeRun.cwd).catch(r=>{n.warn("opencode-adapter",`Auto-approve failed: ${r}`)});return}this.stopIdleTimer(),this.pendingPermissions.set(t,{permissionId:e.id,ocSessionId:i,cwd:this.activeRun.cwd});const o=JSON.stringify(e.metadata??{});this.callbacks.sendToolUse(t,s,e.type,o)}handlePermissionAction(e){if(!this.activeRun)return{handled:!1,kind:""};const t=this.pendingPermissions.get(this.activeRun.eventId);if(!t)return{handled:!1,kind:""};const{permissionId:s,ocSessionId:i,cwd:o}=t,a=e.action_type==="exec_approve"||e.action_type==="permission_approve"?"once":"reject";return this.pendingPermissions.delete(this.activeRun.eventId),this.transport.respondPermission(i,s,a,o).then(()=>{n.info("opencode-adapter",`Permission ${a}: ${s}`),this.resetIdleTimer()}).catch(d=>{n.warn("opencode-adapter",`Permission response failed: ${d}`)}),{handled:!0,kind:"permission"}}startRun(e,t,s=!1){this.activeRun={eventId:e,sessionId:t,ocSessionId:"",cwd:this.getSessionCwd(t),chunkSeq:0,clientMsgId:`oc_${++this.clientMsgSeq}_${Date.now()}`,textBuffer:"",flushTimer:null},this.toolCardsSent.clear(),s&&this.auditCaptures.set(e,[]),this.lastSseAt=Date.now(),this.livenessExtendStartAt=void 0}finishRun(e,t){const s=this.activeRun;if(!s)return;if(this.completedEvents.add(s.eventId),this.completedEvents.size>Q){const a=[...this.completedEvents].slice(-500);this.completedEvents=new Set(a)}this.snapshotAuditBoundary(s),this.activeRun=null,this.toolCallsInFlight.clear(),this.toolCardsSent.clear(),this.livenessExtendStartAt=void 0,this.clearMessageRoleState(),this.stopComposing(),this.stopIdleTimer();const i=++s.chunkSeq,o=s.clientMsgId;e==="failed"&&t&&this.callbacks.sendRunError(s.eventId,s.sessionId,t);const r=()=>{this.callbacks.sendFinalStreamChunkReliable?this.callbacks.sendFinalStreamChunkReliable(s.eventId,s.sessionId,o).then(()=>{this.callbacks.sendEventResult(s.eventId,e,t)}).catch(a=>{const d=e==="responded"?"failed":e,h=e==="responded"?`final output delivery failed: ${a instanceof Error?a.message:String(a)}`:t;this.callbacks.sendEventResult(s.eventId,d,h)}):(this.callbacks.sendStreamChunk(s.eventId,s.sessionId,"",i,!0,o),this.callbacks.sendEventResult(s.eventId,e,t))};if(s.textBuffer){this.stopTextFlush();for(const a of T(s.textBuffer))s.chunkSeq++,this.callbacks.sendStreamChunk(s.eventId,s.sessionId,a,s.chunkSeq,!1,s.clientMsgId);s.textBuffer=""}r(),this.emit("eventDone",s.eventId)}clearRun(){this.activeRun?.flushTimer&&clearTimeout(this.activeRun.flushTimer);const e=this.activeRun?.eventId;this.activeRun&&this.snapshotAuditBoundary(this.activeRun),this.activeRun=null,this.toolCallsInFlight.clear(),this.toolCardsSent.clear(),this.livenessExtendStartAt=void 0,this.clearMessageRoleState(),this.stopIdleTimer(),e&&this.emit("eventDone",e)}snapshotAuditBoundary(e){const t=this.auditCaptures.get(e.eventId);t&&(this.completedAuditBoundaries.set(e.eventId,{adapterType:"opencode",providerSessionId:e.ocSessionId||void 0,openCodeEvidence:{events:t}}),this.auditCaptures.delete(e.eventId))}appendText(e){if(this.activeRun){if(this.activeRun.textBuffer+=e,this.activeRun.textBuffer.length>=z){this.flushTextBuffer();return}this.scheduleTextFlush()}}scheduleTextFlush(){!this.activeRun||this.activeRun.flushTimer||(this.activeRun.flushTimer=setTimeout(()=>{this.activeRun&&(this.activeRun.flushTimer=null),this.flushTextBuffer()},q))}flushTextBuffer(){if(this.stopTextFlush(),!(!this.activeRun||!this.activeRun.textBuffer)){for(const e of T(this.activeRun.textBuffer))this.activeRun.chunkSeq++,this.callbacks.sendStreamChunk(this.activeRun.eventId,this.activeRun.sessionId,e,this.activeRun.chunkSeq,!1,this.activeRun.clientMsgId);this.activeRun.textBuffer=""}}stopTextFlush(){this.activeRun?.flushTimer&&(clearTimeout(this.activeRun.flushTimer),this.activeRun.flushTimer=null)}startComposing(e){}stopComposing(){}shouldExtendByLiveness(){if(!this.activeRun)return!1;const e=this.process?.pid;if(!this.alive||!e||!k(e))return!1;const t=Date.now(),s=this.lastSseAt>0?t-this.lastSseAt:Number.POSITIVE_INFINITY;if(s<W)return this.livenessExtendStartAt=t,n.info("opencode-adapter",`Liveness check: fresh SSE for ${this.activeRun.eventId} (sseAge=${s}ms, toolsInFlight=${this.toolCallsInFlight.size}), extending`),!0;const o=this.livenessExtendStartAt??t;return this.livenessExtendStartAt===void 0&&(this.livenessExtendStartAt=o),t-o>x?(n.warn("opencode-adapter",`Liveness extension budget exhausted for ${this.activeRun.eventId} (no progress for ${Math.round((t-o)/6e4)}min), allowing idle fail`),!1):(n.info("opencode-adapter",`Liveness check: turn in progress for ${this.activeRun.eventId} (toolsInFlight=${this.toolCallsInFlight.size}, sseAge=${Number.isFinite(s)?`${s}ms`:"n/a"}), extending`),!0)}resetIdleTimer(){this.stopIdleTimer(),!(this.stopped||!this.activeRun)&&(this.idleTimer=setTimeout(()=>{if(this.stopped||!this.activeRun)return;if(this.pendingPermissions.has(this.activeRun.eventId)&&this.shouldExtendByLiveness()){n.info("opencode-adapter",`Idle timeout skipped: pendingPermissions for ${this.activeRun.eventId}, resetting timer`),this.resetIdleTimer();return}if(this.shouldExtendByLiveness()){this.resetIdleTimer();return}const e=this.process?.pid,s=!!(this.alive&&e&&k(e))?`liveness budget exhausted after ${x/6e4}min`:"process not alive";n.error("opencode-adapter",`Idle timeout (${s}, toolsInFlight=${this.toolCallsInFlight.size}) \u2014 emitting exit for respawn`),this.flushTextBuffer(),this.activeRun&&(this.callbacks.sendEventResult(this.activeRun.eventId,"failed",`idle timeout: ${s}`),this.clearRun()),this.emit("exit",-1)},V))}stopIdleTimer(){this.idleTimer&&(clearTimeout(this.idleTimer),this.idleTimer=null)}resolveCwd(){const e=this.options.aibotSessionId?this.options.bindingStore?.get(this.options.aibotSessionId)?.cwd:void 0;if(e)return e;const t=(this.config.options??{}).cwd;return typeof t=="string"&&t?t:process.cwd()}getSessionCwd(e){return this.sessions.get(e)?.cwd??this.options.bindingStore?.get(e)?.cwd??this.resolveCwd()}buildPromptText(e){let t=e.text;return e.contextMessages&&e.contextMessages.length>0&&(t=e.contextMessages.map(i=>`[context] ${i.senderId}: ${i.content}`).join(`
|
|
4
4
|
`)+`
|
|
5
5
|
|
|
6
6
|
`+t),this.identity.injectOnce(e.adapterSessionId,t)}buildPromptTextFromEvent(e){let t=e.content||"";if(e.context_messages_json)try{const s=JSON.parse(e.context_messages_json);Array.isArray(s)&&s.length>0&&(t=s.map(o=>`[context] ${o.sender_id??"unknown"}: ${o.content}`).join(`
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{referenceCaptureContent as K}from"../../core/content-reference.js";import{assessToolCallCompleteness as se,deduplicateGaps as oe}from"../../core/tool-call-audit.js";import{InvalidCodexUsageError as z,normalizeCodexUsage as ae}from"../../core/usage.js";import{cleanupRawApiCapture as de,loadRawApiCapture as ue}from"../../raw-capture/body-source.js";import{extractProviderResponseId as ie,extractRequestModel as ce,extractSystemPrompt as pe}from"../../raw-capture/attribution.js";const le=new Set(["rawResponse/completed","codex/rawResponse/completed"]),fe=new Set(["thread/tokenUsage/updated","codex/thread/tokenUsage/updated"]),P=new Set(["item/completed","codex/item/completed"]),H=new Set(["item/started","codex/item/started"]),me=new Set(["rawResponseItem/completed","codex/rawResponseItem/completed"]),Ie=new Set(["error","codex/error"]),ve=new Set(["thread/compacted","codex/thread/compacted"]),V=new Set(["commandExecution","fileChange","mcpToolCall","dynamicToolCall","webSearch","imageView","sleep","imageGeneration"]),G=new Set(["collabAgentToolCall","subAgentActivity"]),he=Object.freeze({inputOutput:!0,tools:!0,subagents:!0,thinking:!0,rawProviderBody:!1});function y(e){if(!(typeof e!="object"||e===null||Array.isArray(e)))return e}function I(e){return typeof e=="string"&&e.length>0?e:void 0}function T(e){return typeof e=="number"&&Number.isFinite(e)?e:void 0}function $(e,t,n){return e[t]??e[n]}function ge(e){return["totalTokens","total_tokens","inputTokens","input_tokens","cachedInputTokens","cached_input_tokens","cacheWriteInputTokens","cache_write_input_tokens","outputTokens","output_tokens","reasoningOutputTokens","reasoning_output_tokens"].some(t=>Object.hasOwn(e,t))}function _e(e){const t=y(e);if(!(!t||!ge(t)))return{total_tokens:$(t,"totalTokens","total_tokens"),input_tokens:$(t,"inputTokens","input_tokens"),cached_input_tokens:$(t,"cachedInputTokens","cached_input_tokens"),cache_write_input_tokens:$(t,"cacheWriteInputTokens","cache_write_input_tokens"),output_tokens:$(t,"outputTokens","output_tokens"),reasoning_output_tokens:$(t,"reasoningOutputTokens","reasoning_output_tokens")}}function J(e){return[e.input.total,e.input.cacheRead??"unknown",e.input.cacheWrite??"unknown",e.output.total,e.output.reasoning??"unknown"].join(":")}function Q(e,t){return e.input.total!==t.input.total||e.output.total!==t.output.total?!1:[[e.input.cacheRead,t.input.cacheRead],[e.input.cacheWrite,t.input.cacheWrite],[e.output.reasoning,t.output.reasoning]].every(([s,o])=>s===null||o===null||s===o)}function R(e){let t=2166136261;for(let n=0;n<e.length;n+=1)t^=e.charCodeAt(n),t=Math.imul(t,16777619);return(t>>>0).toString(16).padStart(8,"0")}function M(e){const t=I(e);if(!(!t||Number.isNaN(Date.parse(t))))return t}function O(e){return e.options?.enabled===!0?e.options.capture:he}function S(e){if(typeof e=="string")return e;try{const t=JSON.stringify(e);return t===void 0?"null":t}catch{return String(e)}}function A(e,t){const n=K(t);return e.push(t),n}function x(e,t){t&&(e.some(n=>n.contentId===t.contentId)||e.push(t))}function Y(e){const t=_e(e);return t?{...ae(t),providerUsageRaw:e}:void 0}function ye(e){return{providerTurnId:I(e.boundary.providerTurnId)??I(e.boundary.turnId)??e.turnId,providerThreadId:I(e.boundary.providerThreadId)??I(e.boundary.threadId)}}function C(e,t){const n=I(e.turnId??e.turn_id);if(n&&n!==t.providerTurnId)return!1;const s=I(e.threadId??e.thread_id);return!(t.providerThreadId&&s&&s!==t.providerThreadId)}function k(e,t,n,s){e.push({code:t,message:n,providerIds:s})}function X(e,t,n){try{const s=Y(e);if(!s){k(n,"codex_usage_missing",`${t.nativeEventType} did not contain a usable usage payload`);return}return{...t,usage:s,providerUsageRaw:e,usageKey:J(s),reconciledWithTokenSnapshot:!1}}catch(s){if(s instanceof z){k(n,"codex_usage_invalid",s.message,t.responseId?{responseId:t.responseId}:void 0);return}throw s}}function L(e){const t=y(e);if(!t)return{events:[]};const n=I(t.modelId);return{...n?{modelId:n}:{},events:Array.isArray(t.events)?t.events.filter(s=>{const o=y(s);return!!(o&&typeof o.method=="string"&&y(o.params))}):[],rolloutEntries:Array.isArray(t.rolloutEntries)?t.rolloutEntries:[],...y(t.rawApiCapture)&&Array.isArray(y(t.rawApiCapture)?.exchanges)?{rawApiCapture:t.rawApiCapture}:{}}}function Z(e){const t=e?.toLowerCase()??"";return t.includes("ndjson")?"text":t.includes("json")?"json":(t.includes("event-stream"),"text")}function we(e){return e.correlation.providerResponseId??(e.upstream.body.value===void 0?void 0:ie(e.upstream.body.value))}function qe(e,t,n,s){const o=t.correlation.providerRequestId,d=e.find(l=>!s.has(l.spanId)&&(n&&(l.provider.nativeIds.responseId===n||l.provider.nativeIds.requestId===n)||o&&(l.provider.nativeIds.requestId===o||l.provider.nativeIds.responseId===o)));if(d)return d;const u=e.filter(l=>!s.has(l.spanId));return u.length===1?u[0]:void 0}function xe(e,t,n,s,o){const d=t.completedAt??t.startedAt;return{spanId:`codex-raw-${R(`${e.traceId}|${t.exchangeId}`)}`,traceId:e.traceId,turnId:e.turnId,sessionId:e.sessionId,parentSpanId:`codex:${e.turnId}:turn`,kind:"llm_request",name:"codex provider request",sequence:n,status:t.status==="cancelled"?"cancelled":t.status==="failed"?"failed":"completed",startedAt:t.startedAt,endedAt:d,durationMs:Math.max(0,Date.parse(d)-Date.parse(t.startedAt)),...s?{modelId:s}:{},inputRefs:[],outputRefs:[],provider:{provider:"codex",nativeEventType:"provider_raw_api_exchange",nativeIds:{requestId:t.correlation.providerRequestId??t.exchangeId,exchangeId:t.exchangeId,...o?{responseId:o}:{}}},provenance:{source:"provider_raw_body",accuracy:"runtime_exact"}}}function Te(e,t,n,s,o){if(!t)return;if(t.status==="unavailable"){k(o,"codex_raw_api_capture_unavailable",t.unavailableReason??"Codex raw API capture is unavailable");return}for(const r of t.errors)k(o,"codex_raw_api_capture_partial",r);const d=n.filter(r=>r.kind==="llm_request"),u=new Set;let l=n.reduce((r,a)=>Math.max(r,a.sequence),0)+1;for(const r of t.exchanges){const a=r.downstream.body.value,i=r.upstream.body.value,c=we(r),g=a?ce(a):void 0,p=qe(d,r,c,u),f=d.filter(q=>!u.has(q.spanId)).length;!p&&f>1&&k(o,"codex_raw_api_correlation_ambiguous",`Raw API exchange ${r.exchangeId} has no stable request identifier`,{exchangeId:r.exchangeId});const v=p??xe(e,r,l++,g,c);n.includes(v)||n.push(v),u.add(v.spanId);const _=a===void 0?void 0:A(s,{role:"model_request",format:Z(r.downstream.body.contentType),value:a,sourcePath:r.downstream.body.sourcePath,captureLevel:"provider_exact"}),w=i===void 0?void 0:A(s,{role:"model_response",format:Z(r.upstream.body.contentType),value:i,sourcePath:r.upstream.body.sourcePath,captureLevel:"provider_exact"}),h=a?pe(a):void 0;h&&A(s,{role:"system_prompt",format:"json",value:h,sourcePath:r.downstream.body.sourcePath,captureLevel:"provider_exact"}),x(v.inputRefs,_),x(v.outputRefs,w),g&&!v.modelId&&(v.modelId=g),v.provider.nativeIds.exchangeId=r.exchangeId,c&&(v.provider.nativeIds.responseId=c),v.provider.rawAttributes={...v.provider.rawAttributes,rawApiExchange:{method:r.downstream.method,path:r.downstream.path,query:r.downstream.query,requestHeaders:r.downstream.redactedHeaders,responseStatus:r.upstream.statusCode,responseHeaders:r.upstream.redactedHeaders,requestSha256:r.downstream.body.sha256,responseSha256:r.upstream.body.sha256,requestBytes:r.downstream.body.bytes,responseBytes:r.upstream.body.bytes}},(!_||!w||r.errors.length>0)&&k(o,"codex_raw_api_capture_partial",`Raw API exchange ${r.exchangeId} is incomplete`,{exchangeId:r.exchangeId})}}function Ae(e,t,n){const s=new Map;let o=0;for(const d of e){if(!le.has(d.method)||!C(d.params,t))continue;const u=I(d.params.turnId??d.params.turn_id)??t.providerTurnId,l=I(d.params.threadId??d.params.thread_id)??t.providerThreadId,r=I(d.params.responseId??d.params.response_id),a=X(d.params.usage,{sequence:T(d.sequence)??o,observedAt:M(d.observedAt),providerTurnId:u,threadId:l,responseId:r,nativeEventType:d.method,source:"provider_raw_body"},n);if(o+=1,!a)continue;const i=r?`response:${r}`:`anonymous:${a.sequence}:${a.usageKey}`,c=s.get(i);if(c&&!Q(c.usage,a.usage)){k(n,"codex_response_usage_conflict",`Response ${r??i} reported conflicting usage`,r?{responseId:r}:void 0);continue}c||s.set(i,a)}return[...s.values()].sort((d,u)=>d.sequence-u.sequence)}function j(e,t,n,s){const o=X(e,n,s);if(!o)return;let d;try{const u=Y(t);u&&(d=[n.threadId??"unknown-thread",n.providerTurnId,J(u)].join("|"))}catch(u){if(u instanceof z)k(s,"codex_total_snapshot_invalid",u.message);else throw u}return{...o,providerUsageRaw:{last:e,total:t},usage:{...o.usage,providerUsageRaw:{last:e,total:t}},snapshotKey:d}}function Se(e,t,n){const s=[];for(const o of e){if(!fe.has(o.method)||!C(o.params,t))continue;const d=y(o.params.tokenUsage??o.params.token_usage);if(!d){k(n,"codex_usage_missing",`${o.method} did not contain tokenUsage`);continue}const u=I(o.params.turnId??o.params.turn_id)??t.providerTurnId,l=I(o.params.threadId??o.params.thread_id)??t.providerThreadId,r=j(d.last??d.last_token_usage,d.total??d.total_token_usage,{sequence:T(o.sequence)??s.length,observedAt:M(o.observedAt),providerTurnId:u,threadId:l,responseId:I(o.params.responseId??o.params.response_id),nativeEventType:o.method,source:"provider_event"},n);r&&s.push(r)}return s}function Re(e,t,n,s){const o=[];return e.forEach((d,u)=>{const l=y(d),r=y(l?.payload);if(l?.type!=="event_msg"||r?.type!=="token_count")return;const a=y(r.info);if(!a)return;const i=j(a.last_token_usage??a.lastTokenUsage,a.total_token_usage??a.totalTokenUsage,{sequence:T(l?.sequence)??n+u,observedAt:M(l?.timestamp),providerTurnId:t.providerTurnId,threadId:t.providerThreadId,nativeEventType:"rollout/event_msg/token_count",source:"provider_transcript"},s);i&&o.push(i)}),o}function Ce(e){const t=new Set;return e.filter(n=>n.snapshotKey?t.has(n.snapshotKey)?!1:(t.add(n.snapshotKey),!0):!0)}function ke(e,t){const n=new Set(e),s=new Set(t);for(const o of t){const d=e.find(u=>!n.has(u)||o.responseId&&u.responseId&&o.responseId!==u.responseId?!1:u.providerTurnId===o.providerTurnId&&Q(u.usage,o.usage));d&&(d.reconciledWithTokenSnapshot=!0,d.snapshotKey=o.snapshotKey,d.threadId??=o.threadId,d.providerUsageRaw={rawResponse:d.providerUsageRaw,tokenUsage:o.providerUsageRaw},d.usage={...d.usage,providerUsageRaw:d.providerUsageRaw},n.delete(d),s.delete(o))}return[...e,...t.filter(o=>s.has(o))].sort((o,d)=>o.sequence-d.sequence)}function Ee(e){if(e.responseId)return e.responseId;const t=e.snapshotKey??[e.threadId??"unknown-thread",e.providerTurnId,e.sequence,e.usageKey].join("|");return`codex-usage-${R(t)}`}function be(e,t,n){const s=Ee(t),o={requestId:s,turnId:t.providerTurnId};t.threadId&&(o.threadId=t.threadId),t.responseId&&(o.responseId=t.responseId),t.snapshotKey&&(o.usageSnapshotId=R(t.snapshotKey));const d=t.observedAt??e.startedAt;return{spanId:`codex-llm-${R(`${e.traceId}|${s}`)}`,traceId:e.traceId,turnId:e.turnId,sessionId:e.sessionId,parentSpanId:`codex:${e.turnId}:turn`,kind:"llm_request",name:"codex response",sequence:t.sequence,status:"completed",startedAt:d,endedAt:d,...n?{modelId:n}:{},inputRefs:[],outputRefs:[],usage:t.usage,provider:{provider:"codex",nativeEventType:t.nativeEventType,nativeIds:o,rawAttributes:{usageSource:t.source,reconciledWithTokenSnapshot:t.reconciledWithTokenSnapshot}},provenance:{source:t.source,accuracy:"provider_reported"}}}function B(e,t){const n=T(e.params.completedAtMs);if(n!==void 0){const s=new Date(n);if(!Number.isNaN(s.getTime()))return s.toISOString()}return M(e.observedAt)??t.endedAt}function N(e,t){const n=T(e.params.startedAtMs);if(n!==void 0){const s=new Date(n);if(!Number.isNaN(s.getTime()))return s.toISOString()}return M(e.observedAt)??t}function ee(e){const t=I(e.status)?.toLowerCase();return t==="inprogress"||t==="in_progress"||t==="running"?"running":t==="failed"||t==="declined"||t==="error"||T(e.exitCode)!==void 0&&T(e.exitCode)!==0?"failed":t==="cancelled"||t==="canceled"?"cancelled":"completed"}function te(e){const t=I(e.type)??"tool";if(t==="mcpToolCall"){const n=I(e.server),s=I(e.tool);return[n,s].filter(Boolean).join("/")||t}return I(e.tool)??t}function ne(e){switch(I(e.type)){case"commandExecution":return typeof e.command=="string"?{format:"text",value:String(e.command)}:void 0;case"fileChange":return Object.hasOwn(e,"changes")?{format:"json",value:S(e.changes)}:void 0;case"mcpToolCall":case"dynamicToolCall":return Object.hasOwn(e,"arguments")?{format:"json",value:S(e.arguments)}:void 0;case"webSearch":return typeof e.query=="string"?{format:"text",value:String(e.query)}:void 0;default:return{format:"json",value:S(e)}}}function $e(e){switch(I(e.type)){case"commandExecution":return typeof e.aggregatedOutput=="string"?{format:"text",value:e.aggregatedOutput}:e.status!==void 0||e.exitCode!==void 0?{format:"json",value:S({status:e.status,exitCode:e.exitCode})}:void 0;case"fileChange":return{format:"json",value:S({status:e.status})};case"mcpToolCall":return Object.hasOwn(e,"result")?{format:"json",value:S(e.result)}:Object.hasOwn(e,"error")?{format:"json",value:S(e.error)}:void 0;case"dynamicToolCall":return Object.hasOwn(e,"contentItems")?{format:"json",value:S(e.contentItems)}:void 0;default:return{format:"json",value:S(e)}}}function Me(e,t,n,s,o){if(!O(e).tools)return[];const d=new Set,u=[],l=new Map;for(const r of t){if(!H.has(r.method)||!C(r.params,n))continue;const a=y(r.params.item),i=I(a?.id);i&&l.set(i,r)}for(const r of t){if(!P.has(r.method)||!C(r.params,n))continue;const a=y(r.params.item),i=I(a?.type);if(!a||!i||!V.has(i))continue;const c=I(a.id)??`sequence-${r.sequence}`;if(d.has(c))continue;d.add(c);const g=B(r,e),p=l.get(c),f=T(a.durationMs),v=Date.parse(g),_=p?N(p,g):f!==void 0&&Number.isFinite(v)?new Date(Math.max(0,v-f)).toISOString():g,w=Date.parse(g)-Date.parse(_),h=Number.isFinite(w)&&w>0?w:f,q=[...s].filter(E=>E.sequence<=r.sequence).sort((E,D)=>D.sequence-E.sequence)[0],m=[...s].filter(E=>E.sequence>r.sequence).sort((E,D)=>E.sequence-D.sequence)[0],b=q??m,U={spanId:`codex-tool-${R(`${e.traceId}|${c}`)}`,traceId:e.traceId,turnId:e.turnId,sessionId:e.sessionId,parentSpanId:b?.spanId??`codex:${e.turnId}:turn`,kind:"tool_call",name:te(a),sequence:r.sequence,status:ee(a),startedAt:_,endedAt:g,...h!==void 0?{durationMs:Math.max(0,h)}:{},inputRefs:[],outputRefs:[],provider:{provider:"codex",nativeEventType:r.method,nativeIds:{toolCallId:c,turnId:n.providerTurnId,...n.providerThreadId?{threadId:n.providerThreadId}:{}},rawAttributes:{itemType:i,auditEventSequence:r.sequence,startEventSequence:p?.sequence,...I(a.cwd)?{cwd:a.cwd}:{},...T(a.exitCode)!==void 0?{exitCode:a.exitCode}:{}}},provenance:{source:"provider_event",accuracy:"provider_reported"}},F=ne(a);F&&x(U.inputRefs,A(o,{role:"tool_arguments",...F,captureLevel:"provider_exact"}));const W=$e(a);W&&x(U.outputRefs,A(o,{role:"tool_result",...W,captureLevel:"provider_exact"})),u.push(U)}for(const[r,a]of l){if(d.has(r))continue;const i=y(a.params.item),c=I(i?.type);if(!i||!c||!V.has(c))continue;const g=N(a,e.startedAt),p=[...s].filter(_=>_.sequence<=a.sequence).sort((_,w)=>w.sequence-_.sequence)[0]??s[0],f={spanId:`codex-tool-${R(`${e.traceId}|${r}`)}`,traceId:e.traceId,turnId:e.turnId,sessionId:e.sessionId,parentSpanId:p?.spanId??`codex:${e.turnId}:turn`,kind:"tool_call",name:te(i),sequence:a.sequence,status:"running",startedAt:g,endedAt:e.endedAt,durationMs:Math.max(0,Date.parse(e.endedAt)-Date.parse(g)),inputRefs:[],outputRefs:[],provider:{provider:"codex",nativeEventType:a.method,nativeIds:{toolCallId:r,turnId:n.providerTurnId,...n.providerThreadId?{threadId:n.providerThreadId}:{}},rawAttributes:{itemType:c,auditEventSequence:a.sequence,hasCompletion:!1}},provenance:{source:"provider_event",accuracy:"provider_reported"}},v=ne(i);v&&x(f.inputRefs,A(o,{role:"tool_arguments",...v,captureLevel:"provider_exact"})),u.push(f)}return u}function Oe(e,t,n,s,o){if(!O(e).subagents)return[];const d=[],u=new Set,l=new Map;for(const r of t){if(!H.has(r.method)||!C(r.params,n))continue;const a=y(r.params.item),i=I(a?.id);i&&l.set(i,r)}for(const r of t){if(!P.has(r.method)||!C(r.params,n))continue;const a=y(r.params.item),i=I(a?.type);if(!a||!i||!G.has(i))continue;const c=I(a.id)??`sequence-${r.sequence}`;if(u.has(c))continue;u.add(c);const g=[...s].filter(m=>m.sequence<=r.sequence).sort((m,b)=>b.sequence-m.sequence)[0],p=B(r,e),f=l.get(c),v=f?N(f,p):p,_=Date.parse(p)-Date.parse(v),w={spanId:`codex-subagent-${R(`${e.traceId}|${c}`)}`,traceId:e.traceId,turnId:e.turnId,sessionId:e.sessionId,parentSpanId:g?.spanId??`codex:${e.turnId}:turn`,kind:"subagent",name:I(a.tool)??i,sequence:r.sequence,status:ee(a),startedAt:v,endedAt:p,...Number.isFinite(_)?{durationMs:Math.max(0,_)}:{},inputRefs:[],outputRefs:[],provider:{provider:"codex",nativeEventType:r.method,nativeIds:{subagentCallId:c,turnId:n.providerTurnId,...n.providerThreadId?{threadId:n.providerThreadId}:{},...I(a.senderThreadId)?{senderThreadId:String(a.senderThreadId)}:{}},rawAttributes:{itemType:i,auditEventSequence:r.sequence,startEventSequence:f?.sequence,receiverThreadIds:a.receiverThreadIds,agentsStates:a.agentsStates,model:a.model,reasoningEffort:a.reasoningEffort}},provenance:{source:"provider_event",accuracy:"provider_reported"}},h=I(a.prompt);h&&x(w.inputRefs,A(o,{role:"subagent_prompt",format:"text",value:h,captureLevel:"provider_exact"}));const q=a.result??a.agentsStates??a.status;q!==void 0&&x(w.outputRefs,A(o,{role:"subagent_result",format:typeof q=="string"?"text":"json",value:S(q),captureLevel:"provider_exact"})),d.push(w)}for(const[r,a]of l){if(u.has(r))continue;const i=y(a.params.item),c=I(i?.type);if(!i||!c||!G.has(c))continue;const g=N(a,e.startedAt),p=[...s].filter(_=>_.sequence<=a.sequence).sort((_,w)=>w.sequence-_.sequence)[0]??s[0],f={spanId:`codex-subagent-${R(`${e.traceId}|${r}`)}`,traceId:e.traceId,turnId:e.turnId,sessionId:e.sessionId,parentSpanId:p?.spanId??`codex:${e.turnId}:turn`,kind:"subagent",name:I(i.tool)??c,sequence:a.sequence,status:"running",startedAt:g,endedAt:e.endedAt,durationMs:Math.max(0,Date.parse(e.endedAt)-Date.parse(g)),inputRefs:[],outputRefs:[],provider:{provider:"codex",nativeEventType:a.method,nativeIds:{subagentCallId:r,turnId:n.providerTurnId,...n.providerThreadId?{threadId:n.providerThreadId}:{},...I(i.senderThreadId)?{senderThreadId:String(i.senderThreadId)}:{}},rawAttributes:{itemType:c,auditEventSequence:a.sequence,hasCompletion:!1,receiverThreadIds:i.receiverThreadIds,model:i.model,reasoningEffort:i.reasoningEffort}},provenance:{source:"provider_event",accuracy:"provider_reported"}},v=I(i.prompt);v&&x(f.inputRefs,A(o,{role:"subagent_prompt",format:"text",value:v,captureLevel:"provider_exact"})),d.push(f)}return d}function Pe(e,t,n,s,o){const d=[];for(const u of t){if(!C(u.params,n))continue;if(Ie.has(u.method)&&u.params.willRetry===!0){const i=M(u.observedAt)??e.endedAt,c=y(u.params.error);d.push({spanId:`codex-retry-${R(`${e.traceId}|${u.sequence}`)}`,traceId:e.traceId,turnId:e.turnId,sessionId:e.sessionId,parentSpanId:`codex:${e.turnId}:turn`,kind:"retry",name:I(c?.message)??"Codex request retry",sequence:u.sequence,status:"completed",startedAt:i,endedAt:i,durationMs:0,inputRefs:[],outputRefs:[],provider:{provider:"codex",nativeEventType:u.method,nativeIds:{turnId:n.providerTurnId,...n.providerThreadId?{threadId:n.providerThreadId}:{}},rawAttributes:{error:u.params.error,willRetry:!0}},provenance:{source:"provider_event",accuracy:"provider_reported"}});continue}const l=y(u.params.item),r=P.has(u.method)&&l?.type==="contextCompaction";if(!ve.has(u.method)&&!r)continue;const a=B(u,e);d.push({spanId:`codex-compaction-${R(`${e.traceId}|${u.sequence}`)}`,traceId:e.traceId,turnId:e.turnId,sessionId:e.sessionId,parentSpanId:`codex:${e.turnId}:turn`,kind:"compaction",name:"Codex context compaction",sequence:u.sequence,status:"completed",startedAt:a,endedAt:a,durationMs:0,inputRefs:[],outputRefs:[],provider:{provider:"codex",nativeEventType:u.method,nativeIds:{turnId:n.providerTurnId,...n.providerThreadId?{threadId:n.providerThreadId}:{},...I(l?.id)?{itemId:String(l?.id)}:{}},rawAttributes:l?{item:l}:{params:u.params}},provenance:{source:"provider_event",accuracy:"provider_reported"}})}if(O(e).rawProviderBody)for(const u of t){if(!me.has(u.method)||!C(u.params,n))continue;const l=A(o,{role:"model_response",format:"json",value:S(u.params.item),captureLevel:"provider_exact"}),r=[...s].filter(a=>a.sequence>=u.sequence).sort((a,i)=>a.sequence-i.sequence)[0]??s.at(-1);r&&x(r.outputRefs,l)}return d}function re(e){return typeof e.text=="string"&&e.text.length>0?e.text:Array.isArray(e.content)&&e.content.map(n=>{if(typeof n=="string")return n;const s=y(n);return I(s?.text)??""}).join("")||void 0}function Ne(e,t,n,s,o,d){const u=[...s].sort((p,f)=>p.sequence-f.sequence),l=t.filter(p=>P.has(p.method)&&C(p.params,n)&&y(p.params.item)).sort((p,f)=>p.sequence-f.sequence),r=O(e);let a=Number.NEGATIVE_INFINITY,i=1;const c=new Set;for(const[p,f]of u.entries()){const v=f.sequence,_=l.filter(h=>h.sequence>a&&h.sequence<=v);if(r.inputOutput)for(const h of _){const q=y(h.params.item),m=I(q.type);if(m!=="userMessage"&&m!=="agentMessage")continue;const b=re(q);b&&x(m==="userMessage"?f.inputRefs:f.outputRefs,A(d,{role:m==="userMessage"?"user_input":"assistant_text",format:"text",value:b,captureLevel:"provider_exact"}))}if(r.thinking)for(const h of _){const q=y(h.params.item);if(q.type!=="reasoning")continue;const m=re(q);m&&x(f.outputRefs,A(d,{role:"thinking",format:"text",value:m,captureLevel:"provider_exact"}))}r.inputOutput&&p===0&&f.inputRefs.length===0&&e.input&&x(f.inputRefs,K(e.input)),r.inputOutput&&p===u.length-1&&f.outputRefs.length===0&&e.finalOutput&&x(f.outputRefs,K(e.finalOutput)),f.sequence=i++;const w=o.filter(h=>{const q=T(h.provider.rawAttributes?.auditEventSequence);return q!==void 0&&q>a&&q<=v}).sort((h,q)=>T(h.provider.rawAttributes?.auditEventSequence)-T(q.provider.rawAttributes?.auditEventSequence));for(const h of w)h.sequence=i++,c.add(h.spanId);a=v}const g=o.filter(p=>!c.has(p.spanId)).sort((p,f)=>p.sequence-f.sequence);for(const p of g)p.sequence=i++;for(const p of o){if(p.outputRefs.length===0)continue;const f=u.findIndex(_=>_.spanId===p.parentSpanId),v=f>=0?u[f+1]:void 0;if(v)for(const _ of p.outputRefs)x(v.inputRefs,_)}}class Fe{provider="codex";async collect(t){const n=L(t.boundary.codexEvidence),s=y(t.boundary.codexEvidence);return s?.rawApiCapture!==void 0&&(n.rawApiCapture=await ue(s.rawApiCapture)),n}async normalize(t,n){const s=L(n),o=ye(t),d=[],u=Ae(s.events,o,d),l=Se(s.events,o,d),r=Re(s.rolloutEntries??[],o,s.events.length+1,d),a=Ce([...l,...r]),c=ke(u,a).map(_=>be(t,_,s.modelId)),g=[],p=Me(t,s.events,o,c,g),f=Oe(t,s.events,o,c,g),v=Pe(t,s.events,o,c,g);return Ne(t,s.events,o,c,p,g),Te(t,s.rawApiCapture,c,g,d),{spans:[...c,...p,...f,...v],contents:g,anomalies:d}}async correlate(t,n){return n}validate(t,n){const s=n.spans.filter(m=>m.kind==="llm_request"&&m.usage),o=n.anomalies.some(m=>m.code==="codex_usage_invalid"||m.code==="codex_total_snapshot_invalid"||m.code==="codex_response_usage_conflict"),d=s.length>0&&!o&&s.every(m=>m.usage?.completeness==="complete"),u=O(t),l=!u.inputOutput||!!t.input,r=n.contents.some(m=>m.role==="assistant_text"||m.role==="model_response"||m.role==="final_response"),a=!u.inputOutput||!!t.finalOutput||r,i=se(n.spans,u.tools),c=i.complete,g=n.spans.filter(m=>m.kind==="subagent"),p=!u.subagents||g.every(m=>m.status!=="running"),f=n.contents.filter(m=>m.role==="model_request"&&m.value!==void 0).length,v=n.contents.filter(m=>m.role==="model_response"&&m.value!==void 0).length,_=n.anomalies.some(m=>m.code==="codex_raw_api_capture_unavailable"||m.code==="codex_raw_api_capture_partial"||m.code==="codex_raw_api_correlation_ambiguous"),w=!u.rawProviderBody||f>0&&v>=f&&!_,h=[];return s.length===0&&h.push({category:"usage",reason:"provider_usage_missing",detail:"No Codex leaf request usage was found for the provider turn"}),s.length>0&&!d&&h.push({category:"provider_usage_cache_partition",reason:"provider_usage_missing",detail:"Codex reported request totals, but one or more cache or reasoning partitions were absent"}),u.subagents&&!p&&h.push({category:"subagents",reason:"correlation_failed",detail:"One or more Codex collaboration items did not reach a terminal state"}),u.rawProviderBody&&(f===0?h.push({category:"raw_provider_body",reason:"raw_capture_disabled",detail:"Codex raw API capture did not produce a request body"}):w||h.push({category:"raw_provider_body",reason:"correlation_failed",detail:"One or more Codex raw API exchanges are incomplete"})),h.push(...i.gaps),{status:d&&l&&a&&c&&p&&w?"complete":"partial",inputComplete:l,outputComplete:a,toolCallsComplete:c,subagentsComplete:p,usageComplete:d,rawRequestsComplete:w,gaps:oe(h)}}async cleanup(t,n){const s=L(n).rawApiCapture;s&&await de(s)}}export{Fe as CodexAuditAdapter};
|
|
1
|
+
import{referenceCaptureContent as K}from"../../core/content-reference.js";import{assessToolCallCompleteness as oe,deduplicateGaps as ae}from"../../core/tool-call-audit.js";import{InvalidCodexUsageError as z,normalizeCodexUsage as de}from"../../core/usage.js";import{cleanupRawApiCapture as ue,loadRawApiCapture as ie}from"../../raw-capture/body-source.js";import{extractProviderResponseId as ce,extractRequestModel as pe,extractSystemPrompt as le}from"../../raw-capture/attribution.js";const fe=new Set(["rawResponse/completed","codex/rawResponse/completed"]),me=new Set(["thread/tokenUsage/updated","codex/thread/tokenUsage/updated"]),P=new Set(["item/completed","codex/item/completed"]),H=new Set(["item/started","codex/item/started"]),he=new Set(["rawResponseItem/completed","codex/rawResponseItem/completed"]),Ie=new Set(["error","codex/error"]),ve=new Set(["thread/compacted","codex/thread/compacted"]),V=new Set(["commandExecution","fileChange","mcpToolCall","dynamicToolCall","webSearch","imageView","sleep","imageGeneration"]),G=new Set(["collabAgentToolCall","subAgentActivity"]),ge=Object.freeze({inputOutput:!0,tools:!0,subagents:!0,thinking:!0,rawProviderBody:!1});function y(e){if(!(typeof e!="object"||e===null||Array.isArray(e)))return e}function I(e){return typeof e=="string"&&e.length>0?e:void 0}function T(e){return typeof e=="number"&&Number.isFinite(e)?e:void 0}function $(e,t,n){return e[t]??e[n]}function _e(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 ye(e){const t=y(e);if(!(!t||!_e(t)))return{total_tokens:$(t,"totalTokens","total_tokens"),input_tokens:$(t,"inputTokens","input_tokens"),cached_input_tokens:$(t,"cachedInputTokens","cached_input_tokens"),cache_write_input_tokens:$(t,"cacheWriteInputTokens","cache_write_input_tokens"),output_tokens:$(t,"outputTokens","output_tokens"),reasoning_output_tokens:$(t,"reasoningOutputTokens","reasoning_output_tokens")}}function J(e){return[e.input.total,e.input.cacheRead??"unknown",e.input.cacheWrite??"unknown",e.output.total,e.output.reasoning??"unknown"].join(":")}function Q(e,t){return e.input.total!==t.input.total||e.output.total!==t.output.total?!1:[[e.input.cacheRead,t.input.cacheRead],[e.input.cacheWrite,t.input.cacheWrite],[e.output.reasoning,t.output.reasoning]].every(([r,s])=>r===null||s===null||r===s)}function R(e){let t=2166136261;for(let n=0;n<e.length;n+=1)t^=e.charCodeAt(n),t=Math.imul(t,16777619);return(t>>>0).toString(16).padStart(8,"0")}function M(e){const t=I(e);if(!(!t||Number.isNaN(Date.parse(t))))return t}function O(e){return e.options?.enabled===!0?e.options.capture:ge}function S(e){if(typeof e=="string")return e;try{const t=JSON.stringify(e);return t===void 0?"null":t}catch{return String(e)}}function A(e,t){const n=K(t);return e.push(t),n}function x(e,t){t&&(e.some(n=>n.contentId===t.contentId)||e.push(t))}function Y(e){const t=ye(e);return t?{...de(t),providerUsageRaw:e}:void 0}function we(e){return{providerTurnId:I(e.boundary.providerTurnId)??I(e.boundary.turnId)??e.turnId,providerThreadId:I(e.boundary.providerThreadId)??I(e.boundary.threadId)}}function E(e,t){const n=I(e.turnId??e.turn_id);if(n&&n!==t.providerTurnId)return!1;const r=I(e.threadId??e.thread_id);return!(t.providerThreadId&&r&&r!==t.providerThreadId)}function C(e,t,n,r){e.push({code:t,message:n,providerIds:r})}function X(e,t,n){try{const r=Y(e);if(!r){C(n,"codex_usage_missing",`${t.nativeEventType} did not contain a usable usage payload`);return}return{...t,usage:r,providerUsageRaw:e,usageKey:J(r),reconciledWithTokenSnapshot:!1}}catch(r){if(r instanceof z){C(n,"codex_usage_invalid",r.message,t.responseId?{responseId:t.responseId}:void 0);return}throw r}}function L(e){const t=y(e);if(!t)return{events:[]};const n=I(t.modelId);return{...n?{modelId:n}:{},events:Array.isArray(t.events)?t.events.filter(r=>{const s=y(r);return!!(s&&typeof s.method=="string"&&y(s.params))}):[],rolloutEntries:Array.isArray(t.rolloutEntries)?t.rolloutEntries:[],...y(t.rawApiCapture)&&Array.isArray(y(t.rawApiCapture)?.exchanges)?{rawApiCapture:t.rawApiCapture}:{}}}function Z(e){const t=e?.toLowerCase()??"";return t.includes("ndjson")?"text":t.includes("json")?"json":(t.includes("event-stream"),"text")}function j(e){return e.correlation.providerResponseId??(e.upstream.body.value===void 0?void 0:ce(e.upstream.body.value))}function qe(e){const t=e.downstream.method.toUpperCase();if(t!=="POST"&&t!=="WEBSOCKET")return!1;const n=e.downstream.path.toLowerCase().replace(/\/+$/,"");return n.endsWith("/responses")||n.endsWith("/responses/compact")||n.endsWith("/chat/completions")||n.endsWith("/completions")}function xe(e,t,n,r){const s=t.correlation.providerRequestId;return e.find(a=>!r.has(a.spanId)&&(n&&(a.provider.nativeIds.responseId===n||a.provider.nativeIds.requestId===n)||s&&(a.provider.nativeIds.requestId===s||a.provider.nativeIds.responseId===s)))}function Te(e,t){const n=new Map,r=new Set;for(const p of t){const d=xe(e,p,j(p),r);d&&(n.set(p.exchangeId,d),r.add(d.spanId))}const s=t.filter(p=>!n.has(p.exchangeId)),u=e.filter(p=>!r.has(p.spanId));if(s.length!==u.length)return n;s.sort((p,d)=>Date.parse(p.startedAt)-Date.parse(d.startedAt)),u.sort((p,d)=>p.sequence-d.sequence);const a=s.every((p,d)=>{const o=Date.parse(p.completedAt??p.startedAt),c=Date.parse(u[d].startedAt);return Number.isFinite(o)&&Number.isFinite(c)&&o<=c});return s.length>1&&!a||s.forEach((p,d)=>{n.set(p.exchangeId,u[d])}),n}function Ae(e,t,n,r,s){const u=t.completedAt??t.startedAt;return{spanId:`codex-raw-${R(`${e.traceId}|${t.exchangeId}`)}`,traceId:e.traceId,turnId:e.turnId,sessionId:e.sessionId,parentSpanId:`codex:${e.turnId}:turn`,kind:"llm_request",name:"codex provider request",sequence:n,status:t.status==="cancelled"?"cancelled":t.status==="failed"?"failed":"completed",startedAt:t.startedAt,endedAt:u,durationMs:Math.max(0,Date.parse(u)-Date.parse(t.startedAt)),...r?{modelId:r}:{},inputRefs:[],outputRefs:[],provider:{provider:"codex",nativeEventType:"provider_raw_api_exchange",nativeIds:{requestId:t.correlation.providerRequestId??t.exchangeId,exchangeId:t.exchangeId,...s?{responseId:s}:{}}},provenance:{source:"provider_raw_body",accuracy:"runtime_exact"}}}function Se(e,t,n,r,s){if(!t)return;if(t.status==="unavailable"){C(s,"codex_raw_api_capture_unavailable",t.unavailableReason??"Codex raw API capture is unavailable");return}for(const i of t.errors)C(s,"codex_raw_api_capture_partial",i);const u=n.filter(i=>i.kind==="llm_request"),a=t.exchanges.filter(qe),p=Te(u,a),d=new Set([...p.values()].map(i=>i.spanId)),o=u.filter(i=>!d.has(i.spanId)).length,c=a.filter(i=>!p.has(i.exchangeId)).length;a.length>0&&o!==c&&C(s,"codex_raw_api_capture_partial",`Codex raw API exchanges and leaf usage requests do not align (${c} exchange(s), ${o} request(s) unmatched)`);let m=n.reduce((i,l)=>Math.max(i,l.sequence),0)+1;for(const i of a){const l=i.downstream.body.value,h=i.upstream.body.value,_=j(i),g=l?pe(l):void 0,q=p.get(i.exchangeId);!q&&o>0&&c>0&&C(s,"codex_raw_api_correlation_ambiguous",`Raw API exchange ${i.exchangeId} has no stable request identifier`,{exchangeId:i.exchangeId});const v=q??Ae(e,i,m++,g,_);n.includes(v)||n.push(v);const w=l===void 0?void 0:A(r,{role:"model_request",format:Z(i.downstream.body.contentType),value:l,sourcePath:i.downstream.body.sourcePath,captureLevel:"provider_exact"}),f=h===void 0?void 0:A(r,{role:"model_response",format:Z(i.upstream.body.contentType),value:h,sourcePath:i.upstream.body.sourcePath,captureLevel:"provider_exact"}),k=l?le(l):void 0;k&&A(r,{role:"system_prompt",format:"json",value:k,sourcePath:i.downstream.body.sourcePath,captureLevel:"provider_exact"}),x(v.inputRefs,w),x(v.outputRefs,f),g&&!v.modelId&&(v.modelId=g),v.provider.nativeIds.exchangeId=i.exchangeId,_&&(v.provider.nativeIds.responseId=_),v.provider.rawAttributes={...v.provider.rawAttributes,rawApiExchange:{method:i.downstream.method,path:i.downstream.path,query:i.downstream.query,requestHeaders:i.downstream.redactedHeaders,responseStatus:i.upstream.statusCode,responseHeaders:i.upstream.redactedHeaders,requestSha256:i.downstream.body.sha256,responseSha256:i.upstream.body.sha256,requestBytes:i.downstream.body.bytes,responseBytes:i.upstream.body.bytes}},(!w||!f||i.errors.length>0)&&C(s,"codex_raw_api_capture_partial",`Raw API exchange ${i.exchangeId} is incomplete`,{exchangeId:i.exchangeId})}}function Re(e,t,n){const r=new Map;let s=0;for(const u of e){if(!fe.has(u.method)||!E(u.params,t))continue;const a=I(u.params.turnId??u.params.turn_id)??t.providerTurnId,p=I(u.params.threadId??u.params.thread_id)??t.providerThreadId,d=I(u.params.responseId??u.params.response_id),o=X(u.params.usage,{sequence:T(u.sequence)??s,observedAt:M(u.observedAt),providerTurnId:a,threadId:p,responseId:d,nativeEventType:u.method,source:"provider_raw_body"},n);if(s+=1,!o)continue;const c=d?`response:${d}`:`anonymous:${o.sequence}:${o.usageKey}`,m=r.get(c);if(m&&!Q(m.usage,o.usage)){C(n,"codex_response_usage_conflict",`Response ${d??c} reported conflicting usage`,d?{responseId:d}:void 0);continue}m||r.set(c,o)}return[...r.values()].sort((u,a)=>u.sequence-a.sequence)}function ee(e,t,n,r){const s=X(e,n,r);if(!s)return;let u;try{const a=Y(t);a&&(u=[n.threadId??"unknown-thread",n.providerTurnId,J(a)].join("|"))}catch(a){if(a instanceof z)C(r,"codex_total_snapshot_invalid",a.message);else throw a}return{...s,providerUsageRaw:{last:e,total:t},usage:{...s.usage,providerUsageRaw:{last:e,total:t}},snapshotKey:u}}function Ce(e,t,n){const r=[];for(const s of e){if(!me.has(s.method)||!E(s.params,t))continue;const u=y(s.params.tokenUsage??s.params.token_usage);if(!u){C(n,"codex_usage_missing",`${s.method} did not contain tokenUsage`);continue}const a=I(s.params.turnId??s.params.turn_id)??t.providerTurnId,p=I(s.params.threadId??s.params.thread_id)??t.providerThreadId,d=ee(u.last??u.last_token_usage,u.total??u.total_token_usage,{sequence:T(s.sequence)??r.length,observedAt:M(s.observedAt),providerTurnId:a,threadId:p,responseId:I(s.params.responseId??s.params.response_id),nativeEventType:s.method,source:"provider_event"},n);d&&r.push(d)}return r}function ke(e,t,n,r){const s=[];return e.forEach((u,a)=>{const p=y(u),d=y(p?.payload);if(p?.type!=="event_msg"||d?.type!=="token_count")return;const o=y(d.info);if(!o)return;const c=ee(o.last_token_usage??o.lastTokenUsage,o.total_token_usage??o.totalTokenUsage,{sequence:T(p?.sequence)??n+a,observedAt:M(p?.timestamp),providerTurnId:t.providerTurnId,threadId:t.providerThreadId,nativeEventType:"rollout/event_msg/token_count",source:"provider_transcript"},r);c&&s.push(c)}),s}function Ee(e){const t=new Set;return e.filter(n=>n.snapshotKey?t.has(n.snapshotKey)?!1:(t.add(n.snapshotKey),!0):!0)}function be(e,t){const n=new Set(e),r=new Set(t);for(const s of t){const u=e.find(a=>!n.has(a)||s.responseId&&a.responseId&&s.responseId!==a.responseId?!1:a.providerTurnId===s.providerTurnId&&Q(a.usage,s.usage));u&&(u.reconciledWithTokenSnapshot=!0,u.snapshotKey=s.snapshotKey,u.threadId??=s.threadId,u.providerUsageRaw={rawResponse:u.providerUsageRaw,tokenUsage:s.providerUsageRaw},u.usage={...u.usage,providerUsageRaw:u.providerUsageRaw},n.delete(u),r.delete(s))}return[...e,...t.filter(s=>r.has(s))].sort((s,u)=>s.sequence-u.sequence)}function $e(e){if(e.responseId)return e.responseId;const t=e.snapshotKey??[e.threadId??"unknown-thread",e.providerTurnId,e.sequence,e.usageKey].join("|");return`codex-usage-${R(t)}`}function Me(e,t,n){const r=$e(t),s={requestId:r,turnId:t.providerTurnId};t.threadId&&(s.threadId=t.threadId),t.responseId&&(s.responseId=t.responseId),t.snapshotKey&&(s.usageSnapshotId=R(t.snapshotKey));const u=t.observedAt??e.startedAt;return{spanId:`codex-llm-${R(`${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:s,rawAttributes:{usageSource:t.source,reconciledWithTokenSnapshot:t.reconciledWithTokenSnapshot}},provenance:{source:t.source,accuracy:"provider_reported"}}}function W(e,t){const n=T(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=T(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 te(e){const t=I(e.status)?.toLowerCase();return t==="inprogress"||t==="in_progress"||t==="running"?"running":t==="failed"||t==="declined"||t==="error"||T(e.exitCode)!==void 0&&T(e.exitCode)!==0?"failed":t==="cancelled"||t==="canceled"?"cancelled":"completed"}function ne(e){const t=I(e.type)??"tool";if(t==="mcpToolCall"){const n=I(e.server),r=I(e.tool);return[n,r].filter(Boolean).join("/")||t}return I(e.tool)??t}function re(e){switch(I(e.type)){case"commandExecution":return typeof e.command=="string"?{format:"text",value:String(e.command)}:void 0;case"fileChange":return Object.hasOwn(e,"changes")?{format:"json",value:S(e.changes)}:void 0;case"mcpToolCall":case"dynamicToolCall":return Object.hasOwn(e,"arguments")?{format:"json",value:S(e.arguments)}:void 0;case"webSearch":return typeof e.query=="string"?{format:"text",value:String(e.query)}:void 0;default:return{format:"json",value:S(e)}}}function Oe(e){switch(I(e.type)){case"commandExecution":return typeof e.aggregatedOutput=="string"?{format:"text",value:e.aggregatedOutput}:e.status!==void 0||e.exitCode!==void 0?{format:"json",value:S({status:e.status,exitCode:e.exitCode})}:void 0;case"fileChange":return{format:"json",value:S({status:e.status})};case"mcpToolCall":return Object.hasOwn(e,"result")?{format:"json",value:S(e.result)}:Object.hasOwn(e,"error")?{format:"json",value:S(e.error)}:void 0;case"dynamicToolCall":return Object.hasOwn(e,"contentItems")?{format:"json",value:S(e.contentItems)}:void 0;default:return{format:"json",value:S(e)}}}function Pe(e,t,n,r,s){if(!O(e).tools)return[];const u=new Set,a=[],p=new Map;for(const d of t){if(!H.has(d.method)||!E(d.params,n))continue;const o=y(d.params.item),c=I(o?.id);c&&p.set(c,d)}for(const d of t){if(!P.has(d.method)||!E(d.params,n))continue;const o=y(d.params.item),c=I(o?.type);if(!o||!c||!V.has(c))continue;const m=I(o.id)??`sequence-${d.sequence}`;if(u.has(m))continue;u.add(m);const i=W(d,e),l=p.get(m),h=T(o.durationMs),_=Date.parse(i),g=l?D(l,i):h!==void 0&&Number.isFinite(_)?new Date(Math.max(0,_-h)).toISOString():i,q=Date.parse(i)-Date.parse(g),v=Number.isFinite(q)&&q>0?q:h,w=[...r].filter(b=>b.sequence<=d.sequence).sort((b,U)=>U.sequence-b.sequence)[0],f=[...r].filter(b=>b.sequence>d.sequence).sort((b,U)=>b.sequence-U.sequence)[0],k=w??f,N={spanId:`codex-tool-${R(`${e.traceId}|${m}`)}`,traceId:e.traceId,turnId:e.turnId,sessionId:e.sessionId,parentSpanId:k?.spanId??`codex:${e.turnId}:turn`,kind:"tool_call",name:ne(o),sequence:d.sequence,status:te(o),startedAt:g,endedAt:i,...v!==void 0?{durationMs:Math.max(0,v)}:{},inputRefs:[],outputRefs:[],provider:{provider:"codex",nativeEventType:d.method,nativeIds:{toolCallId:m,turnId:n.providerTurnId,...n.providerThreadId?{threadId:n.providerThreadId}:{}},rawAttributes:{itemType:c,auditEventSequence:d.sequence,startEventSequence:l?.sequence,...I(o.cwd)?{cwd:o.cwd}:{},...T(o.exitCode)!==void 0?{exitCode:o.exitCode}:{}}},provenance:{source:"provider_event",accuracy:"provider_reported"}},B=re(o);B&&x(N.inputRefs,A(s,{role:"tool_arguments",...B,captureLevel:"provider_exact"}));const F=Oe(o);F&&x(N.outputRefs,A(s,{role:"tool_result",...F,captureLevel:"provider_exact"})),a.push(N)}for(const[d,o]of p){if(u.has(d))continue;const c=y(o.params.item),m=I(c?.type);if(!c||!m||!V.has(m))continue;const i=D(o,e.startedAt),l=[...r].filter(g=>g.sequence<=o.sequence).sort((g,q)=>q.sequence-g.sequence)[0]??r[0],h={spanId:`codex-tool-${R(`${e.traceId}|${d}`)}`,traceId:e.traceId,turnId:e.turnId,sessionId:e.sessionId,parentSpanId:l?.spanId??`codex:${e.turnId}:turn`,kind:"tool_call",name:ne(c),sequence:o.sequence,status:"running",startedAt:i,endedAt:e.endedAt,durationMs:Math.max(0,Date.parse(e.endedAt)-Date.parse(i)),inputRefs:[],outputRefs:[],provider:{provider:"codex",nativeEventType:o.method,nativeIds:{toolCallId:d,turnId:n.providerTurnId,...n.providerThreadId?{threadId:n.providerThreadId}:{}},rawAttributes:{itemType:m,auditEventSequence:o.sequence,hasCompletion:!1}},provenance:{source:"provider_event",accuracy:"provider_reported"}},_=re(c);_&&x(h.inputRefs,A(s,{role:"tool_arguments",..._,captureLevel:"provider_exact"})),a.push(h)}return a}function De(e,t,n,r,s){if(!O(e).subagents)return[];const u=[],a=new Set,p=new Map;for(const d of t){if(!H.has(d.method)||!E(d.params,n))continue;const o=y(d.params.item),c=I(o?.id);c&&p.set(c,d)}for(const d of t){if(!P.has(d.method)||!E(d.params,n))continue;const o=y(d.params.item),c=I(o?.type);if(!o||!c||!G.has(c))continue;const m=I(o.id)??`sequence-${d.sequence}`;if(a.has(m))continue;a.add(m);const i=[...r].filter(f=>f.sequence<=d.sequence).sort((f,k)=>k.sequence-f.sequence)[0],l=W(d,e),h=p.get(m),_=h?D(h,l):l,g=Date.parse(l)-Date.parse(_),q={spanId:`codex-subagent-${R(`${e.traceId}|${m}`)}`,traceId:e.traceId,turnId:e.turnId,sessionId:e.sessionId,parentSpanId:i?.spanId??`codex:${e.turnId}:turn`,kind:"subagent",name:I(o.tool)??c,sequence:d.sequence,status:te(o),startedAt:_,endedAt:l,...Number.isFinite(g)?{durationMs:Math.max(0,g)}:{},inputRefs:[],outputRefs:[],provider:{provider:"codex",nativeEventType:d.method,nativeIds:{subagentCallId:m,turnId:n.providerTurnId,...n.providerThreadId?{threadId:n.providerThreadId}:{},...I(o.senderThreadId)?{senderThreadId:String(o.senderThreadId)}:{}},rawAttributes:{itemType:c,auditEventSequence:d.sequence,startEventSequence:h?.sequence,receiverThreadIds:o.receiverThreadIds,agentsStates:o.agentsStates,model:o.model,reasoningEffort:o.reasoningEffort}},provenance:{source:"provider_event",accuracy:"provider_reported"}},v=I(o.prompt);v&&x(q.inputRefs,A(s,{role:"subagent_prompt",format:"text",value:v,captureLevel:"provider_exact"}));const w=o.result??o.agentsStates??o.status;w!==void 0&&x(q.outputRefs,A(s,{role:"subagent_result",format:typeof w=="string"?"text":"json",value:S(w),captureLevel:"provider_exact"})),u.push(q)}for(const[d,o]of p){if(a.has(d))continue;const c=y(o.params.item),m=I(c?.type);if(!c||!m||!G.has(m))continue;const i=D(o,e.startedAt),l=[...r].filter(g=>g.sequence<=o.sequence).sort((g,q)=>q.sequence-g.sequence)[0]??r[0],h={spanId:`codex-subagent-${R(`${e.traceId}|${d}`)}`,traceId:e.traceId,turnId:e.turnId,sessionId:e.sessionId,parentSpanId:l?.spanId??`codex:${e.turnId}:turn`,kind:"subagent",name:I(c.tool)??m,sequence:o.sequence,status:"running",startedAt:i,endedAt:e.endedAt,durationMs:Math.max(0,Date.parse(e.endedAt)-Date.parse(i)),inputRefs:[],outputRefs:[],provider:{provider:"codex",nativeEventType:o.method,nativeIds:{subagentCallId:d,turnId:n.providerTurnId,...n.providerThreadId?{threadId:n.providerThreadId}:{},...I(c.senderThreadId)?{senderThreadId:String(c.senderThreadId)}:{}},rawAttributes:{itemType:m,auditEventSequence:o.sequence,hasCompletion:!1,receiverThreadIds:c.receiverThreadIds,model:c.model,reasoningEffort:c.reasoningEffort}},provenance:{source:"provider_event",accuracy:"provider_reported"}},_=I(c.prompt);_&&x(h.inputRefs,A(s,{role:"subagent_prompt",format:"text",value:_,captureLevel:"provider_exact"})),u.push(h)}return u}function Ne(e,t,n,r,s){const u=[];for(const a of t){if(!E(a.params,n))continue;if(Ie.has(a.method)&&a.params.willRetry===!0){const c=M(a.observedAt)??e.endedAt,m=y(a.params.error);u.push({spanId:`codex-retry-${R(`${e.traceId}|${a.sequence}`)}`,traceId:e.traceId,turnId:e.turnId,sessionId:e.sessionId,parentSpanId:`codex:${e.turnId}:turn`,kind:"retry",name:I(m?.message)??"Codex request retry",sequence:a.sequence,status:"completed",startedAt:c,endedAt:c,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 p=y(a.params.item),d=P.has(a.method)&&p?.type==="contextCompaction";if(!ve.has(a.method)&&!d)continue;const o=W(a,e);u.push({spanId:`codex-compaction-${R(`${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:o,endedAt:o,durationMs:0,inputRefs:[],outputRefs:[],provider:{provider:"codex",nativeEventType:a.method,nativeIds:{turnId:n.providerTurnId,...n.providerThreadId?{threadId:n.providerThreadId}:{},...I(p?.id)?{itemId:String(p?.id)}:{}},rawAttributes:p?{item:p}:{params:a.params}},provenance:{source:"provider_event",accuracy:"provider_reported"}})}if(O(e).rawProviderBody)for(const a of t){if(!he.has(a.method)||!E(a.params,n))continue;const p=A(s,{role:"model_response",format:"json",value:S(a.params.item),captureLevel:"provider_exact"}),d=[...r].filter(o=>o.sequence>=a.sequence).sort((o,c)=>o.sequence-c.sequence)[0]??r.at(-1);d&&x(d.outputRefs,p)}return u}function se(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=y(n);return I(r?.text)??""}).join("")||void 0}function Ue(e,t,n,r,s,u){const a=[...r].sort((l,h)=>l.sequence-h.sequence),p=t.filter(l=>P.has(l.method)&&E(l.params,n)&&y(l.params.item)).sort((l,h)=>l.sequence-h.sequence),d=O(e);let o=Number.NEGATIVE_INFINITY,c=1;const m=new Set;for(const[l,h]of a.entries()){const _=h.sequence,g=p.filter(v=>v.sequence>o&&v.sequence<=_);if(d.inputOutput)for(const v of g){const w=y(v.params.item),f=I(w.type);if(f!=="userMessage"&&f!=="agentMessage")continue;const k=se(w);k&&x(f==="userMessage"?h.inputRefs:h.outputRefs,A(u,{role:f==="userMessage"?"user_input":"assistant_text",format:"text",value:k,captureLevel:"provider_exact"}))}if(d.thinking)for(const v of g){const w=y(v.params.item);if(w.type!=="reasoning")continue;const f=se(w);f&&x(h.outputRefs,A(u,{role:"thinking",format:"text",value:f,captureLevel:"provider_exact"}))}d.inputOutput&&l===0&&h.inputRefs.length===0&&e.input&&x(h.inputRefs,K(e.input)),d.inputOutput&&l===a.length-1&&h.outputRefs.length===0&&e.finalOutput&&x(h.outputRefs,K(e.finalOutput)),h.sequence=c++;const q=s.filter(v=>{const w=T(v.provider.rawAttributes?.auditEventSequence);return w!==void 0&&w>o&&w<=_}).sort((v,w)=>T(v.provider.rawAttributes?.auditEventSequence)-T(w.provider.rawAttributes?.auditEventSequence));for(const v of q)v.sequence=c++,m.add(v.spanId);o=_}const i=s.filter(l=>!m.has(l.spanId)).sort((l,h)=>l.sequence-h.sequence);for(const l of i)l.sequence=c++;for(const l of s){if(l.outputRefs.length===0)continue;const h=a.findIndex(g=>g.spanId===l.parentSpanId),_=h>=0?a[h+1]:void 0;if(_)for(const g of l.outputRefs)x(_.inputRefs,g)}}class ze{provider="codex";async collect(t){const n=L(t.boundary.codexEvidence),r=y(t.boundary.codexEvidence);return r?.rawApiCapture!==void 0&&(n.rawApiCapture=await ie(r.rawApiCapture)),n}async normalize(t,n){const r=L(n),s=we(t),u=[],a=Re(r.events,s,u),p=Ce(r.events,s,u),d=ke(r.rolloutEntries??[],s,r.events.length+1,u),o=Ee([...p,...d]),m=be(a,o).map(g=>Me(t,g,r.modelId)),i=[],l=Pe(t,r.events,s,m,i),h=De(t,r.events,s,m,i),_=Ne(t,r.events,s,m,i);return Ue(t,r.events,s,m,l,i),Se(t,r.rawApiCapture,m,i,u),{spans:[...m,...l,...h,..._],contents:i,anomalies:u}}async correlate(t,n){return n}validate(t,n){const r=n.spans.filter(f=>f.kind==="llm_request"&&f.usage),s=n.anomalies.some(f=>f.code==="codex_usage_invalid"||f.code==="codex_total_snapshot_invalid"||f.code==="codex_response_usage_conflict"),u=r.length>0&&!s&&r.every(f=>f.usage?.completeness==="complete"),a=O(t),p=!a.inputOutput||!!t.input,d=n.contents.some(f=>f.role==="assistant_text"||f.role==="model_response"||f.role==="final_response"),o=!a.inputOutput||!!t.finalOutput||d,c=oe(n.spans,a.tools),m=c.complete,i=n.spans.filter(f=>f.kind==="subagent"),l=!a.subagents||i.every(f=>f.status!=="running"),h=n.contents.filter(f=>f.role==="model_request"&&f.value!==void 0).length,_=n.contents.filter(f=>f.role==="model_response"&&f.value!==void 0).length,g=n.anomalies.some(f=>f.code==="codex_raw_api_capture_unavailable"||f.code==="codex_raw_api_capture_partial"||f.code==="codex_raw_api_correlation_ambiguous"),q=!a.rawProviderBody||h>0&&_>=h&&!g,v=[];return r.length===0&&v.push({category:"usage",reason:"provider_usage_missing",detail:"No Codex leaf request usage was found for the provider turn"}),r.length>0&&!u&&v.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&&!l&&v.push({category:"subagents",reason:"correlation_failed",detail:"One or more Codex collaboration items did not reach a terminal state"}),a.rawProviderBody&&(h===0?v.push({category:"raw_provider_body",reason:"raw_capture_disabled",detail:"Codex raw API capture did not produce a request body"}):q||v.push({category:"raw_provider_body",reason:"correlation_failed",detail:"One or more Codex raw API exchanges are incomplete"})),v.push(...c.gaps),{status:u&&p&&o&&m&&l&&q?"complete":"partial",inputComplete:p,outputComplete:o,toolCallsComplete:m,subagentsComplete:l,usageComplete:u,rawRequestsComplete:q,gaps:ae(v)}}async cleanup(t,n){const r=L(n).rawApiCapture;r&&await ue(r)}}export{ze as CodexAuditAdapter};
|