@zibby/agent-workflow 0.4.33 β†’ 0.4.35

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/README.md CHANGED
@@ -9,12 +9,12 @@
9
9
 
10
10
  πŸ“– **Full docs:** [docs.zibby.app](https://docs.zibby.app) Β· [Get Started](https://docs.zibby.app/get-started/install) Β· [Concepts](https://docs.zibby.app/concepts/graph) Β· [CLI Reference](https://docs.zibby.app/cli-reference) Β· [Cloud](https://docs.zibby.app/cloud/triggering)
11
11
 
12
- > **The cloud pipeline for Claude Code, Cursor, Codex, and Gemini.** Compose them into structured workflows with Zod-validated handoff between nodes. Vendor-neutral, JavaScript-first, runs locally or in our cloud.
12
+ > **The cloud pipeline for Claude Code, Codex, and Gemini.** Compose them into structured workflows with Zod-validated handoff between nodes. Vendor-neutral, JavaScript-first, runs locally or in our cloud.
13
13
 
14
14
  ```
15
15
  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
16
16
  trigger β†’ β”‚ plan β”‚ β†’ β”‚ implementβ”‚ β†’ β”‚ verify β”‚ β†’ result
17
- β”‚ (claude) β”‚ β”‚ (cursor) β”‚ β”‚ (codex) β”‚
17
+ β”‚ (claude) β”‚ β”‚ (codex) β”‚ β”‚ (gemini) β”‚
18
18
  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
19
19
  β”‚ β”‚ β”‚
20
20
  Zod out Zod out Zod out
@@ -22,16 +22,16 @@
22
22
 
23
23
  Each node hands off to a complete agent. The agent does its own tool calls, file edits, and multi-turn reasoning. Your graph defines *what* agent runs *when*, *what schema* it has to return, and *what state* flows between them.
24
24
 
25
- Mix and match agents per node β€” Claude for planning, Cursor for implementation, Codex for verification. Or stick with one. Your call:
25
+ Mix and match agents per node β€” Claude for planning, Codex for implementation, Gemini for verification. Or stick with one. Your call:
26
26
 
27
27
  ```js
28
28
  graph
29
29
  .addNode('plan', { prompt, outputSchema: Plan, agent: 'claude' })
30
- .addNode('implement', { prompt, outputSchema: Diff, agent: 'cursor' })
31
- .addNode('verify', { prompt, outputSchema: Result, agent: 'codex' });
30
+ .addNode('implement', { prompt, outputSchema: Diff, agent: 'codex' })
31
+ .addNode('verify', { prompt, outputSchema: Result, agent: 'gemini' });
32
32
  ```
33
33
 
34
- Each agent reads its own credential env var (`ANTHROPIC_API_KEY`, `CURSOR_API_KEY`, `OPENAI_API_KEY`). In **Zibby Cloud** you can set those per-workflow β€” different keys per pipeline, no global state β€” see [Per-workflow env vars](https://docs.zibby.app/cloud/env-vars). Per-node `model` overrides come from `.zibby.config.mjs` (`models: { node_id: 'claude-opus-4.6' }`), which the CLI ships to cloud as part of the deploy bundle.
34
+ Each agent reads its own credential env var (`ANTHROPIC_API_KEY`, `OPENAI_API_KEY`). In **Zibby Cloud** you can set those per-workflow β€” different keys per pipeline, no global state β€” see [Per-workflow env vars](https://docs.zibby.app/cloud/env-vars). Per-node `model` overrides come from `.zibby.config.mjs` (`models: { node_id: 'claude-opus-4.6' }`), which the CLI ships to cloud as part of the deploy bundle.
35
35
 
36
36
  ---
37
37
 
@@ -70,6 +70,18 @@ zibby --help
70
70
 
71
71
  ---
72
72
 
73
+ ## πŸš€ Self-hosted Zibby (single VM)
74
+
75
+ Run the **full Zibby platform** β€” control plane + agents + marketplace β€” on your own box:
76
+
77
+ ```bash
78
+ curl -fsSL https://dl.zibby.app/selfhosted/latest/install.sh | bash
79
+ ```
80
+
81
+ Requirements: Docker + ~8 GB RAM. The installer downloads the release bundle, `docker load`s the images locally (**no registry login needed**), generates secrets, brings the stack up, and prints your dashboard URL + access token. Free tier: up to 10 deployed agents.
82
+
83
+ ---
84
+
73
85
  ## The CLI: full workflow lifecycle
74
86
 
75
87
  All workflow operations live under `zibby agent <verb>` for consistency. The bare top-level forms (`zibby start`, `zibby deploy`, `zibby trigger`, `zibby logs`) are kept as backward-compat aliases.
@@ -140,11 +152,11 @@ See [`examples/`](./examples/) for runnable demos of each pattern.
140
152
 
141
153
  | | What it does | Why this is different |
142
154
  |---|---|---|
143
- | **LangGraph** | Python-first graph runtime over LangChain β€” nodes are LangChain agents or LLM calls, state is shared via the graph. | Our nodes hand off to **external coding-agent CLIs** (Claude Code, cursor-agent, OpenAI Codex SDK) β€” independent processes that own their own tool use, multi-turn loops, and file edits. JS-first, no Python interop, no LangChain assembly. |
155
+ | **LangGraph** | Python-first graph runtime over LangChain β€” nodes are LangChain agents or LLM calls, state is shared via the graph. | Our nodes hand off to **external coding-agent CLIs** (Claude Code, OpenAI Codex, Gemini CLI) β€” independent processes that own their own tool use, multi-turn loops, and file edits. JS-first, no Python interop, no LangChain assembly. |
144
156
  | **n8n / Zapier** | Visual workflow editor β€” wire SaaS APIs together. | Code-first, no UI. Built around composing coding-agent CLIs against your repo, not connecting SaaS APIs. |
145
157
  | **CrewAI / AutoGen** | Multi-agent role-play β€” agents converse to solve a task. | No agent debate. Each node is a discrete, schema-validated invocation. Deterministic edges, retry-friendly. |
146
158
 
147
- If you want to compose Claude Code + Cursor + Codex into one pipeline with structured handoff between them β€” JS, no Python, no LangChain β€” this is that.
159
+ If you want to compose Claude Code + Codex + Gemini into one pipeline with structured handoff between them β€” JS, no Python, no LangChain β€” this is that.
148
160
 
149
161
  ---
150
162
 
@@ -238,7 +250,7 @@ Examples 01–03 and 05 use a fake agent β€” no API key required.
238
250
 
239
251
  ## Why graph-of-agents
240
252
 
241
- Real coding agents (Claude Code, cursor-agent, OpenAI Codex CLI) are themselves capable runtimes β€” they edit files, run shells, call MCP tools, handle multi-turn. But on their own they have no memory across runs and no way to verify their own output.
253
+ Real coding agents (Claude Code, OpenAI Codex, Gemini CLI) are themselves capable runtimes β€” they edit files, run shells, call MCP tools, handle multi-turn. But on their own they have no memory across runs and no way to verify their own output.
242
254
 
243
255
  A graph gives you:
244
256
 
@@ -258,7 +270,7 @@ You're not replacing the agent. You're giving it a job description, a contract,
258
270
  | Package | What it adds |
259
271
  |---|---|
260
272
  | [`@zibby/cli`](https://www.npmjs.com/package/@zibby/cli) | `zibby` command β€” scaffold, dev server, deploy, trigger, logs. |
261
- | [`@zibby/core`](https://www.npmjs.com/package/@zibby/core) | Built-in agent strategies (Claude / Cursor / Codex / Gemini / OpenAI Assistant), MCP client, runtime. |
273
+ | [`@zibby/core`](https://www.npmjs.com/package/@zibby/core) | Built-in agent strategies (Claude / Codex / Gemini / OpenAI Assistant), MCP client, runtime. |
262
274
  | [`@zibby/skills`](https://www.npmjs.com/package/@zibby/skills) | Pre-built skills (browser via Playwright MCP, GitHub, Jira, Slack, memory). |
263
275
 
264
276
  Workflow itself ships **zero agent strategies and zero skills** β€” bring your own, or `npm install @zibby/core @zibby/skills` for the batteries-included experience.
@@ -38,7 +38,7 @@ ${s}`);let i=r(),u=i.cwd||process.cwd(),d=i.sessionPath;try{if(d){let l=Te(d,K);
38
38
  `):a.every(n=>typeof n=="object")?Object.assign({},...a):a[a.length-1]}static async loadFile(e){let t=Eo(e,"utf-8");if(e.endsWith(".json"))return JSON.parse(t);if(e.endsWith(".js")||e.endsWith(".mjs")){let{pathToFileURL:r}=await import("url"),a=await import(r(e).href);return a.default||a}return t}};import{mkdirSync as bt,existsSync as Ne,writeFileSync as It,unlinkSync as bo}from"node:fs";import{join as Y,resolve as $t}from"node:path";import{config as $o}from"dotenv";import{zodToJsonSchema as Et}from"zod-to-json-schema";import{z as he}from"zod";import vo from"handlebars";function To({traceFrom:o,sessionId:e,sessionPath:t,idSource:r,mkdirFresh:a}){if(!(process.env.ZIBBY_SESSION_LOG==="1"||process.env.ZIBBY_SESSION_LOG==="true"))return;let n=typeof process.ppid=="number"?process.ppid:"n/a",i=`[zibby:session] from=${o} pid=${process.pid} ppid=${n} sessionId=${e} source=${r} mkdir=${a?"yes":"no"} path=${t}`;if(console.log(i),process.env.ZIBBY_TRACE_SESSION==="1"||process.env.ZIBBY_TRACE_SESSION==="true"){let h=(new Error("session trace").stack||"").split(`
39
39
  `).slice(2,14).join(`
40
40
  `);console.log(`[zibby:session] stack (${o}):
41
- ${h}`)}}function Ao(){return process.env.ZIBBY_TRUST_SESSION_ENV==="1"||process.env.ZIBBY_TRUST_SESSION_ENV==="true"||process.env.ZIBBY_KEEP_SESSION_ENV==="1"||process.env.ZIBBY_KEEP_SESSION_ENV==="true"}function ko(){if(!(process.env.ZIBBY_PIN_SESSION_PATH==="1"||process.env.ZIBBY_PIN_SESSION_PATH==="true"))return;let e=process.env.ZIBBY_SESSION_PATH;if(!(e==null||String(e).trim()===""))try{return $t(String(e).trim())}catch{return String(e).trim()}}function xo(){Ao()||(delete process.env.ZIBBY_SESSION_PATH,delete process.env.ZIBBY_SESSION_ID)}function Oo({sessionPath:o,sessionId:e}){o&&typeof o=="string"&&(process.env.ZIBBY_SESSION_PATH=o),e!=null&&String(e).trim()!==""&&(process.env.ZIBBY_SESSION_ID=String(e).trim())}function No(o={}){let e=et.map(s=>process.env[s]).find(Boolean),t=Math.random().toString(36).slice(2,6),r=e||`${Date.now()}_${t}`,a=o.paths?.sessionPrefix;return a?`${a}_${r}`:r}function Po({cwd:o=process.cwd(),config:e={},initialState:t={},traceFrom:r="resolveWorkflowSession"}={}){let a=t.sessionPath,s=t.sessionTimestamp,n="initialState.sessionPath";if(!a&&process.env.ZIBBY_SESSION_PATH)try{let d=$t(String(process.env.ZIBBY_SESSION_PATH));d&&(a=d,n="ZIBBY_SESSION_PATH")}catch{}let i;if(a)i=String(a).split(/[/\\]/).filter(Boolean).pop(),s==null&&(s=Date.now());else{let d=process.env.ZIBBY_SESSION_ID&&String(process.env.ZIBBY_SESSION_ID).trim();if(d)i=d,n="ZIBBY_SESSION_ID";else{let l=e.sessionId!=null?String(e.sessionId).trim():"";l&&l!=="last"?(i=l,n="config.sessionId"):(i=No(e),n="generated")}s=s??Date.now();let h=e.paths?.output||ue;a=Y(o,h,Xe,i)}let u=!Ne(a);return u&&bt(a,{recursive:!0}),(u||n!=="initialState.sessionPath")&&To({traceFrom:r,sessionId:i,sessionPath:a,idSource:n,mkdirFresh:u}),Oo({sessionPath:a,sessionId:i}),{sessionPath:a,sessionId:i,sessionTimestamp:s}}var ge=class{constructor(e={}){this.nodes=new Map,this.edges=new Map,this.entryPoint=null,this.middleware=Array.isArray(e.middleware)?[...e.middleware]:[],e.nodeMiddleware&&this.middleware.push(e.nodeMiddleware),this.nodeTypeMap=new Map,this.conditionalCodeMap=new Map,this.stateSchema=e.stateSchema||null,this.inputSchema=e.inputSchema||null,this.contextSchema=e.contextSchema||null,this.nodePrompts=new Map,this.nodeOptions=new Map,this._invokeAgent=e.invokeAgent||null,this._compiledPrompts=new Map}setInputSchema(e){return this.inputSchema=e,this}setContextSchema(e){return this.contextSchema=e,this}setStateSchema(e){return this.stateSchema=e,this}getInputSchema(){return this.inputSchema}getContextSchema(){return this.contextSchema}getStateSchema(){return this.stateSchema}_runtimeSchema(){if(this.inputSchema&&this.contextSchema)try{if(typeof this.inputSchema.merge=="function")return this.inputSchema.merge(this.contextSchema);if(typeof this.inputSchema.and=="function")return this.inputSchema.and(this.contextSchema)}catch{}return this.inputSchema&&!this.contextSchema?this.inputSchema:this.stateSchema}addNode(e,t,r={}){if(!(t instanceof L)&&t&&typeof t=="object"&&typeof t.workflow=="string"){let n=t,i={name:e,_isCustomCode:!0,dispatchesWorkflow:n.workflow,retries:n.retries,onComplete:n.onComplete,execute:async d=>{let h=d?.state&&typeof d.state.getAll=="function"?d.state.getAll():d,l;return typeof n.input=="function"?l=n.input(h):n.input&&typeof n.input=="object"?l=n.input:l={},yt(n.workflow,{input:l,async:n.async===!0,conversationId:typeof n.conversationId=="function"?n.conversationId(h):n.conversationId,output:n.output,timeoutMs:n.timeoutMs,pollIntervalMs:n.pollIntervalMs,signal:h?._signal,parentAgent:d?.agent})}},u=new L(i);return u.name=e,this.nodes.set(e,u),r.prompt&&this.nodePrompts.set(e,r.prompt),Object.keys(r).length>0&&this.nodeOptions.set(e,r),this}let a=!(t instanceof L)&&t&&typeof t=="object"&&typeof t.execute!="function"&&t.prompt==null&&t.outputSchema==null&&t._isCustomCode!==!0,s=t instanceof L?t:new L(a?{...t,_isRouter:!0}:t);return s.name=e,this.nodes.set(e,s),r.prompt?this.nodePrompts.set(e,r.prompt):typeof t?.prompt=="string"&&t.prompt.trim()&&this.nodePrompts.set(e,t.prompt),Object.keys(r).length>0&&this.nodeOptions.set(e,r),this}addEdge(e,t){return this.edges.set(e,t),this}setNodeType(e,t){return this.nodeTypeMap.set(e,t),this}addConditionalEdges(e,t,{labels:r}={}){return this.edges.set(e,{conditional:!0,routes:t,labels:r}),typeof t=="function"&&this.conditionalCodeMap.set(e,t.toString()),this}setEntryPoint(e){return this.entryPoint=e,this}use(e){return typeof e=="function"&&this.middleware.push(e),this}_composeMiddleware(e,t,r,a,s){let n=r;for(let i=e.length-1;i>=0;i--){let u=e[i],d=n;n=()=>u(t,d,a,s)}return n()}serialize(){let e=[],t={};for(let[l,c]of this.nodes){let m=this.nodeTypeMap.get(l)||(c?.config?._isRouter===!0?"decision":l);e.push({id:l,type:m,data:{nodeType:m,label:l}});let S={};c._isCustomCode&&typeof c.execute=="function"&&(S.customCode=c.execute.toString());let _=typeof c?.config?.description=="string"&&c.config.description.trim()?c.config.description:typeof c?.description=="string"&&c.description.trim()?c.description:null;_&&(S.description=_);let v=this.nodePrompts.get(l);if(v)S.prompt=v;else if(typeof c.prompt=="function")try{let p=c.prompt({});typeof p=="string"&&p.trim()&&(S.prompt=p,S.promptIsCode=!0)}catch{}if(typeof c.customExecute=="function"&&(S.executeCode=c.customExecute.toString()),typeof c?.config?.dispatchesWorkflow=="string"&&c.config.dispatchesWorkflow.trim()&&(S.dispatchesWorkflow=c.config.dispatchesWorkflow.trim()),c.outputSchema)if(typeof c.outputSchema._def<"u"){let p=null;if(typeof he?.toJSONSchema=="function")try{p=he.toJSONSchema(c.outputSchema)}catch{}if(!p)try{p=Et(c.outputSchema,{target:"openApi3"})}catch{}S.outputSchema=p?{jsonSchema:p,variables:this._flattenJsonSchemaToVariables(p)}:{schema:c.outputSchema}}else S.outputSchema={schema:c.outputSchema};let E=(this.resolvedToolsMap||{})[l];E?.toolIds&&(S.tools=E.toolIds);let g=Array.isArray(c?.config?.skills)?c.config.skills:Array.isArray(c?.skills)?c.skills:null;g&&g.length>0&&(S.skills=[...g]);let f=Array.isArray(c?.config?.plugins)?c.config.plugins:Array.isArray(c?.plugins)?c.plugins:null;f&&f.length>0&&(S.plugins=f.map(p=>p&&typeof p=="object"?{...p}:p));let y=Array.isArray(c?.config?.stores)?c.config.stores:Array.isArray(c?.stores)?c.stores:null;y&&y.length>0&&(S.stores=y.map(p=>p&&typeof p=="object"?{...p}:p)),Object.keys(S).length>0&&(t[l]=S)}let r=[];for(let[l,c]of this.edges)if(typeof c=="string")r.push({source:l,target:c});else if(c.conditional){let m=this.conditionalCodeMap.get(l)||c.routes.toString(),S=this._inferConditionalTargets(c.routes,c.labels),_=c.labels||{},v=this.nodes.get(l),E=v?.config?._isRouter===!0||this.nodeTypeMap.get(l)==="decision"||!v,g=l;if(!E){let f=`${l}__branch`;e.push({id:f,type:"decision",data:{nodeType:"decision",label:f}}),r.push({source:l,target:f}),g=f}for(let f of S){let y={source:g,target:f,data:{conditionalCode:m}};_[f]&&(y.label=_[f]),r.push(y)}}let a=l=>{if(!l)return null;if(typeof he?.toJSONSchema=="function")try{return he.toJSONSchema(l)}catch{}try{return Et(l,{target:"openApi3"})}catch{return null}};this.entryPoint&&this.nodes.has(this.entryPoint)&&(e.unshift({id:"START",type:"start",data:{nodeType:"start",label:"Start"}}),r.unshift({source:"START",target:this.entryPoint}));let s=0;for(let l of r)if(l.target==="END"){s+=1;let c=`END__${s}`;l.target=c,e.push({id:c,type:"end",data:{nodeType:"end",label:"End"}})}for(let l of this.nodes.keys())if(!this.edges.has(l)){s+=1;let c=`END__${s}`;e.push({id:c,type:"end",data:{nodeType:"end",label:"End"}}),r.push({source:l,target:c})}let n=this._topoOrderNodes(e,r),i=this._runtimeSchema(),u=a(i||this.stateSchema),d=a(this.inputSchema),h=a(this.contextSchema);return{nodes:n,edges:r,nodeConfigs:t,stateSchema:u,inputSchema:d,contextSchema:h}}_topoOrderNodes(e,t){let r=new Map(e.map((l,c)=>[l.id,c])),a=new Map(e.map(l=>[l.id,l])),s=new Map(e.map(l=>[l.id,0])),n=new Map(e.map(l=>[l.id,[]]));for(let l of t)n.has(l.source)&&s.has(l.target)&&(n.get(l.source).push(l.target),s.set(l.target,s.get(l.target)+1));let i=new Set,u=new Set(r.keys()),d=[...u].filter(l=>s.get(l)===0),h=[];for(;h.length<e.length;){let l;if(d.length>0){if(d.sort((c,m)=>r.get(c)-r.get(m)),l=d.shift(),i.has(l))continue}else l=[...u].sort((c,m)=>r.get(c)-r.get(m))[0];i.add(l),u.delete(l),h.push(a.get(l));for(let c of n.get(l)||[])s.set(c,s.get(c)-1),s.get(c)<=0&&!i.has(c)&&d.push(c)}return h}_inferConditionalTargets(e,t){let r=e.toString(),a=new Set,s=/(['"])((?:\\.|(?!\1).)*?)\1|`((?:\\.|[^`$]|\$(?!\{))*?)`/g,n;for(;(n=s.exec(r))!==null;){let d=n[2]!==void 0?n[2]:n[3];d!==void 0&&d!==""&&a.add(d)}let i=new Set(["END","START","__end__","__start__"]);for(let d of this.nodes.keys())i.add(d);if(t&&typeof t=="object")for(let d of Object.keys(t))i.add(d);let u=new Set;for(let d of a)i.has(d)&&u.add(d);if(u.size===0){let d=/return\s+['"]([^'"]+)['"]/g,h;for(;(h=d.exec(r))!==null;)u.add(h[1])}return[...u]}_flattenJsonSchemaToVariables(e,t=""){let r=e;if(e.$ref&&e.definitions){let a=e.$ref.replace("#/definitions/","");r=e.definitions[a]||e}return this._flattenSchema(r,t)}_flattenSchema(e,t=""){if(!e||typeof e!="object")return[];let r=[],a=e.properties||{},s=e.required||[];for(let[n,i]of Object.entries(a)){let u=t?`${t}.${n}`:n;r.push({path:u,type:i.type||"unknown",label:i.description||this._formatLabel(n),optional:!s.includes(n)}),i.type==="object"&&i.properties&&r.push(...this._flattenSchema(i,u)),i.type==="array"&&i.items?.type==="object"&&i.items.properties&&r.push(...this._flattenSchema(i.items,`${u}[]`))}return r}_formatLabel(e){return e.replace(/([A-Z])/g," $1").replace(/^./,t=>t.toUpperCase()).trim()}_summarizeNodeOutput(e,t){if(!t||typeof t!="object")return[];let r=[];t.success!==void 0&&r.push(`Result: ${t.success?"passed":"failed"}`);for(let[a,s]of Object.entries(t))if(!(a==="success"||a==="raw"||a==="nextNode")){if(typeof s=="string"&&s.length<=80)r.push(`${a}: ${s}`);else if(Array.isArray(s)){let n=s.length,i=s.filter(d=>d?.passed===!0).length,u=s.some(d=>d?.passed!==void 0);r.push(u?`${a}: ${i}/${n} passed${n-i?`, ${n-i} failed`:""}`:`${a}: ${n} items`)}if(r.length>=4)break}return r}async run(e,t={},r={}){if(!this.entryPoint)throw new Error("No entry point set for graph");let a=new AbortController;r.signal&&(r.signal.aborted?a.abort():r.signal.addEventListener("abort",()=>a.abort(),{once:!0}));let s=r.strategyAbortTimeoutMs??t.config?.strategyAbortTimeoutMs??5e3,n=t.cwd||process.cwd();$o({path:Y(n,".env")});let i=t.config||{};if(!i||Object.keys(i).length===0)try{let $=Y(n,".zibby.config.js");Ne($)&&(i=(await import($)).default||{})}catch{}process.env.EXECUTION_ID&&!i.agent?.strictMode&&(i.agent={...i.agent,strictMode:!0});let u=t.agentType;if(!u){let $=i?.agent;$?.provider?u=$.provider:$?.gemini?u="gemini":$?.claude?u="claude":$?.cursor?u="cursor":$?.codex?u="codex":u=process.env.AGENT_TYPE||"cursor"}let d=t.contextConfig||e?.config?.contextConfig||e?.config?.context||i?.context||{},h=this._runtimeSchema();if(h){let $=h.safeParse(t);if(!$.success){let P=$.error.issues.map(C=>`${C.path.join(".")}: ${C.message}`);throw console.error("\u274C Initial state validation failed:"),P.forEach(C=>console.error(` - ${C}`)),new Error(`State validation failed: ${P.join(", ")}`)}O.step("State validated against schema")}let l=ko(),c=t.sessionPath||l;c||xo();let{sessionPath:m,sessionTimestamp:S,sessionId:_}=Po({cwd:n,config:i,traceFrom:"WorkflowGraph.run",initialState:{sessionPath:c,sessionTimestamp:t.sessionTimestamp}});O.step(`Session ${_}`);let v=await fe.loadContext(t.specPath||"",n,d);Object.keys(v).length>0&&O.step(`Context loaded: ${Object.keys(v).join(", ")}`);let E=t.outputPath;!E&&t.specPath&&(e?.calculateOutputPath?E=e.calculateOutputPath(t.specPath):console.warn(`\u26A0\uFE0F outputPath not resolved (specPath=${t.specPath})`));let g=new ae({...t,config:i,agentType:u,outputPath:E,sessionPath:m,sessionTimestamp:S,context:v,resolvedTools:this.resolvedToolsMap||{},_signal:a.signal}),f=new Map;try{await import("@zibby/skills")}catch{}let{getSkill:y}=await Promise.resolve().then(()=>(de(),ot)),p=i.skills&&typeof i.skills=="object"?i.skills:{},b=Object.values(p).filter($=>$&&typeof $=="object"&&typeof $.id=="string"),A=$=>{for(let P of b)if(P.id===$)return P;return y($)},R=new Set;for(let[,$]of this.nodes)for(let P of $.config?.skills||[])R.add(P);for(let $ of R){let P=A($);if(typeof P?.middleware=="function")try{let C=await P.middleware();typeof C=="function"&&f.set($,C)}catch{}}let w=this.entryPoint,re=[],Be=i?.recursionLimit??100,xt=0;try{for(;w&&w!=="END";){if(++xt>Be)throw new Error(`Workflow exceeded recursion limit (${Be}) \u2014 likely a cyclic conditional route. Set config.recursionLimit if you need a higher cap.`);let P=Y(m,Qe);if(Ne(P)){try{bo(P)}catch{}a.abort()}if(a.signal.aborted)return console.warn(`
41
+ ${h}`)}}function Ao(){return process.env.ZIBBY_TRUST_SESSION_ENV==="1"||process.env.ZIBBY_TRUST_SESSION_ENV==="true"||process.env.ZIBBY_KEEP_SESSION_ENV==="1"||process.env.ZIBBY_KEEP_SESSION_ENV==="true"}function ko(){if(!(process.env.ZIBBY_PIN_SESSION_PATH==="1"||process.env.ZIBBY_PIN_SESSION_PATH==="true"))return;let e=process.env.ZIBBY_SESSION_PATH;if(!(e==null||String(e).trim()===""))try{return $t(String(e).trim())}catch{return String(e).trim()}}function xo(){Ao()||(delete process.env.ZIBBY_SESSION_PATH,delete process.env.ZIBBY_SESSION_ID)}function Oo({sessionPath:o,sessionId:e}){o&&typeof o=="string"&&(process.env.ZIBBY_SESSION_PATH=o),e!=null&&String(e).trim()!==""&&(process.env.ZIBBY_SESSION_ID=String(e).trim())}function No(o={}){let e=et.map(s=>process.env[s]).find(Boolean),t=Math.random().toString(36).slice(2,6),r=e||`${Date.now()}_${t}`,a=o.paths?.sessionPrefix;return a?`${a}_${r}`:r}function Po({cwd:o=process.cwd(),config:e={},initialState:t={},traceFrom:r="resolveWorkflowSession"}={}){let a=t.sessionPath,s=t.sessionTimestamp,n="initialState.sessionPath";if(!a&&process.env.ZIBBY_SESSION_PATH)try{let d=$t(String(process.env.ZIBBY_SESSION_PATH));d&&(a=d,n="ZIBBY_SESSION_PATH")}catch{}let i;if(a)i=String(a).split(/[/\\]/).filter(Boolean).pop(),s==null&&(s=Date.now());else{let d=process.env.ZIBBY_SESSION_ID&&String(process.env.ZIBBY_SESSION_ID).trim();if(d)i=d,n="ZIBBY_SESSION_ID";else{let l=e.sessionId!=null?String(e.sessionId).trim():"";l&&l!=="last"?(i=l,n="config.sessionId"):(i=No(e),n="generated")}s=s??Date.now();let h=e.paths?.output||ue;a=Y(o,h,Xe,i)}let u=!Ne(a);return u&&bt(a,{recursive:!0}),(u||n!=="initialState.sessionPath")&&To({traceFrom:r,sessionId:i,sessionPath:a,idSource:n,mkdirFresh:u}),Oo({sessionPath:a,sessionId:i}),{sessionPath:a,sessionId:i,sessionTimestamp:s}}var ge=class{constructor(e={}){this.nodes=new Map,this.edges=new Map,this.entryPoint=null,this.middleware=Array.isArray(e.middleware)?[...e.middleware]:[],e.nodeMiddleware&&this.middleware.push(e.nodeMiddleware),this.nodeTypeMap=new Map,this.conditionalCodeMap=new Map,this.stateSchema=e.stateSchema||null,this.inputSchema=e.inputSchema||null,this.contextSchema=e.contextSchema||null,this.nodePrompts=new Map,this.nodeOptions=new Map,this._invokeAgent=e.invokeAgent||null,this._compiledPrompts=new Map}setInputSchema(e){return this.inputSchema=e,this}setContextSchema(e){return this.contextSchema=e,this}setStateSchema(e){return this.stateSchema=e,this}getInputSchema(){return this.inputSchema}getContextSchema(){return this.contextSchema}getStateSchema(){return this.stateSchema}_runtimeSchema(){if(this.inputSchema&&this.contextSchema)try{if(typeof this.inputSchema.merge=="function")return this.inputSchema.merge(this.contextSchema);if(typeof this.inputSchema.and=="function")return this.inputSchema.and(this.contextSchema)}catch{}return this.inputSchema&&!this.contextSchema?this.inputSchema:this.stateSchema}addNode(e,t,r={}){if(!(t instanceof L)&&t&&typeof t=="object"&&typeof t.workflow=="string"){let n=t,i={name:e,_isCustomCode:!0,dispatchesWorkflow:n.workflow,retries:n.retries,onComplete:n.onComplete,execute:async d=>{let h=d?.state&&typeof d.state.getAll=="function"?d.state.getAll():d,l;return typeof n.input=="function"?l=n.input(h):n.input&&typeof n.input=="object"?l=n.input:l={},yt(n.workflow,{input:l,async:n.async===!0,conversationId:typeof n.conversationId=="function"?n.conversationId(h):n.conversationId,output:n.output,timeoutMs:n.timeoutMs,pollIntervalMs:n.pollIntervalMs,signal:h?._signal,parentAgent:d?.agent})}},u=new L(i);return u.name=e,this.nodes.set(e,u),r.prompt&&this.nodePrompts.set(e,r.prompt),Object.keys(r).length>0&&this.nodeOptions.set(e,r),this}let a=!(t instanceof L)&&t&&typeof t=="object"&&typeof t.execute!="function"&&t.prompt==null&&t.outputSchema==null&&t._isCustomCode!==!0,s=t instanceof L?t:new L(a?{...t,_isRouter:!0}:t);return s.name=e,this.nodes.set(e,s),r.prompt?this.nodePrompts.set(e,r.prompt):typeof t?.prompt=="string"&&t.prompt.trim()&&this.nodePrompts.set(e,t.prompt),Object.keys(r).length>0&&this.nodeOptions.set(e,r),this}addEdge(e,t){return this.edges.set(e,t),this}setNodeType(e,t){return this.nodeTypeMap.set(e,t),this}addConditionalEdges(e,t,{labels:r}={}){return this.edges.set(e,{conditional:!0,routes:t,labels:r}),typeof t=="function"&&this.conditionalCodeMap.set(e,t.toString()),this}setEntryPoint(e){return this.entryPoint=e,this}use(e){return typeof e=="function"&&this.middleware.push(e),this}_composeMiddleware(e,t,r,a,s){let n=r;for(let i=e.length-1;i>=0;i--){let u=e[i],d=n;n=()=>u(t,d,a,s)}return n()}serialize(){let e=[],t={};for(let[l,c]of this.nodes){let m=this.nodeTypeMap.get(l)||(c?.config?._isRouter===!0?"decision":l);e.push({id:l,type:m,data:{nodeType:m,label:l}});let S={};c._isCustomCode&&typeof c.execute=="function"&&(S.customCode=c.execute.toString());let _=typeof c?.config?.description=="string"&&c.config.description.trim()?c.config.description:typeof c?.description=="string"&&c.description.trim()?c.description:null;_&&(S.description=_);let v=this.nodePrompts.get(l);if(v)S.prompt=v;else if(typeof c.prompt=="function")try{let p=c.prompt({});typeof p=="string"&&p.trim()&&(S.prompt=p,S.promptIsCode=!0)}catch{}if(typeof c.customExecute=="function"&&(S.executeCode=c.customExecute.toString()),typeof c?.config?.dispatchesWorkflow=="string"&&c.config.dispatchesWorkflow.trim()&&(S.dispatchesWorkflow=c.config.dispatchesWorkflow.trim()),c.outputSchema)if(typeof c.outputSchema._def<"u"){let p=null;if(typeof he?.toJSONSchema=="function")try{p=he.toJSONSchema(c.outputSchema)}catch{}if(!p)try{p=Et(c.outputSchema,{target:"openApi3"})}catch{}S.outputSchema=p?{jsonSchema:p,variables:this._flattenJsonSchemaToVariables(p)}:{schema:c.outputSchema}}else S.outputSchema={schema:c.outputSchema};let E=(this.resolvedToolsMap||{})[l];E?.toolIds&&(S.tools=E.toolIds);let g=Array.isArray(c?.config?.skills)?c.config.skills:Array.isArray(c?.skills)?c.skills:null;g&&g.length>0&&(S.skills=[...g]);let f=Array.isArray(c?.config?.plugins)?c.config.plugins:Array.isArray(c?.plugins)?c.plugins:null;f&&f.length>0&&(S.plugins=f.map(p=>p&&typeof p=="object"?{...p}:p));let y=Array.isArray(c?.config?.stores)?c.config.stores:Array.isArray(c?.stores)?c.stores:null;y&&y.length>0&&(S.stores=y.map(p=>p&&typeof p=="object"?{...p}:p)),Object.keys(S).length>0&&(t[l]=S)}let r=[];for(let[l,c]of this.edges)if(typeof c=="string")r.push({source:l,target:c});else if(c.conditional){let m=this.conditionalCodeMap.get(l)||c.routes.toString(),S=this._inferConditionalTargets(c.routes,c.labels),_=c.labels||{},v=this.nodes.get(l),E=v?.config?._isRouter===!0||this.nodeTypeMap.get(l)==="decision"||!v,g=l;if(!E){let f=`${l}__branch`;e.push({id:f,type:"decision",data:{nodeType:"decision",label:f}}),r.push({source:l,target:f}),g=f}for(let f of S){let y={source:g,target:f,data:{conditionalCode:m}};_[f]&&(y.label=_[f]),r.push(y)}}let a=l=>{if(!l)return null;if(typeof he?.toJSONSchema=="function")try{return he.toJSONSchema(l)}catch{}try{return Et(l,{target:"openApi3"})}catch{return null}};this.entryPoint&&this.nodes.has(this.entryPoint)&&(e.unshift({id:"START",type:"start",data:{nodeType:"start",label:"Start"}}),r.unshift({source:"START",target:this.entryPoint}));let s=0;for(let l of r)if(l.target==="END"){s+=1;let c=`END__${s}`;l.target=c,e.push({id:c,type:"end",data:{nodeType:"end",label:"End"}})}for(let l of this.nodes.keys())if(!this.edges.has(l)){s+=1;let c=`END__${s}`;e.push({id:c,type:"end",data:{nodeType:"end",label:"End"}}),r.push({source:l,target:c})}let n=this._topoOrderNodes(e,r),i=this._runtimeSchema(),u=a(i||this.stateSchema),d=a(this.inputSchema),h=a(this.contextSchema);return{nodes:n,edges:r,nodeConfigs:t,stateSchema:u,inputSchema:d,contextSchema:h}}_topoOrderNodes(e,t){let r=new Map(e.map((l,c)=>[l.id,c])),a=new Map(e.map(l=>[l.id,l])),s=new Map(e.map(l=>[l.id,0])),n=new Map(e.map(l=>[l.id,[]]));for(let l of t)n.has(l.source)&&s.has(l.target)&&(n.get(l.source).push(l.target),s.set(l.target,s.get(l.target)+1));let i=new Set,u=new Set(r.keys()),d=[...u].filter(l=>s.get(l)===0),h=[];for(;h.length<e.length;){let l;if(d.length>0){if(d.sort((c,m)=>r.get(c)-r.get(m)),l=d.shift(),i.has(l))continue}else l=[...u].sort((c,m)=>r.get(c)-r.get(m))[0];i.add(l),u.delete(l),h.push(a.get(l));for(let c of n.get(l)||[])s.set(c,s.get(c)-1),s.get(c)<=0&&!i.has(c)&&d.push(c)}return h}_inferConditionalTargets(e,t){let r=e.toString(),a=new Set,s=/(['"])((?:\\.|(?!\1).)*?)\1|`((?:\\.|[^`$]|\$(?!\{))*?)`/g,n;for(;(n=s.exec(r))!==null;){let d=n[2]!==void 0?n[2]:n[3];d!==void 0&&d!==""&&a.add(d)}let i=new Set(["END","START","__end__","__start__"]);for(let d of this.nodes.keys())i.add(d);if(t&&typeof t=="object")for(let d of Object.keys(t))i.add(d);let u=new Set;for(let d of a)i.has(d)&&u.add(d);if(u.size===0){let d=/return\s+['"]([^'"]+)['"]/g,h;for(;(h=d.exec(r))!==null;)u.add(h[1])}return[...u]}_flattenJsonSchemaToVariables(e,t=""){let r=e;if(e.$ref&&e.definitions){let a=e.$ref.replace("#/definitions/","");r=e.definitions[a]||e}return this._flattenSchema(r,t)}_flattenSchema(e,t=""){if(!e||typeof e!="object")return[];let r=[],a=e.properties||{},s=e.required||[];for(let[n,i]of Object.entries(a)){let u=t?`${t}.${n}`:n;r.push({path:u,type:i.type||"unknown",label:i.description||this._formatLabel(n),optional:!s.includes(n)}),i.type==="object"&&i.properties&&r.push(...this._flattenSchema(i,u)),i.type==="array"&&i.items?.type==="object"&&i.items.properties&&r.push(...this._flattenSchema(i.items,`${u}[]`))}return r}_formatLabel(e){return e.replace(/([A-Z])/g," $1").replace(/^./,t=>t.toUpperCase()).trim()}_summarizeNodeOutput(e,t){if(!t||typeof t!="object")return[];let r=[];t.success!==void 0&&r.push(`Result: ${t.success?"passed":"failed"}`);for(let[a,s]of Object.entries(t))if(!(a==="success"||a==="raw"||a==="nextNode")){if(typeof s=="string"&&s.length<=80)r.push(`${a}: ${s}`);else if(Array.isArray(s)){let n=s.length,i=s.filter(d=>d?.passed===!0).length,u=s.some(d=>d?.passed!==void 0);r.push(u?`${a}: ${i}/${n} passed${n-i?`, ${n-i} failed`:""}`:`${a}: ${n} items`)}if(r.length>=4)break}return r}async run(e,t={},r={}){if(!this.entryPoint)throw new Error("No entry point set for graph");let a=new AbortController;r.signal&&(r.signal.aborted?a.abort():r.signal.addEventListener("abort",()=>a.abort(),{once:!0}));let s=r.strategyAbortTimeoutMs??t.config?.strategyAbortTimeoutMs??5e3,n=t.cwd||process.cwd();$o({path:Y(n,".env")});let i=t.config||{};if(!i||Object.keys(i).length===0)try{let $=Y(n,".zibby.config.js");Ne($)&&(i=(await import($)).default||{})}catch{}process.env.EXECUTION_ID&&!i.agent?.strictMode&&(i.agent={...i.agent,strictMode:!0});let u=t.agentType;if(!u){let $=i?.agent;$?.provider?u=$.provider:$?.gemini?u="gemini":$?.claude?u="claude":$?.cursor?u="cursor":$?.codex?u="codex":u=process.env.AGENT_TYPE||"claude"}let d=t.contextConfig||e?.config?.contextConfig||e?.config?.context||i?.context||{},h=this._runtimeSchema();if(h){let $=h.safeParse(t);if(!$.success){let P=$.error.issues.map(C=>`${C.path.join(".")}: ${C.message}`);throw console.error("\u274C Initial state validation failed:"),P.forEach(C=>console.error(` - ${C}`)),new Error(`State validation failed: ${P.join(", ")}`)}O.step("State validated against schema")}let l=ko(),c=t.sessionPath||l;c||xo();let{sessionPath:m,sessionTimestamp:S,sessionId:_}=Po({cwd:n,config:i,traceFrom:"WorkflowGraph.run",initialState:{sessionPath:c,sessionTimestamp:t.sessionTimestamp}});O.step(`Session ${_}`);let v=await fe.loadContext(t.specPath||"",n,d);Object.keys(v).length>0&&O.step(`Context loaded: ${Object.keys(v).join(", ")}`);let E=t.outputPath;!E&&t.specPath&&(e?.calculateOutputPath?E=e.calculateOutputPath(t.specPath):console.warn(`\u26A0\uFE0F outputPath not resolved (specPath=${t.specPath})`));let g=new ae({...t,config:i,agentType:u,outputPath:E,sessionPath:m,sessionTimestamp:S,context:v,resolvedTools:this.resolvedToolsMap||{},_signal:a.signal}),f=new Map;try{await import("@zibby/skills")}catch{}let{getSkill:y}=await Promise.resolve().then(()=>(de(),ot)),p=i.skills&&typeof i.skills=="object"?i.skills:{},b=Object.values(p).filter($=>$&&typeof $=="object"&&typeof $.id=="string"),A=$=>{for(let P of b)if(P.id===$)return P;return y($)},R=new Set;for(let[,$]of this.nodes)for(let P of $.config?.skills||[])R.add(P);for(let $ of R){let P=A($);if(typeof P?.middleware=="function")try{let C=await P.middleware();typeof C=="function"&&f.set($,C)}catch{}}let w=this.entryPoint,re=[],Be=i?.recursionLimit??100,xt=0;try{for(;w&&w!=="END";){if(++xt>Be)throw new Error(`Workflow exceeded recursion limit (${Be}) \u2014 likely a cyclic conditional route. Set config.recursionLimit if you need a higher cap.`);let P=Y(m,Qe);if(Ne(P)){try{bo(P)}catch{}a.abort()}if(a.signal.aborted)return console.warn(`
42
42
  \u{1F6D1} External stop requested \u2014 ending workflow.`),O.step("Workflow stopped externally"),{success:!0,state:g.getAll(),executionLog:re,stoppedExternally:!0};let C=this.nodes.get(w);if(!C)throw new Error(`Node '${w}' not found in graph`);let Me=JSON.stringify({sessionPath:m,sessionTimestamp:S,currentNode:w,createdAt:new Date().toISOString(),config:g.get("config")}),Ot=Y(m,K);It(Ot,Me,"utf-8");let De=g.get("config")?.paths?.output||ue,Nt=Y(n,De,K);bt(Y(n,De),{recursive:!0});try{It(Nt,Me,"utf-8")}catch{}let je=t.onPipelineProgress;if(typeof je=="function")try{je({cwd:n,sessionPath:m,sessionId:_,outputBase:g.get("config")?.paths?.output||ue,currentNode:w})}catch{}let Pt=(this.resolvedToolsMap||{})[w]||null;g.set("_currentNodeTools",Pt);let Ct=g.get("nodeConfigs")||{};g.set("_currentNodeConfig",Ct[w]||{}),O.nodeStart(w);let Le=Date.now(),ne=this.nodePrompts.get(w);if(!this._invokeAgent){let k=await Promise.resolve().then(()=>(te(),ee));this._invokeAgent=k.invokeAgent}let Rt=this._invokeAgent,Se={},Bt=C.config?.skills||[];for(let k of Bt){let B=A(k);if(typeof B?.invokeAgentOptions=="function")try{let T=B.invokeAgentOptions(g.getAll(),{agentType:g.get("agentType"),nodeName:w});T&&typeof T=="object"&&(Se={...Se,...T})}catch(T){console.warn(`[graph] skill '${k}' invokeAgentOptions threw: ${T.message}`)}}let Ue=async(k,B,T={})=>{let M=Rt(k,B,{...Se,...T,signal:a.signal});return M.catch(()=>{}),a.signal.aborted?M:Promise.race([M,new Promise((Z,z)=>{let j=()=>{setTimeout(()=>{let V=new Error(`Strategy ignored AbortSignal \u2014 engine deadman fired after ${s}ms`);V.name="AbortError",z(V)},s)};a.signal.addEventListener("abort",j,{once:!0})})])},Mt=async(k={},B={})=>{let T=B.prompt||"";if(ne){let M=this._compiledPrompts.get(w);M||(M=vo.compile(ne,{noEscape:!0}),this._compiledPrompts.set(w,M));try{T=M(k)}catch(Z){throw console.error(`\u274C Template rendering failed for node '${w}':`,Z.message),new Error(`Template rendering failed: ${Z.message}`,{cause:Z})}}else if(!T)throw new Error(`No prompt template configured for node '${w}' and no prompt provided in options`);return Ue(T,{state:g.getAll(),images:B.images||[]},{model:B.model||g.get("model"),workspace:g.get("workspace"),schema:B.schema,...B,signal:a.signal})},We=g.getAll(),Dt=["state","invokeAgent","_coreInvokeAgent","agent","nodeId","promptTemplate","getPromptTemplate"];for(let k of Dt)Object.prototype.hasOwnProperty.call(We,k)&&console.warn(`[workflow] node "${w}": state key "${k}" is shadowed by the engine context prop; read it via context.state.get('${k}')`);let Ge={...We,state:g,invokeAgent:Mt,_coreInvokeAgent:Ue,agent:e,nodeId:w,promptTemplate:ne,getPromptTemplate:()=>ne};try{let k=(C.config?.skills||[]).map(j=>f.get(j)).filter(Boolean),B=[...this.middleware,...k],T;B.length>0?T=await this._composeMiddleware(B,w,async()=>C.execute(Ge,g),g.getAll(),g):T=await C.execute(Ge,g);let M=Date.now()-Le;if(re.push({node:w,success:T.success,duration:M,timestamp:new Date().toISOString()}),!T.success){if(a.signal.aborted)return O.step("Workflow stopped externally"),{success:!0,state:g.getAll(),executionLog:re,stoppedExternally:!0};g.append("errors",{node:w,error:T.error});let j=C.config?.retries||0,V=`${w}_retries`,se=g.getAll()[V]||0;if(se<j){O.stepInfo(`Retrying (attempt ${se+1}/${j})`),g.update({[V]:se+1,[`${w}_raw`]:T.raw});continue}throw O.nodeFailed(w,T.error,{duration:M}),new Error(`Node '${w}' failed after ${se} attempts: ${T.error}`)}g.update({[w]:T.output});let Z=this._summarizeNodeOutput(w,T.output);O.nodeComplete(w,{duration:M,details:Z});let z=this.edges.get(w);if(!z)w="END";else if(z.conditional){let j=z.routes(g.getAll());O.route(w,j),w=j}else w=z}catch(k){throw O.isInsideNode&&O.nodeFailed(w,k.message,{duration:Date.now()-Le}),g.set("failed",!0),g.set("failedAt",w),k}}O.graphComplete();let $={success:!0,state:g.getAll(),executionLog:re};return e&&typeof e.onComplete=="function"&&await e.onComplete($),$}finally{if(e&&typeof e.cleanup=="function")try{await e.cleanup()}catch($){console.warn(`[workflow] agent.cleanup() failed: ${$.message}`)}}}};var Pe=Symbol.for("@zibby/agent-workflow.nodes");globalThis[Pe]||(globalThis[Pe]=new Map);var Ce=globalThis[Pe];function Co(o,e){Ce.set(o,e)}function vt(o){return Ce.get(o)}function Re(o){return Ce.has(o)}Co("ai_agent",{name:"ai_agent",factory:!0,create:(o,e={})=>({name:o,_isCustomCode:!0,execute:async t=>{let r=t?._coreInvokeAgent;r||(r=(await Promise.resolve().then(()=>(te(),ee))).invokeAgent);let a=e.extraPromptInstructions||"Execute the task based on the current state.",s=Ro(a,t),n=await r(s,{cwd:t.workspace||process.cwd(),model:t.model,tools:e.resolvedTools||null});return{success:!0,output:{raw:n,nodeId:o},raw:typeof n=="string"?n:n.raw}}})});function Ro(o,e){let t=/@([\w.]+)/g,r=new Set,a;for(;(a=t.exec(o))!==null;)r.add(a[1]);if(r.size===0)return o;let s=[],n=new Set;for(let i of r){let u=i.split(".")[0];if(n.has(u))continue;let d=i.split(".").reduce((c,m)=>c?.[m],e);if(d===void 0)continue;let h=typeof d=="string"?d:d?.raw??JSON.stringify(d,null,2),l=i.replace(/_/g," ").replace(/\b\w/g,c=>c.toUpperCase());s.push(`## ${l}
43
43
  ${h}`),i.includes(".")||n.add(u)}return s.length===0?o:`${o}
44
44
 
package/dist/graph.js CHANGED
@@ -38,5 +38,5 @@ ${i}`);let a=r(),u=a.cwd||process.cwd(),p=a.sessionPath;try{if(p){let c=Et(p,Z);
38
38
  `):s.every(n=>typeof n=="object")?Object.assign({},...s):s[s.length-1]}static async loadFile(t){let e=pr(t,"utf-8");if(t.endsWith(".json"))return JSON.parse(e);if(t.endsWith(".js")||t.endsWith(".mjs")){let{pathToFileURL:r}=await import("url"),s=await import(r(t).href);return s.default||s}return e}};import{mkdirSync as Se,existsSync as vt,writeFileSync as he,unlinkSync as dr}from"node:fs";import{join as H,resolve as ye}from"node:path";import{config as fr}from"dotenv";import{zodToJsonSchema as ge}from"zod-to-json-schema";import{z as lt}from"zod";import hr from"handlebars";function gr({traceFrom:o,sessionId:t,sessionPath:e,idSource:r,mkdirFresh:s}){if(!(process.env.ZIBBY_SESSION_LOG==="1"||process.env.ZIBBY_SESSION_LOG==="true"))return;let n=typeof process.ppid=="number"?process.ppid:"n/a",a=`[zibby:session] from=${o} pid=${process.pid} ppid=${n} sessionId=${t} source=${r} mkdir=${s?"yes":"no"} path=${e}`;if(console.log(a),process.env.ZIBBY_TRACE_SESSION==="1"||process.env.ZIBBY_TRACE_SESSION==="true"){let g=(new Error("session trace").stack||"").split(`
39
39
  `).slice(2,14).join(`
40
40
  `);console.log(`[zibby:session] stack (${o}):
41
- ${g}`)}}function mr(){return process.env.ZIBBY_TRUST_SESSION_ENV==="1"||process.env.ZIBBY_TRUST_SESSION_ENV==="true"||process.env.ZIBBY_KEEP_SESSION_ENV==="1"||process.env.ZIBBY_KEEP_SESSION_ENV==="true"}function Sr(){if(!(process.env.ZIBBY_PIN_SESSION_PATH==="1"||process.env.ZIBBY_PIN_SESSION_PATH==="true"))return;let t=process.env.ZIBBY_SESSION_PATH;if(!(t==null||String(t).trim()===""))try{return ye(String(t).trim())}catch{return String(t).trim()}}function yr(){mr()||(delete process.env.ZIBBY_SESSION_PATH,delete process.env.ZIBBY_SESSION_ID)}function wr({sessionPath:o,sessionId:t}){o&&typeof o=="string"&&(process.env.ZIBBY_SESSION_PATH=o),t!=null&&String(t).trim()!==""&&(process.env.ZIBBY_SESSION_ID=String(t).trim())}function _r(o={}){let t=Zt.map(i=>process.env[i]).find(Boolean),e=Math.random().toString(36).slice(2,6),r=t||`${Date.now()}_${e}`,s=o.paths?.sessionPrefix;return s?`${s}_${r}`:r}function Ir({cwd:o=process.cwd(),config:t={},initialState:e={},traceFrom:r="resolveWorkflowSession"}={}){let s=e.sessionPath,i=e.sessionTimestamp,n="initialState.sessionPath";if(!s&&process.env.ZIBBY_SESSION_PATH)try{let p=ye(String(process.env.ZIBBY_SESSION_PATH));p&&(s=p,n="ZIBBY_SESSION_PATH")}catch{}let a;if(s)a=String(s).split(/[/\\]/).filter(Boolean).pop(),i==null&&(i=Date.now());else{let p=process.env.ZIBBY_SESSION_ID&&String(process.env.ZIBBY_SESSION_ID).trim();if(p)a=p,n="ZIBBY_SESSION_ID";else{let c=t.sessionId!=null?String(t.sessionId).trim():"";c&&c!=="last"?(a=c,n="config.sessionId"):(a=_r(t),n="generated")}i=i??Date.now();let g=t.paths?.output||it;s=H(o,g,Jt,a)}let u=!vt(s);return u&&Se(s,{recursive:!0}),(u||n!=="initialState.sessionPath")&&gr({traceFrom:r,sessionId:a,sessionPath:s,idSource:n,mkdirFresh:u}),wr({sessionPath:s,sessionId:a}),{sessionPath:s,sessionId:a,sessionTimestamp:i}}var me=class{constructor(t={}){this.nodes=new Map,this.edges=new Map,this.entryPoint=null,this.middleware=Array.isArray(t.middleware)?[...t.middleware]:[],t.nodeMiddleware&&this.middleware.push(t.nodeMiddleware),this.nodeTypeMap=new Map,this.conditionalCodeMap=new Map,this.stateSchema=t.stateSchema||null,this.inputSchema=t.inputSchema||null,this.contextSchema=t.contextSchema||null,this.nodePrompts=new Map,this.nodeOptions=new Map,this._invokeAgent=t.invokeAgent||null,this._compiledPrompts=new Map}setInputSchema(t){return this.inputSchema=t,this}setContextSchema(t){return this.contextSchema=t,this}setStateSchema(t){return this.stateSchema=t,this}getInputSchema(){return this.inputSchema}getContextSchema(){return this.contextSchema}getStateSchema(){return this.stateSchema}_runtimeSchema(){if(this.inputSchema&&this.contextSchema)try{if(typeof this.inputSchema.merge=="function")return this.inputSchema.merge(this.contextSchema);if(typeof this.inputSchema.and=="function")return this.inputSchema.and(this.contextSchema)}catch{}return this.inputSchema&&!this.contextSchema?this.inputSchema:this.stateSchema}addNode(t,e,r={}){if(!(e instanceof L)&&e&&typeof e=="object"&&typeof e.workflow=="string"){let n=e,a={name:t,_isCustomCode:!0,dispatchesWorkflow:n.workflow,retries:n.retries,onComplete:n.onComplete,execute:async p=>{let g=p?.state&&typeof p.state.getAll=="function"?p.state.getAll():p,c;return typeof n.input=="function"?c=n.input(g):n.input&&typeof n.input=="object"?c=n.input:c={},pe(n.workflow,{input:c,async:n.async===!0,conversationId:typeof n.conversationId=="function"?n.conversationId(g):n.conversationId,output:n.output,timeoutMs:n.timeoutMs,pollIntervalMs:n.pollIntervalMs,signal:g?._signal,parentAgent:p?.agent})}},u=new L(a);return u.name=t,this.nodes.set(t,u),r.prompt&&this.nodePrompts.set(t,r.prompt),Object.keys(r).length>0&&this.nodeOptions.set(t,r),this}let s=!(e instanceof L)&&e&&typeof e=="object"&&typeof e.execute!="function"&&e.prompt==null&&e.outputSchema==null&&e._isCustomCode!==!0,i=e instanceof L?e:new L(s?{...e,_isRouter:!0}:e);return i.name=t,this.nodes.set(t,i),r.prompt?this.nodePrompts.set(t,r.prompt):typeof e?.prompt=="string"&&e.prompt.trim()&&this.nodePrompts.set(t,e.prompt),Object.keys(r).length>0&&this.nodeOptions.set(t,r),this}addEdge(t,e){return this.edges.set(t,e),this}setNodeType(t,e){return this.nodeTypeMap.set(t,e),this}addConditionalEdges(t,e,{labels:r}={}){return this.edges.set(t,{conditional:!0,routes:e,labels:r}),typeof e=="function"&&this.conditionalCodeMap.set(t,e.toString()),this}setEntryPoint(t){return this.entryPoint=t,this}use(t){return typeof t=="function"&&this.middleware.push(t),this}_composeMiddleware(t,e,r,s,i){let n=r;for(let a=t.length-1;a>=0;a--){let u=t[a],p=n;n=()=>u(e,p,s,i)}return n()}serialize(){let t=[],e={};for(let[c,l]of this.nodes){let y=this.nodeTypeMap.get(c)||(l?.config?._isRouter===!0?"decision":c);t.push({id:c,type:y,data:{nodeType:y,label:c}});let w={};l._isCustomCode&&typeof l.execute=="function"&&(w.customCode=l.execute.toString());let $=typeof l?.config?.description=="string"&&l.config.description.trim()?l.config.description:typeof l?.description=="string"&&l.description.trim()?l.description:null;$&&(w.description=$);let v=this.nodePrompts.get(c);if(v)w.prompt=v;else if(typeof l.prompt=="function")try{let d=l.prompt({});typeof d=="string"&&d.trim()&&(w.prompt=d,w.promptIsCode=!0)}catch{}if(typeof l.customExecute=="function"&&(w.executeCode=l.customExecute.toString()),typeof l?.config?.dispatchesWorkflow=="string"&&l.config.dispatchesWorkflow.trim()&&(w.dispatchesWorkflow=l.config.dispatchesWorkflow.trim()),l.outputSchema)if(typeof l.outputSchema._def<"u"){let d=null;if(typeof lt?.toJSONSchema=="function")try{d=lt.toJSONSchema(l.outputSchema)}catch{}if(!d)try{d=ge(l.outputSchema,{target:"openApi3"})}catch{}w.outputSchema=d?{jsonSchema:d,variables:this._flattenJsonSchemaToVariables(d)}:{schema:l.outputSchema}}else w.outputSchema={schema:l.outputSchema};let b=(this.resolvedToolsMap||{})[c];b?.toolIds&&(w.tools=b.toolIds);let h=Array.isArray(l?.config?.skills)?l.config.skills:Array.isArray(l?.skills)?l.skills:null;h&&h.length>0&&(w.skills=[...h]);let f=Array.isArray(l?.config?.plugins)?l.config.plugins:Array.isArray(l?.plugins)?l.plugins:null;f&&f.length>0&&(w.plugins=f.map(d=>d&&typeof d=="object"?{...d}:d));let m=Array.isArray(l?.config?.stores)?l.config.stores:Array.isArray(l?.stores)?l.stores:null;m&&m.length>0&&(w.stores=m.map(d=>d&&typeof d=="object"?{...d}:d)),Object.keys(w).length>0&&(e[c]=w)}let r=[];for(let[c,l]of this.edges)if(typeof l=="string")r.push({source:c,target:l});else if(l.conditional){let y=this.conditionalCodeMap.get(c)||l.routes.toString(),w=this._inferConditionalTargets(l.routes,l.labels),$=l.labels||{},v=this.nodes.get(c),b=v?.config?._isRouter===!0||this.nodeTypeMap.get(c)==="decision"||!v,h=c;if(!b){let f=`${c}__branch`;t.push({id:f,type:"decision",data:{nodeType:"decision",label:f}}),r.push({source:c,target:f}),h=f}for(let f of w){let m={source:h,target:f,data:{conditionalCode:y}};$[f]&&(m.label=$[f]),r.push(m)}}let s=c=>{if(!c)return null;if(typeof lt?.toJSONSchema=="function")try{return lt.toJSONSchema(c)}catch{}try{return ge(c,{target:"openApi3"})}catch{return null}};this.entryPoint&&this.nodes.has(this.entryPoint)&&(t.unshift({id:"START",type:"start",data:{nodeType:"start",label:"Start"}}),r.unshift({source:"START",target:this.entryPoint}));let i=0;for(let c of r)if(c.target==="END"){i+=1;let l=`END__${i}`;c.target=l,t.push({id:l,type:"end",data:{nodeType:"end",label:"End"}})}for(let c of this.nodes.keys())if(!this.edges.has(c)){i+=1;let l=`END__${i}`;t.push({id:l,type:"end",data:{nodeType:"end",label:"End"}}),r.push({source:c,target:l})}let n=this._topoOrderNodes(t,r),a=this._runtimeSchema(),u=s(a||this.stateSchema),p=s(this.inputSchema),g=s(this.contextSchema);return{nodes:n,edges:r,nodeConfigs:e,stateSchema:u,inputSchema:p,contextSchema:g}}_topoOrderNodes(t,e){let r=new Map(t.map((c,l)=>[c.id,l])),s=new Map(t.map(c=>[c.id,c])),i=new Map(t.map(c=>[c.id,0])),n=new Map(t.map(c=>[c.id,[]]));for(let c of e)n.has(c.source)&&i.has(c.target)&&(n.get(c.source).push(c.target),i.set(c.target,i.get(c.target)+1));let a=new Set,u=new Set(r.keys()),p=[...u].filter(c=>i.get(c)===0),g=[];for(;g.length<t.length;){let c;if(p.length>0){if(p.sort((l,y)=>r.get(l)-r.get(y)),c=p.shift(),a.has(c))continue}else c=[...u].sort((l,y)=>r.get(l)-r.get(y))[0];a.add(c),u.delete(c),g.push(s.get(c));for(let l of n.get(c)||[])i.set(l,i.get(l)-1),i.get(l)<=0&&!a.has(l)&&p.push(l)}return g}_inferConditionalTargets(t,e){let r=t.toString(),s=new Set,i=/(['"])((?:\\.|(?!\1).)*?)\1|`((?:\\.|[^`$]|\$(?!\{))*?)`/g,n;for(;(n=i.exec(r))!==null;){let p=n[2]!==void 0?n[2]:n[3];p!==void 0&&p!==""&&s.add(p)}let a=new Set(["END","START","__end__","__start__"]);for(let p of this.nodes.keys())a.add(p);if(e&&typeof e=="object")for(let p of Object.keys(e))a.add(p);let u=new Set;for(let p of s)a.has(p)&&u.add(p);if(u.size===0){let p=/return\s+['"]([^'"]+)['"]/g,g;for(;(g=p.exec(r))!==null;)u.add(g[1])}return[...u]}_flattenJsonSchemaToVariables(t,e=""){let r=t;if(t.$ref&&t.definitions){let s=t.$ref.replace("#/definitions/","");r=t.definitions[s]||t}return this._flattenSchema(r,e)}_flattenSchema(t,e=""){if(!t||typeof t!="object")return[];let r=[],s=t.properties||{},i=t.required||[];for(let[n,a]of Object.entries(s)){let u=e?`${e}.${n}`:n;r.push({path:u,type:a.type||"unknown",label:a.description||this._formatLabel(n),optional:!i.includes(n)}),a.type==="object"&&a.properties&&r.push(...this._flattenSchema(a,u)),a.type==="array"&&a.items?.type==="object"&&a.items.properties&&r.push(...this._flattenSchema(a.items,`${u}[]`))}return r}_formatLabel(t){return t.replace(/([A-Z])/g," $1").replace(/^./,e=>e.toUpperCase()).trim()}_summarizeNodeOutput(t,e){if(!e||typeof e!="object")return[];let r=[];e.success!==void 0&&r.push(`Result: ${e.success?"passed":"failed"}`);for(let[s,i]of Object.entries(e))if(!(s==="success"||s==="raw"||s==="nextNode")){if(typeof i=="string"&&i.length<=80)r.push(`${s}: ${i}`);else if(Array.isArray(i)){let n=i.length,a=i.filter(p=>p?.passed===!0).length,u=i.some(p=>p?.passed!==void 0);r.push(u?`${s}: ${a}/${n} passed${n-a?`, ${n-a} failed`:""}`:`${s}: ${n} items`)}if(r.length>=4)break}return r}async run(t,e={},r={}){if(!this.entryPoint)throw new Error("No entry point set for graph");let s=new AbortController;r.signal&&(r.signal.aborted?s.abort():r.signal.addEventListener("abort",()=>s.abort(),{once:!0}));let i=r.strategyAbortTimeoutMs??e.config?.strategyAbortTimeoutMs??5e3,n=e.cwd||process.cwd();fr({path:H(n,".env")});let a=e.config||{};if(!a||Object.keys(a).length===0)try{let E=H(n,".zibby.config.js");vt(E)&&(a=(await import(E)).default||{})}catch{}process.env.EXECUTION_ID&&!a.agent?.strictMode&&(a.agent={...a.agent,strictMode:!0});let u=e.agentType;if(!u){let E=a?.agent;E?.provider?u=E.provider:E?.gemini?u="gemini":E?.claude?u="claude":E?.cursor?u="cursor":E?.codex?u="codex":u=process.env.AGENT_TYPE||"cursor"}let p=e.contextConfig||t?.config?.contextConfig||t?.config?.context||a?.context||{},g=this._runtimeSchema();if(g){let E=g.safeParse(e);if(!E.success){let N=E.error.issues.map(R=>`${R.path.join(".")}: ${R.message}`);throw console.error("\u274C Initial state validation failed:"),N.forEach(R=>console.error(` - ${R}`)),new Error(`State validation failed: ${N.join(", ")}`)}x.step("State validated against schema")}let c=Sr(),l=e.sessionPath||c;l||yr();let{sessionPath:y,sessionTimestamp:w,sessionId:$}=Ir({cwd:n,config:a,traceFrom:"WorkflowGraph.run",initialState:{sessionPath:l,sessionTimestamp:e.sessionTimestamp}});x.step(`Session ${$}`);let v=await ct.loadContext(e.specPath||"",n,p);Object.keys(v).length>0&&x.step(`Context loaded: ${Object.keys(v).join(", ")}`);let b=e.outputPath;!b&&e.specPath&&(t?.calculateOutputPath?b=t.calculateOutputPath(e.specPath):console.warn(`\u26A0\uFE0F outputPath not resolved (specPath=${e.specPath})`));let h=new ot({...e,config:a,agentType:u,outputPath:b,sessionPath:y,sessionTimestamp:w,context:v,resolvedTools:this.resolvedToolsMap||{},_signal:s.signal}),f=new Map;try{await import("@zibby/skills")}catch{}let{getSkill:m}=await Promise.resolve().then(()=>(St(),Kt)),d=a.skills&&typeof a.skills=="object"?a.skills:{},I=Object.values(d).filter(E=>E&&typeof E=="object"&&typeof E.id=="string"),A=E=>{for(let N of I)if(N.id===E)return N;return m(E)},B=new Set;for(let[,E]of this.nodes)for(let N of E.config?.skills||[])B.add(N);for(let E of B){let N=A(E);if(typeof N?.middleware=="function")try{let R=await N.middleware();typeof R=="function"&&f.set(E,R)}catch{}}let S=this.entryPoint,Q=[],kt=a?.recursionLimit??100,we=0;try{for(;S&&S!=="END";){if(++we>kt)throw new Error(`Workflow exceeded recursion limit (${kt}) \u2014 likely a cyclic conditional route. Set config.recursionLimit if you need a higher cap.`);let N=H(y,Yt);if(vt(N)){try{dr(N)}catch{}s.abort()}if(s.signal.aborted)return console.warn(`
41
+ ${g}`)}}function mr(){return process.env.ZIBBY_TRUST_SESSION_ENV==="1"||process.env.ZIBBY_TRUST_SESSION_ENV==="true"||process.env.ZIBBY_KEEP_SESSION_ENV==="1"||process.env.ZIBBY_KEEP_SESSION_ENV==="true"}function Sr(){if(!(process.env.ZIBBY_PIN_SESSION_PATH==="1"||process.env.ZIBBY_PIN_SESSION_PATH==="true"))return;let t=process.env.ZIBBY_SESSION_PATH;if(!(t==null||String(t).trim()===""))try{return ye(String(t).trim())}catch{return String(t).trim()}}function yr(){mr()||(delete process.env.ZIBBY_SESSION_PATH,delete process.env.ZIBBY_SESSION_ID)}function wr({sessionPath:o,sessionId:t}){o&&typeof o=="string"&&(process.env.ZIBBY_SESSION_PATH=o),t!=null&&String(t).trim()!==""&&(process.env.ZIBBY_SESSION_ID=String(t).trim())}function _r(o={}){let t=Zt.map(i=>process.env[i]).find(Boolean),e=Math.random().toString(36).slice(2,6),r=t||`${Date.now()}_${e}`,s=o.paths?.sessionPrefix;return s?`${s}_${r}`:r}function Ir({cwd:o=process.cwd(),config:t={},initialState:e={},traceFrom:r="resolveWorkflowSession"}={}){let s=e.sessionPath,i=e.sessionTimestamp,n="initialState.sessionPath";if(!s&&process.env.ZIBBY_SESSION_PATH)try{let p=ye(String(process.env.ZIBBY_SESSION_PATH));p&&(s=p,n="ZIBBY_SESSION_PATH")}catch{}let a;if(s)a=String(s).split(/[/\\]/).filter(Boolean).pop(),i==null&&(i=Date.now());else{let p=process.env.ZIBBY_SESSION_ID&&String(process.env.ZIBBY_SESSION_ID).trim();if(p)a=p,n="ZIBBY_SESSION_ID";else{let c=t.sessionId!=null?String(t.sessionId).trim():"";c&&c!=="last"?(a=c,n="config.sessionId"):(a=_r(t),n="generated")}i=i??Date.now();let g=t.paths?.output||it;s=H(o,g,Jt,a)}let u=!vt(s);return u&&Se(s,{recursive:!0}),(u||n!=="initialState.sessionPath")&&gr({traceFrom:r,sessionId:a,sessionPath:s,idSource:n,mkdirFresh:u}),wr({sessionPath:s,sessionId:a}),{sessionPath:s,sessionId:a,sessionTimestamp:i}}var me=class{constructor(t={}){this.nodes=new Map,this.edges=new Map,this.entryPoint=null,this.middleware=Array.isArray(t.middleware)?[...t.middleware]:[],t.nodeMiddleware&&this.middleware.push(t.nodeMiddleware),this.nodeTypeMap=new Map,this.conditionalCodeMap=new Map,this.stateSchema=t.stateSchema||null,this.inputSchema=t.inputSchema||null,this.contextSchema=t.contextSchema||null,this.nodePrompts=new Map,this.nodeOptions=new Map,this._invokeAgent=t.invokeAgent||null,this._compiledPrompts=new Map}setInputSchema(t){return this.inputSchema=t,this}setContextSchema(t){return this.contextSchema=t,this}setStateSchema(t){return this.stateSchema=t,this}getInputSchema(){return this.inputSchema}getContextSchema(){return this.contextSchema}getStateSchema(){return this.stateSchema}_runtimeSchema(){if(this.inputSchema&&this.contextSchema)try{if(typeof this.inputSchema.merge=="function")return this.inputSchema.merge(this.contextSchema);if(typeof this.inputSchema.and=="function")return this.inputSchema.and(this.contextSchema)}catch{}return this.inputSchema&&!this.contextSchema?this.inputSchema:this.stateSchema}addNode(t,e,r={}){if(!(e instanceof L)&&e&&typeof e=="object"&&typeof e.workflow=="string"){let n=e,a={name:t,_isCustomCode:!0,dispatchesWorkflow:n.workflow,retries:n.retries,onComplete:n.onComplete,execute:async p=>{let g=p?.state&&typeof p.state.getAll=="function"?p.state.getAll():p,c;return typeof n.input=="function"?c=n.input(g):n.input&&typeof n.input=="object"?c=n.input:c={},pe(n.workflow,{input:c,async:n.async===!0,conversationId:typeof n.conversationId=="function"?n.conversationId(g):n.conversationId,output:n.output,timeoutMs:n.timeoutMs,pollIntervalMs:n.pollIntervalMs,signal:g?._signal,parentAgent:p?.agent})}},u=new L(a);return u.name=t,this.nodes.set(t,u),r.prompt&&this.nodePrompts.set(t,r.prompt),Object.keys(r).length>0&&this.nodeOptions.set(t,r),this}let s=!(e instanceof L)&&e&&typeof e=="object"&&typeof e.execute!="function"&&e.prompt==null&&e.outputSchema==null&&e._isCustomCode!==!0,i=e instanceof L?e:new L(s?{...e,_isRouter:!0}:e);return i.name=t,this.nodes.set(t,i),r.prompt?this.nodePrompts.set(t,r.prompt):typeof e?.prompt=="string"&&e.prompt.trim()&&this.nodePrompts.set(t,e.prompt),Object.keys(r).length>0&&this.nodeOptions.set(t,r),this}addEdge(t,e){return this.edges.set(t,e),this}setNodeType(t,e){return this.nodeTypeMap.set(t,e),this}addConditionalEdges(t,e,{labels:r}={}){return this.edges.set(t,{conditional:!0,routes:e,labels:r}),typeof e=="function"&&this.conditionalCodeMap.set(t,e.toString()),this}setEntryPoint(t){return this.entryPoint=t,this}use(t){return typeof t=="function"&&this.middleware.push(t),this}_composeMiddleware(t,e,r,s,i){let n=r;for(let a=t.length-1;a>=0;a--){let u=t[a],p=n;n=()=>u(e,p,s,i)}return n()}serialize(){let t=[],e={};for(let[c,l]of this.nodes){let y=this.nodeTypeMap.get(c)||(l?.config?._isRouter===!0?"decision":c);t.push({id:c,type:y,data:{nodeType:y,label:c}});let w={};l._isCustomCode&&typeof l.execute=="function"&&(w.customCode=l.execute.toString());let $=typeof l?.config?.description=="string"&&l.config.description.trim()?l.config.description:typeof l?.description=="string"&&l.description.trim()?l.description:null;$&&(w.description=$);let v=this.nodePrompts.get(c);if(v)w.prompt=v;else if(typeof l.prompt=="function")try{let d=l.prompt({});typeof d=="string"&&d.trim()&&(w.prompt=d,w.promptIsCode=!0)}catch{}if(typeof l.customExecute=="function"&&(w.executeCode=l.customExecute.toString()),typeof l?.config?.dispatchesWorkflow=="string"&&l.config.dispatchesWorkflow.trim()&&(w.dispatchesWorkflow=l.config.dispatchesWorkflow.trim()),l.outputSchema)if(typeof l.outputSchema._def<"u"){let d=null;if(typeof lt?.toJSONSchema=="function")try{d=lt.toJSONSchema(l.outputSchema)}catch{}if(!d)try{d=ge(l.outputSchema,{target:"openApi3"})}catch{}w.outputSchema=d?{jsonSchema:d,variables:this._flattenJsonSchemaToVariables(d)}:{schema:l.outputSchema}}else w.outputSchema={schema:l.outputSchema};let b=(this.resolvedToolsMap||{})[c];b?.toolIds&&(w.tools=b.toolIds);let h=Array.isArray(l?.config?.skills)?l.config.skills:Array.isArray(l?.skills)?l.skills:null;h&&h.length>0&&(w.skills=[...h]);let f=Array.isArray(l?.config?.plugins)?l.config.plugins:Array.isArray(l?.plugins)?l.plugins:null;f&&f.length>0&&(w.plugins=f.map(d=>d&&typeof d=="object"?{...d}:d));let m=Array.isArray(l?.config?.stores)?l.config.stores:Array.isArray(l?.stores)?l.stores:null;m&&m.length>0&&(w.stores=m.map(d=>d&&typeof d=="object"?{...d}:d)),Object.keys(w).length>0&&(e[c]=w)}let r=[];for(let[c,l]of this.edges)if(typeof l=="string")r.push({source:c,target:l});else if(l.conditional){let y=this.conditionalCodeMap.get(c)||l.routes.toString(),w=this._inferConditionalTargets(l.routes,l.labels),$=l.labels||{},v=this.nodes.get(c),b=v?.config?._isRouter===!0||this.nodeTypeMap.get(c)==="decision"||!v,h=c;if(!b){let f=`${c}__branch`;t.push({id:f,type:"decision",data:{nodeType:"decision",label:f}}),r.push({source:c,target:f}),h=f}for(let f of w){let m={source:h,target:f,data:{conditionalCode:y}};$[f]&&(m.label=$[f]),r.push(m)}}let s=c=>{if(!c)return null;if(typeof lt?.toJSONSchema=="function")try{return lt.toJSONSchema(c)}catch{}try{return ge(c,{target:"openApi3"})}catch{return null}};this.entryPoint&&this.nodes.has(this.entryPoint)&&(t.unshift({id:"START",type:"start",data:{nodeType:"start",label:"Start"}}),r.unshift({source:"START",target:this.entryPoint}));let i=0;for(let c of r)if(c.target==="END"){i+=1;let l=`END__${i}`;c.target=l,t.push({id:l,type:"end",data:{nodeType:"end",label:"End"}})}for(let c of this.nodes.keys())if(!this.edges.has(c)){i+=1;let l=`END__${i}`;t.push({id:l,type:"end",data:{nodeType:"end",label:"End"}}),r.push({source:c,target:l})}let n=this._topoOrderNodes(t,r),a=this._runtimeSchema(),u=s(a||this.stateSchema),p=s(this.inputSchema),g=s(this.contextSchema);return{nodes:n,edges:r,nodeConfigs:e,stateSchema:u,inputSchema:p,contextSchema:g}}_topoOrderNodes(t,e){let r=new Map(t.map((c,l)=>[c.id,l])),s=new Map(t.map(c=>[c.id,c])),i=new Map(t.map(c=>[c.id,0])),n=new Map(t.map(c=>[c.id,[]]));for(let c of e)n.has(c.source)&&i.has(c.target)&&(n.get(c.source).push(c.target),i.set(c.target,i.get(c.target)+1));let a=new Set,u=new Set(r.keys()),p=[...u].filter(c=>i.get(c)===0),g=[];for(;g.length<t.length;){let c;if(p.length>0){if(p.sort((l,y)=>r.get(l)-r.get(y)),c=p.shift(),a.has(c))continue}else c=[...u].sort((l,y)=>r.get(l)-r.get(y))[0];a.add(c),u.delete(c),g.push(s.get(c));for(let l of n.get(c)||[])i.set(l,i.get(l)-1),i.get(l)<=0&&!a.has(l)&&p.push(l)}return g}_inferConditionalTargets(t,e){let r=t.toString(),s=new Set,i=/(['"])((?:\\.|(?!\1).)*?)\1|`((?:\\.|[^`$]|\$(?!\{))*?)`/g,n;for(;(n=i.exec(r))!==null;){let p=n[2]!==void 0?n[2]:n[3];p!==void 0&&p!==""&&s.add(p)}let a=new Set(["END","START","__end__","__start__"]);for(let p of this.nodes.keys())a.add(p);if(e&&typeof e=="object")for(let p of Object.keys(e))a.add(p);let u=new Set;for(let p of s)a.has(p)&&u.add(p);if(u.size===0){let p=/return\s+['"]([^'"]+)['"]/g,g;for(;(g=p.exec(r))!==null;)u.add(g[1])}return[...u]}_flattenJsonSchemaToVariables(t,e=""){let r=t;if(t.$ref&&t.definitions){let s=t.$ref.replace("#/definitions/","");r=t.definitions[s]||t}return this._flattenSchema(r,e)}_flattenSchema(t,e=""){if(!t||typeof t!="object")return[];let r=[],s=t.properties||{},i=t.required||[];for(let[n,a]of Object.entries(s)){let u=e?`${e}.${n}`:n;r.push({path:u,type:a.type||"unknown",label:a.description||this._formatLabel(n),optional:!i.includes(n)}),a.type==="object"&&a.properties&&r.push(...this._flattenSchema(a,u)),a.type==="array"&&a.items?.type==="object"&&a.items.properties&&r.push(...this._flattenSchema(a.items,`${u}[]`))}return r}_formatLabel(t){return t.replace(/([A-Z])/g," $1").replace(/^./,e=>e.toUpperCase()).trim()}_summarizeNodeOutput(t,e){if(!e||typeof e!="object")return[];let r=[];e.success!==void 0&&r.push(`Result: ${e.success?"passed":"failed"}`);for(let[s,i]of Object.entries(e))if(!(s==="success"||s==="raw"||s==="nextNode")){if(typeof i=="string"&&i.length<=80)r.push(`${s}: ${i}`);else if(Array.isArray(i)){let n=i.length,a=i.filter(p=>p?.passed===!0).length,u=i.some(p=>p?.passed!==void 0);r.push(u?`${s}: ${a}/${n} passed${n-a?`, ${n-a} failed`:""}`:`${s}: ${n} items`)}if(r.length>=4)break}return r}async run(t,e={},r={}){if(!this.entryPoint)throw new Error("No entry point set for graph");let s=new AbortController;r.signal&&(r.signal.aborted?s.abort():r.signal.addEventListener("abort",()=>s.abort(),{once:!0}));let i=r.strategyAbortTimeoutMs??e.config?.strategyAbortTimeoutMs??5e3,n=e.cwd||process.cwd();fr({path:H(n,".env")});let a=e.config||{};if(!a||Object.keys(a).length===0)try{let E=H(n,".zibby.config.js");vt(E)&&(a=(await import(E)).default||{})}catch{}process.env.EXECUTION_ID&&!a.agent?.strictMode&&(a.agent={...a.agent,strictMode:!0});let u=e.agentType;if(!u){let E=a?.agent;E?.provider?u=E.provider:E?.gemini?u="gemini":E?.claude?u="claude":E?.cursor?u="cursor":E?.codex?u="codex":u=process.env.AGENT_TYPE||"claude"}let p=e.contextConfig||t?.config?.contextConfig||t?.config?.context||a?.context||{},g=this._runtimeSchema();if(g){let E=g.safeParse(e);if(!E.success){let N=E.error.issues.map(R=>`${R.path.join(".")}: ${R.message}`);throw console.error("\u274C Initial state validation failed:"),N.forEach(R=>console.error(` - ${R}`)),new Error(`State validation failed: ${N.join(", ")}`)}x.step("State validated against schema")}let c=Sr(),l=e.sessionPath||c;l||yr();let{sessionPath:y,sessionTimestamp:w,sessionId:$}=Ir({cwd:n,config:a,traceFrom:"WorkflowGraph.run",initialState:{sessionPath:l,sessionTimestamp:e.sessionTimestamp}});x.step(`Session ${$}`);let v=await ct.loadContext(e.specPath||"",n,p);Object.keys(v).length>0&&x.step(`Context loaded: ${Object.keys(v).join(", ")}`);let b=e.outputPath;!b&&e.specPath&&(t?.calculateOutputPath?b=t.calculateOutputPath(e.specPath):console.warn(`\u26A0\uFE0F outputPath not resolved (specPath=${e.specPath})`));let h=new ot({...e,config:a,agentType:u,outputPath:b,sessionPath:y,sessionTimestamp:w,context:v,resolvedTools:this.resolvedToolsMap||{},_signal:s.signal}),f=new Map;try{await import("@zibby/skills")}catch{}let{getSkill:m}=await Promise.resolve().then(()=>(St(),Kt)),d=a.skills&&typeof a.skills=="object"?a.skills:{},I=Object.values(d).filter(E=>E&&typeof E=="object"&&typeof E.id=="string"),A=E=>{for(let N of I)if(N.id===E)return N;return m(E)},B=new Set;for(let[,E]of this.nodes)for(let N of E.config?.skills||[])B.add(N);for(let E of B){let N=A(E);if(typeof N?.middleware=="function")try{let R=await N.middleware();typeof R=="function"&&f.set(E,R)}catch{}}let S=this.entryPoint,Q=[],kt=a?.recursionLimit??100,we=0;try{for(;S&&S!=="END";){if(++we>kt)throw new Error(`Workflow exceeded recursion limit (${kt}) \u2014 likely a cyclic conditional route. Set config.recursionLimit if you need a higher cap.`);let N=H(y,Yt);if(vt(N)){try{dr(N)}catch{}s.abort()}if(s.signal.aborted)return console.warn(`
42
42
  \u{1F6D1} External stop requested \u2014 ending workflow.`),x.step("Workflow stopped externally"),{success:!0,state:h.getAll(),executionLog:Q,stoppedExternally:!0};let R=this.nodes.get(S);if(!R)throw new Error(`Node '${S}' not found in graph`);let Ot=JSON.stringify({sessionPath:y,sessionTimestamp:w,currentNode:S,createdAt:new Date().toISOString(),config:h.get("config")}),_e=H(y,Z);he(_e,Ot,"utf-8");let xt=h.get("config")?.paths?.output||it,Ie=H(n,xt,Z);Se(H(n,xt),{recursive:!0});try{he(Ie,Ot,"utf-8")}catch{}let Pt=e.onPipelineProgress;if(typeof Pt=="function")try{Pt({cwd:n,sessionPath:y,sessionId:$,outputBase:h.get("config")?.paths?.output||it,currentNode:S})}catch{}let Ee=(this.resolvedToolsMap||{})[S]||null;h.set("_currentNodeTools",Ee);let be=h.get("nodeConfigs")||{};h.set("_currentNodeConfig",be[S]||{}),x.nodeStart(S);let Nt=Date.now(),tt=this.nodePrompts.get(S);if(!this._invokeAgent){let k=await Promise.resolve().then(()=>(_t(),wt));this._invokeAgent=k.invokeAgent}let $e=this._invokeAgent,ut={},Te=R.config?.skills||[];for(let k of Te){let C=A(k);if(typeof C?.invokeAgentOptions=="function")try{let T=C.invokeAgentOptions(h.getAll(),{agentType:h.get("agentType"),nodeName:S});T&&typeof T=="object"&&(ut={...ut,...T})}catch(T){console.warn(`[graph] skill '${k}' invokeAgentOptions threw: ${T.message}`)}}let Rt=async(k,C,T={})=>{let M=$e(k,C,{...ut,...T,signal:s.signal});return M.catch(()=>{}),s.signal.aborted?M:Promise.race([M,new Promise((J,Y)=>{let D=()=>{setTimeout(()=>{let K=new Error(`Strategy ignored AbortSignal \u2014 engine deadman fired after ${i}ms`);K.name="AbortError",Y(K)},i)};s.signal.addEventListener("abort",D,{once:!0})})])},Ae=async(k={},C={})=>{let T=C.prompt||"";if(tt){let M=this._compiledPrompts.get(S);M||(M=hr.compile(tt,{noEscape:!0}),this._compiledPrompts.set(S,M));try{T=M(k)}catch(J){throw console.error(`\u274C Template rendering failed for node '${S}':`,J.message),new Error(`Template rendering failed: ${J.message}`,{cause:J})}}else if(!T)throw new Error(`No prompt template configured for node '${S}' and no prompt provided in options`);return Rt(T,{state:h.getAll(),images:C.images||[]},{model:C.model||h.get("model"),workspace:h.get("workspace"),schema:C.schema,...C,signal:s.signal})},Bt=h.getAll(),ve=["state","invokeAgent","_coreInvokeAgent","agent","nodeId","promptTemplate","getPromptTemplate"];for(let k of ve)Object.prototype.hasOwnProperty.call(Bt,k)&&console.warn(`[workflow] node "${S}": state key "${k}" is shadowed by the engine context prop; read it via context.state.get('${k}')`);let Ct={...Bt,state:h,invokeAgent:Ae,_coreInvokeAgent:Rt,agent:t,nodeId:S,promptTemplate:tt,getPromptTemplate:()=>tt};try{let k=(R.config?.skills||[]).map(D=>f.get(D)).filter(Boolean),C=[...this.middleware,...k],T;C.length>0?T=await this._composeMiddleware(C,S,async()=>R.execute(Ct,h),h.getAll(),h):T=await R.execute(Ct,h);let M=Date.now()-Nt;if(Q.push({node:S,success:T.success,duration:M,timestamp:new Date().toISOString()}),!T.success){if(s.signal.aborted)return x.step("Workflow stopped externally"),{success:!0,state:h.getAll(),executionLog:Q,stoppedExternally:!0};h.append("errors",{node:S,error:T.error});let D=R.config?.retries||0,K=`${S}_retries`,et=h.getAll()[K]||0;if(et<D){x.stepInfo(`Retrying (attempt ${et+1}/${D})`),h.update({[K]:et+1,[`${S}_raw`]:T.raw});continue}throw x.nodeFailed(S,T.error,{duration:M}),new Error(`Node '${S}' failed after ${et} attempts: ${T.error}`)}h.update({[S]:T.output});let J=this._summarizeNodeOutput(S,T.output);x.nodeComplete(S,{duration:M,details:J});let Y=this.edges.get(S);if(!Y)S="END";else if(Y.conditional){let D=Y.routes(h.getAll());x.route(S,D),S=D}else S=Y}catch(k){throw x.isInsideNode&&x.nodeFailed(S,k.message,{duration:Date.now()-Nt}),h.set("failed",!0),h.set("failedAt",S),k}}x.graphComplete();let E={success:!0,state:h.getAll(),executionLog:Q};return t&&typeof t.onComplete=="function"&&await t.onComplete(E),E}finally{if(t&&typeof t.cleanup=="function")try{await t.cleanup()}catch(E){console.warn(`[workflow] agent.cleanup() failed: ${E.message}`)}}}};export{me as WorkflowGraph,yr as clearInheritedSessionEnvForFreshRun,_r as generateWorkflowSessionId,Sr as readPinnedSessionPathFromEnv,Ir as resolveWorkflowSession,mr as shouldTrustInheritedSessionEnv,wr as syncProcessEnvToSession};
package/dist/index.js CHANGED
@@ -38,7 +38,7 @@ ${s}`);let a=r(),l=a.cwd||process.cwd(),u=a.sessionPath;try{if(u){let d=Be(u,U);
38
38
  `):i.every(n=>typeof n=="object")?Object.assign({},...i):i[i.length-1]}static async loadFile(e){let t=Fo(e,"utf-8");if(e.endsWith(".json"))return JSON.parse(t);if(e.endsWith(".js")||e.endsWith(".mjs")){let{pathToFileURL:r}=await import("url"),i=await import(r(e).href);return i.default||i}return t}};import{mkdirSync as Gt,existsSync as Ge,writeFileSync as Mt,unlinkSync as Go}from"node:fs";import{join as z,resolve as Ut}from"node:path";import{config as Uo}from"dotenv";import{zodToJsonSchema as Ft}from"zod-to-json-schema";import{z as ye}from"zod";import Wo from"handlebars";function Ho({traceFrom:o,sessionId:e,sessionPath:t,idSource:r,mkdirFresh:i}){if(!(process.env.ZIBBY_SESSION_LOG==="1"||process.env.ZIBBY_SESSION_LOG==="true"))return;let n=typeof process.ppid=="number"?process.ppid:"n/a",a=`[zibby:session] from=${o} pid=${process.pid} ppid=${n} sessionId=${e} source=${r} mkdir=${i?"yes":"no"} path=${t}`;if(console.log(a),process.env.ZIBBY_TRACE_SESSION==="1"||process.env.ZIBBY_TRACE_SESSION==="true"){let f=(new Error("session trace").stack||"").split(`
39
39
  `).slice(2,14).join(`
40
40
  `);console.log(`[zibby:session] stack (${o}):
41
- ${f}`)}}function Wt(){return process.env.ZIBBY_TRUST_SESSION_ENV==="1"||process.env.ZIBBY_TRUST_SESSION_ENV==="true"||process.env.ZIBBY_KEEP_SESSION_ENV==="1"||process.env.ZIBBY_KEEP_SESSION_ENV==="true"}function Ht(){if(!(process.env.ZIBBY_PIN_SESSION_PATH==="1"||process.env.ZIBBY_PIN_SESSION_PATH==="true"))return;let e=process.env.ZIBBY_SESSION_PATH;if(!(e==null||String(e).trim()===""))try{return Ut(String(e).trim())}catch{return String(e).trim()}}function Jt(){Wt()||(delete process.env.ZIBBY_SESSION_PATH,delete process.env.ZIBBY_SESSION_ID)}function Yt({sessionPath:o,sessionId:e}){o&&typeof o=="string"&&(process.env.ZIBBY_SESSION_PATH=o),e!=null&&String(e).trim()!==""&&(process.env.ZIBBY_SESSION_ID=String(e).trim())}function zt(o={}){let e=Ae.map(s=>process.env[s]).find(Boolean),t=Math.random().toString(36).slice(2,6),r=e||`${Date.now()}_${t}`,i=o.paths?.sessionPrefix;return i?`${i}_${r}`:r}function Zt({cwd:o=process.cwd(),config:e={},initialState:t={},traceFrom:r="resolveWorkflowSession"}={}){let i=t.sessionPath,s=t.sessionTimestamp,n="initialState.sessionPath";if(!i&&process.env.ZIBBY_SESSION_PATH)try{let u=Ut(String(process.env.ZIBBY_SESSION_PATH));u&&(i=u,n="ZIBBY_SESSION_PATH")}catch{}let a;if(i)a=String(i).split(/[/\\]/).filter(Boolean).pop(),s==null&&(s=Date.now());else{let u=process.env.ZIBBY_SESSION_ID&&String(process.env.ZIBBY_SESSION_ID).trim();if(u)a=u,n="ZIBBY_SESSION_ID";else{let d=e.sessionId!=null?String(e.sessionId).trim():"";d&&d!=="last"?(a=d,n="config.sessionId"):(a=zt(e),n="generated")}s=s??Date.now();let f=e.paths?.output||se;i=z(o,f,$e,a)}let l=!Ge(i);return l&&Gt(i,{recursive:!0}),(l||n!=="initialState.sessionPath")&&Ho({traceFrom:r,sessionId:a,sessionPath:i,idSource:n,mkdirFresh:l}),Yt({sessionPath:i,sessionId:a}),{sessionPath:i,sessionId:a,sessionTimestamp:s}}var Q=class{constructor(e={}){this.nodes=new Map,this.edges=new Map,this.entryPoint=null,this.middleware=Array.isArray(e.middleware)?[...e.middleware]:[],e.nodeMiddleware&&this.middleware.push(e.nodeMiddleware),this.nodeTypeMap=new Map,this.conditionalCodeMap=new Map,this.stateSchema=e.stateSchema||null,this.inputSchema=e.inputSchema||null,this.contextSchema=e.contextSchema||null,this.nodePrompts=new Map,this.nodeOptions=new Map,this._invokeAgent=e.invokeAgent||null,this._compiledPrompts=new Map}setInputSchema(e){return this.inputSchema=e,this}setContextSchema(e){return this.contextSchema=e,this}setStateSchema(e){return this.stateSchema=e,this}getInputSchema(){return this.inputSchema}getContextSchema(){return this.contextSchema}getStateSchema(){return this.stateSchema}_runtimeSchema(){if(this.inputSchema&&this.contextSchema)try{if(typeof this.inputSchema.merge=="function")return this.inputSchema.merge(this.contextSchema);if(typeof this.inputSchema.and=="function")return this.inputSchema.and(this.contextSchema)}catch{}return this.inputSchema&&!this.contextSchema?this.inputSchema:this.stateSchema}addNode(e,t,r={}){if(!(t instanceof M)&&t&&typeof t=="object"&&typeof t.workflow=="string"){let n=t,a={name:e,_isCustomCode:!0,dispatchesWorkflow:n.workflow,retries:n.retries,onComplete:n.onComplete,execute:async u=>{let f=u?.state&&typeof u.state.getAll=="function"?u.state.getAll():u,d;return typeof n.input=="function"?d=n.input(f):n.input&&typeof n.input=="object"?d=n.input:d={},Me(n.workflow,{input:d,async:n.async===!0,conversationId:typeof n.conversationId=="function"?n.conversationId(f):n.conversationId,output:n.output,timeoutMs:n.timeoutMs,pollIntervalMs:n.pollIntervalMs,signal:f?._signal,parentAgent:u?.agent})}},l=new M(a);return l.name=e,this.nodes.set(e,l),r.prompt&&this.nodePrompts.set(e,r.prompt),Object.keys(r).length>0&&this.nodeOptions.set(e,r),this}let i=!(t instanceof M)&&t&&typeof t=="object"&&typeof t.execute!="function"&&t.prompt==null&&t.outputSchema==null&&t._isCustomCode!==!0,s=t instanceof M?t:new M(i?{...t,_isRouter:!0}:t);return s.name=e,this.nodes.set(e,s),r.prompt?this.nodePrompts.set(e,r.prompt):typeof t?.prompt=="string"&&t.prompt.trim()&&this.nodePrompts.set(e,t.prompt),Object.keys(r).length>0&&this.nodeOptions.set(e,r),this}addEdge(e,t){return this.edges.set(e,t),this}setNodeType(e,t){return this.nodeTypeMap.set(e,t),this}addConditionalEdges(e,t,{labels:r}={}){return this.edges.set(e,{conditional:!0,routes:t,labels:r}),typeof t=="function"&&this.conditionalCodeMap.set(e,t.toString()),this}setEntryPoint(e){return this.entryPoint=e,this}use(e){return typeof e=="function"&&this.middleware.push(e),this}_composeMiddleware(e,t,r,i,s){let n=r;for(let a=e.length-1;a>=0;a--){let l=e[a],u=n;n=()=>l(t,u,i,s)}return n()}serialize(){let e=[],t={};for(let[d,c]of this.nodes){let y=this.nodeTypeMap.get(d)||(c?.config?._isRouter===!0?"decision":d);e.push({id:d,type:y,data:{nodeType:y,label:d}});let g={};c._isCustomCode&&typeof c.execute=="function"&&(g.customCode=c.execute.toString());let S=typeof c?.config?.description=="string"&&c.config.description.trim()?c.config.description:typeof c?.description=="string"&&c.description.trim()?c.description:null;S&&(g.description=S);let b=this.nodePrompts.get(d);if(b)g.prompt=b;else if(typeof c.prompt=="function")try{let p=c.prompt({});typeof p=="string"&&p.trim()&&(g.prompt=p,g.promptIsCode=!0)}catch{}if(typeof c.customExecute=="function"&&(g.executeCode=c.customExecute.toString()),typeof c?.config?.dispatchesWorkflow=="string"&&c.config.dispatchesWorkflow.trim()&&(g.dispatchesWorkflow=c.config.dispatchesWorkflow.trim()),c.outputSchema)if(typeof c.outputSchema._def<"u"){let p=null;if(typeof ye?.toJSONSchema=="function")try{p=ye.toJSONSchema(c.outputSchema)}catch{}if(!p)try{p=Ft(c.outputSchema,{target:"openApi3"})}catch{}g.outputSchema=p?{jsonSchema:p,variables:this._flattenJsonSchemaToVariables(p)}:{schema:c.outputSchema}}else g.outputSchema={schema:c.outputSchema};let _=(this.resolvedToolsMap||{})[d];_?.toolIds&&(g.tools=_.toolIds);let m=Array.isArray(c?.config?.skills)?c.config.skills:Array.isArray(c?.skills)?c.skills:null;m&&m.length>0&&(g.skills=[...m]);let h=Array.isArray(c?.config?.plugins)?c.config.plugins:Array.isArray(c?.plugins)?c.plugins:null;h&&h.length>0&&(g.plugins=h.map(p=>p&&typeof p=="object"?{...p}:p));let w=Array.isArray(c?.config?.stores)?c.config.stores:Array.isArray(c?.stores)?c.stores:null;w&&w.length>0&&(g.stores=w.map(p=>p&&typeof p=="object"?{...p}:p)),Object.keys(g).length>0&&(t[d]=g)}let r=[];for(let[d,c]of this.edges)if(typeof c=="string")r.push({source:d,target:c});else if(c.conditional){let y=this.conditionalCodeMap.get(d)||c.routes.toString(),g=this._inferConditionalTargets(c.routes,c.labels),S=c.labels||{},b=this.nodes.get(d),_=b?.config?._isRouter===!0||this.nodeTypeMap.get(d)==="decision"||!b,m=d;if(!_){let h=`${d}__branch`;e.push({id:h,type:"decision",data:{nodeType:"decision",label:h}}),r.push({source:d,target:h}),m=h}for(let h of g){let w={source:m,target:h,data:{conditionalCode:y}};S[h]&&(w.label=S[h]),r.push(w)}}let i=d=>{if(!d)return null;if(typeof ye?.toJSONSchema=="function")try{return ye.toJSONSchema(d)}catch{}try{return Ft(d,{target:"openApi3"})}catch{return null}};this.entryPoint&&this.nodes.has(this.entryPoint)&&(e.unshift({id:"START",type:"start",data:{nodeType:"start",label:"Start"}}),r.unshift({source:"START",target:this.entryPoint}));let s=0;for(let d of r)if(d.target==="END"){s+=1;let c=`END__${s}`;d.target=c,e.push({id:c,type:"end",data:{nodeType:"end",label:"End"}})}for(let d of this.nodes.keys())if(!this.edges.has(d)){s+=1;let c=`END__${s}`;e.push({id:c,type:"end",data:{nodeType:"end",label:"End"}}),r.push({source:d,target:c})}let n=this._topoOrderNodes(e,r),a=this._runtimeSchema(),l=i(a||this.stateSchema),u=i(this.inputSchema),f=i(this.contextSchema);return{nodes:n,edges:r,nodeConfigs:t,stateSchema:l,inputSchema:u,contextSchema:f}}_topoOrderNodes(e,t){let r=new Map(e.map((d,c)=>[d.id,c])),i=new Map(e.map(d=>[d.id,d])),s=new Map(e.map(d=>[d.id,0])),n=new Map(e.map(d=>[d.id,[]]));for(let d of t)n.has(d.source)&&s.has(d.target)&&(n.get(d.source).push(d.target),s.set(d.target,s.get(d.target)+1));let a=new Set,l=new Set(r.keys()),u=[...l].filter(d=>s.get(d)===0),f=[];for(;f.length<e.length;){let d;if(u.length>0){if(u.sort((c,y)=>r.get(c)-r.get(y)),d=u.shift(),a.has(d))continue}else d=[...l].sort((c,y)=>r.get(c)-r.get(y))[0];a.add(d),l.delete(d),f.push(i.get(d));for(let c of n.get(d)||[])s.set(c,s.get(c)-1),s.get(c)<=0&&!a.has(c)&&u.push(c)}return f}_inferConditionalTargets(e,t){let r=e.toString(),i=new Set,s=/(['"])((?:\\.|(?!\1).)*?)\1|`((?:\\.|[^`$]|\$(?!\{))*?)`/g,n;for(;(n=s.exec(r))!==null;){let u=n[2]!==void 0?n[2]:n[3];u!==void 0&&u!==""&&i.add(u)}let a=new Set(["END","START","__end__","__start__"]);for(let u of this.nodes.keys())a.add(u);if(t&&typeof t=="object")for(let u of Object.keys(t))a.add(u);let l=new Set;for(let u of i)a.has(u)&&l.add(u);if(l.size===0){let u=/return\s+['"]([^'"]+)['"]/g,f;for(;(f=u.exec(r))!==null;)l.add(f[1])}return[...l]}_flattenJsonSchemaToVariables(e,t=""){let r=e;if(e.$ref&&e.definitions){let i=e.$ref.replace("#/definitions/","");r=e.definitions[i]||e}return this._flattenSchema(r,t)}_flattenSchema(e,t=""){if(!e||typeof e!="object")return[];let r=[],i=e.properties||{},s=e.required||[];for(let[n,a]of Object.entries(i)){let l=t?`${t}.${n}`:n;r.push({path:l,type:a.type||"unknown",label:a.description||this._formatLabel(n),optional:!s.includes(n)}),a.type==="object"&&a.properties&&r.push(...this._flattenSchema(a,l)),a.type==="array"&&a.items?.type==="object"&&a.items.properties&&r.push(...this._flattenSchema(a.items,`${l}[]`))}return r}_formatLabel(e){return e.replace(/([A-Z])/g," $1").replace(/^./,t=>t.toUpperCase()).trim()}_summarizeNodeOutput(e,t){if(!t||typeof t!="object")return[];let r=[];t.success!==void 0&&r.push(`Result: ${t.success?"passed":"failed"}`);for(let[i,s]of Object.entries(t))if(!(i==="success"||i==="raw"||i==="nextNode")){if(typeof s=="string"&&s.length<=80)r.push(`${i}: ${s}`);else if(Array.isArray(s)){let n=s.length,a=s.filter(u=>u?.passed===!0).length,l=s.some(u=>u?.passed!==void 0);r.push(l?`${i}: ${a}/${n} passed${n-a?`, ${n-a} failed`:""}`:`${i}: ${n} items`)}if(r.length>=4)break}return r}async run(e,t={},r={}){if(!this.entryPoint)throw new Error("No entry point set for graph");let i=new AbortController;r.signal&&(r.signal.aborted?i.abort():r.signal.addEventListener("abort",()=>i.abort(),{once:!0}));let s=r.strategyAbortTimeoutMs??t.config?.strategyAbortTimeoutMs??5e3,n=t.cwd||process.cwd();Uo({path:z(n,".env")});let a=t.config||{};if(!a||Object.keys(a).length===0)try{let v=z(n,".zibby.config.js");Ge(v)&&(a=(await import(v)).default||{})}catch{}process.env.EXECUTION_ID&&!a.agent?.strictMode&&(a.agent={...a.agent,strictMode:!0});let l=t.agentType;if(!l){let v=a?.agent;v?.provider?l=v.provider:v?.gemini?l="gemini":v?.claude?l="claude":v?.cursor?l="cursor":v?.codex?l="codex":l=process.env.AGENT_TYPE||"cursor"}let u=t.contextConfig||e?.config?.contextConfig||e?.config?.context||a?.context||{},f=this._runtimeSchema();if(f){let v=f.safeParse(t);if(!v.success){let P=v.error.issues.map(C=>`${C.path.join(".")}: ${C.message}`);throw console.error("\u274C Initial state validation failed:"),P.forEach(C=>console.error(` - ${C}`)),new Error(`State validation failed: ${P.join(", ")}`)}N.step("State validated against schema")}let d=Ht(),c=t.sessionPath||d;c||Jt();let{sessionPath:y,sessionTimestamp:g,sessionId:S}=Zt({cwd:n,config:a,traceFrom:"WorkflowGraph.run",initialState:{sessionPath:c,sessionTimestamp:t.sessionTimestamp}});N.step(`Session ${S}`);let b=await le.loadContext(t.specPath||"",n,u);Object.keys(b).length>0&&N.step(`Context loaded: ${Object.keys(b).join(", ")}`);let _=t.outputPath;!_&&t.specPath&&(e?.calculateOutputPath?_=e.calculateOutputPath(t.specPath):console.warn(`\u26A0\uFE0F outputPath not resolved (specPath=${t.specPath})`));let m=new te({...t,config:a,agentType:l,outputPath:_,sessionPath:y,sessionTimestamp:g,context:b,resolvedTools:this.resolvedToolsMap||{},_signal:i.signal}),h=new Map;try{await import("@zibby/skills")}catch{}let{getSkill:w}=await Promise.resolve().then(()=>(ie(),St)),p=a.skills&&typeof a.skills=="object"?a.skills:{},T=Object.values(p).filter(v=>v&&typeof v=="object"&&typeof v.id=="string"),k=v=>{for(let P of T)if(P.id===v)return P;return w(v)},R=new Set;for(let[,v]of this.nodes)for(let P of v.config?.skills||[])R.add(P);for(let v of R){let P=k(v);if(typeof P?.middleware=="function")try{let C=await P.middleware();typeof C=="function"&&h.set(v,C)}catch{}}let E=this.entryPoint,ue=[],Ze=a?.recursionLimit??100,Xt=0;try{for(;E&&E!=="END";){if(++Xt>Ze)throw new Error(`Workflow exceeded recursion limit (${Ze}) \u2014 likely a cyclic conditional route. Set config.recursionLimit if you need a higher cap.`);let P=z(y,ke);if(Ge(P)){try{Go(P)}catch{}i.abort()}if(i.signal.aborted)return console.warn(`
41
+ ${f}`)}}function Wt(){return process.env.ZIBBY_TRUST_SESSION_ENV==="1"||process.env.ZIBBY_TRUST_SESSION_ENV==="true"||process.env.ZIBBY_KEEP_SESSION_ENV==="1"||process.env.ZIBBY_KEEP_SESSION_ENV==="true"}function Ht(){if(!(process.env.ZIBBY_PIN_SESSION_PATH==="1"||process.env.ZIBBY_PIN_SESSION_PATH==="true"))return;let e=process.env.ZIBBY_SESSION_PATH;if(!(e==null||String(e).trim()===""))try{return Ut(String(e).trim())}catch{return String(e).trim()}}function Jt(){Wt()||(delete process.env.ZIBBY_SESSION_PATH,delete process.env.ZIBBY_SESSION_ID)}function Yt({sessionPath:o,sessionId:e}){o&&typeof o=="string"&&(process.env.ZIBBY_SESSION_PATH=o),e!=null&&String(e).trim()!==""&&(process.env.ZIBBY_SESSION_ID=String(e).trim())}function zt(o={}){let e=Ae.map(s=>process.env[s]).find(Boolean),t=Math.random().toString(36).slice(2,6),r=e||`${Date.now()}_${t}`,i=o.paths?.sessionPrefix;return i?`${i}_${r}`:r}function Zt({cwd:o=process.cwd(),config:e={},initialState:t={},traceFrom:r="resolveWorkflowSession"}={}){let i=t.sessionPath,s=t.sessionTimestamp,n="initialState.sessionPath";if(!i&&process.env.ZIBBY_SESSION_PATH)try{let u=Ut(String(process.env.ZIBBY_SESSION_PATH));u&&(i=u,n="ZIBBY_SESSION_PATH")}catch{}let a;if(i)a=String(i).split(/[/\\]/).filter(Boolean).pop(),s==null&&(s=Date.now());else{let u=process.env.ZIBBY_SESSION_ID&&String(process.env.ZIBBY_SESSION_ID).trim();if(u)a=u,n="ZIBBY_SESSION_ID";else{let d=e.sessionId!=null?String(e.sessionId).trim():"";d&&d!=="last"?(a=d,n="config.sessionId"):(a=zt(e),n="generated")}s=s??Date.now();let f=e.paths?.output||se;i=z(o,f,$e,a)}let l=!Ge(i);return l&&Gt(i,{recursive:!0}),(l||n!=="initialState.sessionPath")&&Ho({traceFrom:r,sessionId:a,sessionPath:i,idSource:n,mkdirFresh:l}),Yt({sessionPath:i,sessionId:a}),{sessionPath:i,sessionId:a,sessionTimestamp:s}}var Q=class{constructor(e={}){this.nodes=new Map,this.edges=new Map,this.entryPoint=null,this.middleware=Array.isArray(e.middleware)?[...e.middleware]:[],e.nodeMiddleware&&this.middleware.push(e.nodeMiddleware),this.nodeTypeMap=new Map,this.conditionalCodeMap=new Map,this.stateSchema=e.stateSchema||null,this.inputSchema=e.inputSchema||null,this.contextSchema=e.contextSchema||null,this.nodePrompts=new Map,this.nodeOptions=new Map,this._invokeAgent=e.invokeAgent||null,this._compiledPrompts=new Map}setInputSchema(e){return this.inputSchema=e,this}setContextSchema(e){return this.contextSchema=e,this}setStateSchema(e){return this.stateSchema=e,this}getInputSchema(){return this.inputSchema}getContextSchema(){return this.contextSchema}getStateSchema(){return this.stateSchema}_runtimeSchema(){if(this.inputSchema&&this.contextSchema)try{if(typeof this.inputSchema.merge=="function")return this.inputSchema.merge(this.contextSchema);if(typeof this.inputSchema.and=="function")return this.inputSchema.and(this.contextSchema)}catch{}return this.inputSchema&&!this.contextSchema?this.inputSchema:this.stateSchema}addNode(e,t,r={}){if(!(t instanceof M)&&t&&typeof t=="object"&&typeof t.workflow=="string"){let n=t,a={name:e,_isCustomCode:!0,dispatchesWorkflow:n.workflow,retries:n.retries,onComplete:n.onComplete,execute:async u=>{let f=u?.state&&typeof u.state.getAll=="function"?u.state.getAll():u,d;return typeof n.input=="function"?d=n.input(f):n.input&&typeof n.input=="object"?d=n.input:d={},Me(n.workflow,{input:d,async:n.async===!0,conversationId:typeof n.conversationId=="function"?n.conversationId(f):n.conversationId,output:n.output,timeoutMs:n.timeoutMs,pollIntervalMs:n.pollIntervalMs,signal:f?._signal,parentAgent:u?.agent})}},l=new M(a);return l.name=e,this.nodes.set(e,l),r.prompt&&this.nodePrompts.set(e,r.prompt),Object.keys(r).length>0&&this.nodeOptions.set(e,r),this}let i=!(t instanceof M)&&t&&typeof t=="object"&&typeof t.execute!="function"&&t.prompt==null&&t.outputSchema==null&&t._isCustomCode!==!0,s=t instanceof M?t:new M(i?{...t,_isRouter:!0}:t);return s.name=e,this.nodes.set(e,s),r.prompt?this.nodePrompts.set(e,r.prompt):typeof t?.prompt=="string"&&t.prompt.trim()&&this.nodePrompts.set(e,t.prompt),Object.keys(r).length>0&&this.nodeOptions.set(e,r),this}addEdge(e,t){return this.edges.set(e,t),this}setNodeType(e,t){return this.nodeTypeMap.set(e,t),this}addConditionalEdges(e,t,{labels:r}={}){return this.edges.set(e,{conditional:!0,routes:t,labels:r}),typeof t=="function"&&this.conditionalCodeMap.set(e,t.toString()),this}setEntryPoint(e){return this.entryPoint=e,this}use(e){return typeof e=="function"&&this.middleware.push(e),this}_composeMiddleware(e,t,r,i,s){let n=r;for(let a=e.length-1;a>=0;a--){let l=e[a],u=n;n=()=>l(t,u,i,s)}return n()}serialize(){let e=[],t={};for(let[d,c]of this.nodes){let y=this.nodeTypeMap.get(d)||(c?.config?._isRouter===!0?"decision":d);e.push({id:d,type:y,data:{nodeType:y,label:d}});let g={};c._isCustomCode&&typeof c.execute=="function"&&(g.customCode=c.execute.toString());let S=typeof c?.config?.description=="string"&&c.config.description.trim()?c.config.description:typeof c?.description=="string"&&c.description.trim()?c.description:null;S&&(g.description=S);let b=this.nodePrompts.get(d);if(b)g.prompt=b;else if(typeof c.prompt=="function")try{let p=c.prompt({});typeof p=="string"&&p.trim()&&(g.prompt=p,g.promptIsCode=!0)}catch{}if(typeof c.customExecute=="function"&&(g.executeCode=c.customExecute.toString()),typeof c?.config?.dispatchesWorkflow=="string"&&c.config.dispatchesWorkflow.trim()&&(g.dispatchesWorkflow=c.config.dispatchesWorkflow.trim()),c.outputSchema)if(typeof c.outputSchema._def<"u"){let p=null;if(typeof ye?.toJSONSchema=="function")try{p=ye.toJSONSchema(c.outputSchema)}catch{}if(!p)try{p=Ft(c.outputSchema,{target:"openApi3"})}catch{}g.outputSchema=p?{jsonSchema:p,variables:this._flattenJsonSchemaToVariables(p)}:{schema:c.outputSchema}}else g.outputSchema={schema:c.outputSchema};let _=(this.resolvedToolsMap||{})[d];_?.toolIds&&(g.tools=_.toolIds);let m=Array.isArray(c?.config?.skills)?c.config.skills:Array.isArray(c?.skills)?c.skills:null;m&&m.length>0&&(g.skills=[...m]);let h=Array.isArray(c?.config?.plugins)?c.config.plugins:Array.isArray(c?.plugins)?c.plugins:null;h&&h.length>0&&(g.plugins=h.map(p=>p&&typeof p=="object"?{...p}:p));let w=Array.isArray(c?.config?.stores)?c.config.stores:Array.isArray(c?.stores)?c.stores:null;w&&w.length>0&&(g.stores=w.map(p=>p&&typeof p=="object"?{...p}:p)),Object.keys(g).length>0&&(t[d]=g)}let r=[];for(let[d,c]of this.edges)if(typeof c=="string")r.push({source:d,target:c});else if(c.conditional){let y=this.conditionalCodeMap.get(d)||c.routes.toString(),g=this._inferConditionalTargets(c.routes,c.labels),S=c.labels||{},b=this.nodes.get(d),_=b?.config?._isRouter===!0||this.nodeTypeMap.get(d)==="decision"||!b,m=d;if(!_){let h=`${d}__branch`;e.push({id:h,type:"decision",data:{nodeType:"decision",label:h}}),r.push({source:d,target:h}),m=h}for(let h of g){let w={source:m,target:h,data:{conditionalCode:y}};S[h]&&(w.label=S[h]),r.push(w)}}let i=d=>{if(!d)return null;if(typeof ye?.toJSONSchema=="function")try{return ye.toJSONSchema(d)}catch{}try{return Ft(d,{target:"openApi3"})}catch{return null}};this.entryPoint&&this.nodes.has(this.entryPoint)&&(e.unshift({id:"START",type:"start",data:{nodeType:"start",label:"Start"}}),r.unshift({source:"START",target:this.entryPoint}));let s=0;for(let d of r)if(d.target==="END"){s+=1;let c=`END__${s}`;d.target=c,e.push({id:c,type:"end",data:{nodeType:"end",label:"End"}})}for(let d of this.nodes.keys())if(!this.edges.has(d)){s+=1;let c=`END__${s}`;e.push({id:c,type:"end",data:{nodeType:"end",label:"End"}}),r.push({source:d,target:c})}let n=this._topoOrderNodes(e,r),a=this._runtimeSchema(),l=i(a||this.stateSchema),u=i(this.inputSchema),f=i(this.contextSchema);return{nodes:n,edges:r,nodeConfigs:t,stateSchema:l,inputSchema:u,contextSchema:f}}_topoOrderNodes(e,t){let r=new Map(e.map((d,c)=>[d.id,c])),i=new Map(e.map(d=>[d.id,d])),s=new Map(e.map(d=>[d.id,0])),n=new Map(e.map(d=>[d.id,[]]));for(let d of t)n.has(d.source)&&s.has(d.target)&&(n.get(d.source).push(d.target),s.set(d.target,s.get(d.target)+1));let a=new Set,l=new Set(r.keys()),u=[...l].filter(d=>s.get(d)===0),f=[];for(;f.length<e.length;){let d;if(u.length>0){if(u.sort((c,y)=>r.get(c)-r.get(y)),d=u.shift(),a.has(d))continue}else d=[...l].sort((c,y)=>r.get(c)-r.get(y))[0];a.add(d),l.delete(d),f.push(i.get(d));for(let c of n.get(d)||[])s.set(c,s.get(c)-1),s.get(c)<=0&&!a.has(c)&&u.push(c)}return f}_inferConditionalTargets(e,t){let r=e.toString(),i=new Set,s=/(['"])((?:\\.|(?!\1).)*?)\1|`((?:\\.|[^`$]|\$(?!\{))*?)`/g,n;for(;(n=s.exec(r))!==null;){let u=n[2]!==void 0?n[2]:n[3];u!==void 0&&u!==""&&i.add(u)}let a=new Set(["END","START","__end__","__start__"]);for(let u of this.nodes.keys())a.add(u);if(t&&typeof t=="object")for(let u of Object.keys(t))a.add(u);let l=new Set;for(let u of i)a.has(u)&&l.add(u);if(l.size===0){let u=/return\s+['"]([^'"]+)['"]/g,f;for(;(f=u.exec(r))!==null;)l.add(f[1])}return[...l]}_flattenJsonSchemaToVariables(e,t=""){let r=e;if(e.$ref&&e.definitions){let i=e.$ref.replace("#/definitions/","");r=e.definitions[i]||e}return this._flattenSchema(r,t)}_flattenSchema(e,t=""){if(!e||typeof e!="object")return[];let r=[],i=e.properties||{},s=e.required||[];for(let[n,a]of Object.entries(i)){let l=t?`${t}.${n}`:n;r.push({path:l,type:a.type||"unknown",label:a.description||this._formatLabel(n),optional:!s.includes(n)}),a.type==="object"&&a.properties&&r.push(...this._flattenSchema(a,l)),a.type==="array"&&a.items?.type==="object"&&a.items.properties&&r.push(...this._flattenSchema(a.items,`${l}[]`))}return r}_formatLabel(e){return e.replace(/([A-Z])/g," $1").replace(/^./,t=>t.toUpperCase()).trim()}_summarizeNodeOutput(e,t){if(!t||typeof t!="object")return[];let r=[];t.success!==void 0&&r.push(`Result: ${t.success?"passed":"failed"}`);for(let[i,s]of Object.entries(t))if(!(i==="success"||i==="raw"||i==="nextNode")){if(typeof s=="string"&&s.length<=80)r.push(`${i}: ${s}`);else if(Array.isArray(s)){let n=s.length,a=s.filter(u=>u?.passed===!0).length,l=s.some(u=>u?.passed!==void 0);r.push(l?`${i}: ${a}/${n} passed${n-a?`, ${n-a} failed`:""}`:`${i}: ${n} items`)}if(r.length>=4)break}return r}async run(e,t={},r={}){if(!this.entryPoint)throw new Error("No entry point set for graph");let i=new AbortController;r.signal&&(r.signal.aborted?i.abort():r.signal.addEventListener("abort",()=>i.abort(),{once:!0}));let s=r.strategyAbortTimeoutMs??t.config?.strategyAbortTimeoutMs??5e3,n=t.cwd||process.cwd();Uo({path:z(n,".env")});let a=t.config||{};if(!a||Object.keys(a).length===0)try{let v=z(n,".zibby.config.js");Ge(v)&&(a=(await import(v)).default||{})}catch{}process.env.EXECUTION_ID&&!a.agent?.strictMode&&(a.agent={...a.agent,strictMode:!0});let l=t.agentType;if(!l){let v=a?.agent;v?.provider?l=v.provider:v?.gemini?l="gemini":v?.claude?l="claude":v?.cursor?l="cursor":v?.codex?l="codex":l=process.env.AGENT_TYPE||"claude"}let u=t.contextConfig||e?.config?.contextConfig||e?.config?.context||a?.context||{},f=this._runtimeSchema();if(f){let v=f.safeParse(t);if(!v.success){let P=v.error.issues.map(C=>`${C.path.join(".")}: ${C.message}`);throw console.error("\u274C Initial state validation failed:"),P.forEach(C=>console.error(` - ${C}`)),new Error(`State validation failed: ${P.join(", ")}`)}N.step("State validated against schema")}let d=Ht(),c=t.sessionPath||d;c||Jt();let{sessionPath:y,sessionTimestamp:g,sessionId:S}=Zt({cwd:n,config:a,traceFrom:"WorkflowGraph.run",initialState:{sessionPath:c,sessionTimestamp:t.sessionTimestamp}});N.step(`Session ${S}`);let b=await le.loadContext(t.specPath||"",n,u);Object.keys(b).length>0&&N.step(`Context loaded: ${Object.keys(b).join(", ")}`);let _=t.outputPath;!_&&t.specPath&&(e?.calculateOutputPath?_=e.calculateOutputPath(t.specPath):console.warn(`\u26A0\uFE0F outputPath not resolved (specPath=${t.specPath})`));let m=new te({...t,config:a,agentType:l,outputPath:_,sessionPath:y,sessionTimestamp:g,context:b,resolvedTools:this.resolvedToolsMap||{},_signal:i.signal}),h=new Map;try{await import("@zibby/skills")}catch{}let{getSkill:w}=await Promise.resolve().then(()=>(ie(),St)),p=a.skills&&typeof a.skills=="object"?a.skills:{},T=Object.values(p).filter(v=>v&&typeof v=="object"&&typeof v.id=="string"),k=v=>{for(let P of T)if(P.id===v)return P;return w(v)},R=new Set;for(let[,v]of this.nodes)for(let P of v.config?.skills||[])R.add(P);for(let v of R){let P=k(v);if(typeof P?.middleware=="function")try{let C=await P.middleware();typeof C=="function"&&h.set(v,C)}catch{}}let E=this.entryPoint,ue=[],Ze=a?.recursionLimit??100,Xt=0;try{for(;E&&E!=="END";){if(++Xt>Ze)throw new Error(`Workflow exceeded recursion limit (${Ze}) \u2014 likely a cyclic conditional route. Set config.recursionLimit if you need a higher cap.`);let P=z(y,ke);if(Ge(P)){try{Go(P)}catch{}i.abort()}if(i.signal.aborted)return console.warn(`
42
42
  \u{1F6D1} External stop requested \u2014 ending workflow.`),N.step("Workflow stopped externally"),{success:!0,state:m.getAll(),executionLog:ue,stoppedExternally:!0};let C=this.nodes.get(E);if(!C)throw new Error(`Node '${E}' not found in graph`);let Ke=JSON.stringify({sessionPath:y,sessionTimestamp:g,currentNode:E,createdAt:new Date().toISOString(),config:m.get("config")}),Qt=z(y,U);Mt(Qt,Ke,"utf-8");let Ve=m.get("config")?.paths?.output||se,eo=z(n,Ve,U);Gt(z(n,Ve),{recursive:!0});try{Mt(eo,Ke,"utf-8")}catch{}let qe=t.onPipelineProgress;if(typeof qe=="function")try{qe({cwd:n,sessionPath:y,sessionId:S,outputBase:m.get("config")?.paths?.output||se,currentNode:E})}catch{}let to=(this.resolvedToolsMap||{})[E]||null;m.set("_currentNodeTools",to);let oo=m.get("nodeConfigs")||{};m.set("_currentNodeConfig",oo[E]||{}),N.nodeStart(E);let Xe=Date.now(),pe=this.nodePrompts.get(E);if(!this._invokeAgent){let A=await Promise.resolve().then(()=>(X(),ae));this._invokeAgent=A.invokeAgent}let ro=this._invokeAgent,Ee={},no=C.config?.skills||[];for(let A of no){let B=k(A);if(typeof B?.invokeAgentOptions=="function")try{let $=B.invokeAgentOptions(m.getAll(),{agentType:m.get("agentType"),nodeName:E});$&&typeof $=="object"&&(Ee={...Ee,...$})}catch($){console.warn(`[graph] skill '${A}' invokeAgentOptions threw: ${$.message}`)}}let Qe=async(A,B,$={})=>{let j=ro(A,B,{...Ee,...$,signal:i.signal});return j.catch(()=>{}),i.signal.aborted?j:Promise.race([j,new Promise((Z,K)=>{let L=()=>{setTimeout(()=>{let ee=new Error(`Strategy ignored AbortSignal \u2014 engine deadman fired after ${s}ms`);ee.name="AbortError",K(ee)},s)};i.signal.addEventListener("abort",L,{once:!0})})])},so=async(A={},B={})=>{let $=B.prompt||"";if(pe){let j=this._compiledPrompts.get(E);j||(j=Wo.compile(pe,{noEscape:!0}),this._compiledPrompts.set(E,j));try{$=j(A)}catch(Z){throw console.error(`\u274C Template rendering failed for node '${E}':`,Z.message),new Error(`Template rendering failed: ${Z.message}`,{cause:Z})}}else if(!$)throw new Error(`No prompt template configured for node '${E}' and no prompt provided in options`);return Qe($,{state:m.getAll(),images:B.images||[]},{model:B.model||m.get("model"),workspace:m.get("workspace"),schema:B.schema,...B,signal:i.signal})},et=m.getAll(),io=["state","invokeAgent","_coreInvokeAgent","agent","nodeId","promptTemplate","getPromptTemplate"];for(let A of io)Object.prototype.hasOwnProperty.call(et,A)&&console.warn(`[workflow] node "${E}": state key "${A}" is shadowed by the engine context prop; read it via context.state.get('${A}')`);let tt={...et,state:m,invokeAgent:so,_coreInvokeAgent:Qe,agent:e,nodeId:E,promptTemplate:pe,getPromptTemplate:()=>pe};try{let A=(C.config?.skills||[]).map(L=>h.get(L)).filter(Boolean),B=[...this.middleware,...A],$;B.length>0?$=await this._composeMiddleware(B,E,async()=>C.execute(tt,m),m.getAll(),m):$=await C.execute(tt,m);let j=Date.now()-Xe;if(ue.push({node:E,success:$.success,duration:j,timestamp:new Date().toISOString()}),!$.success){if(i.signal.aborted)return N.step("Workflow stopped externally"),{success:!0,state:m.getAll(),executionLog:ue,stoppedExternally:!0};m.append("errors",{node:E,error:$.error});let L=C.config?.retries||0,ee=`${E}_retries`,fe=m.getAll()[ee]||0;if(fe<L){N.stepInfo(`Retrying (attempt ${fe+1}/${L})`),m.update({[ee]:fe+1,[`${E}_raw`]:$.raw});continue}throw N.nodeFailed(E,$.error,{duration:j}),new Error(`Node '${E}' failed after ${fe} attempts: ${$.error}`)}m.update({[E]:$.output});let Z=this._summarizeNodeOutput(E,$.output);N.nodeComplete(E,{duration:j,details:Z});let K=this.edges.get(E);if(!K)E="END";else if(K.conditional){let L=K.routes(m.getAll());N.route(E,L),E=L}else E=K}catch(A){throw N.isInsideNode&&N.nodeFailed(E,A.message,{duration:Date.now()-Xe}),m.set("failed",!0),m.set("failedAt",E),A}}N.graphComplete();let v={success:!0,state:m.getAll(),executionLog:ue};return e&&typeof e.onComplete=="function"&&await e.onComplete(v),v}finally{if(e&&typeof e.cleanup=="function")try{await e.cleanup()}catch(v){console.warn(`[workflow] agent.cleanup() failed: ${v.message}`)}}}};var Ue=Symbol.for("@zibby/agent-workflow.nodes");globalThis[Ue]||(globalThis[Ue]=new Map);var de=globalThis[Ue];function Kt(o,e){de.set(o,e)}function We(o){return de.get(o)}function we(o){return de.has(o)}function Jo(){return Array.from(de.keys())}function He(o){let e=de.get(o);return e?e.factory&&typeof e.create=="function"?e.create.toString():typeof e.execute=="function"?e.execute.toString():typeof e=="function"?e.toString():null:null}Kt("ai_agent",{name:"ai_agent",factory:!0,create:(o,e={})=>({name:o,_isCustomCode:!0,execute:async t=>{let r=t?._coreInvokeAgent;r||(r=(await Promise.resolve().then(()=>(X(),ae))).invokeAgent);let i=e.extraPromptInstructions||"Execute the task based on the current state.",s=Yo(i,t),n=await r(s,{cwd:t.workspace||process.cwd(),model:t.model,tools:e.resolvedTools||null});return{success:!0,output:{raw:n,nodeId:o},raw:typeof n=="string"?n:n.raw}}})});function Yo(o,e){let t=/@([\w.]+)/g,r=new Set,i;for(;(i=t.exec(o))!==null;)r.add(i[1]);if(r.size===0)return o;let s=[],n=new Set;for(let a of r){let l=a.split(".")[0];if(n.has(l))continue;let u=a.split(".").reduce((c,y)=>c?.[y],e);if(u===void 0)continue;let f=typeof u=="string"?u:u?.raw??JSON.stringify(u,null,2),d=a.replace(/_/g," ").replace(/\b\w/g,c=>c.toUpperCase());s.push(`## ${d}
43
43
  ${f}`),a.includes(".")||n.add(l)}return s.length===0?o:`${o}
44
44
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zibby/agent-workflow",
3
- "version": "0.4.33",
3
+ "version": "0.4.35",
4
4
  "description": "Graph-based AI agent workflow orchestration. Bring your own agent strategies.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",