@zibby/agent-workflow 0.4.10 → 0.4.14
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/constants.d.ts +3 -0
- package/dist/constants.js +1 -1
- package/dist/graph-compiler.js +19 -19
- package/dist/graph.d.ts +3 -0
- package/dist/graph.js +17 -17
- package/dist/index.js +33 -33
- package/dist/node.d.ts +1 -0
- package/dist/node.js +12 -12
- package/package.json +1 -1
package/dist/constants.d.ts
CHANGED
|
@@ -28,6 +28,7 @@ export namespace SKILLS {
|
|
|
28
28
|
let MEMORY: string;
|
|
29
29
|
let CHAT_MEMORY: string;
|
|
30
30
|
let REVIEW_MEMORY: string;
|
|
31
|
+
let KV_MEMORY: string;
|
|
31
32
|
let RUNNER: string;
|
|
32
33
|
let SKILL_INSTALLER: string;
|
|
33
34
|
let CORE_TOOLS: string;
|
|
@@ -37,6 +38,8 @@ export namespace SKILLS {
|
|
|
37
38
|
let ANTHROPIC_BILLING: string;
|
|
38
39
|
let CURSOR_ADMIN: string;
|
|
39
40
|
let NOTION: string;
|
|
41
|
+
let LINEAR: string;
|
|
42
|
+
let PLANE: string;
|
|
40
43
|
}
|
|
41
44
|
/** CI env vars checked when generating session IDs. */
|
|
42
45
|
export const CI_ENV_VARS: string[];
|
package/dist/constants.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var o=".zibby/output",t="sessions",I=".session-info.json",_=".zibby-stop",s="result.json",r="raw_stream_output.txt",
|
|
1
|
+
var o=".zibby/output",t="sessions",I=".session-info.json",_=".zibby-stop",s="result.json",r="raw_stream_output.txt",E="events.json",e={BROWSER:"browser",JIRA:"jira",GITHUB:"github",GITLAB:"gitlab",FIGMA:"figma",GIT:"git",SLACK:"slack",LARK:"lark",CHAT_NOTIFY:"chat_notify",SENTRY:"sentry",MEMORY:"memory",CHAT_MEMORY:"chat-memory",REVIEW_MEMORY:"review-memory",KV_MEMORY:"kv-memory",RUNNER:"runner",SKILL_INSTALLER:"skill-installer",CORE_TOOLS:"core-tools",WORKFLOW_BUILDER:"workflow-builder",SESSION:"session",OPENAI_BILLING:"openai_billing",ANTHROPIC_BILLING:"anthropic_billing",CURSOR_ADMIN:"cursor_admin",NOTION:"notion",LINEAR:"linear",PLANE:"plane"},n=["CI_JOB_ID","GITHUB_RUN_ID","CIRCLE_WORKFLOW_ID","BUILD_ID"];export{n as CI_ENV_VARS,o as DEFAULT_OUTPUT_BASE,E as EVENTS_FILE,r as RAW_OUTPUT_FILE,s as RESULT_FILE,t as SESSIONS_DIR,I as SESSION_INFO_FILE,e as SKILLS,_ as STOP_REQUEST_FILE};
|
package/dist/graph-compiler.js
CHANGED
|
@@ -1,45 +1,45 @@
|
|
|
1
|
-
var
|
|
1
|
+
var Rt=Object.defineProperty;var we=(o=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(o,{get:(e,t)=>(typeof require<"u"?require:e)[t]}):o)(function(o){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+o+'" is not supported')});var ae=(o,e)=>()=>(o&&(e=o(o=0)),e);var Ge=(o,e)=>{for(var t in e)Rt(o,t,{get:e[t],enumerable:!0})};var He,Mt,le,y,F=ae(()=>{He=()=>{},Mt={debug:He,info:He,warn:(...o)=>console.warn("[workflow]",...o),error:(...o)=>console.error("[workflow]",...o)},le={impl:Mt},y={debug:(...o)=>le.impl.debug?.(...o),info:(...o)=>le.impl.info?.(...o),warn:(...o)=>le.impl.warn?.(...o),error:(...o)=>le.impl.error?.(...o)}});var tt=ae(()=>{});var ot={};Ge(ot,{clearSkills:()=>Gt,getAllSkills:()=>Ft,getSkill:()=>Q,hasSkill:()=>Ut,listSkillIds:()=>Wt,registerSkill:()=>jt});function jt(o){if(!o||typeof o.id!="string")throw new Error("Skill definition must include a string id");q.set(o.id,Object.freeze({...o}))}function Q(o){return q.get(o)||null}function Ut(o){return q.has(o)}function Ft(){return new Map(q)}function Wt(){return Array.from(q.keys())}function Gt(){q.clear()}var $e,q,pe=ae(()=>{$e=Symbol.for("@zibby/agent-workflow.skills");globalThis[$e]||(globalThis[$e]=new Map);q=globalThis[$e]});var ee={};Ge(ee,{getAgentStrategy:()=>rt,invokeAgent:()=>Yt,listStrategies:()=>Jt,registerStrategy:()=>Ht});function Ht(o){if(!o||typeof o.getName!="function"||typeof o.invoke!="function")throw new Error("strategy must implement getName() and invoke() (AgentStrategy shape)");let e=W.findIndex(t=>t.getName()===o.getName());e>=0?W[e]=o:W.push(o)}function Jt(){return W.map(o=>o.getName())}function rt(o={}){let{state:e={},preferredAgent:t=null}=o,r=t||e.agentType||process.env.AGENT_TYPE;if(!r){let n=W.map(a=>a.getName()).join(", ")||"none registered";throw new Error(`No agent specified. Set agentType in state or AGENT_TYPE env var. Available: ${n}`)}y.debug(`[workflow] agent selection: requested=${r}`);let s=W.find(n=>n.getName()===r);if(!s){let n=W.map(a=>a.getName()).join(", ")||"none registered";throw new Error(`Unknown agent '${r}'. Available: ${n}`)}if(!s.canHandle(o))throw new Error(`Agent '${r}' is not available in this environment. Check credentials/environment.`);return y.debug(`[workflow] using agent: ${s.getName()}`),s}async function Yt(o,e={},t={}){let r=rt(e),s=e.state?.config||t.config||{},n=s.models||{},a=t.nodeName&&n[t.nodeName]||null,i=n.default||null,c=s.agent?.[r.name]?.model||null,l=a||i||c||t.model||null,p={...t,model:l,workspace:e.state?.workspace||t.workspace,schema:t.schema||e.schema,images:t.images||e.images||[],skills:t.skills||e.skills||[],config:s},u=o,d=p.skills||[];if(d.length>0&&!t.skipPromptFragments){let w=d.map(I=>{let $=Q(I)?.promptFragment;return typeof $=="function"?$():$}).filter(Boolean);w.length>0&&(u+=`
|
|
2
2
|
|
|
3
3
|
${w.join(`
|
|
4
4
|
|
|
5
|
-
`)}`)}let
|
|
5
|
+
`)}`)}let f=e.state?._currentNodeConfig?.extraPromptInstructions?.trim();return f&&(u+=`
|
|
6
6
|
|
|
7
7
|
\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
|
|
8
8
|
PRIORITY OVERRIDE \u2014 THE FOLLOWING INSTRUCTIONS TAKE PRECEDENCE OVER ALL PREVIOUS CONTENT
|
|
9
9
|
\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
|
|
10
10
|
|
|
11
|
-
${
|
|
12
|
-
`),y.debug(`[workflow] prompt length: ${
|
|
11
|
+
${f}
|
|
12
|
+
`),y.debug(`[workflow] prompt length: ${u.length} chars`),r.invoke(u,p)}var Te,W,te=ae(()=>{tt();F();pe();Te=Symbol.for("@zibby/agent-workflow.strategies");globalThis[Te]||(globalThis[Te]=[]);W=globalThis[Te]});var Bt=new Set(["__proto__","constructor","prototype"]);function _e(o){if(Bt.has(o))throw new Error(`Invalid state key: "${o}"`)}var ce=class{constructor(e={}){this._state=Object.create(null),Object.assign(this._state,{messages:[],errors:[],artifacts:{},metadata:{},...e}),this._history=[]}get(e){return this._state[e]}set(e,t){_e(e),this._history.push({...this._state}),this._state[e]=t}update(e){let t=Object.getOwnPropertyNames(e);for(let r of t)_e(r);this._history.push({...this._state});for(let r of t)this._state[r]=e[r]}append(e,t){_e(e),this._history.push({...this._state}),Array.isArray(this._state[e])||(this._state[e]=[]),this._state[e].push(t)}getAll(){return{...this._state}}rollback(){this._history.length>0&&(this._state=this._history.pop())}};import G from"handlebars";var ue=class{constructor(e){this.schema=e}parse(e){let t=e.match(/```json\s*([\s\S]*?)\s*```/);if(t)return this.validate(JSON.parse(t[1]));let r=[e.match(/\{[\s\S]*?\}/),e.match(/\{[\s\S]*\}/)].filter(Boolean).map(s=>s[0]);for(let s of r)try{return this.validate(JSON.parse(s))}catch(n){if(!(n instanceof SyntaxError))throw n}return this.validate({result:e.trim()})}validate(e){let t=[];for(let[r,s]of Object.entries(this.schema)){if(s.required&&!(r in e)&&t.push(`Missing required field: ${r}`),r in e&&s.type){let n=typeof e[r];n!==s.type&&t.push(`Field '${r}' expected ${s.type}, got ${n}`)}if(s.validate&&r in e){let n=s.validate(e[r]);n&&t.push(`Field '${r}': ${n}`)}}if(t.length>0)throw new Error(`Output validation failed:
|
|
13
13
|
${t.join(`
|
|
14
|
-
`)}`);return e}};F();import{writeFileSync as ve,readFileSync as
|
|
15
|
-
`?(a+=
|
|
16
|
-
${
|
|
14
|
+
`)}`);return e}};F();import{writeFileSync as ve,readFileSync as nt,existsSync as st,mkdirSync as Zt}from"node:fs";import{join as Ae,dirname as zt}from"node:path";import A from"chalk";var Dt="__WORKFLOW_GRAPH_LOG__",X=A.gray("\u2502"),Lt=A.gray("\u250C"),Je=A.gray("\u2514"),Ie=A.green("\u25C6"),Ye=A.hex("#c084fc")("\u25C6"),Ze=A.hex("#2dd4bf")("\u25C6"),Ee=A.red("\u25C6"),ze=`${X} `,Ke=2;function qe(o){return o<1e3?`${o}ms`:`${(o/1e3).toFixed(1)}s`}function Ve(o,e){return(t,r,s)=>{if(typeof t!="string")return o(t,r,s);let n=process.stdout.columns||120,a="";for(let i=0;i<t.length;i++){let c=t[i];e.lineStart&&(a+=ze,e.col=Ke,e.lineStart=!1),c===`
|
|
15
|
+
`?(a+=c,e.lineStart=!0,e.col=0,e.inEsc=!1):c==="\x1B"?(e.inEsc=!0,a+=c):e.inEsc?(a+=c,(c>="A"&&c<="Z"||c>="a"&&c<="z")&&(e.inEsc=!1)):(e.col++,a+=c,e.col>=n&&(a+=`
|
|
16
|
+
${ze}`,e.col=Ke))}return o(a,r,s)}}var be=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 e={lineStart:!0,col:0,inEsc:!1},t={lineStart:!0,col:0,inEsc:!1};this._outState=e,this._errState=t,process.stdout.write=Ve(this._origStdoutWrite,e),process.stderr.write=Ve(this._origStderrWrite,t)}_stopIntercepting(){this._origStdoutWrite&&(this._outState&&!this._outState.lineStart&&this._origStdoutWrite(`
|
|
17
17
|
`),process.stdout.write=this._origStdoutWrite),this._origStderrWrite&&(this._errState&&!this._errState.lineStart&&this._origStderrWrite(`
|
|
18
18
|
`),process.stderr.write=this._origStderrWrite),this._origStdoutWrite=null,this._origStderrWrite=null}_rawWrite(e){(this._origStdoutWrite||process.stdout.write.bind(process.stdout))(`${e}
|
|
19
|
-
`)}_emitGraphLogMarker(e){if(!this._emitWorkflowGraphMarkers)return;let t=`${
|
|
19
|
+
`)}_emitGraphLogMarker(e){if(!this._emitWorkflowGraphMarkers)return;let t=`${Dt}${JSON.stringify(e)}
|
|
20
20
|
`;this._origStdoutWrite?this._origStdoutWrite(t):process.stdout.write(t)}_writeDot(e,t){this._origStdoutWrite?(this._outState&&!this._outState.lineStart&&(this._origStdoutWrite(`
|
|
21
21
|
`),this._outState.lineStart=!0,this._outState.col=0),this._origStdoutWrite(`${e} ${t}
|
|
22
22
|
`)):process.stdout.write.bind(process.stdout)(`${e} ${t}
|
|
23
|
-
`)}step(e){this._origStdoutWrite?this._writeDot(
|
|
24
|
-
`)}stepInfo(e){this.step(e)}stepTool(e){this._origStdoutWrite?this._writeDot(
|
|
25
|
-
`)}stepMemory(e){let t=
|
|
26
|
-
`)}stepFail(e){this._origStdoutWrite?this._writeDot(
|
|
27
|
-
`)}nodeStart(e){this._currentNode=e,this._emitGraphLogMarker({phase:"node_begin",node:e}),this._rawWrite(`${
|
|
23
|
+
`)}step(e){this._origStdoutWrite?this._writeDot(Ie,e):process.stdout.write.bind(process.stdout)(`${X} ${Ie} ${e}
|
|
24
|
+
`)}stepInfo(e){this.step(e)}stepTool(e){this._origStdoutWrite?this._writeDot(Ye,e):process.stdout.write.bind(process.stdout)(`${X} ${Ye} ${e}
|
|
25
|
+
`)}stepMemory(e){let t=A.hex("#2dd4bf")(e);this._origStdoutWrite?this._writeDot(Ze,t):process.stdout.write.bind(process.stdout)(`${X} ${Ze} ${t}
|
|
26
|
+
`)}stepFail(e){this._origStdoutWrite?this._writeDot(Ee,A.red(e)):process.stdout.write.bind(process.stdout)(`${X} ${Ee} ${A.red(e)}
|
|
27
|
+
`)}nodeStart(e){this._currentNode=e,this._emitGraphLogMarker({phase:"node_begin",node:e}),this._rawWrite(`${Lt} ${e}`),this._startIntercepting()}nodeComplete(e,t={}){this._stopIntercepting();let{duration:r,details:s}=t;if(s)for(let a of s)this._rawWrite(`${Ie} ${a}`);let n=r?A.dim(` ${qe(r)}`):"";this._rawWrite(`${Je} ${A.green("done")}${n}`),this._emitGraphLogMarker({phase:"node_end",node:e}),this._rawWrite("")}nodeFailed(e,t,r={}){this._stopIntercepting();let{duration:s}=r,n=s?A.dim(` ${qe(s)}`):"";this._rawWrite(`${Ee} ${A.red(t)}`),this._rawWrite(`${Je} ${A.red("failed")}${n}`),this._emitGraphLogMarker({phase:"node_end",node:e}),this._rawWrite("")}route(e,t){this._rawWrite(A.dim(` ${e} \u2192 ${t}`)),this._rawWrite("")}graphComplete(){}},x=new be;var de=".zibby/output",Xe="sessions",K=".session-info.json",Qe=".zibby-stop";var et=["CI_JOB_ID","GITHUB_RUN_ID","CIRCLE_WORKFLOW_ID","BUILD_ID"];G.helpers.inc||G.registerHelper("inc",o=>Number(o)+1);G.helpers.json||G.registerHelper("json",o=>JSON.stringify(o,null,2));G.helpers.eq||G.registerHelper("eq",(o,e)=>o===e);var j=class{constructor(e){if(this.config=e,this.name=e.name,this.prompt=e.prompt,this.outputSchema=e.outputSchema,!this.outputSchema&&!e._isCustomCode)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=e.outputSchema&&!this.isZodSchema?new ue(e.outputSchema):null,this.retries=e.retries||0,this.onComplete=e.onComplete,this.customExecute=e.execute}async execute(e,t){let r=()=>t&&typeof t.getAll=="function"?t.getAll():e,s=u=>t&&typeof t.get=="function"?t.get(u):e?.[u];if(typeof this.customExecute=="function"){y.debug(`[workflow] node '${this.name}': custom execute (skipping LLM)`);try{let u=await this.customExecute(e);return typeof u=="object"&&u!==null&&u.success===!1?{success:!1,error:u.error||"Node execution failed",raw:u.raw||null}:this.isZodSchema?(y.debug(`[workflow] node '${this.name}': validating output schema`),{success:!0,output:this.outputSchema.parse(u),raw:null}):{success:!0,output:u,raw:null}}catch(u){return y.error(`[workflow] node '${this.name}' failed: ${u.message}`),u.name==="ZodError"&&y.error(`Schema errors: ${JSON.stringify(u.issues||u.errors,null,2)}`),{success:!1,error:u.message,raw:null}}}let n;typeof this.prompt=="function"?n=this.prompt(r()):typeof this.prompt=="string"&&this.prompt.includes("{{")?(this._compiledPrompt||(this._compiledPrompt=G.compile(this.prompt,{noEscape:!0})),n=this._compiledPrompt(r())):n=this.prompt;let a=s("_skillHints");a&&(n=`${a}
|
|
28
28
|
|
|
29
|
-
${n}`);let i=r(),u=i.cwd||process.cwd(),c=i.sessionPath;try{if(c){let p=Te(c,z);if(nt(p)){let h=JSON.parse(rt(p,"utf-8"));h.currentNode=this.name,ve(p,JSON.stringify(h,null,2),"utf-8")}let l=Te(c,"..",z);if(nt(l))try{let h=JSON.parse(rt(l,"utf-8"));h.currentNode=this.name,ve(l,JSON.stringify(h,null,2),"utf-8")}catch{}}}catch(p){y.debug(`[workflow] could not update session info: ${p.message}`)}let d=null;for(let p=0;p<=this.retries;p++)try{y.debug(`[workflow] node '${this.name}' attempt ${p}`);let l=r().config||{},h=l.agents||{},w=this.config.agent??h[this.name]??null,_={state:r()};w&&(_.preferredAgent=w);let b={workspace:u,schema:this.isZodSchema?this.outputSchema:null,skills:this.config.skills||[],sessionPath:c,config:l,nodeName:this.name,timeout:this.config?.timeout||3e5},$=e?._coreInvokeAgent;$||($=(await Promise.resolve().then(()=>(ee(),Q))).invokeAgent);let f=await $(n,_,b),I,g;if(typeof f=="string"?(I=f,g=null):f.structured?(I=f.raw||JSON.stringify(f.structured,null,2),g=f.structured):(I=f.raw||JSON.stringify(f,null,2),g=f.extracted||null),c)try{let m=Te(c,this.name,"raw_stream_output.txt");Yt(Zt(m),{recursive:!0}),ve(m,typeof I=="string"?I:JSON.stringify(I),"utf-8")}catch(m){y.debug(`[workflow] could not save raw output: ${m.message}`)}if(this.isZodSchema&&g){y.info(`[workflow] node '${this.name}': output validated: ${JSON.stringify(g,null,2)}`);let m=g;if(typeof this.onComplete=="function")try{m=await this.onComplete(r(),g)}catch(R){y.warn(`[workflow] onComplete hook failed: ${R.message}`)}return{success:!0,output:m,raw:I}}if(typeof this.onComplete=="function")try{return{success:!0,output:await this.onComplete(r(),{raw:I}),raw:I}}catch(m){throw new Error(`onComplete failed: ${m.message}`,{cause:m})}if(this.parser){let m=this.parser.parse(I);return y.info(`[workflow] node '${this.name}': parsed output: ${JSON.stringify(m,null,2)}`),A.step("Output parsed"),{success:!0,output:m,raw:I}}return{success:!0,output:I,raw:I}}catch(l){d=l,p<this.retries&&y.info(`[workflow] node '${this.name}' failed, retrying (${p+1}/${this.retries})\u2026`)}return{success:!1,error:d.message,raw:null}}},de=class extends j{constructor(e){super({...e,_isCustomCode:!0}),this.condition=e.condition}async execute(e,t){let r=t&&typeof t.getAll=="function"?t.getAll():e;return{success:!0,output:{nextNode:this.condition(r)},raw:null}}};F();F();import{mkdirSync as qt,existsSync as H,statSync as dt,readdirSync as pt,rmSync as Vt}from"node:fs";import{spawn as lt}from"node:child_process";import{join as U}from"node:path";import{pathToFileURL as Xt}from"node:url";import{AsyncLocalStorage as zt}from"node:async_hooks";var xe=new zt;function te(){let o=xe.getStore();return o||Object.freeze({executionId:process.env.EXECUTION_ID||null,parentExecutionId:process.env.PARENT_EXECUTION_ID||null,depth:0,conversationId:process.env.ZIBBY_CONVERSATION_ID||null,dispatchMode:process.env.DISPATCH_MODE||null})}function st(o,e){let t=xe.getStore()||te(),r=Object.freeze({executionId:o.executionId,parentExecutionId:o.parentExecutionId??t.executionId??null,depth:(t.depth||0)+(o.executionId!==t.executionId?1:0),conversationId:o.conversationId!==void 0?o.conversationId:t.conversationId??null,dispatchMode:o.dispatchMode??null});return xe.run(r,e)}var Ae=new Map,ke=new Map,it=new Map;function at(o,e,t={}){if(!o||typeof o!="string")throw new Error("subgraph-registry.register: name required");if(typeof e!="function")throw new Error("subgraph-registry.register: factory must be a function");Ae.set(o,e),ke.set(o,"ready"),it.set(o,{...t,cachedAt:Date.now()})}function ct(o,e){ke.set(o,"failed"),it.set(o,{error:e?.message||String(e),failedAt:Date.now()}),Ae.delete(o)}function ut(o){return ke.get(o)==="ready"?Ae.get(o):null}var pe=process.env.ZIBBY_SUBGRAPH_CACHE_DIR||"/tmp/zibby/subgraphs";function Qt(){return`node${(process.versions?.node||"").split(".")[0]||"unknown"}-${process.platform}-${process.arch}`}var k=class extends Error{constructor(e,t){super(`in-process sub-graph fallback: ${e}${t?` (${t})`:""}`),this.fallback=!0,this.reason=e,this.detail=t||null,this.name="SubgraphFallback"}};function eo(){let o=(process.env.SUBGRAPH_INTERNAL_URL||"").replace(/\/$/,""),e=(process.env.PROGRESS_API_URL||"").replace(/\/executions\/?$/,""),t=o||e,r=process.env.PROJECT_ID,s=process.env.PROJECT_API_TOKEN;if(!t||!r||!s)throw new k("env","SUBGRAPH_INTERNAL_URL/PROGRESS_API_URL/PROJECT_ID/PROJECT_API_TOKEN missing");return{apiBase:t,projectId:r,authToken:s}}async function to({apiBase:o,authToken:e,body:t}){let r;try{r=await fetch(`${o}/internal/subgraph/begin`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:JSON.stringify(t)})}catch(n){throw new k("network",`begin fetch failed: ${n.message}`)}let s=null;try{s=await r.json()}catch{}if(!r.ok){if(r.status===404){let n=new Error(`Sub-graph child '${t.childWorkflowType}' not found in project`);throw n.code="SUBGRAPH_NOT_FOUND",n.status=404,n}if(r.status===429){let n=s?.quotaInfo||{},a=new Error(`Sub-graph blocked by quota (${n.used??"?"}/${n.limit??"?"} on ${n.planId||"plan"})`);throw a.code="SUBGRAPH_QUOTA_EXCEEDED",a.status=429,a.quotaInfo=n,a}if(r.status===400&&s?.validationErrors){let n=new Error(`Sub-graph rejected input: ${s?.error||s?.message||"validation failed"}`);throw n.code="SUBGRAPH_INVALID_INPUT",n.status=400,n.validationErrors=s.validationErrors,n.missing=s.missing,n}throw new k("begin-status",`begin returned ${r.status}`)}return s?.data||s}async function G({apiBase:o,authToken:e,payload:t}){try{let r=await fetch(`${o}/internal/subgraph/finalize`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:JSON.stringify(t)});r.ok||y.warn(`[in-process subgraph] finalize returned ${r.status} for ${t.childExecutionId}`)}catch(r){y.warn(`[in-process subgraph] finalize failed: ${r.message}`)}}async function oo(o,e){let t=U(e,".ready"),r=U(e,"graph.mjs");if(H(t)&&H(r))return;qt(e,{recursive:!0});let s=U(e,".lock"),n=!1;try{let{openSync:a,closeSync:i}=await import("node:fs"),u=a(s,"wx");i(u),n=!0}catch(a){if(a.code!=="EEXIST")throw a}if(!n){let a=Date.now()+3e4;for(;Date.now()<a;){if(H(t)&&H(r))return;await new Promise(i=>setTimeout(i,100))}throw new k("bundle-extract-timeout","sibling extract did not complete within 30s")}try{await new Promise((u,c)=>{let d=lt("curl",["-fsSL",o],{stdio:["ignore","pipe","inherit"]}),p=lt("tar",["-xzf","-","-C",e],{stdio:["pipe","inherit","inherit"]});d.stdout.pipe(p.stdin);let l,h,w=()=>{if(l!==void 0&&h!==void 0){if(l!==0)return c(new Error(`curl exited ${l}`));if(h!==0)return c(new Error(`tar exited ${h}`));u()}};d.on("close",_=>{l=_,w()}),p.on("close",_=>{h=_,w()}),d.on("error",c),p.on("error",c)});let{writeFileSync:a,unlinkSync:i}=await import("node:fs");a(t,"");try{i(s)}catch{}}catch(a){try{let{unlinkSync:i}=await import("node:fs");i(s)}catch{}throw new k("bundle-extract-failed",a.message)}}async function ro(o){let e=U(o,"graph.mjs");if(!H(e))throw new k("entry-missing",`graph.mjs missing under ${o}`);let t;try{t=await import(Xt(e).href)}catch(s){throw new k("import-failed",`${s?.code||s?.name||"unknown"}: ${s.message}`)}let r=t.default||Object.values(t).find(s=>typeof s=="function"&&s.prototype?.buildGraph);if(!r)throw new k("entry-class-missing","no buildGraph() class export found");return r}async function ft(o,e={}){if(!o||typeof o!="string")throw new Error("runInProcessSubgraph: workflowName (string) is required");let t=te(),r;try{r=eo()}catch(g){throw g}y.debug(`[in-process subgraph] begin '${o}' parent=${t.executionId||"<root>"}`);let s=await to({apiBase:r.apiBase,authToken:r.authToken,body:{parentExecutionId:t.executionId,childWorkflowType:o,input:e.input||{},...e.conversationId?{conversationId:e.conversationId}:{}}}),{childExecutionId:n,runtimeTag:a,bundlePresignedUrl:i,sourcesPresignedUrl:u,workflowVersion:c,workflowUuid:d,bundleReady:p}=s,l=Qt();if(a&&a!==l)throw await G({apiBase:r.apiBase,authToken:r.authToken,payload:{childExecutionId:n,status:"canceled",error:{message:`runtimeTag mismatch: parent=${l} child=${a}`,code:"RUNTIME_MISMATCH"}}}),new k("runtime-mismatch",`${l} vs ${a}`);if(!p||!i)throw await G({apiBase:r.apiBase,authToken:r.authToken,payload:{childExecutionId:n,status:"canceled",error:{message:"bundle not ready for in-process; falling back to HTTP",code:"NO_BUNDLE"}}}),new k("no-bundle","workflow bundle not built yet");let h=ut(o);if(!h){let g=U(pe,`${d}@${c||"0"}`);try{await oo(i,g);try{so()}catch{}}catch(m){throw m.fallback&&await G({apiBase:r.apiBase,authToken:r.authToken,payload:{childExecutionId:n,status:"failed",error:{message:m.message,code:m.reason}}}),m}try{h=await ro(g),at(o,h,{workflowUuid:d,version:c,runtimeTag:a,cacheDir:g})}catch(m){throw ct(o,m),await G({apiBase:r.apiBase,authToken:r.authToken,payload:{childExecutionId:n,status:"failed",error:{message:m.message,code:m.reason||"IMPORT_FAILED"}}}),m.fallback?m:new k("import-failed",m.message)}}let w=Date.now(),b=await(typeof h=="function"&&h.prototype?.buildGraph?new h:h).buildGraph(),$={...e.input||{}},f,I;try{f=await st({executionId:n,parentExecutionId:t.executionId,conversationId:e.conversationId!==void 0?e.conversationId:t.conversationId,dispatchMode:"inprocess"},()=>b.run(e.parentAgent,$,{signal:e.signal})),I=f&&typeof f=="object"&&"state"in f?f.state:f}catch(g){throw await G({apiBase:r.apiBase,authToken:r.authToken,payload:{childExecutionId:n,status:"failed",error:{message:g.message,code:g.code||"CHILD_THREW",stack:g.stack},durationMs:Date.now()-w}}),g}if(f&&typeof f=="object"&&f.stoppedExternally){await G({apiBase:r.apiBase,authToken:r.authToken,payload:{childExecutionId:n,status:"canceled",finalState:I,durationMs:Date.now()-w}});let g=new Error(`Sub-graph '${o}' canceled by parent abort`);throw g.code="SUBGRAPH_CANCELED",g.subgraphJobId=n,g}return await G({apiBase:r.apiBase,authToken:r.authToken,payload:{childExecutionId:n,status:"completed",finalState:I,durationMs:Date.now()-w}}),{finalState:I,executionId:n}}function no(o){let e=0,t=[o];for(;t.length;){let r=t.pop(),s;try{s=dt(r)}catch{continue}if(s.isDirectory()){let n;try{n=pt(r)}catch{continue}for(let a of n)t.push(U(r,a))}else e+=s.size}return e}function so({cap:o=Number(process.env.ZIBBY_SUBGRAPH_CACHE_CAP_BYTES||2*1024*1024*1024)}={}){try{if(!H(pe))return{evicted:0,freedBytes:0};let e=pt(pe),t=[],r=0;for(let i of e){let u=U(pe,i),c;try{c=dt(u)}catch{continue}let d=c.isDirectory()?no(u):c.size;r+=d,t.push({name:i,full:u,size:d,mtimeMs:c.mtimeMs})}if(r<=o)return{evicted:0,freedBytes:0,totalBytes:r};t.sort((i,u)=>i.mtimeMs-u.mtimeMs);let s=Math.floor(o*.7),n=0,a=0;for(let i of t){if(r-n<=s)break;if(!H(U(i.full,".lock")))try{Vt(i.full,{recursive:!0,force:!0}),n+=i.size,a+=1}catch(u){y.debug(`[sub-graph cache] evict skip ${i.name}: ${u.message}`)}}return a>0&&y.info(`[sub-graph cache] evicted ${a} entr(y/ies), freed ${(n/1024/1024).toFixed(1)}MB`),{evicted:a,freedBytes:n,totalBytes:r-n}}catch(e){return y.debug(`[sub-graph cache] evict failed: ${e.message}`),{evicted:0,freedBytes:0}}}var io=2e3,ao=600*1e3,co=new Set(["completed","failed","canceled","timeout"]);function uo(){let o=process.env.PROGRESS_API_URL;if(!o)throw new Error("Sub-graph dispatch requires PROGRESS_API_URL env var (set automatically on cloud runs). Sub-graphs are not supported in local in-process runs yet \u2014 deploy the parent and child to cloud.");return o.replace(/\/executions\/?$/,"")}function lo(){let o=process.env.PROJECT_ID;if(!o)throw new Error("Sub-graph dispatch requires PROJECT_ID env var.");return o}function po(){let o=process.env.PROJECT_API_TOKEN;if(!o)throw new Error("Sub-graph dispatch requires PROJECT_API_TOKEN env var.");return o}function fo(){return process.env.EXECUTION_ID||null}function ht(o,e){return e==null?o:typeof e=="function"?e(o):typeof e=="string"?e.split(".").reduce((t,r)=>t==null?t:t[r],o):o}async function gt(o,e={}){if(!o||typeof o!="string")throw new Error("dispatchSubgraph: workflowName (string) is required");let t=te(),r=Number(process.env.ZIBBY_SUBGRAPH_MAX_DEPTH||10);if((t.depth||0)>=r)throw new Error(`dispatchSubgraph('${o}'): sub-graph depth ${t.depth} reached cap of ${r}. Restructure the graph or raise ZIBBY_SUBGRAPH_MAX_DEPTH.`);if(process.env.ZIBBY_INPROCESS_SUBGRAPH!=="0"&&!e.async)try{y.debug(`[sub-graph] trying in-process for '${o}'`);let{finalState:g}=await ft(o,{input:e.input,conversationId:e.conversationId,signal:e.signal,parentAgent:e.parentAgent}),m=ht(g,e.output);return y.info(`[sub-graph] '${o}' completed in-process`),m}catch(g){if(g instanceof k||g?.fallback)y.info(`[sub-graph] in-process fallback for '${o}': ${g.reason||"unknown"} \u2014 using HTTP`);else throw g}let s=uo(),n=lo(),a=po(),i=fo(),u=`${s}/projects/${encodeURIComponent(n)}/workflows/${encodeURIComponent(o)}/trigger`,c={input:e.input||{},...i?{parentExecutionId:i}:{},...e.conversationId?{conversationId:e.conversationId}:{}};y.info(`[sub-graph] dispatching '${o}' (${e.async?"async":"sync"}) from parent ${i||"<none>"}`);let d=await fetch(u,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${a}`},body:JSON.stringify(c)});if(!d.ok){let g=null,m="";try{g=await d.json(),m=g?.error||g?.message||JSON.stringify(g)}catch{m=await d.text().catch(()=>"")}if(d.status===429){let T=g?.quotaInfo||{},M=new Error(`Sub-graph '${o}' blocked by execution quota (${T.used??"?"}/${T.limit??"?"} on plan ${T.planId||"unknown"}). Sub-workflow runs count toward the same monthly cap as user-triggered runs.`);throw M.code="SUBGRAPH_QUOTA_EXCEEDED",M.status=429,M.subgraph=o,M.quotaInfo=T,M}if(d.status===400){let T=new Error(`Sub-graph '${o}' rejected input: ${m}`);throw T.code="SUBGRAPH_INVALID_INPUT",T.status=400,T.subgraph=o,T.validationErrors=g?.validationErrors||null,T.missing=g?.missing||null,T}let R=new Error(`Sub-graph '${o}' trigger rejected (${d.status}): ${m}`);throw R.code="SUBGRAPH_TRIGGER_FAILED",R.status=d.status,R.subgraph=o,R}let p=await d.json(),l=p?.data?.jobId||p?.jobId;if(!l)throw new Error(`Sub-graph '${o}' trigger returned no jobId: ${JSON.stringify(p).slice(0,200)}`);if(e.async)return y.info(`[sub-graph] async dispatch of '${o}' \u2192 jobId=${l} (not waiting)`),{jobId:l,status:"accepted",workflow:o};let h=Number.isFinite(e.timeoutMs)?e.timeoutMs:ao,w=Number.isFinite(e.pollIntervalMs)?e.pollIntervalMs:io,_=`${s}/executions/${encodeURIComponent(l)}`,b=Date.now()+h,$="accepted",f=0;for(;Date.now()<b;){await new Promise(T=>setTimeout(T,w)),f+=1;let g=await fetch(_,{headers:{Authorization:`Bearer ${a}`}});if(!g.ok){if(g.status>=500){y.warn(`[sub-graph] status poll for ${l} returned ${g.status}, will retry`);continue}throw new Error(`Sub-graph status poll failed for ${l}: ${g.status}`)}let m=await g.json(),R=m?.data||m?.execution||m;if($=R?.status||$,co.has($)){if($!=="completed"){let S=new Error(`Sub-graph '${o}' (${l}) ended in status '${$}'`);throw S.subgraphJobId=l,S.subgraphStatus=$,S}let T=R?.finalState||R?.state||{},M=ht(T,e.output);return y.info(`[sub-graph] '${o}' (${l}) completed after ${f} polls`),M}}let I=new Error(`Sub-graph '${o}' (${l}) timed out after ${Math.round(h/1e3)}s (last status: ${$})`);throw I.subgraphJobId=l,I.subgraphStatus=$,I}import{existsSync as mt,readFileSync as ho}from"node:fs";import{join as Oe,dirname as St}from"node:path";var fe=class{static async loadContext(e,t,r={}){let s={},n=r.filenames||["CONTEXT.md","AGENTS.md"];if(e){let i=St(Oe(t,e));for(let u of n){let c=await this.findAndMergeContextFiles(u,i,t);if(c){let d=u.replace(/\.[^.]+$/,"").toLowerCase();s[d]=c}}}let a=r.discovery||{};for(let[i,u]of Object.entries(a))try{let c=Oe(t,u);mt(c)&&(s[i]=await this.loadFile(c))}catch(c){console.warn(`[workflow] could not load context '${i}' from '${u}': ${c.message}`)}return s}static async findAndMergeContextFiles(e,t,r){let s=[],n=t;for(;n.startsWith(r);){let a=Oe(n,e);if(mt(a))try{s.unshift(await this.loadFile(a))}catch(u){console.warn(`[workflow] could not load ${e} from ${a}: ${u.message}`)}let i=St(n);if(i===n)break;n=i}return s.length===0?null:s.every(a=>typeof a=="string")?s.join(`
|
|
29
|
+
${n}`);let i=r(),c=i.cwd||process.cwd(),l=i.sessionPath;try{if(l){let u=Ae(l,K);if(st(u)){let f=JSON.parse(nt(u,"utf-8"));f.currentNode=this.name,ve(u,JSON.stringify(f,null,2),"utf-8")}let d=Ae(l,"..",K);if(st(d))try{let f=JSON.parse(nt(d,"utf-8"));f.currentNode=this.name,ve(d,JSON.stringify(f,null,2),"utf-8")}catch{}}}catch(u){y.debug(`[workflow] could not update session info: ${u.message}`)}let p=null;for(let u=0;u<=this.retries;u++)try{y.debug(`[workflow] node '${this.name}' attempt ${u}`);let d=r().config||{},f=d.agents||{},w=this.config.agent??f[this.name]??null,I={state:r()};w&&(I.preferredAgent=w);let $={workspace:c,schema:this.isZodSchema?this.outputSchema:null,skills:this.config.skills||[],sessionPath:l,config:d,nodeName:this.name,timeout:this.config?.timeout||3e5},_=e?._coreInvokeAgent;_||(_=(await Promise.resolve().then(()=>(te(),ee))).invokeAgent);let h=await _(n,I,$),E,g;if(typeof h=="string"?(E=h,g=null):h.structured?(E=h.raw||JSON.stringify(h.structured,null,2),g=h.structured):(E=h.raw||JSON.stringify(h,null,2),g=h.extracted||null),l)try{let m=Ae(l,this.name,"raw_stream_output.txt");Zt(zt(m),{recursive:!0}),ve(m,typeof E=="string"?E:JSON.stringify(E),"utf-8")}catch(m){y.debug(`[workflow] could not save raw output: ${m.message}`)}if(this.isZodSchema&&g){y.info(`[workflow] node '${this.name}': output validated: ${JSON.stringify(g,null,2)}`);let m=g;if(typeof this.onComplete=="function")try{m=await this.onComplete(r(),g)}catch(R){y.warn(`[workflow] onComplete hook failed: ${R.message}`)}return{success:!0,output:m,raw:E}}if(typeof this.onComplete=="function")try{return{success:!0,output:await this.onComplete(r(),{raw:E}),raw:E}}catch(m){throw new Error(`onComplete failed: ${m.message}`,{cause:m})}if(this.parser){let m=this.parser.parse(E);return y.info(`[workflow] node '${this.name}': parsed output: ${JSON.stringify(m,null,2)}`),x.step("Output parsed"),{success:!0,output:m,raw:E}}return{success:!0,output:E,raw:E}}catch(d){p=d,u<this.retries&&y.info(`[workflow] node '${this.name}' failed, retrying (${u+1}/${this.retries})\u2026`)}return{success:!1,error:p.message,raw:null}}},oe=class extends j{constructor(e){super({...e,_isCustomCode:!0}),this.condition=e.condition}async execute(e,t){let r=t&&typeof t.getAll=="function"?t.getAll():e;return{success:!0,output:{nextNode:this.condition(r)},raw:null}}};F();F();import{mkdirSync as Vt,existsSync as J,statSync as pt,readdirSync as ft,rmSync as Xt}from"node:fs";import{spawn as dt}from"node:child_process";import{join as U}from"node:path";import{pathToFileURL as Qt}from"node:url";import{AsyncLocalStorage as Kt}from"node:async_hooks";var xe=new Kt;function re(){let o=xe.getStore();return o||Object.freeze({executionId:process.env.EXECUTION_ID||null,parentExecutionId:process.env.PARENT_EXECUTION_ID||null,depth:0,conversationId:process.env.ZIBBY_CONVERSATION_ID||null,dispatchMode:process.env.DISPATCH_MODE||null})}function it(o,e){let t=xe.getStore()||re(),r=Object.freeze({executionId:o.executionId,parentExecutionId:o.parentExecutionId??t.executionId??null,depth:(t.depth||0)+(o.executionId!==t.executionId?1:0),conversationId:o.conversationId!==void 0?o.conversationId:t.conversationId??null,dispatchMode:o.dispatchMode??null});return xe.run(r,e)}var ke=new Map,Oe=new Map,at=new Map;function ct(o,e,t={}){if(!o||typeof o!="string")throw new Error("subgraph-registry.register: name required");if(typeof e!="function")throw new Error("subgraph-registry.register: factory must be a function");ke.set(o,e),Oe.set(o,"ready"),at.set(o,{...t,cachedAt:Date.now()})}function ut(o,e){Oe.set(o,"failed"),at.set(o,{error:e?.message||String(e),failedAt:Date.now()}),ke.delete(o)}function lt(o){return Oe.get(o)==="ready"?ke.get(o):null}var fe=process.env.ZIBBY_SUBGRAPH_CACHE_DIR||"/tmp/zibby/subgraphs";function eo(){return`node${(process.versions?.node||"").split(".")[0]||"unknown"}-${process.platform}-${process.arch}`}var k=class extends Error{constructor(e,t){super(`in-process sub-graph fallback: ${e}${t?` (${t})`:""}`),this.fallback=!0,this.reason=e,this.detail=t||null,this.name="SubgraphFallback"}};function to(){let o=(process.env.SUBGRAPH_INTERNAL_URL||"").replace(/\/$/,""),e=(process.env.PROGRESS_API_URL||"").replace(/\/executions\/?$/,""),t=o||e,r=process.env.PROJECT_ID,s=process.env.PROJECT_API_TOKEN;if(!t||!r||!s)throw new k("env","SUBGRAPH_INTERNAL_URL/PROGRESS_API_URL/PROJECT_ID/PROJECT_API_TOKEN missing");return{apiBase:t,projectId:r,authToken:s}}async function oo({apiBase:o,authToken:e,body:t}){let r;try{r=await fetch(`${o}/internal/subgraph/begin`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:JSON.stringify(t)})}catch(n){throw new k("network",`begin fetch failed: ${n.message}`)}let s=null;try{s=await r.json()}catch{}if(!r.ok){if(r.status===404){let n=new Error(`Sub-graph child '${t.childWorkflowType}' not found in project`);throw n.code="SUBGRAPH_NOT_FOUND",n.status=404,n}if(r.status===429){let n=s?.quotaInfo||{},a=new Error(`Sub-graph blocked by quota (${n.used??"?"}/${n.limit??"?"} on ${n.planId||"plan"})`);throw a.code="SUBGRAPH_QUOTA_EXCEEDED",a.status=429,a.quotaInfo=n,a}if(r.status===400&&s?.validationErrors){let n=new Error(`Sub-graph rejected input: ${s?.error||s?.message||"validation failed"}`);throw n.code="SUBGRAPH_INVALID_INPUT",n.status=400,n.validationErrors=s.validationErrors,n.missing=s.missing,n}throw new k("begin-status",`begin returned ${r.status}`)}return s?.data||s}async function H({apiBase:o,authToken:e,payload:t}){try{let r=await fetch(`${o}/internal/subgraph/finalize`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:JSON.stringify(t)});r.ok||y.warn(`[in-process subgraph] finalize returned ${r.status} for ${t.childExecutionId}`)}catch(r){y.warn(`[in-process subgraph] finalize failed: ${r.message}`)}}async function ro(o,e){let t=U(e,".ready"),r=U(e,"graph.mjs");if(J(t)&&J(r))return;Vt(e,{recursive:!0});let s=U(e,".lock"),n=!1;try{let{openSync:a,closeSync:i}=await import("node:fs"),c=a(s,"wx");i(c),n=!0}catch(a){if(a.code!=="EEXIST")throw a}if(!n){let a=Date.now()+3e4;for(;Date.now()<a;){if(J(t)&&J(r))return;await new Promise(i=>setTimeout(i,100))}throw new k("bundle-extract-timeout","sibling extract did not complete within 30s")}try{await new Promise((c,l)=>{let p=dt("curl",["-fsSL",o],{stdio:["ignore","pipe","inherit"]}),u=dt("tar",["-xzf","-","-C",e],{stdio:["pipe","inherit","inherit"]});p.stdout.pipe(u.stdin);let d,f,w=()=>{if(d!==void 0&&f!==void 0){if(d!==0)return l(new Error(`curl exited ${d}`));if(f!==0)return l(new Error(`tar exited ${f}`));c()}};p.on("close",I=>{d=I,w()}),u.on("close",I=>{f=I,w()}),p.on("error",l),u.on("error",l)});let{writeFileSync:a,unlinkSync:i}=await import("node:fs");a(t,"");try{i(s)}catch{}}catch(a){try{let{unlinkSync:i}=await import("node:fs");i(s)}catch{}throw new k("bundle-extract-failed",a.message)}}async function no(o){let e=U(o,"graph.mjs");if(!J(e))throw new k("entry-missing",`graph.mjs missing under ${o}`);let t;try{t=await import(Qt(e).href)}catch(s){throw new k("import-failed",`${s?.code||s?.name||"unknown"}: ${s.message}`)}let r=t.default||Object.values(t).find(s=>typeof s=="function"&&s.prototype?.buildGraph);if(!r)throw new k("entry-class-missing","no buildGraph() class export found");return r}async function ht(o,e={}){if(!o||typeof o!="string")throw new Error("runInProcessSubgraph: workflowName (string) is required");let t=re(),r;try{r=to()}catch(g){throw g}y.debug(`[in-process subgraph] begin '${o}' parent=${t.executionId||"<root>"}`);let s=await oo({apiBase:r.apiBase,authToken:r.authToken,body:{parentExecutionId:t.executionId,childWorkflowType:o,input:e.input||{},...e.conversationId?{conversationId:e.conversationId}:{}}}),{childExecutionId:n,runtimeTag:a,bundlePresignedUrl:i,sourcesPresignedUrl:c,workflowVersion:l,workflowUuid:p,bundleReady:u}=s,d=eo();if(a&&a!==d)throw await H({apiBase:r.apiBase,authToken:r.authToken,payload:{childExecutionId:n,status:"canceled",error:{message:`runtimeTag mismatch: parent=${d} child=${a}`,code:"RUNTIME_MISMATCH"}}}),new k("runtime-mismatch",`${d} vs ${a}`);if(!u||!i)throw await H({apiBase:r.apiBase,authToken:r.authToken,payload:{childExecutionId:n,status:"canceled",error:{message:"bundle not ready for in-process; falling back to HTTP",code:"NO_BUNDLE"}}}),new k("no-bundle","workflow bundle not built yet");let f=lt(o);if(!f){let g=U(fe,`${p}@${l||"0"}`);try{await ro(i,g);try{io()}catch{}}catch(m){throw m.fallback&&await H({apiBase:r.apiBase,authToken:r.authToken,payload:{childExecutionId:n,status:"failed",error:{message:m.message,code:m.reason}}}),m}try{f=await no(g),ct(o,f,{workflowUuid:p,version:l,runtimeTag:a,cacheDir:g})}catch(m){throw ut(o,m),await H({apiBase:r.apiBase,authToken:r.authToken,payload:{childExecutionId:n,status:"failed",error:{message:m.message,code:m.reason||"IMPORT_FAILED"}}}),m.fallback?m:new k("import-failed",m.message)}}let w=Date.now(),$=await(typeof f=="function"&&f.prototype?.buildGraph?new f:f).buildGraph(),_={...e.input||{}},h,E;try{h=await it({executionId:n,parentExecutionId:t.executionId,conversationId:e.conversationId!==void 0?e.conversationId:t.conversationId,dispatchMode:"inprocess"},()=>$.run(e.parentAgent,_,{signal:e.signal})),E=h&&typeof h=="object"&&"state"in h?h.state:h}catch(g){throw await H({apiBase:r.apiBase,authToken:r.authToken,payload:{childExecutionId:n,status:"failed",error:{message:g.message,code:g.code||"CHILD_THREW",stack:g.stack},durationMs:Date.now()-w}}),g}if(h&&typeof h=="object"&&h.stoppedExternally){await H({apiBase:r.apiBase,authToken:r.authToken,payload:{childExecutionId:n,status:"canceled",finalState:E,durationMs:Date.now()-w}});let g=new Error(`Sub-graph '${o}' canceled by parent abort`);throw g.code="SUBGRAPH_CANCELED",g.subgraphJobId=n,g}return await H({apiBase:r.apiBase,authToken:r.authToken,payload:{childExecutionId:n,status:"completed",finalState:E,durationMs:Date.now()-w}}),{finalState:E,executionId:n}}function so(o){let e=0,t=[o];for(;t.length;){let r=t.pop(),s;try{s=pt(r)}catch{continue}if(s.isDirectory()){let n;try{n=ft(r)}catch{continue}for(let a of n)t.push(U(r,a))}else e+=s.size}return e}function io({cap:o=Number(process.env.ZIBBY_SUBGRAPH_CACHE_CAP_BYTES||2*1024*1024*1024)}={}){try{if(!J(fe))return{evicted:0,freedBytes:0};let e=ft(fe),t=[],r=0;for(let i of e){let c=U(fe,i),l;try{l=pt(c)}catch{continue}let p=l.isDirectory()?so(c):l.size;r+=p,t.push({name:i,full:c,size:p,mtimeMs:l.mtimeMs})}if(r<=o)return{evicted:0,freedBytes:0,totalBytes:r};t.sort((i,c)=>i.mtimeMs-c.mtimeMs);let s=Math.floor(o*.7),n=0,a=0;for(let i of t){if(r-n<=s)break;if(!J(U(i.full,".lock")))try{Xt(i.full,{recursive:!0,force:!0}),n+=i.size,a+=1}catch(c){y.debug(`[sub-graph cache] evict skip ${i.name}: ${c.message}`)}}return a>0&&y.info(`[sub-graph cache] evicted ${a} entr(y/ies), freed ${(n/1024/1024).toFixed(1)}MB`),{evicted:a,freedBytes:n,totalBytes:r-n}}catch(e){return y.debug(`[sub-graph cache] evict failed: ${e.message}`),{evicted:0,freedBytes:0}}}var ao=2e3,co=600*1e3,uo=new Set(["completed","failed","canceled","timeout"]);function lo(){let o=process.env.PROGRESS_API_URL;if(!o)throw new Error("Sub-graph dispatch requires PROGRESS_API_URL env var (set automatically on cloud runs). Sub-graphs are not supported in local in-process runs yet \u2014 deploy the parent and child to cloud.");return o.replace(/\/executions\/?$/,"")}function po(){let o=process.env.PROJECT_ID;if(!o)throw new Error("Sub-graph dispatch requires PROJECT_ID env var.");return o}function fo(){let o=process.env.PROJECT_API_TOKEN;if(!o)throw new Error("Sub-graph dispatch requires PROJECT_API_TOKEN env var.");return o}function ho(){return process.env.EXECUTION_ID||null}function gt(o,e){return e==null?o:typeof e=="function"?e(o):typeof e=="string"?e.split(".").reduce((t,r)=>t==null?t:t[r],o):o}async function mt(o,e={}){if(!o||typeof o!="string")throw new Error("dispatchSubgraph: workflowName (string) is required");let t=re(),r=Number(process.env.ZIBBY_SUBGRAPH_MAX_DEPTH||10);if((t.depth||0)>=r)throw new Error(`dispatchSubgraph('${o}'): sub-graph depth ${t.depth} reached cap of ${r}. Restructure the graph or raise ZIBBY_SUBGRAPH_MAX_DEPTH.`);if(process.env.ZIBBY_INPROCESS_SUBGRAPH!=="0"&&!e.async)try{y.debug(`[sub-graph] trying in-process for '${o}'`);let{finalState:g}=await ht(o,{input:e.input,conversationId:e.conversationId,signal:e.signal,parentAgent:e.parentAgent}),m=gt(g,e.output);return y.info(`[sub-graph] '${o}' completed in-process`),m}catch(g){if(g instanceof k||g?.fallback)y.info(`[sub-graph] in-process fallback for '${o}': ${g.reason||"unknown"} \u2014 using HTTP`);else throw g}let s=lo(),n=po(),a=fo(),i=ho(),c=`${s}/projects/${encodeURIComponent(n)}/workflows/${encodeURIComponent(o)}/trigger`,l={input:e.input||{},...i?{parentExecutionId:i}:{},...e.conversationId?{conversationId:e.conversationId}:{}};y.info(`[sub-graph] dispatching '${o}' (${e.async?"async":"sync"}) from parent ${i||"<none>"}`);let p=await fetch(c,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${a}`},body:JSON.stringify(l)});if(!p.ok){let g=null,m="";try{g=await p.json(),m=g?.error||g?.message||JSON.stringify(g)}catch{m=await p.text().catch(()=>"")}if(p.status===429){let v=g?.quotaInfo||{},M=new Error(`Sub-graph '${o}' blocked by execution quota (${v.used??"?"}/${v.limit??"?"} on plan ${v.planId||"unknown"}). Sub-workflow runs count toward the same monthly cap as user-triggered runs.`);throw M.code="SUBGRAPH_QUOTA_EXCEEDED",M.status=429,M.subgraph=o,M.quotaInfo=v,M}if(p.status===400){let v=new Error(`Sub-graph '${o}' rejected input: ${m}`);throw v.code="SUBGRAPH_INVALID_INPUT",v.status=400,v.subgraph=o,v.validationErrors=g?.validationErrors||null,v.missing=g?.missing||null,v}let R=new Error(`Sub-graph '${o}' trigger rejected (${p.status}): ${m}`);throw R.code="SUBGRAPH_TRIGGER_FAILED",R.status=p.status,R.subgraph=o,R}let u=await p.json(),d=u?.data?.jobId||u?.jobId;if(!d)throw new Error(`Sub-graph '${o}' trigger returned no jobId: ${JSON.stringify(u).slice(0,200)}`);if(e.async)return y.info(`[sub-graph] async dispatch of '${o}' \u2192 jobId=${d} (not waiting)`),{jobId:d,status:"accepted",workflow:o};let f=Number.isFinite(e.timeoutMs)?e.timeoutMs:co,w=Number.isFinite(e.pollIntervalMs)?e.pollIntervalMs:ao,I=`${s}/executions/${encodeURIComponent(d)}`,$=Date.now()+f,_="accepted",h=0;for(;Date.now()<$;){await new Promise(v=>setTimeout(v,w)),h+=1;let g=await fetch(I,{headers:{Authorization:`Bearer ${a}`}});if(!g.ok){if(g.status>=500){y.warn(`[sub-graph] status poll for ${d} returned ${g.status}, will retry`);continue}throw new Error(`Sub-graph status poll failed for ${d}: ${g.status}`)}let m=await g.json(),R=m?.data||m?.execution||m;if(_=R?.status||_,uo.has(_)){if(_!=="completed"){let S=new Error(`Sub-graph '${o}' (${d}) ended in status '${_}'`);throw S.subgraphJobId=d,S.subgraphStatus=_,S}let v=R?.finalState||R?.state||{},M=gt(v,e.output);return y.info(`[sub-graph] '${o}' (${d}) completed after ${h} polls`),M}}let E=new Error(`Sub-graph '${o}' (${d}) timed out after ${Math.round(f/1e3)}s (last status: ${_})`);throw E.subgraphJobId=d,E.subgraphStatus=_,E}import{existsSync as St,readFileSync as go}from"node:fs";import{join as Ne,dirname as yt}from"node:path";var he=class{static async loadContext(e,t,r={}){let s={},n=r.filenames||["CONTEXT.md","AGENTS.md"];if(e){let i=yt(Ne(t,e));for(let c of n){let l=await this.findAndMergeContextFiles(c,i,t);if(l){let p=c.replace(/\.[^.]+$/,"").toLowerCase();s[p]=l}}}let a=r.discovery||{};for(let[i,c]of Object.entries(a))try{let l=Ne(t,c);St(l)&&(s[i]=await this.loadFile(l))}catch(l){console.warn(`[workflow] could not load context '${i}' from '${c}': ${l.message}`)}return s}static async findAndMergeContextFiles(e,t,r){let s=[],n=t;for(;n.startsWith(r);){let a=Ne(n,e);if(St(a))try{s.unshift(await this.loadFile(a))}catch(c){console.warn(`[workflow] could not load ${e} from ${a}: ${c.message}`)}let i=yt(n);if(i===n)break;n=i}return s.length===0?null:s.every(a=>typeof a=="string")?s.join(`
|
|
30
30
|
|
|
31
31
|
---
|
|
32
32
|
|
|
33
|
-
`):s.every(a=>typeof a=="object")?Object.assign({},...s):s[s.length-1]}static async loadFile(e){let t=
|
|
33
|
+
`):s.every(a=>typeof a=="object")?Object.assign({},...s):s[s.length-1]}static async loadFile(e){let t=go(e,"utf-8");if(e.endsWith(".json"))return JSON.parse(t);if(e.endsWith(".js")||e.endsWith(".mjs")){let{pathToFileURL:r}=await import("url"),s=await import(r(e).href);return s.default||s}return t}};import{mkdirSync as It,existsSync as Pe,writeFileSync as wt,unlinkSync as mo}from"node:fs";import{join as Y,resolve as Et}from"node:path";import{config as So}from"dotenv";import{zodToJsonSchema as _t}from"zod-to-json-schema";import{z as ge}from"zod";import yo from"handlebars";function wo({traceFrom:o,sessionId:e,sessionPath:t,idSource:r,mkdirFresh:s}){if(!(process.env.ZIBBY_SESSION_LOG==="1"||process.env.ZIBBY_SESSION_LOG==="true"))return;let a=typeof process.ppid=="number"?process.ppid:"n/a",i=`[zibby:session] from=${o} pid=${process.pid} ppid=${a} sessionId=${e} source=${r} mkdir=${s?"yes":"no"} path=${t}`;if(console.log(i),process.env.ZIBBY_TRACE_SESSION==="1"||process.env.ZIBBY_TRACE_SESSION==="true"){let p=(new Error("session trace").stack||"").split(`
|
|
34
34
|
`).slice(2,14).join(`
|
|
35
35
|
`);console.log(`[zibby:session] stack (${o}):
|
|
36
|
-
${d}`)}}function yo(){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 _o(){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 It(String(e).trim())}catch{return String(e).trim()}}function Io(){yo()||(delete process.env.ZIBBY_SESSION_PATH,delete process.env.ZIBBY_SESSION_ID)}function Eo({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 bo(o={}){let e=Qe.map(n=>process.env[n]).find(Boolean),t=Math.random().toString(36).slice(2,6),r=e||`${Date.now()}_${t}`,s=o.paths?.sessionPrefix;return s?`${s}_${r}`:r}function $o({cwd:o=process.cwd(),config:e={},initialState:t={},traceFrom:r="resolveWorkflowSession"}={}){let s=t.sessionPath,n=t.sessionTimestamp,a="initialState.sessionPath";if(!s&&process.env.ZIBBY_SESSION_PATH)try{let c=It(String(process.env.ZIBBY_SESSION_PATH));c&&(s=c,a="ZIBBY_SESSION_PATH")}catch{}let i;if(s)i=String(s).split(/[/\\]/).filter(Boolean).pop(),n==null&&(n=Date.now());else{let c=process.env.ZIBBY_SESSION_ID&&String(process.env.ZIBBY_SESSION_ID).trim();if(c)i=c,a="ZIBBY_SESSION_ID";else{let p=e.sessionId!=null?String(e.sessionId).trim():"";p&&p!=="last"?(i=p,a="config.sessionId"):(i=bo(e),a="generated")}n=n??Date.now();let d=e.paths?.output||ue;s=J(o,d,Ve,i)}let u=!Ne(s);return u&&_t(s,{recursive:!0}),(u||a!=="initialState.sessionPath")&&wo({traceFrom:r,sessionId:i,sessionPath:s,idSource:a,mkdirFresh:u}),Eo({sessionPath:s,sessionId:i}),{sessionPath:s,sessionId:i,sessionTimestamp:n}}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{return this.inputSchema.merge(this.contextSchema)}catch{}return this.inputSchema&&!this.contextSchema?this.inputSchema:this.stateSchema}addNode(e,t,r={}){if(!(t instanceof j)&&t&&typeof t=="object"&&typeof t.workflow=="string"){let n=t,a={name:e,_isCustomCode:!0,retries:n.retries,onComplete:n.onComplete,execute:async u=>{let c=u?.state&&typeof u.state.getAll=="function"?u.state.getAll():u,d;return typeof n.input=="function"?d=n.input(c):n.input&&typeof n.input=="object"?d=n.input:d={},gt(n.workflow,{input:d,async:n.async===!0,conversationId:typeof n.conversationId=="function"?n.conversationId(c):n.conversationId,output:n.output,timeoutMs:n.timeoutMs,pollIntervalMs:n.pollIntervalMs,signal:c?._signal,parentAgent:u?.agent})}},i=new j(a);return i.name=e,this.nodes.set(e,i),r.prompt&&this.nodePrompts.set(e,r.prompt),Object.keys(r).length>0&&this.nodeOptions.set(e,r),this}let s=t instanceof j?t:new j(t);return s.name=e,this.nodes.set(e,s),r.prompt&&this.nodePrompts.set(e,r.prompt),Object.keys(r).length>0&&this.nodeOptions.set(e,r),this}addConditionalNode(e,t){return this.nodes.set(e,new de({...t,name:e})),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,s,n){let a=r;for(let i=e.length-1;i>=0;i--){let u=e[i],c=a;a=()=>u(t,c,s,n)}return a()}serialize(){let e=[],t={};for(let[c,d]of this.nodes){let p=this.nodeTypeMap.get(c)||c;e.push({id:c,type:p,data:{nodeType:p,label:c}});let l={};d._isCustomCode&&typeof d.execute=="function"&&(l.customCode=d.execute.toString());let h=this.nodePrompts.get(c);if(h&&(l.prompt=h),typeof d.customExecute=="function"&&(l.executeCode=d.customExecute.toString()),d.outputSchema)if(typeof d.outputSchema._def<"u"){let b=null;if(typeof he?.toJSONSchema=="function")try{b=he.toJSONSchema(d.outputSchema)}catch{}if(!b)try{b=yt(d.outputSchema,{target:"openApi3"})}catch{}l.outputSchema=b?{jsonSchema:b,variables:this._flattenJsonSchemaToVariables(b)}:{schema:d.outputSchema}}else l.outputSchema={schema:d.outputSchema};let w=(this.resolvedToolsMap||{})[c];w?.toolIds&&(l.tools=w.toolIds);let _=Array.isArray(d?.config?.skills)?d.config.skills:Array.isArray(d?.skills)?d.skills:null;_&&_.length>0&&(l.skills=[..._]),Object.keys(l).length>0&&(t[c]=l)}let r=[];for(let[c,d]of this.edges)if(typeof d=="string")r.push({source:c,target:d});else if(d.conditional){let p=this.conditionalCodeMap.get(c)||d.routes.toString(),l=this._inferConditionalTargets(d.routes,d.labels),h=d.labels||{};for(let w of l){let _={source:c,target:w,data:{conditionalCode:p}};h[w]&&(_.label=h[w]),r.push(_)}}let s=c=>{if(!c)return null;if(typeof he?.toJSONSchema=="function")try{return he.toJSONSchema(c)}catch{}try{return yt(c,{target:"openApi3"})}catch{return null}},n=this._runtimeSchema(),a=s(n||this.stateSchema),i=s(this.inputSchema),u=s(this.contextSchema);return{nodes:e,edges:r,nodeConfigs:t,stateSchema:a,inputSchema:i,contextSchema:u}}_inferConditionalTargets(e,t){let r=e.toString(),s=new Set,n=/(['"])((?:\\.|(?!\1).)*?)\1|`((?:\\.|[^`$]|\$(?!\{))*?)`/g,a;for(;(a=n.exec(r))!==null;){let c=a[2]!==void 0?a[2]:a[3];c!==void 0&&c!==""&&s.add(c)}let i=new Set(["END","START","__end__","__start__"]);for(let c of this.nodes.keys())i.add(c);if(t&&typeof t=="object")for(let c of Object.keys(t))i.add(c);let u=new Set;for(let c of s)i.has(c)&&u.add(c);if(u.size===0){let c=/return\s+['"]([^'"]+)['"]/g,d;for(;(d=c.exec(r))!==null;)u.add(d[1])}return[...u]}_flattenJsonSchemaToVariables(e,t=""){let r=e;if(e.$ref&&e.definitions){let s=e.$ref.replace("#/definitions/","");r=e.definitions[s]||e}return this._flattenSchema(r,t)}_flattenSchema(e,t=""){if(!e||typeof e!="object")return[];let r=[],s=e.properties||{},n=e.required||[];for(let[a,i]of Object.entries(s)){let u=t?`${t}.${a}`:a;r.push({path:u,type:i.type||"unknown",label:i.description||this._formatLabel(a),optional:!n.includes(a)}),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[s,n]of Object.entries(t))if(!(s==="success"||s==="raw"||s==="nextNode")){if(typeof n=="string"&&n.length<=80)r.push(`${s}: ${n}`);else if(Array.isArray(n)){let a=n.length,i=n.filter(c=>c?.passed===!0).length,u=n.some(c=>c?.passed!==void 0);r.push(u?`${s}: ${i}/${a} passed${a-i?`, ${a-i} failed`:""}`:`${s}: ${a} 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 s=new AbortController;r.signal&&(r.signal.aborted?s.abort():r.signal.addEventListener("abort",()=>s.abort(),{once:!0}));let n=r.strategyAbortTimeoutMs??t.config?.strategyAbortTimeoutMs??5e3,a=t.cwd||process.cwd();mo({path:J(a,".env")});let i=t.config||{};if(!i||Object.keys(i).length===0)try{let E=J(a,".zibby.config.js");Ne(E)&&(i=(await import(E)).default||{})}catch{}process.env.EXECUTION_ID&&!i.agent?.strictMode&&(i.agent={...i.agent,strictMode:!0});let u=t.agentType;if(!u){let E=i?.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 c=t.contextConfig||e?.config?.contextConfig||e?.config?.context||i?.context||{},d=this._runtimeSchema();if(d){let E=d.safeParse(t);if(!E.success){let O=E.error.issues.map(N=>`${N.path.join(".")}: ${N.message}`);throw console.error("\u274C Initial state validation failed:"),O.forEach(N=>console.error(` - ${N}`)),new Error(`State validation failed: ${O.join(", ")}`)}A.step("State validated against schema")}let p=_o(),l=t.sessionPath||p;l||Io();let{sessionPath:h,sessionTimestamp:w,sessionId:_}=$o({cwd:a,config:i,traceFrom:"WorkflowGraph.run",initialState:{sessionPath:l,sessionTimestamp:t.sessionTimestamp}});A.step(`Session ${_}`);let b=await fe.loadContext(t.specPath||"",a,c);Object.keys(b).length>0&&A.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 f=new ie({...t,config:i,agentType:u,outputPath:$,sessionPath:h,sessionTimestamp:w,context:b,resolvedTools:this.resolvedToolsMap||{},_signal:s.signal}),I=new Map;try{await import("@zibby/skills")}catch{}let{getSkill:g}=await Promise.resolve().then(()=>(le(),tt)),m=i.skills&&typeof i.skills=="object"?i.skills:{},R=Object.values(m).filter(E=>E&&typeof E=="object"&&typeof E.id=="string"),T=E=>{for(let O of R)if(O.id===E)return O;return g(E)},M=new Set;for(let[,E]of this.nodes)for(let O of E.config?.skills||[])M.add(O);for(let E of M){let O=T(E);if(typeof O?.middleware=="function")try{let N=await O.middleware();typeof N=="function"&&I.set(E,N)}catch{}}let S=this.entryPoint,oe=[],Be=i?.recursionLimit??100,Tt=0;try{for(;S&&S!=="END";){if(++Tt>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 O=J(h,Xe);if(Ne(O)){try{go(O)}catch{}s.abort()}if(s.signal.aborted)return console.warn(`
|
|
37
|
-
\u{1F6D1} External stop requested \u2014 ending workflow.`),
|
|
38
|
-
${
|
|
36
|
+
${p}`)}}function _o(){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 Io(){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 Et(String(e).trim())}catch{return String(e).trim()}}function Eo(){_o()||(delete process.env.ZIBBY_SESSION_PATH,delete process.env.ZIBBY_SESSION_ID)}function bo({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 $o(o={}){let e=et.map(n=>process.env[n]).find(Boolean),t=Math.random().toString(36).slice(2,6),r=e||`${Date.now()}_${t}`,s=o.paths?.sessionPrefix;return s?`${s}_${r}`:r}function To({cwd:o=process.cwd(),config:e={},initialState:t={},traceFrom:r="resolveWorkflowSession"}={}){let s=t.sessionPath,n=t.sessionTimestamp,a="initialState.sessionPath";if(!s&&process.env.ZIBBY_SESSION_PATH)try{let l=Et(String(process.env.ZIBBY_SESSION_PATH));l&&(s=l,a="ZIBBY_SESSION_PATH")}catch{}let i;if(s)i=String(s).split(/[/\\]/).filter(Boolean).pop(),n==null&&(n=Date.now());else{let l=process.env.ZIBBY_SESSION_ID&&String(process.env.ZIBBY_SESSION_ID).trim();if(l)i=l,a="ZIBBY_SESSION_ID";else{let u=e.sessionId!=null?String(e.sessionId).trim():"";u&&u!=="last"?(i=u,a="config.sessionId"):(i=$o(e),a="generated")}n=n??Date.now();let p=e.paths?.output||de;s=Y(o,p,Xe,i)}let c=!Pe(s);return c&&It(s,{recursive:!0}),(c||a!=="initialState.sessionPath")&&wo({traceFrom:r,sessionId:i,sessionPath:s,idSource:a,mkdirFresh:c}),bo({sessionPath:s,sessionId:i}),{sessionPath:s,sessionId:i,sessionTimestamp:n}}var me=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{return this.inputSchema.merge(this.contextSchema)}catch{}return this.inputSchema&&!this.contextSchema?this.inputSchema:this.stateSchema}addNode(e,t,r={}){if(!(t instanceof j)&&t&&typeof t=="object"&&typeof t.workflow=="string"){let n=t,a={name:e,_isCustomCode:!0,retries:n.retries,onComplete:n.onComplete,execute:async c=>{let l=c?.state&&typeof c.state.getAll=="function"?c.state.getAll():c,p;return typeof n.input=="function"?p=n.input(l):n.input&&typeof n.input=="object"?p=n.input:p={},mt(n.workflow,{input:p,async:n.async===!0,conversationId:typeof n.conversationId=="function"?n.conversationId(l):n.conversationId,output:n.output,timeoutMs:n.timeoutMs,pollIntervalMs:n.pollIntervalMs,signal:l?._signal,parentAgent:c?.agent})}},i=new j(a);return i.name=e,this.nodes.set(e,i),r.prompt&&this.nodePrompts.set(e,r.prompt),Object.keys(r).length>0&&this.nodeOptions.set(e,r),this}let s=t instanceof j?t:new j(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}addConditionalNode(e,t){return this.nodes.set(e,new oe({...t,name:e})),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,s,n){let a=r;for(let i=e.length-1;i>=0;i--){let c=e[i],l=a;a=()=>c(t,l,s,n)}return a()}serialize(){let e=[],t={};for(let[p,u]of this.nodes){let d=this.nodeTypeMap.get(p)||(u instanceof oe?"decision":p);e.push({id:p,type:d,data:{nodeType:d,label:p}});let f={};u._isCustomCode&&typeof u.execute=="function"&&(f.customCode=u.execute.toString());let w=this.nodePrompts.get(p);if(w)f.prompt=w;else if(typeof u.prompt=="function")try{let _=u.prompt({});typeof _=="string"&&_.trim()&&(f.prompt=_,f.promptIsCode=!0)}catch{}if(typeof u.customExecute=="function"&&(f.executeCode=u.customExecute.toString()),u.outputSchema)if(typeof u.outputSchema._def<"u"){let _=null;if(typeof ge?.toJSONSchema=="function")try{_=ge.toJSONSchema(u.outputSchema)}catch{}if(!_)try{_=_t(u.outputSchema,{target:"openApi3"})}catch{}f.outputSchema=_?{jsonSchema:_,variables:this._flattenJsonSchemaToVariables(_)}:{schema:u.outputSchema}}else f.outputSchema={schema:u.outputSchema};let I=(this.resolvedToolsMap||{})[p];I?.toolIds&&(f.tools=I.toolIds);let $=Array.isArray(u?.config?.skills)?u.config.skills:Array.isArray(u?.skills)?u.skills:null;$&&$.length>0&&(f.skills=[...$]),Object.keys(f).length>0&&(t[p]=f)}let r=[];for(let[p,u]of this.edges)if(typeof u=="string")r.push({source:p,target:u});else if(u.conditional){let d=this.conditionalCodeMap.get(p)||u.routes.toString(),f=this._inferConditionalTargets(u.routes,u.labels),w=u.labels||{};for(let I of f){let $={source:p,target:I,data:{conditionalCode:d}};w[I]&&($.label=w[I]),r.push($)}}let s=p=>{if(!p)return null;if(typeof ge?.toJSONSchema=="function")try{return ge.toJSONSchema(p)}catch{}try{return _t(p,{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 n=0;for(let p of r)if(p.target==="END"){n+=1;let u=`END__${n}`;p.target=u,e.push({id:u,type:"end",data:{nodeType:"end",label:"End"}})}for(let p of this.nodes.keys())if(!this.edges.has(p)){n+=1;let u=`END__${n}`;e.push({id:u,type:"end",data:{nodeType:"end",label:"End"}}),r.push({source:p,target:u})}let a=this._runtimeSchema(),i=s(a||this.stateSchema),c=s(this.inputSchema),l=s(this.contextSchema);return{nodes:e,edges:r,nodeConfigs:t,stateSchema:i,inputSchema:c,contextSchema:l}}_inferConditionalTargets(e,t){let r=e.toString(),s=new Set,n=/(['"])((?:\\.|(?!\1).)*?)\1|`((?:\\.|[^`$]|\$(?!\{))*?)`/g,a;for(;(a=n.exec(r))!==null;){let l=a[2]!==void 0?a[2]:a[3];l!==void 0&&l!==""&&s.add(l)}let i=new Set(["END","START","__end__","__start__"]);for(let l of this.nodes.keys())i.add(l);if(t&&typeof t=="object")for(let l of Object.keys(t))i.add(l);let c=new Set;for(let l of s)i.has(l)&&c.add(l);if(c.size===0){let l=/return\s+['"]([^'"]+)['"]/g,p;for(;(p=l.exec(r))!==null;)c.add(p[1])}return[...c]}_flattenJsonSchemaToVariables(e,t=""){let r=e;if(e.$ref&&e.definitions){let s=e.$ref.replace("#/definitions/","");r=e.definitions[s]||e}return this._flattenSchema(r,t)}_flattenSchema(e,t=""){if(!e||typeof e!="object")return[];let r=[],s=e.properties||{},n=e.required||[];for(let[a,i]of Object.entries(s)){let c=t?`${t}.${a}`:a;r.push({path:c,type:i.type||"unknown",label:i.description||this._formatLabel(a),optional:!n.includes(a)}),i.type==="object"&&i.properties&&r.push(...this._flattenSchema(i,c)),i.type==="array"&&i.items?.type==="object"&&i.items.properties&&r.push(...this._flattenSchema(i.items,`${c}[]`))}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[s,n]of Object.entries(t))if(!(s==="success"||s==="raw"||s==="nextNode")){if(typeof n=="string"&&n.length<=80)r.push(`${s}: ${n}`);else if(Array.isArray(n)){let a=n.length,i=n.filter(l=>l?.passed===!0).length,c=n.some(l=>l?.passed!==void 0);r.push(c?`${s}: ${i}/${a} passed${a-i?`, ${a-i} failed`:""}`:`${s}: ${a} 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 s=new AbortController;r.signal&&(r.signal.aborted?s.abort():r.signal.addEventListener("abort",()=>s.abort(),{once:!0}));let n=r.strategyAbortTimeoutMs??t.config?.strategyAbortTimeoutMs??5e3,a=t.cwd||process.cwd();So({path:Y(a,".env")});let i=t.config||{};if(!i||Object.keys(i).length===0)try{let b=Y(a,".zibby.config.js");Pe(b)&&(i=(await import(b)).default||{})}catch{}process.env.EXECUTION_ID&&!i.agent?.strictMode&&(i.agent={...i.agent,strictMode:!0});let c=t.agentType;if(!c){let b=i?.agent;b?.provider?c=b.provider:b?.gemini?c="gemini":b?.claude?c="claude":b?.cursor?c="cursor":b?.codex?c="codex":c=process.env.AGENT_TYPE||"cursor"}let l=t.contextConfig||e?.config?.contextConfig||e?.config?.context||i?.context||{},p=this._runtimeSchema();if(p){let b=p.safeParse(t);if(!b.success){let O=b.error.issues.map(N=>`${N.path.join(".")}: ${N.message}`);throw console.error("\u274C Initial state validation failed:"),O.forEach(N=>console.error(` - ${N}`)),new Error(`State validation failed: ${O.join(", ")}`)}x.step("State validated against schema")}let u=Io(),d=t.sessionPath||u;d||Eo();let{sessionPath:f,sessionTimestamp:w,sessionId:I}=To({cwd:a,config:i,traceFrom:"WorkflowGraph.run",initialState:{sessionPath:d,sessionTimestamp:t.sessionTimestamp}});x.step(`Session ${I}`);let $=await he.loadContext(t.specPath||"",a,l);Object.keys($).length>0&&x.step(`Context loaded: ${Object.keys($).join(", ")}`);let _=t.outputPath;!_&&t.specPath&&(e?.calculateOutputPath?_=e.calculateOutputPath(t.specPath):console.warn(`\u26A0\uFE0F outputPath not resolved (specPath=${t.specPath})`));let h=new ce({...t,config:i,agentType:c,outputPath:_,sessionPath:f,sessionTimestamp:w,context:$,resolvedTools:this.resolvedToolsMap||{},_signal:s.signal}),E=new Map;try{await import("@zibby/skills")}catch{}let{getSkill:g}=await Promise.resolve().then(()=>(pe(),ot)),m=i.skills&&typeof i.skills=="object"?i.skills:{},R=Object.values(m).filter(b=>b&&typeof b=="object"&&typeof b.id=="string"),v=b=>{for(let O of R)if(O.id===b)return O;return g(b)},M=new Set;for(let[,b]of this.nodes)for(let O of b.config?.skills||[])M.add(O);for(let b of M){let O=v(b);if(typeof O?.middleware=="function")try{let N=await O.middleware();typeof N=="function"&&E.set(b,N)}catch{}}let S=this.entryPoint,ne=[],Me=i?.recursionLimit??100,At=0;try{for(;S&&S!=="END";){if(++At>Me)throw new Error(`Workflow exceeded recursion limit (${Me}) \u2014 likely a cyclic conditional route. Set config.recursionLimit if you need a higher cap.`);let O=Y(f,Qe);if(Pe(O)){try{mo(O)}catch{}s.abort()}if(s.signal.aborted)return console.warn(`
|
|
37
|
+
\u{1F6D1} External stop requested \u2014 ending workflow.`),x.step("Workflow stopped externally"),{success:!0,state:h.getAll(),executionLog:ne,stoppedExternally:!0};let N=this.nodes.get(S);if(!N)throw new Error(`Node '${S}' not found in graph`);let De=JSON.stringify({sessionPath:f,sessionTimestamp:w,currentNode:S,createdAt:new Date().toISOString(),config:h.get("config")}),xt=Y(f,K);wt(xt,De,"utf-8");let Le=h.get("config")?.paths?.output||de,kt=Y(a,Le,K);It(Y(a,Le),{recursive:!0});try{wt(kt,De,"utf-8")}catch{}let je=t.onPipelineProgress;if(typeof je=="function")try{je({cwd:a,sessionPath:f,sessionId:I,outputBase:h.get("config")?.paths?.output||de,currentNode:S})}catch{}let Ot=(this.resolvedToolsMap||{})[S]||null;h.set("_currentNodeTools",Ot);let Nt=h.get("nodeConfigs")||{};h.set("_currentNodeConfig",Nt[S]||{}),x.nodeStart(S);let Ue=Date.now(),se=this.nodePrompts.get(S);if(!this._invokeAgent){let P=await Promise.resolve().then(()=>(te(),ee));this._invokeAgent=P.invokeAgent}let Pt=this._invokeAgent,ye={},Ct=N.config?.skills||[];for(let P of Ct){let C=v(P);if(typeof C?.invokeAgentOptions=="function")try{let T=C.invokeAgentOptions(h.getAll(),{agentType:h.get("agentType"),nodeName:S});T&&typeof T=="object"&&(ye={...ye,...T})}catch(T){console.warn(`[graph] skill '${P}' invokeAgentOptions threw: ${T.message}`)}}let Fe=async(P,C,T={})=>{let B=Pt(P,C,{...ye,...T,signal:s.signal});return B.catch(()=>{}),s.signal.aborted?B:Promise.race([B,new Promise((Z,z)=>{let L=()=>{setTimeout(()=>{let V=new Error(`Strategy ignored AbortSignal \u2014 engine deadman fired after ${n}ms`);V.name="AbortError",z(V)},n)};s.signal.addEventListener("abort",L,{once:!0})})])},We={state:h,invokeAgent:async(P={},C={})=>{let T=C.prompt||"";if(se){let B=this._compiledPrompts.get(S);B||(B=yo.compile(se,{noEscape:!0}),this._compiledPrompts.set(S,B));try{T=B(P)}catch(Z){throw console.error(`\u274C Template rendering failed for node '${S}':`,Z.message),new Error(`Template rendering failed: ${Z.message}`,{cause:Z})}}else if(!T)throw new Error(`No prompt template configured for node '${S}' and no prompt provided in options`);return Fe(T,{state:h.getAll(),images:C.images||[]},{model:C.model||h.get("model"),workspace:h.get("workspace"),schema:C.schema,...C,signal:s.signal})},_coreInvokeAgent:Fe,agent:e,nodeId:S,promptTemplate:se,getPromptTemplate:()=>se,...h.getAll()};try{let P=(N.config?.skills||[]).map(L=>E.get(L)).filter(Boolean),C=[...this.middleware,...P],T;C.length>0?T=await this._composeMiddleware(C,S,async()=>N.execute(We,h),h.getAll(),h):T=await N.execute(We,h);let B=Date.now()-Ue;if(ne.push({node:S,success:T.success,duration:B,timestamp:new Date().toISOString()}),!T.success){if(s.signal.aborted)return x.step("Workflow stopped externally"),{success:!0,state:h.getAll(),executionLog:ne,stoppedExternally:!0};h.append("errors",{node:S,error:T.error});let L=N.config?.retries||0,V=`${S}_retries`,ie=h.getAll()[V]||0;if(ie<L){x.stepInfo(`Retrying (attempt ${ie+1}/${L})`),h.update({[V]:ie+1,[`${S}_raw`]:T.raw});continue}throw x.nodeFailed(S,T.error,{duration:B}),new Error(`Node '${S}' failed after ${ie} attempts: ${T.error}`)}h.update({[S]:T.output});let Z=this._summarizeNodeOutput(S,T.output);x.nodeComplete(S,{duration:B,details:Z});let z=this.edges.get(S);if(!z)S="END";else if(z.conditional){let L=z.routes(h.getAll());x.route(S,L),S=L}else S=z}catch(P){throw x.isInsideNode&&x.nodeFailed(S,P.message,{duration:Date.now()-Ue}),h.set("failed",!0),h.set("failedAt",S),P}}x.graphComplete();let b={success:!0,state:h.getAll(),executionLog:ne};return e&&typeof e.onComplete=="function"&&await e.onComplete(b),b}finally{if(e&&typeof e.cleanup=="function")try{await e.cleanup()}catch(b){console.warn(`[workflow] agent.cleanup() failed: ${b.message}`)}}}};var Ce=Symbol.for("@zibby/agent-workflow.nodes");globalThis[Ce]||(globalThis[Ce]=new Map);var Re=globalThis[Ce];function vo(o,e){Re.set(o,e)}function bt(o){return Re.get(o)}function Be(o){return Re.has(o)}vo("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 s=e.extraPromptInstructions||"Execute the task based on the current state.",n=Ao(s,t),a=await r(n,{cwd:t.workspace||process.cwd(),model:t.model,tools:e.resolvedTools||null});return{success:!0,output:{raw:a,nodeId:o},raw:typeof a=="string"?a:a.raw}}})});function Ao(o,e){let t=/@([\w.]+)/g,r=new Set,s;for(;(s=t.exec(o))!==null;)r.add(s[1]);if(r.size===0)return o;let n=[],a=new Set;for(let i of r){let c=i.split(".")[0];if(a.has(c))continue;let l=i.split(".").reduce((d,f)=>d?.[f],e);if(l===void 0)continue;let p=typeof l=="string"?l:l?.raw??JSON.stringify(l,null,2),u=i.replace(/_/g," ").replace(/\b\w/g,d=>d.toUpperCase());n.push(`## ${u}
|
|
38
|
+
${p}`),i.includes(".")||a.add(c)}return n.length===0?o:`${o}
|
|
39
39
|
|
|
40
40
|
---
|
|
41
41
|
# Referenced Context
|
|
42
42
|
|
|
43
43
|
${n.join(`
|
|
44
44
|
|
|
45
|
-
`)}`}
|
|
45
|
+
`)}`}pe();F();var xo={};function Tt(o,e){if(Array.isArray(e))return $t(e);let t=xo[o];return!t||t.length===0?null:$t(t)}function $t(o){if(!Array.isArray(o)||o.length===0)return null;let e=[],t={},r=[];for(let s of o){let n=Q(s);if(!n){y.warn(`[workflow] unknown skill "${s}" \u2014 skipping`);continue}r.push(s);for(let a of n.tools||[])e.push({name:a.name,description:a.description,input_schema:a.input_schema||{type:"object",properties:{}}});if(!t[n.serverName])if(typeof n.resolve=="function"){let a=n.resolve();a&&(t[n.serverName]={...a,toolPrefix:s})}else{let a={};for(let i of n.envKeys||[]){let c=process.env[i];c&&(a[i]=c)}t[n.serverName]={command:n.command,args:[...n.args||[]],env:a,toolPrefix:s}}}return r.length===0?null:{toolIds:r,claudeTools:e,mcpServers:t}}F();function Br(o,e={}){let{nodes:t,edges:r,nodeConfigs:s={}}=o;if(!Array.isArray(t)||t.length===0)throw new D("Graph must have at least one node");if(!Array.isArray(r))throw new D("Graph edges must be an array");let n=new me(e);e.stateSchema&&n.setStateSchema(e.stateSchema);let a=new Set,i=new Map,c={};for(let d of t){let f=Se(d);i.set(d.id,{...d,resolvedType:f}),f==="decision"&&a.add(d.id)}for(let[d,f]of i){if(a.has(d))continue;let w=f.resolvedType,I=s[d]||{},$=Tt(w,I.tools);$&&(c[d]=$);let _={};I.prompt&&(_.prompt=I.prompt);let h=Be(w);if(y.debug(`[workflow] compiler: node "${d}" type="${w}" registered=${h}`),I.customCode&&!h)n.addNode(d,vt(d,I.customCode,I),_),n.setNodeType(d,w);else if(h){let E=bt(w);E.factory?n.addNode(d,E.create(d,{...I,resolvedTools:$}),_):n.addNode(d,E,_),n.setNodeType(d,w)}else if(I.executeCode)n.addNode(d,vt(d,I.executeCode,I),_),n.setNodeType(d,w);else throw new D(`Unknown node type "${w}" for node "${d}". Did you forget to register it?`)}n.resolvedToolsMap=c;let l=new Set;for(let d of r)a.has(d.target)||l.add(d.target);let p=t.find(d=>!a.has(d.id)&&!l.has(d.id));if(!p)throw new D("Could not determine entry point: no node without incoming edges found");n.setEntryPoint(p.id);let u=ko(r,"source");for(let d of r)if(!a.has(d.source))if(a.has(d.target)){let f=d.target,w=u.get(f)||[];if(w.length===0)throw new D(`Decision node "${f}" has no outgoing edges`);let I=Oo(f,w,a);n.addConditionalEdges(d.source,I)}else n.addEdge(d.source,d.target);return n}function Mr(o){let e=[];if(!o||typeof o!="object")return{valid:!1,errors:["Config must be a non-null object"]};if((!Array.isArray(o.nodes)||o.nodes.length===0)&&e.push("Graph must have at least one node"),Array.isArray(o.edges)||e.push("Graph edges must be an array"),e.length>0)return{valid:!1,errors:e};let t=o.nodeConfigs||{};for(let i of o.nodes){let c=Se(i);if(c==="decision"||Be(c))continue;let l=t[i.id]||{};l.customCode||l.executeCode||e.push(`Unknown node type "${c}" for node "${i.id}". Register it or provide customCode/executeCode.`)}let r=new Set(o.nodes.map(i=>i.id));for(let i of o.edges)r.has(i.source)||e.push(`Edge references unknown source node "${i.source}"`),r.has(i.target)||e.push(`Edge references unknown target node "${i.target}"`);let s=new Set(o.nodes.filter(i=>Se(i)==="decision").map(i=>i.id)),n=new Set;for(let i of o.edges)s.has(i.target)||n.add(i.target);let a=o.nodes.filter(i=>!s.has(i.id)&&!n.has(i.id));a.length===0?e.push("No entry point found (every node has incoming edges)"):a.length>1&&e.push(`Multiple entry points found: ${a.map(i=>i.id).join(", ")}`);for(let i of s){let c=o.edges.filter(p=>p.source===i);c.length===0&&e.push(`Decision node "${i}" has no outgoing edges`),c.some(p=>p.data?.conditionalCode||p.conditionalCode)||e.push(`Decision node "${i}" outgoing edges have no conditionalCode`)}return{valid:e.length===0,errors:e}}function Dr(o){return!o||!Array.isArray(o.nodes)?[]:o.nodes.filter(e=>Se(e)!=="decision").map(e=>e.id)}function Se(o){let e=o.data?.nodeType||o.data?.type||o.type;return e==="workflowNode"||e==="custom"||e==="default"?o.id:e}function ko(o,e){let t=new Map;for(let r of o){let s=r[e];t.has(s)||t.set(s,[]),t.get(s).push(r)}return t}function Oo(o,e,t){let r=e.find(i=>i.data?.conditionalCode||i.conditionalCode);if(!r)throw new D(`Decision node "${o}" has no conditionalCode on its outgoing edges`);let s=r.data?.conditionalCode||r.conditionalCode,n=new Set(e.map(i=>i.target).filter(i=>!t.has(i))),a;try{let c=new Function(`return (${s})`)();a=l=>{let p=c(l);return n.has(p)||y.warn(`[workflow] conditional route from "${o}" returned "${p}" which is not in valid targets: ${[...n].join(", ")}`),p}}catch(i){throw new D(`Failed to compile conditionalCode for "${o}": ${i.message}`)}return a}function vt(o,e,t={}){let r;try{r=new Function("invokeAgent","require","console",`return (${e})`)}catch(a){throw new D(`Failed to compile customCode for node "${o}": ${a.message}`)}let s=r(async(...a)=>{let{invokeAgent:i}=await Promise.resolve().then(()=>(te(),ee));return i(...a)},typeof we<"u"?we:void 0,console),n=null;return t.outputSchema&&(n=t.outputSchema.jsonSchema||t.outputSchema),{name:o,_isCustomCode:!0,outputSchema:n,execute:async a=>{try{let i=await s(a);return typeof i=="object"&&"success"in i?i:{success:!0,output:i,raw:null}}catch(i){return{success:!1,error:i.message,raw:null}}}}}var D=class extends Error{constructor(e){super(e),this.name="CompilationError"}};export{D as CompilationError,Br as compileGraph,Dr as extractSteps,Mr as validateGraphConfig};
|
package/dist/graph.d.ts
CHANGED
package/dist/graph.js
CHANGED
|
@@ -1,37 +1,37 @@
|
|
|
1
|
-
var
|
|
1
|
+
var $e=Object.defineProperty;var st=(r,t)=>()=>(r&&(t=r(r=0)),t);var Mt=(r,t)=>{for(var e in t)$e(r,e,{get:t[e],enumerable:!0})};var Dt,ve,it,w,q=st(()=>{Dt=()=>{},ve={debug:Dt,info:Dt,warn:(...r)=>console.warn("[workflow]",...r),error:(...r)=>console.error("[workflow]",...r)},it={impl:ve},w={debug:(...r)=>it.impl.debug?.(...r),info:(...r)=>it.impl.info?.(...r),warn:(...r)=>it.impl.warn?.(...r),error:(...r)=>it.impl.error?.(...r)}});var zt=st(()=>{});var Kt={};Mt(Kt,{clearSkills:()=>Re,getAllSkills:()=>Pe,getSkill:()=>St,hasSkill:()=>xe,listSkillIds:()=>Ne,registerSkill:()=>Oe});function Oe(r){if(!r||typeof r.id!="string")throw new Error("Skill definition must include a string id");z.set(r.id,Object.freeze({...r}))}function St(r){return z.get(r)||null}function xe(r){return z.has(r)}function Pe(){return new Map(z)}function Ne(){return Array.from(z.keys())}function Re(){z.clear()}var mt,z,wt=st(()=>{mt=Symbol.for("@zibby/agent-workflow.skills");globalThis[mt]||(globalThis[mt]=new Map);z=globalThis[mt]});var _t={};Mt(_t,{getAgentStrategy:()=>qt,invokeAgent:()=>Me,listStrategies:()=>Ce,registerStrategy:()=>Be});function Be(r){if(!r||typeof r.getName!="function"||typeof r.invoke!="function")throw new Error("strategy must implement getName() and invoke() (AgentStrategy shape)");let t=U.findIndex(e=>e.getName()===r.getName());t>=0?U[t]=r:U.push(r)}function Ce(){return U.map(r=>r.getName())}function qt(r={}){let{state:t={},preferredAgent:e=null}=r,s=e||t.agentType||process.env.AGENT_TYPE;if(!s){let n=U.map(i=>i.getName()).join(", ")||"none registered";throw new Error(`No agent specified. Set agentType in state or AGENT_TYPE env var. Available: ${n}`)}w.debug(`[workflow] agent selection: requested=${s}`);let o=U.find(n=>n.getName()===s);if(!o){let n=U.map(i=>i.getName()).join(", ")||"none registered";throw new Error(`Unknown agent '${s}'. Available: ${n}`)}if(!o.canHandle(r))throw new Error(`Agent '${s}' is not available in this environment. Check credentials/environment.`);return w.debug(`[workflow] using agent: ${o.getName()}`),o}async function Me(r,t={},e={}){let s=qt(t),o=t.state?.config||e.config||{},n=o.models||{},i=e.nodeName&&n[e.nodeName]||null,a=n.default||null,l=o.agent?.[s.name]?.model||null,u=i||a||l||e.model||null,p={...e,model:u,workspace:t.state?.workspace||e.workspace,schema:e.schema||t.schema,images:e.images||t.images||[],skills:e.skills||t.skills||[],config:o},c=r,g=p.skills||[];if(g.length>0&&!e.skipPromptFragments){let E=g.map($=>{let T=St($)?.promptFragment;return typeof T=="function"?T():T}).filter(Boolean);E.length>0&&(c+=`
|
|
2
2
|
|
|
3
|
-
${
|
|
3
|
+
${E.join(`
|
|
4
4
|
|
|
5
|
-
`)}`)}let
|
|
5
|
+
`)}`)}let h=t.state?._currentNodeConfig?.extraPromptInstructions?.trim();return h&&(c+=`
|
|
6
6
|
|
|
7
7
|
\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
|
|
8
8
|
PRIORITY OVERRIDE \u2014 THE FOLLOWING INSTRUCTIONS TAKE PRECEDENCE OVER ALL PREVIOUS CONTENT
|
|
9
9
|
\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
|
|
10
10
|
|
|
11
|
-
${
|
|
12
|
-
`),w.debug(`[workflow] prompt length: ${
|
|
11
|
+
${h}
|
|
12
|
+
`),w.debug(`[workflow] prompt length: ${c.length} chars`),s.invoke(c,p)}var yt,U,It=st(()=>{zt();q();wt();yt=Symbol.for("@zibby/agent-workflow.strategies");globalThis[yt]||(globalThis[yt]=[]);U=globalThis[yt]});var Te=new Set(["__proto__","constructor","prototype"]);function dt(r){if(Te.has(r))throw new Error(`Invalid state key: "${r}"`)}var ot=class{constructor(t={}){this._state=Object.create(null),Object.assign(this._state,{messages:[],errors:[],artifacts:{},metadata:{},...t}),this._history=[]}get(t){return this._state[t]}set(t,e){dt(t),this._history.push({...this._state}),this._state[t]=e}update(t){let e=Object.getOwnPropertyNames(t);for(let s of e)dt(s);this._history.push({...this._state});for(let s of e)this._state[s]=t[s]}append(t,e){dt(t),this._history.push({...this._state}),Array.isArray(this._state[t])||(this._state[t]=[]),this._state[t].push(e)}getAll(){return{...this._state}}rollback(){this._history.length>0&&(this._state=this._history.pop())}};import W from"handlebars";var nt=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 s=[t.match(/\{[\s\S]*?\}/),t.match(/\{[\s\S]*\}/)].filter(Boolean).map(o=>o[0]);for(let o of s)try{return this.validate(JSON.parse(o))}catch(n){if(!(n instanceof SyntaxError))throw n}return this.validate({result:t.trim()})}validate(t){let e=[];for(let[s,o]of Object.entries(this.schema)){if(o.required&&!(s in t)&&e.push(`Missing required field: ${s}`),s in t&&o.type){let n=typeof t[s];n!==o.type&&e.push(`Field '${s}' expected ${o.type}, got ${n}`)}if(o.validate&&s in t){let n=o.validate(t[s]);n&&e.push(`Field '${s}': ${n}`)}}if(e.length>0)throw new Error(`Output validation failed:
|
|
13
13
|
${e.join(`
|
|
14
|
-
`)}`);return t}};
|
|
14
|
+
`)}`);return t}};q();import{writeFileSync as Et,readFileSync as Vt,existsSync as Xt,mkdirSync as De}from"node:fs";import{join as bt,dirname as Le}from"node:path";import A from"chalk";var Ae="__WORKFLOW_GRAPH_LOG__",V=A.gray("\u2502"),ke=A.gray("\u250C"),Lt=A.gray("\u2514"),ht=A.green("\u25C6"),jt=A.hex("#c084fc")("\u25C6"),Ut=A.hex("#2dd4bf")("\u25C6"),ft=A.red("\u25C6"),Wt=`${V} `,Ft=2;function Gt(r){return r<1e3?`${r}ms`:`${(r/1e3).toFixed(1)}s`}function Ht(r,t){return(e,s,o)=>{if(typeof e!="string")return r(e,s,o);let n=process.stdout.columns||120,i="";for(let a=0;a<e.length;a++){let l=e[a];t.lineStart&&(i+=Wt,t.col=Ft,t.lineStart=!1),l===`
|
|
15
15
|
`?(i+=l,t.lineStart=!0,t.col=0,t.inEsc=!1):l==="\x1B"?(t.inEsc=!0,i+=l):t.inEsc?(i+=l,(l>="A"&&l<="Z"||l>="a"&&l<="z")&&(t.inEsc=!1)):(t.col++,i+=l,t.col>=n&&(i+=`
|
|
16
|
-
${
|
|
16
|
+
${Wt}`,t.col=Ft))}return r(i,s,o)}}var gt=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=Ht(this._origStdoutWrite,t),process.stderr.write=Ht(this._origStderrWrite,e)}_stopIntercepting(){this._origStdoutWrite&&(this._outState&&!this._outState.lineStart&&this._origStdoutWrite(`
|
|
17
17
|
`),process.stdout.write=this._origStdoutWrite),this._origStderrWrite&&(this._errState&&!this._errState.lineStart&&this._origStderrWrite(`
|
|
18
18
|
`),process.stderr.write=this._origStderrWrite),this._origStdoutWrite=null,this._origStderrWrite=null}_rawWrite(t){(this._origStdoutWrite||process.stdout.write.bind(process.stdout))(`${t}
|
|
19
|
-
`)}_emitGraphLogMarker(t){if(!this._emitWorkflowGraphMarkers)return;let e=`${
|
|
19
|
+
`)}_emitGraphLogMarker(t){if(!this._emitWorkflowGraphMarkers)return;let e=`${Ae}${JSON.stringify(t)}
|
|
20
20
|
`;this._origStdoutWrite?this._origStdoutWrite(e):process.stdout.write(e)}_writeDot(t,e){this._origStdoutWrite?(this._outState&&!this._outState.lineStart&&(this._origStdoutWrite(`
|
|
21
21
|
`),this._outState.lineStart=!0,this._outState.col=0),this._origStdoutWrite(`${t} ${e}
|
|
22
22
|
`)):process.stdout.write.bind(process.stdout)(`${t} ${e}
|
|
23
|
-
`)}step(t){this._origStdoutWrite?this._writeDot(
|
|
24
|
-
`)}stepInfo(t){this.step(t)}stepTool(t){this._origStdoutWrite?this._writeDot(
|
|
25
|
-
`)}stepMemory(t){let e=A.hex("#2dd4bf")(t);this._origStdoutWrite?this._writeDot(
|
|
26
|
-
`)}stepFail(t){this._origStdoutWrite?this._writeDot(
|
|
27
|
-
`)}nodeStart(t){this._currentNode=t,this._emitGraphLogMarker({phase:"node_begin",node:t}),this._rawWrite(`${
|
|
23
|
+
`)}step(t){this._origStdoutWrite?this._writeDot(ht,t):process.stdout.write.bind(process.stdout)(`${V} ${ht} ${t}
|
|
24
|
+
`)}stepInfo(t){this.step(t)}stepTool(t){this._origStdoutWrite?this._writeDot(jt,t):process.stdout.write.bind(process.stdout)(`${V} ${jt} ${t}
|
|
25
|
+
`)}stepMemory(t){let e=A.hex("#2dd4bf")(t);this._origStdoutWrite?this._writeDot(Ut,e):process.stdout.write.bind(process.stdout)(`${V} ${Ut} ${e}
|
|
26
|
+
`)}stepFail(t){this._origStdoutWrite?this._writeDot(ft,A.red(t)):process.stdout.write.bind(process.stdout)(`${V} ${ft} ${A.red(t)}
|
|
27
|
+
`)}nodeStart(t){this._currentNode=t,this._emitGraphLogMarker({phase:"node_begin",node:t}),this._rawWrite(`${ke} ${t}`),this._startIntercepting()}nodeComplete(t,e={}){this._stopIntercepting();let{duration:s,details:o}=e;if(o)for(let i of o)this._rawWrite(`${ht} ${i}`);let n=s?A.dim(` ${Gt(s)}`):"";this._rawWrite(`${Lt} ${A.green("done")}${n}`),this._emitGraphLogMarker({phase:"node_end",node:t}),this._rawWrite("")}nodeFailed(t,e,s={}){this._stopIntercepting();let{duration:o}=s,n=o?A.dim(` ${Gt(o)}`):"";this._rawWrite(`${ft} ${A.red(e)}`),this._rawWrite(`${Lt} ${A.red("failed")}${n}`),this._emitGraphLogMarker({phase:"node_end",node:t}),this._rawWrite("")}route(t,e){this._rawWrite(A.dim(` ${t} \u2192 ${e}`)),this._rawWrite("")}graphComplete(){}},k=new gt;var at=".zibby/output",Jt="sessions",Z=".session-info.json",Yt=".zibby-stop";var Zt=["CI_JOB_ID","GITHUB_RUN_ID","CIRCLE_WORKFLOW_ID","BUILD_ID"];W.helpers.inc||W.registerHelper("inc",r=>Number(r)+1);W.helpers.json||W.registerHelper("json",r=>JSON.stringify(r,null,2));W.helpers.eq||W.registerHelper("eq",(r,t)=>r===t);var L=class{constructor(t){if(this.config=t,this.name=t.name,this.prompt=t.prompt,this.outputSchema=t.outputSchema,!this.outputSchema&&!t._isCustomCode)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 nt(t.outputSchema):null,this.retries=t.retries||0,this.onComplete=t.onComplete,this.customExecute=t.execute}async execute(t,e){let s=()=>e&&typeof e.getAll=="function"?e.getAll():t,o=c=>e&&typeof e.get=="function"?e.get(c):t?.[c];if(typeof this.customExecute=="function"){w.debug(`[workflow] node '${this.name}': custom execute (skipping LLM)`);try{let c=await this.customExecute(t);return typeof c=="object"&&c!==null&&c.success===!1?{success:!1,error:c.error||"Node execution failed",raw:c.raw||null}:this.isZodSchema?(w.debug(`[workflow] node '${this.name}': validating output schema`),{success:!0,output:this.outputSchema.parse(c),raw:null}):{success:!0,output:c,raw:null}}catch(c){return w.error(`[workflow] node '${this.name}' failed: ${c.message}`),c.name==="ZodError"&&w.error(`Schema errors: ${JSON.stringify(c.issues||c.errors,null,2)}`),{success:!1,error:c.message,raw:null}}}let n;typeof this.prompt=="function"?n=this.prompt(s()):typeof this.prompt=="string"&&this.prompt.includes("{{")?(this._compiledPrompt||(this._compiledPrompt=W.compile(this.prompt,{noEscape:!0})),n=this._compiledPrompt(s())):n=this.prompt;let i=o("_skillHints");i&&(n=`${i}
|
|
28
28
|
|
|
29
|
-
${n}`);let a=o(),l=a.cwd||process.cwd(),c=a.sessionPath;try{if(c){let p=Et(c,Y);if(qt(p)){let m=JSON.parse(Vt(p,"utf-8"));m.currentNode=this.name,It(p,JSON.stringify(m,null,2),"utf-8")}let h=Et(c,"..",Y);if(qt(h))try{let m=JSON.parse(Vt(h,"utf-8"));m.currentNode=this.name,It(h,JSON.stringify(m,null,2),"utf-8")}catch{}}}catch(p){w.debug(`[workflow] could not update session info: ${p.message}`)}let u=null;for(let p=0;p<=this.retries;p++)try{w.debug(`[workflow] node '${this.name}' attempt ${p}`);let h=o().config||{},m=h.agents||{},I=this.config.agent??m[this.name]??null,b={state:o()};I&&(b.preferredAgent=I);let $={workspace:l,schema:this.isZodSchema?this.outputSchema:null,skills:this.config.skills||[],sessionPath:c,config:h,nodeName:this.name,timeout:this.config?.timeout||3e5},T=t?._coreInvokeAgent;T||(T=(await Promise.resolve().then(()=>(yt(),_t))).invokeAgent);let d=await T(n,b,$),y,f;if(typeof d=="string"?(y=d,f=null):d.structured?(y=d.raw||JSON.stringify(d.structured,null,2),f=d.structured):(y=d.raw||JSON.stringify(d,null,2),f=d.extracted||null),c)try{let g=Et(c,this.name,"raw_stream_output.txt");Me(De(g),{recursive:!0}),It(g,typeof y=="string"?y:JSON.stringify(y),"utf-8")}catch(g){w.debug(`[workflow] could not save raw output: ${g.message}`)}if(this.isZodSchema&&f){w.info(`[workflow] node '${this.name}': output validated: ${JSON.stringify(f,null,2)}`);let g=f;if(typeof this.onComplete=="function")try{g=await this.onComplete(o(),f)}catch(B){w.warn(`[workflow] onComplete hook failed: ${B.message}`)}return{success:!0,output:g,raw:y}}if(typeof this.onComplete=="function")try{return{success:!0,output:await this.onComplete(o(),{raw:y}),raw:y}}catch(g){throw new Error(`onComplete failed: ${g.message}`,{cause:g})}if(this.parser){let g=this.parser.parse(y);return w.info(`[workflow] node '${this.name}': parsed output: ${JSON.stringify(g,null,2)}`),k.step("Output parsed"),{success:!0,output:g,raw:y}}return{success:!0,output:y,raw:y}}catch(h){u=h,p<this.retries&&w.info(`[workflow] node '${this.name}' failed, retrying (${p+1}/${this.retries})\u2026`)}return{success:!1,error:u.message,raw:null}}},it=class extends L{constructor(t){super({...t,_isCustomCode:!0}),this.condition=t.condition}async execute(t,e){let o=e&&typeof e.getAll=="function"?e.getAll():t;return{success:!0,output:{nextNode:this.condition(o)},raw:null}}};K();K();import{mkdirSync as Ue,existsSync as F,statSync as se,readdirSync as ne,rmSync as We}from"node:fs";import{spawn as oe}from"node:child_process";import{join as j}from"node:path";import{pathToFileURL as Fe}from"node:url";import{AsyncLocalStorage as Le}from"node:async_hooks";var bt=new Le;function q(){let r=bt.getStore();return r||Object.freeze({executionId:process.env.EXECUTION_ID||null,parentExecutionId:process.env.PARENT_EXECUTION_ID||null,depth:0,conversationId:process.env.ZIBBY_CONVERSATION_ID||null,dispatchMode:process.env.DISPATCH_MODE||null})}function Xt(r,t){let e=bt.getStore()||q(),o=Object.freeze({executionId:r.executionId,parentExecutionId:r.parentExecutionId??e.executionId??null,depth:(e.depth||0)+(r.executionId!==e.executionId?1:0),conversationId:r.conversationId!==void 0?r.conversationId:e.conversationId??null,dispatchMode:r.dispatchMode??null});return bt.run(o,t)}var $t=new Map,Tt=new Map,Qt=new Map;function te(r,t,e={}){if(!r||typeof r!="string")throw new Error("subgraph-registry.register: name required");if(typeof t!="function")throw new Error("subgraph-registry.register: factory must be a function");$t.set(r,t),Tt.set(r,"ready"),Qt.set(r,{...e,cachedAt:Date.now()})}function ee(r,t){Tt.set(r,"failed"),Qt.set(r,{error:t?.message||String(t),failedAt:Date.now()}),$t.delete(r)}function re(r){return Tt.get(r)==="ready"?$t.get(r):null}var at=process.env.ZIBBY_SUBGRAPH_CACHE_DIR||"/tmp/zibby/subgraphs";function Ge(){return`node${(process.versions?.node||"").split(".")[0]||"unknown"}-${process.platform}-${process.arch}`}var O=class extends Error{constructor(t,e){super(`in-process sub-graph fallback: ${t}${e?` (${e})`:""}`),this.fallback=!0,this.reason=t,this.detail=e||null,this.name="SubgraphFallback"}};function He(){let r=(process.env.SUBGRAPH_INTERNAL_URL||"").replace(/\/$/,""),t=(process.env.PROGRESS_API_URL||"").replace(/\/executions\/?$/,""),e=r||t,o=process.env.PROJECT_ID,s=process.env.PROJECT_API_TOKEN;if(!e||!o||!s)throw new O("env","SUBGRAPH_INTERNAL_URL/PROGRESS_API_URL/PROJECT_ID/PROJECT_API_TOKEN missing");return{apiBase:e,projectId:o,authToken:s}}async function Je({apiBase:r,authToken:t,body:e}){let o;try{o=await fetch(`${r}/internal/subgraph/begin`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${t}`},body:JSON.stringify(e)})}catch(n){throw new O("network",`begin fetch failed: ${n.message}`)}let s=null;try{s=await o.json()}catch{}if(!o.ok){if(o.status===404){let n=new Error(`Sub-graph child '${e.childWorkflowType}' not found in project`);throw n.code="SUBGRAPH_NOT_FOUND",n.status=404,n}if(o.status===429){let n=s?.quotaInfo||{},i=new Error(`Sub-graph blocked by quota (${n.used??"?"}/${n.limit??"?"} on ${n.planId||"plan"})`);throw i.code="SUBGRAPH_QUOTA_EXCEEDED",i.status=429,i.quotaInfo=n,i}if(o.status===400&&s?.validationErrors){let n=new Error(`Sub-graph rejected input: ${s?.error||s?.message||"validation failed"}`);throw n.code="SUBGRAPH_INVALID_INPUT",n.status=400,n.validationErrors=s.validationErrors,n.missing=s.missing,n}throw new O("begin-status",`begin returned ${o.status}`)}return s?.data||s}async function W({apiBase:r,authToken:t,payload:e}){try{let o=await fetch(`${r}/internal/subgraph/finalize`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${t}`},body:JSON.stringify(e)});o.ok||w.warn(`[in-process subgraph] finalize returned ${o.status} for ${e.childExecutionId}`)}catch(o){w.warn(`[in-process subgraph] finalize failed: ${o.message}`)}}async function Ye(r,t){let e=j(t,".ready"),o=j(t,"graph.mjs");if(F(e)&&F(o))return;Ue(t,{recursive:!0});let s=j(t,".lock"),n=!1;try{let{openSync:i,closeSync:a}=await import("node:fs"),l=i(s,"wx");a(l),n=!0}catch(i){if(i.code!=="EEXIST")throw i}if(!n){let i=Date.now()+3e4;for(;Date.now()<i;){if(F(e)&&F(o))return;await new Promise(a=>setTimeout(a,100))}throw new O("bundle-extract-timeout","sibling extract did not complete within 30s")}try{await new Promise((l,c)=>{let u=oe("curl",["-fsSL",r],{stdio:["ignore","pipe","inherit"]}),p=oe("tar",["-xzf","-","-C",t],{stdio:["pipe","inherit","inherit"]});u.stdout.pipe(p.stdin);let h,m,I=()=>{if(h!==void 0&&m!==void 0){if(h!==0)return c(new Error(`curl exited ${h}`));if(m!==0)return c(new Error(`tar exited ${m}`));l()}};u.on("close",b=>{h=b,I()}),p.on("close",b=>{m=b,I()}),u.on("error",c),p.on("error",c)});let{writeFileSync:i,unlinkSync:a}=await import("node:fs");i(e,"");try{a(s)}catch{}}catch(i){try{let{unlinkSync:a}=await import("node:fs");a(s)}catch{}throw new O("bundle-extract-failed",i.message)}}async function Ze(r){let t=j(r,"graph.mjs");if(!F(t))throw new O("entry-missing",`graph.mjs missing under ${r}`);let e;try{e=await import(Fe(t).href)}catch(s){throw new O("import-failed",`${s?.code||s?.name||"unknown"}: ${s.message}`)}let o=e.default||Object.values(e).find(s=>typeof s=="function"&&s.prototype?.buildGraph);if(!o)throw new O("entry-class-missing","no buildGraph() class export found");return o}async function ie(r,t={}){if(!r||typeof r!="string")throw new Error("runInProcessSubgraph: workflowName (string) is required");let e=q(),o;try{o=He()}catch(f){throw f}w.debug(`[in-process subgraph] begin '${r}' parent=${e.executionId||"<root>"}`);let s=await Je({apiBase:o.apiBase,authToken:o.authToken,body:{parentExecutionId:e.executionId,childWorkflowType:r,input:t.input||{},...t.conversationId?{conversationId:t.conversationId}:{}}}),{childExecutionId:n,runtimeTag:i,bundlePresignedUrl:a,sourcesPresignedUrl:l,workflowVersion:c,workflowUuid:u,bundleReady:p}=s,h=Ge();if(i&&i!==h)throw await W({apiBase:o.apiBase,authToken:o.authToken,payload:{childExecutionId:n,status:"canceled",error:{message:`runtimeTag mismatch: parent=${h} child=${i}`,code:"RUNTIME_MISMATCH"}}}),new O("runtime-mismatch",`${h} vs ${i}`);if(!p||!a)throw await W({apiBase:o.apiBase,authToken:o.authToken,payload:{childExecutionId:n,status:"canceled",error:{message:"bundle not ready for in-process; falling back to HTTP",code:"NO_BUNDLE"}}}),new O("no-bundle","workflow bundle not built yet");let m=re(r);if(!m){let f=j(at,`${u}@${c||"0"}`);try{await Ye(a,f);try{Ke()}catch{}}catch(g){throw g.fallback&&await W({apiBase:o.apiBase,authToken:o.authToken,payload:{childExecutionId:n,status:"failed",error:{message:g.message,code:g.reason}}}),g}try{m=await Ze(f),te(r,m,{workflowUuid:u,version:c,runtimeTag:i,cacheDir:f})}catch(g){throw ee(r,g),await W({apiBase:o.apiBase,authToken:o.authToken,payload:{childExecutionId:n,status:"failed",error:{message:g.message,code:g.reason||"IMPORT_FAILED"}}}),g.fallback?g:new O("import-failed",g.message)}}let I=Date.now(),$=await(typeof m=="function"&&m.prototype?.buildGraph?new m:m).buildGraph(),T={...t.input||{}},d,y;try{d=await Xt({executionId:n,parentExecutionId:e.executionId,conversationId:t.conversationId!==void 0?t.conversationId:e.conversationId,dispatchMode:"inprocess"},()=>$.run(t.parentAgent,T,{signal:t.signal})),y=d&&typeof d=="object"&&"state"in d?d.state:d}catch(f){throw await W({apiBase:o.apiBase,authToken:o.authToken,payload:{childExecutionId:n,status:"failed",error:{message:f.message,code:f.code||"CHILD_THREW",stack:f.stack},durationMs:Date.now()-I}}),f}if(d&&typeof d=="object"&&d.stoppedExternally){await W({apiBase:o.apiBase,authToken:o.authToken,payload:{childExecutionId:n,status:"canceled",finalState:y,durationMs:Date.now()-I}});let f=new Error(`Sub-graph '${r}' canceled by parent abort`);throw f.code="SUBGRAPH_CANCELED",f.subgraphJobId=n,f}return await W({apiBase:o.apiBase,authToken:o.authToken,payload:{childExecutionId:n,status:"completed",finalState:y,durationMs:Date.now()-I}}),{finalState:y,executionId:n}}function ze(r){let t=0,e=[r];for(;e.length;){let o=e.pop(),s;try{s=se(o)}catch{continue}if(s.isDirectory()){let n;try{n=ne(o)}catch{continue}for(let i of n)e.push(j(o,i))}else t+=s.size}return t}function Ke({cap:r=Number(process.env.ZIBBY_SUBGRAPH_CACHE_CAP_BYTES||2*1024*1024*1024)}={}){try{if(!F(at))return{evicted:0,freedBytes:0};let t=ne(at),e=[],o=0;for(let a of t){let l=j(at,a),c;try{c=se(l)}catch{continue}let u=c.isDirectory()?ze(l):c.size;o+=u,e.push({name:a,full:l,size:u,mtimeMs:c.mtimeMs})}if(o<=r)return{evicted:0,freedBytes:0,totalBytes:o};e.sort((a,l)=>a.mtimeMs-l.mtimeMs);let s=Math.floor(r*.7),n=0,i=0;for(let a of e){if(o-n<=s)break;if(!F(j(a.full,".lock")))try{We(a.full,{recursive:!0,force:!0}),n+=a.size,i+=1}catch(l){w.debug(`[sub-graph cache] evict skip ${a.name}: ${l.message}`)}}return i>0&&w.info(`[sub-graph cache] evicted ${i} entr(y/ies), freed ${(n/1024/1024).toFixed(1)}MB`),{evicted:i,freedBytes:n,totalBytes:o-n}}catch(t){return w.debug(`[sub-graph cache] evict failed: ${t.message}`),{evicted:0,freedBytes:0}}}var Ve=2e3,qe=600*1e3,Xe=new Set(["completed","failed","canceled","timeout"]);function Qe(){let r=process.env.PROGRESS_API_URL;if(!r)throw new Error("Sub-graph dispatch requires PROGRESS_API_URL env var (set automatically on cloud runs). Sub-graphs are not supported in local in-process runs yet \u2014 deploy the parent and child to cloud.");return r.replace(/\/executions\/?$/,"")}function tr(){let r=process.env.PROJECT_ID;if(!r)throw new Error("Sub-graph dispatch requires PROJECT_ID env var.");return r}function er(){let r=process.env.PROJECT_API_TOKEN;if(!r)throw new Error("Sub-graph dispatch requires PROJECT_API_TOKEN env var.");return r}function rr(){return process.env.EXECUTION_ID||null}function ae(r,t){return t==null?r:typeof t=="function"?t(r):typeof t=="string"?t.split(".").reduce((e,o)=>e==null?e:e[o],r):r}async function ce(r,t={}){if(!r||typeof r!="string")throw new Error("dispatchSubgraph: workflowName (string) is required");let e=q(),o=Number(process.env.ZIBBY_SUBGRAPH_MAX_DEPTH||10);if((e.depth||0)>=o)throw new Error(`dispatchSubgraph('${r}'): sub-graph depth ${e.depth} reached cap of ${o}. Restructure the graph or raise ZIBBY_SUBGRAPH_MAX_DEPTH.`);if(process.env.ZIBBY_INPROCESS_SUBGRAPH!=="0"&&!t.async)try{w.debug(`[sub-graph] trying in-process for '${r}'`);let{finalState:f}=await ie(r,{input:t.input,conversationId:t.conversationId,signal:t.signal,parentAgent:t.parentAgent}),g=ae(f,t.output);return w.info(`[sub-graph] '${r}' completed in-process`),g}catch(f){if(f instanceof O||f?.fallback)w.info(`[sub-graph] in-process fallback for '${r}': ${f.reason||"unknown"} \u2014 using HTTP`);else throw f}let s=Qe(),n=tr(),i=er(),a=rr(),l=`${s}/projects/${encodeURIComponent(n)}/workflows/${encodeURIComponent(r)}/trigger`,c={input:t.input||{},...a?{parentExecutionId:a}:{},...t.conversationId?{conversationId:t.conversationId}:{}};w.info(`[sub-graph] dispatching '${r}' (${t.async?"async":"sync"}) from parent ${a||"<none>"}`);let u=await fetch(l,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${i}`},body:JSON.stringify(c)});if(!u.ok){let f=null,g="";try{f=await u.json(),g=f?.error||f?.message||JSON.stringify(f)}catch{g=await u.text().catch(()=>"")}if(u.status===429){let v=f?.quotaInfo||{},M=new Error(`Sub-graph '${r}' blocked by execution quota (${v.used??"?"}/${v.limit??"?"} on plan ${v.planId||"unknown"}). Sub-workflow runs count toward the same monthly cap as user-triggered runs.`);throw M.code="SUBGRAPH_QUOTA_EXCEEDED",M.status=429,M.subgraph=r,M.quotaInfo=v,M}if(u.status===400){let v=new Error(`Sub-graph '${r}' rejected input: ${g}`);throw v.code="SUBGRAPH_INVALID_INPUT",v.status=400,v.subgraph=r,v.validationErrors=f?.validationErrors||null,v.missing=f?.missing||null,v}let B=new Error(`Sub-graph '${r}' trigger rejected (${u.status}): ${g}`);throw B.code="SUBGRAPH_TRIGGER_FAILED",B.status=u.status,B.subgraph=r,B}let p=await u.json(),h=p?.data?.jobId||p?.jobId;if(!h)throw new Error(`Sub-graph '${r}' trigger returned no jobId: ${JSON.stringify(p).slice(0,200)}`);if(t.async)return w.info(`[sub-graph] async dispatch of '${r}' \u2192 jobId=${h} (not waiting)`),{jobId:h,status:"accepted",workflow:r};let m=Number.isFinite(t.timeoutMs)?t.timeoutMs:qe,I=Number.isFinite(t.pollIntervalMs)?t.pollIntervalMs:Ve,b=`${s}/executions/${encodeURIComponent(h)}`,$=Date.now()+m,T="accepted",d=0;for(;Date.now()<$;){await new Promise(v=>setTimeout(v,I)),d+=1;let f=await fetch(b,{headers:{Authorization:`Bearer ${i}`}});if(!f.ok){if(f.status>=500){w.warn(`[sub-graph] status poll for ${h} returned ${f.status}, will retry`);continue}throw new Error(`Sub-graph status poll failed for ${h}: ${f.status}`)}let g=await f.json(),B=g?.data||g?.execution||g;if(T=B?.status||T,Xe.has(T)){if(T!=="completed"){let S=new Error(`Sub-graph '${r}' (${h}) ended in status '${T}'`);throw S.subgraphJobId=h,S.subgraphStatus=T,S}let v=B?.finalState||B?.state||{},M=ae(v,t.output);return w.info(`[sub-graph] '${r}' (${h}) completed after ${d} polls`),M}}let y=new Error(`Sub-graph '${r}' (${h}) timed out after ${Math.round(m/1e3)}s (last status: ${T})`);throw y.subgraphJobId=h,y.subgraphStatus=T,y}import{existsSync as le,readFileSync as or}from"node:fs";import{join as vt,dirname as ue}from"node:path";var ct=class{static async loadContext(t,e,o={}){let s={},n=o.filenames||["CONTEXT.md","AGENTS.md"];if(t){let a=ue(vt(e,t));for(let l of n){let c=await this.findAndMergeContextFiles(l,a,e);if(c){let u=l.replace(/\.[^.]+$/,"").toLowerCase();s[u]=c}}}let i=o.discovery||{};for(let[a,l]of Object.entries(i))try{let c=vt(e,l);le(c)&&(s[a]=await this.loadFile(c))}catch(c){console.warn(`[workflow] could not load context '${a}' from '${l}': ${c.message}`)}return s}static async findAndMergeContextFiles(t,e,o){let s=[],n=e;for(;n.startsWith(o);){let i=vt(n,t);if(le(i))try{s.unshift(await this.loadFile(i))}catch(l){console.warn(`[workflow] could not load ${t} from ${i}: ${l.message}`)}let a=ue(n);if(a===n)break;n=a}return s.length===0?null:s.every(i=>typeof i=="string")?s.join(`
|
|
29
|
+
${n}`);let a=s(),l=a.cwd||process.cwd(),u=a.sessionPath;try{if(u){let c=bt(u,Z);if(Xt(c)){let h=JSON.parse(Vt(c,"utf-8"));h.currentNode=this.name,Et(c,JSON.stringify(h,null,2),"utf-8")}let g=bt(u,"..",Z);if(Xt(g))try{let h=JSON.parse(Vt(g,"utf-8"));h.currentNode=this.name,Et(g,JSON.stringify(h,null,2),"utf-8")}catch{}}}catch(c){w.debug(`[workflow] could not update session info: ${c.message}`)}let p=null;for(let c=0;c<=this.retries;c++)try{w.debug(`[workflow] node '${this.name}' attempt ${c}`);let g=s().config||{},h=g.agents||{},E=this.config.agent??h[this.name]??null,$={state:s()};E&&($.preferredAgent=E);let T={workspace:l,schema:this.isZodSchema?this.outputSchema:null,skills:this.config.skills||[],sessionPath:u,config:g,nodeName:this.name,timeout:this.config?.timeout||3e5},y=t?._coreInvokeAgent;y||(y=(await Promise.resolve().then(()=>(It(),_t))).invokeAgent);let d=await y(n,$,T),I,f;if(typeof d=="string"?(I=d,f=null):d.structured?(I=d.raw||JSON.stringify(d.structured,null,2),f=d.structured):(I=d.raw||JSON.stringify(d,null,2),f=d.extracted||null),u)try{let m=bt(u,this.name,"raw_stream_output.txt");De(Le(m),{recursive:!0}),Et(m,typeof I=="string"?I:JSON.stringify(I),"utf-8")}catch(m){w.debug(`[workflow] could not save raw output: ${m.message}`)}if(this.isZodSchema&&f){w.info(`[workflow] node '${this.name}': output validated: ${JSON.stringify(f,null,2)}`);let m=f;if(typeof this.onComplete=="function")try{m=await this.onComplete(s(),f)}catch(B){w.warn(`[workflow] onComplete hook failed: ${B.message}`)}return{success:!0,output:m,raw:I}}if(typeof this.onComplete=="function")try{return{success:!0,output:await this.onComplete(s(),{raw:I}),raw:I}}catch(m){throw new Error(`onComplete failed: ${m.message}`,{cause:m})}if(this.parser){let m=this.parser.parse(I);return w.info(`[workflow] node '${this.name}': parsed output: ${JSON.stringify(m,null,2)}`),k.step("Output parsed"),{success:!0,output:m,raw:I}}return{success:!0,output:I,raw:I}}catch(g){p=g,c<this.retries&&w.info(`[workflow] node '${this.name}' failed, retrying (${c+1}/${this.retries})\u2026`)}return{success:!1,error:p.message,raw:null}}},X=class extends L{constructor(t){super({...t,_isCustomCode:!0}),this.condition=t.condition}async execute(t,e){let s=e&&typeof e.getAll=="function"?e.getAll():t;return{success:!0,output:{nextNode:this.condition(s)},raw:null}}};q();q();import{mkdirSync as We,existsSync as G,statSync as ne,readdirSync as ie,rmSync as Fe}from"node:fs";import{spawn as oe}from"node:child_process";import{join as j}from"node:path";import{pathToFileURL as Ge}from"node:url";import{AsyncLocalStorage as je}from"node:async_hooks";var $t=new je;function Q(){let r=$t.getStore();return r||Object.freeze({executionId:process.env.EXECUTION_ID||null,parentExecutionId:process.env.PARENT_EXECUTION_ID||null,depth:0,conversationId:process.env.ZIBBY_CONVERSATION_ID||null,dispatchMode:process.env.DISPATCH_MODE||null})}function Qt(r,t){let e=$t.getStore()||Q(),s=Object.freeze({executionId:r.executionId,parentExecutionId:r.parentExecutionId??e.executionId??null,depth:(e.depth||0)+(r.executionId!==e.executionId?1:0),conversationId:r.conversationId!==void 0?r.conversationId:e.conversationId??null,dispatchMode:r.dispatchMode??null});return $t.run(s,t)}var Tt=new Map,vt=new Map,te=new Map;function ee(r,t,e={}){if(!r||typeof r!="string")throw new Error("subgraph-registry.register: name required");if(typeof t!="function")throw new Error("subgraph-registry.register: factory must be a function");Tt.set(r,t),vt.set(r,"ready"),te.set(r,{...e,cachedAt:Date.now()})}function re(r,t){vt.set(r,"failed"),te.set(r,{error:t?.message||String(t),failedAt:Date.now()}),Tt.delete(r)}function se(r){return vt.get(r)==="ready"?Tt.get(r):null}var ct=process.env.ZIBBY_SUBGRAPH_CACHE_DIR||"/tmp/zibby/subgraphs";function He(){return`node${(process.versions?.node||"").split(".")[0]||"unknown"}-${process.platform}-${process.arch}`}var O=class extends Error{constructor(t,e){super(`in-process sub-graph fallback: ${t}${e?` (${e})`:""}`),this.fallback=!0,this.reason=t,this.detail=e||null,this.name="SubgraphFallback"}};function Je(){let r=(process.env.SUBGRAPH_INTERNAL_URL||"").replace(/\/$/,""),t=(process.env.PROGRESS_API_URL||"").replace(/\/executions\/?$/,""),e=r||t,s=process.env.PROJECT_ID,o=process.env.PROJECT_API_TOKEN;if(!e||!s||!o)throw new O("env","SUBGRAPH_INTERNAL_URL/PROGRESS_API_URL/PROJECT_ID/PROJECT_API_TOKEN missing");return{apiBase:e,projectId:s,authToken:o}}async function Ye({apiBase:r,authToken:t,body:e}){let s;try{s=await fetch(`${r}/internal/subgraph/begin`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${t}`},body:JSON.stringify(e)})}catch(n){throw new O("network",`begin fetch failed: ${n.message}`)}let o=null;try{o=await s.json()}catch{}if(!s.ok){if(s.status===404){let n=new Error(`Sub-graph child '${e.childWorkflowType}' not found in project`);throw n.code="SUBGRAPH_NOT_FOUND",n.status=404,n}if(s.status===429){let n=o?.quotaInfo||{},i=new Error(`Sub-graph blocked by quota (${n.used??"?"}/${n.limit??"?"} on ${n.planId||"plan"})`);throw i.code="SUBGRAPH_QUOTA_EXCEEDED",i.status=429,i.quotaInfo=n,i}if(s.status===400&&o?.validationErrors){let n=new Error(`Sub-graph rejected input: ${o?.error||o?.message||"validation failed"}`);throw n.code="SUBGRAPH_INVALID_INPUT",n.status=400,n.validationErrors=o.validationErrors,n.missing=o.missing,n}throw new O("begin-status",`begin returned ${s.status}`)}return o?.data||o}async function F({apiBase:r,authToken:t,payload:e}){try{let s=await fetch(`${r}/internal/subgraph/finalize`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${t}`},body:JSON.stringify(e)});s.ok||w.warn(`[in-process subgraph] finalize returned ${s.status} for ${e.childExecutionId}`)}catch(s){w.warn(`[in-process subgraph] finalize failed: ${s.message}`)}}async function Ze(r,t){let e=j(t,".ready"),s=j(t,"graph.mjs");if(G(e)&&G(s))return;We(t,{recursive:!0});let o=j(t,".lock"),n=!1;try{let{openSync:i,closeSync:a}=await import("node:fs"),l=i(o,"wx");a(l),n=!0}catch(i){if(i.code!=="EEXIST")throw i}if(!n){let i=Date.now()+3e4;for(;Date.now()<i;){if(G(e)&&G(s))return;await new Promise(a=>setTimeout(a,100))}throw new O("bundle-extract-timeout","sibling extract did not complete within 30s")}try{await new Promise((l,u)=>{let p=oe("curl",["-fsSL",r],{stdio:["ignore","pipe","inherit"]}),c=oe("tar",["-xzf","-","-C",t],{stdio:["pipe","inherit","inherit"]});p.stdout.pipe(c.stdin);let g,h,E=()=>{if(g!==void 0&&h!==void 0){if(g!==0)return u(new Error(`curl exited ${g}`));if(h!==0)return u(new Error(`tar exited ${h}`));l()}};p.on("close",$=>{g=$,E()}),c.on("close",$=>{h=$,E()}),p.on("error",u),c.on("error",u)});let{writeFileSync:i,unlinkSync:a}=await import("node:fs");i(e,"");try{a(o)}catch{}}catch(i){try{let{unlinkSync:a}=await import("node:fs");a(o)}catch{}throw new O("bundle-extract-failed",i.message)}}async function ze(r){let t=j(r,"graph.mjs");if(!G(t))throw new O("entry-missing",`graph.mjs missing under ${r}`);let e;try{e=await import(Ge(t).href)}catch(o){throw new O("import-failed",`${o?.code||o?.name||"unknown"}: ${o.message}`)}let s=e.default||Object.values(e).find(o=>typeof o=="function"&&o.prototype?.buildGraph);if(!s)throw new O("entry-class-missing","no buildGraph() class export found");return s}async function ae(r,t={}){if(!r||typeof r!="string")throw new Error("runInProcessSubgraph: workflowName (string) is required");let e=Q(),s;try{s=Je()}catch(f){throw f}w.debug(`[in-process subgraph] begin '${r}' parent=${e.executionId||"<root>"}`);let o=await Ye({apiBase:s.apiBase,authToken:s.authToken,body:{parentExecutionId:e.executionId,childWorkflowType:r,input:t.input||{},...t.conversationId?{conversationId:t.conversationId}:{}}}),{childExecutionId:n,runtimeTag:i,bundlePresignedUrl:a,sourcesPresignedUrl:l,workflowVersion:u,workflowUuid:p,bundleReady:c}=o,g=He();if(i&&i!==g)throw await F({apiBase:s.apiBase,authToken:s.authToken,payload:{childExecutionId:n,status:"canceled",error:{message:`runtimeTag mismatch: parent=${g} child=${i}`,code:"RUNTIME_MISMATCH"}}}),new O("runtime-mismatch",`${g} vs ${i}`);if(!c||!a)throw await F({apiBase:s.apiBase,authToken:s.authToken,payload:{childExecutionId:n,status:"canceled",error:{message:"bundle not ready for in-process; falling back to HTTP",code:"NO_BUNDLE"}}}),new O("no-bundle","workflow bundle not built yet");let h=se(r);if(!h){let f=j(ct,`${p}@${u||"0"}`);try{await Ze(a,f);try{qe()}catch{}}catch(m){throw m.fallback&&await F({apiBase:s.apiBase,authToken:s.authToken,payload:{childExecutionId:n,status:"failed",error:{message:m.message,code:m.reason}}}),m}try{h=await ze(f),ee(r,h,{workflowUuid:p,version:u,runtimeTag:i,cacheDir:f})}catch(m){throw re(r,m),await F({apiBase:s.apiBase,authToken:s.authToken,payload:{childExecutionId:n,status:"failed",error:{message:m.message,code:m.reason||"IMPORT_FAILED"}}}),m.fallback?m:new O("import-failed",m.message)}}let E=Date.now(),T=await(typeof h=="function"&&h.prototype?.buildGraph?new h:h).buildGraph(),y={...t.input||{}},d,I;try{d=await Qt({executionId:n,parentExecutionId:e.executionId,conversationId:t.conversationId!==void 0?t.conversationId:e.conversationId,dispatchMode:"inprocess"},()=>T.run(t.parentAgent,y,{signal:t.signal})),I=d&&typeof d=="object"&&"state"in d?d.state:d}catch(f){throw await F({apiBase:s.apiBase,authToken:s.authToken,payload:{childExecutionId:n,status:"failed",error:{message:f.message,code:f.code||"CHILD_THREW",stack:f.stack},durationMs:Date.now()-E}}),f}if(d&&typeof d=="object"&&d.stoppedExternally){await F({apiBase:s.apiBase,authToken:s.authToken,payload:{childExecutionId:n,status:"canceled",finalState:I,durationMs:Date.now()-E}});let f=new Error(`Sub-graph '${r}' canceled by parent abort`);throw f.code="SUBGRAPH_CANCELED",f.subgraphJobId=n,f}return await F({apiBase:s.apiBase,authToken:s.authToken,payload:{childExecutionId:n,status:"completed",finalState:I,durationMs:Date.now()-E}}),{finalState:I,executionId:n}}function Ke(r){let t=0,e=[r];for(;e.length;){let s=e.pop(),o;try{o=ne(s)}catch{continue}if(o.isDirectory()){let n;try{n=ie(s)}catch{continue}for(let i of n)e.push(j(s,i))}else t+=o.size}return t}function qe({cap:r=Number(process.env.ZIBBY_SUBGRAPH_CACHE_CAP_BYTES||2*1024*1024*1024)}={}){try{if(!G(ct))return{evicted:0,freedBytes:0};let t=ie(ct),e=[],s=0;for(let a of t){let l=j(ct,a),u;try{u=ne(l)}catch{continue}let p=u.isDirectory()?Ke(l):u.size;s+=p,e.push({name:a,full:l,size:p,mtimeMs:u.mtimeMs})}if(s<=r)return{evicted:0,freedBytes:0,totalBytes:s};e.sort((a,l)=>a.mtimeMs-l.mtimeMs);let o=Math.floor(r*.7),n=0,i=0;for(let a of e){if(s-n<=o)break;if(!G(j(a.full,".lock")))try{Fe(a.full,{recursive:!0,force:!0}),n+=a.size,i+=1}catch(l){w.debug(`[sub-graph cache] evict skip ${a.name}: ${l.message}`)}}return i>0&&w.info(`[sub-graph cache] evicted ${i} entr(y/ies), freed ${(n/1024/1024).toFixed(1)}MB`),{evicted:i,freedBytes:n,totalBytes:s-n}}catch(t){return w.debug(`[sub-graph cache] evict failed: ${t.message}`),{evicted:0,freedBytes:0}}}var Ve=2e3,Xe=600*1e3,Qe=new Set(["completed","failed","canceled","timeout"]);function tr(){let r=process.env.PROGRESS_API_URL;if(!r)throw new Error("Sub-graph dispatch requires PROGRESS_API_URL env var (set automatically on cloud runs). Sub-graphs are not supported in local in-process runs yet \u2014 deploy the parent and child to cloud.");return r.replace(/\/executions\/?$/,"")}function er(){let r=process.env.PROJECT_ID;if(!r)throw new Error("Sub-graph dispatch requires PROJECT_ID env var.");return r}function rr(){let r=process.env.PROJECT_API_TOKEN;if(!r)throw new Error("Sub-graph dispatch requires PROJECT_API_TOKEN env var.");return r}function sr(){return process.env.EXECUTION_ID||null}function ce(r,t){return t==null?r:typeof t=="function"?t(r):typeof t=="string"?t.split(".").reduce((e,s)=>e==null?e:e[s],r):r}async function le(r,t={}){if(!r||typeof r!="string")throw new Error("dispatchSubgraph: workflowName (string) is required");let e=Q(),s=Number(process.env.ZIBBY_SUBGRAPH_MAX_DEPTH||10);if((e.depth||0)>=s)throw new Error(`dispatchSubgraph('${r}'): sub-graph depth ${e.depth} reached cap of ${s}. Restructure the graph or raise ZIBBY_SUBGRAPH_MAX_DEPTH.`);if(process.env.ZIBBY_INPROCESS_SUBGRAPH!=="0"&&!t.async)try{w.debug(`[sub-graph] trying in-process for '${r}'`);let{finalState:f}=await ae(r,{input:t.input,conversationId:t.conversationId,signal:t.signal,parentAgent:t.parentAgent}),m=ce(f,t.output);return w.info(`[sub-graph] '${r}' completed in-process`),m}catch(f){if(f instanceof O||f?.fallback)w.info(`[sub-graph] in-process fallback for '${r}': ${f.reason||"unknown"} \u2014 using HTTP`);else throw f}let o=tr(),n=er(),i=rr(),a=sr(),l=`${o}/projects/${encodeURIComponent(n)}/workflows/${encodeURIComponent(r)}/trigger`,u={input:t.input||{},...a?{parentExecutionId:a}:{},...t.conversationId?{conversationId:t.conversationId}:{}};w.info(`[sub-graph] dispatching '${r}' (${t.async?"async":"sync"}) from parent ${a||"<none>"}`);let p=await fetch(l,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${i}`},body:JSON.stringify(u)});if(!p.ok){let f=null,m="";try{f=await p.json(),m=f?.error||f?.message||JSON.stringify(f)}catch{m=await p.text().catch(()=>"")}if(p.status===429){let v=f?.quotaInfo||{},M=new Error(`Sub-graph '${r}' blocked by execution quota (${v.used??"?"}/${v.limit??"?"} on plan ${v.planId||"unknown"}). Sub-workflow runs count toward the same monthly cap as user-triggered runs.`);throw M.code="SUBGRAPH_QUOTA_EXCEEDED",M.status=429,M.subgraph=r,M.quotaInfo=v,M}if(p.status===400){let v=new Error(`Sub-graph '${r}' rejected input: ${m}`);throw v.code="SUBGRAPH_INVALID_INPUT",v.status=400,v.subgraph=r,v.validationErrors=f?.validationErrors||null,v.missing=f?.missing||null,v}let B=new Error(`Sub-graph '${r}' trigger rejected (${p.status}): ${m}`);throw B.code="SUBGRAPH_TRIGGER_FAILED",B.status=p.status,B.subgraph=r,B}let c=await p.json(),g=c?.data?.jobId||c?.jobId;if(!g)throw new Error(`Sub-graph '${r}' trigger returned no jobId: ${JSON.stringify(c).slice(0,200)}`);if(t.async)return w.info(`[sub-graph] async dispatch of '${r}' \u2192 jobId=${g} (not waiting)`),{jobId:g,status:"accepted",workflow:r};let h=Number.isFinite(t.timeoutMs)?t.timeoutMs:Xe,E=Number.isFinite(t.pollIntervalMs)?t.pollIntervalMs:Ve,$=`${o}/executions/${encodeURIComponent(g)}`,T=Date.now()+h,y="accepted",d=0;for(;Date.now()<T;){await new Promise(v=>setTimeout(v,E)),d+=1;let f=await fetch($,{headers:{Authorization:`Bearer ${i}`}});if(!f.ok){if(f.status>=500){w.warn(`[sub-graph] status poll for ${g} returned ${f.status}, will retry`);continue}throw new Error(`Sub-graph status poll failed for ${g}: ${f.status}`)}let m=await f.json(),B=m?.data||m?.execution||m;if(y=B?.status||y,Qe.has(y)){if(y!=="completed"){let S=new Error(`Sub-graph '${r}' (${g}) ended in status '${y}'`);throw S.subgraphJobId=g,S.subgraphStatus=y,S}let v=B?.finalState||B?.state||{},M=ce(v,t.output);return w.info(`[sub-graph] '${r}' (${g}) completed after ${d} polls`),M}}let I=new Error(`Sub-graph '${r}' (${g}) timed out after ${Math.round(h/1e3)}s (last status: ${y})`);throw I.subgraphJobId=g,I.subgraphStatus=y,I}import{existsSync as ue,readFileSync as or}from"node:fs";import{join as At,dirname as pe}from"node:path";var lt=class{static async loadContext(t,e,s={}){let o={},n=s.filenames||["CONTEXT.md","AGENTS.md"];if(t){let a=pe(At(e,t));for(let l of n){let u=await this.findAndMergeContextFiles(l,a,e);if(u){let p=l.replace(/\.[^.]+$/,"").toLowerCase();o[p]=u}}}let i=s.discovery||{};for(let[a,l]of Object.entries(i))try{let u=At(e,l);ue(u)&&(o[a]=await this.loadFile(u))}catch(u){console.warn(`[workflow] could not load context '${a}' from '${l}': ${u.message}`)}return o}static async findAndMergeContextFiles(t,e,s){let o=[],n=e;for(;n.startsWith(s);){let i=At(n,t);if(ue(i))try{o.unshift(await this.loadFile(i))}catch(l){console.warn(`[workflow] could not load ${t} from ${i}: ${l.message}`)}let a=pe(n);if(a===n)break;n=a}return o.length===0?null:o.every(i=>typeof i=="string")?o.join(`
|
|
30
30
|
|
|
31
31
|
---
|
|
32
32
|
|
|
33
|
-
`):
|
|
33
|
+
`):o.every(i=>typeof i=="object")?Object.assign({},...o):o[o.length-1]}static async loadFile(t){let e=or(t,"utf-8");if(t.endsWith(".json"))return JSON.parse(e);if(t.endsWith(".js")||t.endsWith(".mjs")){let{pathToFileURL:s}=await import("url"),o=await import(s(t).href);return o.default||o}return e}};import{mkdirSync as ge,existsSync as kt,writeFileSync as de,unlinkSync as nr}from"node:fs";import{join as H,resolve as me}from"node:path";import{config as ir}from"dotenv";import{zodToJsonSchema as he}from"zod-to-json-schema";import{z as ut}from"zod";import ar from"handlebars";function cr({traceFrom:r,sessionId:t,sessionPath:e,idSource:s,mkdirFresh:o}){if(!(process.env.ZIBBY_SESSION_LOG==="1"||process.env.ZIBBY_SESSION_LOG==="true"))return;let i=typeof process.ppid=="number"?process.ppid:"n/a",a=`[zibby:session] from=${r} pid=${process.pid} ppid=${i} sessionId=${t} source=${s} mkdir=${o?"yes":"no"} path=${e}`;if(console.log(a),process.env.ZIBBY_TRACE_SESSION==="1"||process.env.ZIBBY_TRACE_SESSION==="true"){let p=(new Error("session trace").stack||"").split(`
|
|
34
34
|
`).slice(2,14).join(`
|
|
35
35
|
`);console.log(`[zibby:session] stack (${r}):
|
|
36
|
-
${u}`)}}function cr(){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 lr(){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 ge(String(t).trim())}catch{return String(t).trim()}}function ur(){cr()||(delete process.env.ZIBBY_SESSION_PATH,delete process.env.ZIBBY_SESSION_ID)}function pr({sessionPath:r,sessionId:t}){r&&typeof r=="string"&&(process.env.ZIBBY_SESSION_PATH=r),t!=null&&String(t).trim()!==""&&(process.env.ZIBBY_SESSION_ID=String(t).trim())}function dr(r={}){let t=Yt.map(n=>process.env[n]).find(Boolean),e=Math.random().toString(36).slice(2,6),o=t||`${Date.now()}_${e}`,s=r.paths?.sessionPrefix;return s?`${s}_${o}`:o}function hr({cwd:r=process.cwd(),config:t={},initialState:e={},traceFrom:o="resolveWorkflowSession"}={}){let s=e.sessionPath,n=e.sessionTimestamp,i="initialState.sessionPath";if(!s&&process.env.ZIBBY_SESSION_PATH)try{let c=ge(String(process.env.ZIBBY_SESSION_PATH));c&&(s=c,i="ZIBBY_SESSION_PATH")}catch{}let a;if(s)a=String(s).split(/[/\\]/).filter(Boolean).pop(),n==null&&(n=Date.now());else{let c=process.env.ZIBBY_SESSION_ID&&String(process.env.ZIBBY_SESSION_ID).trim();if(c)a=c,i="ZIBBY_SESSION_ID";else{let p=t.sessionId!=null?String(t.sessionId).trim():"";p&&p!=="last"?(a=p,i="config.sessionId"):(a=dr(t),i="generated")}n=n??Date.now();let u=t.paths?.output||nt;s=G(r,u,Ht,a)}let l=!At(s);return l&&fe(s,{recursive:!0}),(l||i!=="initialState.sessionPath")&&ar({traceFrom:o,sessionId:a,sessionPath:s,idSource:i,mkdirFresh:l}),pr({sessionPath:s,sessionId:a}),{sessionPath:s,sessionId:a,sessionTimestamp:n}}var he=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{return this.inputSchema.merge(this.contextSchema)}catch{}return this.inputSchema&&!this.contextSchema?this.inputSchema:this.stateSchema}addNode(t,e,o={}){if(!(e instanceof L)&&e&&typeof e=="object"&&typeof e.workflow=="string"){let n=e,i={name:t,_isCustomCode:!0,retries:n.retries,onComplete:n.onComplete,execute:async l=>{let c=l?.state&&typeof l.state.getAll=="function"?l.state.getAll():l,u;return typeof n.input=="function"?u=n.input(c):n.input&&typeof n.input=="object"?u=n.input:u={},ce(n.workflow,{input:u,async:n.async===!0,conversationId:typeof n.conversationId=="function"?n.conversationId(c):n.conversationId,output:n.output,timeoutMs:n.timeoutMs,pollIntervalMs:n.pollIntervalMs,signal:c?._signal,parentAgent:l?.agent})}},a=new L(i);return a.name=t,this.nodes.set(t,a),o.prompt&&this.nodePrompts.set(t,o.prompt),Object.keys(o).length>0&&this.nodeOptions.set(t,o),this}let s=e instanceof L?e:new L(e);return s.name=t,this.nodes.set(t,s),o.prompt&&this.nodePrompts.set(t,o.prompt),Object.keys(o).length>0&&this.nodeOptions.set(t,o),this}addConditionalNode(t,e){return this.nodes.set(t,new it({...e,name:t})),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:o}={}){return this.edges.set(t,{conditional:!0,routes:e,labels:o}),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,o,s,n){let i=o;for(let a=t.length-1;a>=0;a--){let l=t[a],c=i;i=()=>l(e,c,s,n)}return i()}serialize(){let t=[],e={};for(let[c,u]of this.nodes){let p=this.nodeTypeMap.get(c)||c;t.push({id:c,type:p,data:{nodeType:p,label:c}});let h={};u._isCustomCode&&typeof u.execute=="function"&&(h.customCode=u.execute.toString());let m=this.nodePrompts.get(c);if(m&&(h.prompt=m),typeof u.customExecute=="function"&&(h.executeCode=u.customExecute.toString()),u.outputSchema)if(typeof u.outputSchema._def<"u"){let $=null;if(typeof lt?.toJSONSchema=="function")try{$=lt.toJSONSchema(u.outputSchema)}catch{}if(!$)try{$=de(u.outputSchema,{target:"openApi3"})}catch{}h.outputSchema=$?{jsonSchema:$,variables:this._flattenJsonSchemaToVariables($)}:{schema:u.outputSchema}}else h.outputSchema={schema:u.outputSchema};let I=(this.resolvedToolsMap||{})[c];I?.toolIds&&(h.tools=I.toolIds);let b=Array.isArray(u?.config?.skills)?u.config.skills:Array.isArray(u?.skills)?u.skills:null;b&&b.length>0&&(h.skills=[...b]),Object.keys(h).length>0&&(e[c]=h)}let o=[];for(let[c,u]of this.edges)if(typeof u=="string")o.push({source:c,target:u});else if(u.conditional){let p=this.conditionalCodeMap.get(c)||u.routes.toString(),h=this._inferConditionalTargets(u.routes,u.labels),m=u.labels||{};for(let I of h){let b={source:c,target:I,data:{conditionalCode:p}};m[I]&&(b.label=m[I]),o.push(b)}}let s=c=>{if(!c)return null;if(typeof lt?.toJSONSchema=="function")try{return lt.toJSONSchema(c)}catch{}try{return de(c,{target:"openApi3"})}catch{return null}},n=this._runtimeSchema(),i=s(n||this.stateSchema),a=s(this.inputSchema),l=s(this.contextSchema);return{nodes:t,edges:o,nodeConfigs:e,stateSchema:i,inputSchema:a,contextSchema:l}}_inferConditionalTargets(t,e){let o=t.toString(),s=new Set,n=/(['"])((?:\\.|(?!\1).)*?)\1|`((?:\\.|[^`$]|\$(?!\{))*?)`/g,i;for(;(i=n.exec(o))!==null;){let c=i[2]!==void 0?i[2]:i[3];c!==void 0&&c!==""&&s.add(c)}let a=new Set(["END","START","__end__","__start__"]);for(let c of this.nodes.keys())a.add(c);if(e&&typeof e=="object")for(let c of Object.keys(e))a.add(c);let l=new Set;for(let c of s)a.has(c)&&l.add(c);if(l.size===0){let c=/return\s+['"]([^'"]+)['"]/g,u;for(;(u=c.exec(o))!==null;)l.add(u[1])}return[...l]}_flattenJsonSchemaToVariables(t,e=""){let o=t;if(t.$ref&&t.definitions){let s=t.$ref.replace("#/definitions/","");o=t.definitions[s]||t}return this._flattenSchema(o,e)}_flattenSchema(t,e=""){if(!t||typeof t!="object")return[];let o=[],s=t.properties||{},n=t.required||[];for(let[i,a]of Object.entries(s)){let l=e?`${e}.${i}`:i;o.push({path:l,type:a.type||"unknown",label:a.description||this._formatLabel(i),optional:!n.includes(i)}),a.type==="object"&&a.properties&&o.push(...this._flattenSchema(a,l)),a.type==="array"&&a.items?.type==="object"&&a.items.properties&&o.push(...this._flattenSchema(a.items,`${l}[]`))}return o}_formatLabel(t){return t.replace(/([A-Z])/g," $1").replace(/^./,e=>e.toUpperCase()).trim()}_summarizeNodeOutput(t,e){if(!e||typeof e!="object")return[];let o=[];e.success!==void 0&&o.push(`Result: ${e.success?"passed":"failed"}`);for(let[s,n]of Object.entries(e))if(!(s==="success"||s==="raw"||s==="nextNode")){if(typeof n=="string"&&n.length<=80)o.push(`${s}: ${n}`);else if(Array.isArray(n)){let i=n.length,a=n.filter(c=>c?.passed===!0).length,l=n.some(c=>c?.passed!==void 0);o.push(l?`${s}: ${a}/${i} passed${i-a?`, ${i-a} failed`:""}`:`${s}: ${i} items`)}if(o.length>=4)break}return o}async run(t,e={},o={}){if(!this.entryPoint)throw new Error("No entry point set for graph");let s=new AbortController;o.signal&&(o.signal.aborted?s.abort():o.signal.addEventListener("abort",()=>s.abort(),{once:!0}));let n=o.strategyAbortTimeoutMs??e.config?.strategyAbortTimeoutMs??5e3,i=e.cwd||process.cwd();nr({path:G(i,".env")});let a=e.config||{};if(!a||Object.keys(a).length===0)try{let _=G(i,".zibby.config.js");At(_)&&(a=(await import(_)).default||{})}catch{}process.env.EXECUTION_ID&&!a.agent?.strictMode&&(a.agent={...a.agent,strictMode:!0});let l=e.agentType;if(!l){let _=a?.agent;_?.provider?l=_.provider:_?.gemini?l="gemini":_?.claude?l="claude":_?.cursor?l="cursor":_?.codex?l="codex":l=process.env.AGENT_TYPE||"cursor"}let c=e.contextConfig||t?.config?.contextConfig||t?.config?.context||a?.context||{},u=this._runtimeSchema();if(u){let _=u.safeParse(e);if(!_.success){let x=_.error.issues.map(P=>`${P.path.join(".")}: ${P.message}`);throw console.error("\u274C Initial state validation failed:"),x.forEach(P=>console.error(` - ${P}`)),new Error(`State validation failed: ${x.join(", ")}`)}k.step("State validated against schema")}let p=lr(),h=e.sessionPath||p;h||ur();let{sessionPath:m,sessionTimestamp:I,sessionId:b}=hr({cwd:i,config:a,traceFrom:"WorkflowGraph.run",initialState:{sessionPath:h,sessionTimestamp:e.sessionTimestamp}});k.step(`Session ${b}`);let $=await ct.loadContext(e.specPath||"",i,c);Object.keys($).length>0&&k.step(`Context loaded: ${Object.keys($).join(", ")}`);let T=e.outputPath;!T&&e.specPath&&(t?.calculateOutputPath?T=t.calculateOutputPath(e.specPath):console.warn(`\u26A0\uFE0F outputPath not resolved (specPath=${e.specPath})`));let d=new rt({...e,config:a,agentType:l,outputPath:T,sessionPath:m,sessionTimestamp:I,context:$,resolvedTools:this.resolvedToolsMap||{},_signal:s.signal}),y=new Map;try{await import("@zibby/skills")}catch{}let{getSkill:f}=await Promise.resolve().then(()=>(St(),zt)),g=a.skills&&typeof a.skills=="object"?a.skills:{},B=Object.values(g).filter(_=>_&&typeof _=="object"&&typeof _.id=="string"),v=_=>{for(let x of B)if(x.id===_)return x;return f(_)},M=new Set;for(let[,_]of this.nodes)for(let x of _.config?.skills||[])M.add(x);for(let _ of M){let x=v(_);if(typeof x?.middleware=="function")try{let P=await x.middleware();typeof P=="function"&&y.set(_,P)}catch{}}let S=this.entryPoint,X=[],kt=a?.recursionLimit??100,me=0;try{for(;S&&S!=="END";){if(++me>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 x=G(m,Jt);if(At(x)){try{sr(x)}catch{}s.abort()}if(s.signal.aborted)return console.warn(`
|
|
37
|
-
\u{1F6D1} External stop requested \u2014 ending workflow.`),k.step("Workflow stopped externally"),{success:!0,state:d.getAll(),executionLog:
|
|
36
|
+
${p}`)}}function lr(){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 ur(){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 me(String(t).trim())}catch{return String(t).trim()}}function pr(){lr()||(delete process.env.ZIBBY_SESSION_PATH,delete process.env.ZIBBY_SESSION_ID)}function dr({sessionPath:r,sessionId:t}){r&&typeof r=="string"&&(process.env.ZIBBY_SESSION_PATH=r),t!=null&&String(t).trim()!==""&&(process.env.ZIBBY_SESSION_ID=String(t).trim())}function hr(r={}){let t=Zt.map(n=>process.env[n]).find(Boolean),e=Math.random().toString(36).slice(2,6),s=t||`${Date.now()}_${e}`,o=r.paths?.sessionPrefix;return o?`${o}_${s}`:s}function fr({cwd:r=process.cwd(),config:t={},initialState:e={},traceFrom:s="resolveWorkflowSession"}={}){let o=e.sessionPath,n=e.sessionTimestamp,i="initialState.sessionPath";if(!o&&process.env.ZIBBY_SESSION_PATH)try{let u=me(String(process.env.ZIBBY_SESSION_PATH));u&&(o=u,i="ZIBBY_SESSION_PATH")}catch{}let a;if(o)a=String(o).split(/[/\\]/).filter(Boolean).pop(),n==null&&(n=Date.now());else{let u=process.env.ZIBBY_SESSION_ID&&String(process.env.ZIBBY_SESSION_ID).trim();if(u)a=u,i="ZIBBY_SESSION_ID";else{let c=t.sessionId!=null?String(t.sessionId).trim():"";c&&c!=="last"?(a=c,i="config.sessionId"):(a=hr(t),i="generated")}n=n??Date.now();let p=t.paths?.output||at;o=H(r,p,Jt,a)}let l=!kt(o);return l&&ge(o,{recursive:!0}),(l||i!=="initialState.sessionPath")&&cr({traceFrom:s,sessionId:a,sessionPath:o,idSource:i,mkdirFresh:l}),dr({sessionPath:o,sessionId:a}),{sessionPath:o,sessionId:a,sessionTimestamp:n}}var fe=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{return this.inputSchema.merge(this.contextSchema)}catch{}return this.inputSchema&&!this.contextSchema?this.inputSchema:this.stateSchema}addNode(t,e,s={}){if(!(e instanceof L)&&e&&typeof e=="object"&&typeof e.workflow=="string"){let n=e,i={name:t,_isCustomCode:!0,retries:n.retries,onComplete:n.onComplete,execute:async l=>{let u=l?.state&&typeof l.state.getAll=="function"?l.state.getAll():l,p;return typeof n.input=="function"?p=n.input(u):n.input&&typeof n.input=="object"?p=n.input:p={},le(n.workflow,{input:p,async:n.async===!0,conversationId:typeof n.conversationId=="function"?n.conversationId(u):n.conversationId,output:n.output,timeoutMs:n.timeoutMs,pollIntervalMs:n.pollIntervalMs,signal:u?._signal,parentAgent:l?.agent})}},a=new L(i);return a.name=t,this.nodes.set(t,a),s.prompt&&this.nodePrompts.set(t,s.prompt),Object.keys(s).length>0&&this.nodeOptions.set(t,s),this}let o=e instanceof L?e:new L(e);return o.name=t,this.nodes.set(t,o),s.prompt?this.nodePrompts.set(t,s.prompt):typeof e?.prompt=="string"&&e.prompt.trim()&&this.nodePrompts.set(t,e.prompt),Object.keys(s).length>0&&this.nodeOptions.set(t,s),this}addConditionalNode(t,e){return this.nodes.set(t,new X({...e,name:t})),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:s}={}){return this.edges.set(t,{conditional:!0,routes:e,labels:s}),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,s,o,n){let i=s;for(let a=t.length-1;a>=0;a--){let l=t[a],u=i;i=()=>l(e,u,o,n)}return i()}serialize(){let t=[],e={};for(let[p,c]of this.nodes){let g=this.nodeTypeMap.get(p)||(c instanceof X?"decision":p);t.push({id:p,type:g,data:{nodeType:g,label:p}});let h={};c._isCustomCode&&typeof c.execute=="function"&&(h.customCode=c.execute.toString());let E=this.nodePrompts.get(p);if(E)h.prompt=E;else if(typeof c.prompt=="function")try{let y=c.prompt({});typeof y=="string"&&y.trim()&&(h.prompt=y,h.promptIsCode=!0)}catch{}if(typeof c.customExecute=="function"&&(h.executeCode=c.customExecute.toString()),c.outputSchema)if(typeof c.outputSchema._def<"u"){let y=null;if(typeof ut?.toJSONSchema=="function")try{y=ut.toJSONSchema(c.outputSchema)}catch{}if(!y)try{y=he(c.outputSchema,{target:"openApi3"})}catch{}h.outputSchema=y?{jsonSchema:y,variables:this._flattenJsonSchemaToVariables(y)}:{schema:c.outputSchema}}else h.outputSchema={schema:c.outputSchema};let $=(this.resolvedToolsMap||{})[p];$?.toolIds&&(h.tools=$.toolIds);let T=Array.isArray(c?.config?.skills)?c.config.skills:Array.isArray(c?.skills)?c.skills:null;T&&T.length>0&&(h.skills=[...T]),Object.keys(h).length>0&&(e[p]=h)}let s=[];for(let[p,c]of this.edges)if(typeof c=="string")s.push({source:p,target:c});else if(c.conditional){let g=this.conditionalCodeMap.get(p)||c.routes.toString(),h=this._inferConditionalTargets(c.routes,c.labels),E=c.labels||{};for(let $ of h){let T={source:p,target:$,data:{conditionalCode:g}};E[$]&&(T.label=E[$]),s.push(T)}}let o=p=>{if(!p)return null;if(typeof ut?.toJSONSchema=="function")try{return ut.toJSONSchema(p)}catch{}try{return he(p,{target:"openApi3"})}catch{return null}};this.entryPoint&&this.nodes.has(this.entryPoint)&&(t.unshift({id:"START",type:"start",data:{nodeType:"start",label:"Start"}}),s.unshift({source:"START",target:this.entryPoint}));let n=0;for(let p of s)if(p.target==="END"){n+=1;let c=`END__${n}`;p.target=c,t.push({id:c,type:"end",data:{nodeType:"end",label:"End"}})}for(let p of this.nodes.keys())if(!this.edges.has(p)){n+=1;let c=`END__${n}`;t.push({id:c,type:"end",data:{nodeType:"end",label:"End"}}),s.push({source:p,target:c})}let i=this._runtimeSchema(),a=o(i||this.stateSchema),l=o(this.inputSchema),u=o(this.contextSchema);return{nodes:t,edges:s,nodeConfigs:e,stateSchema:a,inputSchema:l,contextSchema:u}}_inferConditionalTargets(t,e){let s=t.toString(),o=new Set,n=/(['"])((?:\\.|(?!\1).)*?)\1|`((?:\\.|[^`$]|\$(?!\{))*?)`/g,i;for(;(i=n.exec(s))!==null;){let u=i[2]!==void 0?i[2]:i[3];u!==void 0&&u!==""&&o.add(u)}let a=new Set(["END","START","__end__","__start__"]);for(let u of this.nodes.keys())a.add(u);if(e&&typeof e=="object")for(let u of Object.keys(e))a.add(u);let l=new Set;for(let u of o)a.has(u)&&l.add(u);if(l.size===0){let u=/return\s+['"]([^'"]+)['"]/g,p;for(;(p=u.exec(s))!==null;)l.add(p[1])}return[...l]}_flattenJsonSchemaToVariables(t,e=""){let s=t;if(t.$ref&&t.definitions){let o=t.$ref.replace("#/definitions/","");s=t.definitions[o]||t}return this._flattenSchema(s,e)}_flattenSchema(t,e=""){if(!t||typeof t!="object")return[];let s=[],o=t.properties||{},n=t.required||[];for(let[i,a]of Object.entries(o)){let l=e?`${e}.${i}`:i;s.push({path:l,type:a.type||"unknown",label:a.description||this._formatLabel(i),optional:!n.includes(i)}),a.type==="object"&&a.properties&&s.push(...this._flattenSchema(a,l)),a.type==="array"&&a.items?.type==="object"&&a.items.properties&&s.push(...this._flattenSchema(a.items,`${l}[]`))}return s}_formatLabel(t){return t.replace(/([A-Z])/g," $1").replace(/^./,e=>e.toUpperCase()).trim()}_summarizeNodeOutput(t,e){if(!e||typeof e!="object")return[];let s=[];e.success!==void 0&&s.push(`Result: ${e.success?"passed":"failed"}`);for(let[o,n]of Object.entries(e))if(!(o==="success"||o==="raw"||o==="nextNode")){if(typeof n=="string"&&n.length<=80)s.push(`${o}: ${n}`);else if(Array.isArray(n)){let i=n.length,a=n.filter(u=>u?.passed===!0).length,l=n.some(u=>u?.passed!==void 0);s.push(l?`${o}: ${a}/${i} passed${i-a?`, ${i-a} failed`:""}`:`${o}: ${i} items`)}if(s.length>=4)break}return s}async run(t,e={},s={}){if(!this.entryPoint)throw new Error("No entry point set for graph");let o=new AbortController;s.signal&&(s.signal.aborted?o.abort():s.signal.addEventListener("abort",()=>o.abort(),{once:!0}));let n=s.strategyAbortTimeoutMs??e.config?.strategyAbortTimeoutMs??5e3,i=e.cwd||process.cwd();ir({path:H(i,".env")});let a=e.config||{};if(!a||Object.keys(a).length===0)try{let _=H(i,".zibby.config.js");kt(_)&&(a=(await import(_)).default||{})}catch{}process.env.EXECUTION_ID&&!a.agent?.strictMode&&(a.agent={...a.agent,strictMode:!0});let l=e.agentType;if(!l){let _=a?.agent;_?.provider?l=_.provider:_?.gemini?l="gemini":_?.claude?l="claude":_?.cursor?l="cursor":_?.codex?l="codex":l=process.env.AGENT_TYPE||"cursor"}let u=e.contextConfig||t?.config?.contextConfig||t?.config?.context||a?.context||{},p=this._runtimeSchema();if(p){let _=p.safeParse(e);if(!_.success){let x=_.error.issues.map(P=>`${P.path.join(".")}: ${P.message}`);throw console.error("\u274C Initial state validation failed:"),x.forEach(P=>console.error(` - ${P}`)),new Error(`State validation failed: ${x.join(", ")}`)}k.step("State validated against schema")}let c=ur(),g=e.sessionPath||c;g||pr();let{sessionPath:h,sessionTimestamp:E,sessionId:$}=fr({cwd:i,config:a,traceFrom:"WorkflowGraph.run",initialState:{sessionPath:g,sessionTimestamp:e.sessionTimestamp}});k.step(`Session ${$}`);let T=await lt.loadContext(e.specPath||"",i,u);Object.keys(T).length>0&&k.step(`Context loaded: ${Object.keys(T).join(", ")}`);let y=e.outputPath;!y&&e.specPath&&(t?.calculateOutputPath?y=t.calculateOutputPath(e.specPath):console.warn(`\u26A0\uFE0F outputPath not resolved (specPath=${e.specPath})`));let d=new ot({...e,config:a,agentType:l,outputPath:y,sessionPath:h,sessionTimestamp:E,context:T,resolvedTools:this.resolvedToolsMap||{},_signal:o.signal}),I=new Map;try{await import("@zibby/skills")}catch{}let{getSkill:f}=await Promise.resolve().then(()=>(wt(),Kt)),m=a.skills&&typeof a.skills=="object"?a.skills:{},B=Object.values(m).filter(_=>_&&typeof _=="object"&&typeof _.id=="string"),v=_=>{for(let x of B)if(x.id===_)return x;return f(_)},M=new Set;for(let[,_]of this.nodes)for(let x of _.config?.skills||[])M.add(x);for(let _ of M){let x=v(_);if(typeof x?.middleware=="function")try{let P=await x.middleware();typeof P=="function"&&I.set(_,P)}catch{}}let S=this.entryPoint,tt=[],Ot=a?.recursionLimit??100,Se=0;try{for(;S&&S!=="END";){if(++Se>Ot)throw new Error(`Workflow exceeded recursion limit (${Ot}) \u2014 likely a cyclic conditional route. Set config.recursionLimit if you need a higher cap.`);let x=H(h,Yt);if(kt(x)){try{nr(x)}catch{}o.abort()}if(o.signal.aborted)return console.warn(`
|
|
37
|
+
\u{1F6D1} External stop requested \u2014 ending workflow.`),k.step("Workflow stopped externally"),{success:!0,state:d.getAll(),executionLog:tt,stoppedExternally:!0};let P=this.nodes.get(S);if(!P)throw new Error(`Node '${S}' not found in graph`);let xt=JSON.stringify({sessionPath:h,sessionTimestamp:E,currentNode:S,createdAt:new Date().toISOString(),config:d.get("config")}),we=H(h,Z);de(we,xt,"utf-8");let Pt=d.get("config")?.paths?.output||at,ye=H(i,Pt,Z);ge(H(i,Pt),{recursive:!0});try{de(ye,xt,"utf-8")}catch{}let Nt=e.onPipelineProgress;if(typeof Nt=="function")try{Nt({cwd:i,sessionPath:h,sessionId:$,outputBase:d.get("config")?.paths?.output||at,currentNode:S})}catch{}let _e=(this.resolvedToolsMap||{})[S]||null;d.set("_currentNodeTools",_e);let Ie=d.get("nodeConfigs")||{};d.set("_currentNodeConfig",Ie[S]||{}),k.nodeStart(S);let Rt=Date.now(),et=this.nodePrompts.get(S);if(!this._invokeAgent){let N=await Promise.resolve().then(()=>(It(),_t));this._invokeAgent=N.invokeAgent}let Ee=this._invokeAgent,pt={},be=P.config?.skills||[];for(let N of be){let R=v(N);if(typeof R?.invokeAgentOptions=="function")try{let b=R.invokeAgentOptions(d.getAll(),{agentType:d.get("agentType"),nodeName:S});b&&typeof b=="object"&&(pt={...pt,...b})}catch(b){console.warn(`[graph] skill '${N}' invokeAgentOptions threw: ${b.message}`)}}let Bt=async(N,R,b={})=>{let C=Ee(N,R,{...pt,...b,signal:o.signal});return C.catch(()=>{}),o.signal.aborted?C:Promise.race([C,new Promise((J,Y)=>{let D=()=>{setTimeout(()=>{let K=new Error(`Strategy ignored AbortSignal \u2014 engine deadman fired after ${n}ms`);K.name="AbortError",Y(K)},n)};o.signal.addEventListener("abort",D,{once:!0})})])},Ct={state:d,invokeAgent:async(N={},R={})=>{let b=R.prompt||"";if(et){let C=this._compiledPrompts.get(S);C||(C=ar.compile(et,{noEscape:!0}),this._compiledPrompts.set(S,C));try{b=C(N)}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(!b)throw new Error(`No prompt template configured for node '${S}' and no prompt provided in options`);return Bt(b,{state:d.getAll(),images:R.images||[]},{model:R.model||d.get("model"),workspace:d.get("workspace"),schema:R.schema,...R,signal:o.signal})},_coreInvokeAgent:Bt,agent:t,nodeId:S,promptTemplate:et,getPromptTemplate:()=>et,...d.getAll()};try{let N=(P.config?.skills||[]).map(D=>I.get(D)).filter(Boolean),R=[...this.middleware,...N],b;R.length>0?b=await this._composeMiddleware(R,S,async()=>P.execute(Ct,d),d.getAll(),d):b=await P.execute(Ct,d);let C=Date.now()-Rt;if(tt.push({node:S,success:b.success,duration:C,timestamp:new Date().toISOString()}),!b.success){if(o.signal.aborted)return k.step("Workflow stopped externally"),{success:!0,state:d.getAll(),executionLog:tt,stoppedExternally:!0};d.append("errors",{node:S,error:b.error});let D=P.config?.retries||0,K=`${S}_retries`,rt=d.getAll()[K]||0;if(rt<D){k.stepInfo(`Retrying (attempt ${rt+1}/${D})`),d.update({[K]:rt+1,[`${S}_raw`]:b.raw});continue}throw k.nodeFailed(S,b.error,{duration:C}),new Error(`Node '${S}' failed after ${rt} attempts: ${b.error}`)}d.update({[S]:b.output});let J=this._summarizeNodeOutput(S,b.output);k.nodeComplete(S,{duration:C,details:J});let Y=this.edges.get(S);if(!Y)S="END";else if(Y.conditional){let D=Y.routes(d.getAll());k.route(S,D),S=D}else S=Y}catch(N){throw k.isInsideNode&&k.nodeFailed(S,N.message,{duration:Date.now()-Rt}),d.set("failed",!0),d.set("failedAt",S),N}}k.graphComplete();let _={success:!0,state:d.getAll(),executionLog:tt};return t&&typeof t.onComplete=="function"&&await t.onComplete(_),_}finally{if(t&&typeof t.cleanup=="function")try{await t.cleanup()}catch(_){console.warn(`[workflow] agent.cleanup() failed: ${_.message}`)}}}};export{fe as WorkflowGraph,pr as clearInheritedSessionEnvForFreshRun,hr as generateWorkflowSessionId,ur as readPinnedSessionPathFromEnv,fr as resolveWorkflowSession,lr as shouldTrustInheritedSessionEnv,dr as syncProcessEnvToSession};
|
package/dist/index.js
CHANGED
|
@@ -1,54 +1,54 @@
|
|
|
1
|
-
var
|
|
1
|
+
var to=Object.defineProperty;var $e=(t=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(t,{get:(e,o)=>(typeof require<"u"?require:e)[o]}):t)(function(t){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+t+'" is not supported')});var ge=(t,e)=>()=>(t&&(e=t(t=0)),e);var tt=(t,e)=>{for(var o in e)to(t,o,{get:e[o],enumerable:!0})};function ro(t){ne.impl={...nt,...t}}var ot,nt,ne,I,F=ge(()=>{ot=()=>{},nt={debug:ot,info:ot,warn:(...t)=>console.warn("[workflow]",...t),error:(...t)=>console.error("[workflow]",...t)},ne={impl:nt};I={debug:(...t)=>ne.impl.debug?.(...t),info:(...t)=>ne.impl.info?.(...t),warn:(...t)=>ne.impl.warn?.(...t),error:(...t)=>ne.impl.error?.(...t)}});var Ne,Oe=ge(()=>{Ne=class{constructor(e,o,n=0){this.name=e,this.description=o,this.priority=n}async invoke(e,o={}){throw new Error(`${this.constructor.name}.invoke() must be implemented`)}canHandle(e){throw new Error(`${this.constructor.name}.canHandle() must be implemented`)}getName(){return this.name}getDescription(){return this.description}getPriority(){return this.priority}}});var St={};tt(St,{clearSkills:()=>mt,getAllSkills:()=>ht,getSkill:()=>q,hasSkill:()=>ft,listSkillIds:()=>gt,registerSkill:()=>pt});function pt(t){if(!t||typeof t.id!="string")throw new Error("Skill definition must include a string id");K.set(t.id,Object.freeze({...t}))}function q(t){return K.get(t)||null}function ft(t){return K.has(t)}function ht(){return new Map(K)}function gt(){return Array.from(K.keys())}function mt(){K.clear()}var Pe,K,ie=ge(()=>{Pe=Symbol.for("@zibby/agent-workflow.skills");globalThis[Pe]||(globalThis[Pe]=new Map);K=globalThis[Pe]});var ae={};tt(ae,{getAgentStrategy:()=>Re,invokeAgent:()=>_t,listStrategies:()=>wt,registerStrategy:()=>yt});function yt(t){if(!t||typeof t.getName!="function"||typeof t.invoke!="function")throw new Error("strategy must implement getName() and invoke() (AgentStrategy shape)");let e=G.findIndex(o=>o.getName()===t.getName());e>=0?G[e]=t:G.push(t)}function wt(){return G.map(t=>t.getName())}function Re(t={}){let{state:e={},preferredAgent:o=null}=t,n=o||e.agentType||process.env.AGENT_TYPE;if(!n){let r=G.map(s=>s.getName()).join(", ")||"none registered";throw new Error(`No agent specified. Set agentType in state or AGENT_TYPE env var. Available: ${r}`)}I.debug(`[workflow] agent selection: requested=${n}`);let i=G.find(r=>r.getName()===n);if(!i){let r=G.map(s=>s.getName()).join(", ")||"none registered";throw new Error(`Unknown agent '${n}'. Available: ${r}`)}if(!i.canHandle(t))throw new Error(`Agent '${n}' is not available in this environment. Check credentials/environment.`);return I.debug(`[workflow] using agent: ${i.getName()}`),i}async function _t(t,e={},o={}){let n=Re(e),i=e.state?.config||o.config||{},r=i.models||{},s=o.nodeName&&r[o.nodeName]||null,a=r.default||null,c=i.agent?.[n.name]?.model||null,l=s||a||c||o.model||null,d={...o,model:l,workspace:e.state?.workspace||o.workspace,schema:o.schema||e.schema,images:o.images||e.images||[],skills:o.skills||e.skills||[],config:i},u=t,p=d.skills||[];if(p.length>0&&!o.skipPromptFragments){let m=p.map(w=>{let E=q(w)?.promptFragment;return typeof E=="function"?E():E}).filter(Boolean);m.length>0&&(u+=`
|
|
2
2
|
|
|
3
3
|
${m.join(`
|
|
4
4
|
|
|
5
|
-
`)}`)}let
|
|
5
|
+
`)}`)}let f=e.state?._currentNodeConfig?.extraPromptInstructions?.trim();return f&&(u+=`
|
|
6
6
|
|
|
7
7
|
\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
|
|
8
8
|
PRIORITY OVERRIDE \u2014 THE FOLLOWING INSTRUCTIONS TAKE PRECEDENCE OVER ALL PREVIOUS CONTENT
|
|
9
9
|
\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
|
|
10
10
|
|
|
11
|
-
${
|
|
12
|
-
`),
|
|
13
|
-
${
|
|
14
|
-
`)}`);return e}},
|
|
11
|
+
${f}
|
|
12
|
+
`),I.debug(`[workflow] prompt length: ${u.length} chars`),n.invoke(u,d)}var Ce,G,X=ge(()=>{Oe();F();ie();Ce=Symbol.for("@zibby/agent-workflow.strategies");globalThis[Ce]||(globalThis[Ce]=[]);G=globalThis[Ce]});var oo=new Set(["__proto__","constructor","prototype"]);function Te(t){if(oo.has(t))throw new Error(`Invalid state key: "${t}"`)}var te=class{constructor(e={}){this._state=Object.create(null),Object.assign(this._state,{messages:[],errors:[],artifacts:{},metadata:{},...e}),this._history=[]}get(e){return this._state[e]}set(e,o){Te(e),this._history.push({...this._state}),this._state[e]=o}update(e){let o=Object.getOwnPropertyNames(e);for(let n of o)Te(n);this._history.push({...this._state});for(let n of o)this._state[n]=e[n]}append(e,o){Te(e),this._history.push({...this._state}),Array.isArray(this._state[e])||(this._state[e]=[]),this._state[e].push(o)}getAll(){return{...this._state}}rollback(){this._history.length>0&&(this._state=this._history.pop())}};import H from"handlebars";var oe=class{constructor(e){this.schema=e}parse(e){let o=e.match(/```json\s*([\s\S]*?)\s*```/);if(o)return this.validate(JSON.parse(o[1]));let n=[e.match(/\{[\s\S]*?\}/),e.match(/\{[\s\S]*\}/)].filter(Boolean).map(i=>i[0]);for(let i of n)try{return this.validate(JSON.parse(i))}catch(r){if(!(r instanceof SyntaxError))throw r}return this.validate({result:e.trim()})}validate(e){let o=[];for(let[n,i]of Object.entries(this.schema)){if(i.required&&!(n in e)&&o.push(`Missing required field: ${n}`),n in e&&i.type){let r=typeof e[n];r!==i.type&&o.push(`Field '${n}' expected ${i.type}, got ${r}`)}if(i.validate&&n in e){let r=i.validate(e[n]);r&&o.push(`Field '${n}': ${r}`)}}if(o.length>0)throw new Error(`Output validation failed:
|
|
13
|
+
${o.join(`
|
|
14
|
+
`)}`);return e}},no={string:(t=!0)=>({type:"string",required:t}),number:(t=!0)=>({type:"number",required:t}),boolean:(t=!0)=>({type:"boolean",required:t}),array:(t=!0)=>({type:"object",required:t,validate:e=>Array.isArray(e)?null:"must be an array"}),enum:(t,e=!0)=>({type:"string",required:e,validate:o=>t.includes(o)?null:`must be one of: ${t.join(", ")}`})};F();import{writeFileSync as Be,readFileSync as It,existsSync as Et,mkdirSync as uo}from"node:fs";import{join as Me,dirname as po}from"node:path";import k from"chalk";var dt="__WORKFLOW_GRAPH_LOG__",re=k.gray("\u2502"),so=k.gray("\u250C"),rt=k.gray("\u2514"),be=k.green("\u25C6"),st=k.hex("#c084fc")("\u25C6"),it=k.hex("#2dd4bf")("\u25C6"),ve=k.red("\u25C6"),at=`${re} `,ct=2;function lt(t){return t<1e3?`${t}ms`:`${(t/1e3).toFixed(1)}s`}function ut(t,e){return(o,n,i)=>{if(typeof o!="string")return t(o,n,i);let r=process.stdout.columns||120,s="";for(let a=0;a<o.length;a++){let c=o[a];e.lineStart&&(s+=at,e.col=ct,e.lineStart=!1),c===`
|
|
15
15
|
`?(s+=c,e.lineStart=!0,e.col=0,e.inEsc=!1):c==="\x1B"?(e.inEsc=!0,s+=c):e.inEsc?(s+=c,(c>="A"&&c<="Z"||c>="a"&&c<="z")&&(e.inEsc=!1)):(e.col++,s+=c,e.col>=r&&(s+=`
|
|
16
|
-
${
|
|
16
|
+
${at}`,e.col=ct))}return t(s,n,i)}}var me=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 e={lineStart:!0,col:0,inEsc:!1},o={lineStart:!0,col:0,inEsc:!1};this._outState=e,this._errState=o,process.stdout.write=ut(this._origStdoutWrite,e),process.stderr.write=ut(this._origStderrWrite,o)}_stopIntercepting(){this._origStdoutWrite&&(this._outState&&!this._outState.lineStart&&this._origStdoutWrite(`
|
|
17
17
|
`),process.stdout.write=this._origStdoutWrite),this._origStderrWrite&&(this._errState&&!this._errState.lineStart&&this._origStderrWrite(`
|
|
18
18
|
`),process.stderr.write=this._origStderrWrite),this._origStdoutWrite=null,this._origStderrWrite=null}_rawWrite(e){(this._origStdoutWrite||process.stdout.write.bind(process.stdout))(`${e}
|
|
19
|
-
`)}_emitGraphLogMarker(e){if(!this._emitWorkflowGraphMarkers)return;let
|
|
20
|
-
`;this._origStdoutWrite?this._origStdoutWrite(
|
|
21
|
-
`),this._outState.lineStart=!0,this._outState.col=0),this._origStdoutWrite(`${e} ${
|
|
22
|
-
`)):process.stdout.write.bind(process.stdout)(`${e} ${
|
|
23
|
-
`)}step(e){this._origStdoutWrite?this._writeDot(be,e):process.stdout.write.bind(process.stdout)(`${
|
|
24
|
-
`)}stepInfo(e){this.step(e)}stepTool(e){this._origStdoutWrite?this._writeDot(
|
|
25
|
-
`)}stepMemory(e){let
|
|
26
|
-
`)}stepFail(e){this._origStdoutWrite?this._writeDot(
|
|
27
|
-
`)}nodeStart(e){this._currentNode=e,this._emitGraphLogMarker({phase:"node_begin",node:e}),this._rawWrite(`${
|
|
28
|
-
|
|
29
|
-
${r}`);let a=n(),c=a.cwd||process.cwd(),u=a.sessionPath;try{if(u){let p=Be(u,W);if(It(p)){let h=JSON.parse(_t(p,"utf-8"));h.currentNode=this.name,Re(p,JSON.stringify(h,null,2),"utf-8")}let l=Be(u,"..",W);if(It(l))try{let h=JSON.parse(_t(l,"utf-8"));h.currentNode=this.name,Re(l,JSON.stringify(h,null,2),"utf-8")}catch{}}}catch(p){_.debug(`[workflow] could not update session info: ${p.message}`)}let d=null;for(let p=0;p<=this.retries;p++)try{_.debug(`[workflow] node '${this.name}' attempt ${p}`);let l=n().config||{},h=l.agents||{},m=this.config.agent??h[this.name]??null,w={state:n()};m&&(w.preferredAgent=m);let I={workspace:c,schema:this.isZodSchema?this.outputSchema:null,skills:this.config.skills||[],sessionPath:u,config:l,nodeName:this.name,timeout:this.config?.timeout||3e5},E=e?._coreInvokeAgent;E||(E=(await Promise.resolve().then(()=>(q(),se))).invokeAgent);let f=await E(r,w,I),$,g;if(typeof f=="string"?($=f,g=null):f.structured?($=f.raw||JSON.stringify(f.structured,null,2),g=f.structured):($=f.raw||JSON.stringify(f,null,2),g=f.extracted||null),u)try{let S=Be(u,this.name,"raw_stream_output.txt");uo(lo(S),{recursive:!0}),Re(S,typeof $=="string"?$:JSON.stringify($),"utf-8")}catch(S){_.debug(`[workflow] could not save raw output: ${S.message}`)}if(this.isZodSchema&&g){_.info(`[workflow] node '${this.name}': output validated: ${JSON.stringify(g,null,2)}`);let S=g;if(typeof this.onComplete=="function")try{S=await this.onComplete(n(),g)}catch(R){_.warn(`[workflow] onComplete hook failed: ${R.message}`)}return{success:!0,output:S,raw:$}}if(typeof this.onComplete=="function")try{return{success:!0,output:await this.onComplete(n(),{raw:$}),raw:$}}catch(S){throw new Error(`onComplete failed: ${S.message}`,{cause:S})}if(this.parser){let S=this.parser.parse($);return _.info(`[workflow] node '${this.name}': parsed output: ${JSON.stringify(S,null,2)}`),x.step("Output parsed"),{success:!0,output:S,raw:$}}return{success:!0,output:$,raw:$}}catch(l){d=l,p<this.retries&&_.info(`[workflow] node '${this.name}' failed, retrying (${p+1}/${this.retries})\u2026`)}return{success:!1,error:d.message,raw:null}}},ie=class extends j{constructor(e){super({...e,_isCustomCode:!0}),this.condition=e.condition}async execute(e,t){let n=t&&typeof t.getAll=="function"?t.getAll():e;return{success:!0,output:{nextNode:this.condition(n)},raw:null}}};F();F();import{mkdirSync as ho,existsSync as H,statSync as kt,readdirSync as At,rmSync as go}from"node:fs";import{spawn as xt}from"node:child_process";import{join as U}from"node:path";import{pathToFileURL as mo}from"node:url";import{AsyncLocalStorage as po}from"node:async_hooks";var Me=new po;function ae(){let o=Me.getStore();return o||Object.freeze({executionId:process.env.EXECUTION_ID||null,parentExecutionId:process.env.PARENT_EXECUTION_ID||null,depth:0,conversationId:process.env.ZIBBY_CONVERSATION_ID||null,dispatchMode:process.env.DISPATCH_MODE||null})}function Et(o,e){let t=Me.getStore()||ae(),n=Object.freeze({executionId:o.executionId,parentExecutionId:o.parentExecutionId??t.executionId??null,depth:(t.depth||0)+(o.executionId!==t.executionId?1:0),conversationId:o.conversationId!==void 0?o.conversationId:t.conversationId??null,dispatchMode:o.dispatchMode??null});return Me.run(n,e)}var De=new Map,Le=new Map,$t=new Map;function bt(o,e,t={}){if(!o||typeof o!="string")throw new Error("subgraph-registry.register: name required");if(typeof e!="function")throw new Error("subgraph-registry.register: factory must be a function");De.set(o,e),Le.set(o,"ready"),$t.set(o,{...t,cachedAt:Date.now()})}function Tt(o,e){Le.set(o,"failed"),$t.set(o,{error:e?.message||String(e),failedAt:Date.now()}),De.delete(o)}function vt(o){return Le.get(o)==="ready"?De.get(o):null}var me=process.env.ZIBBY_SUBGRAPH_CACHE_DIR||"/tmp/zibby/subgraphs";function So(){return`node${(process.versions?.node||"").split(".")[0]||"unknown"}-${process.platform}-${process.arch}`}var A=class extends Error{constructor(e,t){super(`in-process sub-graph fallback: ${e}${t?` (${t})`:""}`),this.fallback=!0,this.reason=e,this.detail=t||null,this.name="SubgraphFallback"}};function wo(){let o=(process.env.SUBGRAPH_INTERNAL_URL||"").replace(/\/$/,""),e=(process.env.PROGRESS_API_URL||"").replace(/\/executions\/?$/,""),t=o||e,n=process.env.PROJECT_ID,i=process.env.PROJECT_API_TOKEN;if(!t||!n||!i)throw new A("env","SUBGRAPH_INTERNAL_URL/PROGRESS_API_URL/PROJECT_ID/PROJECT_API_TOKEN missing");return{apiBase:t,projectId:n,authToken:i}}async function yo({apiBase:o,authToken:e,body:t}){let n;try{n=await fetch(`${o}/internal/subgraph/begin`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:JSON.stringify(t)})}catch(r){throw new A("network",`begin fetch failed: ${r.message}`)}let i=null;try{i=await n.json()}catch{}if(!n.ok){if(n.status===404){let r=new Error(`Sub-graph child '${t.childWorkflowType}' not found in project`);throw r.code="SUBGRAPH_NOT_FOUND",r.status=404,r}if(n.status===429){let r=i?.quotaInfo||{},s=new Error(`Sub-graph blocked by quota (${r.used??"?"}/${r.limit??"?"} on ${r.planId||"plan"})`);throw s.code="SUBGRAPH_QUOTA_EXCEEDED",s.status=429,s.quotaInfo=r,s}if(n.status===400&&i?.validationErrors){let r=new Error(`Sub-graph rejected input: ${i?.error||i?.message||"validation failed"}`);throw r.code="SUBGRAPH_INVALID_INPUT",r.status=400,r.validationErrors=i.validationErrors,r.missing=i.missing,r}throw new A("begin-status",`begin returned ${n.status}`)}return i?.data||i}async function J({apiBase:o,authToken:e,payload:t}){try{let n=await fetch(`${o}/internal/subgraph/finalize`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:JSON.stringify(t)});n.ok||_.warn(`[in-process subgraph] finalize returned ${n.status} for ${t.childExecutionId}`)}catch(n){_.warn(`[in-process subgraph] finalize failed: ${n.message}`)}}async function _o(o,e){let t=U(e,".ready"),n=U(e,"graph.mjs");if(H(t)&&H(n))return;ho(e,{recursive:!0});let i=U(e,".lock"),r=!1;try{let{openSync:s,closeSync:a}=await import("node:fs"),c=s(i,"wx");a(c),r=!0}catch(s){if(s.code!=="EEXIST")throw s}if(!r){let s=Date.now()+3e4;for(;Date.now()<s;){if(H(t)&&H(n))return;await new Promise(a=>setTimeout(a,100))}throw new A("bundle-extract-timeout","sibling extract did not complete within 30s")}try{await new Promise((c,u)=>{let d=xt("curl",["-fsSL",o],{stdio:["ignore","pipe","inherit"]}),p=xt("tar",["-xzf","-","-C",e],{stdio:["pipe","inherit","inherit"]});d.stdout.pipe(p.stdin);let l,h,m=()=>{if(l!==void 0&&h!==void 0){if(l!==0)return u(new Error(`curl exited ${l}`));if(h!==0)return u(new Error(`tar exited ${h}`));c()}};d.on("close",w=>{l=w,m()}),p.on("close",w=>{h=w,m()}),d.on("error",u),p.on("error",u)});let{writeFileSync:s,unlinkSync:a}=await import("node:fs");s(t,"");try{a(i)}catch{}}catch(s){try{let{unlinkSync:a}=await import("node:fs");a(i)}catch{}throw new A("bundle-extract-failed",s.message)}}async function Io(o){let e=U(o,"graph.mjs");if(!H(e))throw new A("entry-missing",`graph.mjs missing under ${o}`);let t;try{t=await import(mo(e).href)}catch(i){throw new A("import-failed",`${i?.code||i?.name||"unknown"}: ${i.message}`)}let n=t.default||Object.values(t).find(i=>typeof i=="function"&&i.prototype?.buildGraph);if(!n)throw new A("entry-class-missing","no buildGraph() class export found");return n}async function Nt(o,e={}){if(!o||typeof o!="string")throw new Error("runInProcessSubgraph: workflowName (string) is required");let t=ae(),n;try{n=wo()}catch(g){throw g}_.debug(`[in-process subgraph] begin '${o}' parent=${t.executionId||"<root>"}`);let i=await yo({apiBase:n.apiBase,authToken:n.authToken,body:{parentExecutionId:t.executionId,childWorkflowType:o,input:e.input||{},...e.conversationId?{conversationId:e.conversationId}:{}}}),{childExecutionId:r,runtimeTag:s,bundlePresignedUrl:a,sourcesPresignedUrl:c,workflowVersion:u,workflowUuid:d,bundleReady:p}=i,l=So();if(s&&s!==l)throw await J({apiBase:n.apiBase,authToken:n.authToken,payload:{childExecutionId:r,status:"canceled",error:{message:`runtimeTag mismatch: parent=${l} child=${s}`,code:"RUNTIME_MISMATCH"}}}),new A("runtime-mismatch",`${l} vs ${s}`);if(!p||!a)throw await J({apiBase:n.apiBase,authToken:n.authToken,payload:{childExecutionId:r,status:"canceled",error:{message:"bundle not ready for in-process; falling back to HTTP",code:"NO_BUNDLE"}}}),new A("no-bundle","workflow bundle not built yet");let h=vt(o);if(!h){let g=U(me,`${d}@${u||"0"}`);try{await _o(a,g);try{$o()}catch{}}catch(S){throw S.fallback&&await J({apiBase:n.apiBase,authToken:n.authToken,payload:{childExecutionId:r,status:"failed",error:{message:S.message,code:S.reason}}}),S}try{h=await Io(g),bt(o,h,{workflowUuid:d,version:u,runtimeTag:s,cacheDir:g})}catch(S){throw Tt(o,S),await J({apiBase:n.apiBase,authToken:n.authToken,payload:{childExecutionId:r,status:"failed",error:{message:S.message,code:S.reason||"IMPORT_FAILED"}}}),S.fallback?S:new A("import-failed",S.message)}}let m=Date.now(),I=await(typeof h=="function"&&h.prototype?.buildGraph?new h:h).buildGraph(),E={...e.input||{}},f,$;try{f=await Et({executionId:r,parentExecutionId:t.executionId,conversationId:e.conversationId!==void 0?e.conversationId:t.conversationId,dispatchMode:"inprocess"},()=>I.run(e.parentAgent,E,{signal:e.signal})),$=f&&typeof f=="object"&&"state"in f?f.state:f}catch(g){throw await J({apiBase:n.apiBase,authToken:n.authToken,payload:{childExecutionId:r,status:"failed",error:{message:g.message,code:g.code||"CHILD_THREW",stack:g.stack},durationMs:Date.now()-m}}),g}if(f&&typeof f=="object"&&f.stoppedExternally){await J({apiBase:n.apiBase,authToken:n.authToken,payload:{childExecutionId:r,status:"canceled",finalState:$,durationMs:Date.now()-m}});let g=new Error(`Sub-graph '${o}' canceled by parent abort`);throw g.code="SUBGRAPH_CANCELED",g.subgraphJobId=r,g}return await J({apiBase:n.apiBase,authToken:n.authToken,payload:{childExecutionId:r,status:"completed",finalState:$,durationMs:Date.now()-m}}),{finalState:$,executionId:r}}function Eo(o){let e=0,t=[o];for(;t.length;){let n=t.pop(),i;try{i=kt(n)}catch{continue}if(i.isDirectory()){let r;try{r=At(n)}catch{continue}for(let s of r)t.push(U(n,s))}else e+=i.size}return e}function $o({cap:o=Number(process.env.ZIBBY_SUBGRAPH_CACHE_CAP_BYTES||2*1024*1024*1024)}={}){try{if(!H(me))return{evicted:0,freedBytes:0};let e=At(me),t=[],n=0;for(let a of e){let c=U(me,a),u;try{u=kt(c)}catch{continue}let d=u.isDirectory()?Eo(c):u.size;n+=d,t.push({name:a,full:c,size:d,mtimeMs:u.mtimeMs})}if(n<=o)return{evicted:0,freedBytes:0,totalBytes:n};t.sort((a,c)=>a.mtimeMs-c.mtimeMs);let i=Math.floor(o*.7),r=0,s=0;for(let a of t){if(n-r<=i)break;if(!H(U(a.full,".lock")))try{go(a.full,{recursive:!0,force:!0}),r+=a.size,s+=1}catch(c){_.debug(`[sub-graph cache] evict skip ${a.name}: ${c.message}`)}}return s>0&&_.info(`[sub-graph cache] evicted ${s} entr(y/ies), freed ${(r/1024/1024).toFixed(1)}MB`),{evicted:s,freedBytes:r,totalBytes:n-r}}catch(e){return _.debug(`[sub-graph cache] evict failed: ${e.message}`),{evicted:0,freedBytes:0}}}var bo=2e3,To=600*1e3,vo=new Set(["completed","failed","canceled","timeout"]);function xo(){let o=process.env.PROGRESS_API_URL;if(!o)throw new Error("Sub-graph dispatch requires PROGRESS_API_URL env var (set automatically on cloud runs). Sub-graphs are not supported in local in-process runs yet \u2014 deploy the parent and child to cloud.");return o.replace(/\/executions\/?$/,"")}function ko(){let o=process.env.PROJECT_ID;if(!o)throw new Error("Sub-graph dispatch requires PROJECT_ID env var.");return o}function Ao(){let o=process.env.PROJECT_API_TOKEN;if(!o)throw new Error("Sub-graph dispatch requires PROJECT_API_TOKEN env var.");return o}function No(){return process.env.EXECUTION_ID||null}function Ot(o,e){return e==null?o:typeof e=="function"?e(o):typeof e=="string"?e.split(".").reduce((t,n)=>t==null?t:t[n],o):o}async function je(o,e={}){if(!o||typeof o!="string")throw new Error("dispatchSubgraph: workflowName (string) is required");let t=ae(),n=Number(process.env.ZIBBY_SUBGRAPH_MAX_DEPTH||10);if((t.depth||0)>=n)throw new Error(`dispatchSubgraph('${o}'): sub-graph depth ${t.depth} reached cap of ${n}. Restructure the graph or raise ZIBBY_SUBGRAPH_MAX_DEPTH.`);if(process.env.ZIBBY_INPROCESS_SUBGRAPH!=="0"&&!e.async)try{_.debug(`[sub-graph] trying in-process for '${o}'`);let{finalState:g}=await Nt(o,{input:e.input,conversationId:e.conversationId,signal:e.signal,parentAgent:e.parentAgent}),S=Ot(g,e.output);return _.info(`[sub-graph] '${o}' completed in-process`),S}catch(g){if(g instanceof A||g?.fallback)_.info(`[sub-graph] in-process fallback for '${o}': ${g.reason||"unknown"} \u2014 using HTTP`);else throw g}let i=xo(),r=ko(),s=Ao(),a=No(),c=`${i}/projects/${encodeURIComponent(r)}/workflows/${encodeURIComponent(o)}/trigger`,u={input:e.input||{},...a?{parentExecutionId:a}:{},...e.conversationId?{conversationId:e.conversationId}:{}};_.info(`[sub-graph] dispatching '${o}' (${e.async?"async":"sync"}) from parent ${a||"<none>"}`);let d=await fetch(c,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${s}`},body:JSON.stringify(u)});if(!d.ok){let g=null,S="";try{g=await d.json(),S=g?.error||g?.message||JSON.stringify(g)}catch{S=await d.text().catch(()=>"")}if(d.status===429){let v=g?.quotaInfo||{},D=new Error(`Sub-graph '${o}' blocked by execution quota (${v.used??"?"}/${v.limit??"?"} on plan ${v.planId||"unknown"}). Sub-workflow runs count toward the same monthly cap as user-triggered runs.`);throw D.code="SUBGRAPH_QUOTA_EXCEEDED",D.status=429,D.subgraph=o,D.quotaInfo=v,D}if(d.status===400){let v=new Error(`Sub-graph '${o}' rejected input: ${S}`);throw v.code="SUBGRAPH_INVALID_INPUT",v.status=400,v.subgraph=o,v.validationErrors=g?.validationErrors||null,v.missing=g?.missing||null,v}let R=new Error(`Sub-graph '${o}' trigger rejected (${d.status}): ${S}`);throw R.code="SUBGRAPH_TRIGGER_FAILED",R.status=d.status,R.subgraph=o,R}let p=await d.json(),l=p?.data?.jobId||p?.jobId;if(!l)throw new Error(`Sub-graph '${o}' trigger returned no jobId: ${JSON.stringify(p).slice(0,200)}`);if(e.async)return _.info(`[sub-graph] async dispatch of '${o}' \u2192 jobId=${l} (not waiting)`),{jobId:l,status:"accepted",workflow:o};let h=Number.isFinite(e.timeoutMs)?e.timeoutMs:To,m=Number.isFinite(e.pollIntervalMs)?e.pollIntervalMs:bo,w=`${i}/executions/${encodeURIComponent(l)}`,I=Date.now()+h,E="accepted",f=0;for(;Date.now()<I;){await new Promise(v=>setTimeout(v,m)),f+=1;let g=await fetch(w,{headers:{Authorization:`Bearer ${s}`}});if(!g.ok){if(g.status>=500){_.warn(`[sub-graph] status poll for ${l} returned ${g.status}, will retry`);continue}throw new Error(`Sub-graph status poll failed for ${l}: ${g.status}`)}let S=await g.json(),R=S?.data||S?.execution||S;if(E=R?.status||E,vo.has(E)){if(E!=="completed"){let y=new Error(`Sub-graph '${o}' (${l}) ended in status '${E}'`);throw y.subgraphJobId=l,y.subgraphStatus=E,y}let v=R?.finalState||R?.state||{},D=Ot(v,e.output);return _.info(`[sub-graph] '${o}' (${l}) completed after ${f} polls`),D}}let $=new Error(`Sub-graph '${o}' (${l}) timed out after ${Math.round(h/1e3)}s (last status: ${E})`);throw $.subgraphJobId=l,$.subgraphStatus=E,$}import{existsSync as Ct,readFileSync as Oo}from"node:fs";import{join as Fe,dirname as Pt}from"node:path";var ce=class{static async loadContext(e,t,n={}){let i={},r=n.filenames||["CONTEXT.md","AGENTS.md"];if(e){let a=Pt(Fe(t,e));for(let c of r){let u=await this.findAndMergeContextFiles(c,a,t);if(u){let d=c.replace(/\.[^.]+$/,"").toLowerCase();i[d]=u}}}let s=n.discovery||{};for(let[a,c]of Object.entries(s))try{let u=Fe(t,c);Ct(u)&&(i[a]=await this.loadFile(u))}catch(u){console.warn(`[workflow] could not load context '${a}' from '${c}': ${u.message}`)}return i}static async findAndMergeContextFiles(e,t,n){let i=[],r=t;for(;r.startsWith(n);){let s=Fe(r,e);if(Ct(s))try{i.unshift(await this.loadFile(s))}catch(c){console.warn(`[workflow] could not load ${e} from ${s}: ${c.message}`)}let a=Pt(r);if(a===r)break;r=a}return i.length===0?null:i.every(s=>typeof s=="string")?i.join(`
|
|
19
|
+
`)}_emitGraphLogMarker(e){if(!this._emitWorkflowGraphMarkers)return;let o=`${dt}${JSON.stringify(e)}
|
|
20
|
+
`;this._origStdoutWrite?this._origStdoutWrite(o):process.stdout.write(o)}_writeDot(e,o){this._origStdoutWrite?(this._outState&&!this._outState.lineStart&&(this._origStdoutWrite(`
|
|
21
|
+
`),this._outState.lineStart=!0,this._outState.col=0),this._origStdoutWrite(`${e} ${o}
|
|
22
|
+
`)):process.stdout.write.bind(process.stdout)(`${e} ${o}
|
|
23
|
+
`)}step(e){this._origStdoutWrite?this._writeDot(be,e):process.stdout.write.bind(process.stdout)(`${re} ${be} ${e}
|
|
24
|
+
`)}stepInfo(e){this.step(e)}stepTool(e){this._origStdoutWrite?this._writeDot(st,e):process.stdout.write.bind(process.stdout)(`${re} ${st} ${e}
|
|
25
|
+
`)}stepMemory(e){let o=k.hex("#2dd4bf")(e);this._origStdoutWrite?this._writeDot(it,o):process.stdout.write.bind(process.stdout)(`${re} ${it} ${o}
|
|
26
|
+
`)}stepFail(e){this._origStdoutWrite?this._writeDot(ve,k.red(e)):process.stdout.write.bind(process.stdout)(`${re} ${ve} ${k.red(e)}
|
|
27
|
+
`)}nodeStart(e){this._currentNode=e,this._emitGraphLogMarker({phase:"node_begin",node:e}),this._rawWrite(`${so} ${e}`),this._startIntercepting()}nodeComplete(e,o={}){this._stopIntercepting();let{duration:n,details:i}=o;if(i)for(let s of i)this._rawWrite(`${be} ${s}`);let r=n?k.dim(` ${lt(n)}`):"";this._rawWrite(`${rt} ${k.green("done")}${r}`),this._emitGraphLogMarker({phase:"node_end",node:e}),this._rawWrite("")}nodeFailed(e,o,n={}){this._stopIntercepting();let{duration:i}=n,r=i?k.dim(` ${lt(i)}`):"";this._rawWrite(`${ve} ${k.red(o)}`),this._rawWrite(`${rt} ${k.red("failed")}${r}`),this._emitGraphLogMarker({phase:"node_end",node:e}),this._rawWrite("")}route(e,o){this._rawWrite(k.dim(` ${e} \u2192 ${o}`)),this._rawWrite("")}graphComplete(){}},x=new me;var se=".zibby/output",xe="sessions",W=".session-info.json",ke=".zibby-stop",io="result.json",ao="raw_stream_output.txt",co="events.json",lo={BROWSER:"browser",JIRA:"jira",GITHUB:"github",GITLAB:"gitlab",FIGMA:"figma",GIT:"git",SLACK:"slack",LARK:"lark",CHAT_NOTIFY:"chat_notify",SENTRY:"sentry",MEMORY:"memory",CHAT_MEMORY:"chat-memory",REVIEW_MEMORY:"review-memory",KV_MEMORY:"kv-memory",RUNNER:"runner",SKILL_INSTALLER:"skill-installer",CORE_TOOLS:"core-tools",WORKFLOW_BUILDER:"workflow-builder",SESSION:"session",OPENAI_BILLING:"openai_billing",ANTHROPIC_BILLING:"anthropic_billing",CURSOR_ADMIN:"cursor_admin",NOTION:"notion",LINEAR:"linear",PLANE:"plane"},Ae=["CI_JOB_ID","GITHUB_RUN_ID","CIRCLE_WORKFLOW_ID","BUILD_ID"];H.helpers.inc||H.registerHelper("inc",t=>Number(t)+1);H.helpers.json||H.registerHelper("json",t=>JSON.stringify(t,null,2));H.helpers.eq||H.registerHelper("eq",(t,e)=>t===e);var j=class{constructor(e){if(this.config=e,this.name=e.name,this.prompt=e.prompt,this.outputSchema=e.outputSchema,!this.outputSchema&&!e._isCustomCode)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=e.outputSchema&&!this.isZodSchema?new oe(e.outputSchema):null,this.retries=e.retries||0,this.onComplete=e.onComplete,this.customExecute=e.execute}async execute(e,o){let n=()=>o&&typeof o.getAll=="function"?o.getAll():e,i=u=>o&&typeof o.get=="function"?o.get(u):e?.[u];if(typeof this.customExecute=="function"){I.debug(`[workflow] node '${this.name}': custom execute (skipping LLM)`);try{let u=await this.customExecute(e);return typeof u=="object"&&u!==null&&u.success===!1?{success:!1,error:u.error||"Node execution failed",raw:u.raw||null}:this.isZodSchema?(I.debug(`[workflow] node '${this.name}': validating output schema`),{success:!0,output:this.outputSchema.parse(u),raw:null}):{success:!0,output:u,raw:null}}catch(u){return I.error(`[workflow] node '${this.name}' failed: ${u.message}`),u.name==="ZodError"&&I.error(`Schema errors: ${JSON.stringify(u.issues||u.errors,null,2)}`),{success:!1,error:u.message,raw:null}}}let r;typeof this.prompt=="function"?r=this.prompt(n()):typeof this.prompt=="string"&&this.prompt.includes("{{")?(this._compiledPrompt||(this._compiledPrompt=H.compile(this.prompt,{noEscape:!0})),r=this._compiledPrompt(n())):r=this.prompt;let s=i("_skillHints");s&&(r=`${s}
|
|
28
|
+
|
|
29
|
+
${r}`);let a=n(),c=a.cwd||process.cwd(),l=a.sessionPath;try{if(l){let u=Me(l,W);if(Et(u)){let f=JSON.parse(It(u,"utf-8"));f.currentNode=this.name,Be(u,JSON.stringify(f,null,2),"utf-8")}let p=Me(l,"..",W);if(Et(p))try{let f=JSON.parse(It(p,"utf-8"));f.currentNode=this.name,Be(p,JSON.stringify(f,null,2),"utf-8")}catch{}}}catch(u){I.debug(`[workflow] could not update session info: ${u.message}`)}let d=null;for(let u=0;u<=this.retries;u++)try{I.debug(`[workflow] node '${this.name}' attempt ${u}`);let p=n().config||{},f=p.agents||{},m=this.config.agent??f[this.name]??null,w={state:n()};m&&(w.preferredAgent=m);let E={workspace:c,schema:this.isZodSchema?this.outputSchema:null,skills:this.config.skills||[],sessionPath:l,config:p,nodeName:this.name,timeout:this.config?.timeout||3e5},S=e?._coreInvokeAgent;S||(S=(await Promise.resolve().then(()=>(X(),ae))).invokeAgent);let h=await S(r,w,E),$,g;if(typeof h=="string"?($=h,g=null):h.structured?($=h.raw||JSON.stringify(h.structured,null,2),g=h.structured):($=h.raw||JSON.stringify(h,null,2),g=h.extracted||null),l)try{let y=Me(l,this.name,"raw_stream_output.txt");uo(po(y),{recursive:!0}),Be(y,typeof $=="string"?$:JSON.stringify($),"utf-8")}catch(y){I.debug(`[workflow] could not save raw output: ${y.message}`)}if(this.isZodSchema&&g){I.info(`[workflow] node '${this.name}': output validated: ${JSON.stringify(g,null,2)}`);let y=g;if(typeof this.onComplete=="function")try{y=await this.onComplete(n(),g)}catch(R){I.warn(`[workflow] onComplete hook failed: ${R.message}`)}return{success:!0,output:y,raw:$}}if(typeof this.onComplete=="function")try{return{success:!0,output:await this.onComplete(n(),{raw:$}),raw:$}}catch(y){throw new Error(`onComplete failed: ${y.message}`,{cause:y})}if(this.parser){let y=this.parser.parse($);return I.info(`[workflow] node '${this.name}': parsed output: ${JSON.stringify(y,null,2)}`),x.step("Output parsed"),{success:!0,output:y,raw:$}}return{success:!0,output:$,raw:$}}catch(p){d=p,u<this.retries&&I.info(`[workflow] node '${this.name}' failed, retrying (${u+1}/${this.retries})\u2026`)}return{success:!1,error:d.message,raw:null}}},Q=class extends j{constructor(e){super({...e,_isCustomCode:!0}),this.condition=e.condition}async execute(e,o){let n=o&&typeof o.getAll=="function"?o.getAll():e;return{success:!0,output:{nextNode:this.condition(n)},raw:null}}};F();F();import{mkdirSync as go,existsSync as Y,statSync as At,readdirSync as Nt,rmSync as mo}from"node:fs";import{spawn as kt}from"node:child_process";import{join as U}from"node:path";import{pathToFileURL as So}from"node:url";import{AsyncLocalStorage as fo}from"node:async_hooks";var De=new fo;function ce(){let t=De.getStore();return t||Object.freeze({executionId:process.env.EXECUTION_ID||null,parentExecutionId:process.env.PARENT_EXECUTION_ID||null,depth:0,conversationId:process.env.ZIBBY_CONVERSATION_ID||null,dispatchMode:process.env.DISPATCH_MODE||null})}function $t(t,e){let o=De.getStore()||ce(),n=Object.freeze({executionId:t.executionId,parentExecutionId:t.parentExecutionId??o.executionId??null,depth:(o.depth||0)+(t.executionId!==o.executionId?1:0),conversationId:t.conversationId!==void 0?t.conversationId:o.conversationId??null,dispatchMode:t.dispatchMode??null});return De.run(n,e)}var Le=new Map,je=new Map,Tt=new Map;function bt(t,e,o={}){if(!t||typeof t!="string")throw new Error("subgraph-registry.register: name required");if(typeof e!="function")throw new Error("subgraph-registry.register: factory must be a function");Le.set(t,e),je.set(t,"ready"),Tt.set(t,{...o,cachedAt:Date.now()})}function vt(t,e){je.set(t,"failed"),Tt.set(t,{error:e?.message||String(e),failedAt:Date.now()}),Le.delete(t)}function xt(t){return je.get(t)==="ready"?Le.get(t):null}var Se=process.env.ZIBBY_SUBGRAPH_CACHE_DIR||"/tmp/zibby/subgraphs";function yo(){return`node${(process.versions?.node||"").split(".")[0]||"unknown"}-${process.platform}-${process.arch}`}var A=class extends Error{constructor(e,o){super(`in-process sub-graph fallback: ${e}${o?` (${o})`:""}`),this.fallback=!0,this.reason=e,this.detail=o||null,this.name="SubgraphFallback"}};function wo(){let t=(process.env.SUBGRAPH_INTERNAL_URL||"").replace(/\/$/,""),e=(process.env.PROGRESS_API_URL||"").replace(/\/executions\/?$/,""),o=t||e,n=process.env.PROJECT_ID,i=process.env.PROJECT_API_TOKEN;if(!o||!n||!i)throw new A("env","SUBGRAPH_INTERNAL_URL/PROGRESS_API_URL/PROJECT_ID/PROJECT_API_TOKEN missing");return{apiBase:o,projectId:n,authToken:i}}async function _o({apiBase:t,authToken:e,body:o}){let n;try{n=await fetch(`${t}/internal/subgraph/begin`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:JSON.stringify(o)})}catch(r){throw new A("network",`begin fetch failed: ${r.message}`)}let i=null;try{i=await n.json()}catch{}if(!n.ok){if(n.status===404){let r=new Error(`Sub-graph child '${o.childWorkflowType}' not found in project`);throw r.code="SUBGRAPH_NOT_FOUND",r.status=404,r}if(n.status===429){let r=i?.quotaInfo||{},s=new Error(`Sub-graph blocked by quota (${r.used??"?"}/${r.limit??"?"} on ${r.planId||"plan"})`);throw s.code="SUBGRAPH_QUOTA_EXCEEDED",s.status=429,s.quotaInfo=r,s}if(n.status===400&&i?.validationErrors){let r=new Error(`Sub-graph rejected input: ${i?.error||i?.message||"validation failed"}`);throw r.code="SUBGRAPH_INVALID_INPUT",r.status=400,r.validationErrors=i.validationErrors,r.missing=i.missing,r}throw new A("begin-status",`begin returned ${n.status}`)}return i?.data||i}async function J({apiBase:t,authToken:e,payload:o}){try{let n=await fetch(`${t}/internal/subgraph/finalize`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:JSON.stringify(o)});n.ok||I.warn(`[in-process subgraph] finalize returned ${n.status} for ${o.childExecutionId}`)}catch(n){I.warn(`[in-process subgraph] finalize failed: ${n.message}`)}}async function Io(t,e){let o=U(e,".ready"),n=U(e,"graph.mjs");if(Y(o)&&Y(n))return;go(e,{recursive:!0});let i=U(e,".lock"),r=!1;try{let{openSync:s,closeSync:a}=await import("node:fs"),c=s(i,"wx");a(c),r=!0}catch(s){if(s.code!=="EEXIST")throw s}if(!r){let s=Date.now()+3e4;for(;Date.now()<s;){if(Y(o)&&Y(n))return;await new Promise(a=>setTimeout(a,100))}throw new A("bundle-extract-timeout","sibling extract did not complete within 30s")}try{await new Promise((c,l)=>{let d=kt("curl",["-fsSL",t],{stdio:["ignore","pipe","inherit"]}),u=kt("tar",["-xzf","-","-C",e],{stdio:["pipe","inherit","inherit"]});d.stdout.pipe(u.stdin);let p,f,m=()=>{if(p!==void 0&&f!==void 0){if(p!==0)return l(new Error(`curl exited ${p}`));if(f!==0)return l(new Error(`tar exited ${f}`));c()}};d.on("close",w=>{p=w,m()}),u.on("close",w=>{f=w,m()}),d.on("error",l),u.on("error",l)});let{writeFileSync:s,unlinkSync:a}=await import("node:fs");s(o,"");try{a(i)}catch{}}catch(s){try{let{unlinkSync:a}=await import("node:fs");a(i)}catch{}throw new A("bundle-extract-failed",s.message)}}async function Eo(t){let e=U(t,"graph.mjs");if(!Y(e))throw new A("entry-missing",`graph.mjs missing under ${t}`);let o;try{o=await import(So(e).href)}catch(i){throw new A("import-failed",`${i?.code||i?.name||"unknown"}: ${i.message}`)}let n=o.default||Object.values(o).find(i=>typeof i=="function"&&i.prototype?.buildGraph);if(!n)throw new A("entry-class-missing","no buildGraph() class export found");return n}async function Ot(t,e={}){if(!t||typeof t!="string")throw new Error("runInProcessSubgraph: workflowName (string) is required");let o=ce(),n;try{n=wo()}catch(g){throw g}I.debug(`[in-process subgraph] begin '${t}' parent=${o.executionId||"<root>"}`);let i=await _o({apiBase:n.apiBase,authToken:n.authToken,body:{parentExecutionId:o.executionId,childWorkflowType:t,input:e.input||{},...e.conversationId?{conversationId:e.conversationId}:{}}}),{childExecutionId:r,runtimeTag:s,bundlePresignedUrl:a,sourcesPresignedUrl:c,workflowVersion:l,workflowUuid:d,bundleReady:u}=i,p=yo();if(s&&s!==p)throw await J({apiBase:n.apiBase,authToken:n.authToken,payload:{childExecutionId:r,status:"canceled",error:{message:`runtimeTag mismatch: parent=${p} child=${s}`,code:"RUNTIME_MISMATCH"}}}),new A("runtime-mismatch",`${p} vs ${s}`);if(!u||!a)throw await J({apiBase:n.apiBase,authToken:n.authToken,payload:{childExecutionId:r,status:"canceled",error:{message:"bundle not ready for in-process; falling back to HTTP",code:"NO_BUNDLE"}}}),new A("no-bundle","workflow bundle not built yet");let f=xt(t);if(!f){let g=U(Se,`${d}@${l||"0"}`);try{await Io(a,g);try{To()}catch{}}catch(y){throw y.fallback&&await J({apiBase:n.apiBase,authToken:n.authToken,payload:{childExecutionId:r,status:"failed",error:{message:y.message,code:y.reason}}}),y}try{f=await Eo(g),bt(t,f,{workflowUuid:d,version:l,runtimeTag:s,cacheDir:g})}catch(y){throw vt(t,y),await J({apiBase:n.apiBase,authToken:n.authToken,payload:{childExecutionId:r,status:"failed",error:{message:y.message,code:y.reason||"IMPORT_FAILED"}}}),y.fallback?y:new A("import-failed",y.message)}}let m=Date.now(),E=await(typeof f=="function"&&f.prototype?.buildGraph?new f:f).buildGraph(),S={...e.input||{}},h,$;try{h=await $t({executionId:r,parentExecutionId:o.executionId,conversationId:e.conversationId!==void 0?e.conversationId:o.conversationId,dispatchMode:"inprocess"},()=>E.run(e.parentAgent,S,{signal:e.signal})),$=h&&typeof h=="object"&&"state"in h?h.state:h}catch(g){throw await J({apiBase:n.apiBase,authToken:n.authToken,payload:{childExecutionId:r,status:"failed",error:{message:g.message,code:g.code||"CHILD_THREW",stack:g.stack},durationMs:Date.now()-m}}),g}if(h&&typeof h=="object"&&h.stoppedExternally){await J({apiBase:n.apiBase,authToken:n.authToken,payload:{childExecutionId:r,status:"canceled",finalState:$,durationMs:Date.now()-m}});let g=new Error(`Sub-graph '${t}' canceled by parent abort`);throw g.code="SUBGRAPH_CANCELED",g.subgraphJobId=r,g}return await J({apiBase:n.apiBase,authToken:n.authToken,payload:{childExecutionId:r,status:"completed",finalState:$,durationMs:Date.now()-m}}),{finalState:$,executionId:r}}function $o(t){let e=0,o=[t];for(;o.length;){let n=o.pop(),i;try{i=At(n)}catch{continue}if(i.isDirectory()){let r;try{r=Nt(n)}catch{continue}for(let s of r)o.push(U(n,s))}else e+=i.size}return e}function To({cap:t=Number(process.env.ZIBBY_SUBGRAPH_CACHE_CAP_BYTES||2*1024*1024*1024)}={}){try{if(!Y(Se))return{evicted:0,freedBytes:0};let e=Nt(Se),o=[],n=0;for(let a of e){let c=U(Se,a),l;try{l=At(c)}catch{continue}let d=l.isDirectory()?$o(c):l.size;n+=d,o.push({name:a,full:c,size:d,mtimeMs:l.mtimeMs})}if(n<=t)return{evicted:0,freedBytes:0,totalBytes:n};o.sort((a,c)=>a.mtimeMs-c.mtimeMs);let i=Math.floor(t*.7),r=0,s=0;for(let a of o){if(n-r<=i)break;if(!Y(U(a.full,".lock")))try{mo(a.full,{recursive:!0,force:!0}),r+=a.size,s+=1}catch(c){I.debug(`[sub-graph cache] evict skip ${a.name}: ${c.message}`)}}return s>0&&I.info(`[sub-graph cache] evicted ${s} entr(y/ies), freed ${(r/1024/1024).toFixed(1)}MB`),{evicted:s,freedBytes:r,totalBytes:n-r}}catch(e){return I.debug(`[sub-graph cache] evict failed: ${e.message}`),{evicted:0,freedBytes:0}}}var bo=2e3,vo=600*1e3,xo=new Set(["completed","failed","canceled","timeout"]);function ko(){let t=process.env.PROGRESS_API_URL;if(!t)throw new Error("Sub-graph dispatch requires PROGRESS_API_URL env var (set automatically on cloud runs). Sub-graphs are not supported in local in-process runs yet \u2014 deploy the parent and child to cloud.");return t.replace(/\/executions\/?$/,"")}function Ao(){let t=process.env.PROJECT_ID;if(!t)throw new Error("Sub-graph dispatch requires PROJECT_ID env var.");return t}function No(){let t=process.env.PROJECT_API_TOKEN;if(!t)throw new Error("Sub-graph dispatch requires PROJECT_API_TOKEN env var.");return t}function Oo(){return process.env.EXECUTION_ID||null}function Pt(t,e){return e==null?t:typeof e=="function"?e(t):typeof e=="string"?e.split(".").reduce((o,n)=>o==null?o:o[n],t):t}async function Fe(t,e={}){if(!t||typeof t!="string")throw new Error("dispatchSubgraph: workflowName (string) is required");let o=ce(),n=Number(process.env.ZIBBY_SUBGRAPH_MAX_DEPTH||10);if((o.depth||0)>=n)throw new Error(`dispatchSubgraph('${t}'): sub-graph depth ${o.depth} reached cap of ${n}. Restructure the graph or raise ZIBBY_SUBGRAPH_MAX_DEPTH.`);if(process.env.ZIBBY_INPROCESS_SUBGRAPH!=="0"&&!e.async)try{I.debug(`[sub-graph] trying in-process for '${t}'`);let{finalState:g}=await Ot(t,{input:e.input,conversationId:e.conversationId,signal:e.signal,parentAgent:e.parentAgent}),y=Pt(g,e.output);return I.info(`[sub-graph] '${t}' completed in-process`),y}catch(g){if(g instanceof A||g?.fallback)I.info(`[sub-graph] in-process fallback for '${t}': ${g.reason||"unknown"} \u2014 using HTTP`);else throw g}let i=ko(),r=Ao(),s=No(),a=Oo(),c=`${i}/projects/${encodeURIComponent(r)}/workflows/${encodeURIComponent(t)}/trigger`,l={input:e.input||{},...a?{parentExecutionId:a}:{},...e.conversationId?{conversationId:e.conversationId}:{}};I.info(`[sub-graph] dispatching '${t}' (${e.async?"async":"sync"}) from parent ${a||"<none>"}`);let d=await fetch(c,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${s}`},body:JSON.stringify(l)});if(!d.ok){let g=null,y="";try{g=await d.json(),y=g?.error||g?.message||JSON.stringify(g)}catch{y=await d.text().catch(()=>"")}if(d.status===429){let v=g?.quotaInfo||{},D=new Error(`Sub-graph '${t}' blocked by execution quota (${v.used??"?"}/${v.limit??"?"} on plan ${v.planId||"unknown"}). Sub-workflow runs count toward the same monthly cap as user-triggered runs.`);throw D.code="SUBGRAPH_QUOTA_EXCEEDED",D.status=429,D.subgraph=t,D.quotaInfo=v,D}if(d.status===400){let v=new Error(`Sub-graph '${t}' rejected input: ${y}`);throw v.code="SUBGRAPH_INVALID_INPUT",v.status=400,v.subgraph=t,v.validationErrors=g?.validationErrors||null,v.missing=g?.missing||null,v}let R=new Error(`Sub-graph '${t}' trigger rejected (${d.status}): ${y}`);throw R.code="SUBGRAPH_TRIGGER_FAILED",R.status=d.status,R.subgraph=t,R}let u=await d.json(),p=u?.data?.jobId||u?.jobId;if(!p)throw new Error(`Sub-graph '${t}' trigger returned no jobId: ${JSON.stringify(u).slice(0,200)}`);if(e.async)return I.info(`[sub-graph] async dispatch of '${t}' \u2192 jobId=${p} (not waiting)`),{jobId:p,status:"accepted",workflow:t};let f=Number.isFinite(e.timeoutMs)?e.timeoutMs:vo,m=Number.isFinite(e.pollIntervalMs)?e.pollIntervalMs:bo,w=`${i}/executions/${encodeURIComponent(p)}`,E=Date.now()+f,S="accepted",h=0;for(;Date.now()<E;){await new Promise(v=>setTimeout(v,m)),h+=1;let g=await fetch(w,{headers:{Authorization:`Bearer ${s}`}});if(!g.ok){if(g.status>=500){I.warn(`[sub-graph] status poll for ${p} returned ${g.status}, will retry`);continue}throw new Error(`Sub-graph status poll failed for ${p}: ${g.status}`)}let y=await g.json(),R=y?.data||y?.execution||y;if(S=R?.status||S,xo.has(S)){if(S!=="completed"){let _=new Error(`Sub-graph '${t}' (${p}) ended in status '${S}'`);throw _.subgraphJobId=p,_.subgraphStatus=S,_}let v=R?.finalState||R?.state||{},D=Pt(v,e.output);return I.info(`[sub-graph] '${t}' (${p}) completed after ${h} polls`),D}}let $=new Error(`Sub-graph '${t}' (${p}) timed out after ${Math.round(f/1e3)}s (last status: ${S})`);throw $.subgraphJobId=p,$.subgraphStatus=S,$}import{existsSync as Ct,readFileSync as Po}from"node:fs";import{join as Ue,dirname as Rt}from"node:path";var le=class{static async loadContext(e,o,n={}){let i={},r=n.filenames||["CONTEXT.md","AGENTS.md"];if(e){let a=Rt(Ue(o,e));for(let c of r){let l=await this.findAndMergeContextFiles(c,a,o);if(l){let d=c.replace(/\.[^.]+$/,"").toLowerCase();i[d]=l}}}let s=n.discovery||{};for(let[a,c]of Object.entries(s))try{let l=Ue(o,c);Ct(l)&&(i[a]=await this.loadFile(l))}catch(l){console.warn(`[workflow] could not load context '${a}' from '${c}': ${l.message}`)}return i}static async findAndMergeContextFiles(e,o,n){let i=[],r=o;for(;r.startsWith(n);){let s=Ue(r,e);if(Ct(s))try{i.unshift(await this.loadFile(s))}catch(c){console.warn(`[workflow] could not load ${e} from ${s}: ${c.message}`)}let a=Rt(r);if(a===r)break;r=a}return i.length===0?null:i.every(s=>typeof s=="string")?i.join(`
|
|
30
30
|
|
|
31
31
|
---
|
|
32
32
|
|
|
33
|
-
`):i.every(s=>typeof s=="object")?Object.assign({},...i):i[i.length-1]}static async loadFile(e){let
|
|
33
|
+
`):i.every(s=>typeof s=="object")?Object.assign({},...i):i[i.length-1]}static async loadFile(e){let o=Po(e,"utf-8");if(e.endsWith(".json"))return JSON.parse(o);if(e.endsWith(".js")||e.endsWith(".mjs")){let{pathToFileURL:n}=await import("url"),i=await import(n(e).href);return i.default||i}return o}};import{mkdirSync as Dt,existsSync as We,writeFileSync as Bt,unlinkSync as Co}from"node:fs";import{join as z,resolve as Lt}from"node:path";import{config as Ro}from"dotenv";import{zodToJsonSchema as Mt}from"zod-to-json-schema";import{z as ye}from"zod";import Bo from"handlebars";function Mo({traceFrom:t,sessionId:e,sessionPath:o,idSource:n,mkdirFresh:i}){if(!(process.env.ZIBBY_SESSION_LOG==="1"||process.env.ZIBBY_SESSION_LOG==="true"))return;let s=typeof process.ppid=="number"?process.ppid:"n/a",a=`[zibby:session] from=${t} pid=${process.pid} ppid=${s} sessionId=${e} source=${n} mkdir=${i?"yes":"no"} path=${o}`;if(console.log(a),process.env.ZIBBY_TRACE_SESSION==="1"||process.env.ZIBBY_TRACE_SESSION==="true"){let d=(new Error("session trace").stack||"").split(`
|
|
34
34
|
`).slice(2,14).join(`
|
|
35
|
-
`);console.log(`[zibby:session] stack (${
|
|
36
|
-
${d}`)}}function Lt(){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 jt(){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 Dt(String(e).trim())}catch{return String(e).trim()}}function Ft(){Lt()||(delete process.env.ZIBBY_SESSION_PATH,delete process.env.ZIBBY_SESSION_ID)}function Ut({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 Wt(o={}){let e=ke.map(r=>process.env[r]).find(Boolean),t=Math.random().toString(36).slice(2,6),n=e||`${Date.now()}_${t}`,i=o.paths?.sessionPrefix;return i?`${i}_${n}`:n}function Gt({cwd:o=process.cwd(),config:e={},initialState:t={},traceFrom:n="resolveWorkflowSession"}={}){let i=t.sessionPath,r=t.sessionTimestamp,s="initialState.sessionPath";if(!i&&process.env.ZIBBY_SESSION_PATH)try{let u=Dt(String(process.env.ZIBBY_SESSION_PATH));u&&(i=u,s="ZIBBY_SESSION_PATH")}catch{}let a;if(i)a=String(i).split(/[/\\]/).filter(Boolean).pop(),r==null&&(r=Date.now());else{let u=process.env.ZIBBY_SESSION_ID&&String(process.env.ZIBBY_SESSION_ID).trim();if(u)a=u,s="ZIBBY_SESSION_ID";else{let p=e.sessionId!=null?String(e.sessionId).trim():"";p&&p!=="last"?(a=p,s="config.sessionId"):(a=Wt(e),s="generated")}r=r??Date.now();let d=e.paths?.output||ne;i=Y(o,d,ve,a)}let c=!Ue(i);return c&&Mt(i,{recursive:!0}),(c||s!=="initialState.sessionPath")&&Bo({traceFrom:n,sessionId:a,sessionPath:i,idSource:s,mkdirFresh:c}),Ut({sessionPath:i,sessionId:a}),{sessionPath:i,sessionId:a,sessionTimestamp:r}}var ue=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{return this.inputSchema.merge(this.contextSchema)}catch{}return this.inputSchema&&!this.contextSchema?this.inputSchema:this.stateSchema}addNode(e,t,n={}){if(!(t instanceof j)&&t&&typeof t=="object"&&typeof t.workflow=="string"){let r=t,s={name:e,_isCustomCode:!0,retries:r.retries,onComplete:r.onComplete,execute:async c=>{let u=c?.state&&typeof c.state.getAll=="function"?c.state.getAll():c,d;return typeof r.input=="function"?d=r.input(u):r.input&&typeof r.input=="object"?d=r.input:d={},je(r.workflow,{input:d,async:r.async===!0,conversationId:typeof r.conversationId=="function"?r.conversationId(u):r.conversationId,output:r.output,timeoutMs:r.timeoutMs,pollIntervalMs:r.pollIntervalMs,signal:u?._signal,parentAgent:c?.agent})}},a=new j(s);return a.name=e,this.nodes.set(e,a),n.prompt&&this.nodePrompts.set(e,n.prompt),Object.keys(n).length>0&&this.nodeOptions.set(e,n),this}let i=t instanceof j?t:new j(t);return i.name=e,this.nodes.set(e,i),n.prompt&&this.nodePrompts.set(e,n.prompt),Object.keys(n).length>0&&this.nodeOptions.set(e,n),this}addConditionalNode(e,t){return this.nodes.set(e,new ie({...t,name:e})),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:n}={}){return this.edges.set(e,{conditional:!0,routes:t,labels:n}),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,n,i,r){let s=n;for(let a=e.length-1;a>=0;a--){let c=e[a],u=s;s=()=>c(t,u,i,r)}return s()}serialize(){let e=[],t={};for(let[u,d]of this.nodes){let p=this.nodeTypeMap.get(u)||u;e.push({id:u,type:p,data:{nodeType:p,label:u}});let l={};d._isCustomCode&&typeof d.execute=="function"&&(l.customCode=d.execute.toString());let h=this.nodePrompts.get(u);if(h&&(l.prompt=h),typeof d.customExecute=="function"&&(l.executeCode=d.customExecute.toString()),d.outputSchema)if(typeof d.outputSchema._def<"u"){let I=null;if(typeof Se?.toJSONSchema=="function")try{I=Se.toJSONSchema(d.outputSchema)}catch{}if(!I)try{I=Bt(d.outputSchema,{target:"openApi3"})}catch{}l.outputSchema=I?{jsonSchema:I,variables:this._flattenJsonSchemaToVariables(I)}:{schema:d.outputSchema}}else l.outputSchema={schema:d.outputSchema};let m=(this.resolvedToolsMap||{})[u];m?.toolIds&&(l.tools=m.toolIds);let w=Array.isArray(d?.config?.skills)?d.config.skills:Array.isArray(d?.skills)?d.skills:null;w&&w.length>0&&(l.skills=[...w]),Object.keys(l).length>0&&(t[u]=l)}let n=[];for(let[u,d]of this.edges)if(typeof d=="string")n.push({source:u,target:d});else if(d.conditional){let p=this.conditionalCodeMap.get(u)||d.routes.toString(),l=this._inferConditionalTargets(d.routes,d.labels),h=d.labels||{};for(let m of l){let w={source:u,target:m,data:{conditionalCode:p}};h[m]&&(w.label=h[m]),n.push(w)}}let i=u=>{if(!u)return null;if(typeof Se?.toJSONSchema=="function")try{return Se.toJSONSchema(u)}catch{}try{return Bt(u,{target:"openApi3"})}catch{return null}},r=this._runtimeSchema(),s=i(r||this.stateSchema),a=i(this.inputSchema),c=i(this.contextSchema);return{nodes:e,edges:n,nodeConfigs:t,stateSchema:s,inputSchema:a,contextSchema:c}}_inferConditionalTargets(e,t){let n=e.toString(),i=new Set,r=/(['"])((?:\\.|(?!\1).)*?)\1|`((?:\\.|[^`$]|\$(?!\{))*?)`/g,s;for(;(s=r.exec(n))!==null;){let u=s[2]!==void 0?s[2]:s[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 c=new Set;for(let u of i)a.has(u)&&c.add(u);if(c.size===0){let u=/return\s+['"]([^'"]+)['"]/g,d;for(;(d=u.exec(n))!==null;)c.add(d[1])}return[...c]}_flattenJsonSchemaToVariables(e,t=""){let n=e;if(e.$ref&&e.definitions){let i=e.$ref.replace("#/definitions/","");n=e.definitions[i]||e}return this._flattenSchema(n,t)}_flattenSchema(e,t=""){if(!e||typeof e!="object")return[];let n=[],i=e.properties||{},r=e.required||[];for(let[s,a]of Object.entries(i)){let c=t?`${t}.${s}`:s;n.push({path:c,type:a.type||"unknown",label:a.description||this._formatLabel(s),optional:!r.includes(s)}),a.type==="object"&&a.properties&&n.push(...this._flattenSchema(a,c)),a.type==="array"&&a.items?.type==="object"&&a.items.properties&&n.push(...this._flattenSchema(a.items,`${c}[]`))}return n}_formatLabel(e){return e.replace(/([A-Z])/g," $1").replace(/^./,t=>t.toUpperCase()).trim()}_summarizeNodeOutput(e,t){if(!t||typeof t!="object")return[];let n=[];t.success!==void 0&&n.push(`Result: ${t.success?"passed":"failed"}`);for(let[i,r]of Object.entries(t))if(!(i==="success"||i==="raw"||i==="nextNode")){if(typeof r=="string"&&r.length<=80)n.push(`${i}: ${r}`);else if(Array.isArray(r)){let s=r.length,a=r.filter(u=>u?.passed===!0).length,c=r.some(u=>u?.passed!==void 0);n.push(c?`${i}: ${a}/${s} passed${s-a?`, ${s-a} failed`:""}`:`${i}: ${s} items`)}if(n.length>=4)break}return n}async run(e,t={},n={}){if(!this.entryPoint)throw new Error("No entry point set for graph");let i=new AbortController;n.signal&&(n.signal.aborted?i.abort():n.signal.addEventListener("abort",()=>i.abort(),{once:!0}));let r=n.strategyAbortTimeoutMs??t.config?.strategyAbortTimeoutMs??5e3,s=t.cwd||process.cwd();Po({path:Y(s,".env")});let a=t.config||{};if(!a||Object.keys(a).length===0)try{let b=Y(s,".zibby.config.js");Ue(b)&&(a=(await import(b)).default||{})}catch{}process.env.EXECUTION_ID&&!a.agent?.strictMode&&(a.agent={...a.agent,strictMode:!0});let c=t.agentType;if(!c){let b=a?.agent;b?.provider?c=b.provider:b?.gemini?c="gemini":b?.claude?c="claude":b?.cursor?c="cursor":b?.codex?c="codex":c=process.env.AGENT_TYPE||"cursor"}let u=t.contextConfig||e?.config?.contextConfig||e?.config?.context||a?.context||{},d=this._runtimeSchema();if(d){let b=d.safeParse(t);if(!b.success){let N=b.error.issues.map(O=>`${O.path.join(".")}: ${O.message}`);throw console.error("\u274C Initial state validation failed:"),N.forEach(O=>console.error(` - ${O}`)),new Error(`State validation failed: ${N.join(", ")}`)}x.step("State validated against schema")}let p=jt(),l=t.sessionPath||p;l||Ft();let{sessionPath:h,sessionTimestamp:m,sessionId:w}=Gt({cwd:s,config:a,traceFrom:"WorkflowGraph.run",initialState:{sessionPath:l,sessionTimestamp:t.sessionTimestamp}});x.step(`Session ${w}`);let I=await ce.loadContext(t.specPath||"",s,u);Object.keys(I).length>0&&x.step(`Context loaded: ${Object.keys(I).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 f=new Q({...t,config:a,agentType:c,outputPath:E,sessionPath:h,sessionTimestamp:m,context:I,resolvedTools:this.resolvedToolsMap||{},_signal:i.signal}),$=new Map;try{await import("@zibby/skills")}catch{}let{getSkill:g}=await Promise.resolve().then(()=>(re(),mt)),S=a.skills&&typeof a.skills=="object"?a.skills:{},R=Object.values(S).filter(b=>b&&typeof b=="object"&&typeof b.id=="string"),v=b=>{for(let N of R)if(N.id===b)return N;return g(b)},D=new Set;for(let[,b]of this.nodes)for(let N of b.config?.skills||[])D.add(N);for(let b of D){let N=v(b);if(typeof N?.middleware=="function")try{let O=await N.middleware();typeof O=="function"&&$.set(b,O)}catch{}}let y=this.entryPoint,de=[],ze=a?.recursionLimit??100,zt=0;try{for(;y&&y!=="END";){if(++zt>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 N=Y(h,xe);if(Ue(N)){try{Co(N)}catch{}i.abort()}if(i.signal.aborted)return console.warn(`
|
|
37
|
-
\u{1F6D1} External stop requested \u2014 ending workflow.`),x.step("Workflow stopped externally"),{success:!0,state:
|
|
38
|
-
${d}`),a.includes(".")||s.add(c)}return r.length===0?
|
|
35
|
+
`);console.log(`[zibby:session] stack (${t}):
|
|
36
|
+
${d}`)}}function jt(){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 Ft(){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 Lt(String(e).trim())}catch{return String(e).trim()}}function Ut(){jt()||(delete process.env.ZIBBY_SESSION_PATH,delete process.env.ZIBBY_SESSION_ID)}function Wt({sessionPath:t,sessionId:e}){t&&typeof t=="string"&&(process.env.ZIBBY_SESSION_PATH=t),e!=null&&String(e).trim()!==""&&(process.env.ZIBBY_SESSION_ID=String(e).trim())}function Gt(t={}){let e=Ae.map(r=>process.env[r]).find(Boolean),o=Math.random().toString(36).slice(2,6),n=e||`${Date.now()}_${o}`,i=t.paths?.sessionPrefix;return i?`${i}_${n}`:n}function Ht({cwd:t=process.cwd(),config:e={},initialState:o={},traceFrom:n="resolveWorkflowSession"}={}){let i=o.sessionPath,r=o.sessionTimestamp,s="initialState.sessionPath";if(!i&&process.env.ZIBBY_SESSION_PATH)try{let l=Lt(String(process.env.ZIBBY_SESSION_PATH));l&&(i=l,s="ZIBBY_SESSION_PATH")}catch{}let a;if(i)a=String(i).split(/[/\\]/).filter(Boolean).pop(),r==null&&(r=Date.now());else{let l=process.env.ZIBBY_SESSION_ID&&String(process.env.ZIBBY_SESSION_ID).trim();if(l)a=l,s="ZIBBY_SESSION_ID";else{let u=e.sessionId!=null?String(e.sessionId).trim():"";u&&u!=="last"?(a=u,s="config.sessionId"):(a=Gt(e),s="generated")}r=r??Date.now();let d=e.paths?.output||se;i=z(t,d,xe,a)}let c=!We(i);return c&&Dt(i,{recursive:!0}),(c||s!=="initialState.sessionPath")&&Mo({traceFrom:n,sessionId:a,sessionPath:i,idSource:s,mkdirFresh:c}),Wt({sessionPath:i,sessionId:a}),{sessionPath:i,sessionId:a,sessionTimestamp:r}}var ue=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{return this.inputSchema.merge(this.contextSchema)}catch{}return this.inputSchema&&!this.contextSchema?this.inputSchema:this.stateSchema}addNode(e,o,n={}){if(!(o instanceof j)&&o&&typeof o=="object"&&typeof o.workflow=="string"){let r=o,s={name:e,_isCustomCode:!0,retries:r.retries,onComplete:r.onComplete,execute:async c=>{let l=c?.state&&typeof c.state.getAll=="function"?c.state.getAll():c,d;return typeof r.input=="function"?d=r.input(l):r.input&&typeof r.input=="object"?d=r.input:d={},Fe(r.workflow,{input:d,async:r.async===!0,conversationId:typeof r.conversationId=="function"?r.conversationId(l):r.conversationId,output:r.output,timeoutMs:r.timeoutMs,pollIntervalMs:r.pollIntervalMs,signal:l?._signal,parentAgent:c?.agent})}},a=new j(s);return a.name=e,this.nodes.set(e,a),n.prompt&&this.nodePrompts.set(e,n.prompt),Object.keys(n).length>0&&this.nodeOptions.set(e,n),this}let i=o instanceof j?o:new j(o);return i.name=e,this.nodes.set(e,i),n.prompt?this.nodePrompts.set(e,n.prompt):typeof o?.prompt=="string"&&o.prompt.trim()&&this.nodePrompts.set(e,o.prompt),Object.keys(n).length>0&&this.nodeOptions.set(e,n),this}addConditionalNode(e,o){return this.nodes.set(e,new Q({...o,name:e})),this}addEdge(e,o){return this.edges.set(e,o),this}setNodeType(e,o){return this.nodeTypeMap.set(e,o),this}addConditionalEdges(e,o,{labels:n}={}){return this.edges.set(e,{conditional:!0,routes:o,labels:n}),typeof o=="function"&&this.conditionalCodeMap.set(e,o.toString()),this}setEntryPoint(e){return this.entryPoint=e,this}use(e){return typeof e=="function"&&this.middleware.push(e),this}_composeMiddleware(e,o,n,i,r){let s=n;for(let a=e.length-1;a>=0;a--){let c=e[a],l=s;s=()=>c(o,l,i,r)}return s()}serialize(){let e=[],o={};for(let[d,u]of this.nodes){let p=this.nodeTypeMap.get(d)||(u instanceof Q?"decision":d);e.push({id:d,type:p,data:{nodeType:p,label:d}});let f={};u._isCustomCode&&typeof u.execute=="function"&&(f.customCode=u.execute.toString());let m=this.nodePrompts.get(d);if(m)f.prompt=m;else if(typeof u.prompt=="function")try{let S=u.prompt({});typeof S=="string"&&S.trim()&&(f.prompt=S,f.promptIsCode=!0)}catch{}if(typeof u.customExecute=="function"&&(f.executeCode=u.customExecute.toString()),u.outputSchema)if(typeof u.outputSchema._def<"u"){let S=null;if(typeof ye?.toJSONSchema=="function")try{S=ye.toJSONSchema(u.outputSchema)}catch{}if(!S)try{S=Mt(u.outputSchema,{target:"openApi3"})}catch{}f.outputSchema=S?{jsonSchema:S,variables:this._flattenJsonSchemaToVariables(S)}:{schema:u.outputSchema}}else f.outputSchema={schema:u.outputSchema};let w=(this.resolvedToolsMap||{})[d];w?.toolIds&&(f.tools=w.toolIds);let E=Array.isArray(u?.config?.skills)?u.config.skills:Array.isArray(u?.skills)?u.skills:null;E&&E.length>0&&(f.skills=[...E]),Object.keys(f).length>0&&(o[d]=f)}let n=[];for(let[d,u]of this.edges)if(typeof u=="string")n.push({source:d,target:u});else if(u.conditional){let p=this.conditionalCodeMap.get(d)||u.routes.toString(),f=this._inferConditionalTargets(u.routes,u.labels),m=u.labels||{};for(let w of f){let E={source:d,target:w,data:{conditionalCode:p}};m[w]&&(E.label=m[w]),n.push(E)}}let i=d=>{if(!d)return null;if(typeof ye?.toJSONSchema=="function")try{return ye.toJSONSchema(d)}catch{}try{return Mt(d,{target:"openApi3"})}catch{return null}};this.entryPoint&&this.nodes.has(this.entryPoint)&&(e.unshift({id:"START",type:"start",data:{nodeType:"start",label:"Start"}}),n.unshift({source:"START",target:this.entryPoint}));let r=0;for(let d of n)if(d.target==="END"){r+=1;let u=`END__${r}`;d.target=u,e.push({id:u,type:"end",data:{nodeType:"end",label:"End"}})}for(let d of this.nodes.keys())if(!this.edges.has(d)){r+=1;let u=`END__${r}`;e.push({id:u,type:"end",data:{nodeType:"end",label:"End"}}),n.push({source:d,target:u})}let s=this._runtimeSchema(),a=i(s||this.stateSchema),c=i(this.inputSchema),l=i(this.contextSchema);return{nodes:e,edges:n,nodeConfigs:o,stateSchema:a,inputSchema:c,contextSchema:l}}_inferConditionalTargets(e,o){let n=e.toString(),i=new Set,r=/(['"])((?:\\.|(?!\1).)*?)\1|`((?:\\.|[^`$]|\$(?!\{))*?)`/g,s;for(;(s=r.exec(n))!==null;){let l=s[2]!==void 0?s[2]:s[3];l!==void 0&&l!==""&&i.add(l)}let a=new Set(["END","START","__end__","__start__"]);for(let l of this.nodes.keys())a.add(l);if(o&&typeof o=="object")for(let l of Object.keys(o))a.add(l);let c=new Set;for(let l of i)a.has(l)&&c.add(l);if(c.size===0){let l=/return\s+['"]([^'"]+)['"]/g,d;for(;(d=l.exec(n))!==null;)c.add(d[1])}return[...c]}_flattenJsonSchemaToVariables(e,o=""){let n=e;if(e.$ref&&e.definitions){let i=e.$ref.replace("#/definitions/","");n=e.definitions[i]||e}return this._flattenSchema(n,o)}_flattenSchema(e,o=""){if(!e||typeof e!="object")return[];let n=[],i=e.properties||{},r=e.required||[];for(let[s,a]of Object.entries(i)){let c=o?`${o}.${s}`:s;n.push({path:c,type:a.type||"unknown",label:a.description||this._formatLabel(s),optional:!r.includes(s)}),a.type==="object"&&a.properties&&n.push(...this._flattenSchema(a,c)),a.type==="array"&&a.items?.type==="object"&&a.items.properties&&n.push(...this._flattenSchema(a.items,`${c}[]`))}return n}_formatLabel(e){return e.replace(/([A-Z])/g," $1").replace(/^./,o=>o.toUpperCase()).trim()}_summarizeNodeOutput(e,o){if(!o||typeof o!="object")return[];let n=[];o.success!==void 0&&n.push(`Result: ${o.success?"passed":"failed"}`);for(let[i,r]of Object.entries(o))if(!(i==="success"||i==="raw"||i==="nextNode")){if(typeof r=="string"&&r.length<=80)n.push(`${i}: ${r}`);else if(Array.isArray(r)){let s=r.length,a=r.filter(l=>l?.passed===!0).length,c=r.some(l=>l?.passed!==void 0);n.push(c?`${i}: ${a}/${s} passed${s-a?`, ${s-a} failed`:""}`:`${i}: ${s} items`)}if(n.length>=4)break}return n}async run(e,o={},n={}){if(!this.entryPoint)throw new Error("No entry point set for graph");let i=new AbortController;n.signal&&(n.signal.aborted?i.abort():n.signal.addEventListener("abort",()=>i.abort(),{once:!0}));let r=n.strategyAbortTimeoutMs??o.config?.strategyAbortTimeoutMs??5e3,s=o.cwd||process.cwd();Ro({path:z(s,".env")});let a=o.config||{};if(!a||Object.keys(a).length===0)try{let T=z(s,".zibby.config.js");We(T)&&(a=(await import(T)).default||{})}catch{}process.env.EXECUTION_ID&&!a.agent?.strictMode&&(a.agent={...a.agent,strictMode:!0});let c=o.agentType;if(!c){let T=a?.agent;T?.provider?c=T.provider:T?.gemini?c="gemini":T?.claude?c="claude":T?.cursor?c="cursor":T?.codex?c="codex":c=process.env.AGENT_TYPE||"cursor"}let l=o.contextConfig||e?.config?.contextConfig||e?.config?.context||a?.context||{},d=this._runtimeSchema();if(d){let T=d.safeParse(o);if(!T.success){let N=T.error.issues.map(O=>`${O.path.join(".")}: ${O.message}`);throw console.error("\u274C Initial state validation failed:"),N.forEach(O=>console.error(` - ${O}`)),new Error(`State validation failed: ${N.join(", ")}`)}x.step("State validated against schema")}let u=Ft(),p=o.sessionPath||u;p||Ut();let{sessionPath:f,sessionTimestamp:m,sessionId:w}=Ht({cwd:s,config:a,traceFrom:"WorkflowGraph.run",initialState:{sessionPath:p,sessionTimestamp:o.sessionTimestamp}});x.step(`Session ${w}`);let E=await le.loadContext(o.specPath||"",s,l);Object.keys(E).length>0&&x.step(`Context loaded: ${Object.keys(E).join(", ")}`);let S=o.outputPath;!S&&o.specPath&&(e?.calculateOutputPath?S=e.calculateOutputPath(o.specPath):console.warn(`\u26A0\uFE0F outputPath not resolved (specPath=${o.specPath})`));let h=new te({...o,config:a,agentType:c,outputPath:S,sessionPath:f,sessionTimestamp:m,context:E,resolvedTools:this.resolvedToolsMap||{},_signal:i.signal}),$=new Map;try{await import("@zibby/skills")}catch{}let{getSkill:g}=await Promise.resolve().then(()=>(ie(),St)),y=a.skills&&typeof a.skills=="object"?a.skills:{},R=Object.values(y).filter(T=>T&&typeof T=="object"&&typeof T.id=="string"),v=T=>{for(let N of R)if(N.id===T)return N;return g(T)},D=new Set;for(let[,T]of this.nodes)for(let N of T.config?.skills||[])D.add(N);for(let T of D){let N=v(T);if(typeof N?.middleware=="function")try{let O=await N.middleware();typeof O=="function"&&$.set(T,O)}catch{}}let _=this.entryPoint,pe=[],Ze=a?.recursionLimit??100,Zt=0;try{for(;_&&_!=="END";){if(++Zt>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 N=z(f,ke);if(We(N)){try{Co(N)}catch{}i.abort()}if(i.signal.aborted)return console.warn(`
|
|
37
|
+
\u{1F6D1} External stop requested \u2014 ending workflow.`),x.step("Workflow stopped externally"),{success:!0,state:h.getAll(),executionLog:pe,stoppedExternally:!0};let O=this.nodes.get(_);if(!O)throw new Error(`Node '${_}' not found in graph`);let Ve=JSON.stringify({sessionPath:f,sessionTimestamp:m,currentNode:_,createdAt:new Date().toISOString(),config:h.get("config")}),Vt=z(f,W);Bt(Vt,Ve,"utf-8");let Ke=h.get("config")?.paths?.output||se,Kt=z(s,Ke,W);Dt(z(s,Ke),{recursive:!0});try{Bt(Kt,Ve,"utf-8")}catch{}let qe=o.onPipelineProgress;if(typeof qe=="function")try{qe({cwd:s,sessionPath:f,sessionId:w,outputBase:h.get("config")?.paths?.output||se,currentNode:_})}catch{}let qt=(this.resolvedToolsMap||{})[_]||null;h.set("_currentNodeTools",qt);let Xt=h.get("nodeConfigs")||{};h.set("_currentNodeConfig",Xt[_]||{}),x.nodeStart(_);let Xe=Date.now(),fe=this.nodePrompts.get(_);if(!this._invokeAgent){let P=await Promise.resolve().then(()=>(X(),ae));this._invokeAgent=P.invokeAgent}let Qt=this._invokeAgent,Ee={},eo=O.config?.skills||[];for(let P of eo){let C=v(P);if(typeof C?.invokeAgentOptions=="function")try{let b=C.invokeAgentOptions(h.getAll(),{agentType:h.get("agentType"),nodeName:_});b&&typeof b=="object"&&(Ee={...Ee,...b})}catch(b){console.warn(`[graph] skill '${P}' invokeAgentOptions threw: ${b.message}`)}}let Qe=async(P,C,b={})=>{let B=Qt(P,C,{...Ee,...b,signal:i.signal});return B.catch(()=>{}),i.signal.aborted?B:Promise.race([B,new Promise((Z,V)=>{let L=()=>{setTimeout(()=>{let ee=new Error(`Strategy ignored AbortSignal \u2014 engine deadman fired after ${r}ms`);ee.name="AbortError",V(ee)},r)};i.signal.addEventListener("abort",L,{once:!0})})])},et={state:h,invokeAgent:async(P={},C={})=>{let b=C.prompt||"";if(fe){let B=this._compiledPrompts.get(_);B||(B=Bo.compile(fe,{noEscape:!0}),this._compiledPrompts.set(_,B));try{b=B(P)}catch(Z){throw console.error(`\u274C Template rendering failed for node '${_}':`,Z.message),new Error(`Template rendering failed: ${Z.message}`,{cause:Z})}}else if(!b)throw new Error(`No prompt template configured for node '${_}' and no prompt provided in options`);return Qe(b,{state:h.getAll(),images:C.images||[]},{model:C.model||h.get("model"),workspace:h.get("workspace"),schema:C.schema,...C,signal:i.signal})},_coreInvokeAgent:Qe,agent:e,nodeId:_,promptTemplate:fe,getPromptTemplate:()=>fe,...h.getAll()};try{let P=(O.config?.skills||[]).map(L=>$.get(L)).filter(Boolean),C=[...this.middleware,...P],b;C.length>0?b=await this._composeMiddleware(C,_,async()=>O.execute(et,h),h.getAll(),h):b=await O.execute(et,h);let B=Date.now()-Xe;if(pe.push({node:_,success:b.success,duration:B,timestamp:new Date().toISOString()}),!b.success){if(i.signal.aborted)return x.step("Workflow stopped externally"),{success:!0,state:h.getAll(),executionLog:pe,stoppedExternally:!0};h.append("errors",{node:_,error:b.error});let L=O.config?.retries||0,ee=`${_}_retries`,he=h.getAll()[ee]||0;if(he<L){x.stepInfo(`Retrying (attempt ${he+1}/${L})`),h.update({[ee]:he+1,[`${_}_raw`]:b.raw});continue}throw x.nodeFailed(_,b.error,{duration:B}),new Error(`Node '${_}' failed after ${he} attempts: ${b.error}`)}h.update({[_]:b.output});let Z=this._summarizeNodeOutput(_,b.output);x.nodeComplete(_,{duration:B,details:Z});let V=this.edges.get(_);if(!V)_="END";else if(V.conditional){let L=V.routes(h.getAll());x.route(_,L),_=L}else _=V}catch(P){throw x.isInsideNode&&x.nodeFailed(_,P.message,{duration:Date.now()-Xe}),h.set("failed",!0),h.set("failedAt",_),P}}x.graphComplete();let T={success:!0,state:h.getAll(),executionLog:pe};return e&&typeof e.onComplete=="function"&&await e.onComplete(T),T}finally{if(e&&typeof e.cleanup=="function")try{await e.cleanup()}catch(T){console.warn(`[workflow] agent.cleanup() failed: ${T.message}`)}}}};var Ge=Symbol.for("@zibby/agent-workflow.nodes");globalThis[Ge]||(globalThis[Ge]=new Map);var de=globalThis[Ge];function Jt(t,e){de.set(t,e)}function He(t){return de.get(t)}function we(t){return de.has(t)}function Do(){return Array.from(de.keys())}function Je(t){let e=de.get(t);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}Jt("ai_agent",{name:"ai_agent",factory:!0,create:(t,e={})=>({name:t,_isCustomCode:!0,execute:async o=>{let n=o?._coreInvokeAgent;n||(n=(await Promise.resolve().then(()=>(X(),ae))).invokeAgent);let i=e.extraPromptInstructions||"Execute the task based on the current state.",r=Lo(i,o),s=await n(r,{cwd:o.workspace||process.cwd(),model:o.model,tools:e.resolvedTools||null});return{success:!0,output:{raw:s,nodeId:t},raw:typeof s=="string"?s:s.raw}}})});function Lo(t,e){let o=/@([\w.]+)/g,n=new Set,i;for(;(i=o.exec(t))!==null;)n.add(i[1]);if(n.size===0)return t;let r=[],s=new Set;for(let a of n){let c=a.split(".")[0];if(s.has(c))continue;let l=a.split(".").reduce((p,f)=>p?.[f],e);if(l===void 0)continue;let d=typeof l=="string"?l:l?.raw??JSON.stringify(l,null,2),u=a.replace(/_/g," ").replace(/\b\w/g,p=>p.toUpperCase());r.push(`## ${u}
|
|
38
|
+
${d}`),a.includes(".")||s.add(c)}return r.length===0?t:`${t}
|
|
39
39
|
|
|
40
40
|
---
|
|
41
41
|
# Referenced Context
|
|
42
42
|
|
|
43
43
|
${r.join(`
|
|
44
44
|
|
|
45
|
-
`)}`}
|
|
46
|
-
`)}function Jo(
|
|
47
|
-
`)}function
|
|
48
|
-
`)}function
|
|
49
|
-
`)}function
|
|
50
|
-
`)}function
|
|
51
|
-
`)}function
|
|
52
|
-
`).map((d,
|
|
53
|
-
`);s.push(` graph.addConditionalEdges('${c.source}', ${
|
|
54
|
-
`)}function
|
|
45
|
+
`)}`}ie();F();var _e={};function ze(t,e){if(Array.isArray(e))return Ye(e);let o=_e[t];return!o||o.length===0?null:Ye(o)}function Ye(t){if(!Array.isArray(t)||t.length===0)return null;let e=[],o={},n=[];for(let i of t){let r=q(i);if(!r){I.warn(`[workflow] unknown skill "${i}" \u2014 skipping`);continue}n.push(i);for(let s of r.tools||[])e.push({name:s.name,description:s.description,input_schema:s.input_schema||{type:"object",properties:{}}});if(!o[r.serverName])if(typeof r.resolve=="function"){let s=r.resolve();s&&(o[r.serverName]={...s,toolPrefix:i})}else{let s={};for(let a of r.envKeys||[]){let c=process.env[a];c&&(s[a]=c)}o[r.serverName]={command:r.command,args:[...r.args||[]],env:s,toolPrefix:i}}}return n.length===0?null:{toolIds:n,claudeTools:e,mcpServers:o}}F();function jo(t,e={}){let{nodes:o,edges:n,nodeConfigs:i={}}=t;if(!Array.isArray(o)||o.length===0)throw new M("Graph must have at least one node");if(!Array.isArray(n))throw new M("Graph edges must be an array");let r=new ue(e);e.stateSchema&&r.setStateSchema(e.stateSchema);let s=new Set,a=new Map,c={};for(let p of o){let f=Ie(p);a.set(p.id,{...p,resolvedType:f}),f==="decision"&&s.add(p.id)}for(let[p,f]of a){if(s.has(p))continue;let m=f.resolvedType,w=i[p]||{},E=ze(m,w.tools);E&&(c[p]=E);let S={};w.prompt&&(S.prompt=w.prompt);let h=we(m);if(I.debug(`[workflow] compiler: node "${p}" type="${m}" registered=${h}`),w.customCode&&!h)r.addNode(p,Yt(p,w.customCode,w),S),r.setNodeType(p,m);else if(h){let $=He(m);$.factory?r.addNode(p,$.create(p,{...w,resolvedTools:E}),S):r.addNode(p,$,S),r.setNodeType(p,m)}else if(w.executeCode)r.addNode(p,Yt(p,w.executeCode,w),S),r.setNodeType(p,m);else throw new M(`Unknown node type "${m}" for node "${p}". Did you forget to register it?`)}r.resolvedToolsMap=c;let l=new Set;for(let p of n)s.has(p.target)||l.add(p.target);let d=o.find(p=>!s.has(p.id)&&!l.has(p.id));if(!d)throw new M("Could not determine entry point: no node without incoming edges found");r.setEntryPoint(d.id);let u=Wo(n,"source");for(let p of n)if(!s.has(p.source))if(s.has(p.target)){let f=p.target,m=u.get(f)||[];if(m.length===0)throw new M(`Decision node "${f}" has no outgoing edges`);let w=Go(f,m,s);r.addConditionalEdges(p.source,w)}else r.addEdge(p.source,p.target);return r}function Fo(t){let e=[];if(!t||typeof t!="object")return{valid:!1,errors:["Config must be a non-null object"]};if((!Array.isArray(t.nodes)||t.nodes.length===0)&&e.push("Graph must have at least one node"),Array.isArray(t.edges)||e.push("Graph edges must be an array"),e.length>0)return{valid:!1,errors:e};let o=t.nodeConfigs||{};for(let a of t.nodes){let c=Ie(a);if(c==="decision"||we(c))continue;let l=o[a.id]||{};l.customCode||l.executeCode||e.push(`Unknown node type "${c}" for node "${a.id}". Register it or provide customCode/executeCode.`)}let n=new Set(t.nodes.map(a=>a.id));for(let a of t.edges)n.has(a.source)||e.push(`Edge references unknown source node "${a.source}"`),n.has(a.target)||e.push(`Edge references unknown target node "${a.target}"`);let i=new Set(t.nodes.filter(a=>Ie(a)==="decision").map(a=>a.id)),r=new Set;for(let a of t.edges)i.has(a.target)||r.add(a.target);let s=t.nodes.filter(a=>!i.has(a.id)&&!r.has(a.id));s.length===0?e.push("No entry point found (every node has incoming edges)"):s.length>1&&e.push(`Multiple entry points found: ${s.map(a=>a.id).join(", ")}`);for(let a of i){let c=t.edges.filter(d=>d.source===a);c.length===0&&e.push(`Decision node "${a}" has no outgoing edges`),c.some(d=>d.data?.conditionalCode||d.conditionalCode)||e.push(`Decision node "${a}" outgoing edges have no conditionalCode`)}return{valid:e.length===0,errors:e}}function Uo(t){return!t||!Array.isArray(t.nodes)?[]:t.nodes.filter(e=>Ie(e)!=="decision").map(e=>e.id)}function Ie(t){let e=t.data?.nodeType||t.data?.type||t.type;return e==="workflowNode"||e==="custom"||e==="default"?t.id:e}function Wo(t,e){let o=new Map;for(let n of t){let i=n[e];o.has(i)||o.set(i,[]),o.get(i).push(n)}return o}function Go(t,e,o){let n=e.find(a=>a.data?.conditionalCode||a.conditionalCode);if(!n)throw new M(`Decision node "${t}" has no conditionalCode on its outgoing edges`);let i=n.data?.conditionalCode||n.conditionalCode,r=new Set(e.map(a=>a.target).filter(a=>!o.has(a))),s;try{let c=new Function(`return (${i})`)();s=l=>{let d=c(l);return r.has(d)||I.warn(`[workflow] conditional route from "${t}" returned "${d}" which is not in valid targets: ${[...r].join(", ")}`),d}}catch(a){throw new M(`Failed to compile conditionalCode for "${t}": ${a.message}`)}return s}function Yt(t,e,o={}){let n;try{n=new Function("invokeAgent","require","console",`return (${e})`)}catch(s){throw new M(`Failed to compile customCode for node "${t}": ${s.message}`)}let i=n(async(...s)=>{let{invokeAgent:a}=await Promise.resolve().then(()=>(X(),ae));return a(...s)},typeof $e<"u"?$e:void 0,console),r=null;return o.outputSchema&&(r=o.outputSchema.jsonSchema||o.outputSchema),{name:t,_isCustomCode:!0,outputSchema:r,execute:async s=>{try{let a=await i(s);return typeof a=="object"&&"success"in a?a:{success:!0,output:a,raw:null}}catch(a){return{success:!1,error:a.message,raw:null}}}}}var M=class extends Error{constructor(e){super(e),this.name="CompilationError"}};ie();Oe();X();function Ho(t,e={}){let{nodes:o,edges:n,nodeConfigs:i={}}=t,r=new Set,s=[],a=new Map;for(let E of o){let S=E.data?.nodeType||E.type;a.set(E.id,S),S==="decision"?r.add(E.id):s.push({id:E.id,nodeType:S,label:E.data?.label||E.id})}let c=s.some(E=>{let S=i[E.id]||{};return!S.customCode&&!S.executeCode}),{toolsPerNode:l,toolIdsByVar:d}=Xo(s,i),{simpleEdges:u,conditionalEdges:p}=Qo(n,r),f=en(s,n,r),m=[],w=e.workflowType||"workflow";return m.push(Yo(e)),m.push(zo(w,{usesRegisteredNodes:c})),m.push(Zo(d)),m.push(Vo(w)),m.push(Ko(s,i)),m.push(qo(s,f,u,p,l,w)),m.filter(Boolean).join(`
|
|
46
|
+
`)}function Jo(t){let e={};for(let[o,n]of Object.entries(t)){let{tools:i,...r}=n;Object.keys(r).length>0&&(e[o]=r)}return e}function Yo(t){let e=t.workflowType||"workflow";return["// Generated workflow",`// ${t.projectId?`Project: ${t.projectId} | `:""}Type: ${e} | Version: ${t.version??0}`,`// Downloaded: ${new Date().toISOString()}`,""].join(`
|
|
47
|
+
`)}function zo(t,{usesRegisteredNodes:e=!0}={}){let o=["import { WorkflowGraph, invokeAgent, getResolvedToolDefinitions } from '@zibby/agent-workflow';"];return e&&o.push("// import './register-nodes.js'; // register custom node types here"),o.push("import { readFileSync, writeFileSync, existsSync, mkdirSync } from 'node:fs';","import { join, dirname } from 'node:path';","import { fileURLToPath } from 'node:url';",""),o.join(`
|
|
48
|
+
`)}function Zo(t){if(t.size===0)return"";let e=["// \u2500\u2500 Tool Bindings \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"];for(let[o,n]of t)e.push(`const ${o} = getResolvedToolDefinitions(${JSON.stringify(n)}); // ${n.join(", ")}`);return e.push(""),e.join(`
|
|
49
|
+
`)}function Vo(t){return["// \u2500\u2500 Node Configs \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500","const __filename = fileURLToPath(import.meta.url);","const __dirname = dirname(__filename);",`const configPath = join(__dirname, 'workflow-${t}.config.json');`,"const nodeConfigs = existsSync(configPath) ? JSON.parse(readFileSync(configPath, 'utf-8')) : {};",""].join(`
|
|
50
|
+
`)}function Ko(t,e){let o=["// \u2500\u2500 Node Implementations \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500",""];for(let n of t){let i=zt(n.id),r=e[n.id]?.customCode;if(r)o.push(`// @custom \u2014 modified from default "${n.nodeType}" template`),o.push(`const ${i}_execute = ${r};`);else{let s=Je(n.nodeType);s?(o.push(`// Default "${n.nodeType}" implementation`),o.push(`const ${i}_execute = ${s};`)):(o.push(`// No template for "${n.nodeType}" \u2014 passthrough`),o.push(`const ${i}_execute = async (state) => ({ success: true, output: {}, raw: null });`))}o.push("")}return o.join(`
|
|
51
|
+
`)}function qo(t,e,o,n,i,r){let s=["// \u2500\u2500 Graph Builder \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"];s.push("export function buildGraph(options = {}) {"),s.push(" const graph = new WorkflowGraph(options);",""),s.push(" // Nodes");for(let c of t){let l=zt(c.id);s.push(` graph.addNode('${c.id}', { name: '${c.id}', execute: ${l}_execute });`),s.push(` graph.setNodeType('${c.id}', '${c.nodeType}');`)}s.push("",` graph.setEntryPoint('${e}');`,""),(o.length>0||n.length>0)&&s.push(" // Edges");for(let c of o)s.push(` graph.addEdge('${c.source}', '${c.target}');`);for(let c of n){let l=c.code.split(`
|
|
52
|
+
`).map((d,u)=>u===0?d:` ${d}`).join(`
|
|
53
|
+
`);s.push(` graph.addConditionalEdges('${c.source}', ${l});`)}let a=[];for(let c of t){let l=i.get(c.id);l&&a.push(` '${c.id}': ${l},`)}return a.length>0&&s.push(""," graph.resolvedToolsMap = {",...a," };"),s.push(""," return graph;","}",""),s.push("export { nodeConfigs };",""),s.join(`
|
|
54
|
+
`)}function Xo(t,e){let o=new Map,n=new Map;for(let i of t){let r=e[i.id]?.tools,s;if(Array.isArray(r)&&r.length>0)s=[...r].sort();else{let a=_e[i.nodeType];a?.length>0&&(s=[...a].sort())}if(s){let a=`${s.map(c=>c.replace(/[^a-zA-Z0-9]/g,"")).join("And")}Tools`;o.set(i.id,a),n.has(a)||n.set(a,s)}}return{toolsPerNode:o,toolIdsByVar:n}}function Qo(t,e){let o=[],n=[],i=new Map,r=new Set;for(let s of t)i.has(s.source)||i.set(s.source,[]),i.get(s.source).push(s);for(let s of t)if(!e.has(s.source))if(e.has(s.target)){if(r.has(s.target))continue;r.add(s.target);let c=(i.get(s.target)||[]).find(l=>l.data?.conditionalCode||l.conditionalCode);c&&n.push({source:s.source,code:c.data?.conditionalCode||c.conditionalCode})}else o.push({source:s.source,target:s.target});return{simpleEdges:o,conditionalEdges:n}}function en(t,e,o){let n=new Set;for(let r of e)o.has(r.target)||n.add(r.target);let i=t.find(r=>!n.has(r.id));return i?i.id:t[0]?.id}function zt(t){return t.replace(/[^a-zA-Z0-9]/g,"_")}F();export{Ne as AgentStrategy,Ae as CI_ENV_VARS,M as CompilationError,Q as ConditionalNode,le as ContextLoader,se as DEFAULT_OUTPUT_BASE,co as EVENTS_FILE,_e as NODE_DEFAULT_TOOLS,j as Node,oe as OutputParser,ao as RAW_OUTPUT_FILE,io as RESULT_FILE,xe as SESSIONS_DIR,W as SESSION_INFO_FILE,lo as SKILLS,ke as STOP_REQUEST_FILE,no as SchemaTypes,me as Timeline,dt as WORKFLOW_GRAPH_LOG_MARKER_PREFIX,ue as WorkflowGraph,te as WorkflowState,Ut as clearInheritedSessionEnvForFreshRun,mt as clearSkills,jo as compileGraph,Fe as dispatchSubgraph,Uo as extractSteps,Jo as generateNodeConfigsJson,Ho as generateWorkflowCode,Gt as generateWorkflowSessionId,Re as getAgentStrategy,ht as getAllSkills,He as getNodeImpl,Je as getNodeTemplate,Ye as getResolvedToolDefinitions,q as getSkill,we as hasNode,ft as hasSkill,_t as invokeAgent,Do as listNodeTypes,gt as listSkillIds,wt as listStrategies,Ft as readPinnedSessionPathFromEnv,Jt as registerNode,pt as registerSkill,yt as registerStrategy,ze as resolveNodeTools,Ht as resolveWorkflowSession,ro as setLogger,jt as shouldTrustInheritedSessionEnv,Wt as syncProcessEnvToSession,x as timeline,Fo as validateGraphConfig};
|
package/dist/node.d.ts
CHANGED
package/dist/node.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
var
|
|
1
|
+
var st=Object.defineProperty;var b=(r,t)=>()=>(r&&(t=r(r=0)),t);var nt=(r,t)=>{for(var e in t)st(r,e,{get:t[e],enumerable:!0})};var D,at,R,l,T=b(()=>{D=()=>{},at={debug:D,info:D,warn:(...r)=>console.warn("[workflow]",...r),error:(...r)=>console.error("[workflow]",...r)},R={impl:at},l={debug:(...r)=>R.impl.debug?.(...r),info:(...r)=>R.impl.info?.(...r),warn:(...r)=>R.impl.warn?.(...r),error:(...r)=>R.impl.error?.(...r)}});var Z=b(()=>{});function z(r){return ut.get(r)||null}var P,ut,q=b(()=>{P=Symbol.for("@zibby/agent-workflow.skills");globalThis[P]||(globalThis[P]=new Map);ut=globalThis[P]});var Q={};nt(Q,{getAgentStrategy:()=>X,invokeAgent:()=>ht,listStrategies:()=>dt,registerStrategy:()=>pt});function pt(r){if(!r||typeof r.getName!="function"||typeof r.invoke!="function")throw new Error("strategy must implement getName() and invoke() (AgentStrategy shape)");let t=w.findIndex(e=>e.getName()===r.getName());t>=0?w[t]=r:w.push(r)}function dt(){return w.map(r=>r.getName())}function X(r={}){let{state:t={},preferredAgent:e=null}=r,o=e||t.agentType||process.env.AGENT_TYPE;if(!o){let n=w.map(a=>a.getName()).join(", ")||"none registered";throw new Error(`No agent specified. Set agentType in state or AGENT_TYPE env var. Available: ${n}`)}l.debug(`[workflow] agent selection: requested=${o}`);let s=w.find(n=>n.getName()===o);if(!s){let n=w.map(a=>a.getName()).join(", ")||"none registered";throw new Error(`Unknown agent '${o}'. Available: ${n}`)}if(!s.canHandle(r))throw new Error(`Agent '${o}' is not available in this environment. Check credentials/environment.`);return l.debug(`[workflow] using agent: ${s.getName()}`),s}async function ht(r,t={},e={}){let o=X(t),s=t.state?.config||e.config||{},n=s.models||{},a=e.nodeName&&n[e.nodeName]||null,g=n.default||null,p=s.agent?.[o.name]?.model||null,_=a||g||p||e.model||null,y={...e,model:_,workspace:t.state?.workspace||e.workspace,schema:e.schema||t.schema,images:e.images||t.images||[],skills:e.skills||t.skills||[],config:s},i=r,h=y.skills||[];if(h.length>0&&!e.skipPromptFragments){let $=h.map(N=>{let I=z(N)?.promptFragment;return typeof I=="function"?I():I}).filter(Boolean);$.length>0&&(i+=`
|
|
2
2
|
|
|
3
|
-
${
|
|
3
|
+
${$.join(`
|
|
4
4
|
|
|
5
5
|
`)}`)}let f=t.state?._currentNodeConfig?.extraPromptInstructions?.trim();return f&&(i+=`
|
|
6
6
|
|
|
@@ -9,21 +9,21 @@ PRIORITY OVERRIDE \u2014 THE FOLLOWING INSTRUCTIONS TAKE PRECEDENCE OVER ALL PRE
|
|
|
9
9
|
\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
|
|
10
10
|
|
|
11
11
|
${f}
|
|
12
|
-
`),l.debug(`[workflow] prompt length: ${i.length} chars`),o.invoke(i,
|
|
12
|
+
`),l.debug(`[workflow] prompt length: ${i.length} chars`),o.invoke(i,y)}var C,w,tt=b(()=>{Z();T();q();C=Symbol.for("@zibby/agent-workflow.strategies");globalThis[C]||(globalThis[C]=[]);w=globalThis[C]});import E from"handlebars";var k=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(s=>s[0]);for(let s of o)try{return this.validate(JSON.parse(s))}catch(n){if(!(n instanceof SyntaxError))throw n}return this.validate({result:t.trim()})}validate(t){let e=[];for(let[o,s]of Object.entries(this.schema)){if(s.required&&!(o in t)&&e.push(`Missing required field: ${o}`),o in t&&s.type){let n=typeof t[o];n!==s.type&&e.push(`Field '${o}' expected ${s.type}, got ${n}`)}if(s.validate&&o in t){let n=s.validate(t[o]);n&&e.push(`Field '${o}': ${n}`)}}if(e.length>0)throw new Error(`Output validation failed:
|
|
13
13
|
${e.join(`
|
|
14
|
-
`)}`);return t}};T();import{writeFileSync as
|
|
14
|
+
`)}`);return t}};T();import{writeFileSync as M,readFileSync as et,existsSync as rt,mkdirSync as ft}from"node:fs";import{join as F,dirname as mt}from"node:path";import c from"chalk";var lt="__WORKFLOW_GRAPH_LOG__",O=c.gray("\u2502"),ct=c.gray("\u250C"),H=c.gray("\u2514"),W=c.green("\u25C6"),j=c.hex("#c084fc")("\u25C6"),U=c.hex("#2dd4bf")("\u25C6"),L=c.red("\u25C6"),J=`${O} `,B=2;function K(r){return r<1e3?`${r}ms`:`${(r/1e3).toFixed(1)}s`}function Y(r,t){return(e,o,s)=>{if(typeof e!="string")return r(e,o,s);let n=process.stdout.columns||120,a="";for(let g=0;g<e.length;g++){let p=e[g];t.lineStart&&(a+=J,t.col=B,t.lineStart=!1),p===`
|
|
15
15
|
`?(a+=p,t.lineStart=!0,t.col=0,t.inEsc=!1):p==="\x1B"?(t.inEsc=!0,a+=p):t.inEsc?(a+=p,(p>="A"&&p<="Z"||p>="a"&&p<="z")&&(t.inEsc=!1)):(t.col++,a+=p,t.col>=n&&(a+=`
|
|
16
|
-
${
|
|
16
|
+
${J}`,t.col=B))}return r(a,o,s)}}var x=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=Y(this._origStdoutWrite,t),process.stderr.write=Y(this._origStderrWrite,e)}_stopIntercepting(){this._origStdoutWrite&&(this._outState&&!this._outState.lineStart&&this._origStdoutWrite(`
|
|
17
17
|
`),process.stdout.write=this._origStdoutWrite),this._origStderrWrite&&(this._errState&&!this._errState.lineStart&&this._origStderrWrite(`
|
|
18
18
|
`),process.stderr.write=this._origStderrWrite),this._origStdoutWrite=null,this._origStderrWrite=null}_rawWrite(t){(this._origStdoutWrite||process.stdout.write.bind(process.stdout))(`${t}
|
|
19
|
-
`)}_emitGraphLogMarker(t){if(!this._emitWorkflowGraphMarkers)return;let e=`${
|
|
19
|
+
`)}_emitGraphLogMarker(t){if(!this._emitWorkflowGraphMarkers)return;let e=`${lt}${JSON.stringify(t)}
|
|
20
20
|
`;this._origStdoutWrite?this._origStdoutWrite(e):process.stdout.write(e)}_writeDot(t,e){this._origStdoutWrite?(this._outState&&!this._outState.lineStart&&(this._origStdoutWrite(`
|
|
21
21
|
`),this._outState.lineStart=!0,this._outState.col=0),this._origStdoutWrite(`${t} ${e}
|
|
22
22
|
`)):process.stdout.write.bind(process.stdout)(`${t} ${e}
|
|
23
|
-
`)}step(t){this._origStdoutWrite?this._writeDot(W,t):process.stdout.write.bind(process.stdout)(`${
|
|
24
|
-
`)}stepInfo(t){this.step(t)}stepTool(t){this._origStdoutWrite?this._writeDot(
|
|
25
|
-
`)}stepMemory(t){let e=c.hex("#2dd4bf")(t);this._origStdoutWrite?this._writeDot(
|
|
26
|
-
`)}stepFail(t){this._origStdoutWrite?this._writeDot(
|
|
27
|
-
`)}nodeStart(t){this._currentNode=t,this._emitGraphLogMarker({phase:"node_begin",node:t}),this._rawWrite(`${
|
|
23
|
+
`)}step(t){this._origStdoutWrite?this._writeDot(W,t):process.stdout.write.bind(process.stdout)(`${O} ${W} ${t}
|
|
24
|
+
`)}stepInfo(t){this.step(t)}stepTool(t){this._origStdoutWrite?this._writeDot(j,t):process.stdout.write.bind(process.stdout)(`${O} ${j} ${t}
|
|
25
|
+
`)}stepMemory(t){let e=c.hex("#2dd4bf")(t);this._origStdoutWrite?this._writeDot(U,e):process.stdout.write.bind(process.stdout)(`${O} ${U} ${e}
|
|
26
|
+
`)}stepFail(t){this._origStdoutWrite?this._writeDot(L,c.red(t)):process.stdout.write.bind(process.stdout)(`${O} ${L} ${c.red(t)}
|
|
27
|
+
`)}nodeStart(t){this._currentNode=t,this._emitGraphLogMarker({phase:"node_begin",node:t}),this._rawWrite(`${ct} ${t}`),this._startIntercepting()}nodeComplete(t,e={}){this._stopIntercepting();let{duration:o,details:s}=e;if(s)for(let a of s)this._rawWrite(`${W} ${a}`);let n=o?c.dim(` ${K(o)}`):"";this._rawWrite(`${H} ${c.green("done")}${n}`),this._emitGraphLogMarker({phase:"node_end",node:t}),this._rawWrite("")}nodeFailed(t,e,o={}){this._stopIntercepting();let{duration:s}=o,n=s?c.dim(` ${K(s)}`):"";this._rawWrite(`${L} ${c.red(e)}`),this._rawWrite(`${H} ${c.red("failed")}${n}`),this._emitGraphLogMarker({phase:"node_end",node:t}),this._rawWrite("")}route(t,e){this._rawWrite(c.dim(` ${t} \u2192 ${e}`)),this._rawWrite("")}graphComplete(){}},V=new x;var v=".session-info.json";E.helpers.inc||E.registerHelper("inc",r=>Number(r)+1);E.helpers.json||E.registerHelper("json",r=>JSON.stringify(r,null,2));E.helpers.eq||E.registerHelper("eq",(r,t)=>r===t);var G=class{constructor(t){if(this.config=t,this.name=t.name,this.prompt=t.prompt,this.outputSchema=t.outputSchema,!this.outputSchema&&!t._isCustomCode)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 k(t.outputSchema):null,this.retries=t.retries||0,this.onComplete=t.onComplete,this.customExecute=t.execute}async execute(t,e){let o=()=>e&&typeof e.getAll=="function"?e.getAll():t,s=i=>e&&typeof e.get=="function"?e.get(i):t?.[i];if(typeof this.customExecute=="function"){l.debug(`[workflow] node '${this.name}': custom execute (skipping LLM)`);try{let i=await this.customExecute(t);return typeof i=="object"&&i!==null&&i.success===!1?{success:!1,error:i.error||"Node execution failed",raw:i.raw||null}:this.isZodSchema?(l.debug(`[workflow] node '${this.name}': validating output schema`),{success:!0,output:this.outputSchema.parse(i),raw:null}):{success:!0,output:i,raw:null}}catch(i){return l.error(`[workflow] node '${this.name}' failed: ${i.message}`),i.name==="ZodError"&&l.error(`Schema errors: ${JSON.stringify(i.issues||i.errors,null,2)}`),{success:!1,error:i.message,raw:null}}}let n;typeof this.prompt=="function"?n=this.prompt(o()):typeof this.prompt=="string"&&this.prompt.includes("{{")?(this._compiledPrompt||(this._compiledPrompt=E.compile(this.prompt,{noEscape:!0})),n=this._compiledPrompt(o())):n=this.prompt;let a=s("_skillHints");a&&(n=`${a}
|
|
28
28
|
|
|
29
|
-
${n}`);let g=o(),p=g.cwd||process.cwd(),_=g.sessionPath;try{if(_){let i=
|
|
29
|
+
${n}`);let g=o(),p=g.cwd||process.cwd(),_=g.sessionPath;try{if(_){let i=F(_,v);if(rt(i)){let f=JSON.parse(et(i,"utf-8"));f.currentNode=this.name,M(i,JSON.stringify(f,null,2),"utf-8")}let h=F(_,"..",v);if(rt(h))try{let f=JSON.parse(et(h,"utf-8"));f.currentNode=this.name,M(h,JSON.stringify(f,null,2),"utf-8")}catch{}}}catch(i){l.debug(`[workflow] could not update session info: ${i.message}`)}let y=null;for(let i=0;i<=this.retries;i++)try{l.debug(`[workflow] node '${this.name}' attempt ${i}`);let h=o().config||{},f=h.agents||{},$=this.config.agent??f[this.name]??null,N={state:o()};$&&(N.preferredAgent=$);let I={workspace:p,schema:this.isZodSchema?this.outputSchema:null,skills:this.config.skills||[],sessionPath:_,config:h,nodeName:this.name,timeout:this.config?.timeout||3e5},A=t?._coreInvokeAgent;A||(A=(await Promise.resolve().then(()=>(tt(),Q))).invokeAgent);let m=await A(n,N,I),d,S;if(typeof m=="string"?(d=m,S=null):m.structured?(d=m.raw||JSON.stringify(m.structured,null,2),S=m.structured):(d=m.raw||JSON.stringify(m,null,2),S=m.extracted||null),_)try{let u=F(_,this.name,"raw_stream_output.txt");ft(mt(u),{recursive:!0}),M(u,typeof d=="string"?d:JSON.stringify(d),"utf-8")}catch(u){l.debug(`[workflow] could not save raw output: ${u.message}`)}if(this.isZodSchema&&S){l.info(`[workflow] node '${this.name}': output validated: ${JSON.stringify(S,null,2)}`);let u=S;if(typeof this.onComplete=="function")try{u=await this.onComplete(o(),S)}catch(it){l.warn(`[workflow] onComplete hook failed: ${it.message}`)}return{success:!0,output:u,raw:d}}if(typeof this.onComplete=="function")try{return{success:!0,output:await this.onComplete(o(),{raw:d}),raw:d}}catch(u){throw new Error(`onComplete failed: ${u.message}`,{cause:u})}if(this.parser){let u=this.parser.parse(d);return l.info(`[workflow] node '${this.name}': parsed output: ${JSON.stringify(u,null,2)}`),V.step("Output parsed"),{success:!0,output:u,raw:d}}return{success:!0,output:d,raw:d}}catch(h){y=h,i<this.retries&&l.info(`[workflow] node '${this.name}' failed, retrying (${i+1}/${this.retries})\u2026`)}return{success:!1,error:y.message,raw:null}}},ot=class extends G{constructor(t){super({...t,_isCustomCode:!0}),this.condition=t.condition}async execute(t,e){let o=e&&typeof e.getAll=="function"?e.getAll():t;return{success:!0,output:{nextNode:this.condition(o)},raw:null}}};export{ot as ConditionalNode,G as Node};
|