@yuandc/aica 0.1.37 → 0.1.39

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.
@@ -1,5 +1,5 @@
1
- import f from"node:fs";const T=1024*1024;function x(t=process.env){return{compactTokenThreshold:u(t.ACA_CODEX_COMPACT_TOKEN_THRESHOLD,12e4),compactContextRatio:h(t.ACA_CODEX_COMPACT_CONTEXT_RATIO,.45),rolloverTokenThreshold:u(t.ACA_CODEX_ROLLOVER_TOKEN_THRESHOLD,18e4),rolloverContextRatio:h(t.ACA_CODEX_ROLLOVER_CONTEXT_RATIO,.6),rolloutMaxBytes:u(t.ACA_CODEX_ROLLOUT_MAX_BYTES,50*T),threadMaxTurns:u(t.ACA_CODEX_THREAD_MAX_TURNS,40),compactTimeoutMs:u(t.ACA_CODEX_COMPACT_TIMEOUT_MS,600*1e3),slowEventThresholdMs:u(t.ACA_CODEX_SLOW_EVENT_THRESHOLD_MS,300*1e3),usageLoopWindowMs:u(t.ACA_CODEX_USAGE_LOOP_WINDOW_MS,120*1e3),usageLoopMinSamples:u(t.ACA_CODEX_USAGE_LOOP_MIN_SAMPLES,4),usageLoopMinInputTokens:u(t.ACA_CODEX_USAGE_LOOP_MIN_INPUT_TOKENS,5e4),usageLoopMaxOutputTokens:_(t.ACA_CODEX_USAGE_LOOP_MAX_OUTPUT_TOKENS,128)}}function m(t,e=Date.now()){const s=a(t),o=a(s.tokenUsage),n=a(o.last),r=c(n.inputTokens),l=c(n.outputTokens),d=c(n.totalTokens),i=c(o.modelContextWindow);return r===0&&d===0&&i===0?null:{source:"thread_usage",inputTokens:r,outputTokens:l,hasOutputTokens:typeof n.outputTokens=="number"&&Number.isFinite(n.outputTokens),totalTokens:d,contextWindow:i,contextRatio:i>0?r/i:0,observedAtMs:e,threadId:p(s.threadId),turnId:p(s.turnId),responseId:null}}function M(t,e=Date.now()){const s=a(t),o=a(s.usage);if(Object.keys(o).length===0)return null;const n=c(o.inputTokens),r=c(o.outputTokens),l=c(o.totalTokens);return n===0&&r===0&&l===0?null:{source:"raw_response",inputTokens:n,outputTokens:r,hasOutputTokens:typeof o.outputTokens=="number"&&Number.isFinite(o.outputTokens),totalTokens:l,contextWindow:0,contextRatio:0,observedAtMs:e,threadId:p(s.threadId),turnId:p(s.turnId),responseId:p(s.responseId)}}function C(t,e=Date.now()){const s=a(t),o=a(s.update);if(String(o.sessionUpdate||"")!=="usage_update")return null;const n=a(o._meta),r=a(n.codex);return Object.keys(r).length===0?null:m(r,e)}function E(t,e=Date.now()){const s=a(t),o=a(s.update);if(String(o.sessionUpdate||"")!=="aca_codex_raw_response_usage")return null;const n=a(o._meta),r=a(n.codex);return M(r.rawResponse,e)}function k(t,e,s={}){const o=[],n=[];return t.usage&&t.usage.inputTokens>=e.compactTokenThreshold&&o.push("token-threshold"),t.usage&&t.usage.contextRatio>=e.compactContextRatio&&o.push("context-ratio"),t.rolloutBytes>=e.rolloutMaxBytes&&o.push("rollout-size"),t.turnCount>=e.threadMaxTurns&&o.push("turn-count"),s.compactAttempted&&(s.compactFailed&&n.push("compact-failed"),t.usage&&t.usage.inputTokens>=e.rolloverTokenThreshold&&n.push("token-still-high"),t.usage&&t.usage.contextRatio>=e.rolloverContextRatio&&n.push("context-ratio-still-high"),t.rolloutBytes>=e.rolloutMaxBytes&&n.push("rollout-size"),t.turnCount>=e.threadMaxTurns&&n.push("turn-count")),{compact:o.length>0,rollover:n.length>0,reasons:[...new Set([...o,...n])]}}function g(t){if(!t)return 0;try{const e=f.statSync(t);return e.isFile()?e.size:0}catch{return 0}}function R(t){const e=[...new Set(t.affectedFiles.map(s=>s.trim()).filter(Boolean))].slice(0,30);return["ACA automatically rotated a long Codex thread to keep future turns responsive.","Treat the following as continuity context, not as a new user request.","Repository files on disk are authoritative; inspect them before making further edits.","",`Previous thread: ${t.previousThreadId}`,`Working directory: ${t.cwd}`,"","Latest user request:",A(t.userRequest,3e3)||"(not available)","","Latest completed assistant result:",A(t.assistantResponse,7e3)||"(not available)","","Recently affected files:",e.length>0?e.map(s=>`- ${s}`).join(`
1
+ import m from"node:fs";const f=1024*1024;function C(e=process.env){const t=a(e.ACA_CODEX_USAGE_LOOP_MIN_SAMPLES,4);return{compactTokenThreshold:a(e.ACA_CODEX_COMPACT_TOKEN_THRESHOLD,12e4),compactContextRatio:A(e.ACA_CODEX_COMPACT_CONTEXT_RATIO,.45),rolloverTokenThreshold:a(e.ACA_CODEX_ROLLOVER_TOKEN_THRESHOLD,18e4),rolloverContextRatio:A(e.ACA_CODEX_ROLLOVER_CONTEXT_RATIO,.6),rolloutMaxBytes:a(e.ACA_CODEX_ROLLOUT_MAX_BYTES,50*f),threadMaxTurns:a(e.ACA_CODEX_THREAD_MAX_TURNS,40),compactTimeoutMs:a(e.ACA_CODEX_COMPACT_TIMEOUT_MS,600*1e3),slowEventThresholdMs:a(e.ACA_CODEX_SLOW_EVENT_THRESHOLD_MS,300*1e3),usageLoopWindowMs:a(e.ACA_CODEX_USAGE_LOOP_WINDOW_MS,120*1e3),usageLoopMinSamples:t,usageLoopInterruptSamples:Math.max(t+1,a(e.ACA_CODEX_USAGE_LOOP_INTERRUPT_SAMPLES,8)),usageLoopMinInputTokens:a(e.ACA_CODEX_USAGE_LOOP_MIN_INPUT_TOKENS,5e4),usageLoopMaxOutputTokens:O(e.ACA_CODEX_USAGE_LOOP_MAX_OUTPUT_TOKENS,128)}}function _(e,t=Date.now()){const s=i(e),n=i(s.tokenUsage),o=i(n.last),r=c(o.inputTokens),l=c(o.outputTokens),d=c(o.totalTokens),p=c(n.modelContextWindow);return r===0&&d===0&&p===0?null:{source:"thread_usage",inputTokens:r,outputTokens:l,hasOutputTokens:typeof o.outputTokens=="number"&&Number.isFinite(o.outputTokens),totalTokens:d,contextWindow:p,contextRatio:p>0?r/p:0,observedAtMs:t,threadId:h(s.threadId),turnId:h(s.turnId),responseId:null}}function M(e,t=Date.now()){const s=i(e),n=i(s.usage);if(Object.keys(n).length===0)return null;const o=c(n.inputTokens),r=c(n.outputTokens),l=c(n.totalTokens);return o===0&&r===0&&l===0?null:{source:"raw_response",inputTokens:o,outputTokens:r,hasOutputTokens:typeof n.outputTokens=="number"&&Number.isFinite(n.outputTokens),totalTokens:l,contextWindow:0,contextRatio:0,observedAtMs:t,threadId:h(s.threadId),turnId:h(s.turnId),responseId:h(s.responseId)}}function E(e,t=Date.now()){const s=i(e),n=i(s.update);if(String(n.sessionUpdate||"")!=="usage_update")return null;const o=i(n._meta),r=i(o.codex);return Object.keys(r).length===0?null:_(r,t)}function k(e,t=Date.now()){const s=i(e),n=i(s.update);if(String(n.sessionUpdate||"")!=="aca_codex_raw_response_usage")return null;const o=i(n._meta),r=i(o.codex);return M(r.rawResponse,t)}function I(e,t,s={}){const n=[],o=[];return e.usage&&e.usage.inputTokens>=t.compactTokenThreshold&&n.push("token-threshold"),e.usage&&e.usage.contextRatio>=t.compactContextRatio&&n.push("context-ratio"),e.rolloutBytes>=t.rolloutMaxBytes&&n.push("rollout-size"),e.turnCount>=t.threadMaxTurns&&n.push("turn-count"),s.compactAttempted&&(s.compactFailed&&o.push("compact-failed"),e.usage&&e.usage.inputTokens>=t.rolloverTokenThreshold&&o.push("token-still-high"),e.usage&&e.usage.contextRatio>=t.rolloverContextRatio&&o.push("context-ratio-still-high"),e.rolloutBytes>=t.rolloutMaxBytes&&o.push("rollout-size"),e.turnCount>=t.threadMaxTurns&&o.push("turn-count")),{compact:n.length>0,rollover:o.length>0,reasons:[...new Set([...n,...o])]}}function R(e){if(!e)return 0;try{const t=m.statSync(e);return t.isFile()?t.size:0}catch{return 0}}function g(e){const t=[...new Set(e.affectedFiles.map(s=>s.trim()).filter(Boolean))].slice(0,30);return["ACA automatically rotated a long Codex thread to keep future turns responsive.","Treat the following as continuity context, not as a new user request.","Repository files on disk are authoritative; inspect them before making further edits.","",`Previous thread: ${e.previousThreadId}`,`Working directory: ${e.cwd}`,"","Latest user request:",T(e.userRequest,3e3)||"(not available)","","Latest completed assistant result:",T(e.assistantResponse,7e3)||"(not available)","","Recently affected files:",t.length>0?t.map(s=>`- ${s}`).join(`
2
2
  `):"- (not recorded)"].join(`
3
- `)}class I{startedAtMs;firstEventAtMs=null;lastEventAtMs=null;eventCount=0;lastSlowReportAtMs=0;constructor(e=Date.now()){this.startedAtMs=e}recordEvent(e=Date.now()){this.firstEventAtMs===null&&(this.firstEventAtMs=e),this.lastEventAtMs=e,this.eventCount+=1}shouldReportSlow(e,s){const o=this.lastEventAtMs??this.startedAtMs;return e-o<s||this.lastSlowReportAtMs>0&&e-this.lastSlowReportAtMs<s?!1:(this.lastSlowReportAtMs=e,!0)}snapshot(e=Date.now()){const s=this.lastEventAtMs??this.startedAtMs;return{startedAtMs:this.startedAtMs,firstEventAtMs:this.firstEventAtMs,lastEventAtMs:this.lastEventAtMs,eventCount:this.eventCount,firstEventLatencyMs:this.firstEventAtMs===null?null:this.firstEventAtMs-this.startedAtMs,silentForMs:Math.max(0,e-s),durationMs:Math.max(0,e-this.startedAtMs)}}}class w{policy;samples=[];detected=!1;rawResponseObserved=!1;constructor(e){this.policy=e}recordMeaningfulEvent(){this.samples=[],this.detected=!1}recordUsage(e){if(this.detected)return null;if(e.source==="raw_response"&&!this.rawResponseObserved)this.samples=[],this.rawResponseObserved=!0;else if(e.source==="thread_usage"&&this.rawResponseObserved)return null;if(!e.hasOutputTokens||e.inputTokens<this.policy.usageLoopMinInputTokens||e.outputTokens>this.policy.usageLoopMaxOutputTokens)return this.samples=[],null;const s=e.observedAtMs-this.policy.usageLoopWindowMs;if(this.samples=this.samples.filter(i=>i.observedAtMs>=s),this.samples.push(e),this.samples.length<this.policy.usageLoopMinSamples)return null;const o=this.samples.slice(-this.policy.usageLoopMinSamples),n=o.map(i=>i.inputTokens),r=Math.min(...n),l=Math.max(...n),d=Math.max(2e3,Math.floor(l*.05));return l-r>d?null:(this.detected=!0,{source:e.source,sampleCount:o.length,windowMs:o.at(-1).observedAtMs-o[0].observedAtMs,minInputTokens:r,maxInputTokens:l,maxOutputTokens:Math.max(...o.map(i=>i.outputTokens)),detectedAtMs:e.observedAtMs,threadId:e.threadId,turnId:e.turnId,responseIds:o.map(i=>i.responseId).filter(i=>!!i)})}}function u(t,e){const s=Number.parseInt(t??"",10);return Number.isInteger(s)&&s>0?s:e}function _(t,e){const s=Number.parseInt(t??"",10);return Number.isInteger(s)&&s>=0?s:e}function h(t,e){const s=Number.parseFloat(t??"");return Number.isFinite(s)&&s>0&&s<=1?s:e}function c(t){return typeof t=="number"&&Number.isFinite(t)&&t>=0?Math.floor(t):0}function A(t,e){const s=t.replace(/\r\n/g,`
4
- `).trim();return s.length<=e?s:`${s.slice(0,e-16).trimEnd()}
5
- ...[truncated]`}function a(t){return t&&typeof t=="object"&&!Array.isArray(t)?t:{}}function p(t){return typeof t=="string"&&t.trim()?t.trim():null}export{I as CodexPromptPerformanceTracker,w as CodexUsageLoopDetector,R as buildCodexContinuityInstructions,E as codexRawResponseUsageFromAcpSessionUpdate,C as codexTokenUsageFromAcpSessionUpdate,m as codexTokenUsageFromNotification,M as codexTokenUsageFromRawResponseCompleted,k as decideCodexContextMaintenance,x as readCodexContextMaintenancePolicy,g as rolloutFileSize};
3
+ `)}class S{startedAtMs;firstEventAtMs=null;lastEventAtMs=null;eventCount=0;lastSlowReportAtMs=0;constructor(t=Date.now()){this.startedAtMs=t}recordEvent(t=Date.now()){this.firstEventAtMs===null&&(this.firstEventAtMs=t),this.lastEventAtMs=t,this.eventCount+=1}shouldReportSlow(t,s){const n=this.lastEventAtMs??this.startedAtMs;return t-n<s||this.lastSlowReportAtMs>0&&t-this.lastSlowReportAtMs<s?!1:(this.lastSlowReportAtMs=t,!0)}snapshot(t=Date.now()){const s=this.lastEventAtMs??this.startedAtMs;return{startedAtMs:this.startedAtMs,firstEventAtMs:this.firstEventAtMs,lastEventAtMs:this.lastEventAtMs,eventCount:this.eventCount,firstEventLatencyMs:this.firstEventAtMs===null?null:this.firstEventAtMs-this.startedAtMs,silentForMs:Math.max(0,t-s),durationMs:Math.max(0,t-this.startedAtMs)}}}class w{policy;samples=[];detection=null;rawResponseObserved=!1;constructor(t){this.policy=t}recordMeaningfulEvent(){const t=this.detection;return this.samples=[],this.detection=null,t}recordUsage(t){if(t.source==="raw_response"&&!this.rawResponseObserved)this.samples=[],this.rawResponseObserved=!0;else if(t.source==="thread_usage"&&this.rawResponseObserved)return null;if(!t.hasOutputTokens||t.inputTokens<this.policy.usageLoopMinInputTokens||t.outputTokens>this.policy.usageLoopMaxOutputTokens)return this.samples=[],this.detection=null,null;const s=this.samples.at(-1);s&&(s.source!==t.source||s.threadId&&t.threadId&&s.threadId!==t.threadId||s.turnId&&t.turnId&&s.turnId!==t.turnId)&&(this.samples=[],this.detection=null);const n=t.observedAtMs-this.policy.usageLoopWindowMs;if(this.samples=this.samples.filter(u=>u.observedAtMs>=n),this.samples.push(t),this.samples.length<this.policy.usageLoopMinSamples)return null;const o=this.samples,r=o.map(u=>u.inputTokens),l=Math.min(...r),d=Math.max(...r),p=Math.max(2e3,Math.floor(d*.05));return d-l>p?(this.samples=[t],this.detection=null,null):(this.detection={source:t.source,sampleCount:o.length,windowMs:o.at(-1).observedAtMs-o[0].observedAtMs,minInputTokens:l,maxInputTokens:d,maxOutputTokens:Math.max(...o.map(u=>u.outputTokens)),detectedAtMs:t.observedAtMs,threadId:t.threadId,turnId:t.turnId,responseIds:o.map(u=>u.responseId).filter(u=>!!u)},this.detection)}}function a(e,t){const s=Number.parseInt(e??"",10);return Number.isInteger(s)&&s>0?s:t}function O(e,t){const s=Number.parseInt(e??"",10);return Number.isInteger(s)&&s>=0?s:t}function A(e,t){const s=Number.parseFloat(e??"");return Number.isFinite(s)&&s>0&&s<=1?s:t}function c(e){return typeof e=="number"&&Number.isFinite(e)&&e>=0?Math.floor(e):0}function T(e,t){const s=e.replace(/\r\n/g,`
4
+ `).trim();return s.length<=t?s:`${s.slice(0,t-16).trimEnd()}
5
+ ...[truncated]`}function i(e){return e&&typeof e=="object"&&!Array.isArray(e)?e:{}}function h(e){return typeof e=="string"&&e.trim()?e.trim():null}export{S as CodexPromptPerformanceTracker,w as CodexUsageLoopDetector,g as buildCodexContinuityInstructions,k as codexRawResponseUsageFromAcpSessionUpdate,E as codexTokenUsageFromAcpSessionUpdate,_ as codexTokenUsageFromNotification,M as codexTokenUsageFromRawResponseCompleted,I as decideCodexContextMaintenance,C as readCodexContextMaintenancePolicy,R as rolloutFileSize};
@@ -1 +1 @@
1
- import u from"node:fs";import{runAbortableRequest as w}from"../../client/abortable-request.js";import{BoundedItemBuffer as M}from"../../client/bounded-buffer.js";import{promptBlocksToAcpContent as T}from"../../client/acp-content.js";import{acpSessionUpdateFromParams as q,eventFromAcpSessionUpdate as U,statusFromAcpSessionUpdate as E,subtaskContextFromAcpSessionUpdate as D}from"../../client/acp-events.js";import{defaultAcpRuntimePool as y}from"../../client/acp-runtime-pool.js";import{resolveCodexAcpLaunch as C}from"./launch.js";import{CodexPromptPerformanceTracker as O,CodexUsageLoopDetector as L,codexRawResponseUsageFromAcpSessionUpdate as F,codexTokenUsageFromAcpSessionUpdate as j,readCodexContextMaintenancePolicy as I}from"./context-maintenance.js";import{ensureCodexProviderRuntimeConfig as b}from"../../../core/codex-provider-runtime-config.js";const z={sessionResume:!0,imageInput:!0,fileAttachment:!0,filesystem:!0,terminal:!0,permissionRequest:!0,configOptions:!0,usage:!0,contextUsage:!0,contextCompaction:!0,plan:!0,diff:!0};class ie{id="codex-acp";name="Codex ACP";capabilities=z;async createSession(e){return new N(e.cwd,e.providerSessionId??null,e.timeoutMs)}async forkSession(e){if(!u.existsSync(e.cwd)||!u.statSync(e.cwd).isDirectory())throw new Error(`Project root does not exist or is not a directory: ${e.cwd}`);const t=e.sourceProviderSessionId.trim(),o=await b(),r=await y.acquire({providerId:"codex-acp",cwd:e.cwd,providerSessionId:t,runtimeIdentity:o?.runtimeIdentity||"default",env:v(o),...C(),onSessionUpdate:()=>{}});try{await A(r,o),r.initialized||(await r.client.initialize(6e4),r.markInitialized()),e.onStatus?.({phase:"forking",label:"正在分叉 Codex 会话",detail:t,updateType:"session/fork",atMs:Date.now()});const i=await r.client.forkSession({sessionId:t,cwd:e.cwd,config:x(e)},e.timeoutMs??12e4),n=h(i);if(!n)throw new Error("Codex ACP session/fork did not return sessionId");return{providerSessionId:n}}finally{r.release()}}}class N{cwd;providerSessionId;defaultTimeoutMs;lease=null;sessionResponse=null;statusCallback=null;updateCallback=null;permissionCallback=null;userInputCallback=null;abortHandler=null;statusTimeline=[];updates=new M(16);content="";performanceTracker=null;usageLoopDetector=null;usagePatternReport=null;constructor(e,t,o=K()){this.cwd=e,this.providerSessionId=t,this.defaultTimeoutMs=o}async sendPrompt(e){if(!u.existsSync(e.cwd)||!u.statSync(e.cwd).isDirectory())throw new Error(`Project root does not exist or is not a directory: ${e.cwd}`);const t=Date.now();this.statusCallback=e.onStatus??null,this.updateCallback=e.onUpdate??null,this.permissionCallback=e.onPermissionRequest??null,this.userInputCallback=e.onUserInputRequest??null,this.attachAbortSignal(e.signal),this.content="",this.updates.clear(),this.statusTimeline.length=0;const o=I();this.performanceTracker=new O(t),this.usageLoopDetector=new L(o);let r=null,i=null,n=this.providerSessionId,c,a=null;try{this.emitStatus("initializing","Codex ACP 启动中","codex-acp");const d=await this.acquireRuntime(e.cwd);this.lease=d,r=d.client,i=d.started,await this.initialize(d),n=await this.establishSession(d,e),await this.applyConfig(r,n,e),this.emitStatus("thinking","思考中"),a=this.startSlowStatusTimer(),this.usagePatternReport=S=>{const R=`${S.sampleCount} 次内部采样均输入约 ${Math.round(S.maxInputTokens/1e3)}k tokens`;this.emitStatus("thinking","Codex 正在进行内部续步",R,"aca.performance.multi_response")},c=await this.promptWithAbort(r,{sessionId:n,prompt:T(e.prompt,e.promptBlocks),timeoutMs:e.timeoutMs??this.defaultTimeoutMs,signal:e.signal});const p=_(c);p&&p!==n&&(n=p,this.providerSessionId=p,d.setProviderSession({providerSessionId:p,sessionResponse:this.sessionResponse}))}finally{a&&clearInterval(a),this.usagePatternReport=null,this.usageLoopDetector=null,this.abortHandler&&e.signal&&(e.signal.removeEventListener("abort",this.abortHandler),this.abortHandler=null),this.releaseLease()}return this.emitStatus("completed","已完成"),{providerSessionId:n,cliType:"builtin",agentType:"codex",effectiveConfig:{model:e.model??null,mode:e.mode??null,configOptionValues:e.configOptionValues??null,command:i.command,processPid:i.child.pid??null,provider:"codex-acp",protocol:"acp"},command:i.command,args:i.args,cwd:e.cwd,exitCode:i.child.exitCode,signal:i.child.signalCode,durationMs:Date.now()-t,stdout:r.rpc.stdout,stderr:r.rpc.stderr,content:this.content.trim(),updateCount:this.updates.count(),updates:this.updates.snapshot(),statusTimeline:[...this.statusTimeline],performance:this.performanceTracker?.snapshot(),contextUsage:G(c),promptResponse:c}}async compactContext(e){if(!u.existsSync(e.cwd)||!u.statSync(e.cwd).isDirectory())throw new Error(`Project root does not exist or is not a directory: ${e.cwd}`);const t=Date.now();this.statusCallback=e.onStatus??null,this.updateCallback=e.onUpdate??null,this.attachAbortSignal(e.signal);let o=this.providerSessionId,r;try{this.emitStatus("initializing","Codex ACP 启动中","codex-acp");const n=await this.acquireRuntime(e.cwd);this.lease=n,await this.initialize(n),o=await this.establishSession(n,e),await this.applyConfig(n.client,o,e);const c=X(e.timeoutMs);r=await this.compactWithAbort(n.client,{sessionId:o,allowRollover:e.allowRollover===!0,timeoutMs:c,signal:e.signal});const a=_(r);a&&a!==o&&(o=a,this.providerSessionId=a,n.setProviderSession({providerSessionId:a,sessionResponse:this.sessionResponse}))}catch(n){if(this.lease&&V(n,e.signal)){const c=this.lease;this.lease=null,await c.dispose().catch(()=>{})}throw this.emitStatus("failed","上下文压缩失败",n instanceof Error?n.message:String(n)),n}finally{this.abortHandler&&e.signal&&(e.signal.removeEventListener("abort",this.abortHandler),this.abortHandler=null),this.releaseLease()}const i=l(r)??{};return{providerSessionId:o||this.providerSessionId||"",contextUsage:k(i.contextUsage),maintenance:l(i.maintenance)??{},durationMs:Date.now()-t}}async cancel(){this.providerSessionId&&this.lease?.client.cancel(this.providerSessionId)}async close(){this.statusCallback=null,this.updateCallback=null,this.permissionCallback=null,this.userInputCallback=null,this.abortHandler&&(this.abortHandler=null),this.releaseLease()}async acquireRuntime(e){const t=C(),o=await b(),r=await y.acquire({providerId:"codex-acp",cwd:e,providerSessionId:this.providerSessionId,runtimeIdentity:o?.runtimeIdentity||"default",env:v(o),command:t.command,args:t.args,onSessionUpdate:i=>this.handleSessionUpdate(i),onClientRequest:async(i,n)=>{if(i==="session/request_permission")return this.requestPermission(n);if(i==="elicitation/create"||i==="session/request_user_input")return this.requestUserInput(n);throw new Error(`Unsupported Codex ACP client request: ${i}`)}});try{return await A(r,o),r}catch(i){throw await r.dispose().catch(()=>{}),i}}async initialize(e){e.initialized||(await e.client.initialize(6e4),e.markInitialized())}async establishSession(e,t){const o=e.client,r=x(t);if(e.providerSessionId&&e.sessionEstablished)return this.providerSessionId=e.providerSessionId,this.sessionResponse=e.sessionResponse,e.providerSessionId;if(this.providerSessionId)try{this.emitStatus("resuming","Codex ACP 会话恢复中","session/load");const c=await o.loadSession({sessionId:this.providerSessionId,cwd:t.cwd,config:r},6e4);this.sessionResponse=l(c);const a=h(c)||this.providerSessionId;return this.providerSessionId=a,e.setProviderSession({providerSessionId:a,sessionResponse:this.sessionResponse}),a}catch(c){if(t.requireSessionResume){const a=c instanceof Error?c.message:String(c);throw new Error(`无法恢复导入的 Codex ACP Session ${this.providerSessionId}:${a}`)}this.providerSessionId=null}this.emitStatus("acp","Codex ACP 会话创建中","session/new");const i=await o.newSession({cwd:t.cwd,config:r},12e4);this.sessionResponse=l(i);const n=h(i);if(!n)throw new Error("Codex ACP session/new did not return sessionId");return this.providerSessionId=n,e.setProviderSession({providerSessionId:n,sessionResponse:this.sessionResponse}),n}async applyConfig(e,t,o){o.model&&await e.setSessionConfigOption({sessionId:t,configId:"model",value:o.model},6e4).catch(()=>{});const r=g(o.mode);r&&await e.setSessionConfigOption({sessionId:t,configId:"approvalPolicy",value:r},6e4).catch(()=>{});const i=f(o.mode);i&&await e.setSessionConfigOption({sessionId:t,configId:"sandbox",value:i},6e4).catch(()=>{});for(const[n,c]of Object.entries(o.configOptionValues??{}))["model","mode","sandbox","approvalPolicy"].includes(n)||await e.setSessionConfigOption({sessionId:t,configId:n,value:c},6e4).catch(()=>{})}handleSessionUpdate(e){const t=q(e),o=String(t?.update.sessionUpdate||""),r=D(e);if(!r&&H(o))this.performanceTracker?.recordEvent(),this.usageLoopDetector?.recordMeaningfulEvent();else if(!r&&o==="aca_codex_raw_response_usage"){const c=F(e),a=c?this.usageLoopDetector?.recordUsage(c):null;a&&this.usagePatternReport?.(a)}else if(!r&&o==="usage_update"){const c=j(e),a=c?this.usageLoopDetector?.recordUsage(c):null;a&&this.usagePatternReport?.(a)}this.updates.push({method:"session/update",params:e});const i=U(e);i&&(i.type==="agent_message_chunk"&&!r&&(this.content+=i.text??""),this.updateCallback?.(i));const n=E(e);n&&this.emitStatus(n.phase,n.label,n.detail,n.updateType)}startSlowStatusTimer(){const e=I().slowEventThresholdMs,t=setInterval(()=>{const o=this.performanceTracker,r=Date.now();if(!o?.shouldReportSlow(r,e))return;const i=o.snapshot(r),n=Math.max(1,Math.round(i.silentForMs/6e4));this.emitStatus("thinking","模型长时间处理中",`已 ${n} 分钟没有收到新的 ACP 事件`,"aca.performance.slow")},Math.min(3e4,Math.max(1e3,Math.floor(e/4))));return t.unref(),t}attachAbortSignal(e){if(e){if(this.abortHandler=()=>{this.cancel()},e.aborted)throw new Error("Codex ACP prompt cancelled");e.addEventListener("abort",this.abortHandler,{once:!0})}}async promptWithAbort(e,t){return w({signal:t.signal,cancelledMessage:"Codex ACP prompt cancelled",startRequest:()=>e.prompt({sessionId:t.sessionId,prompt:t.prompt},t.timeoutMs),onAbort:async()=>{e.cancel(t.sessionId),await this.lease?.dispose()}})}async compactWithAbort(e,t){return w({signal:t.signal,cancelledMessage:"Codex ACP 上下文压缩已取消",startRequest:()=>e.compactSession({sessionId:t.sessionId,allowRollover:t.allowRollover,timeoutMs:t.timeoutMs},t.timeoutMs),onAbort:async()=>{e.cancel(t.sessionId),await this.lease?.dispose()}})}async requestPermission(e){if(!this.permissionCallback)return{outcome:{outcome:"cancelled"}};const t=e&&typeof e=="object"&&!Array.isArray(e)?e:{},o=t.request&&typeof t.request=="object"&&!Array.isArray(t.request)?t.request:t,i=(Array.isArray(o.options)?o.options:[]).map((n,c)=>{const a=n&&typeof n=="object"&&!Array.isArray(n)?n:{};return{optionId:String(a.optionId??a.id??c),kind:String(a.kind??"choice"),...typeof a.label=="string"?{label:a.label}:{}}});return this.emitStatus("requestPermission","等待授权",W(o),"session/request_permission"),this.permissionCallback({requestId:String(o.requestId??o.id??`codex-acp-permission-${Date.now()}`),params:e,options:i})}async requestUserInput(e){if(!this.userInputCallback)return{outcome:{outcome:"cancelled"}};const t=e&&typeof e=="object"&&!Array.isArray(e)?e:{},o=t.request&&typeof t.request=="object"&&!Array.isArray(t.request)?t.request:t;return this.emitStatus("requestPermission","等待输入",B(o),"elicitation/create"),this.userInputCallback({requestId:String(o.requestId??o.id??`codex-acp-input-${Date.now()}`),prompt:String(o.prompt??o.message??o.question??""),params:e,...typeof o.defaultValue=="string"?{defaultValue:o.defaultValue}:{}})}emitStatus(e,t,o,r){const i={phase:e,label:t,...o?{detail:o}:{},...r?{updateType:r}:{},atMs:Date.now()},n=this.statusTimeline[this.statusTimeline.length-1];n&&n.phase===i.phase&&n.label===i.label&&n.detail===i.detail&&n.updateType===i.updateType||(this.statusTimeline.push(i),this.statusCallback?.(i))}releaseLease(){this.lease?.release(),this.lease=null}}const $=new Set(["agent_message_chunk","agent_progress_chunk","agent_thought_chunk","tool_call","tool_call_update","plan","plan_update","plan_removed","aca_context_maintenance"]);function H(s){return $.has(s)}async function A(s,e){s.runtimeConfigured||(await s.client.configureRuntime({codexProvider:e?{baseUrl:e.baseUrl,apiKey:e.apiKey,revision:e.revision}:null}),s.markRuntimeConfigured())}function v(s){return s?{OPENAI_API_KEY:s.apiKey,OPENAI_BASE_URL:s.baseUrl}:{}}function V(s,e){if(e?.aborted)return!0;const t=s instanceof Error?s.message:String(s||"");return/compact.*timed out|request timed out.*compact|adapter closed|aborted|cancelled/i.test(t)}function h(s){if(!s||typeof s!="object"||Array.isArray(s))return null;const e=s.sessionId;return typeof e=="string"&&e.trim()?e.trim():null}function l(s){return s&&typeof s=="object"&&!Array.isArray(s)?s:null}function f(s){const e=String(s||"").trim();return e?e==="read-only"?"read-only":["agent-full-access","full-access","bypassPermissions","danger-full-access"].includes(e)?"danger-full-access":"workspace-write":null}function g(s){const e=String(s||"").trim();return e?["agent-full-access","full-access","bypassPermissions","danger-full-access"].includes(e)?"never":e==="acceptEdits"||e==="accept-edits"?"on-failure":"on-request":null}function x(s){return{...s.model?{model:s.model}:{},...g(s.mode)?{approvalPolicy:g(s.mode)}:{},...f(s.mode)?{sandbox:f(s.mode)}:{},...s.configOptionValues??{}}}function W(s){const e=s.params&&typeof s.params=="object"&&!Array.isArray(s.params)?s.params:s;for(const t of["command","cwd","reason","grantRoot","method"]){const o=e[t];if(typeof o=="string"&&o.trim())return P(o)}}function B(s){for(const e of["prompt","message","question","title"]){const t=s[e];if(typeof t=="string"&&t.trim())return P(t)}}function P(s){const e=s.replace(/\s+/g," ").trim();return e.length>120?`${e.slice(0,117)}...`:e}function K(){const s=Number.parseInt(process.env.ACA_CODEX_ACP_PROMPT_TIMEOUT_MS??process.env.ACA_ACP_PROMPT_TIMEOUT_MS??"",10);return Number.isInteger(s)&&s>=3e4?s:360*60*1e3}function X(s){const e=Number.isInteger(s)?Number(s):Number.parseInt(process.env.ACA_CODEX_ACP_COMPACT_TIMEOUT_MS??"",10);return Number.isFinite(e)&&e>=3e4?Math.min(e,6e5):12e4}function _(s){if(!s||typeof s!="object"||Array.isArray(s))return null;const e=s;return typeof e.sessionId=="string"&&e.sessionId.trim()?e.sessionId:null}function G(s){const e=l(s),t=l(e?._meta);return k(t?.acaContextUsage)}function k(s){const e=l(s);if(!e)return null;const t=m(e.contextWindow),o=m(e.usedTokens),r=m(e.inputTokens),i=String(e.state||"unknown"),n=["active","compacted","new_thread"].includes(i)?i:"unknown";return{usedTokens:o,inputTokens:r,contextWindow:t,ratio:t>0?Math.max(0,m(e.ratio)||o/t):0,observedAtMs:m(e.observedAtMs)||Date.now(),state:n,maintenanceAction:typeof e.maintenanceAction=="string"?e.maintenanceAction:null}}function m(s){return typeof s=="number"&&Number.isFinite(s)&&s>=0?s:0}export{ie as CodexAcpProvider,z as codexAcpCapabilities};
1
+ import p from"node:fs";import{runAbortableRequest as v}from"../../client/abortable-request.js";import{BoundedItemBuffer as D}from"../../client/bounded-buffer.js";import{promptBlocksToAcpContent as L}from"../../client/acp-content.js";import{acpSessionUpdateFromParams as O,eventFromAcpSessionUpdate as F,statusFromAcpSessionUpdate as j,subtaskContextFromAcpSessionUpdate as z}from"../../client/acp-events.js";import{defaultAcpRuntimePool as A}from"../../client/acp-runtime-pool.js";import{resolveCodexAcpLaunch as x}from"./launch.js";import{CodexPromptPerformanceTracker as $,CodexUsageLoopDetector as N,codexRawResponseUsageFromAcpSessionUpdate as W,codexTokenUsageFromAcpSessionUpdate as H,readCodexContextMaintenancePolicy as _}from"./context-maintenance.js";import{ensureCodexProviderRuntimeConfig as k}from"../../../core/codex-provider-runtime-config.js";const V={sessionResume:!0,imageInput:!0,fileAttachment:!0,filesystem:!0,terminal:!0,permissionRequest:!0,configOptions:!0,usage:!0,contextUsage:!0,contextCompaction:!0,plan:!0,diff:!0};class de{id="codex-acp";name="Codex ACP";capabilities=V;async createSession(e){return new B(e.cwd,e.providerSessionId??null,e.timeoutMs)}async forkSession(e){if(!p.existsSync(e.cwd)||!p.statSync(e.cwd).isDirectory())throw new Error(`Project root does not exist or is not a directory: ${e.cwd}`);const t=e.sourceProviderSessionId.trim(),o=await k(),r=await A.acquire({providerId:"codex-acp",cwd:e.cwd,providerSessionId:t,runtimeIdentity:o?.runtimeIdentity||"default",env:R(o),...x(),onSessionUpdate:()=>{}});try{await P(r,o),r.initialized||(await r.client.initialize(6e4),r.markInitialized()),e.onStatus?.({phase:"forking",label:"正在分叉 Codex 会话",detail:t,updateType:"session/fork",atMs:Date.now()});const i=await r.client.forkSession({sessionId:t,cwd:e.cwd,config:T(e)},e.timeoutMs??12e4),n=g(i);if(!n)throw new Error("Codex ACP session/fork did not return sessionId");return{providerSessionId:n}}finally{r.release()}}}class B{cwd;providerSessionId;defaultTimeoutMs;lease=null;sessionResponse=null;statusCallback=null;updateCallback=null;permissionCallback=null;userInputCallback=null;abortHandler=null;statusTimeline=[];updates=new D(16);content="";performanceTracker=null;usageLoopDetector=null;usagePatternReport=null;usageLoopWarningActive=!1;constructor(e,t,o=Q()){this.cwd=e,this.providerSessionId=t,this.defaultTimeoutMs=o}async sendPrompt(e){if(!p.existsSync(e.cwd)||!p.statSync(e.cwd).isDirectory())throw new Error(`Project root does not exist or is not a directory: ${e.cwd}`);const t=Date.now();this.statusCallback=e.onStatus??null,this.updateCallback=e.onUpdate??null,this.permissionCallback=e.onPermissionRequest??null,this.userInputCallback=e.onUserInputRequest??null,this.attachAbortSignal(e.signal),this.content="",this.updates.clear(),this.statusTimeline.length=0;const o=_();this.performanceTracker=new $(t),this.usageLoopDetector=new N(o),this.usageLoopWarningActive=!1;const r={error:null};let i=null,n=null,a=this.providerSessionId,c,f=null;try{this.emitStatus("initializing","Codex ACP 启动中","codex-acp");const d=await this.acquireRuntime(e.cwd);this.lease=d,i=d.client,n=d.started,await this.initialize(d),a=await this.establishSession(d,e),await this.applyConfig(i,a,e);const y=i,C=a;this.emitStatus("thinking","思考中"),f=this.startSlowStatusTimer(),this.usagePatternReport=u=>{if(r.error)return;const I=Math.round(u.maxInputTokens/1e3),b=`同一 Turn 已连续请求至少 ${u.sampleCount} 次,单次输入约 ${I}k tokens`;if(u.sampleCount<o.usageLoopInterruptSamples){this.usageLoopWarningActive=!0,this.emitStatus("thinking","Codex 出现低产出内部循环",b,"aca.performance.low_output_loop");return}const E=`Codex 低产出内部循环:同一 Turn 已连续请求至少 ${u.sampleCount} 次,单次输入约 ${I}k tokens,且未执行工具或产生有效输出`;r.error=new Error(E),this.emitStatus("failed","Codex 已中断低产出内部循环",b,"aca.performance.low_output_loop_interrupted"),y.cancel(C)};try{c=await this.promptWithAbort(y,{sessionId:C,prompt:L(e.prompt,e.promptBlocks),timeoutMs:e.timeoutMs??this.defaultTimeoutMs,signal:e.signal})}catch(u){throw r.error?r.error:u}if(r.error)throw r.error;const m=q(c);m&&m!==a&&(a=m,this.providerSessionId=m,d.setProviderSession({providerSessionId:m,sessionResponse:this.sessionResponse}))}finally{f&&clearInterval(f),this.usagePatternReport=null,this.usageLoopDetector=null,this.usageLoopWarningActive=!1,this.abortHandler&&e.signal&&(e.signal.removeEventListener("abort",this.abortHandler),this.abortHandler=null),this.releaseLease()}return this.emitStatus("completed","已完成"),{providerSessionId:a,cliType:"builtin",agentType:"codex",effectiveConfig:{model:e.model??null,mode:e.mode??null,configOptionValues:e.configOptionValues??null,command:n.command,processPid:n.child.pid??null,provider:"codex-acp",protocol:"acp"},command:n.command,args:n.args,cwd:e.cwd,exitCode:n.child.exitCode,signal:n.child.signalCode,durationMs:Date.now()-t,stdout:i.rpc.stdout,stderr:i.rpc.stderr,content:this.content.trim(),updateCount:this.updates.count(),updates:this.updates.snapshot(),statusTimeline:[...this.statusTimeline],performance:this.performanceTracker?.snapshot(),contextUsage:ee(c),promptResponse:c}}async compactContext(e){if(!p.existsSync(e.cwd)||!p.statSync(e.cwd).isDirectory())throw new Error(`Project root does not exist or is not a directory: ${e.cwd}`);const t=Date.now();this.statusCallback=e.onStatus??null,this.updateCallback=e.onUpdate??null,this.attachAbortSignal(e.signal);let o=this.providerSessionId,r;try{this.emitStatus("initializing","Codex ACP 启动中","codex-acp");const n=await this.acquireRuntime(e.cwd);this.lease=n,await this.initialize(n),o=await this.establishSession(n,e),await this.applyConfig(n.client,o,e);const a=Z(e.timeoutMs);r=await this.compactWithAbort(n.client,{sessionId:o,allowRollover:e.allowRollover===!0,timeoutMs:a,signal:e.signal});const c=q(r);c&&c!==o&&(o=c,this.providerSessionId=c,n.setProviderSession({providerSessionId:c,sessionResponse:this.sessionResponse}))}catch(n){if(this.lease&&G(n,e.signal)){const a=this.lease;this.lease=null,await a.dispose().catch(()=>{})}throw this.emitStatus("failed","上下文压缩失败",n instanceof Error?n.message:String(n)),n}finally{this.abortHandler&&e.signal&&(e.signal.removeEventListener("abort",this.abortHandler),this.abortHandler=null),this.releaseLease()}const i=l(r)??{};return{providerSessionId:o||this.providerSessionId||"",contextUsage:U(i.contextUsage),maintenance:l(i.maintenance)??{},durationMs:Date.now()-t}}async cancel(){this.providerSessionId&&this.lease?.client.cancel(this.providerSessionId)}async close(){this.statusCallback=null,this.updateCallback=null,this.permissionCallback=null,this.userInputCallback=null,this.abortHandler&&(this.abortHandler=null),this.releaseLease()}async acquireRuntime(e){const t=x(),o=await k(),r=await A.acquire({providerId:"codex-acp",cwd:e,providerSessionId:this.providerSessionId,runtimeIdentity:o?.runtimeIdentity||"default",env:R(o),command:t.command,args:t.args,onSessionUpdate:i=>this.handleSessionUpdate(i),onClientRequest:async(i,n)=>{if(i==="session/request_permission")return this.requestPermission(n);if(i==="elicitation/create"||i==="session/request_user_input")return this.requestUserInput(n);throw new Error(`Unsupported Codex ACP client request: ${i}`)}});try{return await P(r,o),r}catch(i){throw await r.dispose().catch(()=>{}),i}}async initialize(e){e.initialized||(await e.client.initialize(6e4),e.markInitialized())}async establishSession(e,t){const o=e.client,r=T(t);if(e.providerSessionId&&e.sessionEstablished)return this.providerSessionId=e.providerSessionId,this.sessionResponse=e.sessionResponse,e.providerSessionId;if(this.providerSessionId)try{this.emitStatus("resuming","Codex ACP 会话恢复中","session/load");const a=await o.loadSession({sessionId:this.providerSessionId,cwd:t.cwd,config:r},6e4);this.sessionResponse=l(a);const c=g(a)||this.providerSessionId;return this.providerSessionId=c,e.setProviderSession({providerSessionId:c,sessionResponse:this.sessionResponse}),c}catch(a){if(t.requireSessionResume){const c=a instanceof Error?a.message:String(a);throw new Error(`无法恢复导入的 Codex ACP Session ${this.providerSessionId}:${c}`)}this.providerSessionId=null}this.emitStatus("acp","Codex ACP 会话创建中","session/new");const i=await o.newSession({cwd:t.cwd,config:r},12e4);this.sessionResponse=l(i);const n=g(i);if(!n)throw new Error("Codex ACP session/new did not return sessionId");return this.providerSessionId=n,e.setProviderSession({providerSessionId:n,sessionResponse:this.sessionResponse}),n}async applyConfig(e,t,o){o.model&&await e.setSessionConfigOption({sessionId:t,configId:"model",value:o.model},6e4).catch(()=>{});const r=S(o.mode);r&&await e.setSessionConfigOption({sessionId:t,configId:"approvalPolicy",value:r},6e4).catch(()=>{});const i=w(o.mode);i&&await e.setSessionConfigOption({sessionId:t,configId:"sandbox",value:i},6e4).catch(()=>{});for(const[n,a]of Object.entries(o.configOptionValues??{}))["model","mode","sandbox","approvalPolicy"].includes(n)||await e.setSessionConfigOption({sessionId:t,configId:n,value:a},6e4).catch(()=>{})}handleSessionUpdate(e){const t=O(e),o=String(t?.update.sessionUpdate||""),r=z(e);if(!r&&X(o))this.performanceTracker?.recordEvent(),this.usageLoopDetector?.recordMeaningfulEvent(),this.usageLoopWarningActive&&(this.usageLoopWarningActive=!1,this.emitStatus("thinking","Codex 已恢复执行","已重新执行工具或产生有效输出","aca.performance.loop_recovered"));else if(!r&&o==="aca_codex_raw_response_usage"){const a=W(e),c=a?this.usageLoopDetector?.recordUsage(a):null;c&&this.usagePatternReport?.(c)}else if(!r&&o==="usage_update"){const a=H(e),c=a?this.usageLoopDetector?.recordUsage(a):null;c&&this.usagePatternReport?.(c)}this.updates.push({method:"session/update",params:e});const i=F(e);i&&(i.type==="agent_message_chunk"&&!r&&(this.content+=i.text??""),this.updateCallback?.(i));const n=j(e);n&&this.emitStatus(n.phase,n.label,n.detail,n.updateType)}startSlowStatusTimer(){const e=_().slowEventThresholdMs,t=setInterval(()=>{const o=this.performanceTracker,r=Date.now();if(!o?.shouldReportSlow(r,e))return;const i=o.snapshot(r),n=Math.max(1,Math.round(i.silentForMs/6e4)),a=this.usageLoopWarningActive?"Codex 可能卡在内部循环":"Codex 长时间没有有效进展";this.emitStatus("thinking",a,`已 ${n} 分钟没有执行工具或产生有效输出`,"aca.performance.slow")},Math.min(3e4,Math.max(1e3,Math.floor(e/4))));return t.unref(),t}attachAbortSignal(e){if(e){if(this.abortHandler=()=>{this.cancel()},e.aborted)throw new Error("Codex ACP prompt cancelled");e.addEventListener("abort",this.abortHandler,{once:!0})}}async promptWithAbort(e,t){return v({signal:t.signal,cancelledMessage:"Codex ACP prompt cancelled",startRequest:()=>e.prompt({sessionId:t.sessionId,prompt:t.prompt},t.timeoutMs),onAbort:async()=>{e.cancel(t.sessionId),await this.lease?.dispose()}})}async compactWithAbort(e,t){return v({signal:t.signal,cancelledMessage:"Codex ACP 上下文压缩已取消",startRequest:()=>e.compactSession({sessionId:t.sessionId,allowRollover:t.allowRollover,timeoutMs:t.timeoutMs},t.timeoutMs),onAbort:async()=>{e.cancel(t.sessionId),await this.lease?.dispose()}})}async requestPermission(e){if(!this.permissionCallback)return{outcome:{outcome:"cancelled"}};const t=e&&typeof e=="object"&&!Array.isArray(e)?e:{},o=t.request&&typeof t.request=="object"&&!Array.isArray(t.request)?t.request:t,i=(Array.isArray(o.options)?o.options:[]).map((n,a)=>{const c=n&&typeof n=="object"&&!Array.isArray(n)?n:{};return{optionId:String(c.optionId??c.id??a),kind:String(c.kind??"choice"),...typeof c.label=="string"?{label:c.label}:{}}});return this.emitStatus("requestPermission","等待授权",Y(o),"session/request_permission"),this.permissionCallback({requestId:String(o.requestId??o.id??`codex-acp-permission-${Date.now()}`),params:e,options:i})}async requestUserInput(e){if(!this.userInputCallback)return{outcome:{outcome:"cancelled"}};const t=e&&typeof e=="object"&&!Array.isArray(e)?e:{},o=t.request&&typeof t.request=="object"&&!Array.isArray(t.request)?t.request:t;return this.emitStatus("requestPermission","等待输入",J(o),"elicitation/create"),this.userInputCallback({requestId:String(o.requestId??o.id??`codex-acp-input-${Date.now()}`),prompt:String(o.prompt??o.message??o.question??""),params:e,...typeof o.defaultValue=="string"?{defaultValue:o.defaultValue}:{}})}emitStatus(e,t,o,r){const i={phase:e,label:t,...o?{detail:o}:{},...r?{updateType:r}:{},atMs:Date.now()},n=this.statusTimeline[this.statusTimeline.length-1];n&&n.phase===i.phase&&n.label===i.label&&n.detail===i.detail&&n.updateType===i.updateType||(this.statusTimeline.push(i),this.statusCallback?.(i))}releaseLease(){this.lease?.release(),this.lease=null}}const K=new Set(["agent_message_chunk","agent_progress_chunk","agent_thought_chunk","tool_call","tool_call_update","plan","plan_update","plan_removed","aca_context_maintenance"]);function X(s){return K.has(s)}async function P(s,e){s.runtimeConfigured||(await s.client.configureRuntime({codexProvider:e?{baseUrl:e.baseUrl,apiKey:e.apiKey,revision:e.revision}:null}),s.markRuntimeConfigured())}function R(s){return s?{OPENAI_API_KEY:s.apiKey,OPENAI_BASE_URL:s.baseUrl}:{}}function G(s,e){if(e?.aborted)return!0;const t=s instanceof Error?s.message:String(s||"");return/compact.*timed out|request timed out.*compact|adapter closed|aborted|cancelled/i.test(t)}function g(s){if(!s||typeof s!="object"||Array.isArray(s))return null;const e=s.sessionId;return typeof e=="string"&&e.trim()?e.trim():null}function l(s){return s&&typeof s=="object"&&!Array.isArray(s)?s:null}function w(s){const e=String(s||"").trim();return e?e==="read-only"?"read-only":["agent-full-access","full-access","bypassPermissions","danger-full-access"].includes(e)?"danger-full-access":"workspace-write":null}function S(s){const e=String(s||"").trim();return e?["agent-full-access","full-access","bypassPermissions","danger-full-access"].includes(e)?"never":e==="acceptEdits"||e==="accept-edits"?"on-failure":"on-request":null}function T(s){return{...s.model?{model:s.model}:{},...S(s.mode)?{approvalPolicy:S(s.mode)}:{},...w(s.mode)?{sandbox:w(s.mode)}:{},...s.configOptionValues??{}}}function Y(s){const e=s.params&&typeof s.params=="object"&&!Array.isArray(s.params)?s.params:s;for(const t of["command","cwd","reason","grantRoot","method"]){const o=e[t];if(typeof o=="string"&&o.trim())return M(o)}}function J(s){for(const e of["prompt","message","question","title"]){const t=s[e];if(typeof t=="string"&&t.trim())return M(t)}}function M(s){const e=s.replace(/\s+/g," ").trim();return e.length>120?`${e.slice(0,117)}...`:e}function Q(){const s=Number.parseInt(process.env.ACA_CODEX_ACP_PROMPT_TIMEOUT_MS??process.env.ACA_ACP_PROMPT_TIMEOUT_MS??"",10);return Number.isInteger(s)&&s>=3e4?s:360*60*1e3}function Z(s){const e=Number.isInteger(s)?Number(s):Number.parseInt(process.env.ACA_CODEX_ACP_COMPACT_TIMEOUT_MS??"",10);return Number.isFinite(e)&&e>=3e4?Math.min(e,6e5):12e4}function q(s){if(!s||typeof s!="object"||Array.isArray(s))return null;const e=s;return typeof e.sessionId=="string"&&e.sessionId.trim()?e.sessionId:null}function ee(s){const e=l(s),t=l(e?._meta);return U(t?.acaContextUsage)}function U(s){const e=l(s);if(!e)return null;const t=h(e.contextWindow),o=h(e.usedTokens),r=h(e.inputTokens),i=String(e.state||"unknown"),n=["active","compacted","new_thread"].includes(i)?i:"unknown";return{usedTokens:o,inputTokens:r,contextWindow:t,ratio:t>0?Math.max(0,h(e.ratio)||o/t):0,observedAtMs:h(e.observedAtMs)||Date.now(),state:n,maintenanceAction:typeof e.maintenanceAction=="string"?e.maintenanceAction:null}}function h(s){return typeof s=="number"&&Number.isFinite(s)&&s>=0?s:0}export{de as CodexAcpProvider,V as codexAcpCapabilities};
package/dist/version.js CHANGED
@@ -1 +1 @@
1
- const o="0.1.37";export{o as AICA_VERSION};
1
+ const o="0.1.39";export{o as AICA_VERSION};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yuandc/aica",
3
- "version": "0.1.37",
3
+ "version": "0.1.39",
4
4
  "description": "AICA remote Agent worker",
5
5
  "author": "yuandc",
6
6
  "type": "module",
@@ -26,7 +26,7 @@
26
26
  "worker"
27
27
  ],
28
28
  "dependencies": {
29
- "@openai/codex": "0.151.0",
29
+ "@openai/codex": "0.148.0",
30
30
  "chalk": "^5.4.1",
31
31
  "commander": "^12.1.0",
32
32
  "diff": "^9.0.0",