@openduo/duoduo 0.4.5 → 0.4.6
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/release/cli.js +796 -773
- package/dist/release/daemon.js +1 -1
- package/dist/release/feishu-gateway.js +48 -33
- package/dist/release/stdio.js +145 -122
- package/package.json +2 -1
package/dist/release/daemon.js
CHANGED
|
@@ -695,7 +695,7 @@ ${r.join(`
|
|
|
695
695
|
`)}`)}if(e.runtimeDirectives&&t.push(e.runtimeDirectives),t.length!==0)return["<aladuo:runtime-directives>",...t,"</aladuo:runtime-directives>"].join(`
|
|
696
696
|
`)}function Xve(e,t){let r={...jct,...e},i=null,n=!1;return{async run(s){let o;if(typeof s.prompt=="string")o=s.prompt;else{let H=[];for await(let Z of s.prompt)if(typeof Z.message.content=="string")H.push(Z.message.content);else if(Array.isArray(Z.message.content))for(let X of Z.message.content)X.type==="text"&&H.push(X.text);o=H.join(`
|
|
697
697
|
|
|
698
|
-
`)}if(!o.trim())return{text:"",usage:void 0};let a=s.cwd||process.cwd();if((!i||!i.isAlive)&&(i=new QZ(r.codexBinary,a,r.env),i.start(),n=!1),!n){if(await i.request("initialize",{clientInfo:{title:"duoduo-runtime",name:"duoduo",version:"0.1.0"},capabilities:{experimentalApi:!!r.dynamicTools?.length,optOutNotificationMethods:["item/reasoning/summaryTextDelta","item/reasoning/summaryPartAdded","item/reasoning/textDelta"]}},s.abortController?.signal),i.notify("initialized",{}),r.dynamicTools?.length){let H=new Map;for(let Z of r.dynamicTools)H.set(Z.name,Z.handler);i.setToolHandlers(H)}n=!0}let u=zct(s.systemPrompt),l=Mct(t??{},u),c=Lct(t??{}),d=Uct(s.permissionMode,r.sandbox);s.disallowedTools?.length&&Qe("[codex-adapter] disallowedTools ignored — Codex built-in tools cannot be disabled",{disallowedTools:s.disallowedTools});let p=!!s.sessionId,f=p?"thread/resume":"thread/start",m=s.persistSession!==void 0?!s.persistSession:r.ephemeral,h={cwd:a,model:r.model,approvalPolicy:"never",sandbox:d,...p?{threadId:s.sessionId}:{serviceName:r.serviceName,ephemeral:m,experimentalRawEvents:!1}};p||(l&&(h.baseInstructions=l),c&&(h.developerInstructions=c),h.persistExtendedHistory=!1,r.dynamicTools?.length&&(h.dynamicTools=r.dynamicTools.map(H=>({name:H.name,description:H.description,inputSchema:H.inputSchema}))));let b=(await i.request(f,h,s.abortController?.signal)).thread.id,v=[],g,S,E=Date.now(),k=!1,I,R,T=new Promise(H=>{R=H}),O=!1,A=new Promise((H,Z)=>{let X=Q=>{O||(O=!0,we(),Q())},ve=Q=>{if(O)return;let M=Q.params??{},Y=M.threadId,w=M.turnId;if(Y&&Y!==b||I&&w&&w!==I)return;let x=M.item;switch(Q.method){case"item/agentMessage/delta":{let N=M.delta??"";N&&(k||(S=Date.now()-E,k=!0),v.push(N),s.onStream?.(N));break}case"item/started":{if(!x)break;let N=Fct(x);N&&s.onExecutionEvent?.(N);break}case"item/completed":{if(!x)break;let N=qct(x);N&&s.onExecutionEvent?.(N);break}case"item/reasoning/summaryTextDelta":case"item/reasoning/textDelta":{let N=M.delta??"";N&&s.onExecutionEvent?.({type:"thought_chunk",text:N});break}case"thread/tokenUsage/updated":{let C=M.tokenUsage?.total;C&&(g={input_tokens:C.inputTokens,output_tokens:C.outputTokens,cache_read_input_tokens:C.cachedInputTokens});break}case"turn/completed":{let N=M.turn?.id;Y===b&&(!I||N===I)&&X(()=>H());break}case"error":{let N=M.error;X(()=>Z(new Error(N?.message??"codex app-server error notification")));break}}},we=()=>{i?.removeListener("notification",ve)};if(i.on("notification",ve),s.abortController){let Q=()=>{let M=new Promise((w,x)=>setTimeout(()=>x(new Error("turnId timeout on abort")),2e3));Promise.race([T,M]).then(w=>{i?.request("turn/interrupt",{threadId:b,turnId:w}).catch(()=>{})}).catch(()=>{});let Y=new Error("turn aborted");Y.name="AbortError",X(()=>Z(Y))};s.abortController.signal.addEventListener("abort",Q,{once:!0})}});I=(await i.request("turn/start",{threadId:b,input:[{type:"text",text:o,text_elements:[]}],model:r.model,effort:r.effort,outputSchema:s.outputFormat??null},s.abortController?.signal)).turn?.id,I&&R?.(I),s.abortController?.signal.aborted&&I&&i.request("turn/interrupt",{threadId:b,turnId:I}).catch(()=>{}),await A;let U=v.join("");return{sessionId:b,text:U||void 0,usage:g,firstTokenLatencyMs:S}},shutdown(){i?.shutdown(),i=null,n=!1}}}function Uct(e,t){switch(e){case"bypassPermissions":case"acceptEdits":case"dontAsk":return"workspace-write";case"plan":return"read-only";default:return t??"read-only"}}function Fct(e){let t=e.type,r=e.id;switch(t){case"commandExecution":return{type:"tool_use",toolUseId:r,toolName:"Bash",input:{command:e.command}};case"fileChange":return{type:"tool_use",toolUseId:r,toolName:"Write",input:{files:e.changes?.map(i=>i.path)}};case"mcpToolCall":return{type:"tool_use",toolUseId:r,toolName:`mcp__${e.server}__${e.tool}`,input:{}};case"dynamicToolCall":return{type:"tool_use",toolUseId:r,toolName:e.tool??"unknown",input:{}};case"agentMessage":return e.phase==="commentary"?{type:"system",subtype:"codex_commentary",data:{text:e.text}}:null;case"reasoning":return null;default:return null}}function qct(e){let t=e.type,r=e.id;switch(t){case"commandExecution":return{type:"tool_result",toolUseId:r,toolName:"Bash",isError:e.exitCode!==0,summary:`exit=${e.exitCode}`};case"fileChange":return{type:"tool_result",toolUseId:r,toolName:"Write",isError:!1,summary:`files=${JSON.stringify(e.changes?.map(i=>i.path))}`};case"mcpToolCall":return{type:"tool_result",toolUseId:r,toolName:`mcp__${e.server}__${e.tool}`,isError:e.status==="failed",summary:`status=${e.status}`};case"dynamicToolCall":return{type:"tool_result",toolUseId:r,toolName:e.tool??"unknown",isError:e.status==="failed",summary:`status=${e.status}`};default:return null}}var jct,QZ,YZ=q(()=>{"use strict";kr();jct={codexBinary:"codex",env:{},sandbox:"read-only",serviceName:"duoduo_runtime",model:null,effort:null,ephemeral:!0},QZ=class extends Dct{constructor(r,i,n){super();this.binary=r;this.cwd=i;this.env=n}proc=null;rl=null;stderrRl=null;nextId=1;pending=new Map;alive=!1;start(){this.alive||(this.proc=$ct(this.binary,["app-server"],{cwd:this.cwd,stdio:["pipe","pipe","pipe"],env:{...process.env,...this.env}}),this.alive=!0,this.proc.on("error",r=>{this.alive=!1;let i=r.code==="ENOENT"?new Error(`Codex CLI ('${this.binary}') not found. Install it from https://github.com/openai/codex and run 'codex login'.`):r;this.rejectAllPending(i),this.emit("error",i)}),this.proc.on("exit",(r,i)=>{this.alive=!1;let n=new Error(`codex app-server exited (code=${r} signal=${i})`);this.rejectAllPending(n),this.emit("exit",r,i)}),this.rl=Jve({input:this.proc.stdout}),this.rl.on("line",r=>this.handleLine(r)),this.stderrRl=Jve({input:this.proc.stderr}),this.stderrRl.on("line",r=>{Qe("[codex-stderr]",r)}))}request(r,i,n){if(!this.alive||!this.proc?.stdin?.writable)return Promise.reject(new Error("codex app-server is not running"));let s=this.nextId++;return new Promise((o,a)=>{if(this.pending.set(s,{method:r,resolve:o,reject:a}),this.send({id:s,method:r,params:i}),n){let u=()=>{let l=this.pending.get(s);l&&(this.pending.delete(s),l.reject(new Error(`request ${r} aborted`)))};n.addEventListener("abort",u,{once:!0})}})}notify(r,i={}){this.send({method:r,params:i})}shutdown(){this.alive=!1,this.rl?.close(),this.stderrRl?.close(),this.proc&&!this.proc.killed&&this.proc.kill("SIGTERM")}get isAlive(){return this.alive}send(r){this.proc?.stdin?.writable&&this.proc.stdin.write(JSON.stringify(r)+`
|
|
698
|
+
`)}if(!o.trim())return{text:"",usage:void 0};let a=s.cwd||process.cwd();if((!i||!i.isAlive)&&(i=new QZ(r.codexBinary,a,r.env),i.start(),n=!1),!n){if(await i.request("initialize",{clientInfo:{title:"duoduo-runtime",name:"duoduo",version:"0.1.0"},capabilities:{experimentalApi:!!r.dynamicTools?.length,optOutNotificationMethods:["item/reasoning/summaryTextDelta","item/reasoning/summaryPartAdded","item/reasoning/textDelta"]}},s.abortController?.signal),i.notify("initialized",{}),r.dynamicTools?.length){let H=new Map;for(let Z of r.dynamicTools)H.set(Z.name,Z.handler);i.setToolHandlers(H)}n=!0}let u=zct(s.systemPrompt),l=Mct(t??{},u),c=Lct(t??{}),d=Uct(s.permissionMode,r.sandbox);s.disallowedTools?.length&&Qe("[codex-adapter] disallowedTools ignored — Codex built-in tools cannot be disabled",{disallowedTools:s.disallowedTools});let p=!!s.sessionId,f=p?"thread/resume":"thread/start",m=s.persistSession!==void 0?!s.persistSession:r.ephemeral,h={cwd:a,model:r.model,approvalPolicy:"never",sandbox:d,...p?{threadId:s.sessionId}:{serviceName:r.serviceName,ephemeral:m,experimentalRawEvents:!1}};p||(l&&(h.baseInstructions=l),c&&(h.developerInstructions=c),h.persistExtendedHistory=!1,r.dynamicTools?.length&&(h.dynamicTools=r.dynamicTools.map(H=>({name:H.name,description:H.description,inputSchema:H.inputSchema}))));let b=(await i.request(f,h,s.abortController?.signal)).thread.id,v=[],g,S,E=Date.now(),k=!1,I,R,T=new Promise(H=>{R=H}),O=!1,A=new Promise((H,Z)=>{let X=Q=>{O||(O=!0,we(),Q())},ve=Q=>{if(O)return;let M=Q.params??{},Y=M.threadId,w=M.turnId;if(Y&&Y!==b||I&&w&&w!==I)return;let x=M.item;switch(Q.method){case"item/agentMessage/delta":{let N=M.delta??"";N&&(k||(S=Date.now()-E,k=!0),v.push(N),s.onStream?.(N));break}case"item/started":{if(!x)break;let N=Fct(x);N&&s.onExecutionEvent?.(N);break}case"item/completed":{if(!x)break;let N=qct(x);N&&s.onExecutionEvent?.(N);break}case"item/reasoning/summaryTextDelta":case"item/reasoning/textDelta":{let N=M.delta??"";N&&s.onExecutionEvent?.({type:"thought_chunk",text:N});break}case"thread/tokenUsage/updated":{let C=M.tokenUsage?.total;C&&(g={input_tokens:C.inputTokens,output_tokens:C.outputTokens,cache_read_input_tokens:C.cachedInputTokens});break}case"turn/completed":{let N=M.turn?.id;Y===b&&(!I||N===I)&&X(()=>H());break}case"error":{let N=M.error;X(()=>Z(new Error(N?.message??"codex app-server error notification")));break}}},we=()=>{i?.removeListener("notification",ve)};if(i.on("notification",ve),s.abortController){let Q=()=>{let M=new Promise((w,x)=>setTimeout(()=>x(new Error("turnId timeout on abort")),2e3));Promise.race([T,M]).then(w=>{i?.request("turn/interrupt",{threadId:b,turnId:w}).catch(()=>{})}).catch(()=>{});let Y=new Error("turn aborted");Y.name="AbortError",X(()=>Z(Y))};s.abortController.signal.addEventListener("abort",Q,{once:!0})}});I=(await i.request("turn/start",{threadId:b,input:[{type:"text",text:o,text_elements:[]}],model:r.model,effort:r.effort,outputSchema:s.outputFormat??null},s.abortController?.signal)).turn?.id,I&&R?.(I),s.abortController?.signal.aborted&&I&&i.request("turn/interrupt",{threadId:b,turnId:I}).catch(()=>{}),await A;let U=v.join("");return{sessionId:b,text:U||void 0,usage:g,firstTokenLatencyMs:S}},shutdown(){i?.shutdown(),i=null,n=!1}}}function Uct(e,t){switch(e){case"bypassPermissions":case"acceptEdits":case"dontAsk":return"workspace-write";case"plan":return"read-only";default:return t??"read-only"}}function Fct(e){let t=e.type,r=e.id;switch(t){case"commandExecution":return{type:"tool_use",toolUseId:r,toolName:"Bash",input:{command:e.command}};case"fileChange":return{type:"tool_use",toolUseId:r,toolName:"Write",input:{files:e.changes?.map(i=>i.path)}};case"mcpToolCall":return{type:"tool_use",toolUseId:r,toolName:`mcp__${e.server}__${e.tool}`,input:{}};case"dynamicToolCall":return{type:"tool_use",toolUseId:r,toolName:e.tool??"unknown",input:{}};case"agentMessage":return e.phase==="commentary"?{type:"system",subtype:"codex_commentary",data:{text:e.text}}:null;case"reasoning":return null;default:return null}}function qct(e){let t=e.type,r=e.id;switch(t){case"commandExecution":return{type:"tool_result",toolUseId:r,toolName:"Bash",isError:e.exitCode!==0,summary:`exit=${e.exitCode}`};case"fileChange":return{type:"tool_result",toolUseId:r,toolName:"Write",isError:!1,summary:`files=${JSON.stringify(e.changes?.map(i=>i.path))}`};case"mcpToolCall":return{type:"tool_result",toolUseId:r,toolName:`mcp__${e.server}__${e.tool}`,isError:e.status==="failed",summary:`status=${e.status}`};case"dynamicToolCall":return{type:"tool_result",toolUseId:r,toolName:e.tool??"unknown",isError:e.status==="failed",summary:`status=${e.status}`};default:return null}}var jct,QZ,YZ=q(()=>{"use strict";kr();jct={codexBinary:"codex",env:{},sandbox:"read-only",serviceName:"duoduo_runtime",model:null,effort:null,ephemeral:!0,dynamicTools:[]},QZ=class extends Dct{constructor(r,i,n){super();this.binary=r;this.cwd=i;this.env=n}proc=null;rl=null;stderrRl=null;nextId=1;pending=new Map;alive=!1;start(){this.alive||(this.proc=$ct(this.binary,["app-server"],{cwd:this.cwd,stdio:["pipe","pipe","pipe"],env:{...process.env,...this.env}}),this.alive=!0,this.proc.on("error",r=>{this.alive=!1;let i=r.code==="ENOENT"?new Error(`Codex CLI ('${this.binary}') not found. Install it from https://github.com/openai/codex and run 'codex login'.`):r;this.rejectAllPending(i),this.emit("error",i)}),this.proc.on("exit",(r,i)=>{this.alive=!1;let n=new Error(`codex app-server exited (code=${r} signal=${i})`);this.rejectAllPending(n),this.emit("exit",r,i)}),this.rl=Jve({input:this.proc.stdout}),this.rl.on("line",r=>this.handleLine(r)),this.stderrRl=Jve({input:this.proc.stderr}),this.stderrRl.on("line",r=>{Qe("[codex-stderr]",r)}))}request(r,i,n){if(!this.alive||!this.proc?.stdin?.writable)return Promise.reject(new Error("codex app-server is not running"));let s=this.nextId++;return new Promise((o,a)=>{if(this.pending.set(s,{method:r,resolve:o,reject:a}),this.send({id:s,method:r,params:i}),n){let u=()=>{let l=this.pending.get(s);l&&(this.pending.delete(s),l.reject(new Error(`request ${r} aborted`)))};n.addEventListener("abort",u,{once:!0})}})}notify(r,i={}){this.send({method:r,params:i})}shutdown(){this.alive=!1,this.rl?.close(),this.stderrRl?.close(),this.proc&&!this.proc.killed&&this.proc.kill("SIGTERM")}get isAlive(){return this.alive}send(r){this.proc?.stdin?.writable&&this.proc.stdin.write(JSON.stringify(r)+`
|
|
699
699
|
`)}handleLine(r){let i=r.trim();if(!i)return;let n;try{n=JSON.parse(i)}catch{Qe("[codex-transport] unparseable line:",i.slice(0,200));return}if(n.id!=null&&(n.result!==void 0||n.error!==void 0)){let s=this.pending.get(n.id);s&&(this.pending.delete(n.id),n.error?s.reject(Object.assign(new Error(n.error.message||`codex rpc error: ${s.method}`),{code:n.error.code,data:n.error.data})):s.resolve(n.result??{}));return}if(n.method&&n.id!=null){this.handleServerRequest(n);return}n.method&&this.emit("notification",n)}setToolHandlers(r){this.toolHandlers=r}toolHandlers=new Map;handleServerRequest(r){if(Qe("[codex-transport] server request:",r.method),r.method==="item/tool/call"){let i=r.params,n=i?.tool,s=i?.arguments??{},o=n?this.toolHandlers.get(n):void 0;if(o){o(s).then(a=>{this.respond(r.id,{success:a.success,contentItems:[{type:"inputText",text:a.text}]})}).catch(a=>{this.respond(r.id,{success:!1,contentItems:[{type:"inputText",text:`Error: ${a instanceof Error?a.message:String(a)}`}]})});return}}if(r.method==="mcpServer/elicitation/request"){this.respond(r.id,{action:"accept"});return}if(r.method?.includes("Approval")||r.method?.includes("approval")){this.respond(r.id,{decision:"approve"});return}this.respondError(r.id,-32601,`duoduo adapter does not handle ${r.method}`)}respond(r,i){this.proc?.stdin?.writable&&this.proc.stdin.write(JSON.stringify({id:r,result:i})+`
|
|
700
700
|
`)}respondError(r,i,n){this.proc?.stdin?.writable&&this.proc.stdin.write(JSON.stringify({id:r,error:{code:i,message:n}})+`
|
|
701
701
|
`)}rejectAllPending(r){for(let[i,n]of this.pending)n.reject(r),this.pending.delete(i)}}});function LO(){return Ou()?ebe+`
|