@fifthrevision/axle 0.4.0 → 0.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -4,7 +4,7 @@ Axle is a CLI tool and library for building composable LLM workflows. Inspired b
4
4
 
5
5
  The project is evolving quickly and the API is still unstable, so this README will remain minimal for now.
6
6
 
7
- To get started, see the [examples](./examples) directory.
7
+ To get started, see the [examples](https://github.com/johncch/axle/tree/main/examples) directory.
8
8
 
9
9
  ## Configuration
10
10
  For CLI use, you will need to provide a `ax.config.yml` where you're running the tool.
package/dist/cli.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- var F=Object.defineProperty;var g=(i,t)=>F(i,"name",{value:t,configurable:!0});import{Command as A}from"@commander-js/extra-typings";import{b as I,i as L,T as u,L as p,R as W,g as _,e as J,d as N}from"./dag-DzqZGULq.js";import x from"yaml";import r from"chalk";import R from"node:readline";import{access as T,mkdir as P,writeFile as M,appendFile as U}from"node:fs/promises";import{homedir as z}from"node:os";import"@anthropic-ai/sdk";import"@google/genai";import"openai";import"serialize-error";import"fs/promises";import"glob";import"node:path";var B="0.4.0",G={version:B};function H(i,t){if(typeof i!="object"||i===null)return t&&(t.value="Config: must be a non-null object"),!1;if("openai"in i){const e=i.openai;if(typeof e!="object"||e===null)return t&&(t.value="Config: openai must be an object"),!1;if(typeof e["api-key"]!="string")return t&&(t.value="Config: openai.api-key must be a string"),!1;if("model"in e&&typeof e.model!="string")return t&&(t.value="Config: openai.model must be a string"),!1}if("anthropic"in i){const e=i.anthropic;if(typeof e!="object"||e===null)return t&&(t.value="Config: anthropic must be an object"),!1;if(typeof e["api-key"]!="string")return t&&(t.value="Config: anthropic.api-key must be a string"),!1;if("model"in e&&typeof e.model!="string")return t&&(t.value="Config: anthropic.model must be a string"),!1}if("ollama"in i){const e=i.ollama;if(typeof e!="object"||e===null)return t&&(t.value="Config: ollama must be an object"),!1;if("url"in e&&typeof e.url!="string")return t&&(t.value="Config: ollama.url must be a string"),!1;if("model"in e&&typeof e.model!="string")return t&&(t.value="Config: ollama.model must be a string"),!1}if("googleai"in i){const e=i.googleai;if(typeof e!="object"||e===null)return t&&(t.value="Config: googleai must be an object"),!1;if(typeof e["api-key"]!="string")return t&&(t.value="Config: googleai.api-key must be a string"),!1;if("model"in e&&typeof e.model!="string")return t&&(t.value="Config: googleai.model must be a string"),!1}if("brave"in i){const e=i.brave;if(typeof e!="object"||e===null)return t&&(t.value="Config: brave must be an object"),!1;if(typeof e["api-key"]!="string")return t&&(t.value="Config: brave.api-key must be a string"),!1;if("rateLimit"in e&&typeof e.rateLimit!="number")return t&&(t.value="Config: brave.rateLimit must be a number"),!1}return!0}g(H,"isServiceConfig");const X="ax.job",K=["yaml","yml","json"];async function V(i,t){const{recorder:e}=t,{content:s,format:o}=await I({path:i,defaults:{name:X,formats:K},loader:"Job File"});let n=null;if(o==="json")n=JSON.parse(s);else if(o==="yaml"||o==="yml")n=x.parse(s);else throw new Error("Invalid job file format");e?.debug?.heading.log("The Job Object"),e?.debug?.log(n);const a={value:""};if(L(n,a))return n;throw new Error(`The job file is not valid: ${a.value}`)}g(V,"getJobConfig");const Y="ax.config",q=["yaml","yml","json"];async function Q(i,t){const{recorder:e}=t,{content:s,format:o}=await I({path:i,defaults:{name:Y,formats:q},loader:"Config File"});let n=null;if(o==="json")n=JSON.parse(s);else if(o==="yaml"||o==="yml")n=x.parse(s);else throw new Error("Invalid config file format");e?.debug?.heading.log("The Config Object"),e?.debug?.log(n);const a={value:""};if(H(n,a))return n;throw new Error(a.value)}g(Q,"getServiceConfig");const Z=["\u280B","\u2819","\u2839","\u2838","\u283C","\u2834","\u2826","\u2827","\u2807","\u280F"],m={success:"\u2713",fail:"\u2717",spinning:Z};class tt{static{g(this,"ConsoleWriter")}tasks=new Map;entries=[];truncate=0;intervalId=null;spinnerInterval=80;lastRender="";isRendering=!1;inline=!0;constructor(t={}){this.truncate=t.truncate??0,this.inline=t.inline??!0}startSpinner(){this.intervalId===null&&(this.intervalId=setInterval(()=>{[...this.tasks.values()].some(e=>e.status===u.Running)&&this.renderTasks()},this.spinnerInterval))}stopSpinner(){this.intervalId!==null&&(clearInterval(this.intervalId),this.intervalId=null)}renderTasks(){if(this.isRendering)return;if(this.isRendering=!0,this.inline&&this.lastRender){const n=this.lastRender.split(`
2
+ var A=Object.defineProperty;var g=(i,t)=>A(i,"name",{value:t,configurable:!0});import{Command as F}from"@commander-js/extra-typings";import{b as I,i as L,T as u,L as p,R as W,g as _,e as J,d as N}from"./dag-CE2X29BG.js";import x from"yaml";import r from"chalk";import R from"node:readline";import{access as T,mkdir as P,writeFile as M,appendFile as U}from"node:fs/promises";import{homedir as z}from"node:os";import"@anthropic-ai/sdk";import"@google/genai";import"openai";import"serialize-error";import"fs/promises";import"glob";import"node:path";var B="0.4.2",G={version:B};function H(i,t){if(typeof i!="object"||i===null)return t&&(t.value="Config: must be a non-null object"),!1;if("openai"in i){const e=i.openai;if(typeof e!="object"||e===null)return t&&(t.value="Config: openai must be an object"),!1;if(typeof e["api-key"]!="string")return t&&(t.value="Config: openai.api-key must be a string"),!1;if("model"in e&&typeof e.model!="string")return t&&(t.value="Config: openai.model must be a string"),!1}if("anthropic"in i){const e=i.anthropic;if(typeof e!="object"||e===null)return t&&(t.value="Config: anthropic must be an object"),!1;if(typeof e["api-key"]!="string")return t&&(t.value="Config: anthropic.api-key must be a string"),!1;if("model"in e&&typeof e.model!="string")return t&&(t.value="Config: anthropic.model must be a string"),!1}if("ollama"in i){const e=i.ollama;if(typeof e!="object"||e===null)return t&&(t.value="Config: ollama must be an object"),!1;if("url"in e&&typeof e.url!="string")return t&&(t.value="Config: ollama.url must be a string"),!1;if("model"in e&&typeof e.model!="string")return t&&(t.value="Config: ollama.model must be a string"),!1}if("googleai"in i){const e=i.googleai;if(typeof e!="object"||e===null)return t&&(t.value="Config: googleai must be an object"),!1;if(typeof e["api-key"]!="string")return t&&(t.value="Config: googleai.api-key must be a string"),!1;if("model"in e&&typeof e.model!="string")return t&&(t.value="Config: googleai.model must be a string"),!1}if("brave"in i){const e=i.brave;if(typeof e!="object"||e===null)return t&&(t.value="Config: brave must be an object"),!1;if(typeof e["api-key"]!="string")return t&&(t.value="Config: brave.api-key must be a string"),!1;if("rateLimit"in e&&typeof e.rateLimit!="number")return t&&(t.value="Config: brave.rateLimit must be a number"),!1}return!0}g(H,"isServiceConfig");const X="ax.job",K=["yaml","yml","json"];async function V(i,t){const{recorder:e}=t,{content:s,format:o}=await I(i,{defaults:{name:X,formats:K},tag:"Job File"});let n=null;if(o==="json")n=JSON.parse(s);else if(o==="yaml"||o==="yml")n=x.parse(s);else throw new Error("Invalid job file format");e?.debug?.heading.log("The Job Object"),e?.debug?.log(n);const a={value:""};if(L(n,a))return n;throw new Error(`The job file is not valid: ${a.value}`)}g(V,"getJobConfig");const Y="ax.config",q=["yaml","yml","json"];async function Q(i,t){const{recorder:e}=t,{content:s,format:o}=await I(i,{defaults:{name:Y,formats:q},tag:"Config File"});let n=null;if(o==="json")n=JSON.parse(s);else if(o==="yaml"||o==="yml")n=x.parse(s);else throw new Error("Invalid config file format");e?.debug?.heading.log("The Config Object"),e?.debug?.log(n);const a={value:""};if(H(n,a))return n;throw new Error(a.value)}g(Q,"getServiceConfig");const Z=["\u280B","\u2819","\u2839","\u2838","\u283C","\u2834","\u2826","\u2827","\u2807","\u280F"],m={success:"\u2713",fail:"\u2717",spinning:Z};class tt{static{g(this,"ConsoleWriter")}tasks=new Map;entries=[];truncate=0;intervalId=null;spinnerInterval=80;lastRender="";isRendering=!1;inline=!0;constructor(t={}){this.truncate=t.truncate??0,this.inline=t.inline??!0}startSpinner(){this.intervalId===null&&(this.intervalId=setInterval(()=>{[...this.tasks.values()].some(e=>e.status===u.Running)&&this.renderTasks()},this.spinnerInterval))}stopSpinner(){this.intervalId!==null&&(clearInterval(this.intervalId),this.intervalId=null)}renderTasks(){if(this.isRendering)return;if(this.isRendering=!0,this.inline&&this.lastRender){const n=this.lastRender.split(`
3
3
  `).length;R.moveCursor(process.stdout,0,-n+1),R.clearScreenDown(process.stdout)}const t=[...this.tasks.values()],e=t.filter(n=>n.status===u.Running),s=t.filter(n=>n.status===u.Success||n.status===u.Fail);if(e.length===0&&s.length>0){let n="";for(const a of s){if(a.status===u.Success){const f=r.green(m.success);n+=`${f} ${a.text}
4
4
  `}else if(a.status===u.Fail){const f=r.red(m.fail);n+=`${f} ${a.text}
5
5
  `}this.tasks.delete(a.id)}console.log(n)}for(const n of this.entries){const{level:a,time:f,kind:c,payload:h}=n;c==="heading"?it(a,h,{truncate:this.truncate}):nt(a,h,{truncate:this.truncate})}this.entries=[];let o="";for(const n of this.tasks.values())if(n.status===u.Running){const a=r.cyan(m.spinning[n.frameIndex]);n.frameIndex=(n.frameIndex+1)%m.spinning.length,o+=`${a} ${n.text}
@@ -9,4 +9,4 @@ var F=Object.defineProperty;var g=(i,t)=>F(i,"name",{value:t,configurable:!0});i
9
9
  `).map(h=>$+h).join(`
10
10
  `);console.log(s(c))}})}g(S,"values");function D(i){const[t,...e]=i;let s="",o=e;if(t){let{message:n,...a}=t;s=n&&typeof n=="string"?n:"",Object.keys(a).length>0&&(o=[a,...o])}return{message:s,data:o}}g(D,"toMsgData");function st(i){return i===0?null:(t,e)=>typeof e=="string"&&e.length>i?e.slice(0,i)+"<...>":e}g(st,"truncator");const y="./logs/",ot="~/.axle/logs/";class at{static{g(this,"LogWriter")}time;initialized=!1;logDir=y;pendingWrites=[];constructor(){this.time=new Date().toISOString()}get filename(){return`${this.logDir}${this.time}.log`}async initialize(){try{await T(y),this.logDir=y}catch{const s=ot.replace("~",z());try{await T(s),this.logDir=s}catch{await P(s,{recursive:!0}),this.logDir=s}}const t=M(this.filename,`AXLE: New run at ${this.time}
11
11
  `);this.pendingWrites.push(t);try{await t,this.initialized=!0}finally{const e=this.pendingWrites.indexOf(t);e!==-1&&this.pendingWrites.splice(e,1)}}async writeToLog(t){const{time:e,level:s,payload:o}=t;this.initialized||await this.initialize();const n=o.map(c=>typeof c=="string"?c:JSON.stringify(c)),a=`${p[s]} ${new Date(e).toISOString()} > ${n.join(" >> ")}
12
- `,f=U(this.filename,a).catch(c=>{console.error(`Failed to write to log file: ${c}`)});this.pendingWrites.push(f);try{await f}finally{const c=this.pendingWrites.indexOf(f);c!==-1&&this.pendingWrites.splice(c,1)}}async handleEvent(t){await this.writeToLog(t)}async flush(){this.pendingWrites.length>0&&await Promise.all(this.pendingWrites)}}const b=new A().name("axle").description("Axle is a CLI tool for running AI workflows").version(G.version).option("--dry-run","Run the application without executing against the AI providers").option("-c, --config <path>","Path to the config file").option("-j, --job <path>","Path to the job file").option("--no-log","Do not write the output to a log file").option("--no-warn-unused","Do not warn about unused variables").option("--no-inline","Do not inline the console output").option("-d, --debug","Print additional debug information").option("--truncate <num>","Truncate printed strings to a certain number of characters, 0 to disable",parseInt,100).option("--args <args...>","Additional arguments in the form key=value");b.parse(process.argv);const d=b.opts(),v={};d.args&&d.args.forEach(i=>{const[t,e]=i.split("=");t&&e&&(v[t.trim()]=e.trim())}),process.on("uncaughtException",async i=>{console.error("Uncaught exception:"),console.error(i),l&&(l.error?.log("Uncaught exception:"),l.error?.log(i.message),l.error?.log(i.stack||""),await l.shutdown()),process.exit(1)});const l=new W;d.debug&&(l.level=p.Debug);const lt=new tt(d);if(l.subscribe(lt),d.log){const i=new at;await i.initialize(),l.subscribe(i)}d.debug&&(l.debug?.heading.log("Options"),l.debug?.log(d),l.debug?.heading.log("Additional Arguments:"),l.debug?.log(v));let w,k;try{w=await Q(d.config??null,{recorder:l}),k=await V(d.job??null,{recorder:l})}catch(i){l.error.log(i.message),l.debug?.log(i.stack),await l.shutdown(),b.outputHelp(),process.exit(1)}let E;try{const{engine:i,...t}=k.using,e={...w[i],...t};E=_(i,e)}catch(i){l.error.log(i.message),l.error.log(i.stack),await l.shutdown(),b.outputHelp(),process.exit(1)}J().setConfig(w),l.info?.heading.log("All systems operational. Running job...");const rt=Date.now();d.dryRun&&l.info?.log("Dry run mode enabled. No API calls will be made.");const C={in:0,out:0},O=await N(k.jobs).execute({provider:E,variables:v,options:d,stats:C,recorder:l});O&&(l.info?.heading.log("Response"),l.info.log(O)),l.info?.heading.log("Usage"),l.info?.log(`Total run time: ${Date.now()-rt}ms`),l.info?.log(`Input tokens: ${C.in} `),l.info?.log(`Output tokens: ${C.out} `),l.info?.heading.log("Complete. Goodbye"),await l.shutdown();
12
+ `,f=U(this.filename,a).catch(c=>{console.error(`Failed to write to log file: ${c}`)});this.pendingWrites.push(f);try{await f}finally{const c=this.pendingWrites.indexOf(f);c!==-1&&this.pendingWrites.splice(c,1)}}async handleEvent(t){await this.writeToLog(t)}async flush(){this.pendingWrites.length>0&&await Promise.all(this.pendingWrites)}}const b=new F().name("axle").description("Axle is a CLI tool for running AI workflows").version(G.version).option("--dry-run","Run the application without executing against the AI providers").option("-c, --config <path>","Path to the config file").option("-j, --job <path>","Path to the job file").option("--no-log","Do not write the output to a log file").option("--no-warn-unused","Do not warn about unused variables").option("--no-inline","Do not inline the console output").option("-d, --debug","Print additional debug information").option("--truncate <num>","Truncate printed strings to a certain number of characters, 0 to disable",parseInt,100).option("--args <args...>","Additional arguments in the form key=value");b.parse(process.argv);const d=b.opts(),v={};d.args&&d.args.forEach(i=>{const[t,e]=i.split("=");t&&e&&(v[t.trim()]=e.trim())}),process.on("uncaughtException",async i=>{console.error("Uncaught exception:"),console.error(i),l&&(l.error?.log("Uncaught exception:"),l.error?.log(i.message),l.error?.log(i.stack||""),await l.shutdown()),process.exit(1)});const l=new W;d.debug&&(l.level=p.Debug);const lt=new tt(d);if(l.subscribe(lt),d.log){const i=new at;await i.initialize(),l.subscribe(i)}d.debug&&(l.debug?.heading.log("Options"),l.debug?.log(d),l.debug?.heading.log("Additional Arguments:"),l.debug?.log(v));let w,k;try{w=await Q(d.config??null,{recorder:l}),k=await V(d.job??null,{recorder:l})}catch(i){l.error.log(i.message),l.debug?.log(i.stack),await l.shutdown(),b.outputHelp(),process.exit(1)}let E;try{const{engine:i,...t}=k.using,e={...w[i],...t};E=_(i,e)}catch(i){l.error.log(i.message),l.error.log(i.stack),await l.shutdown(),b.outputHelp(),process.exit(1)}J().setConfig(w),l.info?.heading.log("All systems operational. Running job...");const rt=Date.now();d.dryRun&&l.info?.log("Dry run mode enabled. No API calls will be made.");const C={in:0,out:0},O=await N(k.jobs).execute({provider:E,variables:v,options:d,stats:C,recorder:l});O&&(l.info?.heading.log("Response"),l.info.log(O)),l.info?.heading.log("Usage"),l.info?.log(`Total run time: ${Date.now()-rt}ms`),l.info?.log(`Input tokens: ${C.in} `),l.info?.log(`Output tokens: ${C.out} `),l.info?.heading.log("Complete. Goodbye"),await l.shutdown();
@@ -0,0 +1,25 @@
1
+ var Ee=Object.defineProperty;var c=(t,e)=>Ee(t,"name",{value:e,configurable:!0});import Ie from"@anthropic-ai/sdk";import{GoogleGenAI as we,Type as Te,FinishReason as w}from"@google/genai";import Pe from"openai";import{serializeError as Ae}from"serialize-error";import{readFile as ve,access as Ne,constants as Re}from"fs/promises";import{glob as ne}from"glob";import{readFile as x,access as re,stat as Se,writeFile as Oe,mkdir as be}from"node:fs/promises";import{resolve as Z,extname as oe,dirname as Me}from"node:path";class E extends Error{static{c(this,"AxleError")}code;id;details;constructor(e,s){super(e,{cause:s?.cause}),this.name=this.constructor.name,this.code=s?.code||"AXLE_ERROR",this.id=s?.id,this.details=s?.details,Object.setPrototypeOf(this,E.prototype)}}const S={CLAUDE_OPUS_4_20250514:"claude-opus-4-20250514",CLAUDE_OPUS_4_LATEST:"claude-opus-4-0",CLAUDE_SONNET_4_20250514:"claude-sonnet-4-20250514",CLAUDE_SONNET_4_LATEST:"claude-sonnet-4-0",CLAUDE_3_7_SONNET_20250219:"claude-3-7-sonnet-20250219",CLAUDE_3_7_SONNET_LATEST:"claude-3-7-sonnet-latest",CLAUDE_3_5_HAIKU_20241022:"claude-3-5-haiku-20241022",CLAUDE_3_5_HAIKU_LATEST:"claude-3-5-haiku-latest"},ie=[S.CLAUDE_3_7_SONNET_LATEST,S.CLAUDE_3_7_SONNET_20250219,S.CLAUDE_3_5_HAIKU_LATEST,S.CLAUDE_3_5_HAIKU_20241022,S.CLAUDE_SONNET_4_LATEST,S.CLAUDE_SONNET_4_20250514,S.CLAUDE_OPUS_4_LATEST,S.CLAUDE_OPUS_4_20250514];class Ge{static{c(this,"Chat")}system;messages=[];tools=[];setToolSchemas(e){this.tools=e}addSystem(e){this.system=e}addUser(e,s,r){let o,n=[];if(typeof s=="string"?(o=s,n=r||[]):Array.isArray(s)&&(n=s),!o&&n.length===0){this.messages.push({role:"user",content:e});return}const i=[{type:"text",text:e}];o&&i.push({type:"instructions",instructions:o});for(const a of n)i.push({type:"file",file:a});this.messages.push({role:"user",content:i})}addAssistant(e,s){this.messages.push({role:"assistant",content:e,...s&&{toolCalls:s}})}addTools(e){this.messages.push({role:"tool",content:e})}hasFiles(){return this.messages.some(e=>Array.isArray(e.content)&&e.content.some(s=>s.type==="file"))}latest(){return this.messages[this.messages.length-1]}toString(){return JSON.stringify({system:this.system,messages:this.messages,tools:this.tools})}}function U(t,e=`
2
+
3
+ `){if(typeof t=="string")return t;const s=t.filter(o=>o.type==="text").map(o=>o.text),r=t.filter(o=>o.type==="instructions").map(o=>o.instructions);return s.length===0&&r.length===0?null:[...s,...r].join(e)}c(U,"getTextAndInstructions");function ke(t){return typeof t=="string"?t:t.filter(e=>e.type==="text").map(e=>e.text).join(`
4
+
5
+ `)}c(ke,"getTextContent");function $e(t){if(typeof t=="string")return null;const e=t.filter(s=>s.type==="instructions").map(s=>s.instructions);return e.length>0?e.join(`
6
+
7
+ `):null}c($e,"getInstructions");function D(t){return typeof t=="string"?[]:t.filter(e=>e.type==="file"&&e.file.type==="document").map(e=>e.file)}c(D,"getDocuments");function L(t){return typeof t=="string"?[]:t.filter(e=>e.type==="file"&&e.file.type==="image").map(e=>e.file)}c(L,"getImages");var y=(t=>(t[t.Stop=0]="Stop",t[t.Length=1]="Length",t[t.FunctionCall=2]="FunctionCall",t[t.Error=3]="Error",t))(y||{});const xe=S.CLAUDE_SONNET_4_LATEST;class Le{static{c(this,"AnthropicProvider")}name="Anthropic";client;model;constructor(e,s){this.model=s??xe,this.client=new Ie({apiKey:e})}createChatRequest(e,s={}){const{recorder:r}=s;return e.hasFiles()&&!ie.includes(this.model)&&r?.warn?.log(`Model ${this.model} may not support multimodal content. Use one of: ${ie.join(", ")}`),new Fe(this,e)}}class Fe{static{c(this,"AnthropicChatRequest")}constructor(e,s){this.provider=e,this.chat=s}async execute(e){const{recorder:s}=e,{client:r,model:o}=this.provider,n={model:o,max_tokens:4096,...Ce(this.chat)};s?.debug?.log(n);let i;try{const a=await r.messages.create(n);i=Ue(a)}catch(a){i={type:"error",error:{type:a.error.error.type??"Undetermined",message:a.error.error.message??"Unexpected error from Anthropic"},usage:{in:0,out:0},raw:a}}return s?.debug?.log(i),i}}function ae(t){switch(t){case"max_tokens":return y.Length;case"end_turn":return y.Stop;case"stop_sequence":return y.Stop;case"tool_use":return y.FunctionCall;default:return y.Error}}c(ae,"getStopReason$2");function Ce(t){const e=t.messages.map(r=>{if(r.role==="assistant"){const o=[];return o.push({type:"text",text:r.content}),r.toolCalls&&o.push(...r.toolCalls.map(n=>({type:"tool_use",id:n.id,name:n.name,input:n.arguments}))),{role:"assistant",content:o}}if(r.role==="tool")return{role:"user",content:r.content.map(o=>({type:"tool_result",tool_use_id:o.id,content:o.content}))};if(typeof r.content=="string")return{role:"user",content:r.content};{const o=[],n=U(r.content);n&&o.push({type:"text",text:n});const i=L(r.content);i.length>0&&o.push(...i.map(u=>({type:"image",source:{type:"base64",media_type:u.mimeType,data:u.base64}})));const a=D(r.content);return a.length>0&&o.push(...a.filter(u=>u.mimeType==="application/pdf").map(u=>({type:"document",source:{type:"base64",media_type:"application/pdf",data:u.base64}}))),{role:"user",content:o}}}),s=t.tools.map(r=>({name:r.name,description:r.description,input_schema:r.parameters}));return{system:t.system,messages:e,tools:s}}c(Ce,"prepareRequest$4");function Ue(t){const e=ae(t.stop_reason);if(e===y.Error)return{type:"error",error:{type:"Uncaught error",message:"Stop reason is not recognized."},usage:{in:t.usage.input_tokens,out:t.usage.output_tokens},raw:t};if(e===y.FunctionCall){const s=t.content[0],r=s.type==="text"?s.text:"",o=t.content.slice(1).map(n=>{if(n.type==="tool_use")return{id:n.id,name:n.name,arguments:n.input}}).filter(n=>n!==null);return{type:"success",id:t.id,model:t.model,reason:y.FunctionCall,message:{role:t.role,content:r,toolCalls:o},usage:{in:t.usage.input_tokens,out:t.usage.output_tokens},raw:t}}if(t.type=="message"){const s=t.content[0];if(s.type=="text")return{type:"success",id:t.id,model:t.model,reason:ae(t.stop_reason),message:{role:t.role,content:s.text},usage:{in:t.usage.input_tokens,out:t.usage.output_tokens},raw:t}}}c(Ue,"translate");const p={GEMINI_1_0_PRO_VISION_LATEST:"gemini-1.0-pro-vision-latest",GEMINI_PRO_VISION:"gemini-pro-vision",GEMINI_1_5_PRO_LATEST:"gemini-1.5-pro-latest",GEMINI_1_5_PRO_001:"gemini-1.5-pro-001",GEMINI_1_5_PRO_002:"gemini-1.5-pro-002",GEMINI_1_5_PRO:"gemini-1.5-pro",GEMINI_1_5_FLASH_LATEST:"gemini-1.5-flash-latest",GEMINI_1_5_FLASH_001:"gemini-1.5-flash-001",GEMINI_1_5_FLASH_001_TUNING:"gemini-1.5-flash-001-tuning",GEMINI_1_5_FLASH:"gemini-1.5-flash",GEMINI_1_5_FLASH_002:"gemini-1.5-flash-002",GEMINI_1_5_FLASH_8B:"gemini-1.5-flash-8b",GEMINI_1_5_FLASH_8B_001:"gemini-1.5-flash-8b-001",GEMINI_1_5_FLASH_8B_LATEST:"gemini-1.5-flash-8b-latest",GEMINI_1_5_FLASH_8B_EXP_0827:"gemini-1.5-flash-8b-exp-0827",GEMINI_1_5_FLASH_8B_EXP_0924:"gemini-1.5-flash-8b-exp-0924",GEMINI_2_5_PRO_EXP_03_25:"gemini-2.5-pro-exp-03-25",GEMINI_2_5_PRO_PREVIEW_03_25:"gemini-2.5-pro-preview-03-25",GEMINI_2_5_FLASH_PREVIEW_04_17:"gemini-2.5-flash-preview-04-17",GEMINI_2_5_FLASH_PREVIEW_05_20:"gemini-2.5-flash-preview-05-20",GEMINI_2_5_FLASH_PREVIEW_04_17_THINKING:"gemini-2.5-flash-preview-04-17-thinking",GEMINI_2_5_PRO_PREVIEW_05_06:"gemini-2.5-pro-preview-05-06",GEMINI_2_5_PRO_PREVIEW_06_05:"gemini-2.5-pro-preview-06-05",GEMINI_2_0_FLASH_EXP:"gemini-2.0-flash-exp",GEMINI_2_0_FLASH:"gemini-2.0-flash",GEMINI_2_0_FLASH_001:"gemini-2.0-flash-001",GEMINI_2_0_FLASH_EXP_IMAGE_GENERATION:"gemini-2.0-flash-exp-image-generation",GEMINI_2_0_FLASH_LITE_001:"gemini-2.0-flash-lite-001",GEMINI_2_0_FLASH_LITE:"gemini-2.0-flash-lite",GEMINI_2_0_FLASH_PREVIEW_IMAGE_GENERATION:"gemini-2.0-flash-preview-image-generation",GEMINI_2_0_FLASH_LITE_PREVIEW_02_05:"gemini-2.0-flash-lite-preview-02-05",GEMINI_2_0_FLASH_LITE_PREVIEW:"gemini-2.0-flash-lite-preview",GEMINI_2_0_PRO_EXP:"gemini-2.0-pro-exp",GEMINI_2_0_PRO_EXP_02_05:"gemini-2.0-pro-exp-02-05",GEMINI_EXP_1206:"gemini-exp-1206",GEMINI_2_0_FLASH_THINKING_EXP_01_21:"gemini-2.0-flash-thinking-exp-01-21",GEMINI_2_0_FLASH_THINKING_EXP:"gemini-2.0-flash-thinking-exp",GEMINI_2_0_FLASH_THINKING_EXP_1219:"gemini-2.0-flash-thinking-exp-1219",GEMINI_2_5_FLASH_PREVIEW_TTS:"gemini-2.5-flash-preview-tts",GEMINI_2_5_PRO_PREVIEW_TTS:"gemini-2.5-pro-preview-tts",LEARNLM_2_0_FLASH_EXPERIMENTAL:"learnlm-2.0-flash-experimental",GEMMA_3_1B_IT:"gemma-3-1b-it",GEMMA_3_4B_IT:"gemma-3-4b-it",GEMMA_3_12B_IT:"gemma-3-12b-it",GEMMA_3_27B_IT:"gemma-3-27b-it",GEMMA_3N_E4B_IT:"gemma-3n-e4b-it"},ce=[p.GEMINI_1_0_PRO_VISION_LATEST,p.GEMINI_PRO_VISION,p.GEMINI_1_5_PRO_LATEST,p.GEMINI_1_5_PRO_001,p.GEMINI_1_5_PRO_002,p.GEMINI_1_5_PRO,p.GEMINI_1_5_FLASH_LATEST,p.GEMINI_1_5_FLASH_001,p.GEMINI_1_5_FLASH_001_TUNING,p.GEMINI_1_5_FLASH,p.GEMINI_1_5_FLASH_002,p.GEMINI_1_5_FLASH_8B,p.GEMINI_1_5_FLASH_8B_001,p.GEMINI_1_5_FLASH_8B_LATEST,p.GEMINI_1_5_FLASH_8B_EXP_0827,p.GEMINI_1_5_FLASH_8B_EXP_0924,p.GEMINI_2_5_PRO_EXP_03_25,p.GEMINI_2_5_PRO_PREVIEW_03_25,p.GEMINI_2_5_FLASH_PREVIEW_04_17,p.GEMINI_2_5_FLASH_PREVIEW_05_20,p.GEMINI_2_5_FLASH_PREVIEW_04_17_THINKING,p.GEMINI_2_5_PRO_PREVIEW_05_06,p.GEMINI_2_5_PRO_PREVIEW_06_05,p.GEMINI_2_0_FLASH_EXP,p.GEMINI_2_0_FLASH,p.GEMINI_2_0_FLASH_001,p.GEMINI_2_0_FLASH_EXP_IMAGE_GENERATION,p.GEMINI_2_0_FLASH_LITE_001,p.GEMINI_2_0_FLASH_LITE,p.GEMINI_2_0_FLASH_PREVIEW_IMAGE_GENERATION,p.GEMINI_2_0_FLASH_LITE_PREVIEW_02_05,p.GEMINI_2_0_FLASH_LITE_PREVIEW,p.GEMINI_2_0_PRO_EXP,p.GEMINI_2_0_PRO_EXP_02_05,p.GEMINI_EXP_1206,p.GEMINI_2_0_FLASH_THINKING_EXP_01_21,p.GEMINI_2_0_FLASH_THINKING_EXP,p.GEMINI_2_0_FLASH_THINKING_EXP_1219,p.GEMINI_2_5_FLASH_PREVIEW_TTS,p.GEMINI_2_5_PRO_PREVIEW_TTS,p.LEARNLM_2_0_FLASH_EXPERIMENTAL,p.GEMMA_3_1B_IT,p.GEMMA_3_4B_IT,p.GEMMA_3_12B_IT,p.GEMMA_3_27B_IT,p.GEMMA_3N_E4B_IT],De=p.GEMINI_2_5_FLASH_PREVIEW_05_20;class He{static{c(this,"GoogleAIProvider")}name="GoogleAI";client;model;constructor(e,s){this.model=s??De,this.client=new we({apiKey:e})}createChatRequest(e,s={}){const{recorder:r}=s;return e.hasFiles()&&!ce.includes(this.model)&&r?.warn.log(`Model ${this.model} does not support multimodal content. Use one of: ${ce.join(", ")}`),new We(this,e)}}class We{static{c(this,"GoogleAIChatRequest")}constructor(e,s){this.provider=e,this.chat=s}async execute(e){const{recorder:s}=e,{client:r,model:o}=this.provider,n=Be(this.chat);s?.debug?.log(n);let i;try{const a=await r.models.generateContent({model:o,...n});i=Xe(a,e)}catch(a){s?.error?.log(a),i={type:"error",error:{type:a.name??"Undetermined",message:a.message??"Unexpected error from Google AI"},usage:{in:0,out:0},raw:a}}return s?.debug?.log(i),i}}function Be(t){let e;t.messages.length===1&&t.messages[0].role=="user"&&typeof t.messages[0].content=="string"?e=t.messages[0].content:e=t.messages.map(r=>{if(r.role==="user"){if(typeof r.content=="string")return{role:"user",parts:[{text:r.content}]};{const o=[],n=U(r.content);n&&o.push({text:n});const i=L(r.content);i.length>0&&o.push(...i.map(u=>({inlineData:{mimeType:u.mimeType,data:u.base64}})));const a=D(r.content);return a.length>0&&o.push(...a.map(u=>({inlineData:{mimeType:u.mimeType,data:u.base64}}))),{role:"user",parts:o}}}else if(r.role==="assistant"){const o={role:"assistant",parts:[]};return r.content!==void 0&&o.parts.push({text:r.content}),r.toolCalls&&(o.parts=o.parts.concat(r.toolCalls.map(n=>{let i;return typeof n.arguments=="string"?i=JSON.parse(n.arguments):i=n.arguments,{functionCall:{id:n.id??void 0,name:n.name,args:i}}}))),o}else if(r.role==="tool")return{role:"user",parts:r.content.map(o=>({functionResponse:{id:o.id??void 0,name:o.name,response:{output:o.content}}}))}});const s={};return t.system&&(s.systemInstruction=t.system),t.tools.length>0&&(s.tools=t.tools.map(r=>({functionDeclarations:[{name:r.name,description:r.description,parameters:{...r.parameters,type:Te.OBJECT}}]}))),{contents:e,config:s}}c(Be,"prepareRequest$3");function Xe(t,e){const{recorder:s}=e,r=t.usageMetadata.promptTokenCount,o=t.usageMetadata.totalTokenCount-r,n={in:r,out:o};if(!t)return{type:"error",error:{type:"InvalidResponse",message:"Invalid or empty response from Google AI"},usage:{in:0,out:0},raw:t};if(t.promptFeedback&&t.promptFeedback.blockReason)return{type:"error",error:{type:"Blocked",message:`Response blocked by Google AI: ${t.promptFeedback.blockReason}, ${t.promptFeedback.blockReasonMessage}`},usage:n,raw:t};if(!t.candidates||t.candidates.length===0)return{type:"error",error:{type:"InvalidResponse",message:"Invalid or empty response from Google AI"},usage:{in:0,out:0},raw:t};t.candidates.length>1&&s?.warn?.log(`We received ${t.candidates.length} response candidates`);const i=t.candidates[0],u=(i.content?.parts||[]).map(_=>_.text).filter(_=>_!==void 0).join(""),[l,f]=qe(i.finishReason);if(l){let _;return t.functionCalls&&(_=t.functionCalls.map(g=>({id:g.id,name:g.name,arguments:JSON.stringify(g.args)}))),{type:"success",id:t.responseId,model:t.modelVersion,reason:t.functionCalls?y.FunctionCall:f,message:{role:"assistant",...u?{content:u}:{},..._?{toolCalls:_}:{}},usage:n,raw:t}}else return{type:"error",error:{type:"Undetermined",message:`Unexpected stop reason: ${f}`},usage:n,raw:t}}c(Xe,"translateResponse$2");function qe(t){switch(t){case w.STOP:return[!0,y.Stop];case w.MAX_TOKENS:return[!0,y.Length];case w.FINISH_REASON_UNSPECIFIED:case w.SAFETY:case w.RECITATION:case w.LANGUAGE:case w.OTHER:case w.BLOCKLIST:case w.PROHIBITED_CONTENT:case w.SPII:case w.MALFORMED_FUNCTION_CALL:case w.IMAGE_SAFETY:return[!1,y.Error]}}c(qe,"getStopReason$1");const Ke="http://localhost:11434";class Je{static{c(this,"OllamaProvider")}name="Ollama";url;model;recorder;constructor(e,s){this.url=s||Ke,this.model=e}createChatRequest(e,s={}){const{recorder:r}=s;return e.hasFiles()&&r?.warn?.log(`Ollama model ${this.model} multimodal support depends on the specific model. Ensure you're using a vision-capable model like llava.`),new ze(this.url,this.model,e)}}class ze{static{c(this,"OllamaChatCompletionRequest")}chat;url;model;constructor(e,s,r){this.url=e,this.model=s,this.chat=r}async execute(e){const{recorder:s}=e,r={stream:!1,options:{temperature:.7},...Ye(this.chat,this.model)};s?.debug?.log(r);let o;try{const n=await fetch(`${this.url}/api/chat`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(r)});if(!n.ok)throw console.log(n),new Error(`HTTP error! status: ${n.status}`);const i=await n.json();o=Ze(i)}catch(n){s?.error?.log("Error fetching Ollama response:",n),o={type:"error",error:{type:"OllamaError",message:n.message||"Unexpected error from Ollama"},usage:{in:0,out:0},raw:JSON.stringify(n)}}return s?.debug?.log(o),o}}function Ye(t,e){const s=[];t.system&&s.push({role:"system",content:t.system});let r;t.tools.length>0&&(r=t.tools.map(n=>({type:"function",function:n})));const o=t.messages.map(n=>{if(n.role==="tool")return n.content.map(i=>({role:"tool",tool_call_id:i.id,content:i.content}));if(n.role==="assistant"){const i=n.toolCalls?.map(a=>{const u=a.id;return{type:"function",function:{name:a.name,arguments:a.arguments},...u&&{id:u}}});return{role:n.role,content:n.content,...i&&{toolCalls:i}}}if(typeof n.content=="string")return{role:n.role,content:n.content};{const i=U(n.content),a=L(n.content).map(u=>u.base64);return{role:n.role,content:i,...a.length>0&&{images:a}}}}).flat(1);return{model:e,messages:[...s,...o],...r&&{tools:r}}}c(Ye,"prepareRequest$2");function Ze(t){if(t.done_reason==="stop"&&t.message){const e=t.message.content,s=[];if(t.message.tool_calls)for(const o of t.message.tool_calls)s.push({id:o.id,name:o.function.name,arguments:o.function.arguments});const r=s.length>0;return{type:"success",id:`ollama-${Date.now()}`,model:t.model,reason:r?y.FunctionCall:y.Stop,message:{role:"assistant",content:e,...r&&{toolCalls:s}},usage:{in:t.prompt_eval_count||0,out:t.eval_count||0},raw:t}}return{type:"error",error:{type:"OllamaError",message:"Unexpected error from Ollama"},usage:{in:0,out:0},raw:t}}c(Ze,"translateResponse$1");const d={GPT_4_1:"gpt-4.1",GPT_4_1_2025_04_14:"gpt-4.1-2025-04-14",GPT_4_1_MINI:"gpt-4.1-mini",GPT_4_1_MINI_2025_04_14:"gpt-4.1-mini-2025-04-14",GPT_4_1_NANO:"gpt-4.1-nano",GPT_4_1_NANO_2025_04_14:"gpt-4.1-nano-2025-04-14",GPT_4O:"gpt-4o",GPT_4O_2024_05_13:"gpt-4o-2024-05-13",GPT_4O_2024_08_06:"gpt-4o-2024-08-06",GPT_4O_2024_11_20:"gpt-4o-2024-11-20",GPT_4O_AUDIO_PREVIEW:"gpt-4o-audio-preview",GPT_4O_AUDIO_PREVIEW_2024_10_01:"gpt-4o-audio-preview-2024-10-01",GPT_4O_AUDIO_PREVIEW_2024_12_17:"gpt-4o-audio-preview-2024-12-17",GPT_4O_AUDIO_PREVIEW_2025_06_03:"gpt-4o-audio-preview-2025-06-03",GPT_4O_MINI:"gpt-4o-mini",GPT_4O_MINI_2024_07_18:"gpt-4o-mini-2024-07-18",GPT_4O_MINI_AUDIO_PREVIEW:"gpt-4o-mini-audio-preview",GPT_4O_MINI_AUDIO_PREVIEW_2024_12_17:"gpt-4o-mini-audio-preview-2024-12-17",GPT_4O_MINI_REALTIME_PREVIEW:"gpt-4o-mini-realtime-preview",GPT_4O_MINI_REALTIME_PREVIEW_2024_12_17:"gpt-4o-mini-realtime-preview-2024-12-17",GPT_4O_MINI_SEARCH_PREVIEW:"gpt-4o-mini-search-preview",GPT_4O_MINI_SEARCH_PREVIEW_2025_03_11:"gpt-4o-mini-search-preview-2025-03-11",GPT_4O_MINI_TRANSCRIBE:"gpt-4o-mini-transcribe",GPT_4O_MINI_TTS:"gpt-4o-mini-tts",GPT_4O_REALTIME_PREVIEW:"gpt-4o-realtime-preview",GPT_4O_REALTIME_PREVIEW_2024_10_01:"gpt-4o-realtime-preview-2024-10-01",GPT_4O_REALTIME_PREVIEW_2024_12_17:"gpt-4o-realtime-preview-2024-12-17",GPT_4O_REALTIME_PREVIEW_2025_06_03:"gpt-4o-realtime-preview-2025-06-03",GPT_4O_SEARCH_PREVIEW:"gpt-4o-search-preview",GPT_4O_SEARCH_PREVIEW_2025_03_11:"gpt-4o-search-preview-2025-03-11",GPT_4O_TRANSCRIBE:"gpt-4o-transcribe",O3_MINI:"o3-mini",O3_MINI_2025_01_31:"o3-mini-2025-01-31",O4_MINI:"o4-mini",O4_MINI_2025_04_16:"o4-mini-2025-04-16"},Qe=[d.GPT_4_1,d.GPT_4_1_2025_04_14,d.GPT_4_1_MINI,d.GPT_4_1_MINI_2025_04_14,d.GPT_4_1_NANO,d.GPT_4_1_NANO_2025_04_14,d.GPT_4O,d.GPT_4O_2024_05_13,d.GPT_4O_2024_08_06,d.GPT_4O_2024_11_20,d.GPT_4O_AUDIO_PREVIEW,d.GPT_4O_AUDIO_PREVIEW_2024_10_01,d.GPT_4O_AUDIO_PREVIEW_2024_12_17,d.GPT_4O_AUDIO_PREVIEW_2025_06_03,d.GPT_4O_MINI,d.GPT_4O_MINI_2024_07_18,d.GPT_4O_MINI_AUDIO_PREVIEW,d.GPT_4O_MINI_AUDIO_PREVIEW_2024_12_17,d.GPT_4O_MINI_REALTIME_PREVIEW,d.GPT_4O_MINI_REALTIME_PREVIEW_2024_12_17,d.GPT_4O_MINI_SEARCH_PREVIEW,d.GPT_4O_MINI_SEARCH_PREVIEW_2025_03_11,d.GPT_4O_MINI_TRANSCRIBE,d.GPT_4O_MINI_TTS,d.GPT_4O_REALTIME_PREVIEW,d.GPT_4O_REALTIME_PREVIEW_2024_10_01,d.GPT_4O_REALTIME_PREVIEW_2024_12_17,d.GPT_4O_REALTIME_PREVIEW_2025_06_03,d.GPT_4O_SEARCH_PREVIEW,d.GPT_4O_SEARCH_PREVIEW_2025_03_11,d.GPT_4O_TRANSCRIBE,d.O3_MINI,d.O3_MINI_2025_01_31,d.O4_MINI,d.O4_MINI_2025_04_16];class je{static{c(this,"OpenAIChatCompletionRequest")}constructor(e,s){this.provider=e,this.chat=s}async execute(e){const{recorder:s}=e,{client:r,model:o}=this.provider,n=et(this.chat,o);s?.debug?.heading.log("[Open AI Provider] Using the ChatCompletion API"),s?.debug?.log(n);let i;try{const a=await r.chat.completions.create(n);i=tt(a)}catch(a){s?.error?.log(a),i={type:"error",error:{type:a.type??"Undetermined",message:a.message??"Unexpected error from OpenAI"},usage:{in:0,out:0},raw:a}}return s?.debug?.log(i),i}}function Ve(t){switch(t){case"length":return y.Length;case"stop":return y.Stop;case"tool_calls":return y.FunctionCall;default:return y.Error}}c(Ve,"getStopReason");function et(t,e){const s=[];t.system&&s.push({role:"system",content:t.system});let r;t.tools.length>0&&(r=t.tools.map(n=>({type:"function",function:n})));const o=t.messages.map(n=>{if(n.role==="tool")return n.content.map(i=>({role:"tool",tool_call_id:i.id,content:i.content}));if(n.role==="assistant"){const i=n.toolCalls?.map(a=>{const u=a.id;return{type:"function",function:{name:a.name,arguments:typeof a.arguments=="string"?a.arguments:JSON.stringify(a.arguments)},...u&&{id:u}}});return{role:n.role,content:n.content,...i&&{toolCalls:i}}}if(typeof n.content=="string")return{role:n.role,content:n.content};{const i=[],a=U(n.content);a&&i.push({type:"text",text:a});const u=L(n.content);u.length>0&&i.push(...u.map(f=>({type:"image_url",image_url:{url:`data:${f.mimeType};base64,${f.base64}`}})));const l=D(n.content);return l.length>0&&i.push(...l.map(f=>({type:"file",file:{filename:f.name,file_data:`data:${f.mimeType};base64,${f.base64}`}}))),{role:n.role,content:i}}}).flat(1);return{model:e,messages:[...s,...o],...r&&{tools:r}}}c(et,"prepareRequest$1");function tt(t){if(t.choices.length>0){const e=t.choices[0],s=e.message.tool_calls?.map(r=>({id:r.id,name:r.function.name,arguments:r.function.arguments}));return{type:"success",id:t.id,model:t.model,reason:Ve(e.finish_reason),message:{content:e.message.content??"",role:e.message.role,toolCalls:s},usage:{in:t.usage?.prompt_tokens??0,out:t.usage?.completion_tokens??0},raw:t}}return{type:"error",error:{type:"undetermined",message:"Unexpected response from OpenAI"},usage:{in:t.usage?.prompt_tokens??0,out:t.usage?.completion_tokens??0},raw:t}}c(tt,"translateResponse");class st{static{c(this,"OpenAIResponsesAPI")}constructor(e,s){this.provider=e,this.chat=s}async execute(e){const{recorder:s}=e,{client:r,model:o}=this.provider,n=nt(this.chat,o);s?.debug?.heading.log("[Open AI Provider] Using the Responses API"),s?.debug?.log(n);let i;try{const a=await r.responses.create(n);i=rt(a)}catch(a){s?.error?.log(a),i={type:"error",error:{type:a.type??"Undetermined",message:a.message??"Unexpected error from OpenAI"},usage:{in:0,out:0},raw:a}}return s?.debug?.log(i),i}}function nt(t,e){const s=t.messages.map(n=>{if(n.role==="tool")return n.content.map(i=>({type:"function_call_output",call_id:i.id,output:i.content}));if(n.role==="assistant"){const i=n.toolCalls?.map(a=>{const u=a.id;return{type:"function",function:{name:a.name,arguments:typeof a.arguments=="string"?a.arguments:JSON.stringify(a.arguments)},...u&&{id:u}}});return{role:n.role,content:n.content,...i&&{toolCalls:i}}}if(typeof n.content=="string")return{role:n.role,content:n.content};{const i=[],a=ke(n.content);a&&i.push({type:"input_text",text:a});const u=L(n.content);u.length>0&&i.push(...u.map(f=>({type:"input_image",image_url:`data:${f.mimeType};base64,${f.base64}`})));const l=D(n.content);return l.length>0&&i.push(...l.map(f=>({type:"input_file",filename:f.path,file_data:`data:${f.mimeType};base64,${f.base64}`}))),{role:n.role,content:i}}}).flat(1),r={model:e,input:s},o=t.latest();if(o&&o.role==="user"){let n="";const i=$e(o.content);t.system&&(n=t.system),i&&(n=n?`${n}
8
+
9
+ ${i}`:i),n&&(r.instructions=n)}return t.tools.length>0&&(r.tools=t.tools.map(n=>({type:"function",strict:!0,...n}))),r}c(nt,"prepareRequest");function rt(t){if(t.error)return{type:"error",error:{type:t.error.code||"undetermined",message:t.error.message||"Response generation failed"},usage:{in:t.usage?.input_tokens??0,out:t.usage?.output_tokens??0},raw:t};const e=t.output?.filter(s=>s.type==="function_call")?.map(s=>({id:s.id||"",name:s.function?.name||"",arguments:s.function?.arguments||""}));return{type:"success",id:t.id,model:t.model||"",reason:t.incomplete_details?y.Error:y.Stop,message:{content:t.output_text||"",role:"assistant",...e?.length&&{toolCalls:e}},usage:{in:t.usage?.input_tokens??0,out:t.usage?.output_tokens??0},raw:t}}c(rt,"translateResponseToAIResponse");const ot=d.GPT_4_1;class it{static{c(this,"OpenAIProvider")}name="OpenAI";client;model;constructor(e,s){this.model=s||ot,this.client=new Pe({apiKey:e})}createChatRequest(e,s={}){const{recorder:r}=s;return Qe.includes(this.model)?new st(this,e):new je(this,e)}}function at(t,e){if(!e||Object.keys(e).length===0)throw new E(`The provider ${t} is not configured. Please check your configuration.`);switch(t){case"openai":return new it(e["api-key"],e.model);case"anthropic":return new Le(e["api-key"],e.model);case"googleai":return new He(e["api-key"],e.model);case"ollama":{const s=e;return new Je(s.model,s.url)}default:throw new E("The provider is unsupported")}}c(at,"getProvider");class te extends E{static{c(this,"TaskError")}constructor(e,s){super(e,{code:"TASK_ERROR",id:s?.id,details:{taskType:s?.taskType,taskIndex:s?.taskIndex,...s?.details},cause:s?.cause}),Object.setPrototypeOf(this,te.prototype)}}const I={Running:"running",Success:"success",PartialSuccess:"partialSuccess",Fail:"fail"};var P=(t=>(t[t.Trace=10]="Trace",t[t.Debug=20]="Debug",t[t.Info=30]="Info",t[t.Warn=40]="Warn",t[t.Error=50]="Error",t[t.Fatal=60]="Fatal",t))(P||{});class ct{static{c(this,"Recorder")}instanceId=crypto.randomUUID();currentLevel=P.Info;logs=[];writers=[];_debug;_info;_warn;_error;constructor(){this.buildMethods()}buildMethods(){this._debug=P.Debug>=this.currentLevel?this.createLoggingFunction(P.Debug):null,this._info=P.Info>=this.currentLevel?this.createLoggingFunction(P.Info):null,this._warn=P.Warn>=this.currentLevel?this.createLoggingFunction(P.Warn):null,this._error=this.createLoggingFunction(P.Error)}set level(e){this.currentLevel=e,this.buildMethods()}get level(){return this.currentLevel}get info(){return this._info}get warn(){return this._warn}get error(){return this._error}get debug(){return this._debug}subscribe(e){this.writers.includes(e)||this.writers.push(e)}unsubscribe(e){const s=this.writers.indexOf(e);s!==-1&&this.writers.splice(s,1)}publish(e){this.logs.push(e);for(const s of this.writers)s.handleEvent(e)}logFunction(e,s,...r){let o=r.map(n=>typeof n=="string"?{message:n}:n instanceof Error?Ae(n):n);this.publish({level:e,time:Date.now(),kind:s,payload:o})}createLoggingFunction(e){return{log:this.logFunction.bind(this,e,"body"),heading:{log:this.logFunction.bind(this,e,"heading")}}}getLogs(e=P.Info){return this.logs.filter(s=>s.level>=e)}async shutdown(){for(const e of this.writers)typeof e.flush=="function"&&await e.flush()}}async function ut(t,e){const{defaults:s,tag:r}=e;let o=null,n="";if(t)try{n=Z(t),o=await x(n,{encoding:"utf-8"})}catch{throw new Error(`${r} not found, see --help for details`)}else{for(const i of s.formats)try{n=Z(s.name+"."+i),o=await x(n,{encoding:"utf-8"});break}catch{continue}if(o===null)throw new Error(`${r} not found, see --help for details`)}return{content:o,format:n.split(".").pop()??""}}c(ut,"searchAndLoadFile");async function lt(t,e){let s="";for(const r of t){const o=await ne(r);e?.debug?.log(`many-files parser. For glob "${r}", found ${o.length} files.`);const n=await Promise.all(o.map(async i=>{const a=await x(i,"utf-8");return i+`:
10
+ `+a}));s+=n.join(`
11
+ `)}return s}c(lt,"loadManyFiles");function ft(t,e){t=t.replace("**/*","**");const s=/(?<asterisks>\*{1,2})(?<extension>\.[^\\/]+)?/,r=t.match(s);if(r){let o="";return r.groups?.asterisks.length==1?o+=e.stem:o+=e.dir+e.stem,r.groups?.extension?o+=r.groups.extension:o+=e.ext,t.replace(r[0],o)}return t}c(ft,"replaceFilePattern");function pt(t){const e=/(?<name>[^\\/]+)(?<extension>\.[^\\/]+)$/,s=t.match(e);return s&&s.length>0&&s.groups?{abs:t,dir:t.replace(s[0],""),ext:s.groups.extension,stem:s.groups.name,name:s[0]}:null}c(pt,"pathToComponents");async function ue(t){const e=Me(t);try{await re(e)}catch{await be(e),await ue(e)}}c(ue,"ensureDirectoryExistence");async function _t({filePath:t,content:e}){await ue(t),await Oe(t,e)}c(_t,"writeFileWithDirectories");const H=[".jpg",".jpeg",".png",".gif",".webp",".bmp",".tiff"],W=[".pdf"],B=[".txt",".md",".markdown"],le=20*1024*1024;function dt(t){return t.type==="text"}c(dt,"isTextFileInfo");function gt(t){return t.type==="image"||t.type==="document"}c(gt,"isBase64FileInfo");function mt(t){const e=oe(t).toLowerCase();if(B.includes(e))return"utf-8";if(H.includes(e)||W.includes(e))return"base64";{const s=[...B,...H,...W];throw new Error(`Unsupported file type: ${e}. Supported types: ${s.join(", ")}`)}}c(mt,"getEncodingForFile");async function X(t,e){const s=Z(t);try{await re(s)}catch{throw new Error(`File not found: ${t}`)}const r=await Se(s);if(r.size>le)throw new Error(`File too large: ${r.size} bytes. Maximum allowed: ${le} bytes`);const o=oe(s).toLowerCase(),n=s.split("/").pop()||"";if((e||mt(s))==="utf-8"){if(!B.includes(o))throw new Error(`Unsupported text file type: ${o}. Supported types: ${B.join(", ")}`);let a;switch(o){case".txt":a="text/plain";break;case".md":case".markdown":a="text/markdown";break;default:a="text/plain"}const u=await x(s,"utf-8");return{path:s,content:u,mimeType:a,size:r.size,name:n,type:"text"}}else{let a,u;if(H.includes(o))switch(a="image",o){case".jpg":case".jpeg":u="image/jpeg";break;case".png":u="image/png";break;case".gif":u="image/gif";break;case".webp":u="image/webp";break;case".bmp":u="image/bmp";break;case".tiff":u="image/tiff";break;default:u="image/jpeg"}else if(W.includes(o))a="document",u="application/pdf";else throw new Error(`Unsupported file type: ${o}. Supported types: ${[...H,...W].join(", ")}`);const f=(await x(s)).toString("base64");return{path:s,base64:f,mimeType:u,size:r.size,name:n,type:a}}}c(X,"loadFileContent");function ht(t,e){return!t||typeof t!="object"?(e&&(e.value="Not an object"),!1):yt(t.using,e)?!t.jobs||typeof t.jobs!="object"?(e&&(e.value="Missing or invalid 'jobs' property"),!1):fe(t.jobs,e)?!0:(e&&(e.value=`Invalid 'jobs' property: ${e?.value}`),!1):(e&&(e.value=`Invalid 'using' property: ${e?.value}`),!1)}c(ht,"isJobConfig");function yt(t,e){if(!t||typeof t!="object")return e&&(e.value="Not an object"),!1;if(typeof t.engine!="string")return e&&(e.value="Missing or invalid 'engine' property"),!1;if(!["openai","anthropic","ollama","googleai"].includes(t.engine))return e&&(e.value="Invalid provider type. Must be 'openai', 'anthropic', 'googleai', or 'ollama'"),!1;switch(t.engine){case"ollama":if("model"in t&&typeof t.model!="string")return e&&(e.value="Property 'model' must be a string"),!1;if("url"in t&&typeof t.url!="string")return e&&(e.value="Property 'url' must be a string"),!1;break;case"googleai":case"anthropic":case"openai":if("api-key"in t&&typeof t["api-key"]!="string")return e&&(e.value="Property 'api-key' must be a string"),!1;if("model"in t&&typeof t.model!="string")return e&&(e.value="Property 'model' must be a string"),!1;break}return!0}c(yt,"isUsing");function fe(t,e){for(const[s,r]of Object.entries(t))if(!Et(r,e))return e&&(e.value=`Invalid job '${s}': ${e?.value}`),!1;return!0}c(fe,"isDAGJob");function Et(t,e){if(!t||typeof t!="object")return e&&(e.value="Not an object"),!1;if(!It(t,e))return!1;if("dependsOn"in t&&t.dependsOn!==void 0){const s=t.dependsOn;if(typeof s!="string")if(Array.isArray(s)){for(let r=0;r<s.length;r++)if(typeof s[r]!="string")return e&&(e.value=`Dependency at index ${r} must be a string`),!1}else return e&&(e.value="Property 'dependsOn' must be a string or array of strings"),!1}return!0}c(Et,"isDAGJobValue");function It(t,e){return!t||typeof t!="object"?(e&&(e.value="Not an object"),!1):"batch"in t?Tt(t,e):wt(t,e)}c(It,"isJob");function wt(t,e){if(!t||typeof t!="object")return e&&(e.value="Not an object"),!1;if("batch"in t)return e&&(e.value="Serial job should not have a batch property"),!1;if(t.tools!==void 0){if(!Array.isArray(t.tools))return e&&(e.value="Property 'tools' must be an array"),!1;for(const s of t.tools)if(typeof s!="string")return e&&(e.value="All tools must be strings"),!1}if(!Array.isArray(t.steps))return e&&(e.value="Property 'steps' must be an array"),!1;for(let s=0;s<t.steps.length;s++)if(!pe(t.steps[s],e))return e&&(e.value=`Invalid step at index ${s}: ${e?.value}`),!1;return!0}c(wt,"isSerialJob");function Tt(t,e){if(!t||typeof t!="object")return e&&(e.value="Not an object"),!1;if(t.tools!==void 0){if(!Array.isArray(t.tools))return e&&(e.value="Property 'tools' must be an array"),!1;for(const s of t.tools)if(typeof s!="string")return e&&(e.value="All tools must be strings"),!1}if(!Array.isArray(t.batch))return e&&(e.value="Property 'batch' must be an array"),!1;for(let s=0;s<t.batch.length;s++){const r=t.batch[s];if(!r||typeof r!="object")return e&&(e.value=`Batch item at index ${s} must be an object`),!1;if(r.type!=="files")return e&&(e.value=`Batch item at index ${s} must have type 'files'`),!1;if(typeof r.source!="string")return e&&(e.value=`Batch item at index ${s} must have a string 'source' property`),!1;if(typeof r.bind!="string")return e&&(e.value=`Batch item at index ${s} must have a string 'bind' property`),!1;if(r["skip-if"]!==void 0){if(!Array.isArray(r["skip-if"]))return e&&(e.value=`Batch item at index ${s} must have an array 'skip-if' property`),!1;for(let o=0;o<r["skip-if"].length;o++)if(!Pt(r["skip-if"][o],e))return e&&(e.value=`Invalid skip condition at index ${o} in batch item ${s}: ${e?.value}`),!1}}if(!Array.isArray(t.steps))return e&&(e.value="Property 'steps' must be an array"),!1;for(let s=0;s<t.steps.length;s++)if(!pe(t.steps[s],e))return e&&(e.value=`Invalid step at index ${s}: ${e?.value}`),!1;return!0}c(Tt,"isBatchJob");function Pt(t,e){return!t||typeof t!="object"?(e&&(e.value="Not an object"),!1):t.type!=="file-exist"?(e&&(e.value="Property 'type' must be 'file-exist'"),!1):typeof t.pattern!="string"?(e&&(e.value="Property 'pattern' must be a string"),!1):!0}c(Pt,"isSkipOptions");function pe(t,e){return!t||typeof t!="object"?(e&&(e.value="Not an object"),!1):!t.uses||typeof t.uses!="string"?(e&&(e.value="Step must have a string 'uses' property"),!1):t.uses==="chat"?At(t,e):t.uses==="write-to-disk"?vt(t,e):(e&&(e.value=`Unknown uses type: ${t.uses}`),!1)}c(pe,"isStep");function At(t,e){if(!t||typeof t!="object")return e&&(e.value="Not an object"),!1;if(t.uses!=="chat")return e&&(e.value="Uses must be 'chat'"),!1;if(typeof t.message!="string")return e&&(e.value="Property 'message' must be a string"),!1;if(t.output!==void 0){if(!t.output||typeof t.output!="object"||Array.isArray(t.output))return e&&(e.value="Property 'output' must be an object"),!1;const s=["string","string[]","number","boolean"];for(const[r,o]of Object.entries(t.output))if(typeof r!="string"||typeof o!="string"||!s.includes(o))return e&&(e.value="Property 'output' must be a Record<string, ResTypeStrings> where ResTypeStrings is 'string' | 'string[]' | 'number' | 'boolean'"),!1}if(t.system!==void 0&&typeof t.system!="string")return e&&(e.value="Property 'system' must be a string"),!1;if(t.replace!==void 0){if(!Array.isArray(t.replace))return e&&(e.value="Property 'replace' must be an array"),!1;for(let s=0;s<t.replace.length;s++)if(!Nt(t.replace[s],e))return e&&(e.value=`Invalid replace at index ${s}: ${e?.value}`),!1}if(t.tools!==void 0){if(!Array.isArray(t.tools))return e&&(e.value="Property 'tools' must be an array"),!1;for(const s of t.tools)if(typeof s!="string")return e&&(e.value="All tools must be strings"),!1}if(t.images!==void 0){if(!Array.isArray(t.images))return e&&(e.value="Property 'images' must be an array"),!1;for(let s=0;s<t.images.length;s++)if(!Rt(t.images[s],e))return e&&(e.value=`Invalid image at index ${s}: ${e?.value}`),!1}if(t.documents!==void 0){if(!Array.isArray(t.documents))return e&&(e.value="Property 'documents' must be an array"),!1;for(let s=0;s<t.documents.length;s++)if(!St(t.documents[s],e))return e&&(e.value=`Invalid document at index ${s}: ${e?.value}`),!1}if(t.references!==void 0){if(!Array.isArray(t.references))return e&&(e.value="Property 'references' must be an array"),!1;for(let s=0;s<t.references.length;s++)if(!Ot(t.references[s],e))return e&&(e.value=`Invalid reference at index ${s}: ${e?.value}`),!1}return!0}c(At,"isChatStep");function vt(t,e){return!t||typeof t!="object"?(e&&(e.value="Not an object"),!1):t.uses!=="write-to-disk"?(e&&(e.value="Uses must be 'write-to-disk'"),!1):typeof t.output!="string"?(e&&(e.value="Property 'output' must be a string"),!1):!0}c(vt,"isWriteToDiskStep");function Nt(t,e){if(!t||typeof t!="object")return e&&(e.value="Not an object"),!1;if(typeof t.pattern!="string")return e&&(e.value="Property 'pattern' must be a string"),!1;if(t.source!=="file")return e&&(e.value="Property 'source' must be 'file'"),!1;if(typeof t.files!="string"&&!Array.isArray(t.files))return e&&(e.value="Property 'files' must be a string or an array of strings"),!1;if(Array.isArray(t.files)){for(let s=0;s<t.files.length;s++)if(typeof t.files[s]!="string")return e&&(e.value=`Files entry at index ${s} must be a string`),!1}return!0}c(Nt,"isReplace");function Rt(t,e){return!t||typeof t!="object"?(e&&(e.value="Not an object"),!1):typeof t.file!="string"?(e&&(e.value="Property 'file' must be a string"),!1):!0}c(Rt,"isImageReference");function St(t,e){return!t||typeof t!="object"?(e&&(e.value="Not an object"),!1):typeof t.file!="string"?(e&&(e.value="Property 'file' must be a string"),!1):!0}c(St,"isDocumentReference");function Ot(t,e){return!t||typeof t!="object"?(e&&(e.value="Not an object"),!1):typeof t.file!="string"?(e&&(e.value="Property 'file' must be a string"),!1):!0}c(Ot,"isTextFileReference");class bt{static{c(this,"FileRunPlanner")}constructor(e,s,r=[]){this.source=e,this.bind=s,this.skipConditions=r}async plan(e){const s=[],r=await ne(this.source,{withFileTypes:!0});for(const o of r){const n=o.fullpath(),i=pt(n);let a=!1;for(const u of this.skipConditions)if(a=await u.eval({components:i}),a)break;if(!a){const u=await ve(n,"utf-8"),l={variables:{[this.bind]:u,...i},tasks:e};s.push(l)}}return s}}class Mt{static{c(this,"MultiPlanner")}planners;constructor(e){this.planners=e}async plan(e){const s=this.planners.map(async o=>await o.plan(e));return(await Promise.all(s)).flat()}}function Q(t,e,s="{{}}"){const r=s==="{{}}"?/\{\{(.*?)\}\}/g:/\{(.*?)\}/g;return t=t.replace(r,(o,n)=>{if(Object.prototype.hasOwnProperty.call(e,n)){const i=e[n];return i==null?"":String(i)}return o}),t}c(Q,"replaceVariables");class Gt{static{c(this,"FileExistSkipCondition")}constructor(e){this.pattern=e}type="file-exist";async eval(e){const s=Q(this.pattern,e.components,"{}");try{return await Ne(s,Re.F_OK),!0}catch{return!1}}}var N=(t=>(t.String="string",t.List="string[]",t.Number="number",t.Boolean="boolean",t))(N||{});const _e={response:N.String};class de{static{c(this,"AbstractInstruct")}type="instruct";_result=void 0;prompt;system=null;inputs={};tools={};files=[];textReferences=[];resFormat;rawResponse;finalPrompt;constructor(e,s){this.prompt=e,this.resFormat=s}setInputs(e){this.inputs=e}addInput(e,s){this.inputs[e]=s}addTools(e){for(const s of e)this.tools[s.name]=s}addTool(e){this.tools[e.name]=e}addImage(e){if(e.type!=="image")throw new Error(`Expected image file, got ${e.type}`);const s=e;this.files.push(s)}addDocument(e){if(e.type!=="document")throw new Error(`Expected document file, got ${e.type}`);const s=e;this.files.push(s)}addFile(e){if(!gt(e))throw new Error(`Expected image or document file, got ${e.type}`);this.files.push(e)}addReference(e,s){if(typeof e=="string"){this.textReferences.push({content:e,name:s?.name});return}if(dt(e))this.textReferences.push({content:e.content,name:s?.name??e.name});else throw new Error(`Expected text file, got ${e.type}`)}hasTools(){return Object.keys(this.tools).length>0}hasFiles(){return this.files.length>0}get result(){return this._result}compile(e,s={}){const r=this.getFinalUserPrompt(e,s),o=this.getFormatInstructions();return{message:r,instructions:o}}getFinalUserPrompt(e,s={}){const{recorder:r,options:o}=s,n={...e,...this.inputs};let i=Q(this.prompt,n);if(this.textReferences.length>0){i+=`
12
+
13
+ `;for(const[a,u]of this.textReferences.entries()){const l=u.name?`: ${u.name}`:"";i+=`## Reference ${a+1}${l}
14
+
15
+ \`\`\`${u.content}'''
16
+
17
+ `}}if(o?.warnUnused){const a=i.match(/\{\{(.*?)\}\}/g);if(a)throw r?.error.log(`Warning unused variables ${a.join(", ")}`),new Error(`Unused variables: ${a.join(", ")}`)}return i}getFormatInstructions(){let e="";for(const[s,r]of Object.entries(this.resFormat))switch(r){case N.String:e+=`Use <${s}></${s}> to indicate the answer for ${s}. The answer must be a string.
18
+ `;break;case N.Number:e+=`Use <${s}></${s}> to indicate the answer for ${s}. the answer must be a number.
19
+ `;break;case N.Boolean:e+=`Use <${s}></${s}> to indicate the answer for ${s}. The answer must be a true/false.
20
+ `;break;case N.List:e+=`Use <${s}></${s}> to indicate the answer for ${s}. The answer must be a list of strings. Each string should be in a new line.
21
+ `;break}return e}finalize(e,s){this.rawResponse=e;const r={},o=Object.keys(this.resFormat);if(o.length===0){if(e.trim()==="{}"||e.trim()==="")return{};throw new Error("Output format is empty, but rawValue is not an empty object representation or empty string.")}s=s||this.parseTaggedSections(e);for(const n of o){const i=n;let a;const u=s.tags[i];if(u)a=u;else throw new Error(`Expected results with tag ${i} but it does not exist`);const l=this.resFormat[n];try{const f=this.typeResponses(l,a);r[n]=f}catch(f){throw new Error(`Cannot convert value of key ${i} to ${l}: ${f.message}`)}}return this._result=r,r}parseTaggedSections(e){const s=/<(\w+)>(.*?)<\/\1>/gs,r={};let o=e;return o=o.replace(s,(n,i,a)=>(r[i]=a,"")),{tags:r,remaining:o.trim()}}typeResponses(e,s){let r;switch(e){case N.String:r=s;break;case N.Number:if(r=parseFloat(s),isNaN(r))throw new Error(`Cannot parse '${s}' as number. Expected a numeric string.`);break;case N.Boolean:const o=s.toLowerCase();if(o==="true")r=!0;else if(o==="false")r=!1;else throw new Error(`Cannot parse '${s}' as boolean. Expected 'true' or 'false'.`);break;case N.List:s===""?r=[]:r=s.split(`
22
+ `).map(n=>n.trim()).filter(n=>n.length>0);break}return r}}class k extends de{static{c(this,"Instruct")}constructor(e,s){super(e,s)}static with(e,s){return s?new k(e,s):new k(e,_e)}}function F(t){return Array.isArray(t)?t:[t]}c(F,"arrayify");function A(t,e){return e?`${e}:${t.slice(0,8)}`:t.slice(0,8)}c(A,"friendly");function kt(t){return new Promise(e=>setTimeout(e,t))}c(kt,"delay");const $t={name:"brave",description:"Perform a search using the Brave search engine",parameters:{type:"object",properties:{searchTerm:{type:"string",description:"The search term to query"}},required:["searchTerm"]}};class xt{static{c(this,"BraveSearchTool")}name="brave";schema=$t;apiKey;throttle;lastExecTime=0;constructor(e){e&&this.setConfig(e)}setConfig(e){const{rateLimit:s}=e;this.apiKey=e["api-key"],this.throttle=s?1100/s:void 0}async execute(e,s={}){const{searchTerm:r}=e,{recorder:o}=s;if(o?.debug?.heading.log(`Brave: searching for ${r}`),this.throttle){for(;Date.now()-this.lastExecTime<this.throttle;)await kt(this.throttle-(Date.now()-this.lastExecTime));this.lastExecTime=Date.now()}try{const n=this.apiKey,i="https://api.search.brave.com/res/v1/web/search",a=new URL(i);a.searchParams.append("q",r),a.searchParams.append("format","json");const u=await fetch(a.toString(),{method:"GET",headers:{Accept:"application/json","X-Subscription-Token":n}});if(!u.ok)throw new Error(`[Brave] HTTP error ${u.status}: ${u.statusText}`);return await u.json()}catch(n){throw o?.error.log("[Brave] Error fetching search results:",n),n}}}const Lt=new xt,Ft={name:"calculator",description:"Performs basic arithmetic operations",parameters:{type:"object",properties:{operation:{type:"string",description:"The operation to perform (add, subtract, multiply, divide)",enum:["add","subtract","multiply","divide"]},a:{type:"number",description:"First operand"},b:{type:"number",description:"Second operand"}},required:["operation","a","b"]}},Ct={name:"calculator",schema:Ft,execute:c(async t=>{const{operation:e,a:s,b:r}=t;switch(e){case"add":return`${s} + ${r} = ${s+r}`;case"subtract":return`${s} - ${r} = ${s-r}`;case"multiply":return`${s} * ${r} = ${s*r}`;case"divide":if(r===0)throw new Error("Cannot divide by zero");return`${s} / ${r} = ${s/r}`;default:throw new Error(`Unknown operation: ${e}`)}},"execute")};class Ut{static{c(this,"ToolRegistry")}executables={};config;setConfig(e){this.config=e}register(e){if(this.executables[e.name])throw new Error(`Tool with name '${e.name}' is already registered`);this.executables[e.name]=e}get(e){const s=this.executables[e];if(!s)throw new Error(`Tool '${e}' is not registered`);return s.setConfig?.(this.config[e]),s}}let C;function ge(){return C||(C=new Ut,C.register(Ct),C.register(Lt)),C}c(ge,"getToolRegistry");const Dt={async convert(t,e){const{recorder:s,toolNames:r}=e,{message:o,system:n,replace:i}=t;let a;t.output?a=k.with(o,t.output):a=k.with(o),n&&(a.system=n);const u=[...new Set([...r??[],...t.tools??[]])];for(const l of u){const f=ge().get(l);a.addTool(f)}if(i){for(const l of i)if(l.source==="file"){const f=F(l.files),_=await lt(f,s);a.addInput(l.pattern,_)}}if(t.images)for(const l of t.images)try{const f=await X(l.file,"base64");a.addFile(f)}catch(f){throw new Error(`Failed to load image '${l.file}': ${f.message}`)}if(t.documents)for(const l of t.documents)try{const f=await X(l.file,"base64");a.addFile(f)}catch(f){throw new Error(`Failed to load document '${l.file}': ${f.message}`)}if(t.references)for(const l of t.references)try{const f=await X(l.file,"utf-8");a.addReference(f)}catch(f){throw new Error(`Failed to load reference file '${l.file}': ${f.message}`)}return a}};class Ht{static{c(this,"StepToClassRegistry")}converters=new Map;get(e){const s=this.converters.get(e);if(!s)throw new Error(`No converter registered for step: ${e}`);return s}register(e,s){this.converters.set(e,s)}}class j{static{c(this,"WriteOutputTask")}constructor(e,s=["response"]){this.output=e,this.keys=s}type="write-to-disk"}const Wt={async convert(t){if(t.keys){const e=F(t.keys);return new j(t.output,e)}return new j(t.output)}},V=new Ht;V.register("write-to-disk",Wt),V.register("chat",Dt);async function q(t,e){const{recorder:s}=e,r=t.tools??void 0,o=t.steps.map(async n=>(n.uses,await V.get(n.uses).convert(n,{recorder:s,toolNames:r})));return Promise.all(o)}c(q,"configToTasks");async function me(t,e){const{batch:s}=t;return s.length===1?he(s[0]):new Mt(s.map(r=>he(r)))}c(me,"configToPlanner");function he(t){switch(t.type){case"files":let e;return t["skip-if"]&&(e=t["skip-if"].map(r=>Bt(r))),new bt(t.source,t.bind,e)}}c(he,"batchOptionsToPlanner");function Bt(t){switch(t.type){case"file-exist":return new Gt(t.pattern)}}c(Bt,"skipOptionsToSkipConditions");function Xt(t){return t.success===!1&&t.error!==void 0}c(Xt,"isErrorResult");function K(t,e){return{response:t,stats:e,success:!0}}c(K,"createResult");function J(t,e,s){return{response:e,stats:s,error:t,success:!1}}c(J,"createErrorResult");class qt{static{c(this,"WriteToDiskTaskHandler")}taskType="write-to-disk";canHandle(e){return e&&typeof e=="object"&&"type"in e&&e.type==="write-to-disk"}async execute(e){const{task:s,variables:r,options:o={},recorder:n}=e,i=s.output,a=s.keys??[];if(o?.warnUnused){const f=a.filter(_=>!(_ in r));f.length>0&&n?.warn?.log(`[Write To Disk] The following keys were not found in the variables: ${f.join(", ")}`)}let u="";if(a.length===1?u=r[a[0]]??"<not found>":u=a.map(f=>`[${f}]:
23
+ ${r[f]??"<not found>"}
24
+ `).join(`
25
+ `),o?.dryRun){n?.info?.log("[Dry run] Write to Disk is not executed.");return}let l="";i.includes("*")?l=ft(i,r.file):l=Q(i,r,"{}"),await _t({filePath:l,content:u})}}var z=(t=>(t.LastResult="lastResult",t))(z||{});function Kt(t,e,s){const{options:r,recorder:o}=s,n=r?.warnUnused??!0;for(const[i,a]of Object.entries(t))n&&e[i]&&o?.warn?.log(`Warning: Variable "${i}" is being overwritten. Previous value: ${e[i]}, new value: ${a}`),e[i]=a}c(Kt,"setResultsIntoVariables");class Jt{static{c(this,"ChatTaskHandler")}taskType="instruct";canHandle(e){return e&&typeof e=="object"&&"type"in e&&e.type==="instruct"}async execute(e){const{task:s,...r}=e;await zt({instruct:s,...r})}}async function zt(t){const{instruct:e,chat:s,provider:r,stats:o,variables:n,options:i,recorder:a}=t;e.system&&s.addSystem(e.system);const{message:u,instructions:l}=e.compile(n,{recorder:a,options:i});if(e.hasFiles()?s.addUser(u,l,e.files):s.addUser(u,l),e.hasTools()){const _=Zt(e.tools);s.setToolSchemas(_)}if(i?.dryRun)return a?.debug?.log(s),{action:"complete"};let f=!0;for(;f;){const g=await r.createChatRequest(s,{recorder:a}).execute({recorder:a});if(o.in+=g.usage.in,o.out+=g.usage.out,g.type==="error")throw new Error(JSON.stringify(g.error));if(g.type==="success")switch(g.reason){case y.Stop:{if(g.message.content){const h=g.message.content;s.addAssistant(h);const m=e.finalize(h);Kt(m,n,{options:i,recorder:a}),n[z.LastResult]=m}return f=!1,{action:"continue"}}case y.Length:throw new Error("Incomplete model output due to `max_tokens` parameter or token limit");case y.FunctionCall:{let h=g.message;if(g.message&&s.addAssistant(h.content,h.toolCalls),h.toolCalls&&h.toolCalls.length>0){const m=await Yt(h.toolCalls,e,{recorder:a});a?.debug?.log(m),s.addTools(m),f=!0}else f=!1;break}}if(g.type!=="success")throw a?.debug?.log(g),new Error("Unexpected response type")}return{action:"continue"}}c(zt,"executeChatAction");async function Yt(t,e,s={}){const{recorder:r}=s,o=[];for(const n of t)o.push(new Promise((i,a)=>{const u=e.tools[n.name];if(!u){a(`Tool not found: ${n.name}`);return}r?.debug?.heading.log(`Executing tool ${u.name}`);let l={};try{l=typeof n.arguments=="string"?JSON.parse(n.arguments):n.arguments}catch{a(`argument for tool ${n.name} is not valid: ${JSON.stringify(n.arguments)}`)}u.execute(l).then(f=>{r?.debug?.log(`Complete tool ${u.name}: ${n.id}`),i({id:n.id,name:n.name,content:JSON.stringify(f)})}).catch(a)}));return Promise.all(o)}c(Yt,"executeToolCalls");function Zt(t){const e=[];for(const[s,r]of Object.entries(t))e.push(r.schema);return e}c(Zt,"getToolSchemas");class Qt{static{c(this,"TaskRegistry")}handlers=new Map;register(e){this.handlers.set(e.taskType,e)}getHandler(e){return this.handlers.get(e.type)}hasHandler(e){return this.handlers.has(e.type)}async executeTask(e){const{task:s}=e,r=s.type,o=this.getHandler(s);if(!o)throw new Error(`No handler registered for action type: ${r}`);if(!o.canHandle(s))throw new Error(`Handler found but action does not match expected format: ${r}`);await o.execute(e)}}function jt(){const t=new Qt;return t.register(new Jt),t}c(jt,"createBaseRegistry");function Vt(){const t=jt();return t.register(new qt),t}c(Vt,"createNodeRegistry");const ee=c((t,...e)=>{const s=c(async o=>{const{recorder:n}=o;let i=[];return"steps"in t?i=await q(t,{recorder:n}):i=[t,...e],i},"prepare");return{execute:c(async o=>{const{provider:n,variables:i,options:a,stats:u,recorder:l,name:f}=o,_=crypto.randomUUID(),g=Vt();l?.info?.log({type:"task",id:_,status:I.Running,message:`[${A(_,f)}] Starting job`});try{const h=await s({recorder:l}),m=new Ge;for(const[O,T]of h.entries()){l?.info?.log({type:"task",id:_,status:I.Running,message:`[${A(_,f)}] Processing step ${O+1}: ${T.type}`});try{await g.executeTask({task:T,chat:m,provider:n,variables:i,options:a,stats:u,recorder:l})}catch(v){throw v instanceof E?v:new te(`Error executing task ${T.type}`,{id:_,taskType:T.type,taskIndex:O,cause:v instanceof Error?v:new Error(String(v))})}}return l?.info?.log({type:"task",status:I.Success,id:_,message:`[${A(_,f)}] Completed ${h.length} steps`}),K(i[z.LastResult],u)}catch(h){const m=h instanceof E?h:new E("Serial workflow execution failed",{id:_,cause:h instanceof Error?h:new Error(String(h))});return l?.info?.log({type:"task",status:I.Fail,id:_,message:`[${A(_,f)}] Failed: ${m.message}`}),l?.error.log(m),J(m,i[z.LastResult],u)}},"execute")}},"serialWorkflow"),ye=c((t,...e)=>{const s=c(async o=>{const{recorder:n}=o;let i=[],a=null;if("batch"in t){const u=t;a=await me(u),i=await q(u,{recorder:n})}else a=t,i=[...e];return[a,i]},"prepare");return{execute:c(async o=>{const{provider:n,variables:i,options:a,stats:u,recorder:l,name:f}=o,_=crypto.randomUUID();try{const[g,h]=await s({recorder:l}),m=await g.plan(h);if(l?.debug?.heading.log("Runs",m),m.length===0)return l?.info?.log("No runs to execute"),K([],u);let O=0;l?.info?.log({type:"task",status:I.Running,id:_,message:`[${A(_,"CRW")}] Working on 0/${m.length}`});const T=c(async(R,Y)=>{try{return await ee(...R.tasks).execute({provider:n,variables:{...R.variables,...i},options:a,stats:u,recorder:l,name:`${f}-${Y}`})}catch(b){const se=b instanceof E?b:new E("Error executing run",{cause:b instanceof Error?b:new Error(String(b))});return l?.error?.log(se),J(se,null,u)}finally{O++,l?.info?.log({type:"task",status:I.Running,id:_,message:`[${A(_,"CRW")}] Working on ${O}/${m.length}`})}},"executeRun"),v=5;let G=[];for(let R=0;R<m.length;R+=v){const Y=m.slice(R,R+v),b=await Promise.all(Y.map(T));G=G.concat(b)}const M=G.some(Xt);l?.info?.log({type:"task",status:M?I.PartialSuccess:I.Success,id:_,message:`[${A(_,"CRW")}] All jobs (${m.length}) completed${M?" with some errors":""}`});const $=G.map(R=>R.response);return K($,u)}catch(g){const h=g instanceof E?g:new E("Concurrent workflow execution failed",{id:_,cause:g instanceof Error?g:new Error(String(g))});return l?.error?.log(h),J(h,null,u)}},"execute")}},"concurrentWorkflow");class es{static{c(this,"DAGParser")}static parse(e){const s=new Map;for(const[o,n]of Object.entries(e)){const i=this.parseNodeDefinition(o,n);s.set(o,i)}return this.validateDependencies(s),this.checkForCycles(s),{stages:this.createExecutionStages(s),nodes:s}}static parseNodeDefinition(e,s){if(this.isSimpleTask(s))return{id:e,tasks:Array.isArray(s)?s:[s],dependencies:[],executionType:"serial"};if(this.isConcurrentNodeDefinition(s)){const i=s,a=i.dependsOn?F(i.dependsOn):[];return{id:e,tasks:i.tasks,dependencies:a,planner:i.planner,executionType:"concurrent"}}const r=s,o=r.dependsOn?F(r.dependsOn):[],n=F(r.task);return{id:e,tasks:n,dependencies:o,executionType:"serial"}}static isSimpleTask(e){return e.type||Array.isArray(e)}static isConcurrentNodeDefinition(e){return e&&typeof e=="object"&&"planner"in e}static validateDependencies(e){for(const s of e.values())for(const r of s.dependencies)if(!e.has(r))throw new E(`Node "${s.id}" depends on non-existent node "${r}"`)}static checkForCycles(e){const s=new Set,r=new Set,o=c(n=>{if(r.has(n))return!0;if(s.has(n))return!1;s.add(n),r.add(n);const i=e.get(n);for(const a of i.dependencies)if(o(a))return!0;return r.delete(n),!1},"hasCycle");for(const n of e.keys())if(o(n))throw new E(`Circular dependency detected involving node "${n}"`)}static createExecutionStages(e){const s=[],r=new Set,o=new Set(e.keys());for(;o.size>0;){const n=[];for(const i of o)e.get(i).dependencies.every(l=>r.has(l))&&n.push(i);if(n.length===0)throw new E("Unable to resolve DAG dependencies - possible circular reference");s.push(n),n.forEach(i=>{r.add(i),o.delete(i)})}return s}}class ts{static{c(this,"DAGJobToDefinition")}static async convert(e,s){const{recorder:r}=s,o={};for(const[n,i]of Object.entries(e)){const{dependsOn:a,...u}=i;if("batch"in u){const l=u,f=await me(l),_=await q(l,{recorder:r}),g={planner:f,tasks:_,...a?{dependsOn:a}:{}};o[n]=g}else{const l=await q(u,{recorder:r});if(a){const f={task:l,dependsOn:a};o[n]=f}else o[n]=l}}return o}}async function ss(t,e,s,r={}){const{variables:o}=s,n=e.nodes.get(t);try{let i;if(n.executionType==="concurrent"&&n.planner?i=await ye(n.planner,...n.tasks).execute({...s,variables:o,name:t}):i=await ee(...n.tasks).execute({...s,variables:o,name:t}),!i.success)throw new E(`Node "${t}" failed: ${i.error?.message}`);return i.response}catch(i){if(!r.continueOnError)throw i;return null}}c(ss,"executeNode");const ns=c((t,e={})=>{const s=c(async(o,n)=>{const{recorder:i}=n,a={value:""};return fe(o,a)?await ts.convert(o,n):(i?.warn?.log(a),o)},"prepare");return{execute:c(async o=>{const{stats:n,recorder:i}=o,{maxConcurrency:a=3}=e,u=crypto.randomUUID();try{const l=await s(t,{recorder:i});i?.debug?.log(l);const f=es.parse(l),_=new Map;i?.info?.log({type:"task",id:u,status:I.Running,message:`[${A(u)}] Starting workflow execution with ${f.stages.length} stages`});for(const[h,m]of f.stages.entries()){i?.info?.log({type:"task",id:u,status:I.Running,message:`[${A(u)}] Stage ${h+1}/${f.stages.length}, executing ${m.length} nodes: ${m.join(", ")}`});const O=Math.min(m.length,a);for(let T=0;T<m.length;T+=O){const v=m.slice(T,T+O);(await Promise.all(v.map(async M=>{const $=await ss(M,f,o,e);return{nodeId:M,result:$}}))).forEach(({nodeId:M,result:$})=>{_.set(M,$)})}}i?.info?.log({type:"task",status:I.Success,id:u,message:`[${A(u)}] Workflow execution completed successfully`});const g=Object.fromEntries(_);return K(g,n)}catch(l){const f=l instanceof E?l:new E("DAG workflow execution failed",{id:u,cause:l instanceof Error?l:new Error(String(l))});return i?.info?.log({type:"task",status:I.Fail,id:u,message:`[${A(u)}] Workflow execution failed: ${f.message}`}),i?.error?.log(f),J(f,null,n)}},"execute")}},"dagWorkflow");export{E as A,_e as D,k as I,P as L,ct as R,I as T,j as W,de as a,ut as b,ye as c,ns as d,ge as e,at as g,ht as i,X as l,ee as s};
package/dist/index.d.ts CHANGED
@@ -74,18 +74,23 @@ declare class Recorder {
74
74
 
75
75
  interface FileInfo {
76
76
  path: string;
77
- base64: string;
77
+ base64?: string;
78
+ content?: string;
78
79
  mimeType: string;
79
80
  size: number;
80
81
  name: string;
81
- type: "image" | "document";
82
+ type: "image" | "document" | "text";
82
83
  }
83
- /**
84
- * Load a file and encode it to base64 with validation
85
- * @param filePath - Path to the file
86
- * @returns FileInfo object with base64 data and metadata
87
- */
88
- declare function loadFileAsBase64(filePath: string): Promise<FileInfo>;
84
+ type TextFileInfo = FileInfo & {
85
+ content: string;
86
+ base64?: never;
87
+ type: "text";
88
+ };
89
+ type Base64FileInfo = FileInfo & {
90
+ base64: string;
91
+ content?: never;
92
+ type: "image" | "document";
93
+ };
89
94
 
90
95
  interface ToolSchema {
91
96
  name: string;
@@ -114,12 +119,13 @@ declare class Chat {
114
119
  setToolSchemas(schemas: ToolSchema[]): void;
115
120
  addSystem(message: string): void;
116
121
  addUser(message: string): void;
117
- addUserWithFiles(message: string, files?: FileInfo[]): void;
122
+ addUser(message: string, instruction: string): void;
123
+ addUser(message: string, instruction: string, files: FileInfo[]): void;
124
+ addUser(message: string, files: FileInfo[]): any;
118
125
  addAssistant(message: string, toolCalls?: ToolCall[]): void;
119
126
  addTools(input: Array<ChatItemToolCallResult>): void;
120
127
  hasFiles(): boolean;
121
- getTextContent(content: string | ChatContent[]): string;
122
- getFiles(content: string | ChatContent[]): FileInfo[];
128
+ latest(): ChatItem | undefined;
123
129
  toString(): string;
124
130
  }
125
131
 
@@ -206,11 +212,15 @@ interface ChatItemToolCall {
206
212
  role: "tool";
207
213
  content: Array<ChatItemToolCallResult>;
208
214
  }
209
- type ChatContent = ChatContentText | ChatContentFile;
215
+ type ChatContent = ChatContentText | ChatContentFile | ChatContentInstructions;
210
216
  interface ChatContentText {
211
217
  type: "text";
212
218
  text: string;
213
219
  }
220
+ interface ChatContentInstructions {
221
+ type: "instructions";
222
+ instructions: string;
223
+ }
214
224
  interface ChatContentFile {
215
225
  type: "file";
216
226
  file: FileInfo;
@@ -277,7 +287,7 @@ declare class Axle {
277
287
  private provider;
278
288
  private stats;
279
289
  private variables;
280
- private recorder;
290
+ recorder: Recorder;
281
291
  constructor(config: Partial<AIProviderConfig>);
282
292
  addWriter(writer: RecorderWriter): void;
283
293
  /**
@@ -296,11 +306,14 @@ declare class Axle {
296
306
  executeDAG(dagDefinition: DAGDefinition, variables?: Record<string, any>, options?: DAGWorkflowOptions): Promise<WorkflowResult>;
297
307
  get logs(): RecorderEntry[];
298
308
  /**
299
- * Load a file and encode it to base64 for use with multimodal models
300
- * @param filePath - Path to the image or PDF file
301
- * @returns FileInfo object with base64 data and metadata
309
+ * Load a file with the specified encoding or auto-detect based on file extension
310
+ * @param filePath - Path to the file
311
+ * @param encoding - How to load the file: "utf-8" for text, "base64" for binary, or omit for auto-detection
312
+ * @returns FileInfo object with appropriate content based on encoding
302
313
  */
303
- static loadFile(filePath: string): Promise<FileInfo>;
314
+ static loadFileContent(filePath: string): Promise<FileInfo>;
315
+ static loadFileContent(filePath: string, encoding: "utf-8"): Promise<TextFileInfo>;
316
+ static loadFileContent(filePath: string, encoding: "base64"): Promise<Base64FileInfo>;
304
317
  }
305
318
 
306
319
  declare enum ResTypes {
@@ -322,7 +335,11 @@ declare abstract class AbstractInstruct<O extends Record<string, ResTypeStrings>
322
335
  system: string | null;
323
336
  inputs: Record<string, string>;
324
337
  tools: Record<string, ToolExecutable>;
325
- files: FileInfo[];
338
+ files: Base64FileInfo[];
339
+ textReferences: Array<{
340
+ content: string;
341
+ name?: string;
342
+ }>;
326
343
  resFormat: O;
327
344
  rawResponse: string;
328
345
  finalPrompt: string;
@@ -331,8 +348,32 @@ declare abstract class AbstractInstruct<O extends Record<string, ResTypeStrings>
331
348
  addInput(name: string, value: string): void;
332
349
  addTools(tools: ToolExecutable[]): void;
333
350
  addTool(tool: ToolExecutable): void;
351
+ /**
352
+ * Add an image file to the task.
353
+ * Throws an error if the file type is not "image".
354
+ * @param file - the Base64FileInfo representing the image file
355
+ */
334
356
  addImage(file: FileInfo): void;
357
+ /**
358
+ * Add a document file to the task.
359
+ * Throws an error if the file type is not "document".
360
+ * @param file - the Base64FileInfo representing the document file
361
+ */
362
+ addDocument(file: FileInfo): void;
363
+ /**
364
+ * Add a file to the task. It can be an image or document file.
365
+ * Throws an error if the file type is not supported.
366
+ * @param file - the Base64FileInfo representing the document or image file
367
+ */
335
368
  addFile(file: FileInfo): void;
369
+ /**
370
+ * Add a text reference to the task.
371
+ * @param textFile - the TextFileInfo or string content of the reference
372
+ * @param options - optional name for the reference
373
+ */
374
+ addReference(textFile: FileInfo | TextFileInfo | string, options?: {
375
+ name?: string;
376
+ }): void;
336
377
  hasTools(): boolean;
337
378
  hasFiles(): boolean;
338
379
  get result(): StructuredOutput<O>;
@@ -341,7 +382,10 @@ declare abstract class AbstractInstruct<O extends Record<string, ResTypeStrings>
341
382
  options?: {
342
383
  warnUnused?: boolean;
343
384
  };
344
- }): string;
385
+ }): {
386
+ message: string;
387
+ instructions: string;
388
+ };
345
389
  protected getFinalUserPrompt(variables: Record<string, string>, runtime?: {
346
390
  recorder?: Recorder;
347
391
  options?: {
@@ -387,7 +431,10 @@ declare class ChainOfThought<O extends Record<string, ResTypeStrings>> extends A
387
431
  options?: {
388
432
  warnUnused?: boolean;
389
433
  };
390
- }): string;
434
+ }): {
435
+ message: string;
436
+ instructions: string;
437
+ };
391
438
  finalize(rawValue: string): StructuredOutput<O> & {
392
439
  thinking: any;
393
440
  };
@@ -443,6 +490,7 @@ interface ChatStep extends StepBase {
443
490
  tools?: string[];
444
491
  images?: ImageReference[];
445
492
  documents?: DocumentReference[];
493
+ references?: TextFileReference[];
446
494
  }
447
495
  interface WriteToDiskStep extends StepBase {
448
496
  uses: "write-to-disk";
@@ -460,6 +508,9 @@ interface ImageReference {
460
508
  interface DocumentReference {
461
509
  file: string;
462
510
  }
511
+ interface TextFileReference {
512
+ file: string;
513
+ }
463
514
 
464
515
  interface ConcurrentWorkflow {
465
516
  (jobConfig: BatchJob): WorkflowExecutable;
@@ -478,4 +529,4 @@ interface SerialWorkflow {
478
529
  }
479
530
  declare const serialWorkflow: SerialWorkflow;
480
531
 
481
- export { type AIProvider, Axle, ChainOfThought, type DAGDefinition, type DAGWorkflowOptions, type FileInfo, Instruct, type SerializedExecutionResponse, WriteOutputTask, concurrentWorkflow, dagWorkflow, loadFileAsBase64, serialWorkflow };
532
+ export { type AIProvider, Axle, ChainOfThought, type DAGDefinition, type DAGWorkflowOptions, type FileInfo, Instruct, LogLevel, type SerializedExecutionResponse, WriteOutputTask, concurrentWorkflow, dagWorkflow, serialWorkflow };
package/dist/index.js CHANGED
@@ -1,3 +1,3 @@
1
- var d=Object.defineProperty;var a=(c,e)=>d(c,"name",{value:e,configurable:!0});import{R as p,A as o,g,s as l,d as u,l as h,a as w,D as f}from"./dag-DzqZGULq.js";import{I as U,W,c as D}from"./dag-DzqZGULq.js";import"@anthropic-ai/sdk";import"@google/genai";import"openai";import"serialize-error";import"fs/promises";import"glob";import"node:fs/promises";import"node:path";class x{static{a(this,"Axle")}provider;stats={in:0,out:0};variables={};recorder=new p;constructor(e){if(Object.entries(e).length!==1)throw new o("Must have exactly one config");try{const r=Object.keys(e)[0],t=e[r];this.provider=g(r,t)}catch(r){throw r instanceof o?r:new o("Failed to initialize provider",{code:"PROVIDER_INIT_ERROR",cause:r instanceof Error?r:new Error(String(r))})}}addWriter(e){this.recorder.subscribe(e)}async execute(...e){try{let r;return r=await l(...e).execute({provider:this.provider,variables:this.variables,stats:this.stats,recorder:this.recorder}),r}catch(r){const t=r instanceof o?r:new o("Execution failed",{cause:r instanceof Error?r:new Error(String(r))});return this.recorder.error?.log(t),{response:null,error:t,success:!1}}}async executeDAG(e,r={},t){try{return await u(e,t).execute({provider:this.provider,variables:{...this.variables,...r},stats:this.stats,recorder:this.recorder})}catch(s){const i=s instanceof o?s:new o("DAG execution failed",{cause:s instanceof Error?s:new Error(String(s))});return this.recorder.error?.log(i),{response:null,error:i,success:!1}}}get logs(){return this.recorder.getLogs()}static async loadFile(e){return h(e)}}class n extends w{static{a(this,"ChainOfThought")}constructor(e,r){super(e,r)}static with(e,r){return r?new n(e,r):new n(e,f)}compile(e,r={}){const t=this.getFinalUserPrompt(e,r),s=this.getFormatInstructions();return[t,`
2
- Let's think step by step. Use <thinking></thinking> tags to show your reasoning and thought process.`,s].join(`
3
- `)}finalize(e){const r=this.parseTaggedSections(e),t=super.finalize(e,r);if("thinking"in r.tags)t.thinking=r.tags.thinking;else throw new Error("Expected results with tag <thinking> but it does not exist");return t}}export{x as Axle,n as ChainOfThought,U as Instruct,W as WriteOutputTask,D as concurrentWorkflow,u as dagWorkflow,h as loadFileAsBase64,l as serialWorkflow};
1
+ var d=Object.defineProperty;var a=(l,e)=>d(l,"name",{value:e,configurable:!0});import{R as p,A as o,g,s as u,d as h,l as c,a as f,D as w}from"./dag-CE2X29BG.js";import{I as P,L as U,W,c as D}from"./dag-CE2X29BG.js";import"@anthropic-ai/sdk";import"@google/genai";import"openai";import"serialize-error";import"fs/promises";import"glob";import"node:fs/promises";import"node:path";class x{static{a(this,"Axle")}provider;stats={in:0,out:0};variables={};recorder=new p;constructor(e){if(Object.entries(e).length!==1)throw new o("Must have exactly one config");try{const r=Object.keys(e)[0],t=e[r];this.provider=g(r,t)}catch(r){throw r instanceof o?r:new o("Failed to initialize provider",{code:"PROVIDER_INIT_ERROR",cause:r instanceof Error?r:new Error(String(r))})}}addWriter(e){this.recorder.subscribe(e)}async execute(...e){try{let r;return r=await u(...e).execute({provider:this.provider,variables:this.variables,stats:this.stats,recorder:this.recorder}),r}catch(r){const t=r instanceof o?r:new o("Execution failed",{cause:r instanceof Error?r:new Error(String(r))});return this.recorder.error?.log(t),{response:null,error:t,success:!1}}}async executeDAG(e,r={},t){try{return await h(e,t).execute({provider:this.provider,variables:{...this.variables,...r},stats:this.stats,recorder:this.recorder})}catch(s){const i=s instanceof o?s:new o("DAG execution failed",{cause:s instanceof Error?s:new Error(String(s))});return this.recorder.error?.log(i),{response:null,error:i,success:!1}}}get logs(){return this.recorder.getLogs()}static async loadFileContent(e,r){return r==="utf-8"?c(e,"utf-8"):r==="base64"?c(e,"base64"):c(e)}}class n extends f{static{a(this,"ChainOfThought")}constructor(e,r){super(e,r)}static with(e,r){return r?new n(e,r):new n(e,w)}compile(e,r={}){const t=this.getFinalUserPrompt(e,r),s=this.getFormatInstructions();return{message:t,instructions:`Let's think step by step. Use <thinking></thinking> tags to show your reasoning and thought process.
2
+
3
+ ${s}`}}finalize(e){const r=this.parseTaggedSections(e),t=super.finalize(e,r);if("thinking"in r.tags)t.thinking=r.tags.thinking;else throw new Error("Expected results with tag <thinking> but it does not exist");return t}}export{x as Axle,n as ChainOfThought,P as Instruct,U as LogLevel,W as WriteOutputTask,D as concurrentWorkflow,h as dagWorkflow,u as serialWorkflow};
package/package.json CHANGED
@@ -1,6 +1,10 @@
1
1
  {
2
2
  "name": "@fifthrevision/axle",
3
- "version": "0.4.0",
3
+ "version": "0.4.2",
4
+ "repository": {
5
+ "type": "git",
6
+ "url": "https://github.com/johncch/axle.git"
7
+ },
4
8
  "description": "axle is a command line tool for running workflows against LLM APIs.",
5
9
  "type": "module",
6
10
  "main": "./dist/index.js",
@@ -1,12 +0,0 @@
1
- var ge=Object.defineProperty;var c=(t,e)=>ge(t,"name",{value:e,configurable:!0});import de from"@anthropic-ai/sdk";import{GoogleGenAI as me,Type as he,FinishReason as w}from"@google/genai";import ye from"openai";import{serializeError as Ee}from"serialize-error";import{readFile as Ie,access as we,constants as Te}from"fs/promises";import{glob as Q}from"glob";import{readFile as F,access as j,stat as Pe,writeFile as Ae,mkdir as ve}from"node:fs/promises";import{resolve as B,extname as Ne,dirname as Re}from"node:path";class E extends Error{static{c(this,"AxleError")}code;id;details;constructor(e,s){super(e,{cause:s?.cause}),this.name=this.constructor.name,this.code=s?.code||"AXLE_ERROR",this.id=s?.id,this.details=s?.details,Object.setPrototypeOf(this,E.prototype)}}const O={CLAUDE_OPUS_4_20250514:"claude-opus-4-20250514",CLAUDE_OPUS_4_LATEST:"claude-opus-4-0",CLAUDE_SONNET_4_20250514:"claude-sonnet-4-20250514",CLAUDE_SONNET_4_LATEST:"claude-sonnet-4-0",CLAUDE_3_7_SONNET_20250219:"claude-3-7-sonnet-20250219",CLAUDE_3_7_SONNET_LATEST:"claude-3-7-sonnet-latest",CLAUDE_3_5_HAIKU_20241022:"claude-3-5-haiku-20241022",CLAUDE_3_5_HAIKU_LATEST:"claude-3-5-haiku-latest"},V=[O.CLAUDE_3_7_SONNET_LATEST,O.CLAUDE_3_7_SONNET_20250219,O.CLAUDE_3_5_HAIKU_LATEST,O.CLAUDE_3_5_HAIKU_20241022,O.CLAUDE_SONNET_4_LATEST,O.CLAUDE_SONNET_4_20250514,O.CLAUDE_OPUS_4_LATEST,O.CLAUDE_OPUS_4_20250514];var m=(t=>(t[t.Stop=0]="Stop",t[t.Length=1]="Length",t[t.FunctionCall=2]="FunctionCall",t[t.Error=3]="Error",t))(m||{});const Oe=O.CLAUDE_SONNET_4_LATEST;class Se{static{c(this,"AnthropicProvider")}name="Anthropic";client;model;constructor(e,s){this.model=s??Oe,this.client=new de({apiKey:e})}createChatRequest(e,s={}){const{recorder:n}=s;return e.hasFiles()&&!V.includes(this.model)&&n?.warn?.log(`Model ${this.model} may not support multimodal content. Use one of: ${V.join(", ")}`),new Me(this,e)}}class Me{static{c(this,"AnthropicChatRequest")}constructor(e,s){this.provider=e,this.chat=s}async execute(e){const{recorder:s}=e,{client:n,model:o}=this.provider,r={model:o,max_tokens:4096,...be(this.chat)};s?.debug?.log(r);let i;try{const a=await n.messages.create(r);i=Ge(a)}catch(a){i={type:"error",error:{type:a.error.error.type??"Undetermined",message:a.error.error.message??"Unexpected error from Anthropic"},usage:{in:0,out:0},raw:a}}return s?.debug?.log(i),i}}function ee(t){switch(t){case"max_tokens":return m.Length;case"end_turn":return m.Stop;case"stop_sequence":return m.Stop;case"tool_use":return m.FunctionCall;default:return m.Error}}c(ee,"getStopReason$2");function be(t){const e=t.messages.map(n=>{switch(n.role){case"assistant":const o=[];return o.push({type:"text",text:n.content}),n.toolCalls&&o.push(...n.toolCalls.map(r=>({type:"tool_use",id:r.id,name:r.name,input:r.arguments}))),{role:"assistant",content:o};case"tool":return{role:"user",content:n.content.map(r=>({type:"tool_result",tool_use_id:r.id,content:r.content}))};default:if(typeof n.content=="string")return{role:"user",content:n.content};{const r=[];for(const i of n.content)if(i.type==="text")r.push({type:"text",text:i.text});else if(i.type==="file"){const a=i.file;a.type==="image"?r.push({type:"image",source:{type:"base64",media_type:a.mimeType,data:a.base64}}):a.type==="document"&&a.mimeType==="application/pdf"&&r.push({type:"document",source:{type:"base64",media_type:"application/pdf",data:a.base64}})}return{role:"user",content:r}}}}),s=t.tools.map(n=>({name:n.name,description:n.description,input_schema:n.parameters}));return{system:t.system,messages:e,tools:s}}c(be,"prepareRequest$2");function Ge(t){const e=ee(t.stop_reason);if(e===m.Error)return{type:"error",error:{type:"Uncaught error",message:"Stop reason is not recognized."},usage:{in:t.usage.input_tokens,out:t.usage.output_tokens},raw:t};if(e===m.FunctionCall){const s=t.content[0],n=s.type==="text"?s.text:"",o=t.content.slice(1).map(r=>{if(r.type==="tool_use")return{id:r.id,name:r.name,arguments:r.input}}).filter(r=>r!==null);return{type:"success",id:t.id,model:t.model,reason:m.FunctionCall,message:{role:t.role,content:n,toolCalls:o},usage:{in:t.usage.input_tokens,out:t.usage.output_tokens},raw:t}}if(t.type=="message"){const s=t.content[0];if(s.type=="text")return{type:"success",id:t.id,model:t.model,reason:ee(t.stop_reason),message:{role:t.role,content:s.text},usage:{in:t.usage.input_tokens,out:t.usage.output_tokens},raw:t}}}c(Ge,"translate");const p={GEMINI_1_0_PRO_VISION_LATEST:"gemini-1.0-pro-vision-latest",GEMINI_PRO_VISION:"gemini-pro-vision",GEMINI_1_5_PRO_LATEST:"gemini-1.5-pro-latest",GEMINI_1_5_PRO_001:"gemini-1.5-pro-001",GEMINI_1_5_PRO_002:"gemini-1.5-pro-002",GEMINI_1_5_PRO:"gemini-1.5-pro",GEMINI_1_5_FLASH_LATEST:"gemini-1.5-flash-latest",GEMINI_1_5_FLASH_001:"gemini-1.5-flash-001",GEMINI_1_5_FLASH_001_TUNING:"gemini-1.5-flash-001-tuning",GEMINI_1_5_FLASH:"gemini-1.5-flash",GEMINI_1_5_FLASH_002:"gemini-1.5-flash-002",GEMINI_1_5_FLASH_8B:"gemini-1.5-flash-8b",GEMINI_1_5_FLASH_8B_001:"gemini-1.5-flash-8b-001",GEMINI_1_5_FLASH_8B_LATEST:"gemini-1.5-flash-8b-latest",GEMINI_1_5_FLASH_8B_EXP_0827:"gemini-1.5-flash-8b-exp-0827",GEMINI_1_5_FLASH_8B_EXP_0924:"gemini-1.5-flash-8b-exp-0924",GEMINI_2_5_PRO_EXP_03_25:"gemini-2.5-pro-exp-03-25",GEMINI_2_5_PRO_PREVIEW_03_25:"gemini-2.5-pro-preview-03-25",GEMINI_2_5_FLASH_PREVIEW_04_17:"gemini-2.5-flash-preview-04-17",GEMINI_2_5_FLASH_PREVIEW_05_20:"gemini-2.5-flash-preview-05-20",GEMINI_2_5_FLASH_PREVIEW_04_17_THINKING:"gemini-2.5-flash-preview-04-17-thinking",GEMINI_2_5_PRO_PREVIEW_05_06:"gemini-2.5-pro-preview-05-06",GEMINI_2_5_PRO_PREVIEW_06_05:"gemini-2.5-pro-preview-06-05",GEMINI_2_0_FLASH_EXP:"gemini-2.0-flash-exp",GEMINI_2_0_FLASH:"gemini-2.0-flash",GEMINI_2_0_FLASH_001:"gemini-2.0-flash-001",GEMINI_2_0_FLASH_EXP_IMAGE_GENERATION:"gemini-2.0-flash-exp-image-generation",GEMINI_2_0_FLASH_LITE_001:"gemini-2.0-flash-lite-001",GEMINI_2_0_FLASH_LITE:"gemini-2.0-flash-lite",GEMINI_2_0_FLASH_PREVIEW_IMAGE_GENERATION:"gemini-2.0-flash-preview-image-generation",GEMINI_2_0_FLASH_LITE_PREVIEW_02_05:"gemini-2.0-flash-lite-preview-02-05",GEMINI_2_0_FLASH_LITE_PREVIEW:"gemini-2.0-flash-lite-preview",GEMINI_2_0_PRO_EXP:"gemini-2.0-pro-exp",GEMINI_2_0_PRO_EXP_02_05:"gemini-2.0-pro-exp-02-05",GEMINI_EXP_1206:"gemini-exp-1206",GEMINI_2_0_FLASH_THINKING_EXP_01_21:"gemini-2.0-flash-thinking-exp-01-21",GEMINI_2_0_FLASH_THINKING_EXP:"gemini-2.0-flash-thinking-exp",GEMINI_2_0_FLASH_THINKING_EXP_1219:"gemini-2.0-flash-thinking-exp-1219",GEMINI_2_5_FLASH_PREVIEW_TTS:"gemini-2.5-flash-preview-tts",GEMINI_2_5_PRO_PREVIEW_TTS:"gemini-2.5-pro-preview-tts",LEARNLM_2_0_FLASH_EXPERIMENTAL:"learnlm-2.0-flash-experimental",GEMMA_3_1B_IT:"gemma-3-1b-it",GEMMA_3_4B_IT:"gemma-3-4b-it",GEMMA_3_12B_IT:"gemma-3-12b-it",GEMMA_3_27B_IT:"gemma-3-27b-it",GEMMA_3N_E4B_IT:"gemma-3n-e4b-it"},te=[p.GEMINI_1_0_PRO_VISION_LATEST,p.GEMINI_PRO_VISION,p.GEMINI_1_5_PRO_LATEST,p.GEMINI_1_5_PRO_001,p.GEMINI_1_5_PRO_002,p.GEMINI_1_5_PRO,p.GEMINI_1_5_FLASH_LATEST,p.GEMINI_1_5_FLASH_001,p.GEMINI_1_5_FLASH_001_TUNING,p.GEMINI_1_5_FLASH,p.GEMINI_1_5_FLASH_002,p.GEMINI_1_5_FLASH_8B,p.GEMINI_1_5_FLASH_8B_001,p.GEMINI_1_5_FLASH_8B_LATEST,p.GEMINI_1_5_FLASH_8B_EXP_0827,p.GEMINI_1_5_FLASH_8B_EXP_0924,p.GEMINI_2_5_PRO_EXP_03_25,p.GEMINI_2_5_PRO_PREVIEW_03_25,p.GEMINI_2_5_FLASH_PREVIEW_04_17,p.GEMINI_2_5_FLASH_PREVIEW_05_20,p.GEMINI_2_5_FLASH_PREVIEW_04_17_THINKING,p.GEMINI_2_5_PRO_PREVIEW_05_06,p.GEMINI_2_5_PRO_PREVIEW_06_05,p.GEMINI_2_0_FLASH_EXP,p.GEMINI_2_0_FLASH,p.GEMINI_2_0_FLASH_001,p.GEMINI_2_0_FLASH_EXP_IMAGE_GENERATION,p.GEMINI_2_0_FLASH_LITE_001,p.GEMINI_2_0_FLASH_LITE,p.GEMINI_2_0_FLASH_PREVIEW_IMAGE_GENERATION,p.GEMINI_2_0_FLASH_LITE_PREVIEW_02_05,p.GEMINI_2_0_FLASH_LITE_PREVIEW,p.GEMINI_2_0_PRO_EXP,p.GEMINI_2_0_PRO_EXP_02_05,p.GEMINI_EXP_1206,p.GEMINI_2_0_FLASH_THINKING_EXP_01_21,p.GEMINI_2_0_FLASH_THINKING_EXP,p.GEMINI_2_0_FLASH_THINKING_EXP_1219,p.GEMINI_2_5_FLASH_PREVIEW_TTS,p.GEMINI_2_5_PRO_PREVIEW_TTS,p.LEARNLM_2_0_FLASH_EXPERIMENTAL,p.GEMMA_3_1B_IT,p.GEMMA_3_4B_IT,p.GEMMA_3_12B_IT,p.GEMMA_3_27B_IT,p.GEMMA_3N_E4B_IT],ke=p.GEMINI_2_5_FLASH_PREVIEW_05_20;class xe{static{c(this,"GoogleAIProvider")}name="GoogleAI";client;model;constructor(e,s){this.model=s??ke,this.client=new me({apiKey:e})}createChatRequest(e,s={}){const{recorder:n}=s;return e.hasFiles()&&!te.includes(this.model)&&n?.warn.log(`Model ${this.model} does not support multimodal content. Use one of: ${te.join(", ")}`),new $e(this,e)}}class $e{static{c(this,"GoogleAIChatRequest")}constructor(e,s){this.provider=e,this.chat=s}async execute(e){const{recorder:s}=e,{client:n,model:o}=this.provider,r=this.prepareRequest(this.chat);s?.debug?.log(r);let i;try{const a=await n.models.generateContent({model:o,...r});i=Le(a,e)}catch(a){s?.error?.log(a),i={type:"error",error:{type:a.name??"Undetermined",message:a.message??"Unexpected error from Google AI"},usage:{in:0,out:0},raw:a}}return s?.debug?.log(i),i}prepareRequest(e){let s;e.messages.length===1&&e.messages[0].role=="user"&&typeof e.messages[0].content=="string"?s=e.messages[0].content:s=e.messages.map(o=>{if(o.role==="user"){if(typeof o.content=="string")return{role:"user",parts:[{text:o.content}]};{const r=[];for(const i of o.content)if(i.type==="text")r.push({text:i.text});else if(i.type==="file"){const a=i.file;(a.type==="image"||a.type==="document")&&r.push({inlineData:{mimeType:a.mimeType,data:a.base64}})}return{role:"user",parts:r}}}else if(o.role==="assistant"){const r={role:"assistant",parts:[]};return o.content&&r.parts.push({text:o.content}),o.toolCalls&&(r.parts=r.parts.concat(o.toolCalls.map(i=>{let a;return typeof i.arguments=="string"?a=JSON.parse(i.arguments):a=i.arguments,{functionCall:{id:i.id??void 0,name:i.name,args:a}}}))),r}else if(o.role==="tool")return{role:"user",parts:o.content.map(r=>({functionResponse:{id:r.id??void 0,name:r.name,response:{output:r.content}}}))}});const n={};return e.system&&(n.systemInstruction=e.system),e.tools.length>0&&(n.tools=e.tools.map(o=>({functionDeclarations:[{name:o.name,description:o.description,parameters:{...o.parameters,type:he.OBJECT}}]}))),{contents:s,config:n}}}function Le(t,e){const{recorder:s}=e,n=t.usageMetadata.promptTokenCount,o=t.usageMetadata.totalTokenCount-n,r={in:n,out:o};if(!t)return{type:"error",error:{type:"InvalidResponse",message:"Invalid or empty response from Google AI"},usage:{in:0,out:0},raw:t};if(t.promptFeedback&&t.promptFeedback.blockReason)return{type:"error",error:{type:"Blocked",message:`Response blocked by Google AI: ${t.promptFeedback.blockReason}, ${t.promptFeedback.blockReasonMessage}`},usage:r,raw:t};if(!t.candidates||t.candidates.length===0)return{type:"error",error:{type:"InvalidResponse",message:"Invalid or empty response from Google AI"},usage:{in:0,out:0},raw:t};t.candidates.length>1&&s?.warn?.log(`We received ${t.candidates.length} response candidates`);const i=t.candidates[0],l=(i.content?.parts||[]).map(f=>f.text).filter(f=>f!==void 0).join(""),[u,_]=Fe(i.finishReason);if(u){let f;return t.functionCalls&&(f=t.functionCalls.map(d=>({id:d.id,name:d.name,arguments:JSON.stringify(d.args)}))),{type:"success",id:t.responseId,model:t.modelVersion,reason:t.functionCalls?m.FunctionCall:_,message:{role:"assistant",...l?{content:l}:{},...f?{toolCalls:f}:{}},usage:r,raw:t}}else return{type:"error",error:{type:"Undetermined",message:`Unexpected stop reason: ${_}`},usage:r,raw:t}}c(Le,"translateResponse$2");function Fe(t){switch(t){case w.STOP:return[!0,m.Stop];case w.MAX_TOKENS:return[!0,m.Length];case w.FINISH_REASON_UNSPECIFIED:case w.SAFETY:case w.RECITATION:case w.LANGUAGE:case w.OTHER:case w.BLOCKLIST:case w.PROHIBITED_CONTENT:case w.SPII:case w.MALFORMED_FUNCTION_CALL:case w.IMAGE_SAFETY:return[!1,m.Error]}}c(Fe,"getStopReason$1");const Ce="http://localhost:11434";class Ue{static{c(this,"OllamaProvider")}name="Ollama";url;model;recorder;constructor(e,s){this.url=s||Ce,this.model=e}createChatRequest(e,s={}){const{recorder:n}=s;return e.hasFiles()&&n?.warn?.log(`Ollama model ${this.model} multimodal support depends on the specific model. Ensure you're using a vision-capable model like llava.`),new De(this.url,this.model,e)}}class De{static{c(this,"OllamaChatCompletionRequest")}chat;url;model;constructor(e,s,n){this.url=e,this.model=s,this.chat=n}async execute(e){const{recorder:s}=e,n={model:this.model,stream:!1,options:{temperature:.7},...He(this.chat)};s?.debug?.log(n);let o;try{const r=await fetch(`${this.url}/api/chat`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(n)});if(!r.ok)throw console.log(r),new Error(`HTTP error! status: ${r.status}`);const i=await r.json();o=We(i)}catch(r){s?.error?.log("Error fetching Ollama response:",r),o={type:"error",error:{type:"OllamaError",message:r.message||"Unexpected error from Ollama"},usage:{in:0,out:0},raw:JSON.stringify(r)}}return s?.debug?.log(o),o}}function He(t){const e=[];t.system&&e.push({role:"system",content:t.system});const s=t.tools.length>0?t.tools.map(o=>({type:"function",function:o})):void 0,n=t.messages.map(o=>{switch(o.role){case"tool":return o.content.map(r=>({role:"tool",tool_call_id:r.id,content:r.content}));case"assistant":return{role:o.role,content:o.content,tool_calls:o.toolCalls.map(r=>{const i=r.id;return{type:"function",function:{name:r.name,arguments:r.arguments},...i&&{id:i}}})};default:if(typeof o.content=="string")return{role:o.role,content:o.content};{let r="";const i=[];for(const a of o.content)if(a.type==="text")r+=a.text;else if(a.type==="file"){const l=a.file;l.type==="image"&&i.push(l.base64)}return{role:o.role,content:r,...i.length>0&&{images:i}}}}}).flat(1/0);return{messages:[...e,...n],...s&&{tools:s}}}c(He,"prepareRequest$1");function We(t){if(t.done_reason==="stop"&&t.message){const e=t.message.content,s=[];if(t.message.tool_calls)for(const o of t.message.tool_calls)s.push({id:o.id,name:o.function.name,arguments:o.function.arguments});const n=s.length>0;return{type:"success",id:`ollama-${Date.now()}`,model:t.model,reason:n?m.FunctionCall:m.Stop,message:{role:"assistant",content:e,...n&&{toolCalls:s}},usage:{in:t.prompt_eval_count||0,out:t.eval_count||0},raw:t}}return{type:"error",error:{type:"OllamaError",message:"Unexpected error from Ollama"},usage:{in:0,out:0},raw:t}}c(We,"translateResponse$1");const g={GPT_4_1:"gpt-4.1",GPT_4_1_2025_04_14:"gpt-4.1-2025-04-14",GPT_4_1_MINI:"gpt-4.1-mini",GPT_4_1_MINI_2025_04_14:"gpt-4.1-mini-2025-04-14",GPT_4_1_NANO:"gpt-4.1-nano",GPT_4_1_NANO_2025_04_14:"gpt-4.1-nano-2025-04-14",GPT_4O:"gpt-4o",GPT_4O_2024_05_13:"gpt-4o-2024-05-13",GPT_4O_2024_08_06:"gpt-4o-2024-08-06",GPT_4O_2024_11_20:"gpt-4o-2024-11-20",GPT_4O_AUDIO_PREVIEW:"gpt-4o-audio-preview",GPT_4O_AUDIO_PREVIEW_2024_10_01:"gpt-4o-audio-preview-2024-10-01",GPT_4O_AUDIO_PREVIEW_2024_12_17:"gpt-4o-audio-preview-2024-12-17",GPT_4O_AUDIO_PREVIEW_2025_06_03:"gpt-4o-audio-preview-2025-06-03",GPT_4O_MINI:"gpt-4o-mini",GPT_4O_MINI_2024_07_18:"gpt-4o-mini-2024-07-18",GPT_4O_MINI_AUDIO_PREVIEW:"gpt-4o-mini-audio-preview",GPT_4O_MINI_AUDIO_PREVIEW_2024_12_17:"gpt-4o-mini-audio-preview-2024-12-17",GPT_4O_MINI_REALTIME_PREVIEW:"gpt-4o-mini-realtime-preview",GPT_4O_MINI_REALTIME_PREVIEW_2024_12_17:"gpt-4o-mini-realtime-preview-2024-12-17",GPT_4O_MINI_SEARCH_PREVIEW:"gpt-4o-mini-search-preview",GPT_4O_MINI_SEARCH_PREVIEW_2025_03_11:"gpt-4o-mini-search-preview-2025-03-11",GPT_4O_MINI_TRANSCRIBE:"gpt-4o-mini-transcribe",GPT_4O_MINI_TTS:"gpt-4o-mini-tts",GPT_4O_REALTIME_PREVIEW:"gpt-4o-realtime-preview",GPT_4O_REALTIME_PREVIEW_2024_10_01:"gpt-4o-realtime-preview-2024-10-01",GPT_4O_REALTIME_PREVIEW_2024_12_17:"gpt-4o-realtime-preview-2024-12-17",GPT_4O_REALTIME_PREVIEW_2025_06_03:"gpt-4o-realtime-preview-2025-06-03",GPT_4O_SEARCH_PREVIEW:"gpt-4o-search-preview",GPT_4O_SEARCH_PREVIEW_2025_03_11:"gpt-4o-search-preview-2025-03-11",GPT_4O_TRANSCRIBE:"gpt-4o-transcribe",O3_MINI:"o3-mini",O3_MINI_2025_01_31:"o3-mini-2025-01-31",O4_MINI:"o4-mini",O4_MINI_2025_04_16:"o4-mini-2025-04-16"},Be=[g.GPT_4_1,g.GPT_4_1_2025_04_14,g.GPT_4_1_MINI,g.GPT_4_1_MINI_2025_04_14,g.GPT_4_1_NANO,g.GPT_4_1_NANO_2025_04_14,g.GPT_4O,g.GPT_4O_2024_05_13,g.GPT_4O_2024_08_06,g.GPT_4O_2024_11_20,g.GPT_4O_AUDIO_PREVIEW,g.GPT_4O_AUDIO_PREVIEW_2024_10_01,g.GPT_4O_AUDIO_PREVIEW_2024_12_17,g.GPT_4O_AUDIO_PREVIEW_2025_06_03,g.GPT_4O_MINI,g.GPT_4O_MINI_2024_07_18,g.GPT_4O_MINI_AUDIO_PREVIEW,g.GPT_4O_MINI_AUDIO_PREVIEW_2024_12_17,g.GPT_4O_MINI_REALTIME_PREVIEW,g.GPT_4O_MINI_REALTIME_PREVIEW_2024_12_17,g.GPT_4O_MINI_SEARCH_PREVIEW,g.GPT_4O_MINI_SEARCH_PREVIEW_2025_03_11,g.GPT_4O_MINI_TRANSCRIBE,g.GPT_4O_MINI_TTS,g.GPT_4O_REALTIME_PREVIEW,g.GPT_4O_REALTIME_PREVIEW_2024_10_01,g.GPT_4O_REALTIME_PREVIEW_2024_12_17,g.GPT_4O_REALTIME_PREVIEW_2025_06_03,g.GPT_4O_SEARCH_PREVIEW,g.GPT_4O_SEARCH_PREVIEW_2025_03_11,g.GPT_4O_TRANSCRIBE,g.O3_MINI,g.O3_MINI_2025_01_31,g.O4_MINI,g.O4_MINI_2025_04_16];class qe{static{c(this,"OpenAIChatCompletionRequest")}constructor(e,s){this.provider=e,this.chat=s}async execute(e){const{recorder:s}=e,{client:n,model:o}=this.provider,r={model:o,...Ke(this.chat)};s?.debug?.log(r);let i;try{const a=await n.chat.completions.create(r);i=Je(a)}catch(a){s?.error?.log(a),i={type:"error",error:{type:a.type??"Undetermined",message:a.message??"Unexpected error from OpenAI"},usage:{in:0,out:0},raw:a}}return s?.debug?.log(i),i}}function Xe(t){switch(t){case"length":return m.Length;case"stop":return m.Stop;case"tool_calls":return m.FunctionCall;default:return m.Error}}c(Xe,"getStopReason");function Ke(t){const e=[];t.system&&e.push({role:"system",content:t.system});const s=t.tools.length>0?t.tools.map(o=>({type:"function",function:o})):void 0,n=t.messages.map(o=>{switch(o.role){case"tool":return o.content.map(i=>({role:"tool",tool_call_id:i.id,content:i.content}));case"assistant":const r=o.toolCalls?.map(i=>{const a=i.id;return{type:"function",function:{name:i.name,arguments:typeof i.arguments=="string"?i.arguments:JSON.stringify(i.arguments)},...a&&{id:a}}});return{role:o.role,content:o.content,...r&&{toolCalls:r}};default:if(typeof o.content=="string")return{role:o.role,content:o.content};{const i=[];for(const a of o.content)if(a.type==="text")i.push({type:"text",text:a.text});else if(a.type==="file"){const l=a.file;l.type==="image"&&i.push({type:"image_url",image_url:{url:`data:${l.mimeType};base64,${l.base64}`}})}return{role:o.role,content:i}}}}).flat(1/0);return{messages:[...e,...n],...s&&{tools:s}}}c(Ke,"prepareRequest");function Je(t){if(t.choices.length>0){const e=t.choices[0],s=e.message.tool_calls?.map(n=>({id:n.id,name:n.function.name,arguments:n.function.arguments}));return{type:"success",id:t.id,model:t.model,reason:Xe(e.finish_reason),message:{content:e.message.content??"",role:e.message.role,toolCalls:s},usage:{in:t.usage?.prompt_tokens??0,out:t.usage?.completion_tokens??0},raw:t}}return{type:"error",error:{type:"undetermined",message:"Unexpected response from OpenAI"},usage:{in:t.usage?.prompt_tokens??0,out:t.usage?.completion_tokens??0},raw:t}}c(Je,"translateResponse");class ze{static{c(this,"OpenAIResponsesAPI")}constructor(e,s){this.provider=e,this.chat=s}async execute(e){const{recorder:s}=e,{client:n,model:o}=this.provider,r=Ye(this.chat,o);s?.debug?.heading.log("[Open AI Provider] Using the Responses API"),s?.debug?.log(r);let i;try{const a=await n.responses.create(r);i=Ze(a)}catch(a){s?.error?.log(a),i={type:"error",error:{type:a.type??"Undetermined",message:a.message??"Unexpected error from OpenAI"},usage:{in:0,out:0},raw:a}}return s?.debug?.log(i),i}}function Ye(t,e){const s=t.messages.map(o=>{if(o.role==="tool")return o.content.map(r=>({type:"function_call_output",call_id:r.id,output:r.content}));if(o.role==="assistant"){const r=o.toolCalls?.map(i=>{const a=i.id;return{type:"function",function:{name:i.name,arguments:typeof i.arguments=="string"?i.arguments:JSON.stringify(i.arguments)},...a&&{id:a}}});return{role:o.role,content:o.content,...r&&{toolCalls:r}}}if(typeof o.content=="string")return{role:o.role,content:o.content};{const r=[];for(const i of o.content)if(i.type==="text")r.push({type:"input_text",text:i.text});else if(i.type==="file"){const a=i.file;a.type==="image"?r.push({type:"input_image",image_url:`data:${a.mimeType};base64,${a.base64}`}):a.type==="document"&&r.push({type:"input_file",filename:a.path,file_data:`data:${a.mimeType};base64,${a.base64}`})}return{role:o.role,content:r}}}).flat(1),n={model:e,input:s};return t.system&&(n.instructions=t.system),t.tools.length>0&&(n.tools=t.tools.map(o=>({type:"function",strict:!0,...o}))),n}c(Ye,"prepareResponseRequest");function Ze(t){if(t.error)return{type:"error",error:{type:t.error.code||"undetermined",message:t.error.message||"Response generation failed"},usage:{in:t.usage?.input_tokens??0,out:t.usage?.output_tokens??0},raw:t};const e=t.output?.filter(s=>s.type==="function_call")?.map(s=>({id:s.id||"",name:s.function?.name||"",arguments:s.function?.arguments||""}));return{type:"success",id:t.id,model:t.model||"",reason:t.incomplete_details?m.Error:m.Stop,message:{content:t.output_text||"",role:"assistant",...e?.length&&{toolCalls:e}},usage:{in:t.usage?.input_tokens??0,out:t.usage?.output_tokens??0},raw:t}}c(Ze,"translateResponseToAIResponse");const Qe=g.GPT_4_1;class je{static{c(this,"OpenAIProvider")}name="OpenAI";client;model;constructor(e,s){this.model=s||Qe,this.client=new ye({apiKey:e})}createChatRequest(e,s={}){const{recorder:n}=s;return Be.includes(this.model)?new ze(this,e):new qe(this,e)}}function Ve(t,e){if(!e||Object.keys(e).length===0)throw new E(`The provider ${t} is not configured. Please check your configuration.`);switch(t){case"openai":return new je(e["api-key"],e.model);case"anthropic":return new Se(e["api-key"],e.model);case"googleai":return new xe(e["api-key"],e.model);case"ollama":{const s=e;return new Ue(s.model,s.url)}default:throw new E("The provider is unsupported")}}c(Ve,"getProvider");class Y extends E{static{c(this,"TaskError")}constructor(e,s){super(e,{code:"TASK_ERROR",id:s?.id,details:{taskType:s?.taskType,taskIndex:s?.taskIndex,...s?.details},cause:s?.cause}),Object.setPrototypeOf(this,Y.prototype)}}const I={Running:"running",Success:"success",PartialSuccess:"partialSuccess",Fail:"fail"};var P=(t=>(t[t.Trace=10]="Trace",t[t.Debug=20]="Debug",t[t.Info=30]="Info",t[t.Warn=40]="Warn",t[t.Error=50]="Error",t[t.Fatal=60]="Fatal",t))(P||{});class et{static{c(this,"Recorder")}instanceId=crypto.randomUUID();currentLevel=P.Info;logs=[];writers=[];_debug;_info;_warn;_error;constructor(){this.buildMethods()}buildMethods(){this._debug=P.Debug>=this.currentLevel?this.createLoggingFunction(P.Debug):null,this._info=P.Info>=this.currentLevel?this.createLoggingFunction(P.Info):null,this._warn=P.Warn>=this.currentLevel?this.createLoggingFunction(P.Warn):null,this._error=this.createLoggingFunction(P.Error)}set level(e){this.currentLevel=e,this.buildMethods()}get level(){return this.currentLevel}get info(){return this._info}get warn(){return this._warn}get error(){return this._error}get debug(){return this._debug}subscribe(e){this.writers.includes(e)||this.writers.push(e)}unsubscribe(e){const s=this.writers.indexOf(e);s!==-1&&this.writers.splice(s,1)}publish(e){this.logs.push(e);for(const s of this.writers)s.handleEvent(e)}logFunction(e,s,...n){let o=n.map(r=>typeof r=="string"?{message:r}:r instanceof Error?Ee(r):r);this.publish({level:e,time:Date.now(),kind:s,payload:o})}createLoggingFunction(e){return{log:this.logFunction.bind(this,e,"body"),heading:{log:this.logFunction.bind(this,e,"heading")}}}getLogs(e=P.Info){return this.logs.filter(s=>s.level>=e)}async shutdown(){for(const e of this.writers)typeof e.flush=="function"&&await e.flush()}}async function tt({path:t,defaults:e,loader:s="File"}){let n=null,o="";if(t)try{o=B(t),n=await F(o,{encoding:"utf-8"})}catch{throw new Error(`${s} not found, see --help for details`)}else{for(const r of e.formats)try{o=B(e.name+"."+r),n=await F(o,{encoding:"utf-8"});break}catch{continue}if(n===null)throw new Error(`${s} not found, see --help for details`)}return{content:n,format:o.split(".").pop()??""}}c(tt,"loadFile");async function st(t,e){let s="";for(const n of t){const o=await Q(n);e?.debug?.log(`many-files parser. For glob "${n}", found ${o.length} files.`);const r=await Promise.all(o.map(async i=>{const a=await F(i,"utf-8");return i+`:
2
- `+a}));s+=r.join(`
3
- `)}return s}c(st,"loadManyFiles");function nt(t,e){t=t.replace("**/*","**");const s=/(?<asterisks>\*{1,2})(?<extension>\.[^\\/]+)?/,n=t.match(s);if(n){let o="";return n.groups?.asterisks.length==1?o+=e.stem:o+=e.dir+e.stem,n.groups?.extension?o+=n.groups.extension:o+=e.ext,t.replace(n[0],o)}return t}c(nt,"replaceFilePattern");function rt(t){const e=/(?<name>[^\\/]+)(?<extension>\.[^\\/]+)$/,s=t.match(e);return s&&s.length>0&&s.groups?{abs:t,dir:t.replace(s[0],""),ext:s.groups.extension,stem:s.groups.name,name:s[0]}:null}c(rt,"pathToComponents");async function se(t){const e=Re(t);try{await j(e)}catch{await ve(e),await se(e)}}c(se,"ensureDirectoryExistence");async function ot({filePath:t,content:e}){await se(t),await Ae(t,e)}c(ot,"writeFileWithDirectories");const ne=[".jpg",".jpeg",".png",".gif",".webp",".bmp",".tiff"],re=[".pdf"],oe=20*1024*1024;async function q(t){const e=B(t);try{await j(e)}catch{throw new Error(`File not found: ${t}`)}const s=await Pe(e);if(s.size>oe)throw new Error(`File too large: ${s.size} bytes. Maximum allowed: ${oe} bytes`);const n=Ne(e).toLowerCase();let o,r;if(ne.includes(n))switch(o="image",n){case".jpg":case".jpeg":r="image/jpeg";break;case".png":r="image/png";break;case".gif":r="image/gif";break;case".webp":r="image/webp";break;case".bmp":r="image/bmp";break;case".tiff":r="image/tiff";break;default:r="image/jpeg"}else if(re.includes(n))o="document",r="application/pdf";else throw new Error(`Unsupported file type: ${n}. Supported types: ${[...ne,...re].join(", ")}`);const a=(await F(e)).toString("base64");return{path:e,base64:a,mimeType:r,size:s.size,name:e.split("/").pop()||"",type:o}}c(q,"loadFileAsBase64");function it(t,e){return!t||typeof t!="object"?(e&&(e.value="Not an object"),!1):at(t.using,e)?!t.jobs||typeof t.jobs!="object"?(e&&(e.value="Missing or invalid 'jobs' property"),!1):ie(t.jobs,e)?!0:(e&&(e.value=`Invalid 'jobs' property: ${e?.value}`),!1):(e&&(e.value=`Invalid 'using' property: ${e?.value}`),!1)}c(it,"isJobConfig");function at(t,e){if(!t||typeof t!="object")return e&&(e.value="Not an object"),!1;if(typeof t.engine!="string")return e&&(e.value="Missing or invalid 'engine' property"),!1;if(!["openai","anthropic","ollama","googleai"].includes(t.engine))return e&&(e.value="Invalid provider type. Must be 'openai', 'anthropic', 'googleai', or 'ollama'"),!1;switch(t.engine){case"ollama":if("model"in t&&typeof t.model!="string")return e&&(e.value="Property 'model' must be a string"),!1;if("url"in t&&typeof t.url!="string")return e&&(e.value="Property 'url' must be a string"),!1;break;case"googleai":case"anthropic":case"openai":if("api-key"in t&&typeof t["api-key"]!="string")return e&&(e.value="Property 'api-key' must be a string"),!1;if("model"in t&&typeof t.model!="string")return e&&(e.value="Property 'model' must be a string"),!1;break}return!0}c(at,"isUsing");function ie(t,e){for(const[s,n]of Object.entries(t))if(!ct(n,e))return e&&(e.value=`Invalid job '${s}': ${e?.value}`),!1;return!0}c(ie,"isDAGJob");function ct(t,e){if(!t||typeof t!="object")return e&&(e.value="Not an object"),!1;if(!ut(t,e))return!1;if("dependsOn"in t&&t.dependsOn!==void 0){const s=t.dependsOn;if(typeof s!="string")if(Array.isArray(s)){for(let n=0;n<s.length;n++)if(typeof s[n]!="string")return e&&(e.value=`Dependency at index ${n} must be a string`),!1}else return e&&(e.value="Property 'dependsOn' must be a string or array of strings"),!1}return!0}c(ct,"isDAGJobValue");function ut(t,e){return!t||typeof t!="object"?(e&&(e.value="Not an object"),!1):"batch"in t?_t(t,e):lt(t,e)}c(ut,"isJob");function lt(t,e){if(!t||typeof t!="object")return e&&(e.value="Not an object"),!1;if("batch"in t)return e&&(e.value="Serial job should not have a batch property"),!1;if(t.tools!==void 0){if(!Array.isArray(t.tools))return e&&(e.value="Property 'tools' must be an array"),!1;for(const s of t.tools)if(typeof s!="string")return e&&(e.value="All tools must be strings"),!1}if(!Array.isArray(t.steps))return e&&(e.value="Property 'steps' must be an array"),!1;for(let s=0;s<t.steps.length;s++)if(!ae(t.steps[s],e))return e&&(e.value=`Invalid step at index ${s}: ${e?.value}`),!1;return!0}c(lt,"isSerialJob");function _t(t,e){if(!t||typeof t!="object")return e&&(e.value="Not an object"),!1;if(t.tools!==void 0){if(!Array.isArray(t.tools))return e&&(e.value="Property 'tools' must be an array"),!1;for(const s of t.tools)if(typeof s!="string")return e&&(e.value="All tools must be strings"),!1}if(!Array.isArray(t.batch))return e&&(e.value="Property 'batch' must be an array"),!1;for(let s=0;s<t.batch.length;s++){const n=t.batch[s];if(!n||typeof n!="object")return e&&(e.value=`Batch item at index ${s} must be an object`),!1;if(n.type!=="files")return e&&(e.value=`Batch item at index ${s} must have type 'files'`),!1;if(typeof n.source!="string")return e&&(e.value=`Batch item at index ${s} must have a string 'source' property`),!1;if(typeof n.bind!="string")return e&&(e.value=`Batch item at index ${s} must have a string 'bind' property`),!1;if(n["skip-if"]!==void 0){if(!Array.isArray(n["skip-if"]))return e&&(e.value=`Batch item at index ${s} must have an array 'skip-if' property`),!1;for(let o=0;o<n["skip-if"].length;o++)if(!ft(n["skip-if"][o],e))return e&&(e.value=`Invalid skip condition at index ${o} in batch item ${s}: ${e?.value}`),!1}}if(!Array.isArray(t.steps))return e&&(e.value="Property 'steps' must be an array"),!1;for(let s=0;s<t.steps.length;s++)if(!ae(t.steps[s],e))return e&&(e.value=`Invalid step at index ${s}: ${e?.value}`),!1;return!0}c(_t,"isBatchJob");function ft(t,e){return!t||typeof t!="object"?(e&&(e.value="Not an object"),!1):t.type!=="file-exist"?(e&&(e.value="Property 'type' must be 'file-exist'"),!1):typeof t.pattern!="string"?(e&&(e.value="Property 'pattern' must be a string"),!1):!0}c(ft,"isSkipOptions");function ae(t,e){return!t||typeof t!="object"?(e&&(e.value="Not an object"),!1):!t.uses||typeof t.uses!="string"?(e&&(e.value="Step must have a string 'uses' property"),!1):t.uses==="chat"?pt(t,e):t.uses==="write-to-disk"?gt(t,e):(e&&(e.value=`Unknown uses type: ${t.uses}`),!1)}c(ae,"isStep");function pt(t,e){if(!t||typeof t!="object")return e&&(e.value="Not an object"),!1;if(t.uses!=="chat")return e&&(e.value="Uses must be 'chat'"),!1;if(typeof t.message!="string")return e&&(e.value="Property 'message' must be a string"),!1;if(t.output!==void 0){if(!t.output||typeof t.output!="object"||Array.isArray(t.output))return e&&(e.value="Property 'output' must be an object"),!1;const s=["string","string[]","number","boolean"];for(const[n,o]of Object.entries(t.output))if(typeof n!="string"||typeof o!="string"||!s.includes(o))return e&&(e.value="Property 'output' must be a Record<string, ResTypeStrings> where ResTypeStrings is 'string' | 'string[]' | 'number' | 'boolean'"),!1}if(t.system!==void 0&&typeof t.system!="string")return e&&(e.value="Property 'system' must be a string"),!1;if(t.replace!==void 0){if(!Array.isArray(t.replace))return e&&(e.value="Property 'replace' must be an array"),!1;for(let s=0;s<t.replace.length;s++)if(!dt(t.replace[s],e))return e&&(e.value=`Invalid replace at index ${s}: ${e?.value}`),!1}if(t.tools!==void 0){if(!Array.isArray(t.tools))return e&&(e.value="Property 'tools' must be an array"),!1;for(const s of t.tools)if(typeof s!="string")return e&&(e.value="All tools must be strings"),!1}if(t.images!==void 0){if(!Array.isArray(t.images))return e&&(e.value="Property 'images' must be an array"),!1;for(let s=0;s<t.images.length;s++)if(!mt(t.images[s],e))return e&&(e.value=`Invalid image at index ${s}: ${e?.value}`),!1}if(t.documents!==void 0){if(!Array.isArray(t.documents))return e&&(e.value="Property 'documents' must be an array"),!1;for(let s=0;s<t.documents.length;s++)if(!ht(t.documents[s],e))return e&&(e.value=`Invalid document at index ${s}: ${e?.value}`),!1}return!0}c(pt,"isChatStep");function gt(t,e){return!t||typeof t!="object"?(e&&(e.value="Not an object"),!1):t.uses!=="write-to-disk"?(e&&(e.value="Uses must be 'write-to-disk'"),!1):typeof t.output!="string"?(e&&(e.value="Property 'output' must be a string"),!1):!0}c(gt,"isWriteToDiskStep");function dt(t,e){if(!t||typeof t!="object")return e&&(e.value="Not an object"),!1;if(typeof t.pattern!="string")return e&&(e.value="Property 'pattern' must be a string"),!1;if(t.source!=="file")return e&&(e.value="Property 'source' must be 'file'"),!1;if(typeof t.files!="string"&&!Array.isArray(t.files))return e&&(e.value="Property 'files' must be a string or an array of strings"),!1;if(Array.isArray(t.files)){for(let s=0;s<t.files.length;s++)if(typeof t.files[s]!="string")return e&&(e.value=`Files entry at index ${s} must be a string`),!1}return!0}c(dt,"isReplace");function mt(t,e){return!t||typeof t!="object"?(e&&(e.value="Not an object"),!1):typeof t.file!="string"?(e&&(e.value="Property 'file' must be a string"),!1):!0}c(mt,"isImageReference");function ht(t,e){return!t||typeof t!="object"?(e&&(e.value="Not an object"),!1):typeof t.file!="string"?(e&&(e.value="Property 'file' must be a string"),!1):!0}c(ht,"isDocumentReference");class yt{static{c(this,"FileRunPlanner")}constructor(e,s,n=[]){this.source=e,this.bind=s,this.skipConditions=n}async plan(e){const s=[],n=await Q(this.source,{withFileTypes:!0});for(const o of n){const r=o.fullpath(),i=rt(r);let a=!1;for(const l of this.skipConditions)if(a=await l.eval({components:i}),a)break;if(!a){const l=await Ie(r,"utf-8"),u={variables:{[this.bind]:l,...i},tasks:e};s.push(u)}}return s}}class Et{static{c(this,"MultiPlanner")}planners;constructor(e){this.planners=e}async plan(e){const s=this.planners.map(async o=>await o.plan(e));return(await Promise.all(s)).flat()}}function X(t,e,s="{{}}"){const n=s==="{{}}"?/\{\{(.*?)\}\}/g:/\{(.*?)\}/g;return t=t.replace(n,(o,r)=>e[r]?e[r]:o),t}c(X,"replaceVariables");class It{static{c(this,"FileExistSkipCondition")}constructor(e){this.pattern=e}type="file-exist";async eval(e){const s=X(this.pattern,e.components,"{}");try{return await we(s,Te.F_OK),!0}catch{return!1}}}var N=(t=>(t.String="string",t.List="string[]",t.Number="number",t.Boolean="boolean",t))(N||{});const ce={response:N.String};class ue{static{c(this,"AbstractInstruct")}type="instruct";_result=void 0;prompt;system=null;inputs={};tools={};files=[];resFormat;rawResponse;finalPrompt;constructor(e,s){this.prompt=e,this.resFormat=s}setInputs(e){this.inputs=e}addInput(e,s){this.inputs[e]=s}addTools(e){for(const s of e)this.tools[s.name]=s}addTool(e){this.tools[e.name]=e}addImage(e){if(e.type!=="image")throw new Error(`Expected image file, got ${e.type}`);this.files.push(e)}addFile(e){this.files.push(e)}hasTools(){return Object.keys(this.tools).length>0}hasFiles(){return this.files.length>0}get result(){return this._result}compile(e,s={}){const n=this.getFinalUserPrompt(e,s),o=this.getFormatInstructions();return n+`
4
- `+o}getFinalUserPrompt(e,s={}){const{recorder:n,options:o}=s,r={...e,...this.inputs};let i=X(this.prompt,r);if(o?.warnUnused){const a=i.match(/\{\{(.*?)\}\}/g);if(a)throw n?.error.log(`Warning unused variables ${a.join(", ")}`),new Error(`Unused variables: ${a.join(", ")}`)}return i}getFormatInstructions(){let e="";for(const[s,n]of Object.entries(this.resFormat))switch(this.resFormat[s]){case N.String:e+=`
5
- Use <${s}></${s}> to indicate the answer for ${s}. The answer must be a string.`;break;case N.Number:e+=`
6
- Use <${s}></${s}> to indicate the answer for ${s}. the answer must be a number.`;break;case N.Boolean:e+=`
7
- Use <${s}></${s}> to indicate the answer for ${s}. The answer must be a true/false.`;break;case N.List:e+=`
8
- Use <${s}></${s}> to indicate the answer for ${s}. The answer must be a list of strings. Each string should be in a new line.`;break}return e}finalize(e,s){this.rawResponse=e;const n={},o=Object.keys(this.resFormat);if(o.length===0){if(e.trim()==="{}"||e.trim()==="")return{};throw new Error("Output format is empty, but rawValue is not an empty object representation or empty string.")}s=s||this.parseTaggedSections(e);for(const r of o){const i=r;let a;const l=s.tags[i];if(l)a=l;else throw new Error(`Expected results with tag ${i} but it does not exist`);const u=this.resFormat[r];try{const _=this.typeResponses(u,a);n[r]=_}catch(_){throw new Error(`Cannot convert value of key ${i} to ${u}: ${_.message}`)}}return this._result=n,n}parseTaggedSections(e){const s=/<(\w+)>(.*?)<\/\1>/gs,n={};let o=e;return o=o.replace(s,(r,i,a)=>(n[i]=a,"")),{tags:n,remaining:o.trim()}}typeResponses(e,s){let n;switch(e){case N.String:n=s;break;case N.Number:if(n=parseFloat(s),isNaN(n))throw new Error(`Cannot parse '${s}' as number. Expected a numeric string.`);break;case N.Boolean:const o=s.toLowerCase();if(o==="true")n=!0;else if(o==="false")n=!1;else throw new Error(`Cannot parse '${s}' as boolean. Expected 'true' or 'false'.`);break;case N.List:s===""?n=[]:n=s.split(`
9
- `).map(r=>r.trim()).filter(r=>r.length>0);break}return n}}class k extends ue{static{c(this,"Instruct")}constructor(e,s){super(e,s)}static with(e,s){return s?new k(e,s):new k(e,ce)}}function $(t){return Array.isArray(t)?t:[t]}c($,"arrayify");function A(t,e){return e?`${e}:${t.slice(0,8)}`:t.slice(0,8)}c(A,"friendly");function wt(t){return new Promise(e=>setTimeout(e,t))}c(wt,"delay");const Tt={name:"brave",description:"Perform a search using the Brave search engine",parameters:{type:"object",properties:{searchTerm:{type:"string",description:"The search term to query"}},required:["searchTerm"]}};class Pt{static{c(this,"BraveSearchTool")}name="brave";schema=Tt;apiKey;throttle;lastExecTime=0;constructor(e){e&&this.setConfig(e)}setConfig(e){const{rateLimit:s}=e;this.apiKey=e["api-key"],this.throttle=s?1100/s:void 0}async execute(e,s={}){const{searchTerm:n}=e,{recorder:o}=s;if(o?.debug?.heading.log(`Brave: searching for ${n}`),this.throttle){for(;Date.now()-this.lastExecTime<this.throttle;)await wt(this.throttle-(Date.now()-this.lastExecTime));this.lastExecTime=Date.now()}try{const r=this.apiKey,i="https://api.search.brave.com/res/v1/web/search",a=new URL(i);a.searchParams.append("q",n),a.searchParams.append("format","json");const l=await fetch(a.toString(),{method:"GET",headers:{Accept:"application/json","X-Subscription-Token":r}});if(!l.ok)throw new Error(`[Brave] HTTP error ${l.status}: ${l.statusText}`);return await l.json()}catch(r){throw o?.error.log("[Brave] Error fetching search results:",r),r}}}const At=new Pt,vt={name:"calculator",description:"Performs basic arithmetic operations",parameters:{type:"object",properties:{operation:{type:"string",description:"The operation to perform (add, subtract, multiply, divide)",enum:["add","subtract","multiply","divide"]},a:{type:"number",description:"First operand"},b:{type:"number",description:"Second operand"}},required:["operation","a","b"]}},Nt={name:"calculator",schema:vt,execute:c(async t=>{const{operation:e,a:s,b:n}=t;switch(e){case"add":return`${s} + ${n} = ${s+n}`;case"subtract":return`${s} - ${n} = ${s-n}`;case"multiply":return`${s} * ${n} = ${s*n}`;case"divide":if(n===0)throw new Error("Cannot divide by zero");return`${s} / ${n} = ${s/n}`;default:throw new Error(`Unknown operation: ${e}`)}},"execute")};class Rt{static{c(this,"ToolRegistry")}executables={};config;setConfig(e){this.config=e}register(e){if(this.executables[e.name])throw new Error(`Tool with name '${e.name}' is already registered`);this.executables[e.name]=e}get(e){const s=this.executables[e];if(!s)throw new Error(`Tool '${e}' is not registered`);return s.setConfig?.(this.config[e]),s}}let L;function le(){return L||(L=new Rt,L.register(Nt),L.register(At)),L}c(le,"getToolRegistry");const Ot={async convert(t,e){const{recorder:s,toolNames:n}=e,{message:o,system:r,replace:i}=t;let a;t.output?a=k.with(o,t.output):a=k.with(o),r&&(a.system=r);const l=[...new Set([...n??[],...t.tools??[]])];for(const u of l){const _=le().get(u);a.addTool(_)}if(i){for(const u of i)if(u.source==="file"){const _=$(u.files),f=await st(_,s);a.addInput(u.pattern,f)}}if(t.images)for(const u of t.images)try{const _=await q(u.file);a.addFile(_)}catch(_){throw new Error(`Failed to load image '${u.file}': ${_.message}`)}if(t.documents)for(const u of t.documents)try{const _=await q(u.file);a.addFile(_)}catch(_){throw new Error(`Failed to load document '${u.file}': ${_.message}`)}return a}};class St{static{c(this,"StepToClassRegistry")}converters=new Map;get(e){const s=this.converters.get(e);if(!s)throw new Error(`No converter registered for step: ${e}`);return s}register(e,s){this.converters.set(e,s)}}class K{static{c(this,"WriteOutputTask")}constructor(e,s=["response"]){this.output=e,this.keys=s}type="write-to-disk"}const Mt={async convert(t){if(t.keys){const e=$(t.keys);return new K(t.output,e)}return new K(t.output)}},J=new St;J.register("write-to-disk",Mt),J.register("chat",Ot);async function C(t,e){const{recorder:s}=e,n=t.tools??void 0,o=t.steps.map(async r=>(r.uses,await J.get(r.uses).convert(r,{recorder:s,toolNames:n})));return Promise.all(o)}c(C,"configToTasks");async function _e(t,e){const{batch:s}=t;return s.length===1?fe(s[0]):new Et(s.map(n=>fe(n)))}c(_e,"configToPlanner");function fe(t){switch(t.type){case"files":let e;return t["skip-if"]&&(e=t["skip-if"].map(n=>bt(n))),new yt(t.source,t.bind,e)}}c(fe,"batchOptionsToPlanner");function bt(t){switch(t.type){case"file-exist":return new It(t.pattern)}}c(bt,"skipOptionsToSkipConditions");function Gt(t){return t.success===!1&&t.error!==void 0}c(Gt,"isErrorResult");function U(t,e){return{response:t,stats:e,success:!0}}c(U,"createResult");function D(t,e,s){return{response:e,stats:s,error:t,success:!1}}c(D,"createErrorResult");class kt{static{c(this,"Chat")}system;messages=[];tools=[];setToolSchemas(e){this.tools=e}addSystem(e){this.system=e}addUser(e){this.messages.push({role:"user",content:e})}addUserWithFiles(e,s=[]){if(s.length===0){this.addUser(e);return}const n=[{type:"text",text:e}];for(const o of s)n.push({type:"file",file:o});this.messages.push({role:"user",content:n})}addAssistant(e,s){this.messages.push({role:"assistant",content:e,toolCalls:s})}addTools(e){this.messages.push({role:"tool",content:e})}hasFiles(){return this.messages.some(e=>Array.isArray(e.content)&&e.content.some(s=>s.type==="file"))}getTextContent(e){return typeof e=="string"?e:e.filter(n=>n.type==="text").map(n=>n.text).join(" ")}getFiles(e){return typeof e=="string"?[]:e.filter(s=>s.type==="file").map(s=>s.file)}toString(){return JSON.stringify({system:this.system,messages:this.messages,tools:this.tools})}}class xt{static{c(this,"WriteToDiskTaskHandler")}taskType="write-to-disk";canHandle(e){return e&&typeof e=="object"&&"type"in e&&e.type==="write-to-disk"}async execute(e){const{task:s,variables:n,options:o={},recorder:r}=e,i=s.output,a=s.keys??[];if(o?.warnUnused){const _=a.filter(f=>!(f in n));_.length>0&&r?.warn?.log(`[Write To Disk] The following keys were not found in the variables: ${_.join(", ")}`)}let l="";if(a.length===1?l=n[a[0]]??"<not found>":l=a.map(_=>`[${_}]:
10
- ${n[_]??"<not found>"}
11
- `).join(`
12
- `),o?.dryRun){r?.info?.log("[Dry run] Write to Disk is not executed.");return}let u="";i.includes("*")?u=nt(i,n.file):u=X(i,n,"{}"),await ot({filePath:u,content:l})}}var H=(t=>(t.LastResult="lastResult",t))(H||{});function $t(t,e,s){const{options:n,recorder:o}=s,r=n?.warnUnused??!0;for(const[i,a]of Object.entries(t))r&&e[i]&&o?.warn?.log(`Warning: Variable "${i}" is being overwritten. Previous value: ${e[i]}, new value: ${a}`),e[i]=a}c($t,"setResultsIntoVariables");class Lt{static{c(this,"ChatTaskHandler")}taskType="instruct";canHandle(e){return e&&typeof e=="object"&&"type"in e&&e.type==="instruct"}async execute(e){const{task:s,...n}=e;await Ft({instruct:s,...n})}}async function Ft(t){const{instruct:e,chat:s,provider:n,stats:o,variables:r,options:i,recorder:a}=t;e.system&&s.addSystem(e.system);const l=e.compile(r,{recorder:a,options:i});if(e.hasFiles()?s.addUserWithFiles(l,e.files):s.addUser(l),e.hasTools()){const _=Ut(e.tools);s.setToolSchemas(_)}if(i?.dryRun)return a?.debug?.log(s),{action:"complete"};let u=!0;for(;u;){const f=await n.createChatRequest(s,{recorder:a}).execute({recorder:a});if(o.in+=f.usage.in,o.out+=f.usage.out,f.type==="error")throw new Error(JSON.stringify(f.error));if(f.type==="success")switch(f.reason){case m.Stop:{if(f.message.content){const d=f.message.content;s.addAssistant(d);const h=e.finalize(d);$t(h,r,{options:i,recorder:a}),r[H.LastResult]=h}return u=!1,{action:"continue"}}case m.Length:throw new Error("Incomplete model output due to `max_tokens` parameter or token limit");case m.FunctionCall:{let d=f.message;if(f.message&&s.addAssistant(d.content,d.toolCalls),d.toolCalls&&d.toolCalls.length>0){const h=await Ct(d.toolCalls,e,{recorder:a});a?.debug?.log(h),s.addTools(h),u=!0}else u=!1;break}}if(f.type!=="success")throw a?.debug?.log(f),new Error("Unexpected response type")}return{action:"continue"}}c(Ft,"executeChatAction");async function Ct(t,e,s={}){const{recorder:n}=s,o=[];for(const r of t)o.push(new Promise((i,a)=>{const l=e.tools[r.name];if(!l){a(`Tool not found: ${r.name}`);return}n?.debug?.heading.log(`Executing tool ${l.name}`);let u={};try{u=typeof r.arguments=="string"?JSON.parse(r.arguments):r.arguments}catch{a(`argument for tool ${r.name} is not valid: ${JSON.stringify(r.arguments)}`)}l.execute(u).then(_=>{n?.debug?.log(`Complete tool ${l.name}: ${r.id}`),i({id:r.id,name:r.name,content:JSON.stringify(_)})}).catch(a)}));return Promise.all(o)}c(Ct,"executeToolCalls");function Ut(t){const e=[];for(const[s,n]of Object.entries(t))e.push(n.schema);return e}c(Ut,"getToolSchemas");class Dt{static{c(this,"TaskRegistry")}handlers=new Map;register(e){this.handlers.set(e.taskType,e)}getHandler(e){return this.handlers.get(e.type)}hasHandler(e){return this.handlers.has(e.type)}async executeTask(e){const{task:s}=e,n=s.type,o=this.getHandler(s);if(!o)throw new Error(`No handler registered for action type: ${n}`);if(!o.canHandle(s))throw new Error(`Handler found but action does not match expected format: ${n}`);await o.execute(e)}}function Ht(){const t=new Dt;return t.register(new Lt),t}c(Ht,"createBaseRegistry");function Wt(){const t=Ht();return t.register(new xt),t}c(Wt,"createNodeRegistry");const z=c((t,...e)=>{const s=c(async o=>{const{recorder:r}=o;let i=[];return"steps"in t?i=await C(t,{recorder:r}):i=[t,...e],i},"prepare");return{execute:c(async o=>{const{provider:r,variables:i,options:a,stats:l,recorder:u,name:_}=o,f=crypto.randomUUID(),d=Wt();u?.info?.log({type:"task",id:f,status:I.Running,message:`[${A(f,_)}] Starting job`});try{const h=await s({recorder:u}),y=new kt;for(const[S,T]of h.entries()){u?.info?.log({type:"task",id:f,status:I.Running,message:`[${A(f,_)}] Processing step ${S+1}: ${T.type}`});try{await d.executeTask({task:T,chat:y,provider:r,variables:i,options:a,stats:l,recorder:u})}catch(v){throw v instanceof E?v:new Y(`Error executing task ${T.type}`,{id:f,taskType:T.type,taskIndex:S,cause:v instanceof Error?v:new Error(String(v))})}}return u?.info?.log({type:"task",status:I.Success,id:f,message:`[${A(f,_)}] Completed ${h.length} steps`}),U(i[H.LastResult],l)}catch(h){const y=h instanceof E?h:new E("Serial workflow execution failed",{id:f,cause:h instanceof Error?h:new Error(String(h))});return u?.info?.log({type:"task",status:I.Fail,id:f,message:`[${A(f,_)}] Failed: ${y.message}`}),u?.error.log(y),D(y,i[H.LastResult],l)}},"execute")}},"serialWorkflow"),pe=c((t,...e)=>{const s=c(async o=>{const{recorder:r}=o;let i=[],a=null;if("batch"in t){const l=t;a=await _e(l),i=await C(l,{recorder:r})}else a=t,i=[...e];return[a,i]},"prepare");return{execute:c(async o=>{const{provider:r,variables:i,options:a,stats:l,recorder:u,name:_}=o,f=crypto.randomUUID();try{const[d,h]=await s({recorder:u}),y=await d.plan(h);if(u?.debug?.heading.log("Runs",y),y.length===0)return u?.info?.log("No runs to execute"),U([],l);let S=0;u?.info?.log({type:"task",status:I.Running,id:f,message:`[${A(f,"CRW")}] Working on 0/${y.length}`});const T=c(async(R,W)=>{try{return await z(...R.tasks).execute({provider:r,variables:{...R.variables,...i},options:a,stats:l,recorder:u,name:`${_}-${W}`})}catch(M){const Z=M instanceof E?M:new E("Error executing run",{cause:M instanceof Error?M:new Error(String(M))});return u?.error?.log(Z),D(Z,null,l)}finally{S++,u?.info?.log({type:"task",status:I.Running,id:f,message:`[${A(f,"CRW")}] Working on ${S}/${y.length}`})}},"executeRun"),v=5;let G=[];for(let R=0;R<y.length;R+=v){const W=y.slice(R,R+v),M=await Promise.all(W.map(T));G=G.concat(M)}const b=G.some(Gt);u?.info?.log({type:"task",status:b?I.PartialSuccess:I.Success,id:f,message:`[${A(f,"CRW")}] All jobs (${y.length}) completed${b?" with some errors":""}`});const x=G.map(R=>R.response);return U(x,l)}catch(d){const h=d instanceof E?d:new E("Concurrent workflow execution failed",{id:f,cause:d instanceof Error?d:new Error(String(d))});return u?.error?.log(h),D(h,null,l)}},"execute")}},"concurrentWorkflow");class Bt{static{c(this,"DAGParser")}static parse(e){const s=new Map;for(const[o,r]of Object.entries(e)){const i=this.parseNodeDefinition(o,r);s.set(o,i)}return this.validateDependencies(s),this.checkForCycles(s),{stages:this.createExecutionStages(s),nodes:s}}static parseNodeDefinition(e,s){if(this.isSimpleTask(s))return{id:e,tasks:Array.isArray(s)?s:[s],dependencies:[],executionType:"serial"};if(this.isConcurrentNodeDefinition(s)){const i=s,a=i.dependsOn?$(i.dependsOn):[];return{id:e,tasks:i.tasks,dependencies:a,planner:i.planner,executionType:"concurrent"}}const n=s,o=n.dependsOn?$(n.dependsOn):[],r=$(n.task);return{id:e,tasks:r,dependencies:o,executionType:"serial"}}static isSimpleTask(e){return e.type||Array.isArray(e)}static isConcurrentNodeDefinition(e){return e&&typeof e=="object"&&"planner"in e}static validateDependencies(e){for(const s of e.values())for(const n of s.dependencies)if(!e.has(n))throw new E(`Node "${s.id}" depends on non-existent node "${n}"`)}static checkForCycles(e){const s=new Set,n=new Set,o=c(r=>{if(n.has(r))return!0;if(s.has(r))return!1;s.add(r),n.add(r);const i=e.get(r);for(const a of i.dependencies)if(o(a))return!0;return n.delete(r),!1},"hasCycle");for(const r of e.keys())if(o(r))throw new E(`Circular dependency detected involving node "${r}"`)}static createExecutionStages(e){const s=[],n=new Set,o=new Set(e.keys());for(;o.size>0;){const r=[];for(const i of o)e.get(i).dependencies.every(u=>n.has(u))&&r.push(i);if(r.length===0)throw new E("Unable to resolve DAG dependencies - possible circular reference");s.push(r),r.forEach(i=>{n.add(i),o.delete(i)})}return s}}class qt{static{c(this,"DAGJobToDefinition")}static async convert(e,s){const{recorder:n}=s,o={};for(const[r,i]of Object.entries(e)){const{dependsOn:a,...l}=i;if("batch"in l){const u=l,_=await _e(u),f=await C(u,{recorder:n}),d={planner:_,tasks:f,...a?{dependsOn:a}:{}};o[r]=d}else{const u=await C(l,{recorder:n});if(a){const _={task:u,dependsOn:a};o[r]=_}else o[r]=u}}return o}}async function Xt(t,e,s,n={}){const{variables:o}=s,r=e.nodes.get(t);try{let i;if(r.executionType==="concurrent"&&r.planner?i=await pe(r.planner,...r.tasks).execute({...s,variables:o,name:t}):i=await z(...r.tasks).execute({...s,variables:o,name:t}),!i.success)throw new E(`Node "${t}" failed: ${i.error?.message}`);return i.response}catch(i){if(!n.continueOnError)throw i;return null}}c(Xt,"executeNode");const Kt=c((t,e={})=>{const s=c(async(o,r)=>{const{recorder:i}=r,a={value:""};return ie(o,a)?await qt.convert(o,r):(i?.warn?.log(a),o)},"prepare");return{execute:c(async o=>{const{stats:r,recorder:i}=o,{maxConcurrency:a=3}=e,l=crypto.randomUUID();try{const u=await s(t,{recorder:i});i?.debug?.log(u);const _=Bt.parse(u),f=new Map;i?.info?.log({type:"task",id:l,status:I.Running,message:`[${A(l)}] Starting workflow execution with ${_.stages.length} stages`});for(const[h,y]of _.stages.entries()){i?.info?.log({type:"task",id:l,status:I.Running,message:`[${A(l)}] Stage ${h+1}/${_.stages.length}, executing ${y.length} nodes: ${y.join(", ")}`});const S=Math.min(y.length,a);for(let T=0;T<y.length;T+=S){const v=y.slice(T,T+S);(await Promise.all(v.map(async b=>{const x=await Xt(b,_,o,e);return{nodeId:b,result:x}}))).forEach(({nodeId:b,result:x})=>{f.set(b,x)})}}i?.info?.log({type:"task",status:I.Success,id:l,message:`[${A(l)}] Workflow execution completed successfully`});const d=Object.fromEntries(f);return U(d,r)}catch(u){const _=u instanceof E?u:new E("DAG workflow execution failed",{id:l,cause:u instanceof Error?u:new Error(String(u))});return i?.info?.log({type:"task",status:I.Fail,id:l,message:`[${A(l)}] Workflow execution failed: ${_.message}`}),i?.error?.log(_),D(_,null,r)}},"execute")}},"dagWorkflow");export{E as A,ce as D,k as I,P as L,et as R,I as T,K as W,ue as a,tt as b,pe as c,Kt as d,le as e,Ve as g,it as i,q as l,z as s};