@zibby/agent-workflow 2.0.5 → 2.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/node.js CHANGED
@@ -1,34 +1,34 @@
1
- var ut=Object.defineProperty;var W=(r,t,e)=>()=>{if(e)throw e[0];try{return r&&(t=r(r=0)),t}catch(o){throw e=[o],o}};var pt=(r,t)=>{for(var e in t)ut(r,e,{get:t[e],enumerable:!0})};var U,dt,R,x,f,P=W(()=>{U=()=>{},dt={debug:U,info:U,warn:(...r)=>console.warn("[workflow]",...r),error:(...r)=>console.error("[workflow]",...r)},R=Symbol.for("@zibby/agent-workflow.logger");globalThis[R]||(globalThis[R]={impl:dt});x=globalThis[R],f={debug:(...r)=>x.impl.debug?.(...r),info:(...r)=>x.impl.info?.(...r),warn:(...r)=>x.impl.warn?.(...r),error:(...r)=>x.impl.error?.(...r)}});var Q=W(()=>{});function tt(r){return mt.get(r)||null}var j,D,mt,At,et=W(()=>{j=Symbol.for("@zibby/agent-workflow.skills"),D=Symbol.for("@zibby/agent-workflow.skills.sources");globalThis[j]||(globalThis[j]=new Map);globalThis[D]||(globalThis[D]=new Map);mt=globalThis[j],At=globalThis[D]});var it={};pt(it,{getAgentStrategy:()=>st,invokeAgent:()=>yt,listStrategies:()=>St,registerStrategy:()=>gt,resolveInvocationExtras:()=>ot,resolveInvocationModel:()=>rt});function gt(r){if(!r||typeof r.getName!="function"||typeof r.invoke!="function")throw new Error("strategy must implement getName() and invoke() (AgentStrategy shape)");let t=O.findIndex(e=>e.getName()===r.getName());t>=0?O[t]=r:O.push(r)}function St(){return O.map(r=>r.getName())}function rt({config:r={},options:t={},strategyName:e,envModel:o,nodeConfigModel:i}={}){let s=r.models||{},c=typeof i=="string"&&i.trim()?i.trim():null,S=t.nodeName&&s[t.nodeName]||null,h=s.default||null,_=r.agent?.[e]?.model||null,I=(typeof o=="string"?o.trim():"")||null;return c||S||h||_||t.model||I||null}function ot({options:r={},stateView:t={},context:e={}}={}){return{workspace:t.workspace||r.workspace,schema:r.schema||e.schema,images:r.images||e.images||[],skills:r.skills||e.skills||[],extraMcpServers:r.extraMcpServers||t.extraMcpServers||e.extraMcpServers||[],plugins:r.plugins||e.plugins||[]}}function st(r={}){let{state:t={},preferredAgent:e=null}=r,o=e||t.agentType||process.env.AGENT_TYPE;if(!o){let s=O.map(c=>c.getName()).join(", ")||"none registered";throw new Error(`No agent specified. Set agentType in state or AGENT_TYPE env var. Available: ${s}`)}f.debug(`[workflow] agent selection: requested=${o}`);let i=O.find(s=>s.getName()===o);if(!i){let s=O.map(c=>c.getName()).join(", ")||"none registered";throw new Error(`Unknown agent '${o}'. Available: ${s}`)}if(!i.canHandle(r))throw new Error(`Agent '${o}' is not available in this environment. Check credentials/environment.`);return f.debug(`[workflow] using agent: ${i.getName()}`),i}async function yt(r,t={},e={}){let o=t.state&&typeof t.state.getAll=="function"?t.state.getAll():t.state||{},i={...t,state:o},s=st(i),c=o.config||e.config||{},S=o._currentNodeConfig||{},h=typeof S.agent=="string"?S.agent.trim():"",_=!h||h===s.name?S.model:null,I=rt({config:c,options:e,strategyName:s.name,envModel:process.env.MODEL,nodeConfigModel:_}),u={...e,model:I,...ot({options:e,stateView:o,context:t}),config:c},p=r,a=u.skills||[];if(a.length>0&&!e.skipPromptFragments){let $=e.connectedIntegrations;if(!$){let n=process.env.WORKFLOW_CONNECTED_INTEGRATIONS;if(typeof n=="string"&&n.trim()!==""){$={};for(let g of n.split(",").map(b=>b.trim()).filter(Boolean))$[g]=!0}}let E=n=>{let g=n&&n.requiresIntegration;return!g||!$?!0:(Array.isArray(g)?g:[g]).some(A=>$[A]===!0)},l=s.name==="assistant",d=n=>n?.inProcessOnly!==!0||l,y=a.map(n=>{let g=tt(n);if(!E(g)||!d(g))return null;let b=g?.promptFragment;return typeof b=="function"?b():b}).filter(Boolean);y.length>0&&(p+=`
1
+ var _t=Object.defineProperty;var R=(r,t,e)=>()=>{if(e)throw e[0];try{return r&&(t=r(r=0)),t}catch(n){throw e=[n],n}};var wt=(r,t)=>{for(var e in t)_t(r,e,{get:t[e],enumerable:!0})};var z,St,M,x,f,P=R(()=>{z=()=>{},St={debug:z,info:z,warn:(...r)=>console.warn("[workflow]",...r),error:(...r)=>console.error("[workflow]",...r)},M=Symbol.for("@zibby/agent-workflow.logger");globalThis[M]||(globalThis[M]={impl:St});x=globalThis[M],f={debug:(...r)=>x.impl.debug?.(...r),info:(...r)=>x.impl.info?.(...r),warn:(...r)=>x.impl.warn?.(...r),error:(...r)=>x.impl.error?.(...r)}});var st=R(()=>{});function at(r){return xt.get(r)||null}var G,U,xt,zt,ut=R(()=>{G=Symbol.for("@zibby/agent-workflow.skills"),U=Symbol.for("@zibby/agent-workflow.skills.sources");globalThis[G]||(globalThis[G]=new Map);globalThis[U]||(globalThis[U]=new Map);xt=globalThis[G],zt=globalThis[U]});var pt={};wt(pt,{getAgentStrategy:()=>dt,invokeAgent:()=>Wt,listStrategies:()=>Pt,registerStrategy:()=>Mt,resolveInvocationExtras:()=>lt,resolveInvocationModel:()=>ct});function Mt(r){if(!r||typeof r.getName!="function"||typeof r.invoke!="function")throw new Error("strategy must implement getName() and invoke() (AgentStrategy shape)");let t=$.findIndex(e=>e.getName()===r.getName());t>=0?$[t]=r:$.push(r)}function Pt(){return $.map(r=>r.getName())}function ct({config:r={},options:t={},strategyName:e,envModel:n,nodeConfigModel:o}={}){let i=r.models||{},a=typeof o=="string"&&o.trim()?o.trim():null,m=t.nodeName&&i[t.nodeName]||null,l=i.default||null,S=r.agent?.[e]?.model||null,E=(typeof n=="string"?n.trim():"")||null;return a||m||l||S||t.model||E||null}function lt({options:r={},stateView:t={},context:e={}}={}){return{workspace:t.workspace||r.workspace,schema:r.schema||e.schema,images:r.images||e.images||[],skills:r.skills||e.skills||[],extraMcpServers:r.extraMcpServers||t.extraMcpServers||e.extraMcpServers||[],plugins:r.plugins||e.plugins||[]}}function dt(r={}){let{state:t={},preferredAgent:e=null}=r,n=e||t.agentType||process.env.AGENT_TYPE;if(!n){let i=$.map(a=>a.getName()).join(", ")||"none registered";throw new Error(`No agent specified. Set agentType in state or AGENT_TYPE env var. Available: ${i}`)}f.debug(`[workflow] agent selection: requested=${n}`);let o=$.find(i=>i.getName()===n);if(!o){let i=$.map(a=>a.getName()).join(", ")||"none registered";throw new Error(`Unknown agent '${n}'. Available: ${i}`)}if(!o.canHandle(r))throw new Error(`Agent '${n}' is not available in this environment. Check credentials/environment.`);return f.debug(`[workflow] using agent: ${o.getName()}`),o}async function Wt(r,t={},e={}){let n=t.state&&typeof t.state.getAll=="function"?t.state.getAll():t.state||{},o={...t,state:n},i=dt(o),a=n.config||e.config||{},m=n._currentNodeConfig||{},l=typeof m.agent=="string"?m.agent.trim():"",S=!l||l===i.name?m.model:null,E=ct({config:a,options:e,strategyName:i.name,envModel:process.env.MODEL,nodeConfigModel:S}),I={...e,model:E,...lt({options:e,stateView:n,context:t}),config:a},N=r,c=I.skills||[];if(c.length>0&&!e.skipPromptFragments){let w=e.connectedIntegrations;if(!w){let p=process.env.WORKFLOW_CONNECTED_INTEGRATIONS;if(typeof p=="string"&&p.trim()!==""){w={};for(let u of p.split(",").map(b=>b.trim()).filter(Boolean))w[u]=!0}}let T=p=>{let u=p&&p.requiresIntegration;return!u||!w?!0:(Array.isArray(u)?u:[u]).some(O=>w[O]===!0)},s=i.name==="assistant",_=p=>p?.inProcessOnly!==!0||s,h=c.map(p=>{let u=at(p);if(!T(u)||!_(u))return null;let b=u?.promptFragment;return typeof b=="function"?b():b}).filter(Boolean);h.length>0&&(N+=`
2
2
 
3
- ${y.join(`
3
+ ${h.join(`
4
4
 
5
- `)}`)}let w=o._currentNodeConfig?.stores;if(Array.isArray(w)&&w.length>0&&typeof w[0]=="object"){let $=w.length<=8,E=w.map(l=>{let d=l?.id??l?.storeId??"",y=(l?.name??"").toString().trim()||d,n=l?.type?` \xB7 ${l.type}`:"",g=(l?.description||"").toString().replace(/\s+/g," ").trim(),b=`- ${y} \xB7 ${g||"(no description)"}${n} (id: ${d})`;if($&&l?.schema&&typeof l.schema=="object"){let A=l.schema.properties&&typeof l.schema.properties=="object"?Object.keys(l.schema.properties):Object.keys(l.schema);A.length&&(b+=`
6
- fields: ${A.join(", ")}`)}return b});p+=`
5
+ `)}`)}let d=n._currentNodeConfig?.stores;if(Array.isArray(d)&&d.length>0&&typeof d[0]=="object"){let w=d.length<=8,T=d.map(s=>{let _=s?.id??s?.storeId??"",h=(s?.name??"").toString().trim()||_,p=s?.type?` \xB7 ${s.type}`:"",u=(s?.description||"").toString().replace(/\s+/g," ").trim(),b=`- ${h} \xB7 ${u||"(no description)"}${p} (id: ${_})`;if(w&&s?.schema&&typeof s.schema=="object"){let O=s.schema.properties&&typeof s.schema.properties=="object"?Object.keys(s.schema.properties):Object.keys(s.schema);O.length&&(b+=`
6
+ fields: ${O.join(", ")}`)}return b});N+=`
7
7
 
8
8
  AVAILABLE STORES (pick a store by its description and pass its NAME to the store tool):
9
- ${E.join(`
10
- `)}`}let N=o._currentNodeConfig?.extraPromptInstructions?.trim();return N&&(p+=`
9
+ ${T.join(`
10
+ `)}`}let y=n._currentNodeConfig?.extraPromptInstructions?.trim();return y&&(N+=`
11
11
 
12
12
  \u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501
13
13
  PRIORITY OVERRIDE \u2014 THE FOLLOWING INSTRUCTIONS TAKE PRECEDENCE OVER ALL PREVIOUS CONTENT
14
14
  \u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501
15
15
 
16
- ${N}
17
- `),f.debug(`[workflow] prompt length: ${p.length} chars`),s.invoke(p,u)}var G,O,nt=W(()=>{Q();P();et();G=Symbol.for("@zibby/agent-workflow.strategies");globalThis[G]||(globalThis[G]=[]);O=globalThis[G]});import k from"handlebars";var v=class{constructor(t){this.schema=t}parse(t){let e=t.match(/```json\s*([\s\S]*?)\s*```/);if(e)return this.validate(JSON.parse(e[1]));let o=[t.match(/\{[\s\S]*?\}/),t.match(/\{[\s\S]*\}/)].filter(Boolean).map(i=>i[0]);for(let i of o)try{return this.validate(JSON.parse(i))}catch(s){if(!(s instanceof SyntaxError))throw s}return this.validate({result:t.trim()})}validate(t){let e=[];for(let[o,i]of Object.entries(this.schema)){if(i.required&&!(o in t)&&e.push(`Missing required field: ${o}`),o in t&&i.type){let s=typeof t[o];s!==i.type&&e.push(`Field '${o}' expected ${i.type}, got ${s}`)}if(i.validate&&o in t){let s=i.validate(t[o]);s&&e.push(`Field '${o}': ${s}`)}}if(e.length>0)throw new Error(`Output validation failed:
16
+ ${y}
17
+ `),f.debug(`[workflow] prompt length: ${N.length} chars`),i.invoke(N,I)}var H,$,ft=R(()=>{st();P();ut();H=Symbol.for("@zibby/agent-workflow.strategies");globalThis[H]||(globalThis[H]=[]);$=globalThis[H]});import k from"handlebars";var v=class{constructor(t){this.schema=t}parse(t){let e=t.match(/```json\s*([\s\S]*?)\s*```/);if(e)return this.validate(JSON.parse(e[1]));let n=[t.match(/\{[\s\S]*?\}/),t.match(/\{[\s\S]*\}/)].filter(Boolean).map(o=>o[0]);for(let o of n)try{return this.validate(JSON.parse(o))}catch(i){if(!(i instanceof SyntaxError))throw i}return this.validate({result:t.trim()})}validate(t){let e=[];for(let[n,o]of Object.entries(this.schema)){if(o.required&&!(n in t)&&e.push(`Missing required field: ${n}`),n in t&&o.type){let i=typeof t[n];i!==o.type&&e.push(`Field '${n}' expected ${o.type}, got ${i}`)}if(o.validate&&n in t){let i=o.validate(t[n]);i&&e.push(`Field '${n}': ${i}`)}}if(e.length>0)throw new Error(`Output validation failed:
18
18
  ${e.join(`
19
- `)}`);return t}};P();import{writeFileSync as H,readFileSync as at,existsSync as lt,mkdirSync as _t}from"node:fs";import{join as J,dirname as wt}from"node:path";import m from"chalk";var ft="__WORKFLOW_GRAPH_LOG__",T=m.gray("\u2502"),ht=m.gray("\u250C"),K=m.gray("\u2514"),L=m.green("\u25C6"),B=m.hex("#c084fc")("\u25C6"),Y=m.hex("#2dd4bf")("\u25C6"),M=m.red("\u25C6"),Z=`${T} `,z=2;function q(r){return r<1e3?`${r}ms`:`${(r/1e3).toFixed(1)}s`}function V(r,t){return(e,o,i)=>{if(typeof e!="string")return r(e,o,i);let s=process.stdout.columns||120,c="";for(let S=0;S<e.length;S++){let h=e[S];t.lineStart&&(c+=Z,t.col=z,t.lineStart=!1),h===`
20
- `?(c+=h,t.lineStart=!0,t.col=0,t.inEsc=!1):h==="\x1B"?(t.inEsc=!0,c+=h):t.inEsc?(c+=h,(h>="A"&&h<="Z"||h>="a"&&h<="z")&&(t.inEsc=!1)):(t.col++,c+=h,t.col>=s&&(c+=`
21
- ${Z}`,t.col=z))}return r(c,o,i)}}var C=class{constructor(){this._currentNode=null,this._origStdoutWrite=null,this._origStderrWrite=null,this._emitWorkflowGraphMarkers=String(process.env.ZIBBY_EMIT_GRAPH_MARKERS||"").trim()==="1"||String(process.env.ZIBBY_WORKFLOW_GRAPH_LOG_MARKERS||"").trim()==="1"}get isInsideNode(){return this._currentNode!==null}_startIntercepting(){this._origStdoutWrite=process.stdout.write.bind(process.stdout),this._origStderrWrite=process.stderr.write.bind(process.stderr);let t={lineStart:!0,col:0,inEsc:!1},e={lineStart:!0,col:0,inEsc:!1};this._outState=t,this._errState=e,process.stdout.write=V(this._origStdoutWrite,t),process.stderr.write=V(this._origStderrWrite,e)}_stopIntercepting(){this._origStdoutWrite&&(this._outState&&!this._outState.lineStart&&this._origStdoutWrite(`
19
+ `)}`);return t}};P();import{writeFileSync as K,readFileSync as mt,existsSync as ht,mkdirSync as Ct}from"node:fs";import{join as J,dirname as Lt}from"node:path";import g from"chalk";var bt="__WORKFLOW_GRAPH_LOG__",A=g.gray("\u2502"),Et=g.gray("\u250C"),q=g.gray("\u2514"),W=g.green("\u25C6"),Y=g.hex("#c084fc")("\u25C6"),V=g.hex("#2dd4bf")("\u25C6"),C=g.red("\u25C6"),Z=`${A} `,X=2;function Q(r){return r<1e3?`${r}ms`:`${(r/1e3).toFixed(1)}s`}function tt(r,t){return(e,n,o)=>{if(typeof e!="string")return r(e,n,o);let i=process.stdout.columns||120,a="";for(let m=0;m<e.length;m++){let l=e[m];t.lineStart&&(a+=Z,t.col=X,t.lineStart=!1),l===`
20
+ `?(a+=l,t.lineStart=!0,t.col=0,t.inEsc=!1):l==="\x1B"?(t.inEsc=!0,a+=l):t.inEsc?(a+=l,(l>="A"&&l<="Z"||l>="a"&&l<="z")&&(t.inEsc=!1)):(t.col++,a+=l,t.col>=i&&(a+=`
21
+ ${Z}`,t.col=X))}return r(a,n,o)}}var L=class{constructor(){this._currentNode=null,this._origStdoutWrite=null,this._origStderrWrite=null,this._emitWorkflowGraphMarkers=String(process.env.ZIBBY_EMIT_GRAPH_MARKERS||"").trim()==="1"||String(process.env.ZIBBY_WORKFLOW_GRAPH_LOG_MARKERS||"").trim()==="1"}get isInsideNode(){return this._currentNode!==null}_startIntercepting(){this._origStdoutWrite=process.stdout.write.bind(process.stdout),this._origStderrWrite=process.stderr.write.bind(process.stderr);let t={lineStart:!0,col:0,inEsc:!1},e={lineStart:!0,col:0,inEsc:!1};this._outState=t,this._errState=e,process.stdout.write=tt(this._origStdoutWrite,t),process.stderr.write=tt(this._origStderrWrite,e)}_stopIntercepting(){this._origStdoutWrite&&(this._outState&&!this._outState.lineStart&&this._origStdoutWrite(`
22
22
  `),process.stdout.write=this._origStdoutWrite),this._origStderrWrite&&(this._errState&&!this._errState.lineStart&&this._origStderrWrite(`
23
23
  `),process.stderr.write=this._origStderrWrite),this._origStdoutWrite=null,this._origStderrWrite=null}_rawWrite(t){(this._origStdoutWrite||process.stdout.write.bind(process.stdout))(`${t}
24
- `)}_emitGraphLogMarker(t){if(!this._emitWorkflowGraphMarkers)return;let e=`${ft}${JSON.stringify(t)}
24
+ `)}_emitGraphLogMarker(t){if(!this._emitWorkflowGraphMarkers)return;let e=`${bt}${JSON.stringify(t)}
25
25
  `;this._origStdoutWrite?this._origStdoutWrite(e):process.stdout.write(e)}_writeDot(t,e){this._origStdoutWrite?(this._outState&&!this._outState.lineStart&&(this._origStdoutWrite(`
26
26
  `),this._outState.lineStart=!0,this._outState.col=0),this._origStdoutWrite(`${t} ${e}
27
27
  `)):process.stdout.write.bind(process.stdout)(`${t} ${e}
28
- `)}step(t){this._origStdoutWrite?this._writeDot(L,t):process.stdout.write.bind(process.stdout)(`${T} ${L} ${t}
29
- `)}stepInfo(t){this.step(t)}stepTool(t){this._origStdoutWrite?this._writeDot(B,t):process.stdout.write.bind(process.stdout)(`${T} ${B} ${t}
30
- `)}stepMemory(t){let e=m.hex("#2dd4bf")(t);this._origStdoutWrite?this._writeDot(Y,e):process.stdout.write.bind(process.stdout)(`${T} ${Y} ${e}
31
- `)}stepFail(t){this._origStdoutWrite?this._writeDot(M,m.red(t)):process.stdout.write.bind(process.stdout)(`${T} ${M} ${m.red(t)}
32
- `)}nodeStart(t){this._currentNode=t,this._emitGraphLogMarker({phase:"node_begin",node:t}),this._rawWrite(`${ht} ${t}`),this._startIntercepting()}nodeComplete(t,e={}){this._stopIntercepting();let{duration:o,details:i}=e;if(i)for(let c of i)this._rawWrite(`${L} ${c}`);let s=o?m.dim(` ${q(o)}`):"";this._rawWrite(`${K} ${m.green("done")}${s}`),this._emitGraphLogMarker({phase:"node_end",node:t}),this._rawWrite("")}nodeFailed(t,e,o={}){this._stopIntercepting();let{duration:i}=o,s=i?m.dim(` ${q(i)}`):"";this._rawWrite(`${M} ${m.red(e)}`),this._rawWrite(`${K} ${m.red("failed")}${s}`),this._emitGraphLogMarker({phase:"node_end",node:t}),this._rawWrite("")}route(t,e){this._rawWrite(m.dim(` ${t} \u2192 ${e}`)),this._rawWrite("")}graphComplete(){}},X=new C;var F=".session-info.json";var It=Object.freeze(["codebase-memory","code-scan","artifact"]);k.helpers.inc||k.registerHelper("inc",r=>Number(r)+1);k.helpers.json||k.registerHelper("json",r=>JSON.stringify(r,null,2));k.helpers.eq||k.registerHelper("eq",(r,t)=>r===t);var ct=class{constructor(t){if(this.config=t,this.name=t.name,this.prompt=t.prompt,this.outputSchema=t.outputSchema,!this.outputSchema&&!t._isCustomCode&&!t._isRouter)throw new Error(`Node '${this.name}' must define outputSchema (Zod schema). This defines the contract for what the node returns to state.`);this.isZodSchema=this.outputSchema&&typeof this.outputSchema._def<"u",this.parser=t.outputSchema&&!this.isZodSchema?new v(t.outputSchema):null,this.retries=t.retries||0,this.onComplete=t.onComplete,this.customExecute=t.execute}async execute(t,e){if(this.config._isRouter)return f.debug(`[workflow] node '${this.name}': router passthrough (routing happens on its conditional edges)`),{success:!0,output:{},raw:null};let o=()=>e&&typeof e.getAll=="function"?e.getAll():t,i=u=>e&&typeof e.get=="function"?e.get(u):t?.[u];if(typeof this.customExecute=="function"){f.debug(`[workflow] node '${this.name}': custom execute (skipping LLM)`);let u=null;for(let p=0;p<=this.retries;p++){try{let a=await this.customExecute(t);if(typeof a=="object"&&a!==null&&a.success===!1)u={success:!1,error:a.error||"Node execution failed",raw:a.raw||null};else return this.isZodSchema?(f.debug(`[workflow] node '${this.name}': validating output schema`),{success:!0,output:this.outputSchema.parse(a),raw:null}):{success:!0,output:a,raw:null}}catch(a){f.error(`[workflow] node '${this.name}' failed: ${a.message}`),a.name==="ZodError"&&f.error(`Schema errors: ${JSON.stringify(a.issues||a.errors,null,2)}`),u={success:!1,error:a.message,raw:null}}p<this.retries&&f.info(`[workflow] node '${this.name}' failed, retrying (${p+1}/${this.retries})\u2026`)}return u}let s;typeof this.prompt=="function"?s=this.prompt(o()):typeof this.prompt=="string"&&this.prompt.includes("{{")?(this._compiledPrompt||(this._compiledPrompt=k.compile(this.prompt,{noEscape:!0})),s=this._compiledPrompt(o())):s=this.prompt;let c=i("_skillHints");c&&(s=`${c}
28
+ `)}step(t){this._origStdoutWrite?this._writeDot(W,t):process.stdout.write.bind(process.stdout)(`${A} ${W} ${t}
29
+ `)}stepInfo(t){this.step(t)}stepTool(t){this._origStdoutWrite?this._writeDot(Y,t):process.stdout.write.bind(process.stdout)(`${A} ${Y} ${t}
30
+ `)}stepMemory(t){let e=g.hex("#2dd4bf")(t);this._origStdoutWrite?this._writeDot(V,e):process.stdout.write.bind(process.stdout)(`${A} ${V} ${e}
31
+ `)}stepFail(t){this._origStdoutWrite?this._writeDot(C,g.red(t)):process.stdout.write.bind(process.stdout)(`${A} ${C} ${g.red(t)}
32
+ `)}nodeStart(t){this._currentNode=t,this._emitGraphLogMarker({phase:"node_begin",node:t}),this._rawWrite(`${Et} ${t}`),this._startIntercepting()}nodeComplete(t,e={}){this._stopIntercepting();let{duration:n,details:o}=e;if(o)for(let a of o)this._rawWrite(`${W} ${a}`);let i=n?g.dim(` ${Q(n)}`):"";this._rawWrite(`${q} ${g.green("done")}${i}`),this._emitGraphLogMarker({phase:"node_end",node:t}),this._rawWrite("")}nodeFailed(t,e,n={}){this._stopIntercepting();let{duration:o}=n,i=o?g.dim(` ${Q(o)}`):"";this._rawWrite(`${C} ${g.red(e)}`),this._rawWrite(`${q} ${g.red("failed")}${i}`),this._emitGraphLogMarker({phase:"node_end",node:t}),this._rawWrite("")}route(t,e){this._rawWrite(g.dim(` ${t} \u2192 ${e}`)),this._rawWrite("")}graphComplete(){}},et=new L;var F=".session-info.json";var Ut=Object.freeze(["codebase-memory","code-scan","artifact"]);var Nt=Object.freeze({authentication_failed:"deterministic",oauth_org_not_allowed:"deterministic",billing_error:"deterministic",invalid_request:"deterministic",max_output_tokens:"deterministic",rate_limit:"transient",server_error:"transient",unknown:"inconclusive"}),Tt=Object.freeze([/stream idle timeout/i,/partial response received/i,/no chunks received/i,/stream ended without receiving any events/i,/stream completed without receiving/i,/socket hang up/i,/premature close/i,/\b(?:ECONNRESET|ECONNABORTED|ECONNREFUSED|EPIPE|ETIMEDOUT|EAI_AGAIN|ENETUNREACH|ENETRESET|EHOSTUNREACH)\b/,/\bfetch failed\b/i,/\bnetwork (?:error|timeout)\b/i,/request timed out/i,/\brequest timeout\b/i,/\boverloaded(?:_error)?\b/i,/\brate[_ ]limit(?:_error|ed)?\b/i,/\b(?:HTTP|http_status|status(?:\s*code)?)[:= ]\s*(?:429|5\d\d)\b/i,/\b(?:429|500|502|503|504|529)\s+(?:too many requests|internal server error|bad gateway|service unavailable|gateway time-?out|overloaded)\b/i]),$t=Object.freeze([/\bAbortError\b/,/\bAPIUserAbortError\b/,/\boperation was aborted\b/i,/\bcanceled by parent abort\b/i,/\bstopped by operator\b/i]),ot=/provider error \[([a-z_]+)(?:\s+http\s+(\d{3}))?\]/i;function j(r){if(r==null)return"";if(typeof r=="string")return r;if(typeof r!="object")return String(r);let t=r;return[t.message,t.name,t.code,t.providerErrorText,t.cause?.message??(typeof t.cause=="string"?t.cause:void 0),t.cause?.code].filter(n=>typeof n=="string"||typeof n=="number").join(" | ")}function kt(r){if(r&&typeof r=="object"){let e=r.providerErrorKind;if(typeof e=="string"&&e.trim())return e.trim()}let t=ot.exec(j(r));return t?t[1].toLowerCase():null}function It(r){if(r&&typeof r=="object"){let n=Number(r.providerErrorStatus);if(Number.isInteger(n)&&n>=100&&n<=599)return n}let t=ot.exec(j(r)),e=t&&t[2]?Number(t[2]):NaN;return Number.isInteger(e)?e:null}function At(r){let t=j(r);if(!t)return"deterministic";for(let o of $t)if(o.test(t))return"deterministic";let e=kt(r);if(e){let o=Nt[e];if(o==="transient"||o==="deterministic")return o}let n=It(r);if(n===429||n>=500&&n<=599)return"transient";for(let o of Tt)if(o.test(t))return"transient";return"deterministic"}var rt=2,Ot=5;function Rt(r=process.env){let t=r?.AGENT_TRANSIENT_RETRIES;if(t==null||String(t).trim()==="")return rt;let e=Number(t);return!Number.isFinite(e)||e<0?rt:Math.min(Ot,Math.floor(e))}var D=5e3,it=3e4;function vt(r=process.env){let t=r?.AGENT_TRANSIENT_BACKOFF_MS;if(t==null||String(t).trim()==="")return D;let e=Number(t);return!Number.isFinite(e)||e<0?D:Math.min(it,Math.floor(e))}function nt(r,t=Math.random,e=D){if(!(e>0))return 0;let n=Math.max(1,Math.floor(Number(r)||1)),o=Math.min(it,e*2**(n-1)),i=1+(t()-.5)*.4;return Math.max(1,Math.round(o*i))}function B(r,{env:t=process.env,rand:e=Math.random}={}){let n=Math.max(0,Math.floor(Number(r)||0)),o=Rt(t),i=vt(t),a=0,m=0;return{get attemptsMade(){return 1+a+m},get transientUsed(){return m},get transientMax(){return o},next(l){let S=At(l);return a<n?(a+=1,{retry:!0,paidBy:"declared",delayMs:S==="transient"?nt(a,e,i):0,failureClass:S,index:a,of:n}):S==="transient"&&m<o?(m+=1,{retry:!0,paidBy:"transient",delayMs:nt(m,e,i),failureClass:S,index:m,of:o}):{retry:!1,delayMs:0,failureClass:S}}}}async function gt(r,t,e,n){if(!t.retry)return!1;if(n())return f.info(`[workflow] node '${r}': run aborted \u2014 not retrying`),!1;let o=e?.message??String(e??"");return t.paidBy==="transient"?f.warn(`[workflow] node '${r}': TRANSIENT provider failure \u2014 ${o}. Retrying in ${Math.round(t.delayMs/1e3)}s (transient retry ${t.index}/${t.of}; the workspace is untouched, so files this node already wrote survive into the retry).`):f.info(`[workflow] node '${r}' failed (${t.failureClass}), retrying (${t.index}/${t.of})\u2026`),t.delayMs>0&&(await new Promise(i=>setTimeout(i,t.delayMs)),n())?(f.info(`[workflow] node '${r}': run aborted during backoff \u2014 not retrying`),!1):!0}k.helpers.inc||k.registerHelper("inc",r=>Number(r)+1);k.helpers.json||k.registerHelper("json",r=>JSON.stringify(r,null,2));k.helpers.eq||k.registerHelper("eq",(r,t)=>r===t);var yt=class{constructor(t){if(this.config=t,this.name=t.name,this.prompt=t.prompt,this.outputSchema=t.outputSchema,!this.outputSchema&&!t._isCustomCode&&!t._isRouter)throw new Error(`Node '${this.name}' must define outputSchema (Zod schema). This defines the contract for what the node returns to state.`);this.isZodSchema=this.outputSchema&&typeof this.outputSchema._def<"u",this.parser=t.outputSchema&&!this.isZodSchema?new v(t.outputSchema):null,this.retries=t.retries||0,this.onComplete=t.onComplete,this.customExecute=t.execute}async execute(t,e){if(this.config._isRouter)return f.debug(`[workflow] node '${this.name}': router passthrough (routing happens on its conditional edges)`),{success:!0,output:{},raw:null};let n=()=>e&&typeof e.getAll=="function"?e.getAll():t,o=c=>e&&typeof e.get=="function"?e.get(c):t?.[c],i=()=>o("_signal")?.aborted===!0;if(typeof this.customExecute=="function"){f.debug(`[workflow] node '${this.name}': custom execute (skipping LLM)`);let c=B(this.retries),d=null,y=null;for(;;){try{let s=await this.customExecute(t);if(typeof s=="object"&&s!==null&&s.success===!1)y=null,d={success:!1,error:s.error||`node '${this.name}' returned { success: false } with no \`error\` field. On a custom-code node \`success\` is RESERVED: the engine reads it as "this node failed" and stops the graph. If it was meant as a DOMAIN fact (no diff to commit, a PR deliberately skipped), give that fact its own field name and return the outcome \u2014 or set \`error\` to say what actually failed.`,raw:s.raw||null};else return this.isZodSchema?(f.debug(`[workflow] node '${this.name}': validating output schema`),{success:!0,output:this.outputSchema.parse(s),raw:null}):{success:!0,output:s,raw:null}}catch(s){f.error(`[workflow] node '${this.name}' failed: ${s.message}`),s.name==="ZodError"&&f.error(`Schema errors: ${JSON.stringify(s.issues||s.errors,null,2)}`),y=s,d={success:!1,error:s.message,raw:null}}let w=y??d?.error,T=c.next(w);if(!await gt(this.name,T,w,i))break}return d&&(d.attempts=c.attemptsMade),d}let a;typeof this.prompt=="function"?a=this.prompt(n()):typeof this.prompt=="string"&&this.prompt.includes("{{")?(this._compiledPrompt||(this._compiledPrompt=k.compile(this.prompt,{noEscape:!0})),a=this._compiledPrompt(n())):a=this.prompt;let m=o("_skillHints");m&&(a=`${m}
33
33
 
34
- ${s}`);let S=o(),h=S.cwd||process.cwd(),_=S.sessionPath;try{if(_){let u=J(_,F);if(lt(u)){let a=JSON.parse(at(u,"utf-8"));a.currentNode=this.name,H(u,JSON.stringify(a,null,2),"utf-8")}let p=J(_,"..",F);if(lt(p))try{let a=JSON.parse(at(p,"utf-8"));a.currentNode=this.name,H(p,JSON.stringify(a,null,2),"utf-8")}catch{}}}catch(u){f.debug(`[workflow] could not update session info: ${u.message}`)}let I=null;for(let u=0;u<=this.retries;u++)try{f.debug(`[workflow] node '${this.name}' attempt ${u}`);let p=o().config||{},a=p.agents||{},w=this.config.agent??a[this.name]??null,N={state:o()};w&&(N.preferredAgent=w);let $={workspace:h,schema:this.isZodSchema?this.outputSchema:null,skills:this.config.skills||[],disallowedTools:this.config.disallowedTools||[],plugins:this.config.plugins||[],sessionPath:_,config:p,nodeName:this.name,timeout:this.config?.timeout||3e5},E=t?._coreInvokeAgent;E||(E=(await Promise.resolve().then(()=>(nt(),it))).invokeAgent);let l=await E(s,N,$),d,y;if(typeof l=="string"?(d=l,y=null):l.structured?(d=l.raw||JSON.stringify(l.structured,null,2),y=l.structured):(d=l.raw||JSON.stringify(l,null,2),y=l.extracted||null),_)try{let n=J(_,this.name,"raw_stream_output.txt");_t(wt(n),{recursive:!0}),H(n,typeof d=="string"?d:JSON.stringify(d),"utf-8")}catch(n){f.debug(`[workflow] could not save raw output: ${n.message}`)}if(this.isZodSchema&&y){f.debug(`[workflow] node '${this.name}': output validated: ${JSON.stringify(y,null,2)}`);let n=y;if(typeof this.onComplete=="function")try{n=await this.onComplete(o(),y)}catch(g){f.warn(`[workflow] onComplete hook failed: ${g.message}`)}return{success:!0,output:n,raw:d}}if(typeof this.onComplete=="function")try{return{success:!0,output:await this.onComplete(o(),{raw:d}),raw:d}}catch(n){throw new Error(`onComplete failed: ${n.message}`,{cause:n})}if(this.parser){let n=this.parser.parse(d);return f.debug(`[workflow] node '${this.name}': parsed output: ${JSON.stringify(n,null,2)}`),X.step("Output parsed"),{success:!0,output:n,raw:d}}return{success:!0,output:d,raw:d}}catch(p){I=p,u<this.retries&&f.info(`[workflow] node '${this.name}' failed, retrying (${u+1}/${this.retries})\u2026`)}return{success:!1,error:I.message,raw:null}}};export{ct as Node};
34
+ ${a}`);let l=n(),S=l.cwd||process.cwd(),E=l.sessionPath;try{if(E){let c=J(E,F);if(ht(c)){let y=JSON.parse(mt(c,"utf-8"));y.currentNode=this.name,K(c,JSON.stringify(y,null,2),"utf-8")}let d=J(E,"..",F);if(ht(d))try{let y=JSON.parse(mt(d,"utf-8"));y.currentNode=this.name,K(d,JSON.stringify(y,null,2),"utf-8")}catch{}}}catch(c){f.debug(`[workflow] could not update session info: ${c.message}`)}let I=B(this.retries),N=null;for(;;)try{f.debug(`[workflow] node '${this.name}' attempt ${I.attemptsMade-1}`);let c=n().config||{},d=c.agents||{},y=this.config.agent??d[this.name]??null,w={state:n()};y&&(w.preferredAgent=y);let T={workspace:S,schema:this.isZodSchema?this.outputSchema:null,skills:this.config.skills||[],disallowedTools:this.config.disallowedTools||[],plugins:this.config.plugins||[],sessionPath:E,config:c,nodeName:this.name,timeout:this.config?.timeout||3e5},s=t?._coreInvokeAgent;s||(s=(await Promise.resolve().then(()=>(ft(),pt))).invokeAgent);let _=await s(a,w,T),h,p;if(typeof _=="string"?(h=_,p=null):_.structured?(h=_.raw||JSON.stringify(_.structured,null,2),p=_.structured):(h=_.raw||JSON.stringify(_,null,2),p=_.extracted||null),E)try{let u=J(E,this.name,"raw_stream_output.txt");Ct(Lt(u),{recursive:!0}),K(u,typeof h=="string"?h:JSON.stringify(h),"utf-8")}catch(u){f.debug(`[workflow] could not save raw output: ${u.message}`)}if(this.isZodSchema&&p){f.debug(`[workflow] node '${this.name}': output validated: ${JSON.stringify(p,null,2)}`);let u=p;if(typeof this.onComplete=="function")try{u=await this.onComplete(n(),p)}catch(b){f.warn(`[workflow] onComplete hook failed: ${b.message}`)}return{success:!0,output:u,raw:h}}if(typeof this.onComplete=="function")try{return{success:!0,output:await this.onComplete(n(),{raw:h}),raw:h}}catch(u){throw new Error(`onComplete failed: ${u.message}`,{cause:u})}if(this.parser){let u=this.parser.parse(h);return f.debug(`[workflow] node '${this.name}': parsed output: ${JSON.stringify(u,null,2)}`),et.step("Output parsed"),{success:!0,output:u,raw:h}}return{success:!0,output:h,raw:h}}catch(c){N=c;let d=I.next(c);if(!await gt(this.name,d,c,i))break}return{success:!1,error:N.message,raw:null,attempts:I.attemptsMade}}};export{yt as Node};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zibby/agent-workflow",
3
- "version": "2.0.5",
3
+ "version": "2.0.7",
4
4
  "description": "Graph-based AI agent workflow orchestration. Bring your own agent strategies.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",