@zibby/core 0.5.18 → 0.5.19
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/index.js
CHANGED
|
@@ -80,7 +80,7 @@ This usually means the binary is not in PATH. Try:
|
|
|
80
80
|
`),stringified:(()=>{try{return JSON.stringify(x,Object.getOwnPropertyNames(Object(x)))}catch{return String(x)}})()};throw p.error(`Error during query stream: ${x?.message||x}`,L),x}}catch($){throw p.error("Claude Agent SDK call failed",{message:$?.message,name:$?.name,code:$?.code,cause:$?.cause?.message||$?.cause}),$}}finally{for(let S of E)S.dispose()}}_resolveSkills(e,t){let r=["Read","Write","Edit","Bash","Grep","Glob"];if(e===null)return p.debug("No skills \u2014 pure LLM mode"),{allowedTools:[],mcpServers:{}};if(!Array.isArray(e)||e.length===0)return p.debug("Default IDE skills for code generation"),{allowedTools:[...r],mcpServers:{}};let n=[...r],o={},i=process.env.WORKFLOW_ENABLED_INTEGRATIONS,c=typeof i=="string"&&i.trim()!==""?new Set(i.split(",").map(a=>a.trim()).filter(Boolean)):null,l=a=>c!==null&&c.size>0&&Bn.includes(a)&&!c.has(a);for(let a of e){if(l(a)){p.debug(`Skill "${a}" disabled by enabledIntegrations allowlist \u2014 skipping`);continue}let u=Fn(a);if(!u){p.warn(`Unknown skill "${a}" \u2014 skipping`);continue}if(u.allowedTools&&n.push(...u.allowedTools),typeof u.resolve=="function"){let d=u.resolve(t);d&&(o[u.serverName]=d,p.debug(`MCP: ${u.serverName} \u2192 ${d.command} ${d.args[0]}`))}}return{allowedTools:n,mcpServers:o}}_extractJson(e,t){let r=[()=>{if(e.includes("===JSON_START===")){let n=e.indexOf("===JSON_START===")+16,o=e.indexOf("===JSON_END===");return e.substring(n,o).trim()}},()=>e.match(/```json\s*\n([\s\S]*?)\n```/)?.[1]?.trim(),()=>{if(!e.startsWith("{"))return e.match(/```\s*\n([\s\S]*?)\n```/)?.[1]?.trim()},()=>e.trim(),()=>{let n=e.indexOf("{"),o=e.lastIndexOf("}");if(n!==-1&&o>n)return e.substring(n,o+1)}];for(let n of r)try{let o=n();if(!o)continue;let i=JSON.parse(o);if(typeof i!="object"||i===null)continue;return typeof t.parse=="function"?t.parse(i):i}catch{}return null}};function Kn({message:s,sessionPath:e,nodeName:t,model:r,toolCallCount:n}){if(!e||!t)return;let o=s?.usage||s?.message?.usage||{},i=De(o.input_tokens,o.inputTokens),c=De(o.output_tokens,o.outputTokens),l=De(o.cache_read_input_tokens,o.cacheReadInputTokens),a=De(o.cache_creation_input_tokens,o.cacheCreationInputTokens),u=De(s?.duration_ms,s?.durationMs),d={model:r||null,input_tokens:i,output_tokens:c,cache_read_tokens:l,cache_creation_tokens:a,tool_call_count:typeof n=="number"?n:null,duration_ms:u,captured_at:new Date().toISOString()},m=ge(e,t);try{mt(m,{recursive:!0})}catch{}dt(ge(m,"usage.json"),JSON.stringify(d,null,2),"utf-8")}function De(...s){for(let e of s){if(typeof e=="number"&&Number.isFinite(e))return e;if(typeof e=="string"&&e.trim()!==""&&!isNaN(Number(e)))return Number(e)}return null}function Jn(s,e){let t=ge(ir(),".claude"),r=ge(t,".credentials.json"),n={claudeAiOauth:{accessToken:s,refreshToken:"",expiresAt:Date.now()+365*24*60*60*1e3,scopes:["user:inference","user:profile"],...e?{subscriptionType:String(e).toLowerCase()}:{}}};try{if(or(r)&&JSON.parse(sr(r,"utf-8"))?.claudeAiOauth?.accessToken===s)return;mt(t,{recursive:!0}),dt(r,JSON.stringify(n,null,2),"utf-8"),p.debug(`Wrote Claude Code OAuth credentials to ${r}`)}catch(o){p.warn(`Could not write ${r}: ${o.message} \u2014 Claude SDK may fail to authenticate.`)}}function zn(s){let e=ge(ir(),".claude"),t=ge(e,".credentials.json"),r;try{r=JSON.parse(s)}catch(n){p.warn(`CLAUDE_CODE_CREDENTIALS_JSON not valid JSON: ${n.message}`);return}if(!r?.claudeAiOauth?.accessToken){p.warn("CLAUDE_CODE_CREDENTIALS_JSON missing claudeAiOauth.accessToken \u2014 skipping write.");return}try{if(or(t)){let n=JSON.parse(sr(t,"utf-8"));if(n?.claudeAiOauth?.accessToken===r.claudeAiOauth.accessToken&&n?.claudeAiOauth?.expiresAt===r.claudeAiOauth.expiresAt)return}mt(e,{recursive:!0}),dt(t,JSON.stringify(r,null,2),"utf-8"),p.debug(`Wrote full Claude Code credentials blob to ${t}`)}catch(n){p.warn(`Could not write ${t}: ${n.message} \u2014 Claude SDK may fail to authenticate.`)}}Me();import{AgentStrategy as Yn,getSkill as Hn}from"@zibby/agent-workflow";import{execSync as Wn}from"node:child_process";var se=class extends Yn{constructor(){super("codex","Codex (OpenAI)",75)}canHandle(e){if(!!!(process.env.OPENAI_API_KEY||process.env.OPENAI_API_KEY_POOL||process.env.CODEX_API_KEY||process.env.CODEX_API_KEY_POOL))return p.debug("CodexAgentStrategy: OPENAI_API_KEY or CODEX_API_KEY not set"),!1;try{return Wn("codex --version",{encoding:"utf-8",timeout:5e3,stdio:"pipe"}),!0}catch{return p.warn("[Codex] codex CLI not found. Install: npm install -g @openai/codex"),!1}}async invoke(e,t={}){let{model:r,workspace:n=process.cwd(),schema:o=null,skills:i=null,sessionPath:c=null,nodeName:l=null,timeout:a,config:u={},signal:d=null}=t,m=[Y("OPENAI_API_KEY"),Y("CODEX_API_KEY")];try{let{Codex:f}=await import("@openai/codex-sdk"),g=r;(!g||g==="auto")&&(p.debug(`Model is '${g||"undefined"}', using default: ${J.CODEX}`),g=J.CODEX);let y=Xe[g]||g;Xe[g]&&g!==y&&p.debug(`Mapped model: ${g} \u2192 ${y}`),p.debug(`Invoking Codex SDK with model: ${y}, skills: ${JSON.stringify(i)}`);let h=process.env.CODEX_API_KEY||process.env.OPENAI_API_KEY;h&&!process.env.CODEX_API_KEY&&(process.env.CODEX_API_KEY=h);let b=h?` | key: ***${h.slice(-4)}`:" | key: not set";console.log(`
|
|
81
81
|
\u25C6 Model: ${y}${b}
|
|
82
82
|
`);let w=(await import("chalk")).default;console.log(`
|
|
83
|
-
${w.bold("Prompt sent to LLM:")}`),console.log(w.dim("\u2500".repeat(60))),console.log(w.dim(e)),console.log(w.dim("\u2500".repeat(60)));let E=this._resolveSkillsToMcp(i,{sessionPath:c,workspace:n,nodeName:l}),S={};Object.keys(E).length>0&&(S.mcp_servers=E,p.debug(`[Codex] MCP servers: ${Object.keys(E).join(", ")}`));let C=new f({...Object.keys(S).length>0&&{config:S}}).startThread({workingDirectory:n,skipGitRepoCheck:!0,approvalPolicy:"never",sandboxMode:"danger-full-access",networkAccessEnabled:!0}),I=o&&typeof o.parse=="function",T={};if(o)try{let P=I?ne(o,{target:"openAi"}):o;T.outputSchema=P,p.debug("Structured output via SDK outputSchema")}catch(P){p.warn(`[Codex] Schema conversion failed, will extract from text: ${P.message}`)}if(d?.aborted){let P=new Error("Aborted via signal");throw P.name="AbortError",P}try{let{events:P}=await C.runStreamed(e,T),D=0,v="";for await(let k of P){if(d?.aborted){let N=new Error("Aborted via signal");throw N.name="AbortError",N}let $=k.type;if($==="item.completed"){let N=k.item,B=N?.type;if(B==="mcp_tool_call"){D++;let R=`${N.server}/${N.tool}`;if(Z.stepTool(`Tool: ${R}`),N.arguments){let _=JSON.stringify(N.arguments),M=_.length>100?`${_.substring(0,100)}...`:_;console.log(` Input: ${M}`)}}else if(B==="tool_call"||B==="function_call"||B==="command_execution"){D++;let R=N.name||N.tool||N.command||"unknown";Z.stepTool(`Tool: ${R}`)}else B==="agent_message"&&(v=N.text||"",v.length<500?console.log(v):console.log(`${v.substring(0,200)}... (${v.length} chars)`))}else $==="turn.completed"?p.debug(`[Codex] Turn completed. Usage: ${JSON.stringify(k.usage||{})}`):p.debug(`[Codex] Event: ${$} ${JSON.stringify(k).slice(0,300)}`)}if(p.debug(`[Codex] Last agent message (${v.length} chars): ${v.slice(0,500)}`),o){if(!v)throw new Error("Codex agent returned no response");let k=JSON.parse(v),$=I?o.parse(k):k;return p.debug("\u2705 [Codex] Structured output validated"),{raw:v,structured:$}}return v||""}catch(P){let D=P.message||String(P);throw p.error(`\u274C [Codex] SDK call failed: ${D}`),D.includes("exited with code")&&(p.error("\u{1F4A1} [Codex] Verify: codex --version && echo $OPENAI_API_KEY"),p.error("\u{1F4A1} [Codex] If codex is missing: npm install -g @openai/codex")),P}}finally{for(let f of m)f.dispose()}}_resolveSkillsToMcp(e,t={}){if(!Array.isArray(e)||e.length===0)return{};let r={};for(let n of e){let o=Hn(n);if(!o){p.warn(`[Codex] Unknown skill "${n}" \u2014 skipping`);continue}if(typeof o.resolve!="function")continue;let i=o.resolve(t);if(!i)continue;let c=o.serverName||n,l={command:i.command};i.args?.length&&(l.args=i.args),
|
|
83
|
+
${w.bold("Prompt sent to LLM:")}`),console.log(w.dim("\u2500".repeat(60))),console.log(w.dim(e)),console.log(w.dim("\u2500".repeat(60)));let E=this._resolveSkillsToMcp(i,{sessionPath:c,workspace:n,nodeName:l}),S={};Object.keys(E).length>0&&(S.mcp_servers=E,p.debug(`[Codex] MCP servers: ${Object.keys(E).join(", ")}`));let C=new f({...Object.keys(S).length>0&&{config:S}}).startThread({workingDirectory:n,skipGitRepoCheck:!0,approvalPolicy:"never",sandboxMode:"danger-full-access",networkAccessEnabled:!0}),I=o&&typeof o.parse=="function",T={};if(o)try{let P=I?ne(o,{target:"openAi"}):o;T.outputSchema=P,p.debug("Structured output via SDK outputSchema")}catch(P){p.warn(`[Codex] Schema conversion failed, will extract from text: ${P.message}`)}if(d?.aborted){let P=new Error("Aborted via signal");throw P.name="AbortError",P}try{let{events:P}=await C.runStreamed(e,T),D=0,v="";for await(let k of P){if(d?.aborted){let N=new Error("Aborted via signal");throw N.name="AbortError",N}let $=k.type;if($==="item.completed"){let N=k.item,B=N?.type;if(B==="mcp_tool_call"){D++;let R=`${N.server}/${N.tool}`;if(Z.stepTool(`Tool: ${R}`),N.arguments){let _=JSON.stringify(N.arguments),M=_.length>100?`${_.substring(0,100)}...`:_;console.log(` Input: ${M}`)}}else if(B==="tool_call"||B==="function_call"||B==="command_execution"){D++;let R=N.name||N.tool||N.command||"unknown";Z.stepTool(`Tool: ${R}`)}else B==="agent_message"&&(v=N.text||"",v.length<500?console.log(v):console.log(`${v.substring(0,200)}... (${v.length} chars)`))}else $==="turn.completed"?p.debug(`[Codex] Turn completed. Usage: ${JSON.stringify(k.usage||{})}`):p.debug(`[Codex] Event: ${$} ${JSON.stringify(k).slice(0,300)}`)}if(p.debug(`[Codex] Last agent message (${v.length} chars): ${v.slice(0,500)}`),o){if(!v)throw new Error("Codex agent returned no response");let k=JSON.parse(v),$=I?o.parse(k):k;return p.debug("\u2705 [Codex] Structured output validated"),{raw:v,structured:$}}return v||""}catch(P){let D=P.message||String(P);throw p.error(`\u274C [Codex] SDK call failed: ${D}`),D.includes("exited with code")&&(p.error("\u{1F4A1} [Codex] Verify: codex --version && echo $OPENAI_API_KEY"),p.error("\u{1F4A1} [Codex] If codex is missing: npm install -g @openai/codex")),P}}finally{for(let f of m)f.dispose()}}_resolveSkillsToMcp(e,t={}){if(!Array.isArray(e)||e.length===0)return{};let r={};for(let n of e){let o=Hn(n);if(!o){p.warn(`[Codex] Unknown skill "${n}" \u2014 skipping`);continue}if(typeof o.resolve!="function")continue;let i=o.resolve(t);if(!i)continue;let c=o.serverName||n,l={command:i.command};i.args?.length&&(l.args=i.args),l.env={...process.env,...i.env||{}},r[c]=l,p.debug(`[Codex] MCP: ${c} \u2192 ${i.command} ${(i.args||[]).join(" ")}`)}return r}};Me();import{AgentStrategy as Vn,getSkill as Zn}from"@zibby/agent-workflow";import{execSync as Xn,spawn as qn}from"node:child_process";import{existsSync as ar,mkdirSync as lr,readFileSync as cr,rmSync as Qn,writeFileSync as ur}from"node:fs";import{join as ie}from"node:path";function eo(s){if(!s)return null;let e=String(s),t=e.match(/```(?:json)?\s*([\s\S]*?)```/i);if(t?.[1])try{return JSON.parse(t[1].trim())}catch{}let r=e.indexOf("{");if(r<0)return null;let n=0,o=!1,i=!1,c=-1;for(let l=r;l<e.length;l++){let a=e[l];if(o){i?i=!1:a==="\\"?i=!0:a==='"'&&(o=!1);continue}if(a==='"'){o=!0;continue}if(a==="{"){n===0&&(c=l),n+=1;continue}if(a==="}"){if(n===0)continue;if(n-=1,n===0&&c>=0){let u=e.slice(c,l+1);try{return JSON.parse(u)}catch{c=-1}}}}return null}function to(s){let e=String(s||"").trim();if(!e)return null;try{return JSON.parse(e)}catch{return eo(e)}}function ro(s){try{let e=JSON.parse(s);if(typeof e=="string")return e;if(typeof e?.response=="string")return e.response;if(typeof e?.text=="string")return e.text;if(typeof e?.output=="string")return e.output;if(Array.isArray(e?.candidates)&&e.candidates.length>0){let t=e.candidates[0];if(typeof t?.content=="string")return t.content;if(Array.isArray(t?.content?.parts)){let r=t.content.parts.map(n=>typeof n?.text=="string"?n.text:"").join("");if(r.trim())return r}}}catch{}return s}var ae=class extends Vn{constructor(){super("gemini","Gemini (Google)",70)}canHandle(e){if(!!!(process.env.GEMINI_API_KEY||process.env.GEMINI_API_KEY_POOL||process.env.GOOGLE_API_KEY||process.env.GOOGLE_API_KEY_POOL))return p.debug("GeminiAgentStrategy: GEMINI_API_KEY or GOOGLE_API_KEY not set"),!1;try{return Xn("gemini --version",{encoding:"utf-8",timeout:5e3,stdio:"pipe"}),!0}catch{return p.warn("[Gemini] gemini CLI not found. Install: npm install -g @google/gemini-cli"),!1}}async invoke(e,t={}){let{model:r,workspace:n=process.cwd(),schema:o=null,skills:i=null,sessionPath:c=null,nodeName:l=null,timeout:a=600*1e3,signal:u=null}=t,d=[Y("GEMINI_API_KEY"),Y("GOOGLE_API_KEY")];try{let m=r;(!m||m==="auto")&&(m=J.GEMINI);let f=pt[m]||m,g=String(process.env.GEMINI_API_KEY||"").trim(),y=String(process.env.GOOGLE_API_KEY||"").trim(),h=this._resolveSkillsToMcp(i,{sessionPath:c,workspace:n,nodeName:l}),b=Object.keys(h).length>0,w=new de(e),E=o&&typeof o.parse=="function",S=null;if(o){let A;try{let x=E?ne(o,{target:"openAi"}):o;A=JSON.stringify(x,null,2)}catch{A="{}"}if(b){w.addSystemInstruction(`Write valid JSON that matches this schema:
|
|
84
84
|
${A}`,"schema_instruction","append");let x=`zibby-result-${Date.now()}.json`,L=ie(n,".zibby","tmp");S=ie(L,x),lr(L,{recursive:!0}),w.addStructuredOutput(o,S)}else w.addSystemInstruction(`Return ONLY valid JSON (no markdown, no commentary) that matches this schema:
|
|
85
85
|
${A}`,"json_instruction","append")}let O=w.build(),C=w.getUserPrompt(),I=w.getStats(),T=String(process.env.GEMINI_API_KEY||process.env.GOOGLE_API_KEY||"").trim(),P=T?` | key: ***${T.slice(-4)}`:" | key: not set";console.log(`
|
|
86
86
|
\u25C6 Model: ${f||"auto"}${P}
|
package/dist/package.json
CHANGED
|
@@ -80,7 +80,7 @@ This usually means the binary is not in PATH. Try:
|
|
|
80
80
|
`),stringified:(()=>{try{return JSON.stringify(p,Object.getOwnPropertyNames(Object(p)))}catch{return String(p)}})()};throw l.error(`Error during query stream: ${p?.message||p}`,$),p}}catch(k){throw l.error("Claude Agent SDK call failed",{message:k?.message,name:k?.name,code:k?.code,cause:k?.cause?.message||k?.cause}),k}}finally{for(let m of L)m.dispose()}}_resolveSkills(e,t){let n=["Read","Write","Edit","Bash","Grep","Glob"];if(e===null)return l.debug("No skills \u2014 pure LLM mode"),{allowedTools:[],mcpServers:{}};if(!Array.isArray(e)||e.length===0)return l.debug("Default IDE skills for code generation"),{allowedTools:[...n],mcpServers:{}};let o=[...n],r={},i=process.env.WORKFLOW_ENABLED_INTEGRATIONS,a=typeof i=="string"&&i.trim()!==""?new Set(i.split(",").map(d=>d.trim()).filter(Boolean)):null,c=d=>a!==null&&a.size>0&&Qt.includes(d)&&!a.has(d);for(let d of e){if(c(d)){l.debug(`Skill "${d}" disabled by enabledIntegrations allowlist \u2014 skipping`);continue}let u=qt(d);if(!u){l.warn(`Unknown skill "${d}" \u2014 skipping`);continue}if(u.allowedTools&&o.push(...u.allowedTools),typeof u.resolve=="function"){let h=u.resolve(t);h&&(r[u.serverName]=h,l.debug(`MCP: ${u.serverName} \u2192 ${h.command} ${h.args[0]}`))}}return{allowedTools:o,mcpServers:r}}_extractJson(e,t){let n=[()=>{if(e.includes("===JSON_START===")){let o=e.indexOf("===JSON_START===")+16,r=e.indexOf("===JSON_END===");return e.substring(o,r).trim()}},()=>e.match(/```json\s*\n([\s\S]*?)\n```/)?.[1]?.trim(),()=>{if(!e.startsWith("{"))return e.match(/```\s*\n([\s\S]*?)\n```/)?.[1]?.trim()},()=>e.trim(),()=>{let o=e.indexOf("{"),r=e.lastIndexOf("}");if(o!==-1&&r>o)return e.substring(o,r+1)}];for(let o of n)try{let r=o();if(!r)continue;let i=JSON.parse(r);if(typeof i!="object"||i===null)continue;return typeof t.parse=="function"?t.parse(i):i}catch{}return null}};function to({message:s,sessionPath:e,nodeName:t,model:n,toolCallCount:o}){if(!e||!t)return;let r=s?.usage||s?.message?.usage||{},i=pe(r.input_tokens,r.inputTokens),a=pe(r.output_tokens,r.outputTokens),c=pe(r.cache_read_input_tokens,r.cacheReadInputTokens),d=pe(r.cache_creation_input_tokens,r.cacheCreationInputTokens),u=pe(s?.duration_ms,s?.durationMs),h={model:n||null,input_tokens:i,output_tokens:a,cache_read_tokens:c,cache_creation_tokens:d,tool_call_count:typeof o=="number"?o:null,duration_ms:u,captured_at:new Date().toISOString()},g=oe(e,t);try{Ke(g,{recursive:!0})}catch{}Ue(oe(g,"usage.json"),JSON.stringify(h,null,2),"utf-8")}function pe(...s){for(let e of s){if(typeof e=="number"&&Number.isFinite(e))return e;if(typeof e=="string"&&e.trim()!==""&&!isNaN(Number(e)))return Number(e)}return null}function oo(s,e){let t=oe(ct(),".claude"),n=oe(t,".credentials.json"),o={claudeAiOauth:{accessToken:s,refreshToken:"",expiresAt:Date.now()+365*24*60*60*1e3,scopes:["user:inference","user:profile"],...e?{subscriptionType:String(e).toLowerCase()}:{}}};try{if(lt(n)&&JSON.parse(at(n,"utf-8"))?.claudeAiOauth?.accessToken===s)return;Ke(t,{recursive:!0}),Ue(n,JSON.stringify(o,null,2),"utf-8"),l.debug(`Wrote Claude Code OAuth credentials to ${n}`)}catch(r){l.warn(`Could not write ${n}: ${r.message} \u2014 Claude SDK may fail to authenticate.`)}}function no(s){let e=oe(ct(),".claude"),t=oe(e,".credentials.json"),n;try{n=JSON.parse(s)}catch(o){l.warn(`CLAUDE_CODE_CREDENTIALS_JSON not valid JSON: ${o.message}`);return}if(!n?.claudeAiOauth?.accessToken){l.warn("CLAUDE_CODE_CREDENTIALS_JSON missing claudeAiOauth.accessToken \u2014 skipping write.");return}try{if(lt(t)){let o=JSON.parse(at(t,"utf-8"));if(o?.claudeAiOauth?.accessToken===n.claudeAiOauth.accessToken&&o?.claudeAiOauth?.expiresAt===n.claudeAiOauth.expiresAt)return}Ke(e,{recursive:!0}),Ue(t,JSON.stringify(n,null,2),"utf-8"),l.debug(`Wrote full Claude Code credentials blob to ${t}`)}catch(o){l.warn(`Could not write ${t}: ${o.message} \u2014 Claude SDK may fail to authenticate.`)}}fe();import{AgentStrategy as ro,getSkill as so}from"@zibby/agent-workflow";import{execSync as io}from"node:child_process";var Ae=class extends ro{constructor(){super("codex","Codex (OpenAI)",75)}canHandle(e){if(!!!(process.env.OPENAI_API_KEY||process.env.OPENAI_API_KEY_POOL||process.env.CODEX_API_KEY||process.env.CODEX_API_KEY_POOL))return l.debug("CodexAgentStrategy: OPENAI_API_KEY or CODEX_API_KEY not set"),!1;try{return io("codex --version",{encoding:"utf-8",timeout:5e3,stdio:"pipe"}),!0}catch{return l.warn("[Codex] codex CLI not found. Install: npm install -g @openai/codex"),!1}}async invoke(e,t={}){let{model:n,workspace:o=process.cwd(),schema:r=null,skills:i=null,sessionPath:a=null,nodeName:c=null,timeout:d,config:u={},signal:h=null}=t,g=[F("OPENAI_API_KEY"),F("CODEX_API_KEY")];try{let{Codex:S}=await import("@openai/codex-sdk"),E=n;(!E||E==="auto")&&(l.debug(`Model is '${E||"undefined"}', using default: ${j.CODEX}`),E=j.CODEX);let U=Le[E]||E;Le[E]&&E!==U&&l.debug(`Mapped model: ${E} \u2192 ${U}`),l.debug(`Invoking Codex SDK with model: ${U}, skills: ${JSON.stringify(i)}`);let _=process.env.CODEX_API_KEY||process.env.OPENAI_API_KEY;_&&!process.env.CODEX_API_KEY&&(process.env.CODEX_API_KEY=_);let b=_?` | key: ***${_.slice(-4)}`:" | key: not set";console.log(`
|
|
81
81
|
\u25C6 Model: ${U}${b}
|
|
82
82
|
`);let w=(await import("chalk")).default;console.log(`
|
|
83
|
-
${w.bold("Prompt sent to LLM:")}`),console.log(w.dim("\u2500".repeat(60))),console.log(w.dim(e)),console.log(w.dim("\u2500".repeat(60)));let L=this._resolveSkillsToMcp(i,{sessionPath:a,workspace:o,nodeName:c}),m={};Object.keys(L).length>0&&(m.mcp_servers=L,l.debug(`[Codex] MCP servers: ${Object.keys(L).join(", ")}`));let B=new S({...Object.keys(m).length>0&&{config:m}}).startThread({workingDirectory:o,skipGitRepoCheck:!0,approvalPolicy:"never",sandboxMode:"danger-full-access",networkAccessEnabled:!0}),M=r&&typeof r.parse=="function",O={};if(r)try{let T=M?Z(r,{target:"openAi"}):r;O.outputSchema=T,l.debug("Structured output via SDK outputSchema")}catch(T){l.warn(`[Codex] Schema conversion failed, will extract from text: ${T.message}`)}if(h?.aborted){let T=new Error("Aborted via signal");throw T.name="AbortError",T}try{let{events:T}=await B.runStreamed(e,O),N=0,A="";for await(let C of T){if(h?.aborted){let P=new Error("Aborted via signal");throw P.name="AbortError",P}let k=C.type;if(k==="item.completed"){let P=C.item,G=P?.type;if(G==="mcp_tool_call"){N++;let v=`${P.server}/${P.tool}`;if(H.stepTool(`Tool: ${v}`),P.arguments){let f=JSON.stringify(P.arguments),R=f.length>100?`${f.substring(0,100)}...`:f;console.log(` Input: ${R}`)}}else if(G==="tool_call"||G==="function_call"||G==="command_execution"){N++;let v=P.name||P.tool||P.command||"unknown";H.stepTool(`Tool: ${v}`)}else G==="agent_message"&&(A=P.text||"",A.length<500?console.log(A):console.log(`${A.substring(0,200)}... (${A.length} chars)`))}else k==="turn.completed"?l.debug(`[Codex] Turn completed. Usage: ${JSON.stringify(C.usage||{})}`):l.debug(`[Codex] Event: ${k} ${JSON.stringify(C).slice(0,300)}`)}if(l.debug(`[Codex] Last agent message (${A.length} chars): ${A.slice(0,500)}`),r){if(!A)throw new Error("Codex agent returned no response");let C=JSON.parse(A),k=M?r.parse(C):C;return l.debug("\u2705 [Codex] Structured output validated"),{raw:A,structured:k}}return A||""}catch(T){let N=T.message||String(T);throw l.error(`\u274C [Codex] SDK call failed: ${N}`),N.includes("exited with code")&&(l.error("\u{1F4A1} [Codex] Verify: codex --version && echo $OPENAI_API_KEY"),l.error("\u{1F4A1} [Codex] If codex is missing: npm install -g @openai/codex")),T}}finally{for(let S of g)S.dispose()}}_resolveSkillsToMcp(e,t={}){if(!Array.isArray(e)||e.length===0)return{};let n={};for(let o of e){let r=so(o);if(!r){l.warn(`[Codex] Unknown skill "${o}" \u2014 skipping`);continue}if(typeof r.resolve!="function")continue;let i=r.resolve(t);if(!i)continue;let a=r.serverName||o,c={command:i.command};i.args?.length&&(c.args=i.args),
|
|
83
|
+
${w.bold("Prompt sent to LLM:")}`),console.log(w.dim("\u2500".repeat(60))),console.log(w.dim(e)),console.log(w.dim("\u2500".repeat(60)));let L=this._resolveSkillsToMcp(i,{sessionPath:a,workspace:o,nodeName:c}),m={};Object.keys(L).length>0&&(m.mcp_servers=L,l.debug(`[Codex] MCP servers: ${Object.keys(L).join(", ")}`));let B=new S({...Object.keys(m).length>0&&{config:m}}).startThread({workingDirectory:o,skipGitRepoCheck:!0,approvalPolicy:"never",sandboxMode:"danger-full-access",networkAccessEnabled:!0}),M=r&&typeof r.parse=="function",O={};if(r)try{let T=M?Z(r,{target:"openAi"}):r;O.outputSchema=T,l.debug("Structured output via SDK outputSchema")}catch(T){l.warn(`[Codex] Schema conversion failed, will extract from text: ${T.message}`)}if(h?.aborted){let T=new Error("Aborted via signal");throw T.name="AbortError",T}try{let{events:T}=await B.runStreamed(e,O),N=0,A="";for await(let C of T){if(h?.aborted){let P=new Error("Aborted via signal");throw P.name="AbortError",P}let k=C.type;if(k==="item.completed"){let P=C.item,G=P?.type;if(G==="mcp_tool_call"){N++;let v=`${P.server}/${P.tool}`;if(H.stepTool(`Tool: ${v}`),P.arguments){let f=JSON.stringify(P.arguments),R=f.length>100?`${f.substring(0,100)}...`:f;console.log(` Input: ${R}`)}}else if(G==="tool_call"||G==="function_call"||G==="command_execution"){N++;let v=P.name||P.tool||P.command||"unknown";H.stepTool(`Tool: ${v}`)}else G==="agent_message"&&(A=P.text||"",A.length<500?console.log(A):console.log(`${A.substring(0,200)}... (${A.length} chars)`))}else k==="turn.completed"?l.debug(`[Codex] Turn completed. Usage: ${JSON.stringify(C.usage||{})}`):l.debug(`[Codex] Event: ${k} ${JSON.stringify(C).slice(0,300)}`)}if(l.debug(`[Codex] Last agent message (${A.length} chars): ${A.slice(0,500)}`),r){if(!A)throw new Error("Codex agent returned no response");let C=JSON.parse(A),k=M?r.parse(C):C;return l.debug("\u2705 [Codex] Structured output validated"),{raw:A,structured:k}}return A||""}catch(T){let N=T.message||String(T);throw l.error(`\u274C [Codex] SDK call failed: ${N}`),N.includes("exited with code")&&(l.error("\u{1F4A1} [Codex] Verify: codex --version && echo $OPENAI_API_KEY"),l.error("\u{1F4A1} [Codex] If codex is missing: npm install -g @openai/codex")),T}}finally{for(let S of g)S.dispose()}}_resolveSkillsToMcp(e,t={}){if(!Array.isArray(e)||e.length===0)return{};let n={};for(let o of e){let r=so(o);if(!r){l.warn(`[Codex] Unknown skill "${o}" \u2014 skipping`);continue}if(typeof r.resolve!="function")continue;let i=r.resolve(t);if(!i)continue;let a=r.serverName||o,c={command:i.command};i.args?.length&&(c.args=i.args),c.env={...process.env,...i.env||{}},n[a]=c,l.debug(`[Codex] MCP: ${a} \u2192 ${i.command} ${(i.args||[]).join(" ")}`)}return n}};fe();import{AgentStrategy as lo,getSkill as ao}from"@zibby/agent-workflow";import{execSync as co,spawn as uo}from"node:child_process";import{existsSync as ut,mkdirSync as dt,readFileSync as ft,rmSync as fo,writeFileSync as pt}from"node:fs";import{join as q}from"node:path";function po(s){if(!s)return null;let e=String(s),t=e.match(/```(?:json)?\s*([\s\S]*?)```/i);if(t?.[1])try{return JSON.parse(t[1].trim())}catch{}let n=e.indexOf("{");if(n<0)return null;let o=0,r=!1,i=!1,a=-1;for(let c=n;c<e.length;c++){let d=e[c];if(r){i?i=!1:d==="\\"?i=!0:d==='"'&&(r=!1);continue}if(d==='"'){r=!0;continue}if(d==="{"){o===0&&(a=c),o+=1;continue}if(d==="}"){if(o===0)continue;if(o-=1,o===0&&a>=0){let u=e.slice(a,c+1);try{return JSON.parse(u)}catch{a=-1}}}}return null}function mo(s){let e=String(s||"").trim();if(!e)return null;try{return JSON.parse(e)}catch{return po(e)}}function go(s){try{let e=JSON.parse(s);if(typeof e=="string")return e;if(typeof e?.response=="string")return e.response;if(typeof e?.text=="string")return e.text;if(typeof e?.output=="string")return e.output;if(Array.isArray(e?.candidates)&&e.candidates.length>0){let t=e.candidates[0];if(typeof t?.content=="string")return t.content;if(Array.isArray(t?.content?.parts)){let n=t.content.parts.map(o=>typeof o?.text=="string"?o.text:"").join("");if(n.trim())return n}}}catch{}return s}var ve=class extends lo{constructor(){super("gemini","Gemini (Google)",70)}canHandle(e){if(!!!(process.env.GEMINI_API_KEY||process.env.GEMINI_API_KEY_POOL||process.env.GOOGLE_API_KEY||process.env.GOOGLE_API_KEY_POOL))return l.debug("GeminiAgentStrategy: GEMINI_API_KEY or GOOGLE_API_KEY not set"),!1;try{return co("gemini --version",{encoding:"utf-8",timeout:5e3,stdio:"pipe"}),!0}catch{return l.warn("[Gemini] gemini CLI not found. Install: npm install -g @google/gemini-cli"),!1}}async invoke(e,t={}){let{model:n,workspace:o=process.cwd(),schema:r=null,skills:i=null,sessionPath:a=null,nodeName:c=null,timeout:d=600*1e3,signal:u=null}=t,h=[F("GEMINI_API_KEY"),F("GOOGLE_API_KEY")];try{let g=n;(!g||g==="auto")&&(g=j.GEMINI);let S=ze[g]||g,E=String(process.env.GEMINI_API_KEY||"").trim(),U=String(process.env.GOOGLE_API_KEY||"").trim(),_=this._resolveSkillsToMcp(i,{sessionPath:a,workspace:o,nodeName:c}),b=Object.keys(_).length>0,w=new ee(e),L=r&&typeof r.parse=="function",m=null;if(r){let y;try{let p=L?Z(r,{target:"openAi"}):r;y=JSON.stringify(p,null,2)}catch{y="{}"}if(b){w.addSystemInstruction(`Write valid JSON that matches this schema:
|
|
84
84
|
${y}`,"schema_instruction","append");let p=`zibby-result-${Date.now()}.json`,$=q(o,".zibby","tmp");m=q($,p),dt($,{recursive:!0}),w.addStructuredOutput(r,m)}else w.addSystemInstruction(`Return ONLY valid JSON (no markdown, no commentary) that matches this schema:
|
|
85
85
|
${y}`,"json_instruction","append")}let K=w.build(),B=w.getUserPrompt(),M=w.getStats(),O=String(process.env.GEMINI_API_KEY||process.env.GOOGLE_API_KEY||"").trim(),T=O?` | key: ***${O.slice(-4)}`:" | key: not set";console.log(`
|
|
86
86
|
\u25C6 Model: ${S||"auto"}${T}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{AgentStrategy as
|
|
1
|
+
import{AgentStrategy as B,getSkill as j}from"@zibby/agent-workflow";import{execSync as z}from"node:child_process";import{z as G}from"zod";import{zodToJsonSchema as F}from"zod-to-json-schema";function V(l,e={target:"openApi3"}){if(!l)return null;if(typeof G?.toJSONSchema=="function")try{return G.toJSONSchema(l)}catch{}try{return F(l,e)}catch{return null}}import y from"chalk";var u={debug:0,info:1,warn:2,error:3,silent:4},A=class{constructor(){this._level=this._getLogLevel()}_getLogLevel(){if(process.env.ZIBBY_DEBUG==="true")return u.debug;if(process.env.ZIBBY_VERBOSE==="true")return u.info;let e=process.env.LOG_LEVEL?.toLowerCase();return e&&e in u?u[e]:u.info}_shouldLog(e){return u[e]>=this._level}_formatMessage(e,o,s={}){let c=new Date().toISOString(),i=`${this._getPrefix(e)} ${o}`;return Object.keys(s).length>0&&(i+=y.dim(` ${JSON.stringify(s)}`)),i}_getPrefix(e){return{debug:y.gray("[DEBUG]"),info:y.cyan("[INFO]"),warn:y.yellow("[WARN]"),error:y.red("\u274C [ERROR]")}[e]||""}debug(e,o){this._shouldLog("debug")&&console.log(this._formatMessage("debug",e,o))}info(e,o){this._shouldLog("info")&&console.log(this._formatMessage("info",e,o))}warn(e,o){this._shouldLog("warn")&&console.warn(this._formatMessage("warn",e,o))}error(e,o){this._shouldLog("error")&&console.error(this._formatMessage("error",e,o))}setLevel(e){e in u&&(this._level=u[e])}getLevel(){return Object.keys(u).find(e=>u[e]===this._level)}},n=new A;import{timeline as L,Timeline as le,WORKFLOW_GRAPH_LOG_MARKER_PREFIX as se}from"@zibby/agent-workflow";var J=[{alias:"auto",canonicalId:"claude-sonnet-4-6",vendor:"claude",label:"Claude \xB7 Sonnet 4.6",family:"claude-sonnet-4",pickerVisible:!0,isDefault:!0},{alias:"opus-4.8",canonicalId:"claude-opus-4-8",vendor:"claude",label:"Claude \xB7 Opus 4.8",family:"claude-opus-4",pickerVisible:!0},{alias:"opus-4-8",canonicalId:"claude-opus-4-8",vendor:"claude",family:"claude-opus-4",aliasOf:"opus-4.8"},{alias:"sonnet-4.8",canonicalId:"claude-sonnet-4-8",vendor:"claude",label:"Claude \xB7 Sonnet 4.8",family:"claude-sonnet-4",pickerVisible:!0},{alias:"sonnet-4-8",canonicalId:"claude-sonnet-4-8",vendor:"claude",family:"claude-sonnet-4",aliasOf:"sonnet-4.8"},{alias:"opus-4.7",canonicalId:"claude-opus-4-7",vendor:"claude",label:"Claude \xB7 Opus 4.7",family:"claude-opus-4",pickerVisible:!0},{alias:"opus-4-7",canonicalId:"claude-opus-4-7",vendor:"claude",family:"claude-opus-4",aliasOf:"opus-4.7"},{alias:"sonnet-4.7",canonicalId:"claude-sonnet-4-7",vendor:"claude",label:"Claude \xB7 Sonnet 4.7",family:"claude-sonnet-4",pickerVisible:!0},{alias:"sonnet-4-7",canonicalId:"claude-sonnet-4-7",vendor:"claude",family:"claude-sonnet-4",aliasOf:"sonnet-4.7"},{alias:"sonnet-4.6",canonicalId:"claude-sonnet-4-6",vendor:"claude",family:"claude-sonnet-4",aliasOf:"auto"},{alias:"sonnet-4-6",canonicalId:"claude-sonnet-4-6",vendor:"claude",family:"claude-sonnet-4",aliasOf:"auto"},{alias:"opus-4.6",canonicalId:"claude-opus-4-6",vendor:"claude",label:"Claude \xB7 Opus 4.6",family:"claude-opus-4",pickerVisible:!0},{alias:"opus-4-6",canonicalId:"claude-opus-4-6",vendor:"claude",family:"claude-opus-4",aliasOf:"opus-4.6"},{alias:"sonnet-4.5",canonicalId:"claude-sonnet-4-5-20250929",vendor:"claude",label:"Claude \xB7 Sonnet 4.5",family:"claude-sonnet-4",pickerVisible:!0},{alias:"sonnet-4-5",canonicalId:"claude-sonnet-4-5-20250929",vendor:"claude",family:"claude-sonnet-4",aliasOf:"sonnet-4.5"},{alias:"opus-4.5",canonicalId:"claude-opus-4-5-20251101",vendor:"claude",label:"Claude \xB7 Opus 4.5",family:"claude-opus-4",pickerVisible:!0},{alias:"opus-4-5",canonicalId:"claude-opus-4-5-20251101",vendor:"claude",family:"claude-opus-4",aliasOf:"opus-4.5"},{alias:"haiku-4.5",canonicalId:"claude-haiku-4-5-20251001",vendor:"claude",label:"Claude \xB7 Haiku 4.5",family:"claude-haiku-4"},{alias:"haiku-4-5",canonicalId:"claude-haiku-4-5-20251001",vendor:"claude",family:"claude-haiku-4",aliasOf:"haiku-4.5"},{alias:"claude-opus-4-8",canonicalId:"claude-opus-4-8",vendor:"claude",family:"claude-opus-4",aliasOf:"opus-4.8"},{alias:"claude-sonnet-4-8",canonicalId:"claude-sonnet-4-8",vendor:"claude",family:"claude-sonnet-4",aliasOf:"sonnet-4.8"},{alias:"claude-opus-4-7",canonicalId:"claude-opus-4-7",vendor:"claude",family:"claude-opus-4",aliasOf:"opus-4.7"},{alias:"claude-sonnet-4-7",canonicalId:"claude-sonnet-4-7",vendor:"claude",family:"claude-sonnet-4",aliasOf:"sonnet-4.7"},{alias:"claude-sonnet-4-6",canonicalId:"claude-sonnet-4-6",vendor:"claude",family:"claude-sonnet-4",aliasOf:"auto"},{alias:"claude-opus-4-6",canonicalId:"claude-opus-4-6",vendor:"claude",family:"claude-opus-4",aliasOf:"opus-4.6"},{alias:"claude-sonnet-4-5-20250929",canonicalId:"claude-sonnet-4-5-20250929",vendor:"claude",family:"claude-sonnet-4",aliasOf:"sonnet-4.5"},{alias:"claude-opus-4-5-20251101",canonicalId:"claude-opus-4-5-20251101",vendor:"claude",family:"claude-opus-4",aliasOf:"opus-4.5"},{alias:"claude-haiku-4-5-20251001",canonicalId:"claude-haiku-4-5-20251001",vendor:"claude",family:"claude-haiku-4",aliasOf:"haiku-4.5"},{alias:"claude-opus-4-20250514",canonicalId:"claude-opus-4-20250514",vendor:"claude",family:"claude-opus-4",aliasOf:"opus-4.5"},{alias:"auto",canonicalId:"o4-mini",vendor:"codex",label:"Codex \xB7 o4-mini",family:"o4-mini",isDefault:!0},{alias:"o4-mini",canonicalId:"o4-mini",vendor:"codex",label:"Codex \xB7 o4-mini",family:"o4-mini",pickerVisible:!0},{alias:"o3",canonicalId:"o3",vendor:"codex",family:"o3"},{alias:"o3-mini",canonicalId:"o3-mini",vendor:"codex",family:"o3-mini"},{alias:"codex-mini",canonicalId:"codex-mini-latest",vendor:"codex",family:"codex-mini"},{alias:"gpt-4o",canonicalId:"gpt-4o",vendor:"codex",label:"Codex \xB7 GPT-4o",family:"gpt-4o",pickerVisible:!0},{alias:"gpt-4o-mini",canonicalId:"gpt-4o-mini",vendor:"codex",label:"Codex \xB7 GPT-4o mini",family:"gpt-4o-mini",pickerVisible:!0},{alias:"gpt-5.2-codex",canonicalId:"gpt-5.2-codex",vendor:"codex",label:"Codex \xB7 GPT-5.2",family:"gpt-5",pickerVisible:!0},{alias:"gpt-5.2",canonicalId:"gpt-5.2",vendor:"codex",label:"Codex \xB7 GPT-5.2 base",family:"gpt-5",pickerVisible:!0},{alias:"gpt-5.3",canonicalId:"gpt-5.3",vendor:"codex",label:"Codex \xB7 GPT-5.3",family:"gpt-5",pickerVisible:!0},{alias:"gpt-5.3-codex",canonicalId:"gpt-5.3-codex",vendor:"codex",family:"gpt-5"},{alias:"gpt-5.4",canonicalId:"gpt-5.4",vendor:"codex",label:"Codex \xB7 GPT-5.4",family:"gpt-5",pickerVisible:!0},{alias:"gpt-5.5",canonicalId:"gpt-5.5",vendor:"codex",label:"Codex \xB7 GPT-5.5",family:"gpt-5",pickerVisible:!0},{alias:"auto",canonicalId:"gemini-3-pro",vendor:"gemini",label:"Gemini \xB7 3 Pro",family:"gemini-3",isDefault:!0},{alias:"gemini-3-pro",canonicalId:"gemini-3-pro",vendor:"gemini",label:"Gemini \xB7 3 Pro",family:"gemini-3",pickerVisible:!0},{alias:"gemini-3-flash",canonicalId:"gemini-3-flash",vendor:"gemini",label:"Gemini \xB7 3 Flash",family:"gemini-3",pickerVisible:!0},{alias:"gemini-2.5-pro",canonicalId:"gemini-2.5-pro",vendor:"gemini",label:"Gemini \xB7 2.5 Pro",family:"gemini-2.5",pickerVisible:!0},{alias:"gemini-2.5-flash",canonicalId:"gemini-2.5-flash",vendor:"gemini",label:"Gemini \xB7 2.5 Flash",family:"gemini-2.5",pickerVisible:!0}];function _(l){let e={};for(let o of J)o.vendor===l&&(e[o.alias]=o.canonicalId);return e}var w={ASSISTANT:"gpt-5.4-nano-2026-03-17",CLAUDE:"claude-sonnet-4-6",CURSOR:"auto",CODEX:"o4-mini",GEMINI:"gemini-3-pro",OPENAI_POSTPROCESSING:"gpt-4o-mini"};var ce=_("claude"),M=_("codex"),de=_("gemini"),ue={CURSOR_AGENT_DEFAULT:1200*1e3,OPENAI_REQUEST:18e4};function $(l){let e=`${l}_POOL`,o=process.env[e];if(!o||typeof o!="string")return{picked:null,count:0,dispose:()=>{}};let s=o.split(/[,\n]+/).map(i=>i.trim()).filter(Boolean);if(s.length===0)return{picked:null,count:0,dispose:()=>{}};let c=s[Math.floor(Math.random()*s.length)],a=process.env[l];return process.env[l]=c,n.debug(`[auth-pool] ${l}: picked 1 of ${s.length} from pool (***${c.slice(-4)})`),{picked:c,count:s.length,dispose(){a===void 0?delete process.env[l]:process.env[l]=a}}}var R=class extends B{constructor(){super("codex","Codex (OpenAI)",75)}canHandle(e){if(!!!(process.env.OPENAI_API_KEY||process.env.OPENAI_API_KEY_POOL||process.env.CODEX_API_KEY||process.env.CODEX_API_KEY_POOL))return n.debug("CodexAgentStrategy: OPENAI_API_KEY or CODEX_API_KEY not set"),!1;try{return z("codex --version",{encoding:"utf-8",timeout:5e3,stdio:"pipe"}),!0}catch{return n.warn("[Codex] codex CLI not found. Install: npm install -g @openai/codex"),!1}}async invoke(e,o={}){let{model:s,workspace:c=process.cwd(),schema:a=null,skills:i=null,sessionPath:O=null,nodeName:m=null,timeout:W,config:H={},signal:D=null}=o,K=[$("OPENAI_API_KEY"),$("CODEX_API_KEY")];try{let{Codex:E}=await import("@openai/codex-sdk"),p=s;(!p||p==="auto")&&(n.debug(`Model is '${p||"undefined"}', using default: ${w.CODEX}`),p=w.CODEX);let b=M[p]||p;M[p]&&p!==b&&n.debug(`Mapped model: ${p} \u2192 ${b}`),n.debug(`Invoking Codex SDK with model: ${b}, skills: ${JSON.stringify(i)}`);let x=process.env.CODEX_API_KEY||process.env.OPENAI_API_KEY;x&&!process.env.CODEX_API_KEY&&(process.env.CODEX_API_KEY=x);let Y=x?` | key: ***${x.slice(-4)}`:" | key: not set";console.log(`
|
|
2
2
|
\u25C6 Model: ${b}${Y}
|
|
3
3
|
`);let h=(await import("chalk")).default;console.log(`
|
|
4
|
-
${h.bold("Prompt sent to LLM:")}`),console.log(h.dim("\u2500".repeat(60))),console.log(h.dim(e)),console.log(h.dim("\u2500".repeat(60)));let k=this._resolveSkillsToMcp(
|
|
4
|
+
${h.bold("Prompt sent to LLM:")}`),console.log(h.dim("\u2500".repeat(60))),console.log(h.dim(e)),console.log(h.dim("\u2500".repeat(60)));let k=this._resolveSkillsToMcp(i,{sessionPath:O,workspace:c,nodeName:m}),C={};Object.keys(k).length>0&&(C.mcp_servers=k,n.debug(`[Codex] MCP servers: ${Object.keys(k).join(", ")}`));let U=new E({...Object.keys(C).length>0&&{config:C}}).startThread({workingDirectory:c,skipGitRepoCheck:!0,approvalPolicy:"never",sandboxMode:"danger-full-access",networkAccessEnabled:!0}),T=a&&typeof a.parse=="function",N={};if(a)try{let t=T?V(a,{target:"openAi"}):a;N.outputSchema=t,n.debug("Structured output via SDK outputSchema")}catch(t){n.warn(`[Codex] Schema conversion failed, will extract from text: ${t.message}`)}if(D?.aborted){let t=new Error("Aborted via signal");throw t.name="AbortError",t}try{let{events:t}=await U.runStreamed(e,N),g=0,d="";for await(let f of t){if(D?.aborted){let r=new Error("Aborted via signal");throw r.name="AbortError",r}let v=f.type;if(v==="item.completed"){let r=f.item,I=r?.type;if(I==="mcp_tool_call"){g++;let S=`${r.server}/${r.tool}`;if(L.stepTool(`Tool: ${S}`),r.arguments){let P=JSON.stringify(r.arguments),X=P.length>100?`${P.substring(0,100)}...`:P;console.log(` Input: ${X}`)}}else if(I==="tool_call"||I==="function_call"||I==="command_execution"){g++;let S=r.name||r.tool||r.command||"unknown";L.stepTool(`Tool: ${S}`)}else I==="agent_message"&&(d=r.text||"",d.length<500?console.log(d):console.log(`${d.substring(0,200)}... (${d.length} chars)`))}else v==="turn.completed"?n.debug(`[Codex] Turn completed. Usage: ${JSON.stringify(f.usage||{})}`):n.debug(`[Codex] Event: ${v} ${JSON.stringify(f).slice(0,300)}`)}if(n.debug(`[Codex] Last agent message (${d.length} chars): ${d.slice(0,500)}`),a){if(!d)throw new Error("Codex agent returned no response");let f=JSON.parse(d),v=T?a.parse(f):f;return n.debug("\u2705 [Codex] Structured output validated"),{raw:d,structured:v}}return d||""}catch(t){let g=t.message||String(t);throw n.error(`\u274C [Codex] SDK call failed: ${g}`),g.includes("exited with code")&&(n.error("\u{1F4A1} [Codex] Verify: codex --version && echo $OPENAI_API_KEY"),n.error("\u{1F4A1} [Codex] If codex is missing: npm install -g @openai/codex")),t}}finally{for(let E of K)E.dispose()}}_resolveSkillsToMcp(e,o={}){if(!Array.isArray(e)||e.length===0)return{};let s={};for(let c of e){let a=j(c);if(!a){n.warn(`[Codex] Unknown skill "${c}" \u2014 skipping`);continue}if(typeof a.resolve!="function")continue;let i=a.resolve(o);if(!i)continue;let O=a.serverName||c,m={command:i.command};i.args?.length&&(m.args=i.args),m.env={...process.env,...i.env||{}},s[O]=m,n.debug(`[Codex] MCP: ${O} \u2192 ${i.command} ${(i.args||[]).join(" ")}`)}return s}};export{R as CodexAgentStrategy};
|
package/dist/strategies/index.js
CHANGED
|
@@ -80,7 +80,7 @@ This usually means the binary is not in PATH. Try:
|
|
|
80
80
|
`),stringified:(()=>{try{return JSON.stringify(p,Object.getOwnPropertyNames(Object(p)))}catch{return String(p)}})()};throw l.error(`Error during query stream: ${p?.message||p}`,C),p}}catch(N){throw l.error("Claude Agent SDK call failed",{message:N?.message,name:N?.name,code:N?.code,cause:N?.cause?.message||N?.cause}),N}}finally{for(let g of w)g.dispose()}}_resolveSkills(e,t){let n=["Read","Write","Edit","Bash","Grep","Glob"];if(e===null)return l.debug("No skills \u2014 pure LLM mode"),{allowedTools:[],mcpServers:{}};if(!Array.isArray(e)||e.length===0)return l.debug("Default IDE skills for code generation"),{allowedTools:[...n],mcpServers:{}};let o=[...n],r={},i=process.env.WORKFLOW_ENABLED_INTEGRATIONS,a=typeof i=="string"&&i.trim()!==""?new Set(i.split(",").map(d=>d.trim()).filter(Boolean)):null,c=d=>a!==null&&a.size>0&&qt.includes(d)&&!a.has(d);for(let d of e){if(c(d)){l.debug(`Skill "${d}" disabled by enabledIntegrations allowlist \u2014 skipping`);continue}let u=Zt(d);if(!u){l.warn(`Unknown skill "${d}" \u2014 skipping`);continue}if(u.allowedTools&&o.push(...u.allowedTools),typeof u.resolve=="function"){let h=u.resolve(t);h&&(r[u.serverName]=h,l.debug(`MCP: ${u.serverName} \u2192 ${h.command} ${h.args[0]}`))}}return{allowedTools:o,mcpServers:r}}_extractJson(e,t){let n=[()=>{if(e.includes("===JSON_START===")){let o=e.indexOf("===JSON_START===")+16,r=e.indexOf("===JSON_END===");return e.substring(o,r).trim()}},()=>e.match(/```json\s*\n([\s\S]*?)\n```/)?.[1]?.trim(),()=>{if(!e.startsWith("{"))return e.match(/```\s*\n([\s\S]*?)\n```/)?.[1]?.trim()},()=>e.trim(),()=>{let o=e.indexOf("{"),r=e.lastIndexOf("}");if(o!==-1&&r>o)return e.substring(o,r+1)}];for(let o of n)try{let r=o();if(!r)continue;let i=JSON.parse(r);if(typeof i!="object"||i===null)continue;return typeof t.parse=="function"?t.parse(i):i}catch{}return null}};function eo({message:s,sessionPath:e,nodeName:t,model:n,toolCallCount:o}){if(!e||!t)return;let r=s?.usage||s?.message?.usage||{},i=pe(r.input_tokens,r.inputTokens),a=pe(r.output_tokens,r.outputTokens),c=pe(r.cache_read_input_tokens,r.cacheReadInputTokens),d=pe(r.cache_creation_input_tokens,r.cacheCreationInputTokens),u=pe(s?.duration_ms,s?.durationMs),h={model:n||null,input_tokens:i,output_tokens:a,cache_read_tokens:c,cache_creation_tokens:d,tool_call_count:typeof o=="number"?o:null,duration_ms:u,captured_at:new Date().toISOString()},m=oe(e,t);try{Ue(m,{recursive:!0})}catch{}De(oe(m,"usage.json"),JSON.stringify(h,null,2),"utf-8")}function pe(...s){for(let e of s){if(typeof e=="number"&&Number.isFinite(e))return e;if(typeof e=="string"&&e.trim()!==""&&!isNaN(Number(e)))return Number(e)}return null}function to(s,e){let t=oe(at(),".claude"),n=oe(t,".credentials.json"),o={claudeAiOauth:{accessToken:s,refreshToken:"",expiresAt:Date.now()+365*24*60*60*1e3,scopes:["user:inference","user:profile"],...e?{subscriptionType:String(e).toLowerCase()}:{}}};try{if(it(n)&&JSON.parse(lt(n,"utf-8"))?.claudeAiOauth?.accessToken===s)return;Ue(t,{recursive:!0}),De(n,JSON.stringify(o,null,2),"utf-8"),l.debug(`Wrote Claude Code OAuth credentials to ${n}`)}catch(r){l.warn(`Could not write ${n}: ${r.message} \u2014 Claude SDK may fail to authenticate.`)}}function oo(s){let e=oe(at(),".claude"),t=oe(e,".credentials.json"),n;try{n=JSON.parse(s)}catch(o){l.warn(`CLAUDE_CODE_CREDENTIALS_JSON not valid JSON: ${o.message}`);return}if(!n?.claudeAiOauth?.accessToken){l.warn("CLAUDE_CODE_CREDENTIALS_JSON missing claudeAiOauth.accessToken \u2014 skipping write.");return}try{if(it(t)){let o=JSON.parse(lt(t,"utf-8"));if(o?.claudeAiOauth?.accessToken===n.claudeAiOauth.accessToken&&o?.claudeAiOauth?.expiresAt===n.claudeAiOauth.expiresAt)return}Ue(e,{recursive:!0}),De(t,JSON.stringify(n,null,2),"utf-8"),l.debug(`Wrote full Claude Code credentials blob to ${t}`)}catch(o){l.warn(`Could not write ${t}: ${o.message} \u2014 Claude SDK may fail to authenticate.`)}}fe();import{AgentStrategy as no,getSkill as ro}from"@zibby/agent-workflow";import{execSync as so}from"node:child_process";var Ee=class extends no{constructor(){super("codex","Codex (OpenAI)",75)}canHandle(e){if(!!!(process.env.OPENAI_API_KEY||process.env.OPENAI_API_KEY_POOL||process.env.CODEX_API_KEY||process.env.CODEX_API_KEY_POOL))return l.debug("CodexAgentStrategy: OPENAI_API_KEY or CODEX_API_KEY not set"),!1;try{return so("codex --version",{encoding:"utf-8",timeout:5e3,stdio:"pipe"}),!0}catch{return l.warn("[Codex] codex CLI not found. Install: npm install -g @openai/codex"),!1}}async invoke(e,t={}){let{model:n,workspace:o=process.cwd(),schema:r=null,skills:i=null,sessionPath:a=null,nodeName:c=null,timeout:d,config:u={},signal:h=null}=t,m=[F("OPENAI_API_KEY"),F("CODEX_API_KEY")];try{let{Codex:y}=await import("@openai/codex-sdk"),E=n;(!E||E==="auto")&&(l.debug(`Model is '${E||"undefined"}', using default: ${j.CODEX}`),E=j.CODEX);let D=Me[E]||E;Me[E]&&E!==D&&l.debug(`Mapped model: ${E} \u2192 ${D}`),l.debug(`Invoking Codex SDK with model: ${D}, skills: ${JSON.stringify(i)}`);let _=process.env.CODEX_API_KEY||process.env.OPENAI_API_KEY;_&&!process.env.CODEX_API_KEY&&(process.env.CODEX_API_KEY=_);let O=_?` | key: ***${_.slice(-4)}`:" | key: not set";console.log(`
|
|
81
81
|
\u25C6 Model: ${D}${O}
|
|
82
82
|
`);let S=(await import("chalk")).default;console.log(`
|
|
83
|
-
${S.bold("Prompt sent to LLM:")}`),console.log(S.dim("\u2500".repeat(60))),console.log(S.dim(e)),console.log(S.dim("\u2500".repeat(60)));let w=this._resolveSkillsToMcp(i,{sessionPath:a,workspace:o,nodeName:c}),g={};Object.keys(w).length>0&&(g.mcp_servers=w,l.debug(`[Codex] MCP servers: ${Object.keys(w).join(", ")}`));let B=new y({...Object.keys(g).length>0&&{config:g}}).startThread({workingDirectory:o,skipGitRepoCheck:!0,approvalPolicy:"never",sandboxMode:"danger-full-access",networkAccessEnabled:!0}),k=r&&typeof r.parse=="function",A={};if(r)try{let I=k?Z(r,{target:"openAi"}):r;A.outputSchema=I,l.debug("Structured output via SDK outputSchema")}catch(I){l.warn(`[Codex] Schema conversion failed, will extract from text: ${I.message}`)}if(h?.aborted){let I=new Error("Aborted via signal");throw I.name="AbortError",I}try{let{events:I}=await B.runStreamed(e,A),M=0,T="";for await(let P of I){if(h?.aborted){let R=new Error("Aborted via signal");throw R.name="AbortError",R}let N=P.type;if(N==="item.completed"){let R=P.item,J=R?.type;if(J==="mcp_tool_call"){M++;let v=`${R.server}/${R.tool}`;if(H.stepTool(`Tool: ${v}`),R.arguments){let f=JSON.stringify(R.arguments),L=f.length>100?`${f.substring(0,100)}...`:f;console.log(` Input: ${L}`)}}else if(J==="tool_call"||J==="function_call"||J==="command_execution"){M++;let v=R.name||R.tool||R.command||"unknown";H.stepTool(`Tool: ${v}`)}else J==="agent_message"&&(T=R.text||"",T.length<500?console.log(T):console.log(`${T.substring(0,200)}... (${T.length} chars)`))}else N==="turn.completed"?l.debug(`[Codex] Turn completed. Usage: ${JSON.stringify(P.usage||{})}`):l.debug(`[Codex] Event: ${N} ${JSON.stringify(P).slice(0,300)}`)}if(l.debug(`[Codex] Last agent message (${T.length} chars): ${T.slice(0,500)}`),r){if(!T)throw new Error("Codex agent returned no response");let P=JSON.parse(T),N=k?r.parse(P):P;return l.debug("\u2705 [Codex] Structured output validated"),{raw:T,structured:N}}return T||""}catch(I){let M=I.message||String(I);throw l.error(`\u274C [Codex] SDK call failed: ${M}`),M.includes("exited with code")&&(l.error("\u{1F4A1} [Codex] Verify: codex --version && echo $OPENAI_API_KEY"),l.error("\u{1F4A1} [Codex] If codex is missing: npm install -g @openai/codex")),I}}finally{for(let y of m)y.dispose()}}_resolveSkillsToMcp(e,t={}){if(!Array.isArray(e)||e.length===0)return{};let n={};for(let o of e){let r=ro(o);if(!r){l.warn(`[Codex] Unknown skill "${o}" \u2014 skipping`);continue}if(typeof r.resolve!="function")continue;let i=r.resolve(t);if(!i)continue;let a=r.serverName||o,c={command:i.command};i.args?.length&&(c.args=i.args),
|
|
83
|
+
${S.bold("Prompt sent to LLM:")}`),console.log(S.dim("\u2500".repeat(60))),console.log(S.dim(e)),console.log(S.dim("\u2500".repeat(60)));let w=this._resolveSkillsToMcp(i,{sessionPath:a,workspace:o,nodeName:c}),g={};Object.keys(w).length>0&&(g.mcp_servers=w,l.debug(`[Codex] MCP servers: ${Object.keys(w).join(", ")}`));let B=new y({...Object.keys(g).length>0&&{config:g}}).startThread({workingDirectory:o,skipGitRepoCheck:!0,approvalPolicy:"never",sandboxMode:"danger-full-access",networkAccessEnabled:!0}),k=r&&typeof r.parse=="function",A={};if(r)try{let I=k?Z(r,{target:"openAi"}):r;A.outputSchema=I,l.debug("Structured output via SDK outputSchema")}catch(I){l.warn(`[Codex] Schema conversion failed, will extract from text: ${I.message}`)}if(h?.aborted){let I=new Error("Aborted via signal");throw I.name="AbortError",I}try{let{events:I}=await B.runStreamed(e,A),M=0,T="";for await(let P of I){if(h?.aborted){let R=new Error("Aborted via signal");throw R.name="AbortError",R}let N=P.type;if(N==="item.completed"){let R=P.item,J=R?.type;if(J==="mcp_tool_call"){M++;let v=`${R.server}/${R.tool}`;if(H.stepTool(`Tool: ${v}`),R.arguments){let f=JSON.stringify(R.arguments),L=f.length>100?`${f.substring(0,100)}...`:f;console.log(` Input: ${L}`)}}else if(J==="tool_call"||J==="function_call"||J==="command_execution"){M++;let v=R.name||R.tool||R.command||"unknown";H.stepTool(`Tool: ${v}`)}else J==="agent_message"&&(T=R.text||"",T.length<500?console.log(T):console.log(`${T.substring(0,200)}... (${T.length} chars)`))}else N==="turn.completed"?l.debug(`[Codex] Turn completed. Usage: ${JSON.stringify(P.usage||{})}`):l.debug(`[Codex] Event: ${N} ${JSON.stringify(P).slice(0,300)}`)}if(l.debug(`[Codex] Last agent message (${T.length} chars): ${T.slice(0,500)}`),r){if(!T)throw new Error("Codex agent returned no response");let P=JSON.parse(T),N=k?r.parse(P):P;return l.debug("\u2705 [Codex] Structured output validated"),{raw:T,structured:N}}return T||""}catch(I){let M=I.message||String(I);throw l.error(`\u274C [Codex] SDK call failed: ${M}`),M.includes("exited with code")&&(l.error("\u{1F4A1} [Codex] Verify: codex --version && echo $OPENAI_API_KEY"),l.error("\u{1F4A1} [Codex] If codex is missing: npm install -g @openai/codex")),I}}finally{for(let y of m)y.dispose()}}_resolveSkillsToMcp(e,t={}){if(!Array.isArray(e)||e.length===0)return{};let n={};for(let o of e){let r=ro(o);if(!r){l.warn(`[Codex] Unknown skill "${o}" \u2014 skipping`);continue}if(typeof r.resolve!="function")continue;let i=r.resolve(t);if(!i)continue;let a=r.serverName||o,c={command:i.command};i.args?.length&&(c.args=i.args),c.env={...process.env,...i.env||{}},n[a]=c,l.debug(`[Codex] MCP: ${a} \u2192 ${i.command} ${(i.args||[]).join(" ")}`)}return n}};fe();import{AgentStrategy as io,getSkill as lo}from"@zibby/agent-workflow";import{execSync as ao,spawn as co}from"node:child_process";import{existsSync as ct,mkdirSync as ut,readFileSync as dt,rmSync as uo,writeFileSync as ft}from"node:fs";import{join as q}from"node:path";function fo(s){if(!s)return null;let e=String(s),t=e.match(/```(?:json)?\s*([\s\S]*?)```/i);if(t?.[1])try{return JSON.parse(t[1].trim())}catch{}let n=e.indexOf("{");if(n<0)return null;let o=0,r=!1,i=!1,a=-1;for(let c=n;c<e.length;c++){let d=e[c];if(r){i?i=!1:d==="\\"?i=!0:d==='"'&&(r=!1);continue}if(d==='"'){r=!0;continue}if(d==="{"){o===0&&(a=c),o+=1;continue}if(d==="}"){if(o===0)continue;if(o-=1,o===0&&a>=0){let u=e.slice(a,c+1);try{return JSON.parse(u)}catch{a=-1}}}}return null}function po(s){let e=String(s||"").trim();if(!e)return null;try{return JSON.parse(e)}catch{return fo(e)}}function mo(s){try{let e=JSON.parse(s);if(typeof e=="string")return e;if(typeof e?.response=="string")return e.response;if(typeof e?.text=="string")return e.text;if(typeof e?.output=="string")return e.output;if(Array.isArray(e?.candidates)&&e.candidates.length>0){let t=e.candidates[0];if(typeof t?.content=="string")return t.content;if(Array.isArray(t?.content?.parts)){let n=t.content.parts.map(o=>typeof o?.text=="string"?o.text:"").join("");if(n.trim())return n}}}catch{}return s}var Ae=class extends io{constructor(){super("gemini","Gemini (Google)",70)}canHandle(e){if(!!!(process.env.GEMINI_API_KEY||process.env.GEMINI_API_KEY_POOL||process.env.GOOGLE_API_KEY||process.env.GOOGLE_API_KEY_POOL))return l.debug("GeminiAgentStrategy: GEMINI_API_KEY or GOOGLE_API_KEY not set"),!1;try{return ao("gemini --version",{encoding:"utf-8",timeout:5e3,stdio:"pipe"}),!0}catch{return l.warn("[Gemini] gemini CLI not found. Install: npm install -g @google/gemini-cli"),!1}}async invoke(e,t={}){let{model:n,workspace:o=process.cwd(),schema:r=null,skills:i=null,sessionPath:a=null,nodeName:c=null,timeout:d=600*1e3,signal:u=null}=t,h=[F("GEMINI_API_KEY"),F("GOOGLE_API_KEY")];try{let m=n;(!m||m==="auto")&&(m=j.GEMINI);let y=Ye[m]||m,E=String(process.env.GEMINI_API_KEY||"").trim(),D=String(process.env.GOOGLE_API_KEY||"").trim(),_=this._resolveSkillsToMcp(i,{sessionPath:a,workspace:o,nodeName:c}),O=Object.keys(_).length>0,S=new ee(e),w=r&&typeof r.parse=="function",g=null;if(r){let b;try{let p=w?Z(r,{target:"openAi"}):r;b=JSON.stringify(p,null,2)}catch{b="{}"}if(O){S.addSystemInstruction(`Write valid JSON that matches this schema:
|
|
84
84
|
${b}`,"schema_instruction","append");let p=`zibby-result-${Date.now()}.json`,C=q(o,".zibby","tmp");g=q(C,p),ut(C,{recursive:!0}),S.addStructuredOutput(r,g)}else S.addSystemInstruction(`Return ONLY valid JSON (no markdown, no commentary) that matches this schema:
|
|
85
85
|
${b}`,"json_instruction","append")}let K=S.build(),B=S.getUserPrompt(),k=S.getStats(),A=String(process.env.GEMINI_API_KEY||process.env.GOOGLE_API_KEY||"").trim(),I=A?` | key: ***${A.slice(-4)}`:" | key: not set";console.log(`
|
|
86
86
|
\u25C6 Model: ${y||"auto"}${I}
|