hablas-ai 1.3.7 → 1.3.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +6 -8
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -31,7 +31,7 @@ Expecting one of '${s.join("', '")}'`);let r=`${e}Help`;return this.on(r,i=>{let
|
|
|
31
31
|
|
|
32
32
|
`)}var je,un,bi,Ds,Ls,_i=L(()=>{"use strict";je=O(require("fs")),un=O(require("path")),bi=O(require("os")),Ds=un.join(bi.homedir(),".hablas","plugins"),Ls=un.join(bi.homedir(),".hablas","plugins.json")});var Dc={};Ne(Dc,{renderDiagnostics:()=>$i,runDiagnostics:()=>Ai});async function Ai(n){let e=[],t=process.version,s=parseInt(t.slice(1).split(".")[0],10);e.push({name:"Node.js",status:s>=20?"ok":s>=18?"warn":"error",message:s>=20?`${t} (recommended)`:s>=18?`${t} (works, but 20+ recommended)`:`${t} (too old, need 20+)`});let r=Mc.join(nt.homedir(),".hablas");if(e.push({name:"Config directory",status:ki.existsSync(r)?"ok":"warn",message:ki.existsSync(r)?r:"Not created yet (will be created on first use)"}),n.provider==="ollama")try{let i=await fetch(`${n.ollamaHost}/api/tags`,{signal:AbortSignal.timeout(5e3)});if(i.ok){let o=await i.json(),a=Array.isArray(o.models)?o.models.length:0;e.push({name:"Ollama",status:"ok",message:`Connected \u2014 ${a} models available`})}else e.push({name:"Ollama",status:"error",message:`HTTP ${i.status}`})}catch(i){let o=i instanceof Error?i.message:String(i);e.push({name:"Ollama",status:"error",message:o.includes("ECONNREFUSED")?"Not running \u2014 start with: ollama serve":`Connection failed: ${o}`})}else{let i=n.apiUrl||"unknown";try{let o=await fetch(`${i}/models`,{signal:AbortSignal.timeout(5e3),headers:{Authorization:"Bearer test"}});e.push({name:"API Provider",status:o.ok||o.status===401?"ok":"warn",message:`${i} \u2014 reachable`})}catch{e.push({name:"API Provider",status:"warn",message:`${i} \u2014 could not verify`})}}try{let i=nt.homedir();if(process.platform!=="win32"){let a=(0,Ic.execSync)(`df -h "${i}" | tail -1`,{encoding:"utf-8"}).trim().split(/\s+/),l=a[3]||"unknown",u=a[4]||"?";e.push({name:"Disk space",status:parseInt(u)>90?"warn":"ok",message:`${l} available (${u} used)`})}else e.push({name:"Disk space",status:"ok",message:"Check skipped on Windows"})}catch{e.push({name:"Disk space",status:"ok",message:"Could not determine"})}return e.push({name:"Active model",status:n.model?"ok":"warn",message:n.model||"No model configured"}),e.push({name:"Platform",status:"ok",message:`${nt.platform()} ${nt.arch()} \u2014 ${nt.cpus().length} cores, ${Math.round(nt.totalmem()/1024/1024/1024)}GB RAM`}),e}function $i(n){let e={ok:"\u2713",warn:"\u26A0",error:"\u2717"},t={ok:"\x1B[32m",warn:"\x1B[33m",error:"\x1B[31m"},s="\x1B[0m",r="\x1B[2m",i=[""," \u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501"," hablas doctor \u2014 System Diagnostics"," \u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501",""];for(let l of n){let u=`${t[l.status]}${e[l.status]}${s}`,d=l.name.padEnd(18);i.push(` ${u} ${d}${r}${l.message}${s}`)}let o=n.filter(l=>l.status==="error").length,a=n.filter(l=>l.status==="warn").length;return i.push(""),o>0?i.push(` ${t.error}${o} error(s) found \u2014 fix these for hablas to work properly${s}`):a>0?i.push(` ${t.warn}${a} warning(s) \u2014 hablas should work but check the items above${s}`):i.push(` ${t.ok}All checks passed \u2014 hablas is ready!${s}`),i.push(""),i.join(`
|
|
33
33
|
`)}var ki,Mc,nt,Ic,Ci=L(()=>{"use strict";ki=O(require("fs")),Mc=O(require("path")),nt=O(require("os")),Ic=require("child_process")});function Lc(){let n=[];for(let e of xe){let s=e.role==="hablas"?" \u2605":"";n.push(` @${e.name}${s} \u2014 ${e.title}`),n.push(` ${e.description}`)}return n.join(`
|
|
34
|
-
`)}var xe,Ns=L(()=>{"use strict";xe=[{role:"hablas",name:"Hablas",title:"Team Leader",description:"Software Engineer & Team Coordinator. Receives user requests, creates plans, distributes tasks, and compiles final responses.",expertise:["planning","coordination","architecture","code-review","decision-making"]},{role:"bob",name:"Bob",title:"Architect",description:"System Architect. Designs software architecture, database schemas, API structures, and system blueprints.",expertise:["system-design","architecture","database","api-design","scalability"]},{role:"alex",name:"Alex",title:"Engineer",description:"Full-Stack Engineer. Implements code, builds features, fixes bugs, handles DevOps and deployment.",expertise:["coding","implementation","debugging","devops","testing","deployment"]},{role:"david",name:"David",title:"Data Analyst",description:"Data & Research Specialist. Handles research, data analysis, documentation, and information gathering.",expertise:["research","data-analysis","documentation","ml","optimization"]},{role:"emma",name:"Emma",title:"Product Manager",description:"Product Manager. Analyzes user needs, creates PRDs, competitive analysis, market research, and requirement specifications.",expertise:["product-management","requirements","prd","market-research","competitive-analysis","user-stories"]}]});function zt(){try{if(Et.existsSync(Hn)){let n=Et.readFileSync(Hn,"utf-8"),e=JSON.parse(n);return{...Fc,...e}}}catch{}return{...Fc}}function Ei(n){let e=js.dirname(Hn);Et.existsSync(e)||Et.mkdirSync(e,{recursive:!0}),Et.writeFileSync(Hn,JSON.stringify(n,null,2),"utf-8")}function Ti(){return Hn}var Et,js,Nc,Hn,Fc,Ri=L(()=>{"use strict";Et=O(require("fs")),js=O(require("path")),Nc=O(require("os")),Hn=js.join(Nc.homedir(),".hablas","agents.json"),Fc={hablas:{model:"stepfun-ai/step-3.7-flash",temperature:.7},bob:{model:"stepfun-ai/step-3.7-flash",temperature:.4},alex:{model:"stepfun-ai/step-3.7-flash",temperature:.2},david:{model:"stepfun-ai/step-3.7-flash",temperature:.5},emma:{model:"stepfun-ai/step-3.7-flash",temperature:.6},gate:{model:"stepfun-ai/step-3.
|
|
34
|
+
`)}var xe,Ns=L(()=>{"use strict";xe=[{role:"hablas",name:"Hablas",title:"Team Leader",description:"Software Engineer & Team Coordinator. Receives user requests, creates plans, distributes tasks, and compiles final responses.",expertise:["planning","coordination","architecture","code-review","decision-making"]},{role:"bob",name:"Bob",title:"Architect",description:"System Architect. Designs software architecture, database schemas, API structures, and system blueprints.",expertise:["system-design","architecture","database","api-design","scalability"]},{role:"alex",name:"Alex",title:"Engineer",description:"Full-Stack Engineer. Implements code, builds features, fixes bugs, handles DevOps and deployment.",expertise:["coding","implementation","debugging","devops","testing","deployment"]},{role:"david",name:"David",title:"Data Analyst",description:"Data & Research Specialist. Handles research, data analysis, documentation, and information gathering.",expertise:["research","data-analysis","documentation","ml","optimization"]},{role:"emma",name:"Emma",title:"Product Manager",description:"Product Manager. Analyzes user needs, creates PRDs, competitive analysis, market research, and requirement specifications.",expertise:["product-management","requirements","prd","market-research","competitive-analysis","user-stories"]}]});function zt(){try{if(Et.existsSync(Hn)){let n=Et.readFileSync(Hn,"utf-8"),e=JSON.parse(n);return{...Fc,...e}}}catch{}return{...Fc}}function Ei(n){let e=js.dirname(Hn);Et.existsSync(e)||Et.mkdirSync(e,{recursive:!0}),Et.writeFileSync(Hn,JSON.stringify(n,null,2),"utf-8")}function Ti(){return Hn}var Et,js,Nc,Hn,Fc,Ri=L(()=>{"use strict";Et=O(require("fs")),js=O(require("path")),Nc=O(require("os")),Hn=js.join(Nc.homedir(),".hablas","agents.json"),Fc={hablas:{model:"stepfun-ai/step-3.7-flash",temperature:.7},bob:{model:"stepfun-ai/step-3.7-flash",temperature:.4},alex:{model:"stepfun-ai/step-3.7-flash",temperature:.2},david:{model:"stepfun-ai/step-3.7-flash",temperature:.5},emma:{model:"stepfun-ai/step-3.7-flash",temperature:.6},gate:{model:"stepfun-ai/step-3.5-flash",temperature:.3}}});var Ni={};Ne(Ni,{formatStats:()=>Sy,loadStats:()=>Bn,saveStats:()=>dn,trackAgentUsage:()=>Fi,trackFileModified:()=>wy,trackMessage:()=>Di,trackSession:()=>Ii,trackToolCall:()=>Li});function Bn(){try{if(Tt.existsSync(Pi))return JSON.parse(Tt.readFileSync(Pi,"utf-8"))}catch{}return vy()}function dn(n){try{Tt.existsSync(Oi)||Tt.mkdirSync(Oi,{recursive:!0}),Tt.writeFileSync(Pi,JSON.stringify(n,null,2))}catch{}}function vy(){return{totalSessions:0,totalMessages:0,totalTokensUsed:0,totalToolCalls:0,totalFilesModified:0,totalLinesWritten:0,totalBugsFixed:0,totalCommits:0,agentUsage:{},commandUsage:{},dailyActivity:{},streak:0,longestStreak:0,firstUsed:new Date().toISOString(),lastUsed:new Date().toISOString()}}function Ii(n){return n.totalSessions++,n.lastUsed=new Date().toISOString(),xy(n),n}function Di(n,e=0){n.totalMessages++,n.totalTokensUsed+=e;let t=Hs();return n.dailyActivity[t]||(n.dailyActivity[t]={messages:0,tokens:0,toolCalls:0,filesModified:0,linesWritten:0}),n.dailyActivity[t].messages++,n.dailyActivity[t].tokens+=e,n}function Li(n,e){n.totalToolCalls++,n.commandUsage[e]=(n.commandUsage[e]||0)+1;let t=Hs();return n.dailyActivity[t]||(n.dailyActivity[t]={messages:0,tokens:0,toolCalls:0,filesModified:0,linesWritten:0}),n.dailyActivity[t].toolCalls++,n}function Fi(n,e){return n.agentUsage[e]=(n.agentUsage[e]||0)+1,n}function wy(n,e=0){n.totalFilesModified++,n.totalLinesWritten+=e;let t=Hs();return n.dailyActivity[t]||(n.dailyActivity[t]={messages:0,tokens:0,toolCalls:0,filesModified:0,linesWritten:0}),n.dailyActivity[t].filesModified++,n.dailyActivity[t].linesWritten+=e,n}function xy(n){let e=Hs(),t=Hc(new Date(Date.now()-864e5));n.dailyActivity[t]||n.dailyActivity[e]?n.streak++:n.streak=1,n.streak>n.longestStreak&&(n.longestStreak=n.streak)}function Hs(){return Hc(new Date)}function Hc(n){return n.toISOString().split("T")[0]}function Sy(n){let e=[];e.push(`
|
|
35
35
|
\u{1F4CA} Developer Analytics`),e.push(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"),e.push(` Sessions: ${n.totalSessions}`),e.push(` Messages: ${n.totalMessages}`),e.push(` Tokens used: ${n.totalTokensUsed.toLocaleString()}`),e.push(` Tool calls: ${n.totalToolCalls}`),e.push(` Files modified: ${n.totalFilesModified}`),e.push(` Lines written: ${n.totalLinesWritten.toLocaleString()}`),e.push(` Bugs fixed: ${n.totalBugsFixed}`),e.push(` Commits: ${n.totalCommits}`),e.push(""),e.push(` \u{1F525} Streak: ${n.streak} days (best: ${n.longestStreak})`),e.push("");let t=Object.entries(n.agentUsage).sort((r,i)=>i[1]-r[1]).slice(0,5);if(t.length>0){e.push(" Top Agents:");for(let[r,i]of t)e.push(` @${r}: ${i} uses`);e.push("")}let s=Object.entries(n.commandUsage).sort((r,i)=>i[1]-r[1]).slice(0,5);if(s.length>0){e.push(" Top Commands:");for(let[r,i]of s)e.push(` ${r}: ${i} calls`)}return e.join(`
|
|
36
36
|
`)}var Tt,Mi,jc,Oi,Pi,Un=L(()=>{"use strict";Tt=O(require("fs")),Mi=O(require("path")),jc=O(require("os")),Oi=Mi.join(jc.homedir(),".hablas"),Pi=Mi.join(Oi,"analytics.json")});var Uc={};Ne(Uc,{formatScanResults:()=>Hi,runSecurityScan:()=>ji});function $y(n,e){let t=[],s=e.split(`
|
|
37
37
|
`);for(let{pattern:r,name:i,severity:o}of _y){r.lastIndex=0;let a;for(;(a=r.exec(e))!==null;){let u=e.substring(0,a.index).split(`
|
|
@@ -963,7 +963,7 @@ Rate your work. Reply with ONLY a JSON object \u2014 no other text:
|
|
|
963
963
|
`)}getTurnSummary(){let e=this.turnSteps.length,t=this.turnSteps.filter(r=>r.action).length,s=this.turnSteps.filter(r=>r.reflection).length;return`${e} steps, ${t} actions, ${s} reflections`}}});function gs(n=3){return new Il(n)}var N$,Il,Dl=L(()=>{"use strict";N$=[{test:n=>/ENOENT|no such file|not found|does not exist/i.test(n),errorClass:"file_not_found",strategy:"read_first",explanation:"The file or directory does not exist.",suggestion:"Use list_dir to check what files exist, then retry with the correct path.",alternatives:["list_dir","search_codebase"],autoRetry:!1},{test:n=>/EACCES|permission denied/i.test(n),errorClass:"permission_denied",strategy:"graceful_fail",explanation:"Permission denied \u2014 the process lacks access rights.",suggestion:"Check file ownership or try a different path. Do NOT use sudo.",alternatives:[],autoRetry:!1},{test:n=>/EISDIR|is a directory/i.test(n),errorClass:"path_is_directory",strategy:"retry_fixed",explanation:"The path points to a directory, not a file.",suggestion:"Append the filename to the path. Use list_dir to see contents.",alternatives:["list_dir"],autoRetry:!1},{test:n=>/EEXIST|already exists/i.test(n),errorClass:"file_already_exists",strategy:"read_first",explanation:"A file or directory already exists at that path.",suggestion:"Read the existing file first, then decide whether to overwrite or edit it.",alternatives:["read_file","edit_file"],autoRetry:!1},{test:n=>/no match|not found in file|search string not found/i.test(n),errorClass:"search_no_match",strategy:"read_first",explanation:"The search string was not found in the file.",suggestion:"Read the file first to see its actual content, then use the exact text for search/replace.",alternatives:["read_file","search_codebase"],autoRetry:!1},{test:n=>/command not found|not recognized/i.test(n),errorClass:"command_not_found",strategy:"alternative_tool",explanation:"The command does not exist on this system.",suggestion:"Check if the program is installed, or use a different command that achieves the same goal.",alternatives:["run_command"],autoRetry:!1},{test:n=>/timeout|timed out|ETIMEDOUT/i.test(n),errorClass:"command_timeout",strategy:"retry_fixed",explanation:"The command took too long and was terminated.",suggestion:"Try a simpler version of the command, or increase the timeout, or run it in background.",alternatives:[],autoRetry:!1},{test:n=>/exit code|exited with|non-zero/i.test(n),errorClass:"command_exit_error",strategy:"retry_fixed",explanation:"The command executed but returned an error.",suggestion:"Read the error output carefully. Fix the root cause (missing dependency, wrong syntax, etc.).",alternatives:[],autoRetry:!1},{test:n=>/syntax error|unexpected token|parse error|SyntaxError/i.test(n),errorClass:"syntax_error",strategy:"retry_fixed",explanation:"The content has a syntax error.",suggestion:"Review the generated code for syntax issues, fix them, and retry.",alternatives:[],autoRetry:!1},{test:n=>/ECONNREFUSED|ECONNRESET|ENOTFOUND|fetch failed|network/i.test(n),errorClass:"network_error",strategy:"retry_same",explanation:"Network connection failed.",suggestion:"This may be transient. Retry the same operation, or check connectivity.",alternatives:[],autoRetry:!0},{test:n=>/invalid argument|missing required|expected.*but got|type error/i.test(n),errorClass:"invalid_arguments",strategy:"retry_fixed",explanation:"The tool was called with invalid or missing arguments.",suggestion:"Check the tool's parameter requirements and provide correct values.",alternatives:[],autoRetry:!1},{test:n=>/ENOMEM|out of memory|resource|too large|max.*exceeded/i.test(n),errorClass:"resource_limit",strategy:"decompose_task",explanation:"Resource limit exceeded (memory, file size, etc.).",suggestion:"Break the task into smaller pieces, or process less data at once.",alternatives:[],autoRetry:!1}],Il=class{failures=new Map;maxRetriesPerTool;constructor(e=3){this.maxRetriesPerTool=e}resetTurn(){this.failures.clear()}analyze(e,t,s){let r=this.failures.get(e),i=r?r.count+1:1,o={tool:e,count:i,lastError:t,lastStrategy:"retry_same"};if(i>this.maxRetriesPerTool)return o.lastStrategy="ask_user",this.failures.set(e,o),{errorClass:"unknown",strategy:"ask_user",explanation:`Tool "${e}" has failed ${i} times in this turn.`,suggestion:`Stop retrying "${e}". Ask the user for clarification or try a completely different approach.`,alternatives:this.suggestAlternatives(e),autoRetry:!1};for(let a of N$)if(a.test(t)){let l=r?.lastStrategy===a.strategy&&i>=2,u=l?"decompose_task":a.strategy;return o.lastStrategy=u,this.failures.set(e,o),{errorClass:a.errorClass,strategy:u,explanation:a.explanation,suggestion:l?`Previous recovery attempt ("${a.strategy}") also failed. Try breaking this into smaller steps or use a completely different approach.`:a.suggestion,alternatives:a.alternatives,autoRetry:!l&&a.autoRetry}}return o.lastStrategy=i===1?"retry_fixed":"graceful_fail",this.failures.set(e,o),{errorClass:"unknown",strategy:o.lastStrategy,explanation:`Unexpected error from "${e}".`,suggestion:i===1?"Review the error message and adjust your approach.":"This error is persistent. Explain to the user what went wrong and suggest manual steps.",alternatives:this.suggestAlternatives(e),autoRetry:!1}}buildRecoveryMessage(e,t){let s=[`ERROR: ${t}`,"","[Recovery Analysis]",` Type: ${e.errorClass}`,` Strategy: ${e.strategy}`,` Explanation: ${e.explanation}`,` Suggestion: ${e.suggestion}`];switch(e.alternatives.length>0&&s.push(` Alternative tools: ${e.alternatives.join(", ")}`),e.strategy){case"read_first":s.push("","\u2192 ACTION: Read the file or directory first, then retry with correct information.");break;case"retry_fixed":s.push("","\u2192 ACTION: Fix the arguments based on the error, then retry.");break;case"alternative_tool":s.push("","\u2192 ACTION: Use a different tool to achieve the same goal.");break;case"decompose_task":s.push("","\u2192 ACTION: Break this into smaller, simpler steps.");break;case"ask_user":s.push("","\u2192 ACTION: Ask the user for clarification. Do NOT retry automatically.");break;case"graceful_fail":s.push("","\u2192 ACTION: Explain what went wrong clearly. Suggest manual steps if possible.");break}return s.join(`
|
|
964
964
|
`)}getFailureCount(e){return this.failures.get(e)?.count??0}shouldAutoRetry(e){let t=this.failures.get(e);return t?t.count<=1&&t.lastStrategy==="retry_same":!1}suggestAlternatives(e){return{read_file:["search_codebase","list_dir"],write_file:["edit_file","append_to_file"],edit_file:["search_and_replace","write_file","read_file"],search_and_replace:["edit_file","read_file"],patch_file:["edit_file","write_file"],run_command:["search_codebase"],search_codebase:["read_file","list_dir"],delete_file:["run_command"],create_dir:["run_command"],web_search:["scrape_url"]}[e]??[]}}});function j$(){try{if(Lt.existsSync(jr))return JSON.parse(Lt.readFileSync(jr,"utf-8"))}catch{}return{}}function H$(n){try{let e=Hr.dirname(jr);Lt.existsSync(e)||Lt.mkdirSync(e,{recursive:!0}),Lt.writeFileSync(jr,JSON.stringify(n,null,2),"utf-8")}catch{}}function Zm(n,e){let t=0,s=!1,r=!1;for(let i=e;i<n.length;i++){let o=n[i];if(r){r=!1;continue}if(o==="\\"&&s){r=!0;continue}if(o==='"'){s=!s;continue}if(!s&&(o==="{"&&t++,o==="}"&&(t--,t===0)))return n.slice(e,i+1)}return null}function ys(n){if(typeof n.name=="string"&&n.arguments&&typeof n.arguments=="object")return{tool:n.name,args:n.arguments};if(typeof n.tool=="string"&&n.args&&typeof n.args=="object")return{tool:n.tool,args:n.args};if(typeof n.name=="string"&&n.parameters&&typeof n.parameters=="object")return{tool:n.name,args:n.parameters};if(n.function&&typeof n.function=="object"){let e=n.function;if(typeof e.name=="string"){let t={};if(typeof e.arguments=="string")try{t=JSON.parse(e.arguments)}catch{t={}}else e.arguments&&typeof e.arguments=="object"&&(t=e.arguments);return{tool:e.name,args:t}}}return null}function B$(n){return n.replace(/"/g,'"').replace(/'/g,"'").replace(/</g,"<").replace(/>/g,">").replace(/&/g,"&")}function U$(n){let e=[],t=/<<?tool[-_]call\s*>>?([\s\S]*?)<<?\/tool[-_]call\s*>>?/gi,s;for(;(s=t.exec(n))!==null;)try{let r=JSON.parse(s[1].trim()),i=ys(r);i&&e.push({...i,format:"xml_tags",rawMatch:s[0]})}catch{}return e}function K$(n){let e=[],t=/<<?tool[-_]call\s*>>?([\s\S]*?)<<?\/tool[-_]call\s*>>?/gi,s;for(;(s=t.exec(n))!==null;)try{let r=JSON.parse(s[1].trim());if(r.parameters||r.name){let i=ys(r);i&&e.push({...i,format:"hermes",rawMatch:s[0]})}}catch{}return e}function q$(n){let e=[],t=/<<?tool[-_]call\s*>>?([\s\S]*?)<<?\/tool[-_]call\s*>>?/gi,s;for(;(s=t.exec(n))!==null;){let r=s[1],i=eg(r);for(let o of i)e.push({...o,format:"xml_tool_call_wrapper",rawMatch:s[0]})}return e}function eg(n){let e=[],t=["read_file","write_file","edit_file","search_and_replace","run_command","search_codebase","list_dir","create_dir","delete_file","append_to_file","patch_file","move_file","get_file_info"];for(let s of t){let r=new RegExp(`<<?${s}(\\s+[\\s\\S]*?)?(?:>>?([\\s\\S]*?)<<?\\/${s}>>?|\\s*\\/?>>?)`,"gi"),i;for(;(i=r.exec(n))!==null;){let o=i[1]||"",a=i[2]||"",l={},u=/(\w+)\s*=\s*(?:"([^"]*)"|'([^']*)'|(\S+))/g,d;for(;(d=u.exec(o))!==null;){let h=d[1].toLowerCase(),m=d[2]??d[3]??d[4];l[h]=B$(m)}let f=a.trim();f&&(s==="write_file"||s==="append_to_file"?l.content=a:s==="run_command"?l.command=f:s==="patch_file"&&(l.new_content=a)),l.start_line&&(l.start_line=parseInt(l.start_line)),l.end_line&&(l.end_line=parseInt(l.end_line)),l.depth&&(l.depth=parseInt(l.depth)),s==="edit_file"?e.push({tool:"search_and_replace",args:l,format:"xml_prompt",rawMatch:i[0]}):e.push({tool:s,args:l,format:"xml_prompt",rawMatch:i[0]})}}return e}function W$(n){return eg(n)}function G$(n){let e=[],t=/```(?:json|tool_call)?\s*\n([\s\S]*?)\n```/g,s;for(;(s=t.exec(n))!==null;)try{let r=JSON.parse(s[1].trim()),i=ys(r);i&&e.push({...i,format:"markdown_json",rawMatch:s[0]})}catch{}return e}function V$(n){let e=[],t=/\{\s*"function"\s*:/g,s;for(;(s=t.exec(n))!==null;){let r=Zm(n,s.index);if(r)try{let i=JSON.parse(r),o=ys(i);o&&e.push({...o,format:"function_call",rawMatch:r})}catch{}}return e}function z$(n){let e=[],t=/\{\s*"(?:name|tool)"\s*:/g,s;for(;(s=t.exec(n))!==null;){let r=Zm(n,s.index);if(r)try{let i=JSON.parse(r),o=ys(i);o&&e.push({...o,format:"json_object",rawMatch:r})}catch{}}return e}function Y$(n){let e=[],t=/<<?tool[-_]call\s*>>?([\s\S]*?)(?:<<?\/tool[-_]call\s*>>?|$)/gi,s,r=!1;for(;(s=t.exec(n))!==null;){let i=s[1],o=/<function=([^>]+)>/i.exec(i);if(o){r=!0;let a=o[1].trim(),l={},u=/<parameter=([^>]+)>([\s\S]*?)<\/parameter>/gi,d;for(;(d=u.exec(i))!==null;){let f=d[1].trim(),h=d[2].trim();h==="true"?h=!0:h==="false"?h=!1:!isNaN(Number(h))&&h!==""&&(h=Number(h)),l[f]=h}e.push({tool:a,args:l,format:"xml_parameters",rawMatch:s[0]})}}if(!r&&/<function=([^>]+)>/i.test(n)){let i=/<function=([^>]+)>/i.exec(n);if(i){let o=i[1].trim(),a={},l=/<parameter=([^>]+)>([\s\S]*?)<\/parameter>/gi,u;for(;(u=l.exec(n))!==null;){let d=u[1].trim(),f=u[2].trim();f==="true"?f=!0:f==="false"?f=!1:!isNaN(Number(f))&&f!==""&&(f=Number(f)),a[d]=f}e.push({tool:o,args:a,format:"xml_parameters",rawMatch:n})}}return e}function tg(){return Fl||(Fl=new Nl),Fl}var Lt,Hr,Qm,jr,Ll,Nl,Fl,ng=L(()=>{"use strict";Lt=O(require("fs")),Hr=O(require("path")),Qm=O(require("os")),jr=Hr.join(Qm.homedir(),".hablas","model-formats.json");Ll=[{format:"xml_tool_call_wrapper",parse:q$},{format:"xml_prompt",parse:W$},{format:"xml_tags",parse:U$},{format:"xml_parameters",parse:Y$},{format:"hermes",parse:K$},{format:"markdown_json",parse:G$},{format:"function_call",parse:V$},{format:"json_object",parse:z$}],Nl=class{registry;constructor(){this.registry=j$()}parse(e,t,s){if(t&&Array.isArray(t)&&t.length>0){let i=t.filter(o=>o?.function?.name&&typeof o.function.name=="string");if(i.length>0){let o=i.map(a=>({function:{name:a.function.name,arguments:a.function.arguments||{}}}));return s&&this.learnFormat(s,"native"),{toolCalls:o,displayContent:(e||"").trim(),format:"native"}}}let r=e||"";if(!r.trim())return{toolCalls:[],displayContent:"",format:"unknown"};if(s){let i=this.registry[s];if(i&&i.format!=="native"){let o=Ll.find(a=>a.format===i.format);if(o){let a=o.parse(r);if(a.length>0)return this.learnFormat(s,i.format),this.buildResult(a,r)}}}for(let{parse:i}of Ll){let o=i(r);if(o.length>0){let a=o[0].format;return s&&this.learnFormat(s,a),this.buildResult(o,r)}}return{toolCalls:[],displayContent:r.trim(),format:"unknown"}}mightContainToolCall(e){if(!e)return!1;let t=e.trim();return!!(/<<?tool[-_]call[\s>]/i.test(t)||/<function=/i.test(t)||t.includes("```tool_call")||t.includes("```json")&&t.includes('"name"')||/<<?(?:read_file|write_file|run_command|edit_file|search_codebase|create_dir|delete_file|list_dir|append_to_file|patch_file|move_file|get_file_info)[\s>]/i.test(t)||t.startsWith("{")&&(t.includes('"name"')||t.includes('"tool"'))&&(t.includes('"arguments"')||t.includes('"args"')||t.includes('"parameters"'))||t.includes('"function"')&&t.includes('"name"'))}detectFormat(e){for(let{format:t,parse:s}of Ll)if(s(e).length>0)return t;return"unknown"}learnFormat(e,t){let s=this.registry[e];s&&s.format===t?(s.successCount++,s.lastUsed=new Date().toISOString()):this.registry[e]={format:t,successCount:1,lastUsed:new Date().toISOString()},H$(this.registry)}getLearnedFormat(e){return this.registry[e]?.format??null}getLearnedFormats(){let e={};for(let[t,s]of Object.entries(this.registry))e[t]={format:s.format,successCount:s.successCount};return e}buildResult(e,t){let s=e.map(o=>({function:{name:o.tool,arguments:o.args}})),r=t,i=[...e].sort((o,a)=>a.rawMatch.length-o.rawMatch.length);for(let o of i)r=r.replace(o.rawMatch,"");return r=r.replace(/<<?thinking>>?[\s\S]*?<<?\/thinking>>?/gi,""),r=r.replace(/<<?think>>?[\s\S]*?<<?\/think>>?/gi,""),r=r.replace(/\n{3,}/g,`
|
|
965
965
|
|
|
966
|
-
`),{toolCalls:s,displayContent:r.trim(),format:e[0]?.format??"unknown"}}},Fl=null});function X$(n,e,t){let r=tg().parse(e,n,t);return{toolCalls:r.toolCalls,displayContent:r.displayContent}}function Q$(n,e){return n==="write_file"&&typeof e.path=="string"?`create ${e.path}`:(n==="edit_file"||n==="patch_file"||n==="search_and_replace")&&typeof e.path=="string"?`modify ${e.path}`:n==="read_file"&&typeof e.path=="string"?`read ${e.path}`:n==="run_command"&&typeof e.command=="string"?String(e.command).slice(0,80):typeof e.path=="string"?String(e.path):n.replace(/_/g," ")}function Z$(n){let e=(n||"").toLowerCase();return e.includes("eacces")||e.includes("permission")||e.includes("enospc")||e.includes("readonly")||e.includes("security")||e.includes("[write_file]")||e.includes("[delete_file]")||e.includes("[move_file]")||e.includes("[search_and_replace]")}async function ig(n,e,t,s){let r=0,i=Date.now();for(;r<=rg;){let o=await n.execute({name:e,arguments:t});if(o.success||r>=rg)return{success:o.success,output:o.output,error:o.error,duration:Date.now()-i,retries:r};r++,s.info({tool:e,retry:r,error:o.error},"Retrying tool"),await new Promise(a=>setTimeout(a,500))}return{success:!1,output:"",error:"Max retries exceeded",duration:Date.now()-i,retries:r}}async function Br(n){let{identity:e,client:t,registry:s,session:r,contextManager:i,logger:o,io:a={},safetyPolicy:l,abortSignal:u,skipTools:d}=n,f=n.reactEngine??ms(),h=n.errorRecovery??gs(),m=d?[]:s.getOllamaTools(),p=t.getModel(),g=n.maxIterations??J$,x=[],w=[],$=[],A="",y=0,v=!1;for(;y<g;){if(y++,u?.aborted)return{output:A,toolsUsed:qt(x),toolResults:w,touchedFiles:qt($),iterations:y,success:!1,error:"Aborted",completedNaturally:v};let b=f.buildBudgetWarningPrompt();b&&r.addUserMessage(b,{priority:"critical",tags:["system-budget"]});let S;try{S=await t.chatWithTools(r.getMessages(),m,u)}catch(W){let E=W;if(E.name==="AbortError"||u?.aborted)return{output:A,toolsUsed:qt(x),toolResults:w,touchedFiles:qt($),iterations:y,success:!1,error:"Aborted",completedNaturally:v};if(y<=1){a.onNotice?.(`Transient model error: ${E.message??"unknown"} \u2014 retrying\u2026`,"retry"),await new Promise(k=>setTimeout(k,1e3)),y--;continue}return a.onError?.(E.message??"Model request failed"),{output:A,toolsUsed:qt(x),toolResults:w,touchedFiles:qt($),iterations:y,success:!1,error:E.message,completedNaturally:v}}let _=S.message?.content||"",T=S.message?.tool_calls,I=f.parseThinking(_);I.hasThinking&&(f.recordStep({thought:I.thinking}),o.debug({thinking:I.thinking.slice(0,200)},"ReAct thinking"));let{toolCalls:C,displayContent:F}=X$(T,_,p);if(F&&F.trim()&&(A=F,await a.onAssistantText?.(F,e)),C.length===0){r.addAssistantMessage(_,void 0,e.role),v=!0;break}r.addAssistantMessage(_,C,e.role);let H=C.length;for(let W=0;W<C.length;W++){let E=C[W];if(!E?.function?.name)continue;let k=E.function.name,J=E.function.arguments||{},K=s.getSafetyLevel(k)??"confirm";if(!s.get(k)){a.onNotice?.(`Unknown tool: ${k} \u2014 skipping`,"warn"),r.addToolMessage(`Error: Unknown tool "${k}". Available: ${s.getAll().map(Oe=>Oe.name).join(", ")}`);continue}if(await l(k,K,J)==="skip"){r.addToolMessage(`Tool ${k} was skipped by policy/user.`);break}x.push(k),typeof J.path=="string"&&$.push(J.path);let te=Q$(k,J);a.onToolStart?.(k,te,J),a.onToolCall?.(),f.recordStep({thought:I.hasThinking?`Executing: ${k}`:"",action:k,actionInput:J});let Q=await ig(s,k,J,o);a.onToolEnd?.(k,Q.success,Q.error||Q.output,Q.duration,J);let ce;if(Q.success)ce=os(Q.output,sg),f.recordObservation(ce.slice(0,300)),w.push({tool:k,success:!0,summary:Q.output.slice(0,150)});else{let Oe=Q.error||"Unknown error",Fe=h.analyze(k,Oe,J);if(ce=h.buildRecoveryMessage(Fe,Oe),f.recordObservation(`FAILED: ${Oe}`,`Recovery: ${Fe.strategy} \u2014 ${Fe.suggestion}`),o.info({tool:k,errorClass:Fe.errorClass,strategy:Fe.strategy},"Error recovery analysis"),w.push({tool:k,success:!1,summary:Oe.slice(0,150)}),Fe.autoRetry&&!f.isOverBudget()){a.onNotice?.("Auto-retrying (transient error)\u2026","retry");let ye=await ig(s,k,J,o);a.onToolEnd?.(k,ye.success,ye.output,ye.duration,J),ye.success&&(ce=os(ye.output,sg),f.recordObservation(ce.slice(0,300),"Auto-retry succeeded"),w[w.length-1]={tool:k,success:!0,summary:ye.output.slice(0,150)})}}if(r.addToolMessage(ce),Q.success&&k==="read_file"&&typeof J.path=="string"&&i?.addFile(J.path,Q.output),o.info({tool:k,success:Q.success,durationMs:Q.duration,retries:Q.retries},"Tool executed"),!Q.success&&Z$(Q.error)){a.onNotice?.("Critical tool failure \u2014 aborting subsequent tool executions.","warn");break}H>1&&W<H-1}f.isOverBudget()&&a.onNotice?.(`Reached max reasoning steps (${f.getConfig().maxSteps}). Wrapping up.`,"warn")}return y>=g&&!v&&a.onNotice?.(`Reached max iterations (${g}). Stopping.`,"warn"),o.info({summary:f.getTurnSummary(),agent:e.name},"Agentic turn completed"),{output:A,toolsUsed:qt(x),toolResults:w,touchedFiles:qt($),iterations:y,success:!0,completedNaturally:v}}function qt(n){return[...new Set(n)]}function og(n){return async(e,t)=>{let s=e.replace(/_/g," ");return!n.autoMode&&n.interactive?t==="confirm"&&n.confirm?await n.confirm(`Proceed with ${s}?`)?"allow":"skip":t==="dangerous"&&n.confirmDangerous?await n.confirmDangerous(`Dangerous: ${s}`)?"allow":"skip":"allow":!n.autoMode&&t==="dangerous"?"skip":"allow"}}function ag(){return(n,e)=>e==="dangerous"?"skip":"allow"}var J$,sg,rg,jl=L(()=>{"use strict";da();Ml();Dl();ng();J$=150,sg=2e3,rg=2});var cg,e0,t0,n0,lg,bs,ug=L(()=>{"use strict";cg=O(Ol());jn();pa();fa();Ns();Ri();Fa();jl();e0={hablas:"planner",bob:"architect",alex:"coder",david:"researcher",emma:"product-manager",gate:"gate"},t0=(0,cg.default)({level:"silent"}),n0=40,lg={hablas:{role:"hablas",model:"stepfun-ai/step-3.7-flash",temperature:.7},bob:{role:"bob",model:"stepfun-ai/step-3.7-flash",temperature:.4},alex:{role:"alex",model:"stepfun-ai/step-3.7-flash",temperature:.2},david:{role:"david",model:"stepfun-ai/step-3.7-flash",temperature:.5},emma:{role:"emma",model:"stepfun-ai/step-3.7-flash",temperature:.6},gate:{role:"gate",model:"stepfun-ai/step-3.
|
|
966
|
+
`),{toolCalls:s,displayContent:r.trim(),format:e[0]?.format??"unknown"}}},Fl=null});function X$(n,e,t){let r=tg().parse(e,n,t);return{toolCalls:r.toolCalls,displayContent:r.displayContent}}function Q$(n,e){return n==="write_file"&&typeof e.path=="string"?`create ${e.path}`:(n==="edit_file"||n==="patch_file"||n==="search_and_replace")&&typeof e.path=="string"?`modify ${e.path}`:n==="read_file"&&typeof e.path=="string"?`read ${e.path}`:n==="run_command"&&typeof e.command=="string"?String(e.command).slice(0,80):typeof e.path=="string"?String(e.path):n.replace(/_/g," ")}function Z$(n){let e=(n||"").toLowerCase();return e.includes("eacces")||e.includes("permission")||e.includes("enospc")||e.includes("readonly")||e.includes("security")||e.includes("[write_file]")||e.includes("[delete_file]")||e.includes("[move_file]")||e.includes("[search_and_replace]")}async function ig(n,e,t,s){let r=0,i=Date.now();for(;r<=rg;){let o=await n.execute({name:e,arguments:t});if(o.success||r>=rg)return{success:o.success,output:o.output,error:o.error,duration:Date.now()-i,retries:r};r++,s.info({tool:e,retry:r,error:o.error},"Retrying tool"),await new Promise(a=>setTimeout(a,500))}return{success:!1,output:"",error:"Max retries exceeded",duration:Date.now()-i,retries:r}}async function Br(n){let{identity:e,client:t,registry:s,session:r,contextManager:i,logger:o,io:a={},safetyPolicy:l,abortSignal:u,skipTools:d}=n,f=n.reactEngine??ms(),h=n.errorRecovery??gs(),m=d?[]:s.getOllamaTools(),p=t.getModel(),g=n.maxIterations??J$,x=[],w=[],$=[],A="",y=0,v=!1;for(;y<g;){if(y++,u?.aborted)return{output:A,toolsUsed:qt(x),toolResults:w,touchedFiles:qt($),iterations:y,success:!1,error:"Aborted",completedNaturally:v};let b=f.buildBudgetWarningPrompt();b&&r.addUserMessage(b,{priority:"critical",tags:["system-budget"]});let S;try{S=await t.chatWithTools(r.getMessages(),m,u)}catch(W){let E=W;if(E.name==="AbortError"||u?.aborted)return{output:A,toolsUsed:qt(x),toolResults:w,touchedFiles:qt($),iterations:y,success:!1,error:"Aborted",completedNaturally:v};if(y<=1){a.onNotice?.(`Transient model error: ${E.message??"unknown"} \u2014 retrying\u2026`,"retry"),await new Promise(k=>setTimeout(k,1e3)),y--;continue}return a.onError?.(E.message??"Model request failed"),{output:A,toolsUsed:qt(x),toolResults:w,touchedFiles:qt($),iterations:y,success:!1,error:E.message,completedNaturally:v}}let _=S.message?.content||"",T=S.message?.tool_calls,I=f.parseThinking(_);I.hasThinking&&(f.recordStep({thought:I.thinking}),o.debug({thinking:I.thinking.slice(0,200)},"ReAct thinking"));let{toolCalls:C,displayContent:F}=X$(T,_,p);if(F&&F.trim()&&(A=F,await a.onAssistantText?.(F,e)),C.length===0){r.addAssistantMessage(_,void 0,e.role),v=!0;break}r.addAssistantMessage(_,C,e.role);let H=C.length;for(let W=0;W<C.length;W++){let E=C[W];if(!E?.function?.name)continue;let k=E.function.name,J=E.function.arguments||{},K=s.getSafetyLevel(k)??"confirm";if(!s.get(k)){a.onNotice?.(`Unknown tool: ${k} \u2014 skipping`,"warn"),r.addToolMessage(`Error: Unknown tool "${k}". Available: ${s.getAll().map(Oe=>Oe.name).join(", ")}`);continue}if(await l(k,K,J)==="skip"){r.addToolMessage(`Tool ${k} was skipped by policy/user.`);break}x.push(k),typeof J.path=="string"&&$.push(J.path);let te=Q$(k,J);a.onToolStart?.(k,te,J),a.onToolCall?.(),f.recordStep({thought:I.hasThinking?`Executing: ${k}`:"",action:k,actionInput:J});let Q=await ig(s,k,J,o);a.onToolEnd?.(k,Q.success,Q.error||Q.output,Q.duration,J);let ce;if(Q.success)ce=os(Q.output,sg),f.recordObservation(ce.slice(0,300)),w.push({tool:k,success:!0,summary:Q.output.slice(0,150)});else{let Oe=Q.error||"Unknown error",Fe=h.analyze(k,Oe,J);if(ce=h.buildRecoveryMessage(Fe,Oe),f.recordObservation(`FAILED: ${Oe}`,`Recovery: ${Fe.strategy} \u2014 ${Fe.suggestion}`),o.info({tool:k,errorClass:Fe.errorClass,strategy:Fe.strategy},"Error recovery analysis"),w.push({tool:k,success:!1,summary:Oe.slice(0,150)}),Fe.autoRetry&&!f.isOverBudget()){a.onNotice?.("Auto-retrying (transient error)\u2026","retry");let ye=await ig(s,k,J,o);a.onToolEnd?.(k,ye.success,ye.output,ye.duration,J),ye.success&&(ce=os(ye.output,sg),f.recordObservation(ce.slice(0,300),"Auto-retry succeeded"),w[w.length-1]={tool:k,success:!0,summary:ye.output.slice(0,150)})}}if(r.addToolMessage(ce),Q.success&&k==="read_file"&&typeof J.path=="string"&&i?.addFile(J.path,Q.output),o.info({tool:k,success:Q.success,durationMs:Q.duration,retries:Q.retries},"Tool executed"),!Q.success&&Z$(Q.error)){a.onNotice?.("Critical tool failure \u2014 aborting subsequent tool executions.","warn");break}H>1&&W<H-1}f.isOverBudget()&&a.onNotice?.(`Reached max reasoning steps (${f.getConfig().maxSteps}). Wrapping up.`,"warn")}return y>=g&&!v&&a.onNotice?.(`Reached max iterations (${g}). Stopping.`,"warn"),o.info({summary:f.getTurnSummary(),agent:e.name},"Agentic turn completed"),{output:A,toolsUsed:qt(x),toolResults:w,touchedFiles:qt($),iterations:y,success:!0,completedNaturally:v}}function qt(n){return[...new Set(n)]}function og(n){return async(e,t)=>{let s=e.replace(/_/g," ");return!n.autoMode&&n.interactive?t==="confirm"&&n.confirm?await n.confirm(`Proceed with ${s}?`)?"allow":"skip":t==="dangerous"&&n.confirmDangerous?await n.confirmDangerous(`Dangerous: ${s}`)?"allow":"skip":"allow":!n.autoMode&&t==="dangerous"?"skip":"allow"}}function ag(){return(n,e)=>e==="dangerous"?"skip":"allow"}var J$,sg,rg,jl=L(()=>{"use strict";da();Ml();Dl();ng();J$=150,sg=2e3,rg=2});var cg,e0,t0,n0,lg,bs,ug=L(()=>{"use strict";cg=O(Ol());jn();pa();fa();Ns();Ri();Fa();jl();e0={hablas:"planner",bob:"architect",alex:"coder",david:"researcher",emma:"product-manager",gate:"gate"},t0=(0,cg.default)({level:"silent"}),n0=40,lg={hablas:{role:"hablas",model:"stepfun-ai/step-3.7-flash",temperature:.7},bob:{role:"bob",model:"stepfun-ai/step-3.7-flash",temperature:.4},alex:{role:"alex",model:"stepfun-ai/step-3.7-flash",temperature:.2},david:{role:"david",model:"stepfun-ai/step-3.7-flash",temperature:.5},emma:{role:"emma",model:"stepfun-ai/step-3.7-flash",temperature:.6},gate:{role:"gate",model:"stepfun-ai/step-3.5-flash",temperature:.3}},bs=class{baseConfig;agentModels;toolRegistry=null;onOutput=null;channel=null;mindsetRegistry=br();sharedContext=null;contextManager;constructor(e){this.baseConfig=e,this.agentModels=zt(),this.contextManager=new tn(e)}setSharedContext(e){this.sharedContext=e}setChannel(e){this.channel=e}setToolRegistry(e){this.toolRegistry=e}setOutputCallback(e){this.onOutput=e}reloadModels(){this.agentModels=zt()}getAgentModel(e){let t=this.agentModels[e];if(t)return{model:t.model,temperature:t.temperature??lg[e]?.temperature??.5};let s=lg[e];return{model:s.model,temperature:s.temperature??.5}}async runAgent(e,t,s,r,i){let o=Date.now(),a;e==="gate"?a={name:"Gate",title:"Hidden Executive Layer",role:"gate"}:a=xe.find($=>$.role===e);let l=this.getAgentModel(e),u=i?.maxIterations||n0,d={...this.baseConfig,model:l.model},f=Me(d),h=this.buildAgentPrompt(a,s),m=new nn(h,30,this.baseConfig.contextBudget);m.addUserMessage(t);let p={name:a.name,title:a.title,role:e};this.emit(a.name,"thinking",`\u2605 Hablas \u2192 Delegating to @${a.name} (${a.title})...`);let g={onAssistantText:$=>{this.emit(a.name,"speaking",$.slice(0,200))},onToolStart:($,A,y)=>{this.emit(a.name,"tool",A),this.channel&&this.channel.emitEvent({type:"act",agent:a.name,toolName:$,toolArgs:this.safeArgs(y),content:A})},onToolEnd:($,A,y)=>{this.channel&&this.channel.emitEvent({type:"observe",agent:a.name,toolName:$,success:A,content:A?this.summarizeOk($,y):`error: ${y.slice(0,120)}`})},onError:$=>this.emit(a.name,"error",$)},x=await Br({identity:p,client:f,registry:this.toolRegistry,session:m,contextManager:this.contextManager,logger:t0,io:g,safetyPolicy:ag(),abortSignal:i?.abortSignal,skipTools:(!r||r.length===0,!1),maxIterations:u});if(this.sharedContext&&x.touchedFiles.length)try{this.sharedContext.set(`files:@${a.name}`,x.touchedFiles.join(", "))}catch{}let w=x.touchedFiles.length?[`@${a.name} touched: ${x.touchedFiles.join(", ")}`]:[];return{agent:e,agentName:a.name,output:x.output||(x.success?"Done.":x.error??"No output"),toolsUsed:x.toolsUsed,toolResults:x.toolResults,duration:Date.now()-o,iterations:x.iterations,success:x.success,error:x.error,discoveries:w,touchedFiles:x.touchedFiles}}async runSequential(e,t,s){let r=[],i="",o=[];for(let a=0;a<e.length;a++){let{role:l,task:u}=e[a];if(s?.abortSignal?.aborted)break;let d=[];if(i&&(d.push("## Previous Agent Results"),d.push(i)),o.length>0){d.push(`
|
|
967
967
|
## Handoff Chain`);for(let p of o)d.push(`- @${p.from} \u2192 @${p.to}: ${p.context.slice(0,100)}`)}let f=d.join(`
|
|
968
968
|
`),h=xe.find(p=>p.role===l);if(h&&a>0){let p=e[a-1].role,g=xe.find(x=>x.role===p);this.emit(h.name,"thinking",`\u2605 Handoff: @${g?.name||p} \u2192 @${h.name} (${h.title})`)}let m=await this.runAgent(l,u,f,t,s);if(r.push(m),m.success&&m.output){let p=m.output.length>600?m.output.slice(0,600)+"...":m.output;i+=`
|
|
969
969
|
|
|
@@ -1085,9 +1085,9 @@ ${t.content}`).join(`
|
|
|
1085
1085
|
`)}persistKV(){if(this.kvStore.size===0)return;let e=this.read("CONTEXT.md")||mg,t=Array.from(this.kvStore.entries()).map(([i,o])=>`- **${i}**: ${o}`).join(`
|
|
1086
1086
|
`),s=/## Notes\n[\s\S]*$/,r=e.replace(s,`## Notes
|
|
1087
1087
|
${t}
|
|
1088
|
-
`);this.write("CONTEXT.md",r)}ensureDir(){re.existsSync(this.contextDir)||re.mkdirSync(this.contextDir,{recursive:!0})}}});function Bl(n){return xe.find(e=>e.role===n)?.name||n}var xs,yg=L(()=>{"use strict";Ns();Hl();xs=class{channel;runner;chat;constructor(e,t,s,r){this.channel=e,this.runner=t,this.chat=s,this.runner.setChannel(e),this.chat.resetBudget()}async run(e,t,s,r={}){this.chat.setAbortSignal(r.abortSignal);let i=r.peerReview!==!1,o=new Dn(process.cwd());this.runner.setSharedContext(
|
|
1088
|
+
`);this.write("CONTEXT.md",r)}ensureDir(){re.existsSync(this.contextDir)||re.mkdirSync(this.contextDir,{recursive:!0})}}});function Bl(n){return xe.find(e=>e.role===n)?.name||n}var xs,yg=L(()=>{"use strict";Ns();Hl();xs=class{channel;runner;chat;constructor(e,t,s,r){this.channel=e,this.runner=t,this.chat=s,this.runner.setChannel(e),this.chat.resetBudget()}async run(e,t,s,r={}){this.chat.setAbortSignal(r.abortSignal);let i=r.peerReview!==!1,o=r.centralizedToLeader===!0,a=new Dn(process.cwd());this.runner.setSharedContext(a),this.channel.emitEvent({type:"phase",agent:"System",content:"Delegating to the team"});let l=t.tasks.filter(m=>m.role!=="hablas").map(m=>({role:m.role,task:`${m.description}
|
|
1089
1089
|
|
|
1090
|
-
Original request: ${e}`})),
|
|
1090
|
+
Original request: ${e}`})),u=[],d="hablas",f=null;for(let m of l){if(r.abortSignal?.aborted)break;let p=xe.find(w=>w.role===m.role);if(!p)continue;if(this.channel.emitEvent({type:"handoff",agent:Bl(d),to:p.name}),!o){let w=await this.chat.generateHandoffLine(d,m.role,m.task);this.channel.emitEvent({type:"speak",agent:Bl(d),to:p.name,content:w});let $=await this.chat.generateAckLine(m.role,d);this.channel.emitEvent({type:"speak",agent:p.name,to:Bl(d),content:$})}let g=Date.now(),x=await this.runner.runAgent(m.role,m.task,void 0,s,{abortSignal:r.abortSignal});u.push(x),x.success&&x.output?(this.channel.emitEvent({type:"summary",agent:p.name,durationMs:Date.now()-g}),m.role==="alex"&&(f=x.output),i&&m.role==="alex"&&t.tasks.some(w=>w.role==="bob")&&f&&await this.runPeerReview("bob","alex",f,r.abortSignal,o)):x.error&&this.channel.emitEvent({type:"error",agent:p.name,content:x.error}),d=m.role}this.channel.emitEvent({type:"phase",agent:"System",content:"Hablas compiling final report"});let h=await this.synthesize(e,u,s,r.abortSignal);return this.channel.emitEvent({type:"done",agent:"Hablas"}),h}async runPeerReview(e,t,s,r,i=!1){let o=xe.find(l=>l.role===e),a=xe.find(l=>l.role===t);if(!(!o||!a)){if(!i){let l=await this.chat.generateReviewLine(e,t,s);this.channel.emitEvent({type:"review",agent:o.name,to:a.name,content:l});let u=await this.chat.generateReviewAck(t,e);this.channel.emitEvent({type:"speak",agent:a.name,to:o.name,content:u})}r?.aborted}}async synthesize(e,t,s,r){let i=t.filter(d=>d.success&&d.output);if(i.length===0)return{results:t,finalSynthesis:"The team encountered errors and could not complete the task. Please review the logs and try again.",synthesisOk:!1};let o=i.map(d=>{let f=xe.find(h=>h.role===d.agent);return`### Report from @${d.agentName} (${f?.title??d.agent}):
|
|
1091
1091
|
${d.output}`}).join(`
|
|
1092
1092
|
|
|
1093
1093
|
`),a=`You are Hablas, the Team Leader. Your team has completed a multi-agent workflow for the user's request: "${e}".
|
|
@@ -1241,12 +1241,10 @@ ${U}`,{priority:"low",tags:["auto-inject"]})}if(n.team?.enabled&&Re){let U=n.tea
|
|
|
1241
1241
|
${c.warning("\u26A0")} ${c.strong("@Consul")}: a teammate locked ${c.highlight(G)} first. Halting to avoid a conflict.
|
|
1242
1242
|
`);continue}}Re.setActivity(ce.slice(0,80))}let Fe=U=>{let ue=U.trim().toLowerCase();return ue.length<12||["hi","hey","\u0627\u0647","ok","thanks","\u0634\u0643\u0631\u0627","yo","hello","\u0635\u0628\u0627\u062D","\u0645\u0633\u0627\u0621","how are","what's up","\u0643\u064A\u0641\u0643","\u062A\u0645\u0627\u0645","\u0627\u064A\u0647","\u0627\u0647","lol","haha"].some(G=>ue.includes(G))?!0:!["build","create","fix","add","implement","design","make","write","update","remove","deploy","test","plan","generate","complete","setup"].some(G=>ue.includes(G))&&ue.length<40},ye=n.agents.enabled&&!Fe(ce);try{if(m&&n.agents.enabled){let U=`User input: "${ce}"
|
|
1243
1243
|
|
|
1244
|
-
Decide the professional routing for this engineering interaction.`,ue=await m.runAgent("gate",U,void 0,i.getOllamaTools(),{abortSignal:k?.signal});if(ue.success&&ue.output){let Pe=ue.output.toLowerCase();Pe.includes("mode: casual")||Pe.includes("casual")?ye=!1:(Pe.includes("mode: build")||Pe.includes("build")||Pe.includes("mode: design"))&&(ye=!0)}}}catch{}if(ye){console.log(`
|
|
1245
|
-
${c.accent("\u2605")} ${c.strong("FULL TEAM ACTIVE")} \u2014 Hablas + Bob + Alex + David + Emma (rich theatre, max power, no classifier)`),console.log(` ${c.muted("\u25C9 Gate (hidden) analyzing input and routing decision...")}`),console.log(` ${c.muted("Live status updates below (handoffs + summaries) \u2014 shows real activity to reduce perceived delay.")}
|
|
1246
|
-
`);let U=["hablas","bob","alex","david","emma"];for(let ee of U)I=Fi(I,ee);dn(I),p.reset(),x.resetBudget();let ue={id:"build-"+Date.now(),description:ce.substring(0,100),tasks:[{role:"emma",description:"Analyze the request from product/requirements perspective and clarify if needed."},{role:"bob",description:"Provide architecture, design or structural guidance."},{role:"alex",description:"Execute the core implementation, coding or action based on the input."},{role:"david",description:"Research, data analysis or supporting information."}],strategy:"mixed",createdAt:new Date,approved:!0},Pe=i.getOllamaTools(),D=new xs(p,m,x,n),G=[],P="The team operation completed.",V=!1;try{let ee=await D.run(ce,ue,Pe,{abortSignal:k?.signal,peerReview:!0});G=ee.results||[],P=ee.finalSynthesis||P,V=!!ee.synthesisOk}catch(ee){let de=ee?.message||String(ee);de.includes("Aborted")||ee?.name==="AbortError"?(console.log(` ${c.warning("Operation aborted.")}`),P="Team operation was aborted. Provide more details or try a focused request."):(console.log(ke(`Team error: ${de}`)),P="The team encountered an error during execution. Please review logs and retry."),V=!1}console.log(mn("Hablas","Team Leader")),console.log(gn(P)),T.addAssistantMessage(V?P:`[Team Summary]
|
|
1244
|
+
Decide the professional routing for this engineering interaction.`,ue=await m.runAgent("gate",U,void 0,i.getOllamaTools(),{abortSignal:k?.signal});if(ue.success&&ue.output){let Pe=ue.output.toLowerCase();Pe.includes("mode: casual")||Pe.includes("casual")?ye=!1:(Pe.includes("mode: build")||Pe.includes("build")||Pe.includes("mode: design"))&&(ye=!0)}}}catch{}if(ye){let U=["hablas","bob","alex","david","emma"];for(let ee of U)I=Fi(I,ee);dn(I),p.reset(),x.resetBudget();let ue={id:"build-"+Date.now(),description:ce.substring(0,100),tasks:[{role:"emma",description:"Analyze the request from product/requirements perspective and clarify if needed."},{role:"bob",description:"Provide architecture, design or structural guidance."},{role:"alex",description:"Execute the core implementation, coding or action based on the input."},{role:"david",description:"Research, data analysis or supporting information."}],strategy:"mixed",createdAt:new Date,approved:!0},Pe=i.getOllamaTools(),D=new xs(p,m,x,n),G=[],P="The team operation completed.",V=!1;try{let ee=await D.run(ce,ue,Pe,{abortSignal:k?.signal,peerReview:!0,centralizedToLeader:!0});G=ee.results||[],P=ee.finalSynthesis||P,V=!!ee.synthesisOk}catch(ee){let de=ee?.message||String(ee);de.includes("Aborted")||ee?.name==="AbortError"?(console.log(` ${c.warning("Operation aborted.")}`),P="Team operation was aborted. Provide more details or try a focused request."):(console.log(ke(`Team error: ${de}`)),P="The team encountered an error during execution. Please review logs and retry."),V=!1}console.log(mn("Hablas","Team Leader")),console.log(gn(P)),T.addAssistantMessage(V?P:`[Team Summary]
|
|
1247
1245
|
`+P),await Dg(n,t);continue}else T.addUserMessage(ce);k=new AbortController,S.startTurn(),_.resetTurn(),await Fg(T,r,i,o,{interactive:!0,autoMode:W,input:a,logger:e,config:n,abortSignal:k.signal,reactEngine:S,errorRecovery:_,skipTools:!1,onToolCall:()=>{F++,I=Li(I,"tool_call"),dn(I)}}),await Dg(n,t)}catch(Z){if(Z.code==="ERR_USE_AFTER_CLOSE")break;if(Z.name==="AbortError")continue;console.log(ke(Z.message)),e.error(Z,"REPL error")}a.close(),Re&&await Re.shutdown(),console.log(Yi({turns:C,duration:Date.now()-H,toolCalls:F}))}async function $0(n,e,t,s="build"){let r=e.workingDirectory==="."?process.cwd():e.workingDirectory;e.agents.enabled=!0;let i=Me(e),o=new En(r,e),a=new bs(e);a.setToolRegistry(o);let l=new vs,u=new _s(l,{hideActs:!0}).attach(),d=new ws(e,{tokenBudget:500,maxChars:140});a.setChannel(l),l.onEvent(w=>{w.type==="phase"?console.log(`
|
|
1248
1246
|
${c.accent("\u25C6")} ${c.strong(w.content)}`):w.type==="handoff"?console.log(` ${c.muted("\u2605")} ${w.agent} \u2501\u2501\u25B6 ${w.to}`):w.type==="speak"?console.log(` ${c.primary(w.agent)}: ${w.content}`):w.type==="act"||w.type==="tool"?console.log(` ${c.warning("\u{1F527}")} [${w.agent}] ${w.content||w.toolName}`):w.type==="summary"||w.type==="observe"?console.log(` ${c.success("\u2713")} ${w.agent||""} ${w.content||""}`):w.type==="error"&&console.log(` ${c.error("\u2717")} ${w.agent}: ${w.content}`)}),console.log(`
|
|
1249
|
-
${c.accent("\u2605")} ${c.strong("FULL TEAM "+s.toUpperCase())} \u2014 ${e.model} (classification deleted, max power)`);let f={id:`${s}-`+Date.now(),description:n.substring(0,100),tasks:[{role:"emma",description:"Analyze the request from product/requirements perspective and clarify if needed."},{role:"bob",description:"Provide architecture, design or structural guidance."},{role:"alex",description:"Execute the core implementation, coding or action based on the input."},{role:"david",description:"Research, data analysis or supporting information."}],strategy:"mixed",createdAt:new Date,approved:!0},h=o.getOllamaTools(),m=new xs(l,a,d,e),{results:p,finalSynthesis:g,synthesisOk:x}=await m.run(n,f,h,{peerReview:!0});console.log(`
|
|
1247
|
+
${c.accent("\u2605")} ${c.strong("FULL TEAM "+s.toUpperCase())} \u2014 ${e.model} (classification deleted, max power)`);let f={id:`${s}-`+Date.now(),description:n.substring(0,100),tasks:[{role:"emma",description:"Analyze the request from product/requirements perspective and clarify if needed."},{role:"bob",description:"Provide architecture, design or structural guidance."},{role:"alex",description:"Execute the core implementation, coding or action based on the input."},{role:"david",description:"Research, data analysis or supporting information."}],strategy:"mixed",createdAt:new Date,approved:!0},h=o.getOllamaTools(),m=new xs(l,a,d,e),{results:p,finalSynthesis:g,synthesisOk:x}=await m.run(n,f,h,{peerReview:!0,centralizedToLeader:!0});console.log(`
|
|
1250
1248
|
${mn("Hablas","Team Leader")}`),console.log(gn(g||"Team completed the task.")),console.log(`
|
|
1251
1249
|
${c.muted("Full team execution complete. "+(x?"Synthesis OK.":"Used fallback summary."))}`)}async function C0(n,e,t){let s=e.workingDirectory==="."?process.cwd():e.workingDirectory,r=Me(e),i=new En(s,e),o=new tn(e),a=new us(s),l=await bn(s,e),u=vn(Wn,l,a),d=new nn(u,e.historySize),f=Ng(n,s);d.addUserMessage(f),await Fg(d,r,i,o,{interactive:!1,autoMode:e.autoMode||!1,logger:t,config:e})}function Ng(n,e){let t=/#([\w./-]+)/g,s=n,r;for(;(r=t.exec(n))!==null;){let i=r[1],o=Ft.resolve(e,i);mt.existsSync(o)&&(s=s.replace(`#${i}`,i))}return s}async function Dg(n,e){if(!(n.team?.enabled&&Re))return;if(await Re.releaseAllMyLocks(),!n.workspace?.autoPush){console.log(`
|
|
1252
1250
|
${c.info("\u2139")} ${c.strong("@Consul")}: "Changes tracked. Auto-push is off \u2014 commit & push manually when ready."
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hablas-ai",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.9",
|
|
4
4
|
"description": "Premium multi-agent AI coding agent for your terminal — local-first via Ollama, NVIDIA NIM, or any OpenAI-compatible API. Watch the team work in front of you.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"bin": {
|