qlogicagent 2.10.18 → 2.10.20
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/cli.js +34 -34
- package/dist/index.js +34 -34
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -11,7 +11,7 @@ var gb=Object.defineProperty;var xo=(n=>typeof require<"u"?require:typeof Proxy<
|
|
|
11
11
|
|
|
12
12
|
${m}`}))}if(c.length===0)return n;let u=[...n],d=-1;for(let p=0;p<u.length;p++)u[p].role==="system"&&(d=p);return u.splice(d+1,0,...c),u}function No(n,e,t=Mo){if(e.size===0)return{messages:n,tokensFreed:0,removedCount:0};let r=0,s=0,o=[];for(let a of n){let c=a.tool_call_id??"";if(c&&e.has(c)){r+=t(a),s++,e.delete(c);continue}o.push(a)}let i=s>0?{role:"system",content:`[${s} messages removed by snip]`}:void 0;return{messages:o,tokensFreed:r,removedCount:s,boundaryMessage:i}}var Pl,vn,rn,qn,Wn,_l,Gn,Kn,Vb,Kt,Oo=Q(()=>{"use strict";Pl=4,vn=class{constructor(e){this.estimateTokens=e}estimateTokens;compress(e,t){let r=[],s=[];for(let u of e)u.role==="system"?r.push(u):s.push(u);let o=t;for(let u of r)o-=this.estimateTokens(u);let i;for(let u of s)if(u.role==="user"){i=u;break}if(i&&(o-=this.estimateTokens(i)),o<=0)return{messages:i?[...r,i]:r,droppedCount:s.length-(i?1:0),strategy:"sliding-window"};let a=[],c=0;for(let u=s.length-1;u>=0;u--){let d=s[u];if(d===i)continue;let p=this.estimateTokens(d);if(o-p<0&&c>=Pl)break;if(o-p<0&&c<Pl){a.unshift(d),c++;continue}o-=p,a.unshift(d),c++}let l=[...r];return i&&!a.includes(i)&&l.push(i),l.push(...a),{messages:l,droppedCount:s.length-(a.length+(i&&!a.includes(i)?1:0)),strategy:"sliding-window"}}},rn=class{constructor(e=8e3){this.maxToolResultChars=e}maxToolResultChars;compress(e,t){let r=0;return{messages:e.map(o=>o.role!=="tool"||typeof o.content!="string"||o.content.length<=this.maxToolResultChars?o:(r++,{...o,content:Gb(o.content,this.maxToolResultChars)})),droppedCount:r,strategy:"tool-result-trim"}}};qn=class{config;constructor(e){this.config={protectedHeadExchanges:e.protectedHeadExchanges,protectedTailMessages:e.protectedTailMessages,summarize:e.summarize,estimateTokens:e.estimateTokens??Mo,taskContext:e.taskContext}}compress(e,t){return{messages:e,droppedCount:0,strategy:"head-tail-protected"}}async compressAsync(e,t){let r=Date.now(),{system:s,nonSystem:o}=Kb(e),i=e.reduce((_,I)=>_+this.config.estimateTokens(I),0);if(i<=t)return{messages:e,droppedCount:0,strategy:"head-tail-protected"};let a=0,c=0;for(let _=0;_<o.length&&(o[_].role==="user"&&c++,!(c>this.config.protectedHeadExchanges));_++)a=_+1;let l=Math.max(this.config.protectedTailMessages,Math.floor(o.length*.4)),u=Math.max(a,o.length-l);if(u<=a)return{messages:e,droppedCount:0,strategy:"head-tail-protected"};let d=o.slice(0,a),p=o.slice(a,u),m=o.slice(u),h=Il(p,{taskContext:this.config.taskContext}),f=await this.config.summarize(p,h),y={role:"system",content:`[Conversation summary \u2014 ${p.length} messages compressed]
|
|
13
13
|
|
|
14
|
-
${f}`},b=[...s,...d,y,...m],
|
|
14
|
+
${f}`},b=[...s,...d,y,...m],T=Date.now()-r,w=b.reduce((_,I)=>_+this.config.estimateTokens(I),0);return{messages:b,droppedCount:p.length,strategy:"head-tail-protected",metrics:{tokensBefore:i,tokensAfter:w,compressionRatio:i>0?w/i:1,latencyMs:T,usedLlm:!0,cacheInvalidated:!0}}}},Wn=class{config;constructor(e){this.config=e}compress(e,t){let r=Br(e),s=this.config.inner.compress(e,t),o=Br(s.messages),i=r!==o&&s.droppedCount>0;return i&&this.config.onCacheInvalidated?.({droppedCount:s.droppedCount,strategy:s.strategy}),{...s,metrics:{...s.metrics??{tokensBefore:0,tokensAfter:0,compressionRatio:0,latencyMs:0,usedLlm:!1},cacheInvalidated:i}}}async compressAsync(e,t){let r=Br(e),s=Vn(this.config.inner)?await this.config.inner.compressAsync(e,t):this.config.inner.compress(e,t),o=Br(s.messages),i=r!==o&&s.droppedCount>0;return i&&this.config.onCacheInvalidated?.({droppedCount:s.droppedCount,strategy:s.strategy}),{...s,metrics:{...s.metrics??{tokensBefore:0,tokensAfter:0,compressionRatio:0,latencyMs:0,usedLlm:!1},cacheInvalidated:i}}}},_l={modelContextWindow:128e3,targetUsageRatio:.75,minBudget:16e3,maxBudget:12e4};Gn=class{events=[];maxEvents;constructor(e=100){this.maxEvents=e}record(e){this.events.push(e),this.events.length>this.maxEvents&&this.events.shift()}snapshot(){let e=this.events.length;if(e===0)return{totalCompressions:0,totalLlmCalls:0,totalCacheInvalidations:0,averageCompressionRatio:1,averageLatencyMs:0,totalTokensSaved:0,recentEvents:[]};let t=0,r=0,s=0,o=0,i=0;for(let a of this.events)t+=a.tokensBefore>0?a.tokensAfter/a.tokensBefore:1,r+=a.latencyMs,s+=Math.max(0,a.tokensBefore-a.tokensAfter),a.usedLlm&&o++,a.cacheInvalidated&&i++;return{totalCompressions:e,totalLlmCalls:o,totalCacheInvalidations:i,averageCompressionRatio:t/e,averageLatencyMs:r/e,totalTokensSaved:s,recentEvents:this.events.slice(-10)}}reset(){this.events.length=0}},Kn=class{engines=new Map;activeId;register(e){this.engines.set(e.id,e)}activate(e){return this.engines.has(e)?(this.activeId=e,!0):!1}getActive(){return this.activeId?this.engines.get(this.activeId):void 0}listEngines(){return Array.from(this.engines.values()).map(e=>({id:e.id,label:e.label,active:e.id===this.activeId}))}};Vb=new Set(["file_read","read","Read","bash","shell","Bash","grep","search","Grep","grep_search","glob","Glob","file_search","web_search","WebSearch","web_fetch","WebFetch","file_edit","edit","Edit","file_write","write","Write"]),Kt=class{constructor(e=20,t=Mo){this.preserveRecentCount=e;this.estimateTokens=t}preserveRecentCount;estimateTokens;compress(e,t){if(e.length<=this.preserveRecentCount)return{messages:e,droppedCount:0,strategy:"micro-compact"};let r=e.length-this.preserveRecentCount,s=0,o=0;return{messages:e.map((a,c)=>{if(c>=r||a.role!=="tool"||typeof a.content!="string"||!a.name||!Vb.has(a.name)||a.content.length<=200)return a;let l=this.estimateTokens(a);return o+=l,s++,{...a,content:`[result cleared \u2014 ${a.content.length} chars]`}}),droppedCount:s,strategy:"micro-compact",metrics:s>0?{tokensBefore:0,tokensAfter:0,compressionRatio:0,latencyMs:0,usedLlm:!1,cacheInvalidated:!1}:void 0}}}});function Lo(){return{stages:[]}}function $o(n,e,t){let r=t?.thresholdMessages??40;if(n.filter(a=>a.role!=="system").length<=r)return{messages:n,stagedCount:0};let o=Cl(n,e),i=Xb(o,e,r);if(i.length===0)return{messages:o,stagedCount:0};for(let a of i)e.stages.push(a);return o=Cl(n,e),{messages:o,stagedCount:i.length}}function jo(n,e){let t=0;for(let r of e.stages)r.committed||(r.committed=!0,t++);return t===0?{messages:n,committed:0}:{messages:El(n,e),committed:t}}function Cl(n,e){return e.stages.filter(r=>r.committed).length===0?n:El(n,e)}function El(n,e){let t=e.stages.filter(s=>s.committed).sort((s,o)=>o.range[0]-s.range[0]),r=[...n];for(let s of t){let[o,i]=s.range;if(o>=r.length)continue;let a=Math.min(i,r.length),c={role:"system",content:s.summary};r.splice(o,a-o,c)}return r}function Xb(n,e,t){let r=Math.max(0,n.length-Math.floor(t/2)),s=[],o=new Set(e.stages.map(c=>`${c.range[0]}-${c.range[1]}`)),i=-1,a=0;for(let c=0;c<r;c++){let l=n[c];if(l.role==="tool"||l.role==="assistant"&&typeof l.content=="string"&&l.content==="")i<0&&(i=c),a++;else{if(a>=3){let d=`${i}-${i+a}`;o.has(d)||s.push({id:`collapse_${i}_${i+a}`,range:[i,i+a],summary:`[${a} tool results collapsed]`,committed:!1})}i=-1,a=0}}if(a>=3){let c=`${i}-${i+a}`;o.has(c)||s.push({id:`collapse_${i}_${i+a}`,range:[i,i+a],summary:`[${a} tool results collapsed]`,committed:!1})}return s}var Ml=Q(()=>{"use strict"});function Ri(){return{maxRoundsLimit:100,defaultMaxRounds:25,defaultTemperature:0,maxToolBudgetCap:100,defaultToolBudget:Uo,maxConsecutiveFailures:Fo,maxIdenticalCallRepeats:Bo,defaultContextWindowTokens:Ho,responseBufferTokens:qo,defaultMaxOutputTokens:Wo,defaultModelMaxOutputTokens:Go,maxOutputTokensRecoveryLimit:Ko,escalatedMaxOutputTokens:Vo,diminishingReturnsThreshold:Wr,diminishingReturnsMinContinuations:zo,defaultMaxResultSizeChars:Xo,maxToolResultsPerMessageChars:Yo,toolResultPreviewBytes:Gr,heartbeatIntervalMs:Jo,max529Retries:Qo,maxApiRetries:Sn,persistentRetryMaxBackoffMs:Yb,persistentRetryResetCapMs:Jb,compressionTargetUsageRatio:Qb,compressionMinBudget:Zb,compressionMaxBudget:ek,reactiveCompactMaxFailures:tk,reactiveCompactMinMessages:nk,reactiveCompactTargetPercent:rk,maxSkillsPerProject:Zo,maxSkillsGlobal:Dl,minToolCallsForSkill:ei,minDistinctToolsForSkill:ti,skillCreationCooldownMs:ni,skillInjectionMaxChars:sk,skillInjectionMaxCount:ok,skillRecallMaxSkills:ri,skillRecallMaxContentChars:si,skillRecallCacheTtlMs:oi,maxForkDepth:ii,maxSessions:ci,taskSummaryTurnThreshold:li,taskSummaryRegenInterval:di,maxIncludeDepth:ui,maxInstructionChars:ik,instructionsMaxFileSize:pi,instructionsMaxDirSize:mi,mediaMaxDownloadSize:gi,mediaMaxUploadSize:ak,mediaDownloadTimeoutMs:fi,acpMaxSpawnRetries:hi,acpRetryBackoffBase:yi,acpRuntimeRestartMax:bi,acpRuntimeRestartBackoffBase:ki,taskPollIntervalMs:ck,taskStoppedDisplayMs:lk,taskPanelGraceMs:dk,memoryPrefetchMaxSessionBytes:vi,memoryPrefetchLimitPerRecall:Si,memoryMaxSurfacedEntries:Ti,dreamMinIntervalHours:uk,dreamMinSessions:pk,dreamScanIntervalMs:mk,idleDreamMinutes:gk,dreamCooldownMs:fk,dreamMaxDurationMs:hk,teamBudgetTokens:ai}}var Uo,Fo,Bo,qr,Ho,qo,Wo,Go,Ko,Vo,Wr,zo,Xo,Yo,Gr,Jo,Qo,Sn,Yb,Jb,Qb,Zb,ek,tk,nk,rk,Zo,Dl,ei,ti,ni,Nl,Ol,sk,ok,ri,si,oi,ii,ai,ci,li,di,Ll,$l,ui,ik,pi,mi,gi,ak,fi,hi,yi,bi,ki,ck,lk,dk,vi,Si,Ti,uk,pk,mk,gk,fk,hk,je=Q(()=>{"use strict";Uo=Math.min(Math.max(1,Number(process.env.TOOL_LOOP_DEFAULT_BUDGET)||25),100),Fo=3,Bo=2,qr=2,Ho=128e3,qo=13e3,Wo=16384,Go=65536,Ko=3,Vo=65536,Wr=500,zo=3,Xo=5e4,Yo=2e5,Gr=2e3,Jo=3e4,Qo=3,Sn=2,Yb=3e5,Jb=216e5,Qb=.75,Zb=16e3,ek=12e4,tk=3,nk=4,rk=50,Zo=20,Dl=50,ei=3,ti=2,ni=300*1e3,Nl=3,Ol=720*60*60*1e3,sk=4e3,ok=5,ri=3,si=800,oi=300*1e3,ii=4,ai=0,ci=50,li=50,di=30,Ll=3600*1e3,$l=200,ui=5,ik=4e4,pi=50*1024,mi=500*1024,gi=500*1024*1024,ak=50*1024*1024,fi=3e5,hi=2,yi=3e3,bi=3,ki=5e3,ck=1e3,lk=3e3,dk=3e4,vi=60*1024,Si=10,Ti=100,uk=24,pk=5,mk=6e5,gk=30,fk=144e5,hk=3e5});import{existsSync as wi,readFileSync as Ul,writeFileSync as yk,readdirSync as Fl,mkdirSync as bk}from"node:fs";import{join as Ai,dirname as kk}from"node:path";function Hl(n){return Ai(n,".qlogicagent",vk)}function Sk(n){let e=Hl(n);try{return JSON.parse(Ul(e,"utf8"))}catch{return{version:1,patterns:{}}}}function jl(n,e){let t=Hl(n);bk(kk(t),{recursive:!0}),yk(t,JSON.stringify(e,null,2),"utf8")}function Tk(n){let e=Date.now()-Ol;for(let[t,r]of Object.entries(n.patterns))new Date(r.lastSeen).getTime()<e&&delete n.patterns[t]}function ql(n,e){if(e.length===0)return!1;let t=Kr(e),r=Sk(n);Tk(r);let s=new Date().toISOString(),o=r.patterns[t];if(o||(o={signature:t,count:0,firstSeen:s,lastSeen:s,promoted:!1},r.patterns[t]=o),o.promoted)return jl(n,r),!1;o.count++,o.lastSeen=s;let i=o.count>=Nl;return i&&(o.promoted=!0),jl(n,r),i}function Kr(n){return[...n].sort().join("+")}function Rk(n,e){if(!wi(e))return null;let t=Kr(n);try{let r=Fl(e,{withFileTypes:!0});for(let s of r){if(!s.isDirectory())continue;let o=Ai(e,s.name,"SKILL.md");try{let a=Ul(o,"utf8").match(/^tools:\s*\n((?:\s+-\s+\S+\n?)+)/m);if(a){let c=a[1].split(`
|
|
15
15
|
`).map(l=>l.replace(/^\s*-\s*/,"").trim()).filter(Boolean);if(Kr(c)===t)return s.name}}catch{}}}catch{}return null}function wk(n){if(!wi(n))return 0;try{return Fl(n,{withFileTypes:!0}).filter(e=>e.isDirectory()&&wi(Ai(n,e.name,"SKILL.md"))).length}catch{return 0}}function Ak(n,e){return!(!n.ok||n.existingSkillName||!n.multiStep||n.toolCallCount<ei||n.distinctToolCount<ti||Date.now()-Bl<ni||e?.projectSkillsDir&&(wk(e.projectSkillsDir)>=Zo||e.tools.length>0&&Rk(e.tools,e.projectSkillsDir))||e?.projectRoot&&e.tools.length>0&&!ql(e.projectRoot,e.tools))}function xk(n){return n.existingSkillName?n.feedback==="negative":!1}function Vr(n,e){return xk(n)?{type:"skill.improve",skillName:n.existingSkillName,reason:"negative user feedback on existing skill execution"}:Ak(n,e)?(Bl=Date.now(),{type:"skill.create",suggestedName:e.suggestedName??`auto-skill-${e.tools.slice(0,3).join("-")}`,description:`Multi-step orchestration using ${e.tools.join(", ")}`,tools:e.tools,stepCount:n.toolCallCount}):null}var Bl,vk,Wl=Q(()=>{"use strict";je();Bl=0,vk="skill-patterns.json"});function Gl(n){return n.function&&typeof n.function=="object"&&typeof n.function.name=="string"?n.function.name.trim():typeof n.name=="string"?n.name.trim():""}function Pk(n){return n==="enabled-eligible"||n==="installed-awaiting-approval"}function Ik(n){return new Map((n??[]).map(e=>[e.toolName,e]))}function _k(n){if(!n.eligibility?.length)return[...n.tools];let e=Ik(n.eligibility);return n.tools.filter(t=>{let r=Gl(t);if(!r)return!1;let s=e.get(r);return!s||Pk(s.status)})}function Ck(n){let e=[],t=n.compatibility??{},r=n.toolChoice;if(n.thinkingEnabled&&t.requireAutoWhenThinking){let s=typeof r=="object"&&r&&!Array.isArray(r)?String(r.type??""):r;s&&s!=="auto"&&s!=="none"&&(e.push("tool_choice downgraded to auto because thinking mode requires auto/none compatibility."),r="auto")}if(r==="required"&&t.allowRequiredToolChoice===!1){let s=t.requiredFallback??"auto";e.push(`tool_choice=required is not supported by this provider; downgraded to ${s}.`),r=s}if(r&&typeof r=="object"&&!Array.isArray(r)&&r.type==="function"&&t.allowNamedToolChoice===!1){let s=t.namedFallback??"required";e.push(`named tool_choice is not supported by this provider; downgraded to ${s}.`),r=s}return{normalizedToolChoice:r,warnings:e}}function xi(n){let e=Ck({toolChoice:n.toolChoice,thinkingEnabled:n.thinkingEnabled,compatibility:n.compatibility}),t=e.normalizedToolChoice,r=[...e.warnings],s=_k({tools:n.tools,eligibility:n.eligibility});if(!t||t==="auto")return{tools:s,normalizedToolChoice:t,warnings:r};if(t==="none")return{tools:[],normalizedToolChoice:"none",warnings:r};if(t==="required"){if(s.length===0)throw new Error("tool_choice=required but no tools were provided");return{tools:s,normalizedToolChoice:"required",extraSystemPrompt:"You must call one of the available tools before responding.",warnings:r}}if(typeof t=="object"&&!Array.isArray(t)&&t.type==="function"){let o=t.function??void 0,i=typeof o?.name=="string"?o.name.trim():"";if(!i)throw new Error("tool_choice.function.name is required");let a=s.filter(c=>Gl(c)===i);if(a.length===0)throw new Error(`tool_choice requested unknown tool: ${i}`);return{tools:a,normalizedToolChoice:{type:"function",function:{name:i}},extraSystemPrompt:`You must call the ${i} tool before responding.`,warnings:r}}return{tools:s,normalizedToolChoice:t,warnings:r}}var Kl=Q(()=>{"use strict"});function Vl(n){return n==null?[]:typeof n=="string"?n.length>0?[{type:"text",text:n}]:[]:Array.isArray(n)?n:[{type:"text",text:String(n)}]}function Dk(n,e){return{...n,content:[...Vl(n.content),...Vl(e.content)]}}function Nk(n){if(!n||typeof n!="object")return!1;if(n.function&&typeof n.function=="object"){let e=n.function.name;if(typeof e=="string"&&e.length>0)return!0}return typeof n.name=="string"&&n.name.length>0}function Ok(n){return new Set((n??Ek).map(e=>e.trim().toLowerCase()))}function Lk(n,e){return n?Ok(e).has(n.trim().toLowerCase()):!1}function Pi(n){if(!Array.isArray(n)||n.length===0)return[...n];let e=n.map(a=>{if(a.role==="assistant"&&Array.isArray(a.tool_calls)){let c=a.tool_calls.filter(l=>Nk(l));return{...a,...c.length>0?{tool_calls:c}:{tool_calls:void 0}}}return{...a}}),t=new Set;for(let a of e)if(!(a.role!=="assistant"||!Array.isArray(a.tool_calls)))for(let c of a.tool_calls)typeof c.id=="string"&&c.id&&t.add(c.id);let r=e.filter(a=>a.role!=="tool"?!0:!!(a.tool_call_id&&t.has(a.tool_call_id))),s=new Set;for(let a of r)a.role==="tool"&&typeof a.tool_call_id=="string"&&a.tool_call_id&&s.add(a.tool_call_id);let o=[];for(let a of r){if(a.role==="assistant"&&Array.isArray(a.tool_calls)&&a.tool_calls.length>0){let c=a.tool_calls.filter(l=>typeof l.id=="string"&&s.has(l.id));if(c.length===0){let{tool_calls:l,...u}=a;u.content!=null&&u.content!==""&&o.push(u);continue}if(c.length<a.tool_calls.length){o.push({...a,tool_calls:c});continue}}o.push(a)}let i=[];for(let a of o){let c=i.length>0?i[i.length-1]:void 0;if(a.role==="user"&&c?.role==="user"){i[i.length-1]=Dk(c,a);continue}i.push(a)}return i}function Ii(n,e){return Lk(e?.stopReason,e?.forcedStopReasons)?n.map(t=>{if(t.role!=="assistant")return{...t};let r={...t};for(let s of Mk)delete r[s];return r}):[...n]}function _i(n,e){let t=e?.placeholderToolResult??"Error: Tool loop interrupted before the tool result was replayed.",r=new Set;for(let o of n)o.role==="tool"&&typeof o.tool_call_id=="string"&&o.tool_call_id&&r.add(o.tool_call_id);let s=[];for(let o of n)if(s.push({...o}),!(o.role!=="assistant"||!Array.isArray(o.tool_calls)||o.tool_calls.length===0))for(let i of o.tool_calls)typeof i.id!="string"||!i.id||r.has(i.id)||(r.add(i.id),s.push({role:"tool",tool_call_id:i.id,content:t}));return s}function Ci(n,e){let t=Pi(n),r=Ii(t,e);return _i(r,e)}var Ek,Mk,Ei=Q(()=>{"use strict";Ek=["stop","aborted","timeout","cancelled","interrupted","error"],Mk=["tool_calls","toolCalls","function_call","functionCall","raw_tool_calls","rawToolCalls"]});function $k(n){let e=new Set,t=new Set;for(let r of n){if(r.role==="assistant"&&Array.isArray(r.tool_calls))for(let s of r.tool_calls)typeof s.id=="string"&&s.id&&e.add(s.id);r.role==="tool"&&typeof r.tool_call_id=="string"&&r.tool_call_id&&t.add(r.tool_call_id)}return[...e].filter(r=>!t.has(r))}function jk(n){let e=new Set;for(let t of n)t.role==="tool"&&typeof t.tool_call_id=="string"&&t.tool_call_id&&e.add(t.tool_call_id);return[...e]}function Uk(n){return{round:n.round??0,maxRounds:n.maxRounds,pendingToolCallIds:[...n.pendingToolCallIds??[]],completedToolCallIds:[...n.completedToolCallIds??[]],lastStopReason:n.lastStopReason,replayMessages:[...n.replayMessages??[]]}}function Mi(n,e){return{round:n.round+1,maxRounds:n.maxRounds,pendingToolCallIds:[...e.pendingToolCallIds??n.pendingToolCallIds],completedToolCallIds:[...e.completedToolCallIds??n.completedToolCallIds],lastStopReason:e.lastStopReason??n.lastStopReason,replayMessages:[...e.replayMessages??n.replayMessages]}}function zr(n,e){return{round:n.round,maxRounds:n.maxRounds,pendingToolCallIds:[],completedToolCallIds:[...e.completedToolCallIds??n.completedToolCallIds],lastStopReason:e.lastStopReason??n.lastStopReason,replayMessages:[...e.replayMessages??n.replayMessages]}}function Xr(n){let e=[],t=Pi(n.replayMessages);t.length!==n.replayMessages.length&&e.push({kind:"drop-orphan-tool-result",detail:"Removed orphan tool results or invalid assistant tool calls."});let r=Ii(t,n.options);r.some((o,i)=>o!==t[i])&&e.push({kind:"strip-forced-stop-tool-metadata",detail:"Removed assistant tool-call metadata after forced stop."});let s=_i(r,n.options);return s.length>r.length&&e.push({kind:"inject-placeholder-tool-result",detail:"Injected placeholder tool result for pending tool calls."}),{state:Uk({maxRounds:n.maxRounds,round:n.round,lastStopReason:n.lastStopReason,replayMessages:s,pendingToolCallIds:$k(s),completedToolCallIds:jk(s)}),recoveryActions:e}}var zl=Q(()=>{"use strict";Ei()});function Di(n){return n?Fk.has(n):!0}function Ni(n){return n===429||n===529}function Yr(n,e=500,t=32e3){let r=Math.min(e*Math.pow(2,n-1),t);return r+Math.floor(Math.random()*r*.25)}function Jr(){let n=process.env.QLOGICAGENT_PERSISTENT_RETRY;return n==="1"||n==="true"}var Fk,X_,Xn,Xl=Q(()=>{"use strict";Fk=new Set(["main","sdk","agent","compact","hook","verification","side_question"]);X_={maxBackoffMs:300*1e3,resetCapMs:360*60*1e3,heartbeatIntervalMs:3e4};Xn=class extends Error{constructor(t,r){super(`Model fallback triggered: ${t} -> ${r}`);this.originalModel=t;this.fallbackModel=r;this.name="FallbackTriggeredError"}originalModel;fallbackModel}});function Oi(n,e){if(e.allowedTools&&e.allowedTools.length>0){let t=new Set(e.allowedTools);return n.filter(r=>t.has(r))}if(e.toolAccessMode==="none")return[];if(e.toolAccessMode==="read-only"){let t=new Set(["file_edit","create_file","write_file","replace_string_in_file","multi_replace_string_in_file","create_directory","delete_file","rename_file","move_file","exec","run_in_terminal","run_command","git_commit","git_push","patch"]);return n.filter(r=>!t.has(r))}return e.canFork?[...n]:n.filter(t=>t!=="agent")}var Li=Q(()=>{"use strict";je()});function $i(){return[...Yl]}function Qr(n){return Yl.find(e=>e.name===n)}var Bk,Hk,qk,Wk,Gk,Kk,Yl,ji=Q(()=>{"use strict";Bk={name:"general",label:"General Purpose",description:"A general-purpose sub-agent that can perform any task with full tool access.",maxTurns:200,toolAccessMode:"full",canFork:!1},Hk={name:"explore",label:"Explore",description:"Fast read-only codebase exploration. Search files, read code, analyze structure. Cannot write or execute.",maxTurns:50,toolAccessMode:"read-only",allowedTools:["read_file","search","web_search","web_fetch","think","memory","tool_search"],canFork:!1},qk={name:"plan",label:"Plan",description:"Planning mode. Explore, analyze, and produce a structured plan. Cannot write files or execute commands.",maxTurns:80,toolAccessMode:"read-only",allowedTools:["read_file","search","web_search","web_fetch","think","memory","task","tool_search"],canFork:!1},Wk={name:"code",label:"Code",description:"A coding sub-agent with full tool access for implementation tasks.",maxTurns:200,toolAccessMode:"full",canFork:!0},Gk={name:"research",label:"Research",description:"Web research and information gathering. Searches the web, fetches pages, and synthesizes findings.",maxTurns:30,toolAccessMode:"read-only",allowedTools:["web_search","web_fetch","read_file","search","think","memory"],canFork:!1},Kk={name:"verify",label:"Verify",description:"Verification agent. Runs tests, checks build output, validates changes are correct.",maxTurns:40,toolAccessMode:"full",allowedTools:["exec","read_file","search","think"],canFork:!1},Yl=[Bk,Hk,qk,Wk,Gk,Kk]});var Jl=Q(()=>{"use strict"});function Ui(n){return{promptTokens:0,hasAttemptedReactiveCompact:!1,currentMaxOutputTokens:n.maxOutputTokens,consecutiveTruncations:0,aborted:n.abortSignal?.aborted??!1}}function Fi(n,e){if(n.aborted)return{level:"blocking",usagePercent:100,reason:"budget_exhausted"};let t=e.contextWindowTokens-e.responseBufferTokens-n.currentMaxOutputTokens,r=t>0?n.promptTokens/t*100:100;return n.promptTokens>=t?n.hasAttemptedReactiveCompact||!e.reactiveCompactEnabled?{level:"blocking",usagePercent:r,reason:"prompt_too_long"}:{level:"blocking",usagePercent:r,reason:"prompt_too_long"}:r>=85?{level:"warning",usagePercent:r,remainingTokens:t-n.promptTokens}:{level:"ok"}}function Bi(n,e,t){let r=n.message?.toLowerCase()??"",s=n.status??0;return s===413||r.includes("prompt_too_long")||r.includes("context_length_exceeded")?!e.hasAttemptedReactiveCompact&&t.reactiveCompactEnabled?{action:"reactive_compact"}:{action:"abort",reason:"prompt_too_long_unrecoverable"}:s>=500&&s<600?{action:"retry",reason:`server_error_${s}`}:s===429?{action:"retry",reason:"rate_limited"}:s===401||s===403?{action:"abort",reason:"auth_error"}:s===404?{action:"abort",reason:"model_not_found"}:{action:"abort",reason:r||"unknown_error"}}function Hi(n,e,t){if(!e.outputEscalationEnabled)return{shouldEscalate:!1,newMax:n.currentMaxOutputTokens};if(n.consecutiveTruncations>=3)return{shouldEscalate:!1,newMax:n.currentMaxOutputTokens};let r=Math.min(n.currentMaxOutputTokens*2,t);return r<=n.currentMaxOutputTokens?{shouldEscalate:!1,newMax:n.currentMaxOutputTokens}:{shouldEscalate:!0,newMax:r}}function qi(n,e){return n.aborted?!0:e.abortSignal?.aborted?(n.aborted=!0,!0):!1}var Ql=Q(()=>{"use strict"});function Wi(){return{consecutiveFailures:0,attemptedThisTurn:!1,lastCompactAt:null,toolsAtLastCompact:[]}}function Tn(n,e=Vk){return!(n.attemptedThisTurn||n.consecutiveFailures>=e.maxConsecutiveFailures)}var Vk,Zl=Q(()=>{"use strict";Vk={maxConsecutiveFailures:3,minMessagesAfterCompact:4,targetUsagePercent:50}});var Yn=Q(()=>{"use strict";yl();xl();Oo();Oo();Ml();Wl();Kl();Ei();zl();Xl();Li();ji();Jl();Ql();Zl()});import{mkdir as Xk,writeFile as Yk}from"fs/promises";import{join as ed}from"path";import{tmpdir as Jk}from"os";function nd(){return{seenIds:new Set,replacements:new Map}}function rd(n){return ed(Jk(),"qlogicagent-sessions",n,Qk)}async function ev(n){try{await Xk(rd(n),{recursive:!0})}catch{}}function tv(n,e){let t=e.replace(/[^a-zA-Z0-9_-]/g,"_");return ed(rd(n),`${t}.txt`)}function nv(n,e){if(n.length<=e)return{preview:n,hasMore:!1};let r=n.slice(0,e).lastIndexOf(`
|
|
16
16
|
`),s=r>e*.5?r:e;return{preview:n.slice(0,s),hasMore:!0}}function sd(n){return n.includes(td)}async function od(n,e,t){await ev(t);let r=tv(t,e);try{await Yk(r,n,{encoding:"utf-8",flag:"wx"})}catch(i){if(i.code!=="EEXIST")return null}let{preview:s,hasMore:o}=nv(n,Gr);return{filepath:r,originalSize:n.length,preview:s,hasMore:o}}function id(n){let e=`${td}
|
|
17
17
|
`;return e+=`Output too large (${n.originalSize} chars). Full output saved to: ${n.filepath}
|
|
@@ -21,14 +21,14 @@ ${f}`},b=[...s,...d,y,...m],S=Date.now()-r,w=b.reduce((_,I)=>_+this.config.estim
|
|
|
21
21
|
...
|
|
22
22
|
`:`
|
|
23
23
|
`,e+=Zk,e}async function ad(n,e,t,r=Xo){if(n.length<=r||sd(n))return n;let s=await od(n,e,t);return s?id(s):n.slice(0,r)+`
|
|
24
|
-
...[truncated ${n.length-r} chars]`}function rv(n){let e=[],t=[];for(let r of n)r.role==="tool"&&typeof r.content=="string"&&r.tool_call_id?sd(r.content)||t.push({toolCallId:r.tool_call_id,content:r.content,size:r.content.length}):r.role==="assistant"&&t.length>0&&(e.push(t),t=[]);return t.length>0&&e.push(t),e}function sv(n,e){let t=[],r=[],s=[];for(let o of n){let i=e.replacements.get(o.toolCallId);i!==void 0?t.push({...o,replacement:i}):e.seenIds.has(o.toolCallId)?r.push(o):s.push(o)}return{mustReapply:t,frozen:r,fresh:s}}function ov(n,e,t){let r=[...n].sort((i,a)=>a.size-i.size),s=[],o=e+n.reduce((i,a)=>i+a.size,0);for(let i of r){if(o<=t)break;s.push(i),o-=i.size}return s}async function cd(n,e,t,r=Yo){let s=rv(n);if(s.length===0)return{messages:n,newlyReplacedCount:0};let o=new Map,i=[];for(let u of s){let{mustReapply:d,frozen:p,fresh:m}=sv(u,e);for(let S of d)o.set(S.toolCallId,S.replacement);if(m.length===0){for(let S of u)e.seenIds.add(S.toolCallId);continue}let h=p.reduce((S,w)=>S+w.size,0),f=m.reduce((S,w)=>S+w.size,0),y=h+f>r?ov(m,h,r):[],b=new Set(y.map(S=>S.toolCallId));for(let S of u)b.has(S.toolCallId)||e.seenIds.add(S.toolCallId);y.length>0&&i.push(...y)}if(o.size===0&&i.length===0)return{messages:n,newlyReplacedCount:0};let a=await Promise.all(i.map(async u=>{let d=await od(u.content,u.toolCallId,t);return{candidate:u,result:d}})),c=0;for(let{candidate:u,result:d}of a){if(e.seenIds.add(u.toolCallId),!d)continue;let p=id(d);o.set(u.toolCallId,p),e.replacements.set(u.toolCallId,p),c++}return o.size===0?{messages:n,newlyReplacedCount:0}:{messages:n.map(u=>{if(u.role!=="tool"||!u.tool_call_id)return u;let d=o.get(u.tool_call_id);return d===void 0?u:{...u,content:d}}),newlyReplacedCount:c}}var Qk,td,Zk,Gi=Q(()=>{"use strict";je();Qk="tool-results",td="<persisted-output>",Zk="</persisted-output>"});function cv(n){try{return JSON.parse(n)}catch{return}}var iv,av,Zr,ld=Q(()=>{"use strict";Yn();Gi();iv=new Set(["read_file","file_read","FileRead","grep","Grep","glob","Glob","search","list_dir","find_files","web_fetch","web_search","WebFetch","WebSearch"]),av=new Set(["bash","execute_command","Bash","shell"]),Zr=class{tools=[];hasErrored=!1;erroredToolDescription="";discarded=!1;siblingAbortController;progressResolve;config;concurrencySafe;constructor(e){this.config=e,this.concurrencySafe=e.concurrencySafeTools??iv,this.siblingAbortController=new AbortController,e.signal&&e.signal.addEventListener("abort",()=>{this.siblingAbortController.abort("parent_abort")},{once:!0})}discard(){this.discarded=!0}addTool(e){let t=this.concurrencySafe.has(e.function.name);this.tools.push({id:e.id,toolCall:e,status:"queued",isConcurrencySafe:t,results:[],pendingProgress:[]}),this.processQueue()}canExecuteTool(e){let t=this.tools.filter(s=>s.status==="executing"),r=this.config.maxConcurrentTools;return r&&r>0&&t.length>=r?!1:t.length===0||e&&t.every(s=>s.isConcurrencySafe)}async processQueue(){for(let e of this.tools)if(e.status==="queued"){if(this.canExecuteTool(e.isConcurrencySafe))await this.executeTool(e);else if(!e.isConcurrencySafe)break}}getAbortReason(){return this.discarded?"discarded":this.hasErrored?"sibling_error":this.config.signal?.aborted?"user_interrupted":null}getToolDescription(e){let t;try{t=JSON.parse(e.toolCall.function.arguments)}catch{}let r=t?.command??t?.file_path??t?.pattern??"";if(typeof r=="string"&&r.length>0){let s=r.length>40?r.slice(0,40)+"\u2026":r;return`${e.toolCall.function.name}(${s})`}return e.toolCall.function.name}createSyntheticError(e,t){let r=this.erroredToolDescription,s=t==="user_interrupted"?"User rejected tool use":t==="discarded"?"Streaming fallback - tool execution discarded":r?`Cancelled: parallel tool call ${r} errored`:"Cancelled: parallel tool call errored";return{callId:e.id,toolName:e.toolCall.function.name,ok:!1,error:s,message:Gt(e.id,{ok:!1,error:s})}}async executeTool(e){e.status="executing";let r=(async()=>{let s=this.getAbortReason();if(s){e.results.push(this.createSyntheticError(e,s)),e.status="completed";return}let{toolInvoker:o,hooks:i,sessionId:a,turnId:c,log:l}=this.config,u=e.toolCall.function.name,d=!1,p=e.toolCall.function.arguments;if(i)try{let S=await i.invoke("tool.before_invoke",{sessionId:a,turnId:c,callId:e.id,toolName:u,arguments:cv(p)});if(S.action==="abort"){let w=S.reason??"blocked by policy";l.info(`tool ${u} blocked: ${w}`),e.results.push({callId:e.id,toolName:u,ok:!1,error:w,blocked:!0,blockReason:w,message:Gt(e.id,{ok:!1,error:w})}),e.status="completed";return}S.action==="continue"&&S.context?.arguments&&(p=JSON.stringify(S.context.arguments))}catch{}let m=await o.invoke(c,u,p,this.siblingAbortController.signal),h=this.getAbortReason();if(h&&!d){e.results.push(this.createSyntheticError(e,h)),e.status="completed";return}let f=!m.error,y=m.result;f&&y&&y.length>5e4&&(y=await ad(y,e.id,a));let b=Gt(e.id,{ok:f,payload:y,error:m.error,toolReferences:m.toolReferences,imageUrls:m.imageUrls});f||(d=!0,av.has(u)&&(this.hasErrored=!0,this.erroredToolDescription=this.getToolDescription(e),this.siblingAbortController.abort("sibling_error"))),i?.invoke(f?"tool.after_invoke":"tool.invoke_failed",{sessionId:a,turnId:c,callId:e.id,toolName:u,ok:f,...m.error?{error:m.error}:{}}).catch(()=>{}),e.results.push({callId:e.id,toolName:u,ok:f,error:m.error,message:b}),e.status="completed"})();e.promise=r,r.finally(()=>{this.processQueue()})}*getCompletedResults(){if(!this.discarded){for(let e of this.tools)if(e.status!=="yielded"){if(e.status==="completed"&&e.results.length>0){e.status="yielded";for(let t of e.results)yield t}else if(e.status==="executing"&&!e.isConcurrencySafe)break}}}async*getRemainingResults(){if(!this.discarded){for(;this.hasUnfinishedTools();){await this.processQueue();for(let e of this.getCompletedResults())yield e;if(this.hasExecutingTools()&&!this.hasCompletedResults()){let e=this.tools.filter(r=>r.status==="executing"&&r.promise).map(r=>r.promise),t=new Promise(r=>{this.progressResolve=r});e.length>0&&await Promise.race([...e,t])}}for(let e of this.getCompletedResults())yield e}}hasCompletedResults(){return this.tools.some(e=>e.status==="completed")}hasExecutingTools(){return this.tools.some(e=>e.status==="executing")}hasUnfinishedTools(){return this.tools.some(e=>e.status!=="yielded")}}});import{homedir as lv}from"node:os";import{join as xe}from"node:path";import{existsSync as dv}from"node:fs";function q(){return process.env.QLOGICAGENT_HOME||xe(lv(),qe)}function dd(){return xe(q(),"plugins")}function Dt(){return xe(q(),"skills")}function lt(){return xe(q(),"settings.json")}function ud(){return xe(q(),"plugin-cache")}function pd(){return xe(q(),"mcp.json")}function md(){return xe(q(),"marketplace.json")}function gd(){return xe(q(),"workflows")}function fd(){return xe(q(),"rules")}function Me(n){if(!n)throw new Error("getProjectAgentDir: cwd is required (must not fall back to process.cwd())");return xe(n,qe)}function hd(n){return xe(Me(n),"workflows")}function Tt(n){return xe(Me(n),"skills")}function Jn(n){return xe(Me(n),"INSTRUCTIONS.md")}function Rn(n){return xe(Me(n),"rules")}function Nt(n){return xe(Me(n),"sessions")}function yd(n,e){let t=xe(Me(n),"checkpoints");return e?xe(t,e):t}function bd(n){return xe(n,qe,"hooks")}function kd(n,e){return n.filter(t=>t!==e&&dv(xe(t,qe,"skills")))}var qe,ae=Q(()=>{"use strict";qe=".qlogicagent"});var es,vd=Q(()=>{"use strict";es=class{pools=new Map;runtimeStates=new Map;constructor(e){if(e)for(let t of e){this.pools.set(t.providerId,t);for(let r of t.keys)this.runtimeStates.set(r.id,this.createInitialState())}}acquireKey(e){let t=this.pools.get(e);if(!t||t.keys.length===0)return null;let r=Date.now(),s=this.getHealthyCandidates(t,r);if(s.length===0)return null;let o=this.selectByStrategy(s,t.strategy,r);if(!o)return null;let i=this.runtimeStates.get(o.id);return i.inFlight++,i.totalRequests++,i.lastUsedAt=r,i.requestTimestamps.push(r),{keyId:o.id,apiKey:o.key,providerId:e,release:a=>this.releaseKey(o.id,a)}}releaseKey(e,t){let r=this.runtimeStates.get(e);if(r)if(r.inFlight=Math.max(0,r.inFlight-1),t.success)r.consecutiveErrors=0,r.healthStatus="healthy",t.tokens&&(r.totalTokens+=t.tokens,r.tokenCounts.push(t.tokens));else if(r.consecutiveErrors++,r.lastErrorAt=Date.now(),t.errorCode===429){let s=t.retryAfter?t.retryAfter*1e3:3e4;r.cooldownUntil=Date.now()+s,r.healthStatus="cooldown"}else r.consecutiveErrors>=5?(r.cooldownUntil=Date.now()+6e4,r.healthStatus="cooldown"):r.consecutiveErrors>=3&&(r.healthStatus="degraded")}addProvider(e,t){this.pools.has(e)||this.pools.set(e,{providerId:e,baseUrl:t?.baseUrl,strategy:t?.strategy??"weighted-round-robin",keys:[],rateLimit:t?.rateLimit})}removeProvider(e){let t=this.pools.get(e);if(t){for(let r of t.keys)this.runtimeStates.delete(r.id);this.pools.delete(e)}}addKey(e,t,r){let s=this.pools.get(e);s||(s={providerId:e,strategy:"weighted-round-robin",keys:[]},this.pools.set(e,s));let o=r?.id??crypto.randomUUID(),i={id:o,key:t,label:r?.label,weight:r?.weight??1,enabled:r?.enabled??!0};return s.keys.push(i),this.runtimeStates.set(o,this.createInitialState()),o}removeKey(e){for(let t of this.pools.values()){let r=t.keys.findIndex(s=>s.id===e);if(r!==-1){t.keys.splice(r,1),this.runtimeStates.delete(e);return}}}updateKey(e,t){for(let r of this.pools.values()){let s=r.keys.find(o=>o.id===e);if(s){if(t.label!==void 0&&(s.label=t.label),t.weight!==void 0&&(s.weight=t.weight),t.enabled!==void 0){s.enabled=t.enabled;let o=this.runtimeStates.get(e);o&&(o.healthStatus=t.enabled?"healthy":"disabled")}return}}}setKeyHealth(e,t){let r=this.runtimeStates.get(e);r&&(r.healthStatus=t)}setStrategy(e,t){let r=this.pools.get(e);r&&(r.strategy=t)}setRateLimit(e,t){let r=this.pools.get(e);r&&(r.rateLimit=t)}getPoolStatus(e){let t=this.pools.get(e);return t?this.buildPoolStatus(t):null}getAllStatus(){return[...this.pools.values()].map(e=>this.buildPoolStatus(e))}getProviderIds(){return[...this.pools.keys()]}hasProvider(e){return this.pools.has(e)}hasAvailableKey(e){let t=this.pools.get(e);return t?this.getHealthyCandidates(t,Date.now()).length>0:!1}exportConfig(){return[...this.pools.values()]}reloadConfig(e){let t=new Set;for(let r of e){this.pools.set(r.providerId,r);for(let s of r.keys)t.add(s.id),this.runtimeStates.has(s.id)||this.runtimeStates.set(s.id,this.createInitialState())}for(let r of[...this.pools.keys()])e.some(s=>s.providerId===r)||this.pools.delete(r);for(let r of[...this.runtimeStates.keys()])t.has(r)||this.runtimeStates.delete(r)}createInitialState(){return{inFlight:0,totalRequests:0,totalTokens:0,lastUsedAt:0,lastErrorAt:0,consecutiveErrors:0,cooldownUntil:0,healthStatus:"healthy",requestTimestamps:[],tokenCounts:[]}}getHealthyCandidates(e,t){let r=[];for(let s of e.keys){if(!s.enabled)continue;let o=this.runtimeStates.get(s.id);if(o){if(o.healthStatus==="cooldown")if(t>=o.cooldownUntil)o.healthStatus="healthy",o.consecutiveErrors=0;else continue;o.healthStatus!=="disabled"&&(e.rateLimit?.rpm&&(this.pruneWindow(o.requestTimestamps,t),o.requestTimestamps.length>=e.rateLimit.rpm*.9)||e.rateLimit?.tpm&&(this.pruneWindow(o.tokenCounts,t),o.tokenCounts.reduce((a,c)=>a+c,0)>=e.rateLimit.tpm*.9)||r.push(s))}}return r}selectByStrategy(e,t,r){if(e.length===0)return null;if(e.length===1)return e[0];switch(t){case"weighted-round-robin":return this.weightedRandom(e);case"least-busy":return this.leastBusy(e);case"random":return e[Math.floor(Math.random()*e.length)];default:return this.weightedRandom(e)}}weightedRandom(e){let t=e.reduce((s,o)=>s+o.weight,0),r=Math.random()*t;for(let s of e)if(r-=s.weight,r<=0)return s;return e[e.length-1]}leastBusy(e){let t=1/0,r=e[0];for(let s of e){let i=this.runtimeStates.get(s.id)?.inFlight??0;(i<t||i===t&&s.weight>r.weight)&&(t=i,r=s)}return r}pruneWindow(e,t){let r=t-6e4;for(;e.length>0&&e[0]<r;)e.shift()}buildPoolStatus(e){return{providerId:e.providerId,baseUrl:e.baseUrl,strategy:e.strategy,rateLimit:e.rateLimit,keys:e.keys.map(t=>{let r=this.runtimeStates.get(t.id)??this.createInitialState();return{...t,inFlight:r.inFlight,totalRequests:r.totalRequests,totalTokens:r.totalTokens,lastUsedAt:r.lastUsedAt,lastErrorAt:r.lastErrorAt,consecutiveErrors:r.consecutiveErrors,cooldownUntil:r.cooldownUntil,healthStatus:t.enabled?r.healthStatus:"disabled"}})}}}});var Sd={};Zt(Sd,{ALL_PURPOSES:()=>Zn,ModelRegistry:()=>ts,deriveModelPurposes:()=>gv,getModelRegistry:()=>X,resetModelRegistry:()=>mv});import*as Ze from"node:fs";import{ProviderRegistry as uv,ProviderVariantResolver as pv}from"@xiaozhiclaw/provider-core";function X(){return Qn||(Qn=new ts,Qn.load()),Qn}function mv(){Qn=null}function gv(n){let e=[];switch((!n.mediaType||n.mediaType==="image_understanding"||n.mediaType==="video_understanding")&&e.push("textGeneration"),(n.vision||n.mediaType==="image_understanding")&&e.push("imageUnderstanding"),n.mediaType==="video_understanding"&&e.push("videoUnderstanding"),n.mediaType){case"image":e.push("imageGeneration");break;case"video":e.push("videoGeneration");break;case"tts":e.push("tts");break;case"stt":e.push("stt");break;case"music":case"music_realtime":e.push("musicGeneration");break;case"voice_clone":e.push("voiceClone");break;case"embedding":e.push("embedding");break;case"3d":e.push("threeDGeneration");break;case"realtime_audio":e.push("realtimeAudio");break}return e.includes("textGeneration")&&e.push("smallModel"),[...new Set(e.length>0?e:["textGeneration"])]}function fv(n){switch(n){case"openai-chat":case"openai-responses":case"anthropic-messages":case"volcengine-responses":return n;default:return}}function hv(n,e){switch(n){case"imageUnderstanding":case"videoUnderstanding":case"imageGeneration":case"videoGeneration":case"threeDGeneration":case"stt":case"tts":case"voiceClone":case"musicGeneration":case"realtimeAudio":case"realtimeVideo":case"embedding":return;default:return fv(e)}}function yv(n){switch(n){case"imageUnderstanding":case"videoUnderstanding":return["vision"];case"imageGeneration":case"videoGeneration":case"threeDGeneration":case"stt":case"tts":case"voiceClone":case"musicGeneration":case"realtimeAudio":case"realtimeVideo":case"embedding":return["media"];default:return[]}}var Zn,ts,Qn,dt=Q(()=>{"use strict";ae();vd();Zn=["textGeneration","smallModel","stt","tts","imageGeneration","imageUnderstanding","videoGeneration","videoUnderstanding","threeDGeneration","embedding","voiceClone","musicGeneration","realtimeAudio","realtimeVideo"],ts=class{keyPool;coreProviderRegistry=new uv;providerVariantResolver=new pv(this.coreProviderRegistry);models=new Map;modelEnabledOverrides=new Map;bindings={};settingsPath;changeListeners=[];constructor(e){this.settingsPath=lt(),this.keyPool=new es(e?.providers),e?.models&&this.loadModelState(e.models),e?.bindings&&(this.bindings={...e.bindings})}getActiveModel(e){let t=this.bindings[e];if(!t)return null;let r=this.models.get(t);if(!r||!r.enabled)return null;let s=this.resolveTechnicalVariant(r,e),o=s?.provider??r.provider,i=s?.nativeModelId??r.nativeModelId??r.model,a=this.acquireKeyForProviderVariant(o);if(!a)return null;let{keyHandle:c,keyProviderId:l}=a,u=this.getProviderBaseUrl(o),d=this.getProviderBaseUrl(l);return{provider:o,model:i,apiKey:c.apiKey,baseUrl:u??(r.provider===o?r.baseUrl:void 0)??d,keyHandle:c}}peekActiveModel(e){let t=this.bindings[e];return t?this.models.get(t)??null:null}isAvailable(e){let t=this.peekActiveModel(e);return!!t?.enabled&&this.hasAvailableKeyForProviderVariant(t.provider)}resolveModelForPurpose(e){let t=this.peekActiveModel(e);return t?t.model:null}addProvider(e,t){this.keyPool.addProvider(e,t),this.emitChange()}removeProvider(e){this.keyPool.removeProvider(e);for(let[t,r]of this.models)r.provider===e&&this.removeModel(t);this.emitChange()}addKey(e,t,r){let s=this.keyPool.addKey(e,t,r);return this.emitChange(),s}removeKey(e){this.keyPool.removeKey(e),this.emitChange()}updateKey(e,t){this.keyPool.updateKey(e,t),this.emitChange()}setKeyHealth(e,t){this.keyPool.setKeyHealth(e,t),this.emitChange()}setStrategy(e,t){this.keyPool.setStrategy(e,t),this.emitChange()}addModel(e){let t=e.id??`${e.provider}:${e.model}`;return this.models.set(t,{...e,id:t,enabled:this.modelEnabledOverrides.get(t)??e.enabled}),this.emitChange(),t}replaceCatalogModels(e){let t=new Map;for(let r of e)t.set(r.id,{...r,enabled:this.modelEnabledOverrides.get(r.id)??r.enabled});for(let r of this.modelEnabledOverrides.keys())t.has(r)||this.modelEnabledOverrides.delete(r);this.models=t;for(let[r,s]of Object.entries(this.bindings))s&&!this.models.has(s)&&delete this.bindings[r];this.emitChange()}migrateModelIds(e){for(let[t,r]of e){let s=this.modelEnabledOverrides.get(t);s!==void 0&&!this.modelEnabledOverrides.has(r)&&this.modelEnabledOverrides.set(r,s),this.modelEnabledOverrides.delete(t);for(let[o,i]of Object.entries(this.bindings))i===t&&(this.bindings[o]=r)}this.emitChange()}removeModel(e){this.models.delete(e),this.modelEnabledOverrides.delete(e);for(let[t,r]of Object.entries(this.bindings))r===e&&delete this.bindings[t];this.emitChange()}enableModel(e){let t=this.models.get(e);t&&(t.enabled=!0),this.modelEnabledOverrides.set(e,!0),this.emitChange()}disableModel(e){let t=this.models.get(e);t&&(t.enabled=!1),this.modelEnabledOverrides.set(e,!1),this.emitChange()}listModels(e){let t=[...this.models.values()];return e?.purpose&&(t=t.filter(r=>r.purposes.includes(e.purpose))),e?.provider&&(t=t.filter(r=>r.provider===e.provider)),e?.enabledOnly&&(t=t.filter(r=>r.enabled)),t}getModel(e){return this.models.get(e)??null}setBinding(e,t){let r=this.models.get(t);if(!r)throw new Error(`Model "${t}" not found in pool.`);if(!r.purposes.includes(e))throw new Error(`Model "${t}" does not support purpose "${e}".`);this.bindings[e]=t,this.emitChange()}removeBinding(e){delete this.bindings[e],this.emitChange()}getBinding(e){let t=this.bindings[e];return t?this.models.get(t)??null:null}getAllBindings(){let e={};for(let t of Zn){let r=this.bindings[t];e[t]=r?this.models.get(r)??null:null}return e}getProviderStatus(e){return this.keyPool.getPoolStatus(e)}getAllProviderStatus(){return this.keyPool.getAllStatus()}save(){let e={};try{Ze.existsSync(this.settingsPath)&&(e=JSON.parse(Ze.readFileSync(this.settingsPath,"utf-8")))}catch{e={}}delete e.provider,delete e.apiKey,delete e.model,delete e.baseUrl;let t={...e,providers:this.keyPool.exportConfig(),models:this.exportModelState(),bindings:{...this.bindings}},r=this.settingsPath.replace(/[/\\][^/\\]+$/,"");Ze.existsSync(r)||Ze.mkdirSync(r,{recursive:!0}),Ze.writeFileSync(this.settingsPath,JSON.stringify(t,null,2),"utf-8")}load(){try{if(!Ze.existsSync(this.settingsPath))return!1;let e=Ze.readFileSync(this.settingsPath,"utf-8"),t=JSON.parse(e);return t.providers&&this.keyPool.reloadConfig(t.providers),this.models.clear(),this.modelEnabledOverrides.clear(),t.models&&this.loadModelState(t.models),this.bindings=t.bindings??{},this.emitChange(),!0}catch{return!1}}exportConfig(){return{providers:this.keyPool.exportConfig(),models:this.exportModelState(),bindings:{...this.bindings}}}getTunable(e){try{if(!Ze.existsSync(this.settingsPath))return;let t=Ze.readFileSync(this.settingsPath,"utf-8");return JSON.parse(t).tunables?.[e]}catch{return}}getModelInfo(e,t){let r=this.listModels({provider:e}).find(s=>s.model===t);if(r)return{id:r.model,name:r.displayName,contextWindow:r.contextWindow,maxOutput:r.maxOutput,streamRequired:r.streamRequired}}getProviderDefaultModel(e){return this.listModels({provider:e,enabledOnly:!0})[0]?.model??this.listModels({provider:e})[0]?.model}hasConfiguredKeyForProviderVariant(e){return this.providerVariantKeyCandidates(e).some(t=>!!this.keyPool.getPoolStatus(t)?.keys.some(s=>s.enabled))}hasAvailableKeyForProviderVariant(e){return this.providerVariantKeyCandidates(e).some(t=>this.keyPool.hasAvailableKey(t))}listProviderDefs(){return this.keyPool.getAllStatus().map(e=>({id:e.providerId,name:e.providerId,transport:"",baseUrl:e.baseUrl??"",defaultModel:this.getProviderDefaultModel(e.providerId),models:this.listModels({provider:e.providerId}).map(t=>({id:t.model,name:t.displayName,contextWindow:t.contextWindow,maxOutput:t.maxOutput,streamRequired:t.streamRequired}))}))}resolveProviderApiKey(e){return this.getKeyForProvider(e)??void 0}onChange(e){return this.changeListeners.push(e),()=>{let t=this.changeListeners.indexOf(e);t>=0&&this.changeListeners.splice(t,1)}}getKeyForProvider(e){let r=this.acquireKeyForProviderVariant(e)?.keyHandle;if(!r)return null;let s=r.apiKey;return r.release({success:!0}),s}snapshotProviderKeys(){let e={};for(let t of this.keyPool.getAllStatus()){let r=this.getKeyForProvider(t.providerId);r&&(e[t.providerId]=r)}return e}getProviderBaseUrl(e){return this.coreProviderRegistry.getProvider(e)?.baseUrl??this.keyPool.getPoolStatus(e)?.baseUrl}acquireKeyForProviderVariant(e){for(let t of this.providerVariantKeyCandidates(e)){let r=this.keyPool.acquireKey(t);if(r)return{keyHandle:r,keyProviderId:t}}return null}resolveTechnicalVariant(e,t){let r=this.providerVariantKeyCandidates(e.provider).filter(o=>this.hasConfiguredKeyForProviderVariant(o));if(r.length===0)return;let s=this.providerVariantResolver.resolveBest({publicModel:e.model,requestedProtocol:hv(t,e.transport),capabilities:yv(t),purpose:t,userPreference:{providerIds:r}});if(s)return{provider:s.provider,nativeModelId:s.nativeModelId}}providerVariantKeyCandidates(e){let t=[e],r=this.coreProviderRegistry.getProvider(e),s=r?.group??r?.id??e;for(let o of this.coreProviderRegistry.listProviders())(o.group??o.id)===s&&t.push(o.id);return s!==e&&t.push(s),[...new Set(t)]}loadModelState(e){for(let t of e)typeof t.id!="string"||!t.id||typeof t.enabled=="boolean"&&this.modelEnabledOverrides.set(t.id,t.enabled)}exportModelState(){let e=new Map;for(let[t,r]of this.modelEnabledOverrides)e.set(t,r);for(let t of this.models.values())e.set(t.id,t.enabled);return[...e.entries()].map(([t,r])=>({id:t,enabled:r}))}emitChange(){for(let e of this.changeListeners)try{e()}catch{}}},Qn=null});import{readFile as bv}from"node:fs/promises";function sn(n){let e=typeof n.content=="string"?n.content:n.content!=null?JSON.stringify(n.content):"";return Math.ceil(e.length/4)}function on(n){let e=0;for(let t of n)e+=sn(t);return e}function Rd(n){if(!n)return 128e3;if(n in Ki)return Ki[n];let e=n.toLowerCase();for(let[t,r]of Object.entries(Ki))if(e.startsWith(t.toLowerCase()))return r;return 128e3}function vv(){return X().resolveModelForPurpose("textGeneration")??kv}function Ad(){return zi}function Sv(n,e){return async(t,r)=>{let s=e?.transport,o=e?.apiKey;if(!s||!o)return n.debug("[context-compression] no LLM transport for summarization \u2014 using sync fallback"),Vi(t);try{let i="",a=e?.model??vv();for await(let c of s.stream({model:a,messages:[{role:"system",content:"You are a precise conversation summarizer."},{role:"user",content:r}],maxTokens:2e3,temperature:.3},o,AbortSignal.timeout(3e4)))c.type==="delta"&&(i+=c.text);return i||(n.warn("[context-compression] empty summary response"),Vi(t))}catch(i){return n.warn({err:i.message},"[context-compression] summarize call error \u2014 using fallback"),Vi(t)}}}function Vi(n){let e=[],t=n.filter(o=>o.role==="user"),r=t.slice(0,20).map(o=>{let i=typeof o.content=="string"?o.content:JSON.stringify(o.content??"");return`- [user]: ${i.slice(0,300)}${i.length>300?"...":""}`});e.push(`## User Requests (${t.length} messages)`),e.push(...r);let s=n.filter(o=>o.role==="assistant");if(s.length>0){let o=s.slice(0,10).map(i=>{let a=typeof i.content=="string"?i.content:JSON.stringify(i.content??"");return`- [assistant]: ${a.slice(0,150)}${a.length>150?"...":""}`});e.push("",`## Assistant Responses (${s.length} total)`),e.push(...o)}return e.join(`
|
|
25
|
-
`)}function Tv(){return Co(new rn(Xi),new Kt(20,sn),new vn(sn))}function Td(n,e){let t=Eo(new rn(Xi),new Kt(20,sn),new qn({protectedHeadExchanges:1,protectedTailMessages:8,summarize:n,estimateTokens:sn}),new vn(sn));return new Wn({inner:t,estimateTokens:sn,onCacheInvalidated:e?.onCacheInvalidated})}function xd(n,e){let t=e?.budget??Hr({modelContextWindow:Rd(e?.model)}),s=(e?.pipeline??Tv()).compress(n,t);if(s.droppedCount>0){let o=on(n),i=on(s.messages);wd.record({timestamp:Date.now(),strategy:s.strategy,tokensBefore:o,tokensAfter:i,droppedCount:s.droppedCount,latencyMs:s.metrics?.latencyMs??0,usedLlm:!1,cacheInvalidated:s.metrics?.cacheInvalidated??!1,tier:zn(o,t)})}return s.droppedCount>0&&Yi?.(s.droppedCount,on(s.messages)),s}async function Rv(n,e,t){let r=t??Hr({modelContextWindow:Rd(e.model)}),s=on(n),o=zn(s,r),i;switch(o){case"none":i={messages:n,droppedCount:0,strategy:"none"};break;case"trim-only":i=new rn(Xi).compress(n,r);break;case"sliding-window":{i=await Td(e.summarize).compressAsync(n,r);break}case"llm-summarize":{let a=e.pipeline??Td(e.summarize);i=Vn(a)?await a.compressAsync(n,r):a.compress(n,r);break}}return i.droppedCount>0&&(i={...i,messages:await Do(i.messages,n,{maxFiles:5,maxTokenBudget:5e4,readFile:async a=>{try{return await bv(a,"utf-8")}catch{return null}}})}),wv(n,i,r),i}function wv(n,e,t){if(e.droppedCount>0||e.metrics?.usedLlm){let r=e.metrics?.tokensBefore||on(n),s=e.metrics?.tokensAfter||on(e.messages);wd.record({timestamp:Date.now(),strategy:e.strategy,tokensBefore:r,tokensAfter:s,droppedCount:e.droppedCount,latencyMs:e.metrics?.latencyMs??0,usedLlm:e.metrics?.usedLlm??!1,cacheInvalidated:e.metrics?.cacheInvalidated??!1,tier:zn(r,t)})}if(e.droppedCount>0){let r=e.metrics?.tokensAfter||on(e.messages);Yi?.(e.droppedCount,r)}}function Av(n,e){let t=Sv(n,e),r={id:"builtin-compressor",label:"4-Layer Compression Funnel (built-in)",async compressAsync(s,o,i){return Rv(s,{budget:o,model:i?.model,sessionId:i?.sessionId,summarize:t},o)}};zi.register(r),zi.activate(r.id),n.info(`[context-compression] registered context engine: ${r.id}`)}function Pd(n,e,t){Av(e,t),n.register({point:"context.before_compact",priority:50,label:"context-compression-bridge",handler:(r,s)=>{let o=s.messageCount;return o&&o>0&&e.debug(`[context-compression] before_compact: ${o} messages entering compression`),{action:"continue"}}}),Yi=(r,s)=>{e.debug(`[context-compression] after_compact: removed ${r}, ${s} tokens remaining`),n.invoke("context.after_compact",{sessionId:"",turnId:"",removedCount:r,tokenCount:s}).catch(()=>{})}}var Ki,Xi,kv,wd,zi,Yi,Ji=Q(()=>{"use strict";Yn();dt();Ki={"deepseek-v4-flash":1e6,"deepseek-v4-pro":1e6,"deepseek-chat":1e6,"deepseek-reasoner":1e6,"gpt-4o":128e3,"gpt-4o-mini":128e3,"claude-sonnet-4-20250514":2e5,"claude-3-5-haiku-20241022":2e5,"gemini-3.1-pro-preview":1e6,"gemini-3-flash-preview":1e6,"gemini-3.1-flash-lite":1e6};Xi=8e3,kv="deepseek-v4-flash";wd=new Gn(200),zi=new Kn;Yi=null});function Id(n,e,t){let r=t-e;return`[Budget] ${Math.round(n)}% used (${e.toLocaleString()} / ${t.toLocaleString()} tokens). ${r.toLocaleString()} tokens remaining. `+(n>=90?"Wrap up your current taskyou are near the token limit.":"Continue workingdo not summarize prematurely.")}var _d=Q(()=>{"use strict"});var Cd={};Zt(Cd,{resolveToolEligibility:()=>Cv});function Pv(n,e){if(xv.some(t=>t.test(n)))return!0;if(e)for(let t of e)try{if(new RegExp(t,"i").test(n))return!0}catch{}return!1}function Iv(n,e){let t=n.function.name,r=n.meta,s=[];return e.blockedToolNames?.includes(t)?(s.push("policy_blocked"),{level:5,reasons:s}):r?.isReadOnly?(s.push("always_allowed"),{level:1,reasons:s}):r?.requiresApproval?(s.push("approval_required"),{level:4,reasons:s}):r?.isDangerous||Pv(t,e.dangerousPatterns)?(s.push("dangerous_tool"),{level:3,reasons:s}):{level:2,reasons:s}}function _v(n){switch(n){case 1:return"eligible";case 2:return"eligible";case 3:return"dangerous-notify";case 4:return"approval-required";case 5:return"blocked-by-policy"}}function Cv(n,e={}){let t=new Map,r=[],s=[],o=[];for(let i of n){let a=i.function.name,{level:c,reasons:l}=Iv(i,e),u=_v(c),d={toolName:a,status:u,permissionLevel:c,approvalRequired:c===4,reasonCodes:l};t.set(a,d),c===5?s.push(d):(r.push(i),c===4&&o.push(d))}return{eligibleTools:r,blockedTools:s,approvalRequiredTools:o,eligibilityByName:t}}var xv,Ed=Q(()=>{"use strict";xv=[/^(?:bash|shell|exec|terminal|run_command)$/i,/^(?:write_file|delete_file|move_file|create_directory)$/i,/^(?:git_push|git_reset|git_force)$/i]});import{accumulateToolCalls as Dv}from"@xiaozhiclaw/provider-core";function Ov(n){let e=n.split(".").pop()?.toLowerCase()??"";return["png","jpg","jpeg","gif","webp","svg","bmp","ico"].includes(e)?"image":["md","txt","pdf","doc","docx","rtf","html"].includes(e)?"document":["mermaid","mmd","dot","puml","plantuml"].includes(e)?"diagram":["csv","tsv","xlsx","xls"].includes(e)?"table":["ts","tsx","js","jsx","py","rs","go","java","c","cpp","h","cs","rb","sh","sql","json","yaml","yml","toml","xml","css","scss","vue","svelte"].includes(e)?"code":"file"}function Lv(n){let e=n.split(".").pop()?.toLowerCase()??"";return{ts:"typescript",tsx:"typescriptreact",js:"javascript",jsx:"javascriptreact",py:"python",rs:"rust",go:"go",java:"java",c:"c",cpp:"cpp",h:"c",cs:"csharp",rb:"ruby",sh:"shellscript",sql:"sql",json:"json",yaml:"yaml",yml:"yaml",toml:"toml",xml:"xml",html:"html",css:"css",scss:"scss",vue:"vue",svelte:"svelte",md:"markdown"}[e]}function Uv(n){if(!jv.has(n.toolName))return!1;let e=typeof n.message?.content=="string"?n.message.content.trim():"";return e.length>0&&e.length<200&&$v.test(e)}function Md(n,e){for(let t=n.length-1;t>=0;t--){let r=n[t];if(!r||r.role!=="tool")continue;let s=typeof r.content=="string"?r.content:"";if(s.startsWith("Error: "))return s.slice(7).trim()}}function Fv(n){return typeof n=="number"&&Number.isFinite(n)&&n>=1?Math.min(Math.round(n),100):Uo}function Dd(n){let e=n.message.toLowerCase();return n.status===413||e.includes("prompt_too_long")||e.includes("context_length_exceeded")||e.includes("maximum context length")}function Bv(n){return n==="length"||n==="max_tokens"}function Nd(n){let e=n.message.toLowerCase();return(e.includes("image")||e.includes("media")||e.includes("file too large")||e.includes("payload too large"))&&(n.status===413||e.includes("too large")||e.includes("size"))}function Hv(n){let e=n.headers;if(!e)return null;let t=e["retry-after"]??e["Retry-After"];if(!t)return null;let r=parseInt(t,10);return!isNaN(r)&&r>0?r*1e3:null}function qv(n){if(n.status!==400)return null;let e=n.message.match(/input length and `max_tokens` exceed context limit: (\d+) \+ (\d+) > (\d+)/);if(!e?.[1]||!e?.[3])return null;let t=parseInt(e[1],10),r=parseInt(e[3],10);if(isNaN(t)||isNaN(r))return null;let s=r-t-1e3;return s>=3e3?s:null}function Wv(n){return n.filter(e=>e.role!=="assistant"?!0:!(typeof e.content=="string"&&e.content.trim()===""))}async function*Od(n,e,t,r){let{turnId:s,sessionId:o,messages:i,tools:a,model:c,apiKey:l,temperature:u=0,hooks:d,signal:p}=n,m={sessionId:o,turnId:s},h=n.maxTurns??0,f=n.querySource,{resolveToolEligibility:y}=await Promise.resolve().then(()=>(Ed(),Cd)),b=y(a,n.toolEligibilityContext),S=b.eligibleTools;for(let j of b.blockedTools)yield{type:"tool_blocked",turnId:s,callId:"",name:j.toolName,reason:"blocked-by-policy"};if(!S.length){yield*Gv(s,c,i,l,u,p,e,r);return}let w=Fv(n.maxRounds),_={contextWindowTokens:n.contextWindowTokens??Ho,responseBufferTokens:qo,maxOutputTokens:n.maxOutputTokens??Wo,abortSignal:p,reactiveCompactEnabled:!0,outputEscalationEnabled:!0},I=new Set,D=0,L=S,F,T={messages:[...i],maxOutputTokensRecoveryCount:0,hasAttemptedReactiveCompact:!1,maxOutputTokensOverride:void 0,turnCount:1,transition:void 0,guardState:Ui(_),reactiveCompactState:Wi(),toolLoopState:Xr({maxRounds:w,replayMessages:[...i]}).state,consecutiveFailedRounds:0,finalText:"",totalUsage:{inputTokens:0,outputTokens:0},collapseStore:Lo(),currentModel:c,consecutive529Errors:0,consecutiveApiRetries:0,stopHookActive:void 0,lastResponseId:void 0,snipRemovedIds:new Set,contentReplacementState:nd(),budgetContinuationCount:0,lastBudgetDeltaTokens:0,lastBudgetGlobalTokens:0,identicalCallCounts:new Map,toolFailureCounts:new Map,fileReadCounts:new Map},ce=Math.max(h*5,200),le=0;for(;;){if(le++,le>ce){r.info(`hard iteration cap reached (${ce}), forcing completion`);let P=T.finalText||er(T.messages,r);yield{type:"end",turnId:s,content:P,usage:T.totalUsage,model:T.currentModel};return}let{messages:j,maxOutputTokensRecoveryCount:ke,hasAttemptedReactiveCompact:oe,maxOutputTokensOverride:$e,turnCount:te,guardState:Y,reactiveCompactState:R,collapseStore:B}=T,{toolLoopState:U}=T;if(F){try{let P=await F;P&&(yield{type:"tool_use_summary",turnId:s,summary:P})}catch{}F=void 0}if(n.refreshTools&&te>1){let P=n.refreshTools();P!==L&&(L=P,r.debug(`tools refreshed: ${P.length} tools`))}if(qi(Y,_)){r.info(`turn aborted by guard at turn ${te}`),yield{type:"error",turnId:s,error:"Turn aborted",code:"ABORTED",usage:T.totalUsage};return}let we=Fi(Y,_);if(we.level==="blocking"){we.reason==="prompt_too_long"&&Tn(R)&&(R.attemptedThisTurn=!0,Y.hasAttemptedReactiveCompact=!0,r.info(`token budget blocking (${we.reason}), reactive compact needed`),yield{type:"recovery",turnId:s,action:"reactive_compact",detail:"token budget pre-check"}),r.info(`token budget blocking (${we.reason}), ending tool loop`);break}we.level==="warning"&&r.info(`token budget warning: ${we.usagePercent}% used, ${we.remainingTokens} remaining`);let fe;{let P=await cd(j,T.contentReplacementState,o);fe=P.messages,P.newlyReplacedCount>0&&(r.info(`tool-result-budget: persisted ${P.newlyReplacedCount} oversized tool results`),yield{type:"recovery",turnId:s,action:"tool_result_budget",detail:`${P.newlyReplacedCount} persisted`})}{let P=No(fe,T.snipRemovedIds);fe=P.messages,P.removedCount>0&&(r.info(`snip: removed ${P.removedCount} messages, freed ~${P.tokensFreed} tokens`),yield{type:"recovery",turnId:s,action:"snip",detail:`${P.removedCount} messages`})}{let E=new Kt().compress(fe,0);E.droppedCount>0&&(fe=E.messages,r.info(`microcompact: cleared ${E.droppedCount} old tool results`))}if(fe=$o(fe,B).messages,Y.promptTokens>0){let P=_.contextWindowTokens*.75,E=Ad().getActive(),O;E?O=await E.compressAsync(fe,P,{model:T.currentModel,sessionId:o}):O=xd(fe,{budget:P,model:T.currentModel}),O.droppedCount>0&&(fe=O.messages,r.info(`autocompact: ${O.strategy}, dropped ${O.droppedCount}`),yield{type:"recovery",turnId:s,action:"autocompact",detail:`${O.strategy}: ${O.droppedCount} dropped`},T.hasAttemptedReactiveCompact=!1,d?.invoke("context.after_compact",{...m,removedCount:O.droppedCount}).catch(()=>{}))}fe=Wv(fe);let Et=xi({tools:L,toolChoice:n.toolChoice??"auto"}),g=Xr({maxRounds:w,replayMessages:fe,lastStopReason:U.lastStopReason,options:{stopReason:U.lastStopReason}}),v=Et.extraSystemPrompt?[{role:"system",content:Et.extraSystemPrompt},...g.state.replayMessages]:g.state.replayMessages;U=g.state,g.recoveryActions.length>0&&r.debug(`tool loop recovery: ${g.recoveryActions.map(P=>P.detail??P.kind).join("; ")}`),r.debug(`turn ${te}, messages: ${v.length}`),d?.invoke("turn.before_inference",{...m,model:T.currentModel}).catch(()=>{});let x=!1,C=[],A=new Map,$="stop",N,M=null,W=!1,ie=[],Z=[];try{for await(let P of e.stream({model:T.currentModel,messages:v,tools:Et.tools,toolChoice:Et.normalizedToolChoice??"auto",temperature:u,maxTokens:($e??Y.currentMaxOutputTokens)||void 0,streamRequired:n.streamRequired,previousResponseId:T.lastResponseId,reasoning:n.reasoning,promptCacheKey:n.promptCacheKey,promptCacheRetention:n.promptCacheRetention,serviceTier:n.serviceTier,openaiBuiltinTools:n.openaiBuiltinTools,maxToolCalls:n.maxToolCalls,parallelToolCalls:n.parallelToolCalls,textVerbosity:n.textVerbosity},l,p))switch(P.type){case"delta":C.push(P.text),x||(yield{type:"delta",turnId:s,text:P.text});break;case"tool_call_delta":x=!0,Dv(A,P);break;case"reasoning_delta":ie.push(P.text);break;case"reasoning_block_complete":P.signature&&Z.push({thinking:ie.join(""),signature:P.signature}),ie.length=0;break;case"usage":N={inputTokens:P.promptTokens,outputTokens:P.completionTokens,reasoningTokens:P.reasoningTokens,cacheRead:P.cacheReadTokens,cacheWrite:P.cacheCreationTokens};break;case"response_id":T.lastResponseId=P.id;break;case"annotations":yield{type:"annotations",turnId:s,annotations:P.annotations};break;case"builtin_tool_status":yield{type:"heartbeat",turnId:s,message:`${P.toolType}: ${P.event}`};break;case"done":$=P.finishReason;break}if(x||d?.invoke("turn.after_inference",{...m,model:T.currentModel}).catch(()=>{}),n.postSamplingHooks&&n.postSamplingHooks.length>0){let P=T.currentModel;for(let E of n.postSamplingHooks)try{E({messages:[...fe],model:P,sessionId:o})}catch{}}}catch(P){if(P instanceof Xn&&n.fallbackModel){r.info(`model fallback triggered: ${P.originalModel} \u2192 ${P.fallbackModel}`),yield{type:"recovery",turnId:s,action:"model_fallback",detail:`${P.originalModel} \u2192 ${P.fallbackModel}`},T={...T,currentModel:P.fallbackModel,consecutive529Errors:0,consecutiveApiRetries:0,transition:void 0};continue}let E=P instanceof Error?P.message:String(P),O=typeof P?.status=="number"?P.status:void 0;if(!O&&E&&(E.includes("ECONNRESET")||E.includes("EPIPE"))){let re=(T.consecutiveApiRetries??0)+1;if(re>Sn){r.info(`stale connection retry limit reached (${Sn}), aborting`),yield{type:"error",turnId:s,error:E,code:"RETRIES_EXHAUSTED",usage:T.totalUsage};return}r.info(`stale connection (${E.includes("ECONNRESET")?"ECONNRESET":"EPIPE"}): retrying`),yield{type:"recovery",turnId:s,action:"stale_connection_retry",detail:E.slice(0,80)},T={...T,consecutiveApiRetries:re,transition:void 0};continue}let H=qv({status:O,message:E});if(H!==null){r.info(`max_tokens overflow: adjusting to ${H}`),Y.currentMaxOutputTokens=H,T={...T,maxOutputTokensOverride:H,transition:void 0};continue}if(Ni(O)){T.consecutive529Errors++;let re=2,Ae=n.fallbackModel&&T.currentModel!==n.fallbackModel;if(T.consecutive529Errors>re&&!Ae&&!Jr()){r.info(`transient ${O} \xD7 ${T.consecutive529Errors}: hard limit reached, aborting`),yield{type:"error",turnId:s,error:`API unavailable after ${T.consecutive529Errors} consecutive ${O} errors`,code:"API_ERROR",usage:T.totalUsage};return}if(T.consecutive529Errors>=Qo&&n.fallbackModel&&T.currentModel!==n.fallbackModel){r.info(`529 \xD7 ${T.consecutive529Errors}: triggering fallback to ${n.fallbackModel}`),yield{type:"recovery",turnId:s,action:"model_fallback",detail:`529 \xD7 ${T.consecutive529Errors}`},T={...T,currentModel:n.fallbackModel,consecutive529Errors:0,transition:void 0};continue}if(Jr()){let J=Yr(T.consecutive529Errors);r.info(`persistent retry: waiting ${J}ms (attempt ${T.consecutive529Errors})`);let he=J;for(;he>0;){if(p?.aborted){yield{type:"error",turnId:s,error:"Aborted during retry wait",code:"ABORTED",usage:T.totalUsage};return}yield{type:"heartbeat",turnId:s,message:`Retrying in ${Math.ceil(he/1e3)}s (${O})`};let ot=Math.min(he,Jo);await new Promise(Ao=>setTimeout(Ao,ot)),he-=ot}T={...T,transition:void 0};continue}if(Di(f)){let he=Hv({status:O,message:E})??Yr(T.consecutive529Errors);r.info(`transient ${O}: retry in ${he}ms`),yield{type:"recovery",turnId:s,action:"retry",detail:`${O} retry in ${he}ms`},await new Promise(ot=>setTimeout(ot,he)),T={...T,transition:void 0};continue}r.info(`background source ${f}: not retrying ${O}`)}M={status:O,message:E}}if(M&&d?.invoke("turn.after_inference",{...m,model:T.currentModel,response:{error:M.message}}).catch(()=>{}),M)if(Dd(M))W=!0,r.info(`withheld prompt_too_long error (status=${M.status})`);else if(Nd(M))W=!0,r.info(`withheld media_size error (status=${M.status})`);else{let P=Bi({status:M.status??500,message:M.message},Y,_);if(P.action==="reactive_compact"&&Tn(R)&&(R.attemptedThisTurn=!0,Y.hasAttemptedReactiveCompact=!0,yield{type:"recovery",turnId:s,action:"reactive_compact",detail:`API ${M.status??500}: ${M.message}`}),P.action==="retry"){let O=(T.consecutiveApiRetries??0)+1;if(O>Sn){r.info(`API retry limit reached (${Sn}), aborting`);let H=kn(M.status,M.message);yield{type:"error",turnId:s,error:M.message,code:H,usage:T.totalUsage};return}yield{type:"recovery",turnId:s,action:"retry",detail:P.reason},T={...T,consecutiveApiRetries:O,transition:void 0};continue}let E=kn(M.status,M.message);d?.invoke("stop.failure",{sessionId:o,reason:E,error:M.message}).catch(()=>{}),yield{type:"error",turnId:s,error:M.message,code:E,usage:T.totalUsage};return}N&&(T.totalUsage.inputTokens+=N.inputTokens,T.totalUsage.outputTokens+=N.outputTokens,N.reasoningTokens&&(T.totalUsage.reasoningTokens=(T.totalUsage.reasoningTokens??0)+N.reasoningTokens),N.cacheRead&&(T.totalUsage.cacheRead=(T.totalUsage.cacheRead??0)+N.cacheRead),N.cacheWrite&&(T.totalUsage.cacheWrite=(T.totalUsage.cacheWrite??0)+N.cacheWrite)),N?.inputTokens&&(Y.promptTokens=N.inputTokens);let ne=C.join("");ne&&(T.finalText=ne);let pe=[...A.values()].map(P=>({id:P.id||`tc_${s}_${te}_${Math.random().toString(36).slice(2,8)}`,type:"function",function:{name:P.name,arguments:P.arguments}}));if(pe.length===0&&!x){if(W&&M&&Dd(M)){if(T.transition?.reason!=="collapse_drain_retry"){let O=jo(fe,B);if(O.committed>0){r.info(`collapse drain: committed ${O.committed} stages`),yield{type:"recovery",turnId:s,action:"collapse_drain",detail:`${O.committed} stages committed`},T={...T,messages:O.messages,transition:{reason:"collapse_drain_retry",committed:O.committed}};continue}}if(Tn(R)){R.attemptedThisTurn=!0,Y.hasAttemptedReactiveCompact=!0,r.info("withheld 413: reactive compact attempt"),yield{type:"recovery",turnId:s,action:"reactive_compact",detail:"withheld prompt_too_long"},T={...T,hasAttemptedReactiveCompact:!0,transition:{reason:"reactive_compact_retry"}};continue}r.info("withheld 413: recovery exhausted, surfacing error"),d?.invoke("stop.failure",{sessionId:o,reason:"prompt_too_long",error:M.message}).catch(()=>{}),yield{type:"error",turnId:s,error:M.message,code:"PROMPT_TOO_LONG",usage:T.totalUsage};return}if(W&&M&&Nd(M)){if(Tn(R)){R.attemptedThisTurn=!0,Y.hasAttemptedReactiveCompact=!0,r.info("withheld media error: reactive compact strip-retry"),yield{type:"recovery",turnId:s,action:"reactive_compact",detail:"media error strip-retry"},T={...T,hasAttemptedReactiveCompact:!0,transition:{reason:"reactive_compact_retry"}};continue}r.info("withheld media error: recovery exhausted"),d?.invoke("stop.failure",{sessionId:o,reason:"media_error",error:M.message}).catch(()=>{}),yield{type:"error",turnId:s,error:M.message,code:"IMAGE_ERROR",usage:T.totalUsage};return}if(Bv($)){Y.consecutiveTruncations+=1;let O=n.modelMaxOutputTokens??Go,H=Hi(Y,_,O);if(H.shouldEscalate&&$e===void 0){Y.currentMaxOutputTokens=H.newMax,r.info(`max_output_tokens escalate: ${H.newMax} tokens`),yield{type:"recovery",turnId:s,action:"output_escalation",detail:`${H.newMax} tokens`},T={...T,maxOutputTokensOverride:Vo,transition:{reason:"max_output_tokens_escalate"}};continue}if(ke<Ko){let re={role:"user",content:"Output token limit hit. Resume directly \u2014 no apology, no recap of what you were doing. Pick up mid-thought if that is where the cut happened. Break remaining work into smaller pieces."};r.info(`max_output_tokens recovery #${ke+1}`),yield{type:"recovery",turnId:s,action:"max_output_tokens_recovery",detail:`attempt ${ke+1}`},T={...T,messages:[...fe,re],maxOutputTokensRecoveryCount:ke+1,maxOutputTokensOverride:void 0,transition:{reason:"max_output_tokens_recovery",attempt:ke+1}};continue}r.info("max_output_tokens recovery exhausted, completing with partial content")}else Y.consecutiveTruncations=0;if(U=zr(U,{replayMessages:j,lastStopReason:"completed"}),d){let O=await d.invoke("stop",{sessionId:o,reason:"completed"});if(O.action==="prevent"){r.info(`stop hook prevented continuation: ${O.reason??"no reason"}`),yield{type:"end",turnId:s,content:T.finalText,usage:T.totalUsage,model:T.currentModel};return}if(O.action==="abort"){let H=O.reason??"Stop hook requested continuation";r.info(`stop hook blocking: ${H}`);let re={role:"user",content:H},Ae={role:"assistant",content:T.finalText,...Z.length>0&&{thinkingBlocks:[...Z]}};T={...T,messages:[...j,Ae,re],stopHookActive:!0,transition:{reason:"stop_hook_blocking"}};continue}}if(n.tokenBudget&&n.tokenBudget>0&&T.budgetContinuationCount<5){let O=T.totalUsage.inputTokens+T.totalUsage.outputTokens+(T.totalUsage.reasoningTokens??0),H=O/n.tokenBudget*100,re=O-T.lastBudgetGlobalTokens,Ae=T.budgetContinuationCount>=zo&&re<Wr&&T.lastBudgetDeltaTokens<Wr;if(Ae&&r.info(`token budget early stop: diminishing returns at ${Math.round(H)}% (delta=${re})`),!Ae&&H<90){let J=T.budgetContinuationCount+1,he={role:"user",content:Id(H,O,n.tokenBudget)};r.info(`token budget continuation #${J}: ${Math.round(H)}% used`),yield{type:"recovery",turnId:s,action:"budget_continuation",detail:`${Math.round(H)}% used (#${J})`};let ot={role:"assistant",content:T.finalText,...Z.length>0&&{thinkingBlocks:[...Z]}};T={...T,messages:[...j,ot,he],budgetContinuationCount:J,lastBudgetDeltaTokens:re,lastBudgetGlobalTokens:O,transition:{reason:"token_budget_continuation"}};continue}}if(!T.stopHookActive){let O=i.find(J=>J.role==="user"),H=typeof O?.content=="string"?O.content:"",re=/创建文件|生成文件|写入|写一个|建一个|新建|重写|改写|create\s+(a\s+)?file|write\s+(a\s+)?file|make\s+(a\s+)?file|修改|改成|把.*改|文件名叫/i.test(H),Ae=I.has("write")||I.has("edit");if(re&&!Ae){if(r.info("AP1 action-verification: user requested file action but no write/edit tool was called, injecting nudge"),D>0){let ot=[...j].reverse().find(Ao=>Ao.role==="tool");ot&&typeof ot.content=="string"&&(ot.content+=`
|
|
24
|
+
...[truncated ${n.length-r} chars]`}function rv(n){let e=[],t=[];for(let r of n)r.role==="tool"&&typeof r.content=="string"&&r.tool_call_id?sd(r.content)||t.push({toolCallId:r.tool_call_id,content:r.content,size:r.content.length}):r.role==="assistant"&&t.length>0&&(e.push(t),t=[]);return t.length>0&&e.push(t),e}function sv(n,e){let t=[],r=[],s=[];for(let o of n){let i=e.replacements.get(o.toolCallId);i!==void 0?t.push({...o,replacement:i}):e.seenIds.has(o.toolCallId)?r.push(o):s.push(o)}return{mustReapply:t,frozen:r,fresh:s}}function ov(n,e,t){let r=[...n].sort((i,a)=>a.size-i.size),s=[],o=e+n.reduce((i,a)=>i+a.size,0);for(let i of r){if(o<=t)break;s.push(i),o-=i.size}return s}async function cd(n,e,t,r=Yo){let s=rv(n);if(s.length===0)return{messages:n,newlyReplacedCount:0};let o=new Map,i=[];for(let u of s){let{mustReapply:d,frozen:p,fresh:m}=sv(u,e);for(let T of d)o.set(T.toolCallId,T.replacement);if(m.length===0){for(let T of u)e.seenIds.add(T.toolCallId);continue}let h=p.reduce((T,w)=>T+w.size,0),f=m.reduce((T,w)=>T+w.size,0),y=h+f>r?ov(m,h,r):[],b=new Set(y.map(T=>T.toolCallId));for(let T of u)b.has(T.toolCallId)||e.seenIds.add(T.toolCallId);y.length>0&&i.push(...y)}if(o.size===0&&i.length===0)return{messages:n,newlyReplacedCount:0};let a=await Promise.all(i.map(async u=>{let d=await od(u.content,u.toolCallId,t);return{candidate:u,result:d}})),c=0;for(let{candidate:u,result:d}of a){if(e.seenIds.add(u.toolCallId),!d)continue;let p=id(d);o.set(u.toolCallId,p),e.replacements.set(u.toolCallId,p),c++}return o.size===0?{messages:n,newlyReplacedCount:0}:{messages:n.map(u=>{if(u.role!=="tool"||!u.tool_call_id)return u;let d=o.get(u.tool_call_id);return d===void 0?u:{...u,content:d}}),newlyReplacedCount:c}}var Qk,td,Zk,Gi=Q(()=>{"use strict";je();Qk="tool-results",td="<persisted-output>",Zk="</persisted-output>"});function cv(n){try{return JSON.parse(n)}catch{return}}var iv,av,Zr,ld=Q(()=>{"use strict";Yn();Gi();iv=new Set(["read_file","file_read","FileRead","grep","Grep","glob","Glob","search","list_dir","find_files","web_fetch","web_search","WebFetch","WebSearch"]),av=new Set(["bash","execute_command","Bash","shell"]),Zr=class{tools=[];hasErrored=!1;erroredToolDescription="";discarded=!1;siblingAbortController;progressResolve;config;concurrencySafe;constructor(e){this.config=e,this.concurrencySafe=e.concurrencySafeTools??iv,this.siblingAbortController=new AbortController,e.signal&&e.signal.addEventListener("abort",()=>{this.siblingAbortController.abort("parent_abort")},{once:!0})}discard(){this.discarded=!0}addTool(e){let t=this.concurrencySafe.has(e.function.name);this.tools.push({id:e.id,toolCall:e,status:"queued",isConcurrencySafe:t,results:[],pendingProgress:[]}),this.processQueue()}canExecuteTool(e){let t=this.tools.filter(s=>s.status==="executing"),r=this.config.maxConcurrentTools;return r&&r>0&&t.length>=r?!1:t.length===0||e&&t.every(s=>s.isConcurrencySafe)}async processQueue(){for(let e of this.tools)if(e.status==="queued"){if(this.canExecuteTool(e.isConcurrencySafe))await this.executeTool(e);else if(!e.isConcurrencySafe)break}}getAbortReason(){return this.discarded?"discarded":this.hasErrored?"sibling_error":this.config.signal?.aborted?"user_interrupted":null}getToolDescription(e){let t;try{t=JSON.parse(e.toolCall.function.arguments)}catch{}let r=t?.command??t?.file_path??t?.pattern??"";if(typeof r=="string"&&r.length>0){let s=r.length>40?r.slice(0,40)+"\u2026":r;return`${e.toolCall.function.name}(${s})`}return e.toolCall.function.name}createSyntheticError(e,t){let r=this.erroredToolDescription,s=t==="user_interrupted"?"User rejected tool use":t==="discarded"?"Streaming fallback - tool execution discarded":r?`Cancelled: parallel tool call ${r} errored`:"Cancelled: parallel tool call errored";return{callId:e.id,toolName:e.toolCall.function.name,ok:!1,error:s,message:Gt(e.id,{ok:!1,error:s})}}async executeTool(e){e.status="executing";let r=(async()=>{let s=this.getAbortReason();if(s){e.results.push(this.createSyntheticError(e,s)),e.status="completed";return}let{toolInvoker:o,hooks:i,sessionId:a,turnId:c,log:l}=this.config,u=e.toolCall.function.name,d=!1,p=e.toolCall.function.arguments;if(i)try{let T=await i.invoke("tool.before_invoke",{sessionId:a,turnId:c,callId:e.id,toolName:u,arguments:cv(p)});if(T.action==="abort"){let w=T.reason??"blocked by policy";l.info(`tool ${u} blocked: ${w}`),e.results.push({callId:e.id,toolName:u,ok:!1,error:w,blocked:!0,blockReason:w,message:Gt(e.id,{ok:!1,error:w})}),e.status="completed";return}T.action==="continue"&&T.context?.arguments&&(p=JSON.stringify(T.context.arguments))}catch{}let m=await o.invoke(c,u,p,this.siblingAbortController.signal),h=this.getAbortReason();if(h&&!d){e.results.push(this.createSyntheticError(e,h)),e.status="completed";return}let f=!m.error,y=m.result;f&&y&&y.length>5e4&&(y=await ad(y,e.id,a));let b=Gt(e.id,{ok:f,payload:y,error:m.error,toolReferences:m.toolReferences,imageUrls:m.imageUrls});f||(d=!0,av.has(u)&&(this.hasErrored=!0,this.erroredToolDescription=this.getToolDescription(e),this.siblingAbortController.abort("sibling_error"))),i?.invoke(f?"tool.after_invoke":"tool.invoke_failed",{sessionId:a,turnId:c,callId:e.id,toolName:u,ok:f,...m.error?{error:m.error}:{}}).catch(()=>{}),e.results.push({callId:e.id,toolName:u,ok:f,error:m.error,message:b}),e.status="completed"})();e.promise=r,r.finally(()=>{this.processQueue()})}*getCompletedResults(){if(!this.discarded){for(let e of this.tools)if(e.status!=="yielded"){if(e.status==="completed"&&e.results.length>0){e.status="yielded";for(let t of e.results)yield t}else if(e.status==="executing"&&!e.isConcurrencySafe)break}}}async*getRemainingResults(){if(!this.discarded){for(;this.hasUnfinishedTools();){await this.processQueue();for(let e of this.getCompletedResults())yield e;if(this.hasExecutingTools()&&!this.hasCompletedResults()){let e=this.tools.filter(r=>r.status==="executing"&&r.promise).map(r=>r.promise),t=new Promise(r=>{this.progressResolve=r});e.length>0&&await Promise.race([...e,t])}}for(let e of this.getCompletedResults())yield e}}hasCompletedResults(){return this.tools.some(e=>e.status==="completed")}hasExecutingTools(){return this.tools.some(e=>e.status==="executing")}hasUnfinishedTools(){return this.tools.some(e=>e.status!=="yielded")}}});import{homedir as lv}from"node:os";import{join as xe}from"node:path";import{existsSync as dv}from"node:fs";function q(){return process.env.QLOGICAGENT_HOME||xe(lv(),qe)}function dd(){return xe(q(),"plugins")}function Dt(){return xe(q(),"skills")}function lt(){return xe(q(),"settings.json")}function ud(){return xe(q(),"plugin-cache")}function pd(){return xe(q(),"mcp.json")}function md(){return xe(q(),"marketplace.json")}function gd(){return xe(q(),"workflows")}function fd(){return xe(q(),"rules")}function Me(n){if(!n)throw new Error("getProjectAgentDir: cwd is required (must not fall back to process.cwd())");return xe(n,qe)}function hd(n){return xe(Me(n),"workflows")}function Tt(n){return xe(Me(n),"skills")}function Jn(n){return xe(Me(n),"INSTRUCTIONS.md")}function Rn(n){return xe(Me(n),"rules")}function Nt(n){return xe(Me(n),"sessions")}function yd(n,e){let t=xe(Me(n),"checkpoints");return e?xe(t,e):t}function bd(n){return xe(n,qe,"hooks")}function kd(n,e){return n.filter(t=>t!==e&&dv(xe(t,qe,"skills")))}var qe,ae=Q(()=>{"use strict";qe=".qlogicagent"});var es,vd=Q(()=>{"use strict";es=class{pools=new Map;runtimeStates=new Map;constructor(e){if(e)for(let t of e){this.pools.set(t.providerId,t);for(let r of t.keys)this.runtimeStates.set(r.id,this.createInitialState())}}acquireKey(e){let t=this.pools.get(e);if(!t||t.keys.length===0)return null;let r=Date.now(),s=this.getHealthyCandidates(t,r);if(s.length===0)return null;let o=this.selectByStrategy(s,t.strategy,r);if(!o)return null;let i=this.runtimeStates.get(o.id);return i.inFlight++,i.totalRequests++,i.lastUsedAt=r,i.requestTimestamps.push(r),{keyId:o.id,apiKey:o.key,providerId:e,release:a=>this.releaseKey(o.id,a)}}releaseKey(e,t){let r=this.runtimeStates.get(e);if(r)if(r.inFlight=Math.max(0,r.inFlight-1),t.success)r.consecutiveErrors=0,r.healthStatus="healthy",t.tokens&&(r.totalTokens+=t.tokens,r.tokenCounts.push(t.tokens));else if(r.consecutiveErrors++,r.lastErrorAt=Date.now(),t.errorCode===429){let s=t.retryAfter?t.retryAfter*1e3:3e4;r.cooldownUntil=Date.now()+s,r.healthStatus="cooldown"}else r.consecutiveErrors>=5?(r.cooldownUntil=Date.now()+6e4,r.healthStatus="cooldown"):r.consecutiveErrors>=3&&(r.healthStatus="degraded")}addProvider(e,t){this.pools.has(e)||this.pools.set(e,{providerId:e,baseUrl:t?.baseUrl,strategy:t?.strategy??"weighted-round-robin",keys:[],rateLimit:t?.rateLimit})}removeProvider(e){let t=this.pools.get(e);if(t){for(let r of t.keys)this.runtimeStates.delete(r.id);this.pools.delete(e)}}addKey(e,t,r){let s=this.pools.get(e);s||(s={providerId:e,strategy:"weighted-round-robin",keys:[]},this.pools.set(e,s));let o=r?.id??crypto.randomUUID(),i={id:o,key:t,label:r?.label,weight:r?.weight??1,enabled:r?.enabled??!0};return s.keys.push(i),this.runtimeStates.set(o,this.createInitialState()),o}removeKey(e){for(let t of this.pools.values()){let r=t.keys.findIndex(s=>s.id===e);if(r!==-1){t.keys.splice(r,1),this.runtimeStates.delete(e);return}}}updateKey(e,t){for(let r of this.pools.values()){let s=r.keys.find(o=>o.id===e);if(s){if(t.label!==void 0&&(s.label=t.label),t.weight!==void 0&&(s.weight=t.weight),t.enabled!==void 0){s.enabled=t.enabled;let o=this.runtimeStates.get(e);o&&(o.healthStatus=t.enabled?"healthy":"disabled")}return}}}setKeyHealth(e,t){let r=this.runtimeStates.get(e);r&&(r.healthStatus=t)}setStrategy(e,t){let r=this.pools.get(e);r&&(r.strategy=t)}setRateLimit(e,t){let r=this.pools.get(e);r&&(r.rateLimit=t)}getPoolStatus(e){let t=this.pools.get(e);return t?this.buildPoolStatus(t):null}getAllStatus(){return[...this.pools.values()].map(e=>this.buildPoolStatus(e))}getProviderIds(){return[...this.pools.keys()]}hasProvider(e){return this.pools.has(e)}hasAvailableKey(e){let t=this.pools.get(e);return t?this.getHealthyCandidates(t,Date.now()).length>0:!1}exportConfig(){return[...this.pools.values()]}reloadConfig(e){let t=new Set;for(let r of e){this.pools.set(r.providerId,r);for(let s of r.keys)t.add(s.id),this.runtimeStates.has(s.id)||this.runtimeStates.set(s.id,this.createInitialState())}for(let r of[...this.pools.keys()])e.some(s=>s.providerId===r)||this.pools.delete(r);for(let r of[...this.runtimeStates.keys()])t.has(r)||this.runtimeStates.delete(r)}createInitialState(){return{inFlight:0,totalRequests:0,totalTokens:0,lastUsedAt:0,lastErrorAt:0,consecutiveErrors:0,cooldownUntil:0,healthStatus:"healthy",requestTimestamps:[],tokenCounts:[]}}getHealthyCandidates(e,t){let r=[];for(let s of e.keys){if(!s.enabled)continue;let o=this.runtimeStates.get(s.id);if(o){if(o.healthStatus==="cooldown")if(t>=o.cooldownUntil)o.healthStatus="healthy",o.consecutiveErrors=0;else continue;o.healthStatus!=="disabled"&&(e.rateLimit?.rpm&&(this.pruneWindow(o.requestTimestamps,t),o.requestTimestamps.length>=e.rateLimit.rpm*.9)||e.rateLimit?.tpm&&(this.pruneWindow(o.tokenCounts,t),o.tokenCounts.reduce((a,c)=>a+c,0)>=e.rateLimit.tpm*.9)||r.push(s))}}return r}selectByStrategy(e,t,r){if(e.length===0)return null;if(e.length===1)return e[0];switch(t){case"weighted-round-robin":return this.weightedRandom(e);case"least-busy":return this.leastBusy(e);case"random":return e[Math.floor(Math.random()*e.length)];default:return this.weightedRandom(e)}}weightedRandom(e){let t=e.reduce((s,o)=>s+o.weight,0),r=Math.random()*t;for(let s of e)if(r-=s.weight,r<=0)return s;return e[e.length-1]}leastBusy(e){let t=1/0,r=e[0];for(let s of e){let i=this.runtimeStates.get(s.id)?.inFlight??0;(i<t||i===t&&s.weight>r.weight)&&(t=i,r=s)}return r}pruneWindow(e,t){let r=t-6e4;for(;e.length>0&&e[0]<r;)e.shift()}buildPoolStatus(e){return{providerId:e.providerId,baseUrl:e.baseUrl,strategy:e.strategy,rateLimit:e.rateLimit,keys:e.keys.map(t=>{let r=this.runtimeStates.get(t.id)??this.createInitialState();return{...t,inFlight:r.inFlight,totalRequests:r.totalRequests,totalTokens:r.totalTokens,lastUsedAt:r.lastUsedAt,lastErrorAt:r.lastErrorAt,consecutiveErrors:r.consecutiveErrors,cooldownUntil:r.cooldownUntil,healthStatus:t.enabled?r.healthStatus:"disabled"}})}}}});var Sd={};Zt(Sd,{ALL_PURPOSES:()=>Zn,ModelRegistry:()=>ts,deriveModelPurposes:()=>gv,getModelRegistry:()=>X,resetModelRegistry:()=>mv});import*as Ze from"node:fs";import{ProviderRegistry as uv,ProviderVariantResolver as pv}from"@xiaozhiclaw/provider-core";function X(){return Qn||(Qn=new ts,Qn.load()),Qn}function mv(){Qn=null}function gv(n){let e=[];switch((!n.mediaType||n.mediaType==="image_understanding"||n.mediaType==="video_understanding")&&e.push("textGeneration"),(n.vision||n.mediaType==="image_understanding")&&e.push("imageUnderstanding"),n.mediaType==="video_understanding"&&e.push("videoUnderstanding"),n.mediaType){case"image":e.push("imageGeneration");break;case"video":e.push("videoGeneration");break;case"tts":e.push("tts");break;case"stt":e.push("stt");break;case"music":case"music_realtime":e.push("musicGeneration");break;case"voice_clone":e.push("voiceClone");break;case"embedding":e.push("embedding");break;case"3d":e.push("threeDGeneration");break;case"realtime_audio":e.push("realtimeAudio");break}return e.includes("textGeneration")&&e.push("smallModel"),[...new Set(e.length>0?e:["textGeneration"])]}function fv(n){switch(n){case"openai-chat":case"openai-responses":case"anthropic-messages":case"volcengine-responses":return n;default:return}}function hv(n,e){switch(n){case"imageUnderstanding":case"videoUnderstanding":case"imageGeneration":case"videoGeneration":case"threeDGeneration":case"stt":case"tts":case"voiceClone":case"musicGeneration":case"realtimeAudio":case"realtimeVideo":case"embedding":return;default:return fv(e)}}function yv(n){switch(n){case"imageUnderstanding":case"videoUnderstanding":return["vision"];case"imageGeneration":case"videoGeneration":case"threeDGeneration":case"stt":case"tts":case"voiceClone":case"musicGeneration":case"realtimeAudio":case"realtimeVideo":case"embedding":return["media"];default:return[]}}var Zn,ts,Qn,dt=Q(()=>{"use strict";ae();vd();Zn=["textGeneration","smallModel","stt","tts","imageGeneration","imageUnderstanding","videoGeneration","videoUnderstanding","threeDGeneration","embedding","voiceClone","musicGeneration","realtimeAudio","realtimeVideo"],ts=class{keyPool;coreProviderRegistry=new uv;providerVariantResolver=new pv(this.coreProviderRegistry);models=new Map;modelEnabledOverrides=new Map;bindings={};settingsPath;changeListeners=[];constructor(e){this.settingsPath=lt(),this.keyPool=new es(e?.providers),e?.models&&this.loadModelState(e.models),e?.bindings&&(this.bindings={...e.bindings})}getActiveModel(e){let t=this.bindings[e];if(!t)return null;let r=this.models.get(t);if(!r||!r.enabled)return null;let s=this.resolveTechnicalVariant(r,e),o=s?.provider??r.provider,i=s?.nativeModelId??r.nativeModelId??r.model,a=this.acquireKeyForProviderVariant(o);if(!a)return null;let{keyHandle:c,keyProviderId:l}=a,u=this.getProviderBaseUrl(o),d=this.getProviderBaseUrl(l);return{provider:o,model:i,apiKey:c.apiKey,baseUrl:u??(r.provider===o?r.baseUrl:void 0)??d,keyHandle:c}}peekActiveModel(e){let t=this.bindings[e];return t?this.models.get(t)??null:null}isAvailable(e){let t=this.peekActiveModel(e);return!!t?.enabled&&this.hasAvailableKeyForProviderVariant(t.provider)}resolveModelForPurpose(e){let t=this.peekActiveModel(e);return t?t.model:null}addProvider(e,t){this.keyPool.addProvider(e,t),this.emitChange()}removeProvider(e){this.keyPool.removeProvider(e);for(let[t,r]of this.models)r.provider===e&&this.removeModel(t);this.emitChange()}addKey(e,t,r){let s=this.keyPool.addKey(e,t,r);return this.emitChange(),s}removeKey(e){this.keyPool.removeKey(e),this.emitChange()}updateKey(e,t){this.keyPool.updateKey(e,t),this.emitChange()}setKeyHealth(e,t){this.keyPool.setKeyHealth(e,t),this.emitChange()}setStrategy(e,t){this.keyPool.setStrategy(e,t),this.emitChange()}addModel(e){let t=e.id??`${e.provider}:${e.model}`;return this.models.set(t,{...e,id:t,enabled:this.modelEnabledOverrides.get(t)??e.enabled}),this.emitChange(),t}replaceCatalogModels(e){let t=new Map;for(let r of e)t.set(r.id,{...r,enabled:this.modelEnabledOverrides.get(r.id)??r.enabled});for(let r of this.modelEnabledOverrides.keys())t.has(r)||this.modelEnabledOverrides.delete(r);this.models=t;for(let[r,s]of Object.entries(this.bindings))s&&!this.models.has(s)&&delete this.bindings[r];this.emitChange()}migrateModelIds(e){for(let[t,r]of e){let s=this.modelEnabledOverrides.get(t);s!==void 0&&!this.modelEnabledOverrides.has(r)&&this.modelEnabledOverrides.set(r,s),this.modelEnabledOverrides.delete(t);for(let[o,i]of Object.entries(this.bindings))i===t&&(this.bindings[o]=r)}this.emitChange()}removeModel(e){this.models.delete(e),this.modelEnabledOverrides.delete(e);for(let[t,r]of Object.entries(this.bindings))r===e&&delete this.bindings[t];this.emitChange()}enableModel(e){let t=this.models.get(e);t&&(t.enabled=!0),this.modelEnabledOverrides.set(e,!0),this.emitChange()}disableModel(e){let t=this.models.get(e);t&&(t.enabled=!1),this.modelEnabledOverrides.set(e,!1),this.emitChange()}listModels(e){let t=[...this.models.values()];return e?.purpose&&(t=t.filter(r=>r.purposes.includes(e.purpose))),e?.provider&&(t=t.filter(r=>r.provider===e.provider)),e?.enabledOnly&&(t=t.filter(r=>r.enabled)),t}getModel(e){return this.models.get(e)??null}setBinding(e,t){let r=this.models.get(t);if(!r)throw new Error(`Model "${t}" not found in pool.`);if(!r.purposes.includes(e))throw new Error(`Model "${t}" does not support purpose "${e}".`);this.bindings[e]=t,this.emitChange()}removeBinding(e){delete this.bindings[e],this.emitChange()}getBinding(e){let t=this.bindings[e];return t?this.models.get(t)??null:null}getAllBindings(){let e={};for(let t of Zn){let r=this.bindings[t];e[t]=r?this.models.get(r)??null:null}return e}getProviderStatus(e){return this.keyPool.getPoolStatus(e)}getAllProviderStatus(){return this.keyPool.getAllStatus()}save(){let e={};try{Ze.existsSync(this.settingsPath)&&(e=JSON.parse(Ze.readFileSync(this.settingsPath,"utf-8")))}catch{e={}}delete e.provider,delete e.apiKey,delete e.model,delete e.baseUrl;let t={...e,providers:this.keyPool.exportConfig(),models:this.exportModelState(),bindings:{...this.bindings}},r=this.settingsPath.replace(/[/\\][^/\\]+$/,"");Ze.existsSync(r)||Ze.mkdirSync(r,{recursive:!0}),Ze.writeFileSync(this.settingsPath,JSON.stringify(t,null,2),"utf-8")}load(){try{if(!Ze.existsSync(this.settingsPath))return!1;let e=Ze.readFileSync(this.settingsPath,"utf-8"),t=JSON.parse(e);return t.providers&&this.keyPool.reloadConfig(t.providers),this.models.clear(),this.modelEnabledOverrides.clear(),t.models&&this.loadModelState(t.models),this.bindings=t.bindings??{},this.emitChange(),!0}catch{return!1}}exportConfig(){return{providers:this.keyPool.exportConfig(),models:this.exportModelState(),bindings:{...this.bindings}}}getTunable(e){try{if(!Ze.existsSync(this.settingsPath))return;let t=Ze.readFileSync(this.settingsPath,"utf-8");return JSON.parse(t).tunables?.[e]}catch{return}}getModelInfo(e,t){let r=this.listModels({provider:e}).find(s=>s.model===t);if(r)return{id:r.model,name:r.displayName,contextWindow:r.contextWindow,maxOutput:r.maxOutput,streamRequired:r.streamRequired}}getProviderDefaultModel(e){return this.listModels({provider:e,enabledOnly:!0})[0]?.model??this.listModels({provider:e})[0]?.model}hasConfiguredKeyForProviderVariant(e){return this.providerVariantKeyCandidates(e).some(t=>!!this.keyPool.getPoolStatus(t)?.keys.some(s=>s.enabled))}hasAvailableKeyForProviderVariant(e){return this.providerVariantKeyCandidates(e).some(t=>this.keyPool.hasAvailableKey(t))}listProviderDefs(){return this.keyPool.getAllStatus().map(e=>({id:e.providerId,name:e.providerId,transport:"",baseUrl:e.baseUrl??"",defaultModel:this.getProviderDefaultModel(e.providerId),models:this.listModels({provider:e.providerId}).map(t=>({id:t.model,name:t.displayName,contextWindow:t.contextWindow,maxOutput:t.maxOutput,streamRequired:t.streamRequired}))}))}resolveProviderApiKey(e){return this.getKeyForProvider(e)??void 0}onChange(e){return this.changeListeners.push(e),()=>{let t=this.changeListeners.indexOf(e);t>=0&&this.changeListeners.splice(t,1)}}getKeyForProvider(e){let r=this.acquireKeyForProviderVariant(e)?.keyHandle;if(!r)return null;let s=r.apiKey;return r.release({success:!0}),s}snapshotProviderKeys(){let e={};for(let t of this.keyPool.getAllStatus()){let r=this.getKeyForProvider(t.providerId);r&&(e[t.providerId]=r)}return e}getProviderBaseUrl(e){return this.coreProviderRegistry.getProvider(e)?.baseUrl??this.keyPool.getPoolStatus(e)?.baseUrl}acquireKeyForProviderVariant(e){for(let t of this.providerVariantKeyCandidates(e)){let r=this.keyPool.acquireKey(t);if(r)return{keyHandle:r,keyProviderId:t}}return null}resolveTechnicalVariant(e,t){let r=this.providerVariantKeyCandidates(e.provider).filter(o=>this.hasConfiguredKeyForProviderVariant(o));if(r.length===0)return;let s=this.providerVariantResolver.resolveBest({publicModel:e.model,requestedProtocol:hv(t,e.transport),capabilities:yv(t),purpose:t,userPreference:{providerIds:r}});if(s)return{provider:s.provider,nativeModelId:s.nativeModelId}}providerVariantKeyCandidates(e){let t=[e],r=this.coreProviderRegistry.getProvider(e),s=r?.group??r?.id??e;for(let o of this.coreProviderRegistry.listProviders())(o.group??o.id)===s&&t.push(o.id);return s!==e&&t.push(s),[...new Set(t)]}loadModelState(e){for(let t of e)typeof t.id!="string"||!t.id||typeof t.enabled=="boolean"&&this.modelEnabledOverrides.set(t.id,t.enabled)}exportModelState(){let e=new Map;for(let[t,r]of this.modelEnabledOverrides)e.set(t,r);for(let t of this.models.values())e.set(t.id,t.enabled);return[...e.entries()].map(([t,r])=>({id:t,enabled:r}))}emitChange(){for(let e of this.changeListeners)try{e()}catch{}}},Qn=null});import{readFile as bv}from"node:fs/promises";function sn(n){let e=typeof n.content=="string"?n.content:n.content!=null?JSON.stringify(n.content):"";return Math.ceil(e.length/4)}function on(n){let e=0;for(let t of n)e+=sn(t);return e}function Rd(n){if(!n)return 128e3;if(n in Ki)return Ki[n];let e=n.toLowerCase();for(let[t,r]of Object.entries(Ki))if(e.startsWith(t.toLowerCase()))return r;return 128e3}function vv(){return X().resolveModelForPurpose("textGeneration")??kv}function Ad(){return zi}function Sv(n,e){return async(t,r)=>{let s=e?.transport,o=e?.apiKey;if(!s||!o)return n.debug("[context-compression] no LLM transport for summarization \u2014 using sync fallback"),Vi(t);try{let i="",a=e?.model??vv();for await(let c of s.stream({model:a,messages:[{role:"system",content:"You are a precise conversation summarizer."},{role:"user",content:r}],maxTokens:2e3,temperature:.3},o,AbortSignal.timeout(3e4)))c.type==="delta"&&(i+=c.text);return i||(n.warn("[context-compression] empty summary response"),Vi(t))}catch(i){return n.warn({err:i.message},"[context-compression] summarize call error \u2014 using fallback"),Vi(t)}}}function Vi(n){let e=[],t=n.filter(o=>o.role==="user"),r=t.slice(0,20).map(o=>{let i=typeof o.content=="string"?o.content:JSON.stringify(o.content??"");return`- [user]: ${i.slice(0,300)}${i.length>300?"...":""}`});e.push(`## User Requests (${t.length} messages)`),e.push(...r);let s=n.filter(o=>o.role==="assistant");if(s.length>0){let o=s.slice(0,10).map(i=>{let a=typeof i.content=="string"?i.content:JSON.stringify(i.content??"");return`- [assistant]: ${a.slice(0,150)}${a.length>150?"...":""}`});e.push("",`## Assistant Responses (${s.length} total)`),e.push(...o)}return e.join(`
|
|
25
|
+
`)}function Tv(){return Co(new rn(Xi),new Kt(20,sn),new vn(sn))}function Td(n,e){let t=Eo(new rn(Xi),new Kt(20,sn),new qn({protectedHeadExchanges:1,protectedTailMessages:8,summarize:n,estimateTokens:sn}),new vn(sn));return new Wn({inner:t,estimateTokens:sn,onCacheInvalidated:e?.onCacheInvalidated})}function xd(n,e){let t=e?.budget??Hr({modelContextWindow:Rd(e?.model)}),s=(e?.pipeline??Tv()).compress(n,t);if(s.droppedCount>0){let o=on(n),i=on(s.messages);wd.record({timestamp:Date.now(),strategy:s.strategy,tokensBefore:o,tokensAfter:i,droppedCount:s.droppedCount,latencyMs:s.metrics?.latencyMs??0,usedLlm:!1,cacheInvalidated:s.metrics?.cacheInvalidated??!1,tier:zn(o,t)})}return s.droppedCount>0&&Yi?.(s.droppedCount,on(s.messages)),s}async function Rv(n,e,t){let r=t??Hr({modelContextWindow:Rd(e.model)}),s=on(n),o=zn(s,r),i;switch(o){case"none":i={messages:n,droppedCount:0,strategy:"none"};break;case"trim-only":i=new rn(Xi).compress(n,r);break;case"sliding-window":{i=await Td(e.summarize).compressAsync(n,r);break}case"llm-summarize":{let a=e.pipeline??Td(e.summarize);i=Vn(a)?await a.compressAsync(n,r):a.compress(n,r);break}}return i.droppedCount>0&&(i={...i,messages:await Do(i.messages,n,{maxFiles:5,maxTokenBudget:5e4,readFile:async a=>{try{return await bv(a,"utf-8")}catch{return null}}})}),wv(n,i,r),i}function wv(n,e,t){if(e.droppedCount>0||e.metrics?.usedLlm){let r=e.metrics?.tokensBefore||on(n),s=e.metrics?.tokensAfter||on(e.messages);wd.record({timestamp:Date.now(),strategy:e.strategy,tokensBefore:r,tokensAfter:s,droppedCount:e.droppedCount,latencyMs:e.metrics?.latencyMs??0,usedLlm:e.metrics?.usedLlm??!1,cacheInvalidated:e.metrics?.cacheInvalidated??!1,tier:zn(r,t)})}if(e.droppedCount>0){let r=e.metrics?.tokensAfter||on(e.messages);Yi?.(e.droppedCount,r)}}function Av(n,e){let t=Sv(n,e),r={id:"builtin-compressor",label:"4-Layer Compression Funnel (built-in)",async compressAsync(s,o,i){return Rv(s,{budget:o,model:i?.model,sessionId:i?.sessionId,summarize:t},o)}};zi.register(r),zi.activate(r.id),n.info(`[context-compression] registered context engine: ${r.id}`)}function Pd(n,e,t){Av(e,t),n.register({point:"context.before_compact",priority:50,label:"context-compression-bridge",handler:(r,s)=>{let o=s.messageCount;return o&&o>0&&e.debug(`[context-compression] before_compact: ${o} messages entering compression`),{action:"continue"}}}),Yi=(r,s)=>{e.debug(`[context-compression] after_compact: removed ${r}, ${s} tokens remaining`),n.invoke("context.after_compact",{sessionId:"",turnId:"",removedCount:r,tokenCount:s}).catch(()=>{})}}var Ki,Xi,kv,wd,zi,Yi,Ji=Q(()=>{"use strict";Yn();dt();Ki={"deepseek-v4-flash":1e6,"deepseek-v4-pro":1e6,"deepseek-chat":1e6,"deepseek-reasoner":1e6,"gpt-4o":128e3,"gpt-4o-mini":128e3,"claude-sonnet-4-20250514":2e5,"claude-3-5-haiku-20241022":2e5,"gemini-3.1-pro-preview":1e6,"gemini-3-flash-preview":1e6,"gemini-3.1-flash-lite":1e6};Xi=8e3,kv="deepseek-v4-flash";wd=new Gn(200),zi=new Kn;Yi=null});function Id(n,e,t){let r=t-e;return`[Budget] ${Math.round(n)}% used (${e.toLocaleString()} / ${t.toLocaleString()} tokens). ${r.toLocaleString()} tokens remaining. `+(n>=90?"Wrap up your current taskyou are near the token limit.":"Continue workingdo not summarize prematurely.")}var _d=Q(()=>{"use strict"});var Cd={};Zt(Cd,{resolveToolEligibility:()=>Cv});function Pv(n,e){if(xv.some(t=>t.test(n)))return!0;if(e)for(let t of e)try{if(new RegExp(t,"i").test(n))return!0}catch{}return!1}function Iv(n,e){let t=n.function.name,r=n.meta,s=[];return e.blockedToolNames?.includes(t)?(s.push("policy_blocked"),{level:5,reasons:s}):r?.isReadOnly?(s.push("always_allowed"),{level:1,reasons:s}):r?.requiresApproval?(s.push("approval_required"),{level:4,reasons:s}):r?.isDangerous||Pv(t,e.dangerousPatterns)?(s.push("dangerous_tool"),{level:3,reasons:s}):{level:2,reasons:s}}function _v(n){switch(n){case 1:return"eligible";case 2:return"eligible";case 3:return"dangerous-notify";case 4:return"approval-required";case 5:return"blocked-by-policy"}}function Cv(n,e={}){let t=new Map,r=[],s=[],o=[];for(let i of n){let a=i.function.name,{level:c,reasons:l}=Iv(i,e),u=_v(c),d={toolName:a,status:u,permissionLevel:c,approvalRequired:c===4,reasonCodes:l};t.set(a,d),c===5?s.push(d):(r.push(i),c===4&&o.push(d))}return{eligibleTools:r,blockedTools:s,approvalRequiredTools:o,eligibilityByName:t}}var xv,Ed=Q(()=>{"use strict";xv=[/^(?:bash|shell|exec|terminal|run_command)$/i,/^(?:write_file|delete_file|move_file|create_directory)$/i,/^(?:git_push|git_reset|git_force)$/i]});import{accumulateToolCalls as Dv}from"@xiaozhiclaw/provider-core";function Ov(n){let e=n.split(".").pop()?.toLowerCase()??"";return["png","jpg","jpeg","gif","webp","svg","bmp","ico"].includes(e)?"image":["md","txt","pdf","doc","docx","rtf","html"].includes(e)?"document":["mermaid","mmd","dot","puml","plantuml"].includes(e)?"diagram":["csv","tsv","xlsx","xls"].includes(e)?"table":["ts","tsx","js","jsx","py","rs","go","java","c","cpp","h","cs","rb","sh","sql","json","yaml","yml","toml","xml","css","scss","vue","svelte"].includes(e)?"code":"file"}function Lv(n){let e=n.split(".").pop()?.toLowerCase()??"";return{ts:"typescript",tsx:"typescriptreact",js:"javascript",jsx:"javascriptreact",py:"python",rs:"rust",go:"go",java:"java",c:"c",cpp:"cpp",h:"c",cs:"csharp",rb:"ruby",sh:"shellscript",sql:"sql",json:"json",yaml:"yaml",yml:"yaml",toml:"toml",xml:"xml",html:"html",css:"css",scss:"scss",vue:"vue",svelte:"svelte",md:"markdown"}[e]}function Uv(n){if(!jv.has(n.toolName))return!1;let e=typeof n.message?.content=="string"?n.message.content.trim():"";return e.length>0&&e.length<200&&$v.test(e)}function Md(n,e){for(let t=n.length-1;t>=0;t--){let r=n[t];if(!r||r.role!=="tool")continue;let s=typeof r.content=="string"?r.content:"";if(s.startsWith("Error: "))return s.slice(7).trim()}}function Fv(n){return typeof n=="number"&&Number.isFinite(n)&&n>=1?Math.min(Math.round(n),100):Uo}function Dd(n){let e=n.message.toLowerCase();return n.status===413||e.includes("prompt_too_long")||e.includes("context_length_exceeded")||e.includes("maximum context length")}function Bv(n){return n==="length"||n==="max_tokens"}function Nd(n){let e=n.message.toLowerCase();return(e.includes("image")||e.includes("media")||e.includes("file too large")||e.includes("payload too large"))&&(n.status===413||e.includes("too large")||e.includes("size"))}function Hv(n){let e=n.headers;if(!e)return null;let t=e["retry-after"]??e["Retry-After"];if(!t)return null;let r=parseInt(t,10);return!isNaN(r)&&r>0?r*1e3:null}function qv(n){if(n.status!==400)return null;let e=n.message.match(/input length and `max_tokens` exceed context limit: (\d+) \+ (\d+) > (\d+)/);if(!e?.[1]||!e?.[3])return null;let t=parseInt(e[1],10),r=parseInt(e[3],10);if(isNaN(t)||isNaN(r))return null;let s=r-t-1e3;return s>=3e3?s:null}function Wv(n){return n.filter(e=>e.role!=="assistant"?!0:!(typeof e.content=="string"&&e.content.trim()===""))}async function*Od(n,e,t,r){let{turnId:s,sessionId:o,messages:i,tools:a,model:c,apiKey:l,temperature:u=0,hooks:d,signal:p}=n,m={sessionId:o,turnId:s},h=n.maxTurns??0,f=n.querySource,{resolveToolEligibility:y}=await Promise.resolve().then(()=>(Ed(),Cd)),b=y(a,n.toolEligibilityContext),T=b.eligibleTools;for(let j of b.blockedTools)yield{type:"tool_blocked",turnId:s,callId:"",name:j.toolName,reason:"blocked-by-policy"};if(!T.length){yield*Gv(s,c,i,l,u,p,e,r);return}let w=Fv(n.maxRounds),_={contextWindowTokens:n.contextWindowTokens??Ho,responseBufferTokens:qo,maxOutputTokens:n.maxOutputTokens??Wo,abortSignal:p,reactiveCompactEnabled:!0,outputEscalationEnabled:!0},I=new Set,D=0,L=T,F,S={messages:[...i],maxOutputTokensRecoveryCount:0,hasAttemptedReactiveCompact:!1,maxOutputTokensOverride:void 0,turnCount:1,transition:void 0,guardState:Ui(_),reactiveCompactState:Wi(),toolLoopState:Xr({maxRounds:w,replayMessages:[...i]}).state,consecutiveFailedRounds:0,finalText:"",totalUsage:{inputTokens:0,outputTokens:0},collapseStore:Lo(),currentModel:c,consecutive529Errors:0,consecutiveApiRetries:0,stopHookActive:void 0,lastResponseId:void 0,snipRemovedIds:new Set,contentReplacementState:nd(),budgetContinuationCount:0,lastBudgetDeltaTokens:0,lastBudgetGlobalTokens:0,identicalCallCounts:new Map,toolFailureCounts:new Map,fileReadCounts:new Map},ce=Math.max(h*5,200),le=0;for(;;){if(le++,le>ce){r.info(`hard iteration cap reached (${ce}), forcing completion`);let P=S.finalText||er(S.messages,r);yield{type:"end",turnId:s,content:P,usage:S.totalUsage,model:S.currentModel};return}let{messages:j,maxOutputTokensRecoveryCount:ke,hasAttemptedReactiveCompact:oe,maxOutputTokensOverride:$e,turnCount:te,guardState:Y,reactiveCompactState:R,collapseStore:B}=S,{toolLoopState:U}=S;if(F){try{let P=await F;P&&(yield{type:"tool_use_summary",turnId:s,summary:P})}catch{}F=void 0}if(n.refreshTools&&te>1){let P=n.refreshTools();P!==L&&(L=P,r.debug(`tools refreshed: ${P.length} tools`))}if(qi(Y,_)){r.info(`turn aborted by guard at turn ${te}`),yield{type:"error",turnId:s,error:"Turn aborted",code:"ABORTED",usage:S.totalUsage};return}let we=Fi(Y,_);if(we.level==="blocking"){we.reason==="prompt_too_long"&&Tn(R)&&(R.attemptedThisTurn=!0,Y.hasAttemptedReactiveCompact=!0,r.info(`token budget blocking (${we.reason}), reactive compact needed`),yield{type:"recovery",turnId:s,action:"reactive_compact",detail:"token budget pre-check"}),r.info(`token budget blocking (${we.reason}), ending tool loop`);break}we.level==="warning"&&r.info(`token budget warning: ${we.usagePercent}% used, ${we.remainingTokens} remaining`);let fe;{let P=await cd(j,S.contentReplacementState,o);fe=P.messages,P.newlyReplacedCount>0&&(r.info(`tool-result-budget: persisted ${P.newlyReplacedCount} oversized tool results`),yield{type:"recovery",turnId:s,action:"tool_result_budget",detail:`${P.newlyReplacedCount} persisted`})}{let P=No(fe,S.snipRemovedIds);fe=P.messages,P.removedCount>0&&(r.info(`snip: removed ${P.removedCount} messages, freed ~${P.tokensFreed} tokens`),yield{type:"recovery",turnId:s,action:"snip",detail:`${P.removedCount} messages`})}{let E=new Kt().compress(fe,0);E.droppedCount>0&&(fe=E.messages,r.info(`microcompact: cleared ${E.droppedCount} old tool results`))}if(fe=$o(fe,B).messages,Y.promptTokens>0){let P=_.contextWindowTokens*.75,E=Ad().getActive(),O;E?O=await E.compressAsync(fe,P,{model:S.currentModel,sessionId:o}):O=xd(fe,{budget:P,model:S.currentModel}),O.droppedCount>0&&(fe=O.messages,r.info(`autocompact: ${O.strategy}, dropped ${O.droppedCount}`),yield{type:"recovery",turnId:s,action:"autocompact",detail:`${O.strategy}: ${O.droppedCount} dropped`},S.hasAttemptedReactiveCompact=!1,d?.invoke("context.after_compact",{...m,removedCount:O.droppedCount}).catch(()=>{}))}fe=Wv(fe);let Et=xi({tools:L,toolChoice:n.toolChoice??"auto"}),g=Xr({maxRounds:w,replayMessages:fe,lastStopReason:U.lastStopReason,options:{stopReason:U.lastStopReason}}),v=Et.extraSystemPrompt?[{role:"system",content:Et.extraSystemPrompt},...g.state.replayMessages]:g.state.replayMessages;U=g.state,g.recoveryActions.length>0&&r.debug(`tool loop recovery: ${g.recoveryActions.map(P=>P.detail??P.kind).join("; ")}`),r.debug(`turn ${te}, messages: ${v.length}`),d?.invoke("turn.before_inference",{...m,model:S.currentModel}).catch(()=>{});let x=!1,C=[],A=new Map,$="stop",N,M=null,W=!1,ie=[],Z=[];try{for await(let P of e.stream({model:S.currentModel,messages:v,tools:Et.tools,toolChoice:Et.normalizedToolChoice??"auto",temperature:u,maxTokens:($e??Y.currentMaxOutputTokens)||void 0,streamRequired:n.streamRequired,previousResponseId:S.lastResponseId,reasoning:n.reasoning,promptCacheKey:n.promptCacheKey,promptCacheRetention:n.promptCacheRetention,serviceTier:n.serviceTier,openaiBuiltinTools:n.openaiBuiltinTools,maxToolCalls:n.maxToolCalls,parallelToolCalls:n.parallelToolCalls,textVerbosity:n.textVerbosity},l,p))switch(P.type){case"delta":C.push(P.text),x||(yield{type:"delta",turnId:s,text:P.text});break;case"tool_call_delta":x=!0,Dv(A,P);break;case"reasoning_delta":ie.push(P.text);break;case"reasoning_block_complete":P.signature&&Z.push({thinking:ie.join(""),signature:P.signature}),ie.length=0;break;case"usage":N={inputTokens:P.promptTokens,outputTokens:P.completionTokens,reasoningTokens:P.reasoningTokens,cacheRead:P.cacheReadTokens,cacheWrite:P.cacheCreationTokens};break;case"response_id":S.lastResponseId=P.id;break;case"annotations":yield{type:"annotations",turnId:s,annotations:P.annotations};break;case"builtin_tool_status":yield{type:"heartbeat",turnId:s,message:`${P.toolType}: ${P.event}`};break;case"done":$=P.finishReason;break}if(x||d?.invoke("turn.after_inference",{...m,model:S.currentModel}).catch(()=>{}),n.postSamplingHooks&&n.postSamplingHooks.length>0){let P=S.currentModel;for(let E of n.postSamplingHooks)try{E({messages:[...fe],model:P,sessionId:o})}catch{}}}catch(P){if(P instanceof Xn&&n.fallbackModel){r.info(`model fallback triggered: ${P.originalModel} \u2192 ${P.fallbackModel}`),yield{type:"recovery",turnId:s,action:"model_fallback",detail:`${P.originalModel} \u2192 ${P.fallbackModel}`},S={...S,currentModel:P.fallbackModel,consecutive529Errors:0,consecutiveApiRetries:0,transition:void 0};continue}let E=P instanceof Error?P.message:String(P),O=typeof P?.status=="number"?P.status:void 0;if(!O&&E&&(E.includes("ECONNRESET")||E.includes("EPIPE"))){let re=(S.consecutiveApiRetries??0)+1;if(re>Sn){r.info(`stale connection retry limit reached (${Sn}), aborting`),yield{type:"error",turnId:s,error:E,code:"RETRIES_EXHAUSTED",usage:S.totalUsage};return}r.info(`stale connection (${E.includes("ECONNRESET")?"ECONNRESET":"EPIPE"}): retrying`),yield{type:"recovery",turnId:s,action:"stale_connection_retry",detail:E.slice(0,80)},S={...S,consecutiveApiRetries:re,transition:void 0};continue}let H=qv({status:O,message:E});if(H!==null){r.info(`max_tokens overflow: adjusting to ${H}`),Y.currentMaxOutputTokens=H,S={...S,maxOutputTokensOverride:H,transition:void 0};continue}if(Ni(O)){S.consecutive529Errors++;let re=2,Ae=n.fallbackModel&&S.currentModel!==n.fallbackModel;if(S.consecutive529Errors>re&&!Ae&&!Jr()){r.info(`transient ${O} \xD7 ${S.consecutive529Errors}: hard limit reached, aborting`),yield{type:"error",turnId:s,error:`API unavailable after ${S.consecutive529Errors} consecutive ${O} errors`,code:"API_ERROR",usage:S.totalUsage};return}if(S.consecutive529Errors>=Qo&&n.fallbackModel&&S.currentModel!==n.fallbackModel){r.info(`529 \xD7 ${S.consecutive529Errors}: triggering fallback to ${n.fallbackModel}`),yield{type:"recovery",turnId:s,action:"model_fallback",detail:`529 \xD7 ${S.consecutive529Errors}`},S={...S,currentModel:n.fallbackModel,consecutive529Errors:0,transition:void 0};continue}if(Jr()){let J=Yr(S.consecutive529Errors);r.info(`persistent retry: waiting ${J}ms (attempt ${S.consecutive529Errors})`);let he=J;for(;he>0;){if(p?.aborted){yield{type:"error",turnId:s,error:"Aborted during retry wait",code:"ABORTED",usage:S.totalUsage};return}yield{type:"heartbeat",turnId:s,message:`Retrying in ${Math.ceil(he/1e3)}s (${O})`};let ot=Math.min(he,Jo);await new Promise(Ao=>setTimeout(Ao,ot)),he-=ot}S={...S,transition:void 0};continue}if(Di(f)){let he=Hv({status:O,message:E})??Yr(S.consecutive529Errors);r.info(`transient ${O}: retry in ${he}ms`),yield{type:"recovery",turnId:s,action:"retry",detail:`${O} retry in ${he}ms`},await new Promise(ot=>setTimeout(ot,he)),S={...S,transition:void 0};continue}r.info(`background source ${f}: not retrying ${O}`)}M={status:O,message:E}}if(M&&d?.invoke("turn.after_inference",{...m,model:S.currentModel,response:{error:M.message}}).catch(()=>{}),M)if(Dd(M))W=!0,r.info(`withheld prompt_too_long error (status=${M.status})`);else if(Nd(M))W=!0,r.info(`withheld media_size error (status=${M.status})`);else{let P=Bi({status:M.status??500,message:M.message},Y,_);if(P.action==="reactive_compact"&&Tn(R)&&(R.attemptedThisTurn=!0,Y.hasAttemptedReactiveCompact=!0,yield{type:"recovery",turnId:s,action:"reactive_compact",detail:`API ${M.status??500}: ${M.message}`}),P.action==="retry"){let O=(S.consecutiveApiRetries??0)+1;if(O>Sn){r.info(`API retry limit reached (${Sn}), aborting`);let H=kn(M.status,M.message);yield{type:"error",turnId:s,error:M.message,code:H,usage:S.totalUsage};return}yield{type:"recovery",turnId:s,action:"retry",detail:P.reason},S={...S,consecutiveApiRetries:O,transition:void 0};continue}let E=kn(M.status,M.message);d?.invoke("stop.failure",{sessionId:o,reason:E,error:M.message}).catch(()=>{}),yield{type:"error",turnId:s,error:M.message,code:E,usage:S.totalUsage};return}N&&(S.totalUsage.inputTokens+=N.inputTokens,S.totalUsage.outputTokens+=N.outputTokens,N.reasoningTokens&&(S.totalUsage.reasoningTokens=(S.totalUsage.reasoningTokens??0)+N.reasoningTokens),N.cacheRead&&(S.totalUsage.cacheRead=(S.totalUsage.cacheRead??0)+N.cacheRead),N.cacheWrite&&(S.totalUsage.cacheWrite=(S.totalUsage.cacheWrite??0)+N.cacheWrite)),N?.inputTokens&&(Y.promptTokens=N.inputTokens);let ne=C.join("");ne&&(S.finalText=ne);let pe=[...A.values()].map(P=>({id:P.id||`tc_${s}_${te}_${Math.random().toString(36).slice(2,8)}`,type:"function",function:{name:P.name,arguments:P.arguments}}));if(pe.length===0&&!x){if(W&&M&&Dd(M)){if(S.transition?.reason!=="collapse_drain_retry"){let O=jo(fe,B);if(O.committed>0){r.info(`collapse drain: committed ${O.committed} stages`),yield{type:"recovery",turnId:s,action:"collapse_drain",detail:`${O.committed} stages committed`},S={...S,messages:O.messages,transition:{reason:"collapse_drain_retry",committed:O.committed}};continue}}if(Tn(R)){R.attemptedThisTurn=!0,Y.hasAttemptedReactiveCompact=!0,r.info("withheld 413: reactive compact attempt"),yield{type:"recovery",turnId:s,action:"reactive_compact",detail:"withheld prompt_too_long"},S={...S,hasAttemptedReactiveCompact:!0,transition:{reason:"reactive_compact_retry"}};continue}r.info("withheld 413: recovery exhausted, surfacing error"),d?.invoke("stop.failure",{sessionId:o,reason:"prompt_too_long",error:M.message}).catch(()=>{}),yield{type:"error",turnId:s,error:M.message,code:"PROMPT_TOO_LONG",usage:S.totalUsage};return}if(W&&M&&Nd(M)){if(Tn(R)){R.attemptedThisTurn=!0,Y.hasAttemptedReactiveCompact=!0,r.info("withheld media error: reactive compact strip-retry"),yield{type:"recovery",turnId:s,action:"reactive_compact",detail:"media error strip-retry"},S={...S,hasAttemptedReactiveCompact:!0,transition:{reason:"reactive_compact_retry"}};continue}r.info("withheld media error: recovery exhausted"),d?.invoke("stop.failure",{sessionId:o,reason:"media_error",error:M.message}).catch(()=>{}),yield{type:"error",turnId:s,error:M.message,code:"IMAGE_ERROR",usage:S.totalUsage};return}if(Bv($)){Y.consecutiveTruncations+=1;let O=n.modelMaxOutputTokens??Go,H=Hi(Y,_,O);if(H.shouldEscalate&&$e===void 0){Y.currentMaxOutputTokens=H.newMax,r.info(`max_output_tokens escalate: ${H.newMax} tokens`),yield{type:"recovery",turnId:s,action:"output_escalation",detail:`${H.newMax} tokens`},S={...S,maxOutputTokensOverride:Vo,transition:{reason:"max_output_tokens_escalate"}};continue}if(ke<Ko){let re={role:"user",content:"Output token limit hit. Resume directly \u2014 no apology, no recap of what you were doing. Pick up mid-thought if that is where the cut happened. Break remaining work into smaller pieces."};r.info(`max_output_tokens recovery #${ke+1}`),yield{type:"recovery",turnId:s,action:"max_output_tokens_recovery",detail:`attempt ${ke+1}`},S={...S,messages:[...fe,re],maxOutputTokensRecoveryCount:ke+1,maxOutputTokensOverride:void 0,transition:{reason:"max_output_tokens_recovery",attempt:ke+1}};continue}r.info("max_output_tokens recovery exhausted, completing with partial content")}else Y.consecutiveTruncations=0;if(U=zr(U,{replayMessages:j,lastStopReason:"completed"}),d){let O=await d.invoke("stop",{sessionId:o,reason:"completed"});if(O.action==="prevent"){r.info(`stop hook prevented continuation: ${O.reason??"no reason"}`),yield{type:"end",turnId:s,content:S.finalText,usage:S.totalUsage,model:S.currentModel};return}if(O.action==="abort"){let H=O.reason??"Stop hook requested continuation";r.info(`stop hook blocking: ${H}`);let re={role:"user",content:H},Ae={role:"assistant",content:S.finalText,...Z.length>0&&{thinkingBlocks:[...Z]}};S={...S,messages:[...j,Ae,re],stopHookActive:!0,transition:{reason:"stop_hook_blocking"}};continue}}if(n.tokenBudget&&n.tokenBudget>0&&S.budgetContinuationCount<5){let O=S.totalUsage.inputTokens+S.totalUsage.outputTokens+(S.totalUsage.reasoningTokens??0),H=O/n.tokenBudget*100,re=O-S.lastBudgetGlobalTokens,Ae=S.budgetContinuationCount>=zo&&re<Wr&&S.lastBudgetDeltaTokens<Wr;if(Ae&&r.info(`token budget early stop: diminishing returns at ${Math.round(H)}% (delta=${re})`),!Ae&&H<90){let J=S.budgetContinuationCount+1,he={role:"user",content:Id(H,O,n.tokenBudget)};r.info(`token budget continuation #${J}: ${Math.round(H)}% used`),yield{type:"recovery",turnId:s,action:"budget_continuation",detail:`${Math.round(H)}% used (#${J})`};let ot={role:"assistant",content:S.finalText,...Z.length>0&&{thinkingBlocks:[...Z]}};S={...S,messages:[...j,ot,he],budgetContinuationCount:J,lastBudgetDeltaTokens:re,lastBudgetGlobalTokens:O,transition:{reason:"token_budget_continuation"}};continue}}if(!S.stopHookActive){let O=i.find(J=>J.role==="user"),H=typeof O?.content=="string"?O.content:"",re=/创建文件|生成文件|写入|写一个|建一个|新建|重写|改写|create\s+(a\s+)?file|write\s+(a\s+)?file|make\s+(a\s+)?file|修改|改成|把.*改|文件名叫/i.test(H),Ae=I.has("write")||I.has("edit");if(re&&!Ae){if(r.info("AP1 action-verification: user requested file action but no write/edit tool was called, injecting nudge"),D>0){let ot=[...j].reverse().find(Ao=>Ao.role==="tool");ot&&typeof ot.content=="string"&&(ot.content+=`
|
|
26
26
|
|
|
27
|
-
\u26A0\uFE0F NOTE: You used shell commands but did not call the write or edit tool to create/modify the file. Shell commands may fail silently or produce incorrect results on this platform. Please use the 'write' tool directly to create the requested file with the correct content.`)}let J={role:"user",content:D===0?"You described what to do but did not actually call any tool to write or edit a file. Please use the write or edit tool now to perform the requested action. Do not just describe the changes \u2014 actually make them.":"You used shell commands but did not call the write or edit tool to create/modify the file. Shell commands may fail on this platform. Please use the write tool directly to create the requested file with the correct content."},he={role:"assistant",content:
|
|
27
|
+
\u26A0\uFE0F NOTE: You used shell commands but did not call the write or edit tool to create/modify the file. Shell commands may fail silently or produce incorrect results on this platform. Please use the 'write' tool directly to create the requested file with the correct content.`)}let J={role:"user",content:D===0?"You described what to do but did not actually call any tool to write or edit a file. Please use the write or edit tool now to perform the requested action. Do not just describe the changes \u2014 actually make them.":"You used shell commands but did not call the write or edit tool to create/modify the file. Shell commands may fail on this platform. Please use the write tool directly to create the requested file with the correct content."},he={role:"assistant",content:S.finalText,...Z.length>0&&{thinkingBlocks:[...Z]}};S={...S,messages:[...j,he,J],stopHookActive:!0,transition:{reason:"stop_hook_blocking"}};continue}}if(!S.stopHookActive&&D>=3&&I.has("write")){let O=0;for(let H of j){let re=H,Ae=re.is_error===!0||typeof re.content=="string"&&re.content.startsWith("Error:");re.role==="tool"&&typeof re.content=="string"&&!Ae&&O++}if(O>=3){r.info("AP3 verification nudge: 3+ files created, injecting completeness check");let H={role:"user",content:"You created multiple files. Before completing, verify: (1) All imports between your files resolve to real exports. (2) No TODO, placeholder, or 'not implemented' stubs remain. (3) Functions that are imported are actually called, not just declared. If everything is correct, confirm completion. If not, fix the issues now."},re={role:"assistant",content:S.finalText,...Z.length>0&&{thinkingBlocks:[...Z]}};S={...S,messages:[...j,re,H],stopHookActive:!0,transition:{reason:"stop_hook_blocking"}};continue}}if(D>0){let O={ok:!0,toolCallCount:D,distinctToolCount:I.size,multiStep:D>=2,hasSubAgent:!1,feedback:null,existingSkillName:null},H=Vr(O,{tools:[...I],projectRoot:n.projectRoot});H&&(yield{type:"skill_instruction",turnId:s,instruction:H})}let E=S.finalText||er(j,r);yield{type:"end",turnId:s,content:E,usage:S.totalUsage,model:S.currentModel};return}let He=Z.length===0&&ie.length>0?ie.join(""):void 0;j.push(Po(pe,S.finalText||void 0,Z.length>0?Z:void 0,He)),U=Mi(U,{replayMessages:j,pendingToolCallIds:pe.map(P=>P.id),completedToolCallIds:U.completedToolCallIds,lastStopReason:"tool_calls"});let Ee=S.identicalCallCounts,Wt=[],ge=[],Mt=!1;for(let P of pe){let E=`${P.function.name}::${P.function.arguments}`,O=Ee.get(E)??0;Ee.set(E,O+1),O+1>Bo?(ge.push(P),Mt||(Mt=!0,r.info(`AP4 blocked: ${P.function.name} repeated ${O+1}x`))):Wt.push(P)}let St=[];for(let P of ge){let E=Ee.get(`${P.function.name}::${P.function.arguments}`),O=Md(j,P.function.name),H=O?`This exact tool call has been attempted ${E} times. Last error: ${O}. Do not retry. Report this error to the user.`:`This exact tool call has been attempted ${E} times and keeps failing. Do not retry it. Report the issue to the user or try a completely different approach.`,re=Gt(P.id,{ok:!1,error:H});j.push(re),St.push(P.id),I.add(P.function.name),D++,yield{type:"tool_result",turnId:s,callId:P.id,name:P.function.name,ok:!1,error:H}}if(ge.length>0){let P=Md(j,ge[0].function.name),E={role:"user",content:"Tool calls were blocked because you repeated them with identical arguments too many times. "+(P?`The error was: "${P}". Tell the user about this error. `:"The operation is not working. ")+"Stop retrying and report the result to the user."};j.push(E)}let Ge=[],Ro=[];for(let P of Wt)(S.toolFailureCounts.get(P.function.name)??0)>=qr?Ro.push(P):Ge.push(P);if(Ro.length>0){for(let E of Ro){let O=S.toolFailureCounts.get(E.function.name),H=`Tool "${E.function.name}" has failed ${O} times this turn with different arguments. The target likely does not exist. Stop trying variations and report the issue to the user.`,re=Gt(E.id,{ok:!1,error:H});j.push(re),St.push(E.id),I.add(E.function.name),D++,yield{type:"tool_result",turnId:s,callId:E.id,name:E.function.name,ok:!1,error:H},r.info(`AP4-variant blocked: ${E.function.name} failed ${O}x with different args`)}let P={role:"user",content:"Tool calls were blocked because the tool has failed too many times with different arguments. The resource you are looking for does not exist. Stop trying variations and tell the user what happened."};j.push(P)}for(let P of Ge){let E=P.function.arguments,O=L.find(H=>H.function.name===P.function.name);if(O?.backfillObservableInput)try{let H=JSON.parse(P.function.arguments),re={...H};O.backfillObservableInput(re),Object.keys(re).some(J=>!(J in H))&&(E=JSON.stringify(re))}catch{}yield{type:"tool_call",turnId:s,callId:P.id,name:P.function.name,arguments:E}}let ub=new Map(S.toolFailureCounts);try{let P=new Zr({toolInvoker:t,hooks:d,sessionId:o,turnId:s,log:r,signal:p,maxConcurrentTools:n?.maxConcurrentTools});for(let E of Ge)P.addTool(E);for await(let E of P.getRemainingResults()){E.blocked&&(yield{type:"tool_blocked",turnId:s,callId:E.callId,name:E.toolName,reason:E.blockReason??"blocked"}),j.push(E.message),St.push(E.callId),I.add(E.toolName),D++;let O=E.ok&&Uv(E);if(!E.ok||O){let J=(S.toolFailureCounts.get(E.toolName)??0)+1;S.toolFailureCounts.set(E.toolName,J)}if(E.ok&&E.toolName==="read"){let Ae=Ge.find(J=>J.id===E.callId);if(Ae)try{let J=JSON.parse(Ae.function.arguments),he=J.file_path??J.path??J.filePath??"";if(he){let ot=S.fileReadCounts.get(he)??0;S.fileReadCounts.set(he,ot+1)}}catch{}}let H=typeof E.message?.content=="string"?E.message.content:"",re=E.ok&&H?H.slice(0,2e3):void 0;if(yield{type:"tool_result",turnId:s,callId:E.callId,name:E.toolName,ok:E.ok,error:E.error,outputPreview:re},E.ok){let Ae=pe.find(J=>J.id===E.callId);if(Ae){if(E.toolName==="plan_mode")try{let J=JSON.parse(Ae.function.arguments);J.action==="exit"&&typeof J.plan=="string"&&J.plan.length>0&&(yield{type:"plan_update",turnId:s,slug:"approved-plan",content:J.plan})}catch{}if(Nv.has(E.toolName))try{let J=JSON.parse(Ae.function.arguments),he=typeof J.file_path=="string"?J.file_path:typeof J.filePath=="string"?J.filePath:typeof J.path=="string"?J.path:void 0;he&&(yield{type:"artifact",turnId:s,artifactId:`artifact-${E.callId}`,artifactType:Ov(he),title:he.split(/[\\/]/).pop()||he,filePath:he,language:Lv(he)})}catch{}}}}}catch(P){let E=P instanceof Error?P.message:String(P);yield{type:"error",turnId:s,error:E,code:"TOOL_EXECUTION_ERROR",usage:S.totalUsage};return}for(let[P,E]of S.toolFailureCounts)E>=qr&&(ub.get(P)??0)<qr&&j.push({role:"user",content:`Tool "${P}" has now failed/returned empty results ${E} times with different arguments. The target clearly does not exist. Do NOT call "${P}" again. Report the result to the user immediately.`});if(U=zr(U,{replayMessages:j,completedToolCallIds:[...U.completedToolCallIds,...St],lastStopReason:"tool_calls"}),n.generateToolUseSummary&&pe.length>0){let P=pe.map(E=>({name:E.function.name,arguments:E.function.arguments}));F=n.generateToolUseSummary(P).catch(()=>null)}let pb=pe.length>0&&pe.every(P=>{let E=j.find(H=>H?.role==="tool"&&H?.tool_call_id===P.id);if(!E)return!0;let O=E.content;return typeof O=="string"&&O.startsWith("Error: ")}),Hn=S.consecutiveFailedRounds;if(pb){if(Hn+=1,Hn>=Fo){let P=S.finalText||er(j,r);r.info(`early exit: ${Hn} consecutive failed rounds, returning ${S.finalText?"partial":"fallback"} response`),yield{type:"end",turnId:s,content:P,usage:S.totalUsage,model:S.currentModel};return}}else Hn=0;let mb=3,hl=[...S.fileReadCounts.entries()].filter(([,P])=>P>=mb);if(hl.length>0){let P=hl.map(([O])=>O).join(", ");r.info(`AP5: file read cycle detected on ${P}, injecting nudge`);let E={role:"user",content:`You are reading the same files repeatedly (${P}). This indicates a circular dependency or cycle. Stop reading files, summarize your findings so far, and explain the circular structure to the user.`};j.push(E),S.fileReadCounts.clear()}let wo=te+1;if(h>0&&wo>h){if(r.info(`max turns reached (${h}), completing`),d){let E=await d.invoke("stop",{sessionId:o,reason:"max_turns"});if(E.action==="abort"){let O=E.reason??"Stop hook requested continuation after max_turns",H={role:"assistant",content:S.finalText,...Z.length>0&&{thinkingBlocks:[...Z]}};S={...S,messages:[...j,H,{role:"user",content:O}],stopHookActive:!0,transition:{reason:"stop_hook_blocking"}};continue}}let P=S.finalText||er(j,r);yield{type:"end",turnId:s,content:P,usage:S.totalUsage,model:S.currentModel};return}if(wo>w){if(r.info(`tool loop budget exhausted (${w} rounds), returning`),D>0){let E={ok:!0,toolCallCount:D,distinctToolCount:I.size,multiStep:D>=2,hasSubAgent:!1,feedback:null,existingSkillName:null},O=Vr(E,{tools:[...I],projectRoot:n.projectRoot});O&&(yield{type:"skill_instruction",turnId:s,instruction:O})}let P=S.finalText||er(j,r);yield{type:"end",turnId:s,content:P,usage:S.totalUsage,model:S.currentModel};return}S={messages:j,maxOutputTokensRecoveryCount:0,hasAttemptedReactiveCompact:!1,maxOutputTokensOverride:void 0,turnCount:wo,transition:{reason:"next_turn"},guardState:Y,reactiveCompactState:R,toolLoopState:U,consecutiveFailedRounds:Hn,finalText:S.finalText,totalUsage:S.totalUsage,collapseStore:B,currentModel:S.currentModel,consecutive529Errors:0,consecutiveApiRetries:0,stopHookActive:S.stopHookActive,lastResponseId:S.lastResponseId,snipRemovedIds:S.snipRemovedIds,contentReplacementState:S.contentReplacementState,budgetContinuationCount:0,lastBudgetDeltaTokens:0,lastBudgetGlobalTokens:0,identicalCallCounts:Ee,toolFailureCounts:S.toolFailureCounts,fileReadCounts:S.fileReadCounts}}}function er(n,e){let t=[];for(let r=n.length-1;r>=0;r--){let s=n[r];if(s.role==="tool"&&typeof s.content=="string")t.unshift(s.content.slice(0,500));else if(s.role==="assistant"){if(typeof s.content=="string"&&s.content.trim())return e.info("synthesizeFallbackContent: found assistant text, using it"),s.content;break}else break}return t.length>0?(e.info(`synthesizeFallbackContent: synthesized from ${t.length} tool result(s)`),t.join(`
|
|
28
28
|
|
|
29
29
|
`)):""}async function*Gv(n,e,t,r,s,o,i,a){let c=[],l;a.debug(`single LLM round, messages: ${t.length}`);for await(let u of i.stream({model:e,messages:t,temperature:s},r,o))switch(u.type){case"delta":c.push(u.text),yield{type:"delta",turnId:n,text:u.text};break;case"usage":l={inputTokens:u.promptTokens,outputTokens:u.completionTokens,reasoningTokens:u.reasoningTokens,cacheRead:u.cacheReadTokens,cacheWrite:u.cacheCreationTokens};break;case"done":break}yield{type:"end",turnId:n,content:c.join(""),usage:l??{inputTokens:0,outputTokens:0},model:e}}var Nv,$v,jv,Ld=Q(()=>{"use strict";Yn();ld();Ji();_d();Gi();je();Nv=new Set(["write","edit","patch","apply_patch"]);$v=/^no (matches|files|results) found\.?$|^file not found|^not found|^0 results|^\(exit code \d+, no output\)$/i,jv=new Set(["search","grep","glob","find","list","read","exec"])});function $d(n){if(!n||n.length<5)return{scenario:"general",preferred:[],deprioritized:[],confidence:0};let e=[];for(let[s,o]of Object.entries(Kv)){if(s==="general")continue;let i=o.filter(a=>a.test(n)).length;if(i>0){let a=Math.min(1,i/2);e.push({scenario:s,score:a})}}if(e.length===0)return{scenario:"general",preferred:[],deprioritized:[],confidence:0};e.sort((s,o)=>o.score-s.score);let t=e[0];if(t.score<.5)return{scenario:"general",preferred:[],deprioritized:[],confidence:t.score};let r=Vv[t.scenario];return{scenario:t.scenario,preferred:r.preferred,deprioritized:r.deprioritized,confidence:t.score}}function Qi(n,e,t){return!e||t.scenario==="general"?n:t.preferred.includes(e)?Math.min(1,n*1.2):t.deprioritized.includes(e)?n*.7:n}function jd(n){let e=n.replace(/\.md$/,"").toLowerCase();for(let[t,r]of Object.entries(zv))if(e.startsWith(t+"-")||e.startsWith(t+"_")||e===t)return r;return null}var Kv,Vv,zv,Zi=Q(()=>{"use strict";Kv={coding:[/(?:bug|error|fix|debug|报错|修复|编译|compile|build|lint)/i,/(?:implement|refactor|重构|实现|代码|code|function|method|class)/i,/(?:test|测试|vitest|jest|断言|assert)/i,/(?:type(?:script)?|接口|interface|generic|泛型)/i,/(?:import|export|module|依赖|package|npm|pnpm)/i,/(?:git|commit|branch|merge|rebase|PR|MR)/i],config:[/(?:deploy|部署|运维|docker|container|kubernetes|k8s)/i,/(?:port|端口|config|配置|env|环境变量|.env)/i,/(?:server|service|daemon|进程|systemd|nginx|redis)/i,/(?:版本|version|upgrade|migrate|迁移)/i,/(?:domain|域名|ssl|cert|证书|DNS)/i],conversation:[/(?:你好|hi|hello|hey|请问|问一下)/i,/(?:我(?:喜欢|偏好|习惯|想)|prefer|I (?:like|want|need))/i,/(?:帮我|help me|能不能|可以吗|would you)/i,/(?:style|风格|format|格式|命名|naming)/i],learning:[/(?:best practice|最佳实践|pattern|模式|惯例|convention)/i,/(?:怎么做|how to|how do|what's the|推荐|recommend)/i,/(?:为什么|why|原因|reason|explain|解释)/i,/(?:lesson|经验|教训|gotcha|pitfall|坑)/i],decision:[/(?:should|应该|选择|choose|decision|决定|trade-?off|权衡)/i,/(?:vs|versus|对比|compare|区别|difference)/i,/(?:architecture|架构|方案|approach|strategy)/i,/(?:pros|cons|优缺点|利弊|好处|坏处)/i],general:[]},Vv={coding:{preferred:["lesson","pattern","fact"],deprioritized:["preference"]},config:{preferred:["fact","decision","lesson"],deprioritized:["preference","skill-learning"]},conversation:{preferred:["preference","fact"],deprioritized:["pattern","skill-learning"]},learning:{preferred:["lesson","pattern","skill-learning"],deprioritized:["preference"]},decision:{preferred:["decision","fact","lesson"],deprioritized:["skill-learning","preference"]},general:{preferred:[],deprioritized:[]}};zv={lesson:"lesson",debug:"lesson",gotcha:"lesson",fix:"lesson",preference:"preference",style:"preference",pattern:"pattern",convention:"pattern",practice:"pattern",fact:"fact",config:"fact",architecture:"fact",env:"fact",deploy:"fact",decision:"decision",choice:"decision",skill:"skill-learning",workflow:"skill-learning"}});var Fd={};Zt(Fd,{Agent:()=>tr});var tr,ea=Q(()=>{"use strict";Yn();Ld();je();Zi();dt();tr=class{transport;apiKey;toolInvoker;log;hooks;maxRounds;projectRoot;constructor(e){this.transport=e.llmTransport,this.apiKey=e.apiKey,this.toolInvoker=e.toolInvoker,this.log=e.log,this.hooks=e.hooks,this.projectRoot=e.projectRoot,this.maxRounds=Math.min(e.maxRounds??25,100)}async*run(e,t){let{turnId:r,messages:s,tools:o,systemPrompt:i,config:a}=e,c={sessionId:e.sessionId,turnId:r};yield{type:"start",turnId:r},this.hooks?.invoke("turn.submitted",{...c,prompt:s[s.length-1]?.content??void 0}).catch(()=>{});let l=Ci(s),u=[];if(i&&u.push({role:"system",content:i}),u.push(...l),this.hooks){let m=l.filter(f=>f.role==="user").pop(),h=typeof m?.content=="string"?m.content.slice(0,500):void 0;if(h)try{let f=$d(h),y=await this.hooks.invoke("memory.before_recall",{sessionId:e.sessionId,turnId:r,query:h,preferredCategories:f.preferred.length>0?f.preferred:void 0,deprioritizedCategories:f.deprioritized.length>0?f.deprioritized:void 0}),b=y?.context?.recalledMemories;if(b&&b.length>0){let w=0,_=[];for(let I of b){let D=(I.text?.length??0)*2;if(w+D>8192)break;_.push(I),w+=D}if(_.length>0){let I=_.map(D=>`- ${D.text}`).join(`
|
|
30
30
|
`);u.splice(i?1:0,0,{role:"system",content:`[Recalled memories \u2014 context priority: project-specific facts override general user preferences when they conflict]
|
|
31
|
-
${I}`})}}this.hooks.invoke("memory.after_recall",{sessionId:e.sessionId,turnId:r,blockCount:y?.context?.recalledMemories?.length??0}).catch(()=>{})}catch{}}let d=a?.model??"",p=Math.min(a?.maxRounds??this.maxRounds,100);try{let m=async y=>{let b=X().resolveModelForPurpose("smallModel");if(!b)return null;try{let
|
|
31
|
+
${I}`})}}this.hooks.invoke("memory.after_recall",{sessionId:e.sessionId,turnId:r,blockCount:y?.context?.recalledMemories?.length??0}).catch(()=>{})}catch{}}let d=a?.model??"",p=Math.min(a?.maxRounds??this.maxRounds,100);try{let m=async y=>{let b=X().resolveModelForPurpose("smallModel");if(!b)return null;try{let T=y.map(I=>`${I.name}(${I.arguments.slice(0,200)})`).join(", "),w=this.transport.stream({model:b,messages:[{role:"system",content:"Summarize the tool usage in ~30 chars, git-commit-subject style. Reply with ONLY the summary, nothing else."},{role:"user",content:T}],tools:[],maxTokens:60},a?.apiKey??this.apiKey),_="";for await(let I of w)I.type==="delta"&&(_+=I.text);return _.trim()||null}catch{return null}},h={turnId:r,sessionId:e.sessionId,messages:u,tools:o,model:d,apiKey:a?.apiKey??this.apiKey,temperature:a?.temperature,maxRounds:p,contextWindowTokens:a?.contextWindowTokens,maxOutputTokens:a?.maxOutputTokens,modelMaxOutputTokens:a?.modelMaxOutputTokens,toolChoice:a?.toolChoice,parentDepth:a?.parentDepth,hooks:this.hooks,fallbackModel:a?.fallbackModel,maxTurns:a?.maxTurns,tokenBudget:a?.tokenBudget,maxConcurrentTools:a?.maxConcurrentTools,streamRequired:a?.streamRequired,reasoning:a?.reasoning,promptCacheKey:a?.promptCacheKey,promptCacheRetention:a?.promptCacheRetention,serviceTier:a?.serviceTier,openaiBuiltinTools:a?.openaiBuiltinTools,maxToolCalls:a?.maxToolCalls,parallelToolCalls:a?.parallelToolCalls,textVerbosity:a?.textVerbosity,projectRoot:this.projectRoot,generateToolUseSummary:m,signal:t},f;for await(let y of Od(h,this.transport,this.toolInvoker,this.log))f=y,yield y;f?.type==="end"?this.hooks?.invoke("turn.completed",{...c}).catch(()=>{}):f?.type==="error"&&this.hooks?.invoke("turn.failed",{...c,code:f.code,error:f.error}).catch(()=>{})}catch(m){if(t?.aborted)this.hooks?.invoke("turn.failed",{...c,code:"ABORTED",error:"Turn aborted"}).catch(()=>{}),yield{type:"error",turnId:r,error:"Turn aborted",code:"ABORTED"};else{let h=m instanceof Error?m.message:String(m),f=typeof m?.status=="number"?m.status:void 0,y=kn(f,h);this.log.error(`turn ${r} error [${y}, retryable=${_o(y)}]: ${h}`),this.hooks?.invoke("turn.failed",{...c,code:y,error:h}).catch(()=>{}),yield{type:"error",turnId:r,error:h,code:y}}}}}});import{createHash as sl}from"node:crypto";import Nr from"node:fs";import By from"node:path";function e_(n){return rl.find(e=>e.id===n)}function t_(n,e,t){let r=e_(t);if(r)return r;let s=rl.filter(a=>a.rarity===e);if(s.length===0)return rl[0];let i=sl("sha256").update(`breed-${n}`).digest()[0]%s.length;return s[i]}function n_(n){let t=sl("sha256").update(n).digest()[0]%100,r=0;for(let s=0;s<Hy.length;s++)if(r+=Hy[s],t<r)return ZI[s];return"common"}function r_(n){let e=sl("sha256").update(`stats-${n}`).digest();return{grip:e[0]%10+1,patience:e[1]%10+1,curiosity:e[2]%10+1,appetite:e[3]%10+1,humor:e[4]%10+1}}var ZI,Hy,rl,Qt,qy=Q(()=>{"use strict";ZI=["common","uncommon","rare","epic","legendary"],Hy=[50,25,15,8,2],rl=[{id:"default",name:"\u84DD\u8272\u4F19\u4F34",colors:{primary:"#5A7EFF",secondary:"#1E3A8A"},rarity:"default"},{id:"golden",name:"\u9EC4\u91D1\u4F19\u4F34",colors:{primary:"#F59E0B",secondary:"#92400E"},rarity:"legendary"},{id:"crystal",name:"\u6C34\u6676\u4F19\u4F34",colors:{primary:"#7DD3FC",secondary:"#0C4A6E"},rarity:"rare"},{id:"obsidian",name:"\u9ED1\u66DC\u4F19\u4F34",colors:{primary:"#7C3AED",secondary:"#1E1B4B"},rarity:"epic"},{id:"ghost",name:"\u96FE\u5F71\u4F19\u4F34",colors:{primary:"#94A3B8",secondary:"#475569"},rarity:"uncommon"},{id:"rainbow",name:"\u5F69\u8679\u4F19\u4F34",colors:{primary:"#EC4899",secondary:"#7C3AED"},rarity:"rare"}];Qt=class{constructor(e){this.workspaceDir=e;this.storagePath=By.join(e,".qlogicagent","pet","soul.json")}workspaceDir;soul=null;storagePath;load(){if(this.soul)return this.soul;if(!Nr.existsSync(this.storagePath))return null;try{let e=JSON.parse(Nr.readFileSync(this.storagePath,"utf-8"));return this.soul=e,this.soul}catch{return null}}async hatch(e,t,r){let s=`${e}-xiaozhi-claw`,o=n_(s),i=r_(s),a=t_(s,o,r),c="\u963F\u84DD",l="\u5B89\u9759\u3001\u597D\u5947\uFF0C\u4F1A\u5728\u4F60\u4E13\u6CE8\u65F6\u966A\u5728\u65C1\u8FB9\u3002",u="\u6211\u5728\u8FD9\u91CC\u3002";if(t){let d=await t(o,i);c=d.name,l=d.personality,u=d.catchphrase}return this.soul={name:c,species:a.name,personality:l,catchphrase:u,stats:i,rarity:o,breed:a.id,breedColors:a.colors,level:1,experience:0,hatchedAt:new Date().toISOString()},this.persist(),this.soul}addExperience(e){if(!this.soul)return{leveledUp:!1,level:0,experience:0};this.soul.experience+=e;let t=this.soul.level*100,r=!1;for(;this.soul.experience>=t;)this.soul.experience-=t,this.soul.level+=1,r=!0;return this.persist(),{leveledUp:r,level:this.soul.level,experience:this.soul.experience}}getSoul(){return this.soul}updateSoul(e){this.soul=e,this.persist()}persist(){let e=By.dirname(this.storagePath);Nr.existsSync(e)||Nr.mkdirSync(e,{recursive:!0}),Nr.writeFileSync(this.storagePath,JSON.stringify(this.soul,null,2),"utf-8")}}});function go(n){let e=o_[n];if(!e||Math.random()>e.probability)return null;let t=s_[e.pool];return{text:t[Math.floor(Math.random()*t.length)],style:e.style}}async function fo(n,e){let t=Or.length>0?`
|
|
32
32
|
\u907F\u514D\u548C\u8FD9\u4E9B\u7C7B\u4F3C: ${Or.join("\u3001")}`:"",r=`\u4F60\u662F\u4E00\u53EA\u53EB\u300C${n.soul.name}\u300D\u7684${n.soul.species}\u684C\u9762\u5BA0\u7269\u3002
|
|
33
33
|
\u6027\u683C: ${n.soul.personality}
|
|
34
34
|
\u53E3\u5934\u7985\u98CE\u683C: "${n.soul.catchphrase}"
|
|
@@ -372,13 +372,13 @@ ${t.join(`
|
|
|
372
372
|
|
|
373
373
|
`)}`:""}var rr=null,ha=null;async function Iu(n,e){return rr&&ha===n||(rr=await JS(n,e),ha=n),rr}function _u(){rr=null,ha=null}import*as G from"node:fs";import*as K from"node:path";import{execFile as Rw}from"node:child_process";var ya=new Set(["gateway","agents_list","session_status","sessions_send","sessions_list","sessions_history","sessions_spawn","cron","config","workflow"]),Cu=new Set([...ya,"agent"]);function ba(n,e){let t=e?ya:Cu;return n.filter(r=>r.function.name.startsWith("mcp__")?!0:!t.has(r.function.name))}var jt=new Map,ka=new Set;function Eu(n){jt.clear(),ka.clear();for(let e of n)jt.set(e.name,e)}function Pe(n){jt.set(n.name,n)}function va(n){for(let e of n)jt.set(e.name,e)}function ps(n){return jt.delete(n)}function tt(n){return jt.get(n)}function zt(){return Array.from(jt.keys())}function Mu(n){let e=jt.get(n);return!e||e.isEnabled?.()===!1?!1:(ka.add(n),!0)}function At(n=!1){let e=[];for(let t of jt.values())t.isEnabled?.()!==!1&&(!n&&t.shouldDefer&&!ka.has(t.name)||e.push({type:"function",function:{name:t.name,description:t.description,parameters:t.parameters},meta:{parallelSafe:t.isConcurrencySafe??!1,isReadOnly:t.isReadOnly??!1,isDangerous:!(t.isReadOnly??!1)&&!(t.isConcurrencySafe??!1)}}));return e}var QS="think",ZS={type:"object",properties:{thought:{type:"string",description:["Your internal reasoning about the current situation.","Use this to:","\u2022 Analyze what the user really wants (disambiguate vague requests)","\u2022 Plan multi-step approaches before executing","\u2022 Evaluate which tool(s) to use and why","\u2022 Consider edge cases or potential issues","\u2022 Reflect on conversation context and user preferences","This content is never shown to the user."].join(`
|
|
374
374
|
`)}},required:["thought"]};function Du(){return{name:QS,label:"Think",shouldDefer:!0,description:["Use this tool to think and reason about the current situation BEFORE taking action.","Call this tool when you need to:","- Analyze an ambiguous or complex user request before deciding what to do","- Plan a multi-step approach (what tools to call and in what order)","- Identify which steps can run in parallel vs. which must be sequential","- Evaluate tradeoffs between different approaches","- Reflect on user preferences from conversation history","- Process new information that changes your understanding","","This tool has NO side effects \u2014 it simply records your reasoning process.","Your thought is NOT shown to the user; it only improves YOUR decision quality.","After thinking, proceed to take the appropriate action.","","When planning multi-step work, be explicit about parallelism:",'- Say "\u8FD9\u4E9B\u53EF\u4EE5\u5E76\u884C\u751F\u6210" or "these can run in parallel" for independent tasks.','- Say "\u5148\u2026\u7136\u540E\u2026" or "step 1 first, then step 2" for sequential dependencies.'].join(`
|
|
375
|
-
`),parameters:ZS,execute:async(n,e)=>({content:[{type:"text",text:"Thought recorded. Now proceed with the best action based on your reasoning."}],details:{type:"think"}})}}var eT="task",tT=["create","update","delete","list","get"];var nT={type:"object",properties:{action:{type:"string",enum:[...tT],description:"create \u2014 add a new task (auto-assigns id). update \u2014 modify a task by id (partial, supports dependency wiring). delete \u2014 remove a task by id (cascades block refs). list \u2014 read current task list with summary. get \u2014 get a single task by id."},id:{type:"number",description:"[update|delete|get] Task id to operate on."},title:{type:"string",description:"[create|update] Task title (3-7 words, imperative form)."},description:{type:"string",description:"[create|update] Detailed task description."},status:{type:"string",enum:["not-started","in-progress","completed"],description:"[create|update] Task status. create defaults to not-started."},owner:{type:"string",description:"[create|update] Owner agent/subagent identifier."},addBlocks:{type:"array",items:{type:"number"},description:"[update] Task IDs that this task should block (they depend on this task)."},addBlockedBy:{type:"array",items:{type:"number"},description:"[update] Task IDs that should block this task (this task depends on them)."}},required:["action"]};function sr(n){let e=new Set(n.filter(t=>t.status==="completed").map(t=>t.id));return{total:n.length,completed:n.filter(t=>t.status==="completed").length,inProgress:n.filter(t=>t.status==="in-progress").length,notStarted:n.filter(t=>t.status==="not-started").length,blocked:n.filter(t=>t.status!=="completed"&&t.blockedBy?.some(r=>!e.has(r))).length}}function Nu(n,e){let t=[],r=0,s=n??{},o=s.verificationNudge!==!1;function i(){let f=t.reduce((y,b)=>Math.max(y,b.id),0);return r=Math.max(r,f)+1,r}function a(f){return{content:[{type:"text",text:`Error: ${f}`}],details:{type:"task",error:f}}}function c(f){let y=sr(t),b=new Set(t.filter(I=>I.status==="completed").map(I=>I.id)),
|
|
376
|
-
`)}],details:{type:"task",...y,...f,taskList:
|
|
377
|
-
`)}],details:{type:"task",action:"get",task:y}}}return{name:eT,label:"Task",description:"Manage a structured task list to track multi-step work progress. Actions: create (add task), update (modify by id), delete (remove by id), list (read all), get (single task). Supports dependency tracking (blocks/blockedBy) \u2014 tasks cannot start until blockers complete. Use frequently during complex work to plan steps, coordinate subagents, and show progress.",parameters:nT,searchHint:"manage session task checklist progress tracking dependencies planning",maxResultSizeChars:1e5,execute:async(f,y)=>{let b=y.action;switch(b){case"create":return d(y);case"update":return p(y);case"delete":return m(y);case"list":return c();case"get":return h(y);default:return a(`Unknown action: ${b}. Valid: create, update, delete, list, get.`)}}}}import{isAbsolute as PT,resolve as IT}from"node:path";var Ou=new Set(["find","grep","rg","ag","ack","locate","which","whereis"]),Lu=new Set(["cat","head","tail","less","more","wc","stat","file","strings","jq","awk","cut","sort","uniq","tr"]),$u=new Set(["ls","tree","du"]);var ju=new Set(["mv","cp","rm","mkdir","rmdir","chmod","chown","chgrp","touch","ln","cd","export","unset","wait"]);function rT(n){let t=n.replace(/\\\n/g," ").trim().split(/[|;&]/).shift()?.trim()??"";if(!t)return null;let r=t.split(/\s+/),s=0;for(;s<r.length&&/^[A-Za-z_]\w*=/.test(r[s]);)s++;let o=/^(?:timeout|time|nice|nohup|stdbuf|command|builtin|exec)$/;for(;s<r.length;){let c=r[s];if(o.test(c)){for(s++;s<r.length&&/^[-+]/.test(r[s]);)s++;s<r.length&&/^\d+(?:\.\d+)?[smhd]?$/.test(r[s])&&s++;continue}break}if(s>=r.length)return null;let i=r[s],a=i.lastIndexOf("/");return a>=0?i.slice(a+1):i}function Uu(n){return/(?:^|[;&|])\s*(?:cd|pushd|popd)\b/.test(n)}function Sa(n){let e=rT(n),t=e!==null&&Ou.has(e),r=e!==null&&Lu.has(e),s=e!==null&&$u.has(e),o=e!==null&&ju.has(e),i=/(?:[^2]>|^>|\|>)/.test(n),a=Uu(n),c=(t||r||s)&&!i&&!a;return{firstCommand:e,isSearch:t,isRead:r,isList:s,isSilent:o,isConcurrencySafe:c,isReadOnly:c}}var sT=n=>({isError:n!==0,message:n!==0?`Command failed with exit code ${n}`:void 0}),oT=new Map([["grep",n=>({isError:n>=2,message:n===1?"No matches found":void 0})],["rg",n=>({isError:n>=2,message:n===1?"No matches found":void 0})],["egrep",n=>({isError:n>=2,message:n===1?"No matches found":void 0})],["fgrep",n=>({isError:n>=2,message:n===1?"No matches found":void 0})],["ag",n=>({isError:n>=2,message:n===1?"No matches found":void 0})],["find",n=>({isError:n>=2,message:n===1?"Some directories were inaccessible":void 0})],["diff",n=>({isError:n>=2,message:n===1?"Files differ":void 0})],["test",n=>({isError:n>=2,message:n===1?"Condition is false":void 0})],["[",n=>({isError:n>=2,message:n===1?"Condition is false":void 0})],["cmp",n=>({isError:n>=2,message:n===1?"Files differ":void 0})]]);function iT(n){let e=n.trim(),t=e.split(/\s*\|\s*/);return(t[t.length-1]??e).trim().split(/\s+/)[0]??""}function Ta(n,e,t,r){let s=iT(n);return(oT.get(s)??sT)(e,t,r)}function Ra(n){return/(?:^|[;&|])\s*sleep\s+\d/i.test(n)?"sleep command blocks execution \u2014 use run_in_background: true":/\bwhile\s+(?:true|:|\[\s*1\s*\])\b/.test(n)?"infinite loop \u2014 use run_in_background: true or monitor tool":null}import{spawn as kT}from"node:child_process";import{constants as fs,readFileSync as vT,unlinkSync as ST}from"node:fs";import{mkdir as TT,open as RT,realpath as qu}from"node:fs/promises";import{isAbsolute as wT,resolve as AT}from"node:path";function cn(){if(process.platform!=="win32")return!1;let n=process.env.QLOGICAGENT_USE_POWERSHELL;return n==="1"||n==="true"}function wa(){return cn()?"powershell":"bash"}function Aa(){return Math.floor(Math.random()*65536).toString(16).padStart(4,"0")}import{mkdir as aT,readFile as cT,writeFile as lT,unlink as dT}from"node:fs/promises";import{join as Fu}from"node:path";import{tmpdir as uT}from"node:os";var pT=8*1024*1024,mT=5*1024*1024*1024;var xa;function or(){if(!xa){let n=Math.random().toString(36).slice(2,10);xa=Fu(uT(),"qla-tasks",n)}return xa}function Bu(n){return Fu(or(),`${n}.output`)}function Ut(n="local_bash"){return`${n}-${Date.now()}-${Math.random().toString(36).slice(2,8)}`}var Xt=class{taskId;path;stdoutToFile;#e="";#n="";#s=0;#o=0;#t;#i;#r=0;#a=!1;constructor(e,t,r=!1,s=pT){this.taskId=e,this.path=Bu(e),this.stdoutToFile=r,this.#t=s,this.#i=t}writeStdout(e){this.#e+=e,this.#o+=e.length,this.#s+=gT(e),this.#d()}writeStderr(e){this.#n+=e}async getStdout(){if(this.stdoutToFile)try{let e=await cT(this.path,"utf-8");return this.#r=Buffer.byteLength(e),e}catch{return""}return this.#e}getStderr(){return this.#n}get outputFileSize(){return this.#r}get outputFileRedundant(){return this.#r<=this.#t}#d(){this.#e.length>this.#t&&this.spillToDisk()}spillToDisk(){this.#e.length!==0&&aT(or(),{recursive:!0}).then(()=>lT(this.path,this.#e).catch(()=>{}))}async deleteOutputFile(){try{await dT(this.path)}catch{}}clear(){this.#a||(this.#a=!0,this.#e="",this.#n="",this.#i=null,this.deleteOutputFile())}};function gT(n){let e=0;for(let t=0;t<n.length;t++)n.charCodeAt(t)===10&&e++;return e}var Pa=137,Hu=143,fT=5e3,Ia=5*1024*1024*1024,ms=class{#e;#n;#s;#o=!1;constructor(e,t,r){this.#e=e,this.#n=t,this.#s=r,e.setEncoding("utf-8"),e.on("data",this.#t)}#t=e=>{let t=typeof e=="string"?e:e.toString();this.#s?this.#n.writeStderr(t):this.#n.writeStdout(t)};cleanup(){this.#o||(this.#o=!0,this.#e.removeListener("data",this.#t),this.#e=null,this.#n=null)}},_a=class n{#e="running";#n;#s;#o;#t;#i=null;#r=null;#a=!1;#d;#c;#u;#g;#b;#p=null;#m=null;#l=null;taskOutput;result;onTimeout;constructor(e,t,r,s,o=!1,i=Ia){this.#t=e,this.#c=t,this.#g=r,this.#b=o,this.#d=i,this.taskOutput=s,this.#o=e.stderr?new ms(e.stderr,s,!0):null,this.#s=e.stdout?new ms(e.stdout,s,!1):null,o&&(this.onTimeout=a=>{this.#u=a}),this.result=this.#A()}get status(){return this.#e}static#v(e){e.#b&&e.#u?e.#u(e.background.bind(e)):e.#y(Hu)}#S(){this.#c.reason!=="interrupt"&&this.kill()}#T(e,t){let r=e??(t==="SIGTERM"?144:1);this.#f(r)}#R(){this.#f(1)}#f(e){this.#m&&(this.#m(e),this.#m=null)}#h(){this.#k(),this.#i&&(clearTimeout(this.#i),this.#i=null),this.#l&&(this.#c.removeEventListener("abort",this.#l),this.#l=null)}#k(){this.#r&&(clearInterval(this.#r),this.#r=null)}#w(){this.#r=setInterval(()=>{import("node:fs/promises").then(({stat:e})=>e(this.taskOutput.path).then(t=>{t.size>this.#d&&this.#e==="backgrounded"&&this.#r!==null&&(this.#a=!0,this.#k(),this.#y(Pa))},()=>{}))},fT),this.#r.unref?.()}#A(){this.#l=this.#S.bind(this),this.#c.addEventListener("abort",this.#l,{once:!0}),this.#t.once("exit",this.#T.bind(this)),this.#t.once("error",this.#R.bind(this)),this.#i=setTimeout(n.#v,this.#g,this);let e=new Promise(t=>{this.#m=t});return new Promise(t=>{this.#p=t,e.then(this.#x.bind(this))})}async#x(e){this.#h(),(this.#e==="running"||this.#e==="backgrounded")&&(this.#e="completed");let t=await this.taskOutput.getStdout(),r={code:e,stdout:t,stderr:this.taskOutput.getStderr(),interrupted:e===Pa,backgroundTaskId:this.#n};this.taskOutput.stdoutToFile&&!this.#n&&(this.taskOutput.outputFileRedundant?this.taskOutput.deleteOutputFile():(r.outputFilePath=this.taskOutput.path,r.outputFileSize=this.taskOutput.outputFileSize)),this.#a?r.stderr=`Background command killed: output file exceeded ${Ia} bytes. ${r.stderr}`:e===Hu&&(r.stderr=`Command timed out after ${this.#g}ms. ${r.stderr}`),this.#p&&(this.#p(r),this.#p=null)}#y(e){this.#e="killed";let t=this.#t.pid;if(t)try{if(process.platform==="win32")import("node:child_process").then(({execSync:r})=>{try{r(`taskkill /PID ${t} /T /F`,{stdio:"ignore"})}catch{}});else try{process.kill(-t,"SIGKILL")}catch{try{process.kill(t,"SIGKILL")}catch{}}}catch{try{this.#t.kill("SIGKILL")}catch{}}this.#f(e??Pa)}kill(){this.#y()}background(e){return this.#e==="running"?(this.#n=e,this.#e="backgrounded",this.#h(),this.taskOutput.stdoutToFile?this.#w():this.taskOutput.spillToDisk(),!0):!1}cleanup(){this.#s?.cleanup(),this.#o?.cleanup(),this.taskOutput.clear(),this.#h(),this.#t=null,this.#c=null,this.#u=void 0}};function Ca(n,e,t,r,s=!1,o=Ia){return new _a(n,e,t,r,s,o)}function gs(n,e){let t=new Xt(Ut("local_bash"),null);return{status:"killed",result:Promise.resolve({code:e?.code??145,stdout:"",stderr:e?.stderr??"Command aborted before execution",interrupted:!0,backgroundTaskId:n}),taskOutput:t,background:()=>!1,kill:()=>{},cleanup:()=>{}}}function Ea(n){let e=new Xt(Ut("local_bash"),null);return{status:"completed",result:Promise.resolve({code:1,stdout:"",stderr:n,interrupted:!1,preSpawnError:n}),taskOutput:e,background:()=>!1,kill:()=>{},cleanup:()=>{}}}var hT=new Set(["API_KEY","ANTHROPIC_API_KEY","OPENAI_API_KEY","DEEPSEEK_API_KEY","DOUBAO_API_KEY","MINIMAX_API_KEY","GLM_API_KEY","KIMI_API_KEY","QWEN_API_KEY","MOONSHOT_API_KEY","ZHIPU_API_KEY","BAICHUAN_API_KEY","VOLCENGINE_API_KEY","AWS_SECRET_ACCESS_KEY","AWS_SESSION_TOKEN","GOOGLE_APPLICATION_CREDENTIALS","AZURE_CLIENT_SECRET","AZURE_CLIENT_ID","AZURE_TENANT_ID","ACTIONS_ID_TOKEN_REQUEST_TOKEN","ACTIONS_RUNTIME_TOKEN","GITHUB_TOKEN","GH_TOKEN","GITLAB_TOKEN","CI_JOB_TOKEN","DATABASE_URL","REDIS_URL","REDIS_PASSWORD"]),yT=["_SECRET","_TOKEN","_PASSWORD","_CREDENTIAL","_API_KEY","SECRET_","TOKEN_","PASSWORD_","CREDENTIAL_","_AUTH_","PRIVATE_KEY"];function Ma(){let n={...process.env};for(let e of Object.keys(n))bT(e)&&delete n[e];return n}function bT(n){if(hT.has(n))return!0;let e=n.toUpperCase();for(let t of yT)if(e.includes(t))return!0;return!1}var xT=1800*1e3,hs=process.cwd(),Wu=process.cwd();function ys(){return hs}function Da(n,e){hs=wT(n)?n:AT(e||hs,n)}function Gu(){return Wu}function bs(n){hs=n,Wu=n}var Na=null;function ir(n){Na={provider:n}}function Ku(){if(!Na)throw new Error("Shell provider not configured. Call setShellProvider() at startup.");return Na.provider}async function ks(n,e,t,r){let{timeout:s,onProgress:o,preventCwdChanges:i,shouldAutoBackground:a,onStdout:c,cwd:l}=r??{},u=s||xT,d=t??wa(),p=Ku(),m=Aa(),{commandString:h,cwdFilePath:f}=await p.buildExecCommand(n,{id:m,useSandbox:!1}),y=h,b=l??ys();try{await qu(b)}catch{let T=Gu();try{await qu(T),Da(T),b=T}catch{return Ea(`Working directory "${b}" no longer exists.`)}}if(e.aborted)return gs();let S=p.shellPath,w=p.getSpawnArgs(y),_=await p.getEnvironmentOverrides(n),I=!!c,D=Ut("local_bash"),L=new Xt(D,o??null,!I);await TT(or(),{recursive:!0});let F;if(!I){let T=fs.O_NOFOLLOW??0;F=await RT(L.path,process.platform==="win32"?"w":fs.O_WRONLY|fs.O_CREAT|fs.O_APPEND|T)}try{let T=kT(S,w,{env:{...Ma(),GIT_EDITOR:"true",QLOGICAGENT:"1",..._},cwd:b,stdio:I?["pipe","pipe","pipe"]:["pipe",F?.fd,F?.fd],detached:p.detached,windowsHide:!0}),ce=Ca(T,e,u,L,a);if(F!==void 0)try{await F.close()}catch{}return T.stdout&&c&&T.stdout.on("data",le=>{c(typeof le=="string"?le:le.toString())}),f&&ce.result.then(le=>{if(le&&!i&&!le.backgroundTaskId){try{let j=vT(f,{encoding:"utf8"}).trim();j&&j.normalize("NFC")!==b&&Da(j,b)}catch{}try{ST(f)}catch{}}}),ce}catch(T){if(F!==void 0)try{await F.close()}catch{}return L.clear(),gs(void 0,{code:126,stderr:T instanceof Error?T.message:String(T)})}}var _T="exec",CT={type:"object",properties:{command:{type:"string",description:cn()?"Shell command to execute in PowerShell.":"Shell command to execute in bash. Use Unix-style commands (ls, cat, mkdir -p, etc.)."},description:{type:"string",description:'Clear, concise description of what this command does (e.g. "Install dependencies", "Run unit tests"). Used for UI display and permission logging. For simple commands keep it 5-10 words; for complex piped/flagged commands add enough context to clarify intent.'},workdir:{type:"string",description:"Working directory for the command."},timeout:{type:"number",description:"Timeout in milliseconds (default: 120000). Only applies to foreground commands. Max allowed: 600000 (10 min)."},background:{type:"boolean",description:"If true, start the command in the background and return immediately with a task ID. Use getOutput to check on it later. Good for dev servers, watchers, long builds. Default: false."}},required:["command"]},ET=12e4,MT=6e5,vs=3e4;function Oa(n,e){if(n.length<=e)return n;let t=Math.floor(e/2)-50;return`${n.slice(0,t)}
|
|
375
|
+
`),parameters:ZS,execute:async(n,e)=>({content:[{type:"text",text:"Thought recorded. Now proceed with the best action based on your reasoning."}],details:{type:"think"}})}}var eT="task",tT=["create","update","delete","list","get"];var nT={type:"object",properties:{action:{type:"string",enum:[...tT],description:"create \u2014 add a new task (auto-assigns id). update \u2014 modify a task by id (partial, supports dependency wiring). delete \u2014 remove a task by id (cascades block refs). list \u2014 read current task list with summary. get \u2014 get a single task by id."},id:{type:"number",description:"[update|delete|get] Task id to operate on."},title:{type:"string",description:"[create|update] Task title (3-7 words, imperative form)."},description:{type:"string",description:"[create|update] Detailed task description."},status:{type:"string",enum:["not-started","in-progress","completed"],description:"[create|update] Task status. create defaults to not-started."},owner:{type:"string",description:"[create|update] Owner agent/subagent identifier."},addBlocks:{type:"array",items:{type:"number"},description:"[update] Task IDs that this task should block (they depend on this task)."},addBlockedBy:{type:"array",items:{type:"number"},description:"[update] Task IDs that should block this task (this task depends on them)."}},required:["action"]};function sr(n){let e=new Set(n.filter(t=>t.status==="completed").map(t=>t.id));return{total:n.length,completed:n.filter(t=>t.status==="completed").length,inProgress:n.filter(t=>t.status==="in-progress").length,notStarted:n.filter(t=>t.status==="not-started").length,blocked:n.filter(t=>t.status!=="completed"&&t.blockedBy?.some(r=>!e.has(r))).length}}function Nu(n,e){let t=[],r=0,s=n??{},o=s.verificationNudge!==!1;function i(){let f=t.reduce((y,b)=>Math.max(y,b.id),0);return r=Math.max(r,f)+1,r}function a(f){return{content:[{type:"text",text:`Error: ${f}`}],details:{type:"task",error:f}}}function c(f){let y=sr(t),b=new Set(t.filter(I=>I.status==="completed").map(I=>I.id)),T=t.map(I=>{let D=I.blockedBy?.filter(L=>!b.has(L));return{...I,...D?.length?{blockedBy:D}:{blockedBy:void 0}}}),w=[];if(w.push(`Task list updated. ${y.total} tasks: ${y.completed} completed, ${y.inProgress} in-progress, ${y.notStarted} not-started.`),y.blocked>0&&w.push(`${y.blocked} blocked.`),f?.created){let I=f.created;w.push(`Created task #${I.id}: "${I.title}"`)}if(f?.updated){let I=f.updated;w.push(`Updated task #${I.id}: "${I.title}"`)}if(f?.deleted!=null&&w.push(`Deleted task #${f.deleted}`),T.length>0){w.push("");for(let I of T){let D=I.status==="completed"?"\u2713":I.status==="in-progress"?"\u2192":"\u25CB",L=I.blockedBy?.length?` [blocked by #${I.blockedBy.join(", #")}]`:"",F=I.owner?` (${I.owner})`:"";w.push(` ${D} #${I.id}: ${I.title} (${I.status})${F}${L}`)}}let _=!1;if(o&&f?.updated&&f.updated.status==="completed"){let D=t.every(S=>S.status==="completed"),L=t.length,F=t.some(S=>/verif/i.test(S.title));D&&L>=3&&!F&&(_=!0,w.push(""),w.push("NOTE: You just closed out "+L+' tasks and none of them was a verification step. Before writing your final summary, spawn the verification agent (agent type="verify"). You cannot self-assign PARTIAL by listing caveats in your summary \u2014 only the verifier issues a verdict.'))}return{content:[{type:"text",text:w.join(`
|
|
376
|
+
`)}],details:{type:"task",...y,...f,taskList:T,agentId:s.agentId,..._&&{verificationNudgeNeeded:!0}}}}function l(f,y,b){let T=t.find(w=>w.id===f);if(T){if(y?.length){T.blocks=[...new Set([...T.blocks??[],...y])];for(let w of y){let _=t.find(I=>I.id===w);_&&(_.blockedBy=[...new Set([..._.blockedBy??[],f])])}}if(b?.length){T.blockedBy=[...new Set([...T.blockedBy??[],...b])];for(let w of b){let _=t.find(I=>I.id===w);_&&(_.blocks=[...new Set([..._.blocks??[],f])])}}}}function u(f){for(let y of t)y.blocks&&(y.blocks=y.blocks.filter(b=>b!==f)),y.blockedBy&&(y.blockedBy=y.blockedBy.filter(b=>b!==f))}function d(f){if(!f.title)return a("title is required for create action.");let y={id:i(),title:f.title,status:f.status??"not-started",...f.description!=null&&{description:f.description},...f.owner!=null&&{owner:f.owner}};return t.push(y),l(y.id,void 0,f.addBlockedBy),e?.onTaskCreated?.(y),c({created:{id:y.id,title:y.title}})}function p(f){if(f.id==null)return a("id is required for update action.");let y=t.find(b=>b.id===f.id);if(!y)return a(`Task #${f.id} not found.`);if(f.status==="in-progress"){let b=new Set(t.filter(w=>w.status==="completed").map(w=>w.id)),T=y.blockedBy?.filter(w=>!b.has(w));if(T?.length)return a(`Cannot set #${f.id} to in-progress: blocked by unresolved task(s) #${T.join(", #")}.`)}if(f.title!=null&&(y.title=f.title),f.description!=null&&(y.description=f.description),f.owner!=null&&(y.owner=f.owner),f.status!=null){let b=y.status;y.status=f.status,b!=="completed"&&f.status==="completed"&&e?.onTaskCompleted?.(y)}return l(y.id,f.addBlocks,f.addBlockedBy),c({updated:{id:y.id,title:y.title,status:y.status}})}function m(f){if(f.id==null)return a("id is required for delete action.");let y=t.findIndex(b=>b.id===f.id);return y===-1?a(`Task #${f.id} not found.`):(r=Math.max(r,f.id),t.splice(y,1),u(f.id),c({deleted:f.id}))}function h(f){if(f.id==null)return a("id is required for get action.");let y=t.find(_=>_.id===f.id);if(!y)return a(`Task #${f.id} not found.`);let b=new Set(t.filter(_=>_.status==="completed").map(_=>_.id)),T=y.blockedBy?.filter(_=>!b.has(_));return{content:[{type:"text",text:[`Task #${y.id}: ${y.title}`,`Status: ${y.status}`,y.description?`Description: ${y.description}`:"",y.owner?`Owner: ${y.owner}`:"",T?.length?`Blocked by: #${T.join(", #")}`:"",y.blocks?.length?`Blocks: #${y.blocks.join(", #")}`:""].filter(Boolean).join(`
|
|
377
|
+
`)}],details:{type:"task",action:"get",task:y}}}return{name:eT,label:"Task",description:"Manage a structured task list to track multi-step work progress. Actions: create (add task), update (modify by id), delete (remove by id), list (read all), get (single task). Supports dependency tracking (blocks/blockedBy) \u2014 tasks cannot start until blockers complete. Use frequently during complex work to plan steps, coordinate subagents, and show progress.",parameters:nT,searchHint:"manage session task checklist progress tracking dependencies planning",maxResultSizeChars:1e5,execute:async(f,y)=>{let b=y.action;switch(b){case"create":return d(y);case"update":return p(y);case"delete":return m(y);case"list":return c();case"get":return h(y);default:return a(`Unknown action: ${b}. Valid: create, update, delete, list, get.`)}}}}import{isAbsolute as PT,resolve as IT}from"node:path";var Ou=new Set(["find","grep","rg","ag","ack","locate","which","whereis"]),Lu=new Set(["cat","head","tail","less","more","wc","stat","file","strings","jq","awk","cut","sort","uniq","tr"]),$u=new Set(["ls","tree","du"]);var ju=new Set(["mv","cp","rm","mkdir","rmdir","chmod","chown","chgrp","touch","ln","cd","export","unset","wait"]);function rT(n){let t=n.replace(/\\\n/g," ").trim().split(/[|;&]/).shift()?.trim()??"";if(!t)return null;let r=t.split(/\s+/),s=0;for(;s<r.length&&/^[A-Za-z_]\w*=/.test(r[s]);)s++;let o=/^(?:timeout|time|nice|nohup|stdbuf|command|builtin|exec)$/;for(;s<r.length;){let c=r[s];if(o.test(c)){for(s++;s<r.length&&/^[-+]/.test(r[s]);)s++;s<r.length&&/^\d+(?:\.\d+)?[smhd]?$/.test(r[s])&&s++;continue}break}if(s>=r.length)return null;let i=r[s],a=i.lastIndexOf("/");return a>=0?i.slice(a+1):i}function Uu(n){return/(?:^|[;&|])\s*(?:cd|pushd|popd)\b/.test(n)}function Sa(n){let e=rT(n),t=e!==null&&Ou.has(e),r=e!==null&&Lu.has(e),s=e!==null&&$u.has(e),o=e!==null&&ju.has(e),i=/(?:[^2]>|^>|\|>)/.test(n),a=Uu(n),c=(t||r||s)&&!i&&!a;return{firstCommand:e,isSearch:t,isRead:r,isList:s,isSilent:o,isConcurrencySafe:c,isReadOnly:c}}var sT=n=>({isError:n!==0,message:n!==0?`Command failed with exit code ${n}`:void 0}),oT=new Map([["grep",n=>({isError:n>=2,message:n===1?"No matches found":void 0})],["rg",n=>({isError:n>=2,message:n===1?"No matches found":void 0})],["egrep",n=>({isError:n>=2,message:n===1?"No matches found":void 0})],["fgrep",n=>({isError:n>=2,message:n===1?"No matches found":void 0})],["ag",n=>({isError:n>=2,message:n===1?"No matches found":void 0})],["find",n=>({isError:n>=2,message:n===1?"Some directories were inaccessible":void 0})],["diff",n=>({isError:n>=2,message:n===1?"Files differ":void 0})],["test",n=>({isError:n>=2,message:n===1?"Condition is false":void 0})],["[",n=>({isError:n>=2,message:n===1?"Condition is false":void 0})],["cmp",n=>({isError:n>=2,message:n===1?"Files differ":void 0})]]);function iT(n){let e=n.trim(),t=e.split(/\s*\|\s*/);return(t[t.length-1]??e).trim().split(/\s+/)[0]??""}function Ta(n,e,t,r){let s=iT(n);return(oT.get(s)??sT)(e,t,r)}function Ra(n){return/(?:^|[;&|])\s*sleep\s+\d/i.test(n)?"sleep command blocks execution \u2014 use run_in_background: true":/\bwhile\s+(?:true|:|\[\s*1\s*\])\b/.test(n)?"infinite loop \u2014 use run_in_background: true or monitor tool":null}import{spawn as kT}from"node:child_process";import{constants as fs,readFileSync as vT,unlinkSync as ST}from"node:fs";import{mkdir as TT,open as RT,realpath as qu}from"node:fs/promises";import{isAbsolute as wT,resolve as AT}from"node:path";function cn(){if(process.platform!=="win32")return!1;let n=process.env.QLOGICAGENT_USE_POWERSHELL;return n==="1"||n==="true"}function wa(){return cn()?"powershell":"bash"}function Aa(){return Math.floor(Math.random()*65536).toString(16).padStart(4,"0")}import{mkdir as aT,readFile as cT,writeFile as lT,unlink as dT}from"node:fs/promises";import{join as Fu}from"node:path";import{tmpdir as uT}from"node:os";var pT=8*1024*1024,mT=5*1024*1024*1024;var xa;function or(){if(!xa){let n=Math.random().toString(36).slice(2,10);xa=Fu(uT(),"qla-tasks",n)}return xa}function Bu(n){return Fu(or(),`${n}.output`)}function Ut(n="local_bash"){return`${n}-${Date.now()}-${Math.random().toString(36).slice(2,8)}`}var Xt=class{taskId;path;stdoutToFile;#e="";#n="";#s=0;#o=0;#t;#i;#r=0;#a=!1;constructor(e,t,r=!1,s=pT){this.taskId=e,this.path=Bu(e),this.stdoutToFile=r,this.#t=s,this.#i=t}writeStdout(e){this.#e+=e,this.#o+=e.length,this.#s+=gT(e),this.#d()}writeStderr(e){this.#n+=e}async getStdout(){if(this.stdoutToFile)try{let e=await cT(this.path,"utf-8");return this.#r=Buffer.byteLength(e),e}catch{return""}return this.#e}getStderr(){return this.#n}get outputFileSize(){return this.#r}get outputFileRedundant(){return this.#r<=this.#t}#d(){this.#e.length>this.#t&&this.spillToDisk()}spillToDisk(){this.#e.length!==0&&aT(or(),{recursive:!0}).then(()=>lT(this.path,this.#e).catch(()=>{}))}async deleteOutputFile(){try{await dT(this.path)}catch{}}clear(){this.#a||(this.#a=!0,this.#e="",this.#n="",this.#i=null,this.deleteOutputFile())}};function gT(n){let e=0;for(let t=0;t<n.length;t++)n.charCodeAt(t)===10&&e++;return e}var Pa=137,Hu=143,fT=5e3,Ia=5*1024*1024*1024,ms=class{#e;#n;#s;#o=!1;constructor(e,t,r){this.#e=e,this.#n=t,this.#s=r,e.setEncoding("utf-8"),e.on("data",this.#t)}#t=e=>{let t=typeof e=="string"?e:e.toString();this.#s?this.#n.writeStderr(t):this.#n.writeStdout(t)};cleanup(){this.#o||(this.#o=!0,this.#e.removeListener("data",this.#t),this.#e=null,this.#n=null)}},_a=class n{#e="running";#n;#s;#o;#t;#i=null;#r=null;#a=!1;#d;#c;#u;#g;#b;#p=null;#m=null;#l=null;taskOutput;result;onTimeout;constructor(e,t,r,s,o=!1,i=Ia){this.#t=e,this.#c=t,this.#g=r,this.#b=o,this.#d=i,this.taskOutput=s,this.#o=e.stderr?new ms(e.stderr,s,!0):null,this.#s=e.stdout?new ms(e.stdout,s,!1):null,o&&(this.onTimeout=a=>{this.#u=a}),this.result=this.#A()}get status(){return this.#e}static#v(e){e.#b&&e.#u?e.#u(e.background.bind(e)):e.#y(Hu)}#S(){this.#c.reason!=="interrupt"&&this.kill()}#T(e,t){let r=e??(t==="SIGTERM"?144:1);this.#f(r)}#R(){this.#f(1)}#f(e){this.#m&&(this.#m(e),this.#m=null)}#h(){this.#k(),this.#i&&(clearTimeout(this.#i),this.#i=null),this.#l&&(this.#c.removeEventListener("abort",this.#l),this.#l=null)}#k(){this.#r&&(clearInterval(this.#r),this.#r=null)}#w(){this.#r=setInterval(()=>{import("node:fs/promises").then(({stat:e})=>e(this.taskOutput.path).then(t=>{t.size>this.#d&&this.#e==="backgrounded"&&this.#r!==null&&(this.#a=!0,this.#k(),this.#y(Pa))},()=>{}))},fT),this.#r.unref?.()}#A(){this.#l=this.#S.bind(this),this.#c.addEventListener("abort",this.#l,{once:!0}),this.#t.once("exit",this.#T.bind(this)),this.#t.once("error",this.#R.bind(this)),this.#i=setTimeout(n.#v,this.#g,this);let e=new Promise(t=>{this.#m=t});return new Promise(t=>{this.#p=t,e.then(this.#x.bind(this))})}async#x(e){this.#h(),(this.#e==="running"||this.#e==="backgrounded")&&(this.#e="completed");let t=await this.taskOutput.getStdout(),r={code:e,stdout:t,stderr:this.taskOutput.getStderr(),interrupted:e===Pa,backgroundTaskId:this.#n};this.taskOutput.stdoutToFile&&!this.#n&&(this.taskOutput.outputFileRedundant?this.taskOutput.deleteOutputFile():(r.outputFilePath=this.taskOutput.path,r.outputFileSize=this.taskOutput.outputFileSize)),this.#a?r.stderr=`Background command killed: output file exceeded ${Ia} bytes. ${r.stderr}`:e===Hu&&(r.stderr=`Command timed out after ${this.#g}ms. ${r.stderr}`),this.#p&&(this.#p(r),this.#p=null)}#y(e){this.#e="killed";let t=this.#t.pid;if(t)try{if(process.platform==="win32")import("node:child_process").then(({execSync:r})=>{try{r(`taskkill /PID ${t} /T /F`,{stdio:"ignore"})}catch{}});else try{process.kill(-t,"SIGKILL")}catch{try{process.kill(t,"SIGKILL")}catch{}}}catch{try{this.#t.kill("SIGKILL")}catch{}}this.#f(e??Pa)}kill(){this.#y()}background(e){return this.#e==="running"?(this.#n=e,this.#e="backgrounded",this.#h(),this.taskOutput.stdoutToFile?this.#w():this.taskOutput.spillToDisk(),!0):!1}cleanup(){this.#s?.cleanup(),this.#o?.cleanup(),this.taskOutput.clear(),this.#h(),this.#t=null,this.#c=null,this.#u=void 0}};function Ca(n,e,t,r,s=!1,o=Ia){return new _a(n,e,t,r,s,o)}function gs(n,e){let t=new Xt(Ut("local_bash"),null);return{status:"killed",result:Promise.resolve({code:e?.code??145,stdout:"",stderr:e?.stderr??"Command aborted before execution",interrupted:!0,backgroundTaskId:n}),taskOutput:t,background:()=>!1,kill:()=>{},cleanup:()=>{}}}function Ea(n){let e=new Xt(Ut("local_bash"),null);return{status:"completed",result:Promise.resolve({code:1,stdout:"",stderr:n,interrupted:!1,preSpawnError:n}),taskOutput:e,background:()=>!1,kill:()=>{},cleanup:()=>{}}}var hT=new Set(["API_KEY","ANTHROPIC_API_KEY","OPENAI_API_KEY","DEEPSEEK_API_KEY","DOUBAO_API_KEY","MINIMAX_API_KEY","GLM_API_KEY","KIMI_API_KEY","QWEN_API_KEY","MOONSHOT_API_KEY","ZHIPU_API_KEY","BAICHUAN_API_KEY","VOLCENGINE_API_KEY","AWS_SECRET_ACCESS_KEY","AWS_SESSION_TOKEN","GOOGLE_APPLICATION_CREDENTIALS","AZURE_CLIENT_SECRET","AZURE_CLIENT_ID","AZURE_TENANT_ID","ACTIONS_ID_TOKEN_REQUEST_TOKEN","ACTIONS_RUNTIME_TOKEN","GITHUB_TOKEN","GH_TOKEN","GITLAB_TOKEN","CI_JOB_TOKEN","DATABASE_URL","REDIS_URL","REDIS_PASSWORD"]),yT=["_SECRET","_TOKEN","_PASSWORD","_CREDENTIAL","_API_KEY","SECRET_","TOKEN_","PASSWORD_","CREDENTIAL_","_AUTH_","PRIVATE_KEY"];function Ma(){let n={...process.env};for(let e of Object.keys(n))bT(e)&&delete n[e];return n}function bT(n){if(hT.has(n))return!0;let e=n.toUpperCase();for(let t of yT)if(e.includes(t))return!0;return!1}var xT=1800*1e3,hs=process.cwd(),Wu=process.cwd();function ys(){return hs}function Da(n,e){hs=wT(n)?n:AT(e||hs,n)}function Gu(){return Wu}function bs(n){hs=n,Wu=n}var Na=null;function ir(n){Na={provider:n}}function Ku(){if(!Na)throw new Error("Shell provider not configured. Call setShellProvider() at startup.");return Na.provider}async function ks(n,e,t,r){let{timeout:s,onProgress:o,preventCwdChanges:i,shouldAutoBackground:a,onStdout:c,cwd:l}=r??{},u=s||xT,d=t??wa(),p=Ku(),m=Aa(),{commandString:h,cwdFilePath:f}=await p.buildExecCommand(n,{id:m,useSandbox:!1}),y=h,b=l??ys();try{await qu(b)}catch{let S=Gu();try{await qu(S),Da(S),b=S}catch{return Ea(`Working directory "${b}" no longer exists.`)}}if(e.aborted)return gs();let T=p.shellPath,w=p.getSpawnArgs(y),_=await p.getEnvironmentOverrides(n),I=!!c,D=Ut("local_bash"),L=new Xt(D,o??null,!I);await TT(or(),{recursive:!0});let F;if(!I){let S=fs.O_NOFOLLOW??0;F=await RT(L.path,process.platform==="win32"?"w":fs.O_WRONLY|fs.O_CREAT|fs.O_APPEND|S)}try{let S=kT(T,w,{env:{...Ma(),GIT_EDITOR:"true",QLOGICAGENT:"1",..._},cwd:b,stdio:I?["pipe","pipe","pipe"]:["pipe",F?.fd,F?.fd],detached:p.detached,windowsHide:!0}),ce=Ca(S,e,u,L,a);if(F!==void 0)try{await F.close()}catch{}return S.stdout&&c&&S.stdout.on("data",le=>{c(typeof le=="string"?le:le.toString())}),f&&ce.result.then(le=>{if(le&&!i&&!le.backgroundTaskId){try{let j=vT(f,{encoding:"utf8"}).trim();j&&j.normalize("NFC")!==b&&Da(j,b)}catch{}try{ST(f)}catch{}}}),ce}catch(S){if(F!==void 0)try{await F.close()}catch{}return L.clear(),gs(void 0,{code:126,stderr:S instanceof Error?S.message:String(S)})}}var _T="exec",CT={type:"object",properties:{command:{type:"string",description:cn()?"Shell command to execute in PowerShell.":"Shell command to execute in bash. Use Unix-style commands (ls, cat, mkdir -p, etc.)."},description:{type:"string",description:'Clear, concise description of what this command does (e.g. "Install dependencies", "Run unit tests"). Used for UI display and permission logging. For simple commands keep it 5-10 words; for complex piped/flagged commands add enough context to clarify intent.'},workdir:{type:"string",description:"Working directory for the command."},timeout:{type:"number",description:"Timeout in milliseconds (default: 120000). Only applies to foreground commands. Max allowed: 600000 (10 min)."},background:{type:"boolean",description:"If true, start the command in the background and return immediately with a task ID. Use getOutput to check on it later. Good for dev servers, watchers, long builds. Default: false."}},required:["command"]},ET=12e4,MT=6e5,vs=3e4;function Oa(n,e){if(n.length<=e)return n;let t=Math.floor(e/2)-50;return`${n.slice(0,t)}
|
|
378
378
|
|
|
379
379
|
... [truncated ${n.length-e} chars] ...
|
|
380
380
|
|
|
381
|
-
${n.slice(-t)}`}function DT(n){return n==null||n<=0?ET:Math.min(n,MT)}async function*NT(n){let{command:e,abortController:t,timeout:r,shouldAutoBackground:s,cwd:o}=n,i="",a=0,c=0,l=Date.now(),u=null;function d(){return new Promise(h=>{u=()=>h(null)})}let p=await ks(e,t.signal,void 0,{timeout:r,onProgress(h,f,y,b,
|
|
381
|
+
${n.slice(-t)}`}function DT(n){return n==null||n<=0?ET:Math.min(n,MT)}async function*NT(n){let{command:e,abortController:t,timeout:r,shouldAutoBackground:s,cwd:o}=n,i="",a=0,c=0,l=Date.now(),u=null;function d(){return new Promise(h=>{u=()=>h(null)})}let p=await ks(e,t.signal,void 0,{timeout:r,onProgress(h,f,y,b,T){i=f,a=y,c=b,u&&(u(),u=null)},shouldAutoBackground:s,cwd:o});for(p.onTimeout&&s&&p.onTimeout(h=>{let f=Ut("bg");h(f)});p.status==="running"&&await Promise.race([d(),p.result])===null;)yield{type:"exec_progress",output:i.slice(-4096),fullOutput:i,elapsedTimeSeconds:(Date.now()-l)/1e3,totalLines:a,totalBytes:c};let m=await p.result;return p.cleanup(),m}function Vu(n={}){return{name:_T,label:"Execute Command",description:"Execute a shell command. Supports foreground (blocking, returns output) and background (non-blocking, returns task ID) modes. "+(cn()?"Uses PowerShell. ":"Uses bash. ")+`Commands are classified for safety: search/read commands may run in parallel; silent commands (mv, cp, rm) show 'Done' instead of empty output. Output is truncated and persisted if too long.
|
|
382
382
|
IMPORTANT: Do NOT use this tool for file operations when dedicated tools exist. Use the 'write' tool instead of echo/cat/heredoc for creating files. Use the 'edit' tool instead of sed/awk for modifying files. Use the 'read' tool instead of cat/head/tail for reading files. Reserve this tool exclusively for system commands, builds, tests, and terminal operations that require shell execution.`,searchHint:"execute shell commands",parameters:CT,maxResultSizeChars:vs,execute:async(e,t)=>{let r=Sa(t.command);if(!t.background){let m=Ra(t.command);if(m)return{content:[{type:"text",text:`Command blocked: ${m}`}],details:{type:"exec",error:"blocked_sleep_pattern",classification:r}}}if(n.validateCommand){let m=await n.validateCommand(t.command);if(m)return{content:[{type:"text",text:`Command blocked: ${m}`}],details:{type:"exec",error:"blocked_by_guard",reason:m,classification:r}}}let s=new AbortController,o=DT(t.timeout),i=t.workdir?PT(t.workdir)?t.workdir:IT(ys(),t.workdir):void 0;if(t.background){let m=await ks(t.command,s.signal,void 0,{shouldAutoBackground:!1,cwd:i}),h=Ut("bg");if(m.background(h))return{content:[{type:"text",text:`Background task started (id: ${h}).
|
|
383
383
|
Use getOutput to check on it later.`}],details:{type:"exec_background",backgroundTaskId:h,description:t.description,classification:r}}}let a=NT({command:t.command,abortController:s,timeout:o,shouldAutoBackground:!0,cwd:i}),c;do c=await a.next(),!c.done&&n.onProgress&&n.onProgress(c.value);while(!c.done);let l=c.value,u=[];if(l.backgroundTaskId)return{content:[{type:"text",text:`Command auto-backgrounded (task: ${l.backgroundTaskId}).`}],details:{type:"exec_background",backgroundTaskId:l.backgroundTaskId,assistantAutoBackgrounded:l.assistantAutoBackgrounded,classification:r}};l.outputFilePath?(u.push(Oa(l.stdout,vs)),u.push(`[full output: ${l.outputFilePath} (${l.outputFileSize} bytes)]`)):l.stdout&&u.push(Oa(l.stdout,vs)),l.stderr&&u.push(`[stderr]
|
|
384
384
|
${Oa(l.stderr,Math.floor(vs/4))}`),l.interrupted&&u.push(`[interrupted \u2014 exit code ${l.code}]`);let d=l.code!==0?Ta(t.command,l.code,l.stdout,l.stderr):void 0;d&&!d.isError&&d.message&&u.push(`[exit ${l.code}: ${d.message}]`);let p;return l.code!==0&&n.interpretExitCode&&(!d||d.isError)&&(p=n.interpretExitCode(l.code,l.stderr),p&&u.push(`[exit ${l.code}: ${p}]`)),u.length===0&&u.push(r.isSilent&&l.code===0?"Done":`(exit code ${l.code}, no output)`),{content:[{type:"text",text:u.join(`
|
|
@@ -419,15 +419,15 @@ Fuzzy matching automatically handles whitespace/indent/unicode drift in the sear
|
|
|
419
419
|
`).map(f=>f.trim()),i=n.split(`
|
|
420
420
|
`),a=ip(i,o,(f,y)=>f.trim()===y);if(a)return[{...ap(n,i,a),strategy:"line_trimmed"}];let c=e.replace(/[ \t]+/g," "),l=n.replace(/[ \t]+/g," ");if(s=l.indexOf(c),s!==-1){let f=cp(n,l,s,c.length);if(f)return[{...f,strategy:"whitespace_normalized"}]}let u=ip(i,o,(f,y)=>f.trimStart()===y.trimStart());if(u)return[{...ap(n,i,u),strategy:"indentation_flexible"}];let d=lR(e);if(d!==e&&(s=n.indexOf(d),s!==-1))return[{start:s,end:s+d.length,strategy:"escape_normalized"}];let p=e.split(`
|
|
421
421
|
`);if(p.length>=3){let f=p.slice(1,-1).join(`
|
|
422
|
-
`),y=p[0].trim(),b=p[p.length-1].trim();for(let
|
|
422
|
+
`),y=p[0].trim(),b=p[p.length-1].trim();for(let T=0;T<i.length;T++)if(i[T].trim()===y){let w=i.slice(0,T+1).join(`
|
|
423
423
|
`).length+1,_=n.indexOf(f,w);if(_!==-1){let I=_+f.length,D=n.indexOf(`
|
|
424
424
|
`,I);if((D===-1?n.slice(I):n.slice(I,D)).trim()===b||D!==-1&&n.slice(I+1,n.indexOf(`
|
|
425
425
|
`,I+1)===-1?void 0:n.indexOf(`
|
|
426
|
-
`,I+1)).trim()===b){let F=i.slice(0,
|
|
427
|
-
`).length+(
|
|
428
|
-
`).length;return[{start:F,end:le,strategy:"trimmed_boundary"}]}}}}}let m=sp(e),h=sp(n);if((m!==e||h!==n)&&(s=h.indexOf(m),s!==-1)){let f=cp(n,h,s,m.length);if(f)return[{...f,strategy:"unicode_normalized"}]}if(p.length>=3){let f=p[0],y=p[p.length-1];for(let b=0;b<i.length;b++)if(i[b]===f){for(let
|
|
429
|
-
`).length+(b>0?1:0),
|
|
430
|
-
`).length;return[{start:F,end:
|
|
426
|
+
`,I+1)).trim()===b){let F=i.slice(0,T).join(`
|
|
427
|
+
`).length+(T>0?1:0),S=T,ce=p.length;if(T+ce<=i.length){S=T+ce;let le=i.slice(0,S).join(`
|
|
428
|
+
`).length;return[{start:F,end:le,strategy:"trimmed_boundary"}]}}}}}let m=sp(e),h=sp(n);if((m!==e||h!==n)&&(s=h.indexOf(m),s!==-1)){let f=cp(n,h,s,m.length);if(f)return[{...f,strategy:"unicode_normalized"}]}if(p.length>=3){let f=p[0],y=p[p.length-1];for(let b=0;b<i.length;b++)if(i[b]===f){for(let T=b+p.length-1;T<Math.min(b+p.length+2,i.length);T++)if(i[T]===y){let w=T-b+1,_=i.slice(b+1,T),I=p.slice(1,-1),D=I.filter(F=>_.some(S=>op(S,F)>=.7)).length;if((I.length>0?D/I.length:1)>=.5&&w<=p.length+2){let F=i.slice(0,b).join(`
|
|
429
|
+
`).length+(b>0?1:0),S=i.slice(0,T+1).join(`
|
|
430
|
+
`).length;return[{start:F,end:S,strategy:"block_anchor"}]}}}}if(p.length>=2)for(let f=0;f<=i.length-p.length;f++){let y=i.slice(f,f+p.length);if(p.map((w,_)=>op(w,y[_])).filter(w=>w>=.8).length/p.length>=.5){let w=i.slice(0,f).join(`
|
|
431
431
|
`).length+(f>0?1:0),_=i.slice(0,f+p.length).join(`
|
|
432
432
|
`).length;return[{start:w,end:_,strategy:"context_aware"}]}}return[]}function ip(n,e,t){for(let r=0;r<=n.length-e.length;r++){let s=!0;for(let o=0;o<e.length;o++)if(!t(n[r+o],e[o])){s=!1;break}if(s)return{startIdx:r,endIdx:r+e.length}}return null}function ap(n,e,t){let r=e.slice(0,t.startIdx).join(`
|
|
433
433
|
`).length+(t.startIdx>0?1:0),s=e.slice(0,t.endIdx).join(`
|
|
@@ -441,7 +441,7 @@ Fuzzy matching automatically handles whitespace/indent/unicode drift in the sear
|
|
|
441
441
|
`+o.join(`
|
|
442
442
|
`),strategy:"exact"};let l=up(n,c,t);if(l.length===0)return null;let u=[];for(let h of e.lines)(h.prefix===" "||h.prefix==="+")&&u.push(h.content);let d=u.join(`
|
|
443
443
|
`),p=l[0];return{content:n.slice(0,p.start)+d+n.slice(p.end),strategy:p.strategy}}function Ha(n){return{name:aR,label:"Patch",description:"Apply edits to files using fuzzy matching. Supports V4A unified diff format (*** Begin Patch / *** End Patch) for multi-file operations, and simple search/replace blocks. The fuzzy matcher handles whitespace, indentation, unicode, and escape drift \u2014 LLM output with minor formatting differences will still match correctly.",parameters:cR,execute:async(e,t)=>{let r=t.replaceAll??!1,s={filesModified:[],filesAdded:[],filesDeleted:[],strategies:{},errors:[]},o=t.input.includes("*** Begin Patch"),i=t.input.includes("<<<< SEARCH");if(o){let l=lp(t.input);if(l.length===0)return{content:[{type:"text",text:"Error: No valid V4A operations found. Ensure *** Begin Patch / *** End Patch markers are present."}],details:{type:"patch",error:"parse_failed"}};for(let u of l){let d=n.resolvePath(u.path);try{switch(u.type){case"add":{let p=u.hunks.flatMap(m=>m.lines.filter(h=>h.prefix==="+").map(h=>h.content)).join(`
|
|
444
|
-
`);await n.writeFile(d,p),s.filesAdded.push(u.path),s.strategies[u.path]="exact";break}case"delete":{await n.deleteFile(d),s.filesDeleted.push(u.path);break}case"move":{let p=await n.readFile(d);if(u.newPath){let m=n.resolvePath(u.newPath),h=p;for(let f of u.hunks){let y=dp(h,f,r);y&&(h=y.content,s.strategies[u.path]=y.strategy)}await n.writeFile(m,h),await n.deleteFile(d),s.filesModified.push(`${u.path} \u2192 ${u.newPath}`)}break}case"update":{let p=await n.readFile(d),m="exact",h=!0;for(let f of u.hunks){let y=dp(p,f,r);if(y)p=y.content,m=y.strategy;else{h=!1;let b=f.lines.filter(
|
|
444
|
+
`);await n.writeFile(d,p),s.filesAdded.push(u.path),s.strategies[u.path]="exact";break}case"delete":{await n.deleteFile(d),s.filesDeleted.push(u.path);break}case"move":{let p=await n.readFile(d);if(u.newPath){let m=n.resolvePath(u.newPath),h=p;for(let f of u.hunks){let y=dp(h,f,r);y&&(h=y.content,s.strategies[u.path]=y.strategy)}await n.writeFile(m,h),await n.deleteFile(d),s.filesModified.push(`${u.path} \u2192 ${u.newPath}`)}break}case"update":{let p=await n.readFile(d),m="exact",h=!0;for(let f of u.hunks){let y=dp(p,f,r);if(y)p=y.content,m=y.strategy;else{h=!1;let b=f.lines.filter(T=>T.prefix===" "||T.prefix==="-").map(T=>T.content).slice(0,5).join(`
|
|
445
445
|
`);s.errors.push(`${u.path}: hunk not matched. Search begins with:
|
|
446
446
|
${b}`)}}(h||p!==await n.readFile(d))&&(await n.writeFile(d,p),s.filesModified.push(u.path),s.strategies[u.path]=m);break}}}catch(p){s.errors.push(`${u.type} ${u.path}: ${p instanceof Error?p.message:String(p)}`)}}}else if(i){let l=dR(t.input);if(l.length===0)return{content:[{type:"text",text:"Error: Invalid search/replace format. Use <<<< SEARCH / ==== / >>>> REPLACE blocks."}],details:{type:"patch",error:"parse_failed"}};for(let u of l){let d=n.resolvePath(u.path);try{let p=await n.readFile(d),m=up(p,u.search,r);if(m.length===0){s.errors.push(`${u.path}: search text not matched (tried all 9 strategies)`);continue}let h=[...m].sort((f,y)=>y.start-f.start);for(let f of h)p=p.slice(0,f.start)+u.replace+p.slice(f.end);await n.writeFile(d,p),s.filesModified.push(u.path),s.strategies[u.path]=m[0].strategy}catch(p){s.errors.push(`${u.path}: ${p instanceof Error?p.message:String(p)}`)}}}else return lp(`*** Begin Patch
|
|
447
447
|
`+t.input+`
|
|
@@ -468,7 +468,7 @@ list: Show all active worktrees.`},name:{type:"string",description:"Worktree/bra
|
|
|
468
468
|
Restored to: ${s.previousCwd||"main workspace"}`}],details:{type:"worktree",action:"exit",exitAction:r,previousCwd:s.previousCwd}}:{content:[{type:"text",text:`Error: ${s.error||"failed to exit worktree"}`}],details:{type:"worktree",error:s.error}}}case"list":{let r=await n.listWorktrees();if(!r.worktrees||r.worktrees.length===0)return{content:[{type:"text",text:"No worktrees (only the main working tree)."}],details:{type:"worktree",action:"list",count:0}};let s=[`Worktrees (${r.worktrees.length}):`,""];for(let o of r.worktrees){let i=o.isCurrent?" \u2190 current":"",a=o.hasChanges?" (has changes)":"";s.push(` ${o.name} [${o.branch}]${i}${a}`),s.push(` path: ${o.path}`)}return{content:[{type:"text",text:s.join(`
|
|
469
469
|
`)}],details:{type:"worktree",action:"list",count:r.worktrees.length}}}default:return{content:[{type:"text",text:`Error: unknown action "${t.action}".`}],details:{type:"worktree",error:"unknown_action"}}}}}}ae();import{execFile as TR}from"node:child_process";import{promisify as RR}from"node:util";import{join as ln,resolve as hp,basename as qa}from"node:path";import{mkdir as Tp,rm as Rp,symlink as wR,readdir as L0,stat as AR}from"node:fs/promises";var cr=RR(TR),xR=/^[a-zA-Z0-9._-]+$/,yp=64;function wp(n){if(n.length>yp)throw new Error(`Invalid worktree name: must be ${yp} characters or fewer (got ${n.length})`);for(let e of n.split("/")){if(e==="."||e==="..")throw new Error(`Invalid worktree name "${n}": must not contain "." or ".." path segments`);if(!xR.test(e))throw new Error(`Invalid worktree name "${n}": segment must contain only letters, digits, dots, underscores, and dashes`)}}function Wa(n){return n.replaceAll("/","+")}function Ap(n){return`worktree-${Wa(n)}`}var nt=null;async function Le(n,e){try{let{stdout:t,stderr:r}=await cr("git",n,{cwd:e??process.cwd(),env:{...process.env,GIT_TERMINAL_PROMPT:"0",GIT_ASKPASS:""},timeout:3e4});return{stdout:t,stderr:r,code:0}}catch(t){let r=t;return{stdout:r.stdout??"",stderr:r.stderr??String(t),code:r.code??1}}}async function ar(n){let{stdout:e,code:t}=await Le(["rev-parse","--show-toplevel"],n);return t===0?e.trim():null}async function bp(n){let{stdout:e,code:t}=await Le(["status","--porcelain"],n);return t!==0?-1:e.trim().split(`
|
|
470
470
|
`).filter(Boolean).length}async function kp(n,e){let{stdout:t,code:r}=await Le(["rev-list",`origin/${e}..${e}`,"--count"],n);return r!==0?0:parseInt(t.trim(),10)||0}async function xp(n,e,t,r){for(let s of t){if(s.includes("..")||s.startsWith("/")||s.startsWith("\\")){r?.warn(`[worktree] skipping symlink for "${s}": path traversal detected`);continue}let o=ln(n,s),i=ln(e,s);try{await wR(o,i,"dir"),r?.info(`[worktree] symlinked ${s} from main repo to worktree`)}catch(a){let c=a.code;c!=="ENOENT"&&c!=="EEXIST"&&r?.warn(`[worktree] failed to symlink ${s} (${c??"unknown"}): ${a}`)}}}async function PR(n,e,t){let{code:r,stderr:s}=await Le(["sparse-checkout","set","--cone","--",...t],n);if(r!==0)throw await Le(["worktree","remove","--force",n],e),new Error(`Failed to configure sparse-checkout: ${s}`);let{code:o,stderr:i}=await Le(["checkout","HEAD"],n);if(o!==0)throw await Le(["worktree","remove","--force",n],e),new Error(`Failed to checkout sparse worktree: ${i}`);return!0}async function IR(){try{return await cr("tmux",["-V"],{timeout:5e3}),!0}catch{return!1}}function _R(n,e){return`${qa(n)}_${e}`.replace(/[/.]/g,"_")}async function CR(n,e){if(!await IR())return null;try{return await cr("tmux",["new-session","-d","-s",e,"-c",n],{timeout:1e4}),e}catch{return null}}async function vp(n){try{return await cr("tmux",["kill-session","-t",n],{timeout:5e3}),!0}catch{return!1}}async function Sp(n,e,t,r){let s=bd(e),o=ln(s,n);try{if(!(await AR(o)).isFile())return null}catch{return null}try{let{stdout:i,stderr:a}=await cr(o,[],{cwd:e,env:{...process.env,...t},timeout:3e4});return r?.info(`[worktree] hook ${n} succeeded: ${i.trim()}`),i.trim()||null}catch(i){return r?.warn(`[worktree] hook ${n} failed: ${i}`),null}}async function Pp(n,e,t){wp(e);let r=Wa(e),s=Ap(e),o=ln(n,".worktrees"),i=ln(o,r);await Tp(o,{recursive:!0});let{code:a,stderr:c}=await Le(["worktree","add","-B",s,i,"HEAD"],n);return a!==0?(t?.warn(`[worktree] agent worktree creation failed: ${c}`),null):(await xp(n,i,["node_modules"],t),t?.info(`[worktree] agent worktree created: ${e} at ${i}`),{worktreePath:i,branch:s})}async function Ip(n,e,t,r){let{code:s}=await Le(["worktree","remove","--force",e],n);return s!==0&&(await Rp(e,{recursive:!0,force:!0}).catch(()=>{}),await Le(["worktree","prune"],n)),await Le(["branch","-D",t],n),r?.info(`[worktree] agent worktree removed: ${e}`),!0}function _p(n){let{log:e,symlinkDirs:t=["node_modules"],sparsePaths:r}=n;return{async enterWorktree(s){try{let o=Date.now(),i=await ar();if(!i)return{success:!1,error:"Not in a git repository"};let a=await Sp("worktree-create",i,{WORKTREE_NAME:s??""},e);if(a){let L=process.cwd();return process.chdir(a),nt={originalCwd:L,worktreePath:a,worktreeName:s??qa(a),worktreeBranch:"",hookBased:!0,creationDurationMs:Date.now()-o},{success:!0,worktree:{name:nt.worktreeName,path:a,branch:"",isCurrent:!0,hasChanges:!1,unpushedCommits:0}}}let c=s??`agent-${Date.now().toString(36)}`;wp(c);let l=Wa(c),u=Ap(c),d=ln(i,".worktrees"),p=ln(d,l);await Tp(d,{recursive:!0});let{stdout:m}=await Le(["worktree","list","--porcelain"],i),h=m.split(`
|
|
471
|
-
`).find(L=>L.startsWith("worktree ")&&L.includes(l));if(h){let L=h.replace("worktree ","").trim(),F=process.cwd();return process.chdir(L),nt={originalCwd:F,worktreePath:L,worktreeName:c,worktreeBranch:u},e.info(`[worktree] resumed existing worktree: ${c} at ${L}`),{success:!0,worktree:{name:c,path:L,branch:u,isCurrent:!0,hasChanges:!1,unpushedCommits:0}}}let f=r&&r.length>0,y=["worktree","add"];f&&y.push("--no-checkout"),y.push("-B",u,p,"HEAD");let{code:b,stderr:
|
|
471
|
+
`).find(L=>L.startsWith("worktree ")&&L.includes(l));if(h){let L=h.replace("worktree ","").trim(),F=process.cwd();return process.chdir(L),nt={originalCwd:F,worktreePath:L,worktreeName:c,worktreeBranch:u},e.info(`[worktree] resumed existing worktree: ${c} at ${L}`),{success:!0,worktree:{name:c,path:L,branch:u,isCurrent:!0,hasChanges:!1,unpushedCommits:0}}}let f=r&&r.length>0,y=["worktree","add"];f&&y.push("--no-checkout"),y.push("-B",u,p,"HEAD");let{code:b,stderr:T}=await Le(y,i);if(b!==0)return{success:!1,error:`git worktree add failed: ${T.trim()}`};let w=!1;f&&r&&(await PR(p,i,r),w=!0),await xp(i,p,t,e);let _=process.cwd();process.chdir(p);let I=_R(i,u),D=await CR(p,I);return nt={originalCwd:_,worktreePath:p,worktreeName:c,worktreeBranch:u,tmuxSessionName:D??void 0,creationDurationMs:Date.now()-o,usedSparsePaths:w},e.info(`[worktree] entered: ${c} at ${p}`),{success:!0,worktree:{name:c,path:p,branch:u,isCurrent:!0,hasChanges:!1,unpushedCommits:0}}}catch(o){return{success:!1,error:o instanceof Error?o.message:String(o)}}},async exitWorktree(s,o){if(!nt)return{success:!1,error:"Not in a worktree"};try{let i=nt,a=await ar(i.originalCwd);if(!a)return{success:!1,error:"Original git root not found"};if(s==="remove"){let c=await bp(i.worktreePath),l=await kp(i.worktreePath,i.worktreeBranch);if((c>0||l>0)&&!o)return{success:!1,error:`Worktree has ${c} uncommitted change(s) and ${l} unpushed commit(s). Set discardChanges=true to confirm.`};process.chdir(i.originalCwd),nt=null,i.tmuxSessionName&&await vp(i.tmuxSessionName),await Sp("worktree-remove",a,{WORKTREE_PATH:i.worktreePath},e);let u=["worktree","remove"];o&&u.push("--force"),u.push(i.worktreePath);let{code:d,stderr:p}=await Le(u,a);d!==0&&(e.warn(`[worktree] git worktree remove failed: ${p.trim()}, cleaning up manually`),await Rp(i.worktreePath,{recursive:!0,force:!0}).catch(()=>{}),await Le(["worktree","prune"],a)),await Le(["branch","-D",i.worktreeBranch],a),e.info(`[worktree] removed: ${i.worktreeName}`)}else process.chdir(i.originalCwd),i.tmuxSessionName&&await vp(i.tmuxSessionName),nt=null,e.info(`[worktree] exited (kept): ${i.worktreeName}`);return{success:!0,previousCwd:i.originalCwd}}catch(i){return{success:!1,error:i instanceof Error?i.message:String(i)}}},async listWorktrees(){try{let{stdout:s,code:o}=await Le(["worktree","list","--porcelain"]);if(o!==0)return{success:!0,worktrees:[]};let i=[],a=process.cwd(),c=s.split(`
|
|
472
472
|
|
|
473
473
|
`).filter(Boolean);for(let l of c){let u=l.split(`
|
|
474
474
|
`),d="",p="";for(let y of u)y.startsWith("worktree ")&&(d=y.slice(9).trim()),y.startsWith("branch ")&&(p=y.slice(7).trim().replace("refs/heads/",""));if(!d)continue;let m=hp(d)===hp(a),h=await bp(d),f=await kp(d,p);i.push({name:p.startsWith("worktree-")?p.slice(9):qa(d),path:d,branch:p,isCurrent:m,hasChanges:h>0,unpushedCommits:f})}return{success:!0,worktrees:i}}catch(s){return{success:!1,error:s instanceof Error?s.message:String(s)}}},isInWorktree(){return nt!==null},currentWorktree(){return nt?{name:nt.worktreeName,path:nt.worktreePath,branch:nt.worktreeBranch,isCurrent:!0,hasChanges:!1,unpushedCommits:0}:null}}}import{readFile as ER,writeFile as MR}from"node:fs/promises";import*as Cp from"node:path";var DR={type:"object",properties:{notebook_path:{type:"string",description:"Absolute path to the .ipynb notebook file."},cell_number:{type:"number",description:"1-based cell number to operate on. For 'insert', the new cell is inserted after this cell (use 0 to insert at the beginning)."},new_source:{type:"string",description:"New cell content. Required for 'replace' and 'insert' modes."},cell_type:{type:"string",enum:["code","markdown"],description:"Cell type for 'insert' mode. Default: 'code'."},edit_mode:{type:"string",enum:["replace","insert","delete"],description:"Edit operation: replace (default), insert (after cell_number), or delete."}},required:["notebook_path","cell_number"]};function Ep(n){let e=n.split(`
|
|
@@ -485,7 +485,7 @@ ${d}${p}`}],details:{type:"notebook_edit",edit_mode:s,cell_number:r,total_cells:
|
|
|
485
485
|
run: Execute a workflow by name.
|
|
486
486
|
describe: Show workflow steps and variables.`},workflow:{type:"string",description:"Workflow name (required for 'run' and 'describe')."},variables:{type:"object",description:"Variable overrides (key-value pairs) for the workflow run.",additionalProperties:{type:"string"}}},required:["action"]};async function Ga(n){let e=new Map,t=hd(n);await Np(t,e);let r=gd();return await Np(r,e),e}async function Np(n,e){if(jR(n))try{let t=await $R(n,{withFileTypes:!0});for(let r of t)if(r.isFile()&&r.name.endsWith(".json")){let s=r.name.replace(/\.json$/,"");e.has(s)||e.set(s,Op.join(n,r.name))}}catch{}}async function Ka(n){let e=await LR(n,"utf-8");return JSON.parse(e)}function FR(n){let e=new Map(n.map(o=>[o.id,o])),t=new Set,r=[];function s(o,i){if(t.has(o))return;if(i.has(o))throw new Error(`Circular dependency detected at step: ${o}`);i.add(o);let a=e.get(o);if(!a)throw new Error(`Unknown step dependency: ${o}`);for(let c of a.dependsOn??[])s(c,i);i.delete(o),t.add(o),r.push(a)}for(let o of n)s(o.id,new Set);return r}function BR(n,e,t){let r={};for(let[s,o]of Object.entries(n))if(typeof o=="string"){let i=o;i=i.replace(/\$\{var\.(\w+)\}/g,(a,c)=>e[c]??`\${var.${c}}`),i=i.replace(/\$\{step\.(\w+)\.result\}/g,(a,c)=>t.get(c)?.output??""),r[s]=i}else r[s]=o;return r}function Lp(n){return{name:"workflow",label:"Workflow",description:"Execute predefined automation workflows. Workflows are step-based pipelines defined as JSON files in .qlogicagent/workflows/ or ~/.qlogicagent/workflows/. Steps run in dependency order, support variable interpolation, and can reference previous step outputs via ${step.<id>.result}.",parameters:UR,shouldDefer:!0,isConcurrencySafe:!1,isReadOnly:!1,searchHint:"workflow pipeline automation steps DAG",execute:async(e,t,r)=>{let s=n.getCwd();switch(t.action){case"list":{let o=await Ga(s);if(o.size===0)return{content:[{type:"text",text:"No workflows found. Create .json files in .qlogicagent/workflows/ or ~/.qlogicagent/workflows/."}],details:{type:"workflow",action:"list",count:0}};let i=["Available workflows:"];for(let[a,c]of o)try{let l=await Ka(c);i.push(` - ${a}: ${l.description??"(no description)"} (${l.steps.length} steps)`)}catch{i.push(` - ${a}: (failed to load)`)}return{content:[{type:"text",text:i.join(`
|
|
487
487
|
`)}],details:{type:"workflow",action:"list",count:o.size}}}case"describe":{if(!t.workflow)return{content:[{type:"text",text:"Error: 'workflow' parameter is required for 'describe'."}],details:{error:"missing_workflow"}};let i=(await Ga(s)).get(t.workflow);if(!i)return{content:[{type:"text",text:`Error: Workflow "${t.workflow}" not found.`}],details:{error:"not_found"}};let a=await Ka(i),c=[`Workflow: ${a.name}`,a.description?`Description: ${a.description}`:"","","Steps:"];for(let l of a.steps){let u=l.dependsOn?.length?` (after: ${l.dependsOn.join(", ")})`:"";c.push(` ${l.id}: ${l.label??l.tool}${u}`),c.push(` tool: ${l.tool}`),c.push(` args: ${JSON.stringify(l.args)}`)}if(a.variables&&Object.keys(a.variables).length>0){c.push("","Variables (defaults):");for(let[l,u]of Object.entries(a.variables))c.push(` ${l} = ${u}`)}return{content:[{type:"text",text:c.filter(Boolean).join(`
|
|
488
|
-
`)}],details:{type:"workflow",action:"describe",workflow:a.name}}}case"run":{if(!t.workflow)return{content:[{type:"text",text:"Error: 'workflow' parameter is required for 'run'."}],details:{error:"missing_workflow"}};let i=(await Ga(s)).get(t.workflow);if(!i)return{content:[{type:"text",text:`Error: Workflow "${t.workflow}" not found.`}],details:{error:"not_found"}};let a=await Ka(i),c={...a.variables,...t.variables},l;try{l=FR(a.steps)}catch(m){return{content:[{type:"text",text:`Error: ${m.message}`}],details:{error:"dag_error"}}}let u=new Map,d=[`Running workflow: ${a.name}`,""],p=!0;for(let m of l){if(r?.aborted){d.push(`\u26A1 Aborted at step: ${m.id}`),p=!1;break}let h=(m.dependsOn??[]).some(b=>!u.get(b)?.success),f=m.condition??"on_success";if(f==="on_success"&&h){d.push(`\u23ED Skipped ${m.id} (dependency failed)`),u.set(m.id,{stepId:m.id,success:!1,output:"",error:"dependency_failed"}),p=!1;continue}if(f==="on_failure"&&!h){d.push(`\u23ED Skipped ${m.id} (no failure to handle)`),u.set(m.id,{stepId:m.id,success:!0,output:""});continue}d.push(`\u25B6 ${m.id}: ${m.label??m.tool}`);let y=BR(m.args,c,u);try{let b=await n.invokeTool(m.tool,y,r),
|
|
488
|
+
`)}],details:{type:"workflow",action:"describe",workflow:a.name}}}case"run":{if(!t.workflow)return{content:[{type:"text",text:"Error: 'workflow' parameter is required for 'run'."}],details:{error:"missing_workflow"}};let i=(await Ga(s)).get(t.workflow);if(!i)return{content:[{type:"text",text:`Error: Workflow "${t.workflow}" not found.`}],details:{error:"not_found"}};let a=await Ka(i),c={...a.variables,...t.variables},l;try{l=FR(a.steps)}catch(m){return{content:[{type:"text",text:`Error: ${m.message}`}],details:{error:"dag_error"}}}let u=new Map,d=[`Running workflow: ${a.name}`,""],p=!0;for(let m of l){if(r?.aborted){d.push(`\u26A1 Aborted at step: ${m.id}`),p=!1;break}let h=(m.dependsOn??[]).some(b=>!u.get(b)?.success),f=m.condition??"on_success";if(f==="on_success"&&h){d.push(`\u23ED Skipped ${m.id} (dependency failed)`),u.set(m.id,{stepId:m.id,success:!1,output:"",error:"dependency_failed"}),p=!1;continue}if(f==="on_failure"&&!h){d.push(`\u23ED Skipped ${m.id} (no failure to handle)`),u.set(m.id,{stepId:m.id,success:!0,output:""});continue}d.push(`\u25B6 ${m.id}: ${m.label??m.tool}`);let y=BR(m.args,c,u);try{let b=await n.invokeTool(m.tool,y,r),T=!b.error;if(u.set(m.id,{stepId:m.id,success:T,output:b.result,error:b.error}),T){let w=b.result.length>200?b.result.slice(0,200)+"...":b.result;d.push(` \u2705 ${w}`)}else d.push(` \u274C ${b.error}`),p=!1}catch(b){let T=b.message;u.set(m.id,{stepId:m.id,success:!1,output:"",error:T}),d.push(` \u274C ${T}`),p=!1}}return d.push("",p?"Workflow completed successfully.":"Workflow completed with errors."),{content:[{type:"text",text:d.join(`
|
|
489
489
|
`)}],details:{type:"workflow",action:"run",workflow:a.name,success:p,stepsExecuted:u.size,totalSteps:a.steps.length}}}default:return{content:[{type:"text",text:`Error: unknown action "${t.action}". Use list, run, or describe.`}],details:{error:"unknown_action"}}}}}}var HR="sleep",qR={type:"object",properties:{duration:{type:"number",description:"Duration to sleep in seconds (1\u20133600). Prefer short sleeps (10\u201360s) to stay responsive.",minimum:1,maximum:3600},reason:{type:"string",description:'Brief reason for sleeping. Examples: "waiting for build to finish", "nothing to do", "user asked to rest".'}},required:["duration"]};function $p(n){return{name:HR,label:"Sleep",shouldDefer:!0,isConcurrencySafe:!0,isReadOnly:!0,searchHint:"wait sleep rest idle tick proactive",description:["Wait for a specified duration. The user can interrupt the sleep at any time.","","Use this when:","\u2022 You have nothing useful to do right now","\u2022 You're waiting for an external process to complete","\u2022 The user tells you to sleep or rest","\u2022 You receive a <tick> check-in with no actionable work","","Prefer this over `exec(sleep ...)` \u2014 it doesn't hold a shell process.","You can call this concurrently with other tools \u2014 it won't interfere with them.","","Each wake-up costs an API call, but the prompt cache expires after 5 minutes of inactivity \u2014 balance accordingly."].join(`
|
|
490
490
|
`),parameters:qR,execute:async(e,t,r)=>{let s=Math.max(1,Math.min(3600,Math.round(t.duration))),o=s*1e3,i=new AbortController,a=()=>i.abort();r?.addEventListener("abort",a,{once:!0}),r?.aborted&&i.abort();try{let c=await n.sleep(o,i.signal),l=[];return c.interrupted?(l.push(`Sleep interrupted after ${c.sleptSeconds}s.`),c.interruptReason&&l.push(`Reason: ${c.interruptReason}`),l.push("Check for new messages or tasks.")):l.push(`Slept for ${c.sleptSeconds}s. Waking up.`),{content:[{type:"text",text:l.join(`
|
|
491
491
|
`)}],details:{...c,requestedSeconds:s}}}finally{r?.removeEventListener("abort",a)}}}}var WR="tool_search",GR={type:"object",properties:{query:{type:"string",description:'Search query for tools. Use "select:toolName" to directly activate a deferred tool, or provide keywords to search tool names/descriptions. Prefix a term with "+" to mark it as required (all +terms must match).'},maxResults:{type:"number",description:"Maximum number of results to return (default: 5)."}},required:["query"]},KR=5;function Up(n){return{name:WR,label:"Tool Search",description:'Search for available tools that are not currently loaded. Many tools are deferred to save context tokens. Use "select:toolName" to directly activate a tool, or provide keywords to find relevant tools. Activated tools become available in subsequent messages.',parameters:GR,execute:async(e,t)=>{if(!t.query||t.query.trim().length===0)return{content:[{type:"text",text:"Error: query is required."}],details:{type:"tool_search",error:"empty_query"}};let r=t.query.trim(),s=t.maxResults??KR;if(r.startsWith("select:")){let i=r.slice(7).split(",").map(u=>u.trim()).filter(Boolean),a=[],c=[];if(n.activateTool)for(let u of i)await n.activateTool(u)?a.push(u):c.push(u);else{let u=await n.searchTools(r,{maxResults:s});return jp(u)}let l=[];return a.length>0&&l.push(`Activated: ${a.join(", ")}. These tools are now available.`),c.length>0&&l.push(`Not found: ${c.join(", ")}.`),{content:[{type:"text",text:l.join(`
|
|
@@ -500,15 +500,15 @@ describe: Show workflow steps and variables.`},workflow:{type:"string",descripti
|
|
|
500
500
|
`+a.map(c=>` - ${c}`).join(`
|
|
501
501
|
`))}async function sm(n,e,t){let r=ve.getTransport(n);if(!r)return{ok:!1,error:"transport not available"};let s=Ue[n];if(!s)return{ok:!1,error:"no API key"};try{let o={...t,model:e},i=await r.generate(o,s);i.billingUnit||(t.mediaType==="tts"&&t.text?(i.billingUnit="per_character",i.billingQuantity=t.text.length):(t.mediaType==="video"||t.mediaType==="music")&&t.duration?(i.billingUnit="per_second",i.billingQuantity=t.duration):(i.billingUnit="per_call",i.billingQuantity=1));let a=i.model??o.model,c=i.billingUnit??"per_call",l=i.billingQuantity??1;return am?.(a,c,l),{ok:!0,result:i}}catch(o){return{ok:!1,error:o instanceof Error?o.message:String(o)}}}function Pt(n){if(!ve)return!1;let e=Yt[n];if(!e)return!1;let t=ve.getTransport(e.provider),r=Ue[e.provider];return!!(t&&r)}function Qa(n,e){if(!Pt(n))return!1;let t=Yt[n],r=ve.resolveModelById(t.provider,t.model,n);if(!r)return!1;let s=r.modelInfo.mediaCapabilities;return!s||!("operations"in s)||!s.operations?!0:s.operations.includes(e)}function Ts(){if(!ve)return;for(let[,e]of Object.entries(Yt)){if(!e)continue;let t=ve.getTransport(e.provider),r=Ue[e.provider];if(t instanceof lr&&r)return{id:e.provider,type:"volcengine"}}if(Ue.google)return{id:"google",type:"gemini"}}var Za;function Rs(){return Za||(Za=new xw({baseUrl:"https://generativelanguage.googleapis.com/v1beta"})),Za}var rt=process.cwd(),nc=!1;function gm(n){rt=n,nc=!0,bs(n)}function Fe(n){return K.isAbsolute(n)?K.normalize(n):K.resolve(rt,n)}function dr(n){let e=K.resolve(rt)+K.sep,t=K.resolve(n);return process.platform==="win32"?t.toLowerCase().startsWith(e.toLowerCase())||t.toLowerCase()===e.slice(0,-1).toLowerCase():t.startsWith(e)||t===e.slice(0,-1)}function Ft(n){return dr(n)?null:`Blocked: path "${n}" is outside the workspace boundary "${rt}"`}function om(n){let e=n.replace(/\\/g,"/");return e.includes("../")||e.includes("..")}var Ow=new Set([".png",".jpg",".jpeg",".gif",".webp",".bmp",".svg",".ico"]),fm=new Set([".exe",".dll",".so",".dylib",".zip",".tar",".gz",".7z",".rar",".wasm",".class"]),rc=new Set,Lw={".pdf":"application/pdf",".txt":"text/plain",".html":"text/html",".htm":"text/html",".css":"text/css",".js":"text/javascript",".ts":"text/plain",".json":"application/json",".xml":"application/xml",".csv":"text/csv",".md":"text/markdown",".png":"image/png",".jpg":"image/jpeg",".jpeg":"image/jpeg",".gif":"image/gif",".webp":"image/webp",".bmp":"image/bmp",".svg":"image/svg+xml",".mp3":"audio/mpeg",".wav":"audio/wav",".ogg":"audio/ogg",".flac":"audio/flac",".m4a":"audio/mp4",".aac":"audio/aac",".mp4":"video/mp4",".webm":"video/webm",".avi":"video/x-msvideo",".mov":"video/quicktime",".doc":"application/msword",".docx":"application/vnd.openxmlformats-officedocument.wordprocessingml.document",".xls":"application/vnd.ms-excel",".xlsx":"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",".pptx":"application/vnd.openxmlformats-officedocument.presentationml.presentation"};function $w(){return{resolvePath:Fe,async readFile(n){let e=Fe(n),t=K.extname(e).toLowerCase();if(nc){let s=Ft(e);if(s)throw new Error(s)}else if(om(n)&&!dr(e))throw new Error(`Blocked: path traversal "${n}" escapes workspace "${rt}"`);if(e.startsWith("/dev/")||e.startsWith("/proc/")||e.startsWith("/sys/"))throw new Error(`Blocked: reading device/system path ${e}`);if(fm.has(t))return{type:"binary",mimeType:"application/octet-stream"};if(Ow.has(t))return{type:"image",localPath:e,mimeType:t===".png"?"image/png":t===".svg"?"image/svg+xml":t===".gif"?"image/gif":t===".webp"?"image/webp":"image/jpeg"};let r=await G.promises.readFile(e,"utf8");return rc.add(e),{type:"text",text:r}},validatePath(n){let e=Fe(n);if(nc){let t=Ft(e);if(t)return t}else if(om(n)&&!dr(e))return`Blocked: path traversal "${n}" escapes workspace "${rt}"`;return e.startsWith("/dev/")||e.startsWith("/proc/")||e.startsWith("/sys/")?`Blocked: reading device/system path ${e}`:sc&&Ja(e)?"Blocked: reading sensitive file in group chat mode":null}}}function jw(){return{resolvePath:Fe,validatePath(n){let e=Fe(n),t=Ft(e);return t||(e.startsWith("/dev/")||e.startsWith("/proc/")||e.startsWith("/sys/")?`Blocked: writing to device/system path ${e}`:sc&&Ja(e)?"Blocked: writing sensitive file in group chat mode":null)},checkReadBeforeWrite(n){try{G.accessSync(n,G.constants.F_OK)}catch{return null}return rc.has(n)?null:"File already exists but has not been read yet in this session. Read it first with the read tool before overwriting, to avoid unintended data loss. If you intend to completely replace the file, read it first to confirm."},async writeFile(n,e){let t=Fe(n),r=Ft(t);if(r)throw new Error(r);await G.promises.mkdir(K.dirname(t),{recursive:!0}),await G.promises.writeFile(t,e,"utf8"),rc.add(t)}}}function Uw(){return{resolvePath:Fe,async readFile(n){let e=Fe(n),t=Ft(e);if(t)throw new Error(t);return G.promises.readFile(e,"utf8")},async writeFile(n,e){let t=Fe(n),r=Ft(t);if(r)throw new Error(r);await G.promises.mkdir(K.dirname(t),{recursive:!0}),await G.promises.writeFile(t,e,"utf8")}}}function Fw(){return{resolvePath:Fe,async readFile(n){let e=Fe(n),t=Ft(e);if(t)throw new Error(t);return G.promises.readFile(e,"utf8")},async writeFile(n,e){let t=Fe(n),r=Ft(t);if(r)throw new Error(r);await G.promises.mkdir(K.dirname(t),{recursive:!0}),await G.promises.writeFile(t,e,"utf8")},async deleteFile(n){let e=Fe(n),t=Ft(e);if(t)throw new Error(t);await G.promises.unlink(e)},async fileExists(n){let e=Fe(n);try{return await G.promises.access(e),!0}catch{return!1}}}}function Bw(){return{resolvePath:Fe,async glob(n,e){let t=e.cwd||rt,r=e.limit||1e3,s=[],o=!1,i=n.replace(/\\/g,"/").split("/"),a=i.some(u=>u==="**"),c=i[i.length-1]??"*",l=hm(c);try{await cc(t,async u=>{if(s.length>=r)return o=!0,!1;let d=K.basename(u);return l.test(d)&&s.push(u),!0},a?1/0:1)}catch{}return{files:s,truncated:o}},async grep(n,e){let t=e.cwd||rt;try{return await qw(n,t,e)}catch{return await Ww(n,t,e)}}}}function hm(n){let e=n.replace(/[.+^$|()[\]\\]/g,"\\$&").replace(/\*/g,".*").replace(/\?/g,".");return e=e.replace(/\\\{([^}]+)\\\}/g,(t,r)=>"("+r.replace(/,/g,"|")+")"),new RegExp(`^${e}$`,"i")}var Hw=new Set([".git",".svn",".hg","node_modules","__pycache__",".next","dist",".tox",".venv"]);async function cc(n,e,t,r=0,s=""){if(r>t)return;let o;try{o=await G.promises.readdir(n,{withFileTypes:!0})}catch{return}for(let i of o){let a=s?`${s}/${i.name}`:i.name;if(i.isDirectory()){if(Hw.has(i.name))continue;await cc(K.join(n,i.name),e,t,r+1,a)}else if(i.isFile()&&!await e(a))return}}function qw(n,e,t){return new Promise((r,s)=>{let o=["--json","--no-heading","--max-columns","500"];t.caseInsensitive&&o.push("-i"),t.contextLines&&o.push("-C",String(t.contextLines)),t.fileGlob&&o.push("-g",t.fileGlob),o.push("--max-count",String(t.headLimit??250)),o.push(n),o.push("."),Rw("rg",o,{cwd:e,maxBuffer:10*1024*1024,timeout:3e4},(i,a)=>{if(i&&!("killed"in i&&i.killed)&&i.code!==1){s(i);return}let c=[];for(let p of a.split(`
|
|
502
502
|
`))if(p.trim())try{let m=JSON.parse(p);m.type==="match"&&m.data&&c.push({path:m.data.path?.text??"",line:m.data.line_number??0,text:(m.data.lines?.text??"").trimEnd()})}catch{}let l=t.headLimit??250,u=t.offset??0,d=c.slice(u,u+l);r({matches:d,truncated:c.length>u+l})})})}async function Ww(n,e,t){let r=new RegExp(n,t.caseInsensitive?"i":""),s=t.headLimit??250,o=t.offset??0,i=t.fileGlob?hm(t.fileGlob):null,a=[],c=!1;return await cc(e,async l=>{if(a.length>=o+s+1)return c=!0,!1;if(i&&!i.test(K.basename(l)))return!0;let u=K.extname(l).toLowerCase();if(fm.has(u))return!0;try{let p=(await G.promises.readFile(K.join(e,l),"utf8")).split(`
|
|
503
|
-
`);for(let m=0;m<p.length;m++)if(r.test(p[m])&&(a.push({path:l,line:m+1,text:p[m].slice(0,500)}),a.length>=o+s+1))return c=!0,!1}catch{}return!0},1/0),{matches:a.slice(o,o+s),truncated:c}}var im=!1;function Gw(){if(!im)if(im=!0,cn()){let n=process.env.QLOGICAGENT_POWERSHELL_PATH??"powershell.exe";ir($a(n))}else if(process.platform==="win32"){let n=Kw();ir(Ss(n))}else{let n=process.env.SHELL?.endsWith("bash")?process.env.SHELL:"/bin/bash";ir(Ss(n))}}function Kw(){let n=process.env.QLOGICAGENT_BASH_PATH;if(n&&G.existsSync(n))return n;let e=["C:\\Program Files\\Git\\bin\\bash.exe","C:\\Program Files (x86)\\Git\\bin\\bash.exe"],t=process.env.ProgramFiles?K.join(process.env.ProgramFiles,"Git","bin","bash.exe"):null;t&&!e.includes(t)&&e.unshift(t);for(let r of e)if(G.existsSync(r))return r;return"bash"}function Vw(){return{async fetchUrl(n){let e=new AbortController,t=setTimeout(()=>e.abort(),3e4);try{let r=await fetch(n.url,{signal:e.signal,headers:{"User-Agent":"Mozilla/5.0 (compatible; QLogicAgent/1.0)",Accept:"text/html,application/xhtml+xml,text/plain,*/*"},redirect:"follow"});if(!r.ok)return{content:`HTTP ${r.status} ${r.statusText}`};let s=r.headers.get("content-type")??"",o=await r.text();return n.maxChars&&o.length>n.maxChars&&(o=o.slice(0,n.maxChars)),s.includes("html")&&n.extractMode!=="json"&&(o=zw(o)),{content:o,title:Xw(o)}}finally{clearTimeout(t)}}}}function zw(n){return n.replace(/<script[\s\S]*?<\/script>/gi,"").replace(/<style[\s\S]*?<\/style>/gi,"").replace(/<[^>]+>/g," ").replace(/ /gi," ").replace(/&/gi,"&").replace(/</gi,"<").replace(/>/gi,">").replace(/"/gi,'"').replace(/'/gi,"'").replace(/\s{2,}/g," ").trim()}function Xw(n){return n.match(/<title[^>]*>([^<]+)<\/title>/i)?.[1]?.trim()}function Yw(){let n=async(e,t)=>{let{getModelRegistry:r}=await Promise.resolve().then(()=>(dt(),Sd)),s=r().getTunable("searxngBaseUrl")??process.env.SEARXNG_BASE_URL?.trim();if(!s)return{query:e,results:[],totalResults:0};let o=t?.maxResults??10,i=new URL("/search",s);i.searchParams.set("q",e),i.searchParams.set("format","json"),i.searchParams.set("pageno","1");let a=new AbortController,c=setTimeout(()=>a.abort(),15e3);try{let l=await fetch(i.toString(),{signal:a.signal,headers:{Accept:"application/json"}});if(!l.ok)return{query:e,results:[]};let u=await l.json(),d=(u.results??[]).slice(0,o).map(p=>({title:p.title??"",url:p.url??"",snippet:p.content??""}));if(t?.allowedDomains?.length){let p=new Set(t.allowedDomains.map(m=>m.toLowerCase()));return{query:e,results:d.filter(m=>{try{return p.has(new URL(m.url).hostname.toLowerCase())}catch{return!1}})}}if(t?.blockedDomains?.length){let p=new Set(t.blockedDomains.map(m=>m.toLowerCase()));return{query:e,results:d.filter(m=>{try{return!p.has(new URL(m.url).hostname.toLowerCase())}catch{return!0}})}}return{query:e,results:d,totalResults:u.number_of_results}}finally{clearTimeout(c)}};return{search:(e,t)=>nm(cm,n)(e,t)}}function Jw(){let n=K.join(process.env.HOME??process.env.USERPROFILE??".",".qlogicagent");function e(s){return K.join(n,"projects",s,".instructions")}function t(s,o){if(!o.endsWith(".md"))throw new Error("Filename must end with .md");if(o.includes(".."))throw new Error("Path traversal not allowed");let i=e(s),a=K.resolve(i,o);if(!a.startsWith(i+K.sep)&&a!==i)throw new Error("Path traversal not allowed");return a}function r(s,o){if(!G.existsSync(s))return[];let i=[];for(let a of G.readdirSync(s,{withFileTypes:!0})){let c=K.join(s,a.name);if(a.isDirectory())i.push(...r(c,o));else if(a.isFile()&&a.name.endsWith(".md")){let l=G.statSync(c);i.push({filename:K.relative(o,c).replace(/\\/g,"/"),path:c,size:l.size,updatedAt:l.mtime.toISOString(),content:G.readFileSync(c,"utf-8")})}}return i}return{list(s){let o=e(s);return r(o,o).map(i=>({filename:i.filename,path:i.path,size:i.size,updatedAt:i.updatedAt}))},read(s,o){try{let i=t(s,o);if(!G.existsSync(i))return null;let a=G.statSync(i),c=G.readFileSync(i,"utf-8");return{filename:o,path:i,size:a.size,updatedAt:a.mtime.toISOString(),content:c}}catch{return null}},write(s,o,i){let a=t(s,o);G.mkdirSync(K.dirname(a),{recursive:!0}),G.writeFileSync(a,i,"utf-8");let c=G.statSync(a);return{filename:o,path:a,size:c.size,updatedAt:c.mtime.toISOString(),content:i}},remove(s,o){try{let i=t(s,o);return G.existsSync(i)?(G.unlinkSync(i),!0):!1}catch{return!1}}}}function ym(n){n?.workdir&&(rt=n.workdir),Gw(),bs(rt);let e=[];e.push(Du()),e.push(Nu(void 0,{onTaskCreated:d=>tc?.onTaskCreated?.(d),onTaskCompleted:d=>tc?.onTaskCompleted?.(d)})),e.push(em({askUser:async d=>dm?.(d)??null})),e.push(Vu({onProgress:n?.onExecProgress,validateCommand:async d=>{let p=/(?:>>?|[12]>)\s*(?:"([^"]+)"|'([^']+)'|(\S+))/g,m;for(;(m=p.exec(d))!==null;){let f=m[1]||m[2]||m[3];if(f){let y=K.isAbsolute(f)?K.normalize(f):K.resolve(rt,f);if(!dr(y))return`Blocked: output redirection to path outside workspace: ${f}`}}let h=[/(?:^|[\s;|&(])(?:"(\/[^"]+)"|'(\/[^']+)'|(\/(?!dev\/null\b)[^\s;|&><)]+))/g,/(?:^|[\s;|&(])(?:"([A-Za-z]:[\\\/][^"]+)"|'([A-Za-z]:[\\\/][^']+)'|([A-Za-z]:[\\\/][^\s;|&><)]+))/g,/(?:^|[\s;|&(])(?:"([^"]*\.\.[\\/][^"]+)"|'([^']*\.\.[\\/][^']+)'|([^\s;|&><)"']*\.\.[\\/][^\s;|&><)]+))/g];for(let f of h){let y;for(;(y=f.exec(d))!==null;){let b=y[1]||y[2]||y[3];if(!b||/^\/[a-zA-Z](?:[- ]|$)/.test(b)||/^\/[a-zA-Z]{1,3}$/.test(b))continue;let
|
|
504
|
-
`),error:f.details?.error}}catch(f){return{result:"",error:f.message}}},getCwd:()=>rt};e.push(Lp(c)),e.push($p({sleep:(d,p)=>new Promise(m=>{let h=Date.now(),f=setTimeout(()=>{m({sleptSeconds:Math.round((Date.now()-h)/1e3),interrupted:!1})},d),y=()=>{clearTimeout(f),m({sleptSeconds:Math.round((Date.now()-h)/1e3),interrupted:!0,interruptReason:"aborted"})};p.addEventListener("abort",y,{once:!0}),p.aborted&&(clearTimeout(f),y())})}));let l={listProjects:()=>me(),switchProject:d=>ut(d),onSwitched:d=>_w?.(d)};e.push(tm(l)),e.push(Up({searchTools:async(d,p)=>{let m=p?.maxResults??5,h=zt(),f=d.toLowerCase().split(/\s+/).filter(Boolean),y=[],b=[];for(let D of f)D.startsWith("+")&&D.length>1?y.push(D.slice(1)):b.push(D);let S=[...y,...b],w=D=>D.replace(/([a-z])([A-Z])/g,"$1 $2").replace(/_/g," ").toLowerCase().split(/\s+/).filter(Boolean);return{matches:h.map(D=>{let L=tt(D),F=w(D),T=(L?.description??"").toLowerCase(),ce=(L?.searchHint??"").toLowerCase();if(y.length>0){let j=`${F.join(" ")} ${T} ${ce}`;if(!y.every(oe=>j.includes(oe)))return null}let le=0;for(let j of S){let ke=0;F.some(oe=>oe===j)?ke=10:F.some(oe=>oe.includes(j))?ke=5:D.toLowerCase().includes(j)&&(ke=3),ce&&new RegExp(`\\b${j}`,"i").test(ce)&&(ke+=4),new RegExp(`\\b${j}`,"i").test(T)&&(ke+=2),le+=ke}return{name:D,description:L?.description??"",searchHint:L?.searchHint,score:le}}).filter(D=>D!==null&&D.score>0).sort((D,L)=>L.score-D.score).slice(0,m),query:d,totalDeferred:h.length}},activateTool:async d=>Mu(d)})),e.push({...Fp({generateImage:async d=>{let p=await xt({mediaType:"image",model:"",prompt:d.prompt,purpose:d.purpose,style:d.style,size:d.size,imageUrl:d.imageUrl,n:d.n,quality:d.quality,seed:d.seed});return{mediaUrls:p.mediaUrls,model:p.model,size:p.size,durationMs:p.durationMs}}}),isEnabled:()=>Pt("image")}),e.push({...Bp({textToSpeech:async d=>{let p=await xt({mediaType:"tts",model:"",prompt:"",text:d.text,channel:d.channel,voice:d.voice,speed:d.speed});return{audioPath:"",provider:p.model,mediaUrls:p.mediaUrls}}}),isEnabled:()=>Pt("tts")}),e.push({...Hp({generateVideo:async d=>{let p=await xt({mediaType:"video",model:"",prompt:d.prompt,purpose:d.purpose,style:d.style,imageUrl:d.imageUrl,referenceVideos:d.referenceVideos,referenceAudios:d.referenceAudios,generateAudio:d.generateAudio,aspectRatio:d.aspectRatio,duration:d.duration,resolution:d.resolution,fps:d.fps,seed:d.seed,cameraFixed:d.cameraFixed,returnLastFrame:d.returnLastFrame,draft:d.draft,serviceTier:d.serviceTier,callbackUrl:d.callbackUrl,safetyIdentifier:d.safetyIdentifier,executionExpiresAfterSeconds:d.executionExpiresAfterSeconds,videoTools:d.videoTools});return{mediaUrls:p.mediaUrls,model:p.model,durationMs:p.durationMs,lastFrameUrl:p.lastFrameUrl,taskId:p.taskId}}}),isEnabled:()=>Pt("video")}),e.push({...qp({generateMusic:async d=>{let p=await xt({mediaType:"music",model:"",prompt:d.prompt,purpose:d.purpose,style:d.style,lyrics:d.lyrics,duration:d.duration,isInstrumental:d.isInstrumental,audioUrl:d.audioUrl,audioFormat:d.audioFormat});return{mediaUrls:p.mediaUrls,model:p.model,durationMs:p.durationMs}},generateLyrics:async d=>{let p=Yt.music;if(!p||!ve)return"";let m=ve.getTransport(p.provider);if(!(m instanceof Aw))return"";let h=Ue[p.provider];return h?m.generateLyrics(d,h):""}}),isEnabled:()=>Pt("music")}),e.push({...Wp({editVideo:async d=>{let p=await xt({mediaType:"video",model:"",prompt:d.prompt,operation:"edit",sourceVideos:d.sourceVideos,referenceImages:d.referenceImages,duration:d.duration,aspectRatio:d.aspectRatio,resolution:d.resolution});return{mediaUrls:p.mediaUrls,model:p.model,durationMs:p.durationMs}}}),shouldDefer:!0,isEnabled:()=>Qa("video","edit")}),e.push({...Gp({mergeVideos:async d=>{let p=[`merge ${d.clips.length} clips`];d.transition&&p.push(`transition: ${d.transition}${d.transitionDuration?` (${d.transitionDuration}s)`:""}`),d.subtitles&&p.push(`burn-in subtitles: ${d.subtitles}`),d.bgm&&p.push(`background music: ${d.bgm}${d.bgmVolume!==void 0?` at volume ${d.bgmVolume}`:""}`);let m=await xt({mediaType:"video",model:"",prompt:p.join("; "),operation:"merge",sourceVideos:d.clips.map(h=>h.video),resolution:d.outputResolution,fps:d.outputFps});return{localPath:"",servePath:m.mediaUrls[0]??"",durationSec:(m.durationMs??0)/1e3,clipCount:d.clips.length,mediaUrls:m.mediaUrls}}}),shouldDefer:!0,isEnabled:()=>Qa("video","merge")}),e.push({...Kp({upscaleVideo:async d=>{let p=["upscale"];d.sharpness&&p.push(`sharpness: ${d.sharpness}`);let m=await xt({mediaType:"video",model:"",prompt:p.join(", "),operation:"upscale",sourceVideos:[d.video],resolution:d.targetResolution??"1080p"});return{localPath:"",servePath:m.mediaUrls[0]??"",resolution:d.targetResolution??"1080p",durationSec:(m.durationMs??0)/1e3,mediaUrls:m.mediaUrls}}}),shouldDefer:!0,isEnabled:()=>Qa("video","upscale")}),e.push({...Vp({generate3D:async d=>{let p=await xt({mediaType:"3d",model:"",prompt:d.prompt,imageUrl:d.imageUrl,outputFormat:d.outputFormat,seed:d.seed});return{mediaUrls:p.mediaUrls,model:p.model,durationMs:p.durationMs,metadata:p.metadata}}}),shouldDefer:!0,isEnabled:()=>Pt("3d")}),e.push({...zp({speechToText:async d=>{let p=await xt({mediaType:"stt",model:"",prompt:"",audioUrl:d.audioUrl,metadata:d.language?{language:d.language}:void 0});return{transcription:p.metadata?.transcription??"",model:p.model,durationMs:p.durationMs}}}),shouldDefer:!0,isEnabled:()=>Pt("stt")}),e.push({...Xp({cloneVoice:async d=>{let p=await xt({mediaType:"voice_clone",model:"",prompt:"",text:d.text,audioUrl:d.sampleAudioUrl,speed:d.speed});return{mediaUrls:p.mediaUrls,model:p.model,voiceId:p.metadata?.voiceId,durationMs:p.durationMs}}}),shouldDefer:!0,isEnabled:()=>Pt("voice_clone")}),e.push({...Yp({cancelTask:async d=>{let p=d.provider??"doubao";if(!ve)return{ok:!1,message:"Media client not configured."};let m=ve.getTransport(p);if(!m)return{ok:!1,message:`No transport for provider: ${p}`};let h=Ue[p];if(!h)return{ok:!1,message:`No API key for provider: ${p}`};try{return"deleteVideoTask"in m&&typeof m.deleteVideoTask=="function"?(await m.deleteVideoTask(d.taskId,h),{ok:!0,message:"Task cancelled."}):{ok:!1,message:`Provider ${p} does not support task cancellation.`}}catch(f){return{ok:!1,message:f instanceof Error?f.message:String(f)}}}}),shouldDefer:!0,isEnabled:()=>Pt("video")||Pt("3d")});let u=Ts();return e.push({...Jp({uploadFile:async d=>{if(!u)throw new Error("No file upload provider available. Configure a media provider with Files API support (e.g. Volcengine, Google).");let p=Fe(d.filePath);if(!G.existsSync(p))throw new Error(`File not found: ${p}`);let m=G.statSync(p);if(m.size>100*1024*1024)throw new Error(`File too large (${(m.size/1024/1024).toFixed(1)} MB). Max: 100 MB.`);let h=await G.promises.readFile(p),f=K.basename(p);if(u.type==="gemini"){let I=Rs(),D=Ue.google,L=K.extname(p).toLowerCase(),F=Lw[L]??"application/octet-stream",T=await I.uploadFile(Buffer.from(h),D,{mimeType:F,displayName:f});if(T.state==="PROCESSING"){let ce=await I.waitForProcessing(T.name,D);return{fileId:ce.name,url:ce.uri,filename:f,bytes:m.size,provider:"google"}}return{fileId:T.name,url:T.uri,filename:f,bytes:m.size,provider:"google"}}let y=new Blob([h]),b=ve.getTransport(u.id),S=Ue[u.id];if(!(b instanceof lr))throw new Error(`File upload only supported via Volcengine or Google provider. Current: ${u.id}`);let w=await b.uploadFile(y,S,{purpose:d.purpose??"media_reference",filename:f}),_;try{let I=await b.getFile(w.id,S);typeof I.url=="string"&&I.url&&(_=I.url)}catch{}return{fileId:w.id,url:_,filename:f,bytes:m.size,provider:u.id}}}),shouldDefer:!0,isEnabled:()=>!!Ts()}),e.push({...Qp({queryFile:async d=>{if(!u)throw new Error("No file API provider available.");if(u.type==="gemini"){let f=Rs(),y=Ue.google,b=await f.getFile(d.fileId,y);return{id:b.name,filename:b.displayName??"",bytes:Number(b.sizeBytes??0),status:b.state?.toLowerCase()??"unknown",createdAt:b.createTime,url:b.uri}}let p=ve.getTransport(u.id),m=Ue[u.id];if(!(p instanceof lr))throw new Error("File query only supported via Volcengine or Google provider.");let h=await p.getFile(d.fileId,m);return{id:String(h.id??d.fileId),filename:String(h.filename??""),bytes:Number(h.bytes??0),status:String(h.status??"unknown"),createdAt:h.created_at?String(h.created_at):void 0,url:h.url?String(h.url):void 0}},listFiles:async d=>{if(!u)throw new Error("No file API provider available.");if(u.type==="gemini"){let y=Rs(),b=Ue.google;return(await y.listFiles(b,{pageSize:d.limit??10})).files.map(w=>({id:w.name,filename:w.displayName??"",bytes:Number(w.sizeBytes??0),status:w.state?.toLowerCase()??"unknown",createdAt:w.createTime,url:w.uri}))}let p=ve.getTransport(u.id),m=Ue[u.id];if(!(p instanceof lr))throw new Error("File list only supported via Volcengine or Google provider.");return((await p.listFiles(m,{limit:d.limit??10})).data??[]).map(y=>({id:String(y.id??""),filename:String(y.filename??""),bytes:Number(y.bytes??0),status:String(y.status??"unknown"),createdAt:y.created_at?String(y.created_at):void 0,url:y.url?String(y.url):void 0}))}}),shouldDefer:!0,isEnabled:()=>!!Ts()}),e.push({...Zp({deleteFile:async d=>{if(!u)throw new Error("No file API provider available.");if(u.type==="gemini"){let h=Rs(),f=Ue.google;await h.deleteFile(d.fileId,f);return}let p=ve.getTransport(u.id),m=Ue[u.id];if(!(p instanceof lr))throw new Error("File delete only supported via Volcengine or Google provider.");await p.deleteFile(d.fileId,m)}}),shouldDefer:!0,isEnabled:()=>!!Ts()}),Eu(e),n?.log?.info(`[tool-bootstrap] Registered ${e.length} local tools (${e.filter(d=>d.isEnabled?.()!==!1).length} enabled): ${zt().join(", ")}`),e}import{spawn as Qw}from"node:child_process";import{createInterface as Zw}from"node:readline";var ws=class{process=null;readline=null;pending=new Map;nextId=1;connected=!1;toolsCache=[];serverName="";serverVersion="";supportsToolsListChanged=!1;onToolsChanged=null;stderrBuffer="";config;constructor(e){this.config=e}async connect(){if(this.connected)return;let e={...process.env,...this.config.env};this.process=Qw(this.config.command,this.config.args??[],{stdio:["pipe","pipe","pipe"],env:e,cwd:this.config.cwd,windowsHide:!0}),this.process.on("error",r=>{this.handleProcessError(r)}),this.process.on("exit",r=>{this.handleProcessExit(r)}),this.process.stderr?.on("data",r=>{this.stderrBuffer+=r.toString(),this.stderrBuffer.length>4096&&(this.stderrBuffer=this.stderrBuffer.slice(-4096))}),this.readline=Zw({input:this.process.stdout,crlfDelay:Number.POSITIVE_INFINITY}),this.readline.on("line",r=>this.handleLine(r));let t=await this.sendRequest("initialize",{protocolVersion:"2024-11-05",capabilities:{},clientInfo:{name:"qlogicagent",version:"0.3.0"}},this.config.initTimeoutMs??3e4);this.serverName=t.serverInfo?.name??this.config.name,this.serverVersion=t.serverInfo?.version??"unknown",this.supportsToolsListChanged=t.capabilities?.tools?.listChanged??!1,this.sendNotification("notifications/initialized",{}),this.connected=!0,await this.refreshTools()}async disconnect(){if(this.connected){this.connected=!1;for(let[,e]of this.pending)e.reject(new Error("MCP client disconnecting"));if(this.pending.clear(),this.toolsCache=[],this.readline?.close(),this.readline=null,this.process){this.process.kill("SIGTERM");let e=setTimeout(()=>this.process?.kill("SIGKILL"),5e3);this.process.on("exit",()=>clearTimeout(e)),this.process=null}}}get isConnected(){return this.connected}get info(){return{name:this.serverName,version:this.serverVersion}}async refreshTools(){if(!this.connected)return[];try{let e=await this.sendRequest("tools/list",{});this.toolsCache=e.tools??[]}catch{this.toolsCache=[]}return this.toolsCache}getCachedTools(){return this.toolsCache}async callTool(e,t,r){if(!this.connected)throw new Error(`MCP server ${this.config.name} not connected`);return await this.sendRequest("tools/call",{name:e,arguments:t??{}},12e4,r)}async listResources(){if(!this.connected)return[];try{return(await this.sendRequest("resources/list",{})).resources??[]}catch{return[]}}async readResource(e){if(!this.connected)throw new Error(`MCP server ${this.config.name} not connected`);return(await this.sendRequest("resources/read",{uri:e})).contents??[]}toPortableTools(){let e=eA(this.config.name);return this.toolsCache.map(t=>({name:`mcp__${e}__${t.name}`,label:`[${this.config.name}] ${t.name}`,description:t.description??`MCP tool from ${this.config.name}`,parameters:t.inputSchema??{type:"object",properties:{}},isConcurrencySafe:!0,isReadOnly:!1,searchHint:`mcp ${this.config.name} ${t.name}`,execute:async(r,s,o)=>this.executeAsTool(t.name,s,o)}))}setOnToolsChanged(e){this.onToolsChanged=e}async executeAsTool(e,t,r){try{let s=await this.callTool(e,t,r);return{content:[{type:"text",text:s.content.filter(a=>a.type==="text"&&a.text).map(a=>a.text).join(`
|
|
503
|
+
`);for(let m=0;m<p.length;m++)if(r.test(p[m])&&(a.push({path:l,line:m+1,text:p[m].slice(0,500)}),a.length>=o+s+1))return c=!0,!1}catch{}return!0},1/0),{matches:a.slice(o,o+s),truncated:c}}var im=!1;function Gw(){if(!im)if(im=!0,cn()){let n=process.env.QLOGICAGENT_POWERSHELL_PATH??"powershell.exe";ir($a(n))}else if(process.platform==="win32"){let n=Kw();ir(Ss(n))}else{let n=process.env.SHELL?.endsWith("bash")?process.env.SHELL:"/bin/bash";ir(Ss(n))}}function Kw(){let n=process.env.QLOGICAGENT_BASH_PATH;if(n&&G.existsSync(n))return n;let e=["C:\\Program Files\\Git\\bin\\bash.exe","C:\\Program Files (x86)\\Git\\bin\\bash.exe"],t=process.env.ProgramFiles?K.join(process.env.ProgramFiles,"Git","bin","bash.exe"):null;t&&!e.includes(t)&&e.unshift(t);for(let r of e)if(G.existsSync(r))return r;return"bash"}function Vw(){return{async fetchUrl(n){let e=new AbortController,t=setTimeout(()=>e.abort(),3e4);try{let r=await fetch(n.url,{signal:e.signal,headers:{"User-Agent":"Mozilla/5.0 (compatible; QLogicAgent/1.0)",Accept:"text/html,application/xhtml+xml,text/plain,*/*"},redirect:"follow"});if(!r.ok)return{content:`HTTP ${r.status} ${r.statusText}`};let s=r.headers.get("content-type")??"",o=await r.text();return n.maxChars&&o.length>n.maxChars&&(o=o.slice(0,n.maxChars)),s.includes("html")&&n.extractMode!=="json"&&(o=zw(o)),{content:o,title:Xw(o)}}finally{clearTimeout(t)}}}}function zw(n){return n.replace(/<script[\s\S]*?<\/script>/gi,"").replace(/<style[\s\S]*?<\/style>/gi,"").replace(/<[^>]+>/g," ").replace(/ /gi," ").replace(/&/gi,"&").replace(/</gi,"<").replace(/>/gi,">").replace(/"/gi,'"').replace(/'/gi,"'").replace(/\s{2,}/g," ").trim()}function Xw(n){return n.match(/<title[^>]*>([^<]+)<\/title>/i)?.[1]?.trim()}function Yw(){let n=async(e,t)=>{let{getModelRegistry:r}=await Promise.resolve().then(()=>(dt(),Sd)),s=r().getTunable("searxngBaseUrl")??process.env.SEARXNG_BASE_URL?.trim();if(!s)return{query:e,results:[],totalResults:0};let o=t?.maxResults??10,i=new URL("/search",s);i.searchParams.set("q",e),i.searchParams.set("format","json"),i.searchParams.set("pageno","1");let a=new AbortController,c=setTimeout(()=>a.abort(),15e3);try{let l=await fetch(i.toString(),{signal:a.signal,headers:{Accept:"application/json"}});if(!l.ok)return{query:e,results:[]};let u=await l.json(),d=(u.results??[]).slice(0,o).map(p=>({title:p.title??"",url:p.url??"",snippet:p.content??""}));if(t?.allowedDomains?.length){let p=new Set(t.allowedDomains.map(m=>m.toLowerCase()));return{query:e,results:d.filter(m=>{try{return p.has(new URL(m.url).hostname.toLowerCase())}catch{return!1}})}}if(t?.blockedDomains?.length){let p=new Set(t.blockedDomains.map(m=>m.toLowerCase()));return{query:e,results:d.filter(m=>{try{return!p.has(new URL(m.url).hostname.toLowerCase())}catch{return!0}})}}return{query:e,results:d,totalResults:u.number_of_results}}finally{clearTimeout(c)}};return{search:(e,t)=>nm(cm,n)(e,t)}}function Jw(){let n=K.join(process.env.HOME??process.env.USERPROFILE??".",".qlogicagent");function e(s){return K.join(n,"projects",s,".instructions")}function t(s,o){if(!o.endsWith(".md"))throw new Error("Filename must end with .md");if(o.includes(".."))throw new Error("Path traversal not allowed");let i=e(s),a=K.resolve(i,o);if(!a.startsWith(i+K.sep)&&a!==i)throw new Error("Path traversal not allowed");return a}function r(s,o){if(!G.existsSync(s))return[];let i=[];for(let a of G.readdirSync(s,{withFileTypes:!0})){let c=K.join(s,a.name);if(a.isDirectory())i.push(...r(c,o));else if(a.isFile()&&a.name.endsWith(".md")){let l=G.statSync(c);i.push({filename:K.relative(o,c).replace(/\\/g,"/"),path:c,size:l.size,updatedAt:l.mtime.toISOString(),content:G.readFileSync(c,"utf-8")})}}return i}return{list(s){let o=e(s);return r(o,o).map(i=>({filename:i.filename,path:i.path,size:i.size,updatedAt:i.updatedAt}))},read(s,o){try{let i=t(s,o);if(!G.existsSync(i))return null;let a=G.statSync(i),c=G.readFileSync(i,"utf-8");return{filename:o,path:i,size:a.size,updatedAt:a.mtime.toISOString(),content:c}}catch{return null}},write(s,o,i){let a=t(s,o);G.mkdirSync(K.dirname(a),{recursive:!0}),G.writeFileSync(a,i,"utf-8");let c=G.statSync(a);return{filename:o,path:a,size:c.size,updatedAt:c.mtime.toISOString(),content:i}},remove(s,o){try{let i=t(s,o);return G.existsSync(i)?(G.unlinkSync(i),!0):!1}catch{return!1}}}}function ym(n){n?.workdir&&(rt=n.workdir),Gw(),bs(rt);let e=[];e.push(Du()),e.push(Nu(void 0,{onTaskCreated:d=>tc?.onTaskCreated?.(d),onTaskCompleted:d=>tc?.onTaskCompleted?.(d)})),e.push(em({askUser:async d=>dm?.(d)??null})),e.push(Vu({onProgress:n?.onExecProgress,validateCommand:async d=>{let p=/(?:>>?|[12]>)\s*(?:"([^"]+)"|'([^']+)'|(\S+))/g,m;for(;(m=p.exec(d))!==null;){let f=m[1]||m[2]||m[3];if(f){let y=K.isAbsolute(f)?K.normalize(f):K.resolve(rt,f);if(!dr(y))return`Blocked: output redirection to path outside workspace: ${f}`}}let h=[/(?:^|[\s;|&(])(?:"(\/[^"]+)"|'(\/[^']+)'|(\/(?!dev\/null\b)[^\s;|&><)]+))/g,/(?:^|[\s;|&(])(?:"([A-Za-z]:[\\\/][^"]+)"|'([A-Za-z]:[\\\/][^']+)'|([A-Za-z]:[\\\/][^\s;|&><)]+))/g,/(?:^|[\s;|&(])(?:"([^"]*\.\.[\\/][^"]+)"|'([^']*\.\.[\\/][^']+)'|([^\s;|&><)"']*\.\.[\\/][^\s;|&><)]+))/g];for(let f of h){let y;for(;(y=f.exec(d))!==null;){let b=y[1]||y[2]||y[3];if(!b||/^\/[a-zA-Z](?:[- ]|$)/.test(b)||/^\/[a-zA-Z]{1,3}$/.test(b))continue;let T;if(process.platform==="win32"&&/^\/[a-zA-Z]\//.test(b)){let w=b.replace(/^\/([a-zA-Z])\//,(_,I)=>`${I.toUpperCase()}:\\`).replace(/\//g,"\\");T=K.normalize(w)}else T=K.isAbsolute(b)?K.normalize(b):K.resolve(rt,b);if(!dr(T))return`Blocked: command references path outside workspace: ${b}`}}return null},interpretExitCode:(d,p)=>{if(d===127)return"command not found";if(d===126)return"permission denied";if(d===137)return"killed (SIGKILL / OOM)";if(d===143)return"terminated (SIGTERM)";if(d===130)return"interrupted (Ctrl+C)"}}));let t=$w(),r=jw(),s=Uw(),o=Fw();e.push(Yu(t)),e.push(Qu(r)),e.push(Zu(s)),e.push(Ha(o)),e.push(rp(o)),e.push(np(Bw())),e.push(pp(Vw())),e.push(mp(Yw()));let i=Jw();e.push(gp(i));let a=n?.log??{info:()=>{},warn:()=>{}};e.push(fp(_p({log:a}))),e.push(Dp());let c={invokeTool:async(d,p,m)=>{let h=tt(d);if(!h)return{result:"",error:`Unknown tool: ${d}`};try{let f=await h.execute(`wf_${Date.now()}`,p,m);return{result:f.content.map(b=>b.text??"").join(`
|
|
504
|
+
`),error:f.details?.error}}catch(f){return{result:"",error:f.message}}},getCwd:()=>rt};e.push(Lp(c)),e.push($p({sleep:(d,p)=>new Promise(m=>{let h=Date.now(),f=setTimeout(()=>{m({sleptSeconds:Math.round((Date.now()-h)/1e3),interrupted:!1})},d),y=()=>{clearTimeout(f),m({sleptSeconds:Math.round((Date.now()-h)/1e3),interrupted:!0,interruptReason:"aborted"})};p.addEventListener("abort",y,{once:!0}),p.aborted&&(clearTimeout(f),y())})}));let l={listProjects:()=>me(),switchProject:d=>ut(d),onSwitched:d=>_w?.(d)};e.push(tm(l)),e.push(Up({searchTools:async(d,p)=>{let m=p?.maxResults??5,h=zt(),f=d.toLowerCase().split(/\s+/).filter(Boolean),y=[],b=[];for(let D of f)D.startsWith("+")&&D.length>1?y.push(D.slice(1)):b.push(D);let T=[...y,...b],w=D=>D.replace(/([a-z])([A-Z])/g,"$1 $2").replace(/_/g," ").toLowerCase().split(/\s+/).filter(Boolean);return{matches:h.map(D=>{let L=tt(D),F=w(D),S=(L?.description??"").toLowerCase(),ce=(L?.searchHint??"").toLowerCase();if(y.length>0){let j=`${F.join(" ")} ${S} ${ce}`;if(!y.every(oe=>j.includes(oe)))return null}let le=0;for(let j of T){let ke=0;F.some(oe=>oe===j)?ke=10:F.some(oe=>oe.includes(j))?ke=5:D.toLowerCase().includes(j)&&(ke=3),ce&&new RegExp(`\\b${j}`,"i").test(ce)&&(ke+=4),new RegExp(`\\b${j}`,"i").test(S)&&(ke+=2),le+=ke}return{name:D,description:L?.description??"",searchHint:L?.searchHint,score:le}}).filter(D=>D!==null&&D.score>0).sort((D,L)=>L.score-D.score).slice(0,m),query:d,totalDeferred:h.length}},activateTool:async d=>Mu(d)})),e.push({...Fp({generateImage:async d=>{let p=await xt({mediaType:"image",model:"",prompt:d.prompt,purpose:d.purpose,style:d.style,size:d.size,imageUrl:d.imageUrl,n:d.n,quality:d.quality,seed:d.seed});return{mediaUrls:p.mediaUrls,model:p.model,size:p.size,durationMs:p.durationMs}}}),isEnabled:()=>Pt("image")}),e.push({...Bp({textToSpeech:async d=>{let p=await xt({mediaType:"tts",model:"",prompt:"",text:d.text,channel:d.channel,voice:d.voice,speed:d.speed});return{audioPath:"",provider:p.model,mediaUrls:p.mediaUrls}}}),isEnabled:()=>Pt("tts")}),e.push({...Hp({generateVideo:async d=>{let p=await xt({mediaType:"video",model:"",prompt:d.prompt,purpose:d.purpose,style:d.style,imageUrl:d.imageUrl,referenceVideos:d.referenceVideos,referenceAudios:d.referenceAudios,generateAudio:d.generateAudio,aspectRatio:d.aspectRatio,duration:d.duration,resolution:d.resolution,fps:d.fps,seed:d.seed,cameraFixed:d.cameraFixed,returnLastFrame:d.returnLastFrame,draft:d.draft,serviceTier:d.serviceTier,callbackUrl:d.callbackUrl,safetyIdentifier:d.safetyIdentifier,executionExpiresAfterSeconds:d.executionExpiresAfterSeconds,videoTools:d.videoTools});return{mediaUrls:p.mediaUrls,model:p.model,durationMs:p.durationMs,lastFrameUrl:p.lastFrameUrl,taskId:p.taskId}}}),isEnabled:()=>Pt("video")}),e.push({...qp({generateMusic:async d=>{let p=await xt({mediaType:"music",model:"",prompt:d.prompt,purpose:d.purpose,style:d.style,lyrics:d.lyrics,duration:d.duration,isInstrumental:d.isInstrumental,audioUrl:d.audioUrl,audioFormat:d.audioFormat});return{mediaUrls:p.mediaUrls,model:p.model,durationMs:p.durationMs}},generateLyrics:async d=>{let p=Yt.music;if(!p||!ve)return"";let m=ve.getTransport(p.provider);if(!(m instanceof Aw))return"";let h=Ue[p.provider];return h?m.generateLyrics(d,h):""}}),isEnabled:()=>Pt("music")}),e.push({...Wp({editVideo:async d=>{let p=await xt({mediaType:"video",model:"",prompt:d.prompt,operation:"edit",sourceVideos:d.sourceVideos,referenceImages:d.referenceImages,duration:d.duration,aspectRatio:d.aspectRatio,resolution:d.resolution});return{mediaUrls:p.mediaUrls,model:p.model,durationMs:p.durationMs}}}),shouldDefer:!0,isEnabled:()=>Qa("video","edit")}),e.push({...Gp({mergeVideos:async d=>{let p=[`merge ${d.clips.length} clips`];d.transition&&p.push(`transition: ${d.transition}${d.transitionDuration?` (${d.transitionDuration}s)`:""}`),d.subtitles&&p.push(`burn-in subtitles: ${d.subtitles}`),d.bgm&&p.push(`background music: ${d.bgm}${d.bgmVolume!==void 0?` at volume ${d.bgmVolume}`:""}`);let m=await xt({mediaType:"video",model:"",prompt:p.join("; "),operation:"merge",sourceVideos:d.clips.map(h=>h.video),resolution:d.outputResolution,fps:d.outputFps});return{localPath:"",servePath:m.mediaUrls[0]??"",durationSec:(m.durationMs??0)/1e3,clipCount:d.clips.length,mediaUrls:m.mediaUrls}}}),shouldDefer:!0,isEnabled:()=>Qa("video","merge")}),e.push({...Kp({upscaleVideo:async d=>{let p=["upscale"];d.sharpness&&p.push(`sharpness: ${d.sharpness}`);let m=await xt({mediaType:"video",model:"",prompt:p.join(", "),operation:"upscale",sourceVideos:[d.video],resolution:d.targetResolution??"1080p"});return{localPath:"",servePath:m.mediaUrls[0]??"",resolution:d.targetResolution??"1080p",durationSec:(m.durationMs??0)/1e3,mediaUrls:m.mediaUrls}}}),shouldDefer:!0,isEnabled:()=>Qa("video","upscale")}),e.push({...Vp({generate3D:async d=>{let p=await xt({mediaType:"3d",model:"",prompt:d.prompt,imageUrl:d.imageUrl,outputFormat:d.outputFormat,seed:d.seed});return{mediaUrls:p.mediaUrls,model:p.model,durationMs:p.durationMs,metadata:p.metadata}}}),shouldDefer:!0,isEnabled:()=>Pt("3d")}),e.push({...zp({speechToText:async d=>{let p=await xt({mediaType:"stt",model:"",prompt:"",audioUrl:d.audioUrl,metadata:d.language?{language:d.language}:void 0});return{transcription:p.metadata?.transcription??"",model:p.model,durationMs:p.durationMs}}}),shouldDefer:!0,isEnabled:()=>Pt("stt")}),e.push({...Xp({cloneVoice:async d=>{let p=await xt({mediaType:"voice_clone",model:"",prompt:"",text:d.text,audioUrl:d.sampleAudioUrl,speed:d.speed});return{mediaUrls:p.mediaUrls,model:p.model,voiceId:p.metadata?.voiceId,durationMs:p.durationMs}}}),shouldDefer:!0,isEnabled:()=>Pt("voice_clone")}),e.push({...Yp({cancelTask:async d=>{let p=d.provider??"doubao";if(!ve)return{ok:!1,message:"Media client not configured."};let m=ve.getTransport(p);if(!m)return{ok:!1,message:`No transport for provider: ${p}`};let h=Ue[p];if(!h)return{ok:!1,message:`No API key for provider: ${p}`};try{return"deleteVideoTask"in m&&typeof m.deleteVideoTask=="function"?(await m.deleteVideoTask(d.taskId,h),{ok:!0,message:"Task cancelled."}):{ok:!1,message:`Provider ${p} does not support task cancellation.`}}catch(f){return{ok:!1,message:f instanceof Error?f.message:String(f)}}}}),shouldDefer:!0,isEnabled:()=>Pt("video")||Pt("3d")});let u=Ts();return e.push({...Jp({uploadFile:async d=>{if(!u)throw new Error("No file upload provider available. Configure a media provider with Files API support (e.g. Volcengine, Google).");let p=Fe(d.filePath);if(!G.existsSync(p))throw new Error(`File not found: ${p}`);let m=G.statSync(p);if(m.size>100*1024*1024)throw new Error(`File too large (${(m.size/1024/1024).toFixed(1)} MB). Max: 100 MB.`);let h=await G.promises.readFile(p),f=K.basename(p);if(u.type==="gemini"){let I=Rs(),D=Ue.google,L=K.extname(p).toLowerCase(),F=Lw[L]??"application/octet-stream",S=await I.uploadFile(Buffer.from(h),D,{mimeType:F,displayName:f});if(S.state==="PROCESSING"){let ce=await I.waitForProcessing(S.name,D);return{fileId:ce.name,url:ce.uri,filename:f,bytes:m.size,provider:"google"}}return{fileId:S.name,url:S.uri,filename:f,bytes:m.size,provider:"google"}}let y=new Blob([h]),b=ve.getTransport(u.id),T=Ue[u.id];if(!(b instanceof lr))throw new Error(`File upload only supported via Volcengine or Google provider. Current: ${u.id}`);let w=await b.uploadFile(y,T,{purpose:d.purpose??"media_reference",filename:f}),_;try{let I=await b.getFile(w.id,T);typeof I.url=="string"&&I.url&&(_=I.url)}catch{}return{fileId:w.id,url:_,filename:f,bytes:m.size,provider:u.id}}}),shouldDefer:!0,isEnabled:()=>!!Ts()}),e.push({...Qp({queryFile:async d=>{if(!u)throw new Error("No file API provider available.");if(u.type==="gemini"){let f=Rs(),y=Ue.google,b=await f.getFile(d.fileId,y);return{id:b.name,filename:b.displayName??"",bytes:Number(b.sizeBytes??0),status:b.state?.toLowerCase()??"unknown",createdAt:b.createTime,url:b.uri}}let p=ve.getTransport(u.id),m=Ue[u.id];if(!(p instanceof lr))throw new Error("File query only supported via Volcengine or Google provider.");let h=await p.getFile(d.fileId,m);return{id:String(h.id??d.fileId),filename:String(h.filename??""),bytes:Number(h.bytes??0),status:String(h.status??"unknown"),createdAt:h.created_at?String(h.created_at):void 0,url:h.url?String(h.url):void 0}},listFiles:async d=>{if(!u)throw new Error("No file API provider available.");if(u.type==="gemini"){let y=Rs(),b=Ue.google;return(await y.listFiles(b,{pageSize:d.limit??10})).files.map(w=>({id:w.name,filename:w.displayName??"",bytes:Number(w.sizeBytes??0),status:w.state?.toLowerCase()??"unknown",createdAt:w.createTime,url:w.uri}))}let p=ve.getTransport(u.id),m=Ue[u.id];if(!(p instanceof lr))throw new Error("File list only supported via Volcengine or Google provider.");return((await p.listFiles(m,{limit:d.limit??10})).data??[]).map(y=>({id:String(y.id??""),filename:String(y.filename??""),bytes:Number(y.bytes??0),status:String(y.status??"unknown"),createdAt:y.created_at?String(y.created_at):void 0,url:y.url?String(y.url):void 0}))}}),shouldDefer:!0,isEnabled:()=>!!Ts()}),e.push({...Zp({deleteFile:async d=>{if(!u)throw new Error("No file API provider available.");if(u.type==="gemini"){let h=Rs(),f=Ue.google;await h.deleteFile(d.fileId,f);return}let p=ve.getTransport(u.id),m=Ue[u.id];if(!(p instanceof lr))throw new Error("File delete only supported via Volcengine or Google provider.");await p.deleteFile(d.fileId,m)}}),shouldDefer:!0,isEnabled:()=>!!Ts()}),Eu(e),n?.log?.info(`[tool-bootstrap] Registered ${e.length} local tools (${e.filter(d=>d.isEnabled?.()!==!1).length} enabled): ${zt().join(", ")}`),e}import{spawn as Qw}from"node:child_process";import{createInterface as Zw}from"node:readline";var ws=class{process=null;readline=null;pending=new Map;nextId=1;connected=!1;toolsCache=[];serverName="";serverVersion="";supportsToolsListChanged=!1;onToolsChanged=null;stderrBuffer="";config;constructor(e){this.config=e}async connect(){if(this.connected)return;let e={...process.env,...this.config.env};this.process=Qw(this.config.command,this.config.args??[],{stdio:["pipe","pipe","pipe"],env:e,cwd:this.config.cwd,windowsHide:!0}),this.process.on("error",r=>{this.handleProcessError(r)}),this.process.on("exit",r=>{this.handleProcessExit(r)}),this.process.stderr?.on("data",r=>{this.stderrBuffer+=r.toString(),this.stderrBuffer.length>4096&&(this.stderrBuffer=this.stderrBuffer.slice(-4096))}),this.readline=Zw({input:this.process.stdout,crlfDelay:Number.POSITIVE_INFINITY}),this.readline.on("line",r=>this.handleLine(r));let t=await this.sendRequest("initialize",{protocolVersion:"2024-11-05",capabilities:{},clientInfo:{name:"qlogicagent",version:"0.3.0"}},this.config.initTimeoutMs??3e4);this.serverName=t.serverInfo?.name??this.config.name,this.serverVersion=t.serverInfo?.version??"unknown",this.supportsToolsListChanged=t.capabilities?.tools?.listChanged??!1,this.sendNotification("notifications/initialized",{}),this.connected=!0,await this.refreshTools()}async disconnect(){if(this.connected){this.connected=!1;for(let[,e]of this.pending)e.reject(new Error("MCP client disconnecting"));if(this.pending.clear(),this.toolsCache=[],this.readline?.close(),this.readline=null,this.process){this.process.kill("SIGTERM");let e=setTimeout(()=>this.process?.kill("SIGKILL"),5e3);this.process.on("exit",()=>clearTimeout(e)),this.process=null}}}get isConnected(){return this.connected}get info(){return{name:this.serverName,version:this.serverVersion}}async refreshTools(){if(!this.connected)return[];try{let e=await this.sendRequest("tools/list",{});this.toolsCache=e.tools??[]}catch{this.toolsCache=[]}return this.toolsCache}getCachedTools(){return this.toolsCache}async callTool(e,t,r){if(!this.connected)throw new Error(`MCP server ${this.config.name} not connected`);return await this.sendRequest("tools/call",{name:e,arguments:t??{}},12e4,r)}async listResources(){if(!this.connected)return[];try{return(await this.sendRequest("resources/list",{})).resources??[]}catch{return[]}}async readResource(e){if(!this.connected)throw new Error(`MCP server ${this.config.name} not connected`);return(await this.sendRequest("resources/read",{uri:e})).contents??[]}toPortableTools(){let e=eA(this.config.name);return this.toolsCache.map(t=>({name:`mcp__${e}__${t.name}`,label:`[${this.config.name}] ${t.name}`,description:t.description??`MCP tool from ${this.config.name}`,parameters:t.inputSchema??{type:"object",properties:{}},isConcurrencySafe:!0,isReadOnly:!1,searchHint:`mcp ${this.config.name} ${t.name}`,execute:async(r,s,o)=>this.executeAsTool(t.name,s,o)}))}setOnToolsChanged(e){this.onToolsChanged=e}async executeAsTool(e,t,r){try{let s=await this.callTool(e,t,r);return{content:[{type:"text",text:s.content.filter(a=>a.type==="text"&&a.text).map(a=>a.text).join(`
|
|
505
505
|
`)||"(no text output)"}],...s.isError?{details:{error:"mcp_tool_error"}}:{}}}catch(s){let o=s instanceof Error?s.message:String(s);return{content:[{type:"text",text:`MCP tool error: ${o}`}],details:{error:o}}}}sendRequest(e,t,r=3e4,s){return new Promise((o,i)=>{if(s?.aborted){i(new Error("Aborted"));return}let a=this.nextId++,c={jsonrpc:"2.0",id:a,method:e,params:t},l=setTimeout(()=>{this.pending.delete(a),i(new Error(`MCP request ${e} timed out after ${r}ms`))},r),u=()=>{clearTimeout(l),this.pending.delete(a)};s?.addEventListener("abort",()=>{u(),i(new Error("Aborted"))},{once:!0}),this.pending.set(a,{resolve:d=>{u(),d.error?i(new Error(`MCP error ${d.error.code}: ${d.error.message}`)):o(d.result)},reject:d=>{u(),i(d)}}),this.writeLine(JSON.stringify(c))})}sendNotification(e,t){let r={jsonrpc:"2.0",method:e,params:t};this.writeLine(JSON.stringify(r))}writeLine(e){this.process?.stdin?.writable&&this.process.stdin.write(e+`
|
|
506
506
|
`)}handleLine(e){let t=e.trim();if(!t)return;let r;try{r=JSON.parse(t)}catch{return}if("id"in r&&("result"in r||"error"in r)){let s=r.id,o=this.pending.get(s);o&&o.resolve(r)}else"method"in r&&!("id"in r)&&this.handleNotification(r)}handleNotification(e){e.method==="notifications/tools/list_changed"&&this.refreshTools().then(()=>{this.onToolsChanged?.()}).catch(()=>{})}handleProcessError(e){this.connected=!1;for(let[,t]of this.pending)t.reject(new Error(`MCP process error: ${e.message}`));this.pending.clear()}handleProcessExit(e){this.connected=!1;for(let[,t]of this.pending)t.reject(new Error(`MCP process exited with code ${e}`));this.pending.clear()}};function eA(n){return n.replace(/[^a-zA-Z0-9_]/g,"_").toLowerCase()}import{randomUUID as tA}from"node:crypto";var As=class{connected=!1;toolsCache=[];serverName="";serverVersion="";sessionId=null;onToolsChanged=null;config;constructor(e){this.config=e}async connect(){if(this.connected)return;let e=await this.sendRequest("initialize",{protocolVersion:"2025-03-26",capabilities:{},clientInfo:{name:"qlogicagent",version:"0.3.0"}},this.config.initTimeoutMs??3e4);this.serverName=e.serverInfo?.name??this.config.name,this.serverVersion=e.serverInfo?.version??"unknown",await this.sendNotification("notifications/initialized",{}),this.connected=!0,await this.refreshTools()}async disconnect(){this.connected=!1,this.toolsCache=[],this.sessionId=null}async callTool(e,t,r){if(!this.connected)throw new Error(`MCP server ${this.config.name} not connected`);return await this.sendRequest("tools/call",{name:e,arguments:t??{}},this.config.toolCallTimeoutMs??12e4,r)}async listResources(){if(!this.connected)return[];try{return(await this.sendRequest("resources/list",{})).resources??[]}catch{return[]}}async readResource(e){if(!this.connected)throw new Error(`MCP server ${this.config.name} not connected`);return(await this.sendRequest("resources/read",{uri:e})).contents??[]}toPortableTools(){return this.toolsCache.map(e=>this.schemaToPortableTool(e))}getCachedTools(){return[...this.toolsCache]}get isConnected(){return this.connected}get info(){return{name:this.serverName,version:this.serverVersion}}setOnToolsChanged(e){this.onToolsChanged=e}async refreshTools(){let e=await this.sendRequest("tools/list",{});this.toolsCache=e.tools??[]}async sendRequest(e,t,r=3e4,s){let o=tA(),i={jsonrpc:"2.0",id:o,method:e,params:t},a=new AbortController,c=setTimeout(()=>a.abort(),r);s&&s.addEventListener("abort",()=>a.abort(),{once:!0});try{let l={"Content-Type":"application/json",Accept:"application/json, text/event-stream",...this.config.headers};this.sessionId&&(l["Mcp-Session-Id"]=this.sessionId);let u=await fetch(this.config.url,{method:"POST",headers:l,body:JSON.stringify(i),signal:a.signal}),d=u.headers.get("mcp-session-id");if(d&&(this.sessionId=d),!u.ok)throw new Error(`MCP HTTP error ${u.status}: ${u.statusText}`);if((u.headers.get("content-type")??"").includes("text/event-stream"))return await this.parseSSEResponse(u,o);let m=await u.json();if(m.error)throw new Error(`MCP error ${m.error.code}: ${m.error.message}`);return m.result}finally{clearTimeout(c)}}async sendNotification(e,t){let r={jsonrpc:"2.0",method:e,params:t},s={"Content-Type":"application/json",...this.config.headers};this.sessionId&&(s["Mcp-Session-Id"]=this.sessionId),await fetch(this.config.url,{method:"POST",headers:s,body:JSON.stringify(r)}).catch(()=>{})}async parseSSEResponse(e,t){let r=e.body;if(!r)throw new Error("MCP SSE response has no body");let s=r.getReader(),o=new TextDecoder,i="";try{for(;;){let{done:a,value:c}=await s.read();if(a)break;i+=o.decode(c,{stream:!0});let l=i.split(`
|
|
507
507
|
`);i=l.pop()??"";for(let u of l){if(!u.startsWith("data: "))continue;let d=u.slice(6).trim();if(d)try{let p=JSON.parse(d);if("method"in p&&p.method==="notifications/tools/list_changed"){this.onToolsChanged?.();continue}if(p.id===t){if(p.error)throw new Error(`MCP error ${p.error.code}: ${p.error.message}`);return p.result}}catch(p){if(p instanceof Error&&p.message.startsWith("MCP error"))throw p}}}}finally{s.releaseLock()}throw new Error("MCP SSE stream ended without response")}schemaToPortableTool(e){let t=this;return{name:`mcp__${nA(this.config.name)}__${e.name}`,label:`[${this.config.name}] ${e.name}`,description:e.description??`MCP tool from ${this.config.name}`,parameters:e.inputSchema??{type:"object",properties:{}},isConcurrencySafe:!0,isReadOnly:!1,searchHint:`mcp ${this.config.name} ${e.name}`,execute:async(s,o,i)=>{try{let a=await t.callTool(e.name,o,i);return{content:[{type:"text",text:(a.content??[]).filter(u=>u.type==="text"&&u.text).map(u=>u.text).join(`
|
|
508
508
|
`)||"(no output)"}],details:a.isError?{type:"mcp",error:"tool_error"}:{type:"mcp"}}}catch(a){let c=a instanceof Error?a.message:String(a);return{content:[{type:"text",text:`MCP tool error: ${c}`}],details:{type:"mcp",error:c}}}}}}};function nA(n){return n.replace(/[^a-zA-Z0-9_]/g,"_").toLowerCase()}var xs=class{clients=new Map;injected=!1;log;constructor(e){this.log=e.log??{info:()=>{},warn:()=>{}};for(let t of e.servers){if(t.disabled)continue;if((t.type??(t.url?"http":"stdio"))==="http"){if(!t.url){this.log.warn(`[mcp] server "${t.name}" is type "http" but has no url, skipping`);continue}let s={name:t.name,url:t.url,headers:t.headers,initTimeoutMs:t.initTimeoutMs};this.clients.set(t.name,new As(s))}else{if(!t.command){this.log.warn(`[mcp] server "${t.name}" is type "stdio" but has no command, skipping`);continue}let s={name:t.name,command:t.command,args:t.args,env:t.env,initTimeoutMs:t.initTimeoutMs};this.clients.set(t.name,new ws(s))}}}async connectAll(){let e=Array.from(this.clients.entries()).map(async([t,r])=>{try{await r.connect(),this.log.info(`[mcp] connected to ${t} (${r.info.name} v${r.info.version})`),r.setOnToolsChanged(()=>{this.log.info(`[mcp] tools changed on ${t}, re-injecting`),this.injected&&this.reinjectTools(t,r)})}catch(s){this.log.warn(`[mcp] failed to connect to ${t}: ${s instanceof Error?s.message:s}`)}});await Promise.allSettled(e)}injectTools(){this.injected=!0;for(let[e,t]of this.clients){if(!t.isConnected)continue;let r=t.toPortableTools();va(r),this.log.info(`[mcp] injected ${r.length} tools from ${e}`)}}getConnectedServers(){return Array.from(this.clients.entries()).filter(([,e])=>e.isConnected).map(([e])=>e)}getToolCount(){let e=0;for(let t of this.clients.values())t.isConnected&&(e+=t.getCachedTools().length);return e}async disconnectAll(){let e=Array.from(this.clients.values()).map(async t=>{try{await t.disconnect()}catch{}});await Promise.allSettled(e),this.clients.clear(),this.injected=!1}async listResources(e){let t=e?[[e,this.clients.get(e)]].filter(([,s])=>s):Array.from(this.clients.entries());return(await Promise.all(t.map(async([s,o])=>{if(!o?.isConnected||!o.listResources)return[];try{return(await o.listResources()).map(a=>({...a,server:s}))}catch{return this.log.warn(`[mcp] failed to list resources from ${s}`),[]}}))).flat()}async readResource(e,t){let r=this.clients.get(e);if(!r?.isConnected)throw new Error(`MCP server "${e}" is not connected`);if(!r.readResource)throw new Error(`MCP server "${e}" does not support resources`);return r.readResource(t)}reinjectTools(e,t){if(!this.injected)return;let r=`mcp__${e.replace(/[^a-zA-Z0-9_]/g,"_").toLowerCase()}__`;for(let o of zt())o.startsWith(r)&&ps(o);let s=t.toPortableTools();va(s),this.log.info(`[mcp] re-injected ${s.length} tools from ${e}`)}};function lc(n){if(!n||typeof n!="object")return[];let e=n,t=[],r=e.mcpServers??e.servers??e;for(let[s,o]of Object.entries(r)){if(!o||typeof o!="object")continue;let i=o;if(typeof i.url=="string"){t.push({name:s,type:"http",url:i.url,headers:i.headers&&typeof i.headers=="object"?i.headers:void 0,disabled:i.disabled===!0,initTimeoutMs:typeof i.initTimeoutMs=="number"?i.initTimeoutMs:void 0});continue}typeof i.command=="string"&&t.push({name:s,type:"stdio",command:i.command,args:Array.isArray(i.args)?i.args:void 0,env:i.env&&typeof i.env=="object"?i.env:void 0,disabled:i.disabled===!0})}return t}var rA={type:"object",properties:{server:{type:"string",description:"MCP server name to list resources from. Omit to list from all connected servers."}}};function bm(n){return{name:"list_mcp_resources",label:"List MCP Resources",description:"List resources available from connected MCP servers. Resources are data items (files, database records, API data) exposed by MCP servers that can be read with read_mcp_resource.",parameters:rA,shouldDefer:!0,isConcurrencySafe:!0,isReadOnly:!0,searchHint:"mcp resource list browse discover",execute:async(e,t)=>{let r=n();if(!r)return{content:[{type:"text",text:"No MCP servers configured."}],details:{type:"list_mcp_resources",count:0}};let s=await r.listResources(t.server);if(s.length===0)return{content:[{type:"text",text:t.server?`No resources found from MCP server "${t.server}".`:"No resources found from any connected MCP server."}],details:{type:"list_mcp_resources",count:0}};let o=new Map;for(let a of s){let c=o.get(a.server)??[];c.push(a),o.set(a.server,c)}let i=[];for(let[a,c]of o){i.push(`Server: ${a} (${c.length} resources)`);for(let l of c){let u=l.mimeType?` [${l.mimeType}]`:"",d=l.description?` \u2014 ${l.description}`:"";i.push(` ${l.name}: ${l.uri}${u}${d}`)}i.push("")}return{content:[{type:"text",text:i.join(`
|
|
509
509
|
`).trim()}],details:{type:"list_mcp_resources",count:s.length}}}}}var sA={type:"object",properties:{server:{type:"string",description:"Name of the MCP server that hosts the resource."},uri:{type:"string",description:"URI of the resource to read (from list_mcp_resources output)."}},required:["server","uri"]};function km(n){return{name:"read_mcp_resource",label:"Read MCP Resource",description:"Read a specific resource from an MCP server by URI. Returns the resource content (text or binary metadata). Use list_mcp_resources first to discover available URIs.",parameters:sA,shouldDefer:!0,isConcurrencySafe:!0,isReadOnly:!0,searchHint:"mcp resource read fetch content",execute:async(e,t)=>{let r=n();if(!r)return{content:[{type:"text",text:"No MCP servers configured."}],details:{error:"no_mcp"}};try{let s=await r.readResource(t.server,t.uri);if(s.length===0)return{content:[{type:"text",text:`Resource "${t.uri}" returned no content.`}],details:{type:"read_mcp_resource",empty:!0}};let o=[];for(let i of s)if(i.text){let a=i.mimeType?` (${i.mimeType})`:"";o.push({type:"text",text:`--- ${i.uri}${a}-
|
|
510
510
|
${i.text}`})}else if(i.blob){let a=Math.ceil(i.blob.length*3/4/1024);o.push({type:"text",text:`--- ${i.uri} (binary, ~${a}KB, ${i.mimeType??"unknown"})-
|
|
511
|
-
[Binary content not displayed. Use appropriate tool to process.]`})}return o.length===0?{content:[{type:"text",text:`Resource "${t.uri}" has no readable content.`}],details:{type:"read_mcp_resource",empty:!0}}:{content:o,details:{type:"read_mcp_resource",uri:t.uri,server:t.server,contentCount:s.length}}}catch(s){return{content:[{type:"text",text:`Error reading resource: ${s.message}`}],details:{error:s.message}}}}}}import*as It from"node:fs";import*as ur from"node:path";import{pathToFileURL as oA}from"node:url";var vm={preToolUse:"tool.before_invoke",postToolUse:"tool.after_invoke",onTurnStart:"turn.submitted",onTurnEnd:"turn.completed",onSessionEnd:"session.ended"};var Ps=class{constructor(e){this.config=e;this.log=e.log??{info:()=>{},warn:()=>{}}}config;loaded=[];pluginSkills=[];activations=new Map;log;async loadAll(){for(let e of this.config.pluginDirs){if(!It.existsSync(e))continue;let t;try{t=It.readdirSync(e,{withFileTypes:!0})}catch{continue}for(let r of t){if(!r.isDirectory()||r.name.startsWith(".")||r.name.startsWith("_"))continue;let s=ur.join(e,r.name);await this.loadPlugin(r.name,s)}}return this.log.info(`[plugins] loaded ${this.loaded.length} plugin(s): ${this.loaded.map(e=>e.name).join(", ")||"(none)"}`),this.loaded}getPluginSkills(){return this.pluginSkills}getLoaded(){return this.loaded}async discoverNew(){let e=new Set(this.loaded.map(r=>r.name)),t=0;for(let r of this.config.pluginDirs){if(!It.existsSync(r))continue;let s;try{s=It.readdirSync(r,{withFileTypes:!0})}catch{continue}for(let o of s){if(!o.isDirectory()||o.name.startsWith(".")||o.name.startsWith("_")||e.has(o.name))continue;let i=ur.join(r,o.name);await this.loadPlugin(o.name,i),t++}}return t>0&&this.log.info(`[plugins] discovered ${t} new plugin(s)`),t}async refreshActivations(){let e=Date.now();for(let[t,r]of this.activations){if(e-r.lastCheckAt<r.ttlMs)continue;let s;try{s=await r.checkFn()}catch(o){this.log.warn(`[plugins] ${t}: check_fn error: ${o instanceof Error?o.message:o}`),s=r.lastResult}if(r.lastCheckAt=e,s!==r.lastResult){if(r.lastResult=s,s&&!r.active){for(let o of r.tools)Pe(o);r.active=!0,this.log.info(`[plugins] ${t}: reactivated (${r.tools.length} tools)`)}else if(!s&&r.active){for(let o of r.tools)ps(o.name);for(let o of r.hookUnregisterFns)o();r.active=!1,this.log.info(`[plugins] ${t}: deactivated`)}}}}async loadPlugin(e,t){let r=["index.js","index.mjs"],s=null;for(let f of r){let y=ur.join(t,f);if(It.existsSync(y)){s=y;break}}if(!s){this.log.warn(`[plugins] ${e}: no index.js found, skipping`);return}let o=0,i=0,a=0,c=[],l=[],u=null,d=6e4,p={},m=ur.join(t,"config.json");if(It.existsSync(m))try{p=JSON.parse(It.readFileSync(m,"utf8"))}catch{}let h={pluginName:e,registerTool:f=>{Pe(f),c.push(f),o++},registerHook:(f,y)=>{let b=vm[f];if(!b){this.log.warn(`[plugins] ${e}: unknown hook phase "${f}"`);return}let
|
|
511
|
+
[Binary content not displayed. Use appropriate tool to process.]`})}return o.length===0?{content:[{type:"text",text:`Resource "${t.uri}" has no readable content.`}],details:{type:"read_mcp_resource",empty:!0}}:{content:o,details:{type:"read_mcp_resource",uri:t.uri,server:t.server,contentCount:s.length}}}catch(s){return{content:[{type:"text",text:`Error reading resource: ${s.message}`}],details:{error:s.message}}}}}}import*as It from"node:fs";import*as ur from"node:path";import{pathToFileURL as oA}from"node:url";var vm={preToolUse:"tool.before_invoke",postToolUse:"tool.after_invoke",onTurnStart:"turn.submitted",onTurnEnd:"turn.completed",onSessionEnd:"session.ended"};var Ps=class{constructor(e){this.config=e;this.log=e.log??{info:()=>{},warn:()=>{}}}config;loaded=[];pluginSkills=[];activations=new Map;log;async loadAll(){for(let e of this.config.pluginDirs){if(!It.existsSync(e))continue;let t;try{t=It.readdirSync(e,{withFileTypes:!0})}catch{continue}for(let r of t){if(!r.isDirectory()||r.name.startsWith(".")||r.name.startsWith("_"))continue;let s=ur.join(e,r.name);await this.loadPlugin(r.name,s)}}return this.log.info(`[plugins] loaded ${this.loaded.length} plugin(s): ${this.loaded.map(e=>e.name).join(", ")||"(none)"}`),this.loaded}getPluginSkills(){return this.pluginSkills}getLoaded(){return this.loaded}async discoverNew(){let e=new Set(this.loaded.map(r=>r.name)),t=0;for(let r of this.config.pluginDirs){if(!It.existsSync(r))continue;let s;try{s=It.readdirSync(r,{withFileTypes:!0})}catch{continue}for(let o of s){if(!o.isDirectory()||o.name.startsWith(".")||o.name.startsWith("_")||e.has(o.name))continue;let i=ur.join(r,o.name);await this.loadPlugin(o.name,i),t++}}return t>0&&this.log.info(`[plugins] discovered ${t} new plugin(s)`),t}async refreshActivations(){let e=Date.now();for(let[t,r]of this.activations){if(e-r.lastCheckAt<r.ttlMs)continue;let s;try{s=await r.checkFn()}catch(o){this.log.warn(`[plugins] ${t}: check_fn error: ${o instanceof Error?o.message:o}`),s=r.lastResult}if(r.lastCheckAt=e,s!==r.lastResult){if(r.lastResult=s,s&&!r.active){for(let o of r.tools)Pe(o);r.active=!0,this.log.info(`[plugins] ${t}: reactivated (${r.tools.length} tools)`)}else if(!s&&r.active){for(let o of r.tools)ps(o.name);for(let o of r.hookUnregisterFns)o();r.active=!1,this.log.info(`[plugins] ${t}: deactivated`)}}}}async loadPlugin(e,t){let r=["index.js","index.mjs"],s=null;for(let f of r){let y=ur.join(t,f);if(It.existsSync(y)){s=y;break}}if(!s){this.log.warn(`[plugins] ${e}: no index.js found, skipping`);return}let o=0,i=0,a=0,c=[],l=[],u=null,d=6e4,p={},m=ur.join(t,"config.json");if(It.existsSync(m))try{p=JSON.parse(It.readFileSync(m,"utf8"))}catch{}let h={pluginName:e,registerTool:f=>{Pe(f),c.push(f),o++},registerHook:(f,y)=>{let b=vm[f];if(!b){this.log.warn(`[plugins] ${e}: unknown hook phase "${f}"`);return}let T=this.config.hookRegistry.register({point:b,handler:y,label:`plugin:${e}:${f}`,priority:200});l.push(T),i++},registerSkill:f=>{this.pluginSkills.push(f),a++},getConfig:()=>p,setActivationCheck:(f,y)=>{u=f,y!==void 0&&(d=y)}};try{let y=await import(oA(s).href);if(typeof y.register!="function"){this.log.warn(`[plugins] ${e}: no register() export, skipping`);return}await y.register(h),u&&this.activations.set(e,{checkFn:u,ttlMs:d,lastCheckAt:Date.now(),lastResult:!0,tools:c,hookUnregisterFns:l,active:!0}),this.loaded.push({name:e,directory:t,toolCount:o,hookCount:i,skillCount:a}),this.log.info(`[plugins] ${e}: ${o} tools, ${i} hooks, ${a} skills`)}catch(f){this.log.warn(`[plugins] ${e}: load error: ${f instanceof Error?f.message:f}`)}}};ae();import*as De from"node:fs";import*as pr from"node:path";function dc(){return ud()}function Sm(){return pr.join(dc(),"installed_plugins.json")}function Tm(){let n=Sm();if(!De.existsSync(n))return{version:1,plugins:[]};try{return JSON.parse(De.readFileSync(n,"utf-8"))}catch{return{version:1,plugins:[]}}}function iA(n){let e=dc();De.existsSync(e)||De.mkdirSync(e,{recursive:!0}),De.writeFileSync(Sm(),JSON.stringify(n,null,2),"utf-8")}function aA(n,e){return!(e.blocklist?.includes(n)||e.allowlist&&!e.allowlist.includes(n))}async function cA(n,e,t){let{execFile:r}=await import("node:child_process"),{promisify:s}=await import("node:util"),o=s(r),i=dc(),a=e?`${n}@${e}`:n;try{let{stdout:c}=await o("npm",["pack",a,"--pack-destination",i],{timeout:6e4,cwd:i}),l=c.trim().split(`
|
|
512
512
|
`).pop()?.trim();if(!l)return t.warn(`[marketplace] npm pack returned no output for ${a}`),null;let u=pr.join(i,l),p=l.match(/^(.+)-(\d+\.\d+\.\d+.*)\.tgz$/)?.[2]??"0.0.0",m=pr.join(i,`${n}@${p}`);De.existsSync(m)||De.mkdirSync(m,{recursive:!0}),await o("tar",["xzf",u,"-C",m,"--strip-components=1"],{timeout:3e4});try{De.unlinkSync(u)}catch{}let h=pr.join(m,"package.json");if(De.existsSync(h))try{await o("npm",["install","--production","--no-save"],{cwd:m,timeout:12e4})}catch(f){t.warn(`[marketplace] npm install for ${n} failed: ${f.message}`)}return t.info(`[marketplace] installed ${n}@${p} from npm`),{name:n,version:p,installPath:m}}catch(c){return t.warn(`[marketplace] failed to install ${a} from npm: ${c.message}`),null}}function lA(){return Tm().plugins.filter(e=>De.existsSync(e.installPath)).map(e=>e.installPath)}async function dA(n,e){let t=Tm(),r=[];for(let s of n.enabledPlugins){let o=s.specifier.split("/").pop()??s.specifier;if(!aA(o,n)){e.warn(`[marketplace] plugin "${o}" blocked by enterprise policy`);continue}let i=t.plugins.find(c=>c.source.specifier===s.specifier&&c.source.type===s.type);if(i&&De.existsSync(i.installPath)&&(!s.version||i.version===s.version)){r.push(i.installPath);continue}let a=null;switch(s.type){case"npm":a=await cA(s.specifier,s.version,e);break;case"git":case"url":e.warn(`[marketplace] ${s.type} source not yet implemented for "${s.specifier}"`);break}if(a){let c={name:a.name,version:a.version,source:s,installPath:a.installPath,installedAt:new Date().toISOString()};t.plugins=t.plugins.filter(l=>!(l.source.specifier===s.specifier&&l.source.type===s.type)),t.plugins.push(c),r.push(a.installPath)}}return iA(t),r}function uA(){let n=md();if(!De.existsSync(n))return null;try{return JSON.parse(De.readFileSync(n,"utf-8"))}catch{return null}}async function Rm(n,e){let t=[...n],r=lA();t.push(...r);let s=uA();if(s&&s.enabledPlugins.length>0)try{let o=await dA(s,e),i=new Set(t);for(let a of o)i.has(a)||t.push(a)}catch(o){e.warn(`[marketplace] failed to update plugins: ${o.message}`)}return t}var Is=class{mode;rules;defaultBehavior;compiledPatterns;constructor(e){this.mode=e.mode,this.rules=[...e.rules],this.defaultBehavior=e.defaultBehavior,this.compiledPatterns=this.compileRules(this.rules)}getMode(){return this.mode}setMode(e){this.mode=e}getRules(){return this.rules}getDefaultBehavior(){return this.defaultBehavior}replaceRules(e){this.rules=[...e],this.compiledPatterns=this.compileRules(this.rules)}setDefaultBehavior(e){this.defaultBehavior=e}addRule(e){this.rules.push(e),this.compiledPatterns=this.compileRules(this.rules)}applyUpdate(e){this.addRule({pattern:e.pattern,behavior:e.behavior,reason:e.description,source:"user"})}check(e){let{toolName:t,meta:r}=e;switch(this.mode){case"bypassPermissions":return{behavior:"allow",decisionReason:{type:"mode",mode:"bypassPermissions"}};case"dontAsk":return r?.isReadOnly?{behavior:"allow",decisionReason:{type:"mode",mode:"dontAsk"}}:{behavior:"deny",message:`Tool "${t}" denied \u2014 mode is dontAsk`,decisionReason:{type:"mode",mode:"dontAsk"}};case"plan":return{behavior:"deny",message:`Tool "${t}" paused \u2014 mode is plan (execution suspended)`,decisionReason:{type:"mode",mode:"plan"}}}for(let{rule:s,regex:o}of this.compiledPatterns)if(o.test(t))return mA(s,e);return r?.isReadOnly?{behavior:"allow",decisionReason:{type:"tool_check",reason:"isReadOnly"}}:r?.requiresApproval?{behavior:"ask",message:`Tool "${t}" requires approval`,toolName:t,input:e.arguments,decisionReason:{type:"tool_check",reason:"requiresApproval"}}:this.mode==="acceptEdits"?{behavior:"allow",decisionReason:{type:"mode",mode:"acceptEdits"}}:r?.isDangerous?{behavior:"ask",message:`Tool "${t}" is marked dangerous`,toolName:t,input:e.arguments,decisionReason:{type:"tool_check",reason:"isDangerous"}}:this.defaultBehavior==="allow"?{behavior:"allow"}:this.defaultBehavior==="deny"?{behavior:"deny",message:`Tool "${t}" denied by default policy`,decisionReason:{type:"other",reason:"default_deny"}}:{behavior:"ask",message:`Tool "${t}" requires approval (default policy)`,toolName:t,input:e.arguments}}compileRules(e){return e.map(t=>({rule:t,regex:pA(t.pattern)}))}};function _s(n){if(!n||typeof n!="object")return{mode:"default",rules:[],defaultBehavior:"allow"};let e=n,t=[];for(let a of["allow","deny","ask"]){let c=e[a];if(Array.isArray(c))for(let l of c)typeof l=="string"&&t.push({pattern:l,behavior:a,source:"config"})}if(Array.isArray(e.rules)){for(let a of e.rules)if(a&&typeof a=="object"){let c=a,l=c.pattern,u=c.behavior??c.action;typeof l=="string"&&typeof u=="string"&&(u==="allow"||u==="deny"||u==="ask")&&t.push({pattern:l,behavior:u,reason:typeof c.reason=="string"?c.reason:void 0,source:typeof c.source=="string"?c.source:"config"})}}let r=e.mode,s=typeof r=="string"&&gA(r)?r:"default",o=e.default??e.defaultBehavior,i=typeof o=="string"&&fA(o)?o:"allow";return{mode:s,rules:t,defaultBehavior:i}}function pA(n){let t=n.replace(/[.+^${}()|[\]\\]/g,"\\$&").replace(/\*+/g,".*");return new RegExp(`^${t}$`,"i")}function mA(n,e){let t={type:"rule",rule:n};return n.behavior==="allow"?{behavior:"allow",decisionReason:t}:n.behavior==="deny"?{behavior:"deny",message:n.reason??`Tool "${e.toolName}" denied by rule "${n.pattern}"`,decisionReason:t}:{behavior:"ask",message:n.reason??`Tool "${e.toolName}" requires approval (rule "${n.pattern}")`,toolName:e.toolName,input:e.arguments,decisionReason:t}}function gA(n){return n==="default"||n==="bypassPermissions"||n==="acceptEdits"||n==="dontAsk"||n==="plan"}function fA(n){return n==="allow"||n==="deny"||n==="ask"}import{randomUUID as xA}from"node:crypto";var hA=new Set(["nodeversion","npmversion","npxversion","pnpmversion","yarnversion","bunversion","denoversion","pythonversion","python3version","pipversion","rubyversion","go version","rustcversion","cargoversion","java -version","javac -version","dotnetversion","gccversion","g++version","clangversion","gitversion","dockerversion","--help","-h"]),wm=new Set(["ls","dir","find","fd","locate","which","where","type","cat","head","tail","less","more","bat","wc","file","stat","du","df","tree","exa","eza","grep","rg","ripgrep","ag","ack","fgrep","egrep","git status","git log","git diff","git show","git branch","git tag","git remote","git stash list","git blame","git shortlog","git describe","git rev-parse","git ls-files","git ls-tree","git cat-file","git reflog","ps","top","htop","uptime","uname","hostname","whoami","id","env","printenv","echo","ping","nslookup","dig","host","ifconfig","ip","netstat","ss","npm list","npm ls","npm info","npm view","npm outdated","npm audit","pnpm list","pnpm ls","pnpm outdated","pip list","pip show","pip freeze","cargo tree","npm test","npm run test","npm run build","npm run lint","pnpm test","pnpm run test","pnpm run build","pnpm run lint","yarn test","yarn build","yarn lint","cargo test","cargo build","cargo check","cargo clippy","go test","go build","go vet","make","cmake","pytest","python -m pytest","python3 -m pytest","jest","vitest","mocha","tsc","tscnoEmit","eslint","prettier","oxlint"]),yA=[/\brm\s+-rf?\s+[/~]/,/\brm\s+-rf?\s+\.\.\//,/\bsudo\b/,/\bsu\s/,/\bchmod\s+777\b/,/\bmkfs\b/,/\bfdisk\b/,/\bdd\s+if=/,/\bsystemctl\s+(start|stop|restart|enable|disable)\b/,/\bservice\s+\S+\s+(start|stop|restart)\b/,/\breg\s+(add|delete)\b/i,/\\Windows\\System32/i,/\/etc\/(passwd|shadow|sudoers|fstab)/,/\bgit\s+push\s+.*--force\b/,/\bgit\s+push\s+-f\b/,/\bcurl\b.*(-H|--header)\s+.*[Aa]uthorization/,/\bwget\b.*--header.*[Aa]uthorization/,/\bcurl\b.*\|\s*(sh|bash|zsh)\b/,/\bwget\b.*-O\s*-\s*\|\s*(sh|bash|zsh)\b/,/\bnpm\s+install\s+-g\b/,/\bpip\s+install\b(?!.*-r\b)(?!.*requirements)/,/\bDROP\s+(DATABASE|TABLE|SCHEMA)\b/i,/\bTRUNCATE\s+TABLE\b/i],Am=new Set(["npm install","npm i","npm ci","pnpm install","pnpm i","yarn install","yarn","pip install -r","pip install -e","cargo build","cargo install","go mod download","go get","bundle install","composer install","git add","git commit","git stash","git checkout","git switch","git merge","git rebase","git cherry-pick","git pull","git fetch","docker build","docker compose","mkdir","touch","cp"]);function xm(n,e,t){let r=n.trim();if(!r)return{decision:"allow",reason:"empty command"};let s=ja(r)??Ua(r)??void 0;for(let l of yA)if(l.test(r))return{decision:"deny",reason:`matches dangerous pattern: ${l.source}`,destructiveWarning:s};for(let l of hA)if(r===l||r.startsWith(l+" "))return{decision:"allow",reason:`known safe command: ${l}`,destructiveWarning:s};let o=r.split(/\s+/),i=o[0],a=o.length>1?`${o[0]} ${o[1]}`:i;return wm.has(i)||wm.has(a)?{decision:"allow",reason:`known safe command: ${i}`,destructiveWarning:s}:e&&t&&e.startsWith(t)&&(Am.has(i)||Am.has(a))?{decision:"allow",reason:`safe in project: ${a}`,destructiveWarning:s}:{decision:"defer",reason:"unknown command \u2014 needs LLM classification",destructiveWarning:s}}function bA(n){let e=Object.keys(n).sort(),t={};for(let r of e){let s=n[r];typeof s=="string"?t[r]=s.replace(/\s+/g," ").trim():t[r]=s}return JSON.stringify(t)}function uc(n,e){return`${n}::${bA(e)}`}var kA=500,Cs=class{cache=new Map;get(e,t){let r=uc(e,t),s=this.cache.get(r);if(s)return s.hitCount++,s}set(e,t,r){if(this.cache.size>=kA){let o=this.cache.keys().next().value;o!==void 0&&this.cache.delete(o)}let s=uc(e,t);this.cache.set(s,{shouldBlock:r.shouldBlock,reason:r.reason,classifiedAt:Date.now(),hitCount:0})}has(e,t){return this.cache.has(uc(e,t))}clear(){this.cache.clear()}get size(){return this.cache.size}get totalHits(){let e=0;for(let t of this.cache.values())e+=t.hitCount;return e}};var vA=new Set(["read","search","instructions","think","task","memory","skill","tool_search","plan_mode","lsp","brief","web_search","checkpoint"]);function mr(n){return vA.has(n)}var Pm=`You are a security classifier for an AI coding agent. Your job is to decide whether a tool invocation is safe to execute without user confirmation.
|
|
513
513
|
|
|
514
514
|
The agent operates in a workspace and has been given permission to use tools autonomously. You must decide if each tool call is SAFE (routine development work) or DANGEROUS (could cause harm, data loss, or unexpected side effects).
|
|
@@ -659,13 +659,13 @@ ${s}`}],details:{type:"repl",error:r.error,duration:r.duration}}:{content:[{type
|
|
|
659
659
|
`)}catch(u){clearTimeout(l),this.pendingRpcs.delete(o),c(u instanceof Error?u:new Error(String(u)))}})}async initialize(e){let t=await this.sendRpc(e,"initialize",{protocolVersion:mx,clientInfo:{name:"qlogicagent",version:"1.0.0"},clientCapabilities:{fs:{readTextFile:!0,writeTextFile:!0},terminal:!0,auth:{terminal:!1}}},gx),r=t?.agentCapabilities??{};return{protocolVersion:typeof t?.protocolVersion=="number"?t.protocolVersion:0,agentCapabilities:{loadSession:r.loadSession===!0,mcpCapabilities:r.mcpCapabilities,promptCapabilities:r.promptCapabilities,sessionCapabilities:r.sessionCapabilities},agentInfo:t?.agentInfo,authMethods:t?.authMethods}}async createSession(e,t){let r={cwd:t.cwd,mcpServers:t.mcpServers??[]};t.additionalDirectories?.length&&(r.additionalDirectories=t.additionalDirectories),t.systemPrompt&&(r.systemPrompt=t.systemPrompt);let s=await this.sendRpc(e,"session/new",r);if(typeof s?.sessionId!="string")throw new Error("ACP session/new: agent did not return sessionId");return{sessionId:s.sessionId}}async sendPrompt(e,t,r,s=3e5){let o=await this.sendRpc(e,"session/prompt",{sessionId:t,prompt:[{type:"text",text:r}]},s);return{stopReason:o?.stopReason??"end_turn",usage:o?.usage,userMessageId:o?.userMessageId}}async resumeSession(e,t,r){let s={sessionId:t,cwd:r?.cwd??process.cwd(),mcpServers:r?.mcpServers??[]},o=await this.sendRpc(e,"session/load",s,3e4);if(typeof o?.sessionId!="string")throw new Error("ACP session/load: agent did not return sessionId");return{sessionId:o.sessionId}}async closeSession(e,t){try{await this.sendRpc(e,"session/close",{sessionId:t},5e3)}catch{}}static translateNotification(e,t){let r=t;if(e==="session/update"){if(!r)return null;let s=r.update;if(!s)return null;let o=s.sessionUpdate,i=r.sessionId;switch(o){case gt.AGENT_MESSAGE_CHUNK:{let a=s.content;return{method:"turn.delta",params:{text:a?.text??a?.content??"",sessionId:i,messageId:s.messageId}}}case gt.AGENT_THOUGHT_CHUNK:return{method:"turn.thought_delta",params:{text:s.content?.text??"",sessionId:i}};case gt.TOOL_CALL:return{method:"turn.tool_call",params:{callId:s.toolCallId,toolName:s.title,status:s.status??"running",content:s.content,kind:s.kind,rawInput:s.rawInput,sessionId:i}};case gt.TOOL_CALL_UPDATE:return{method:"turn.tool_result",params:{callId:s.toolCallId,toolName:s.title,status:s.status??"completed",content:s.content,rawOutput:s.rawOutput,sessionId:i}};case gt.USAGE_UPDATE:return{method:"turn.usage_update",params:s??{}};case gt.PLAN:return{method:"turn.plan",params:{steps:s.steps,sessionId:i}};case gt.AVAILABLE_COMMANDS_UPDATE:case gt.CURRENT_MODE_UPDATE:case gt.CONFIG_OPTION_UPDATE:case gt.SESSION_INFO_UPDATE:return{method:"turn.session_info",params:{type:o,...s,sessionId:i}};case gt.USER_MESSAGE_CHUNK:return null;default:return{method:`turn.${o??"unknown"}`,params:{...s,sessionId:i}}}}return null}};var yr=class{usage={inputTokens:0,outputTokens:0,totalTokens:0,cachedReadTokens:0,thoughtTokens:0,cost:0,hasTier1:!1,turnCount:0};onUsageUpdate(e){this.usage.hasTier1=!0,typeof e.inputTokens=="number"&&(this.usage.inputTokens+=e.inputTokens),typeof e.outputTokens=="number"&&(this.usage.outputTokens+=e.outputTokens),typeof e.totalTokens=="number"&&(this.usage.totalTokens+=e.totalTokens),typeof e.cost=="number"&&(this.usage.cost+=e.cost)}onPromptResponseUsage(e){e&&(this.usage.hasTier1||(this.usage.turnCount++,typeof e.inputTokens=="number"&&(this.usage.inputTokens+=e.inputTokens),typeof e.outputTokens=="number"&&(this.usage.outputTokens+=e.outputTokens),typeof e.totalTokens=="number"&&(this.usage.totalTokens+=e.totalTokens),typeof e.cachedReadTokens=="number"&&(this.usage.cachedReadTokens+=e.cachedReadTokens),typeof e.thoughtTokens=="number"&&(this.usage.thoughtTokens+=e.thoughtTokens)))}getUsage(){return{...this.usage}}reset(){this.usage={inputTokens:0,outputTokens:0,totalTokens:0,cachedReadTokens:0,thoughtTokens:0,cost:0,hasTier1:!1,turnCount:0}}hasData(){return this.usage.hasTier1||this.usage.turnCount>0}};import{execSync as eg}from"node:child_process";import{existsSync as tg,readdirSync as fx}from"node:fs";import{homedir as hx,platform as yx}from"node:os";import{join as br}from"node:path";var hc={claude:{id:"claude",name:"Claude Code",cliCommand:"claude",acpArgs:["--experimental-acp"],authRequired:!0,skillsDirs:[".claude/skills"],supportsBaseUrlOverride:!0,apiKeyEnvVar:"ANTHROPIC_API_KEY",baseUrlEnvVar:"ANTHROPIC_BASE_URL"},codex:{id:"codex",name:"OpenAI Codex CLI",cliCommand:"codex-acp",acpArgs:[],authRequired:!0,supportsBaseUrlOverride:!0,apiKeyEnvVar:"OPENAI_API_KEY",baseUrlEnvVar:"OPENAI_BASE_URL"},qwen:{id:"qwen",name:"Qwen Code",cliCommand:"qwen-code",acpArgs:["--acp","--experimental-skills"],defaultCliPath:"npx @qwen-code/qwen-code",authRequired:!0,skillsDirs:[".qwen/skills"],supportsBaseUrlOverride:!0,apiKeyEnvVar:"DASHSCOPE_API_KEY"},kimi:{id:"kimi",name:"Kimi CLI",cliCommand:"kimi",acpArgs:["acp"],authRequired:!1,skillsDirs:[".kimi/skills"],supportsBaseUrlOverride:!0},opencode:{id:"opencode",name:"OpenCode",cliCommand:"opencode",acpArgs:["acp"],authRequired:!1,skillsDirs:[".opencode/skills"],supportsBaseUrlOverride:!0},cursor:{id:"cursor",name:"Cursor Agent",cliCommand:"cursor-agent",acpArgs:["acp"],authRequired:!0,skillsDirs:[".cursor/skills"],supportsBaseUrlOverride:!1},hermes:{id:"hermes",name:"Hermes Agent",cliCommand:"hermes",acpArgs:["acp"],authRequired:!1,supportsBaseUrlOverride:!0},copilot:{id:"copilot",name:"GitHub Copilot",cliCommand:"copilot",acpArgs:["--acp"],authRequired:!0,supportsBaseUrlOverride:!1},codebuddy:{id:"codebuddy",name:"CodeBuddy",cliCommand:"codebuddy",acpArgs:["--acp"],authRequired:!0,skillsDirs:[".codebuddy/skills"],supportsBaseUrlOverride:!0},kiro:{id:"kiro",name:"Kiro CLI",cliCommand:"kiro-cli",acpArgs:["acp"],authRequired:!0,supportsBaseUrlOverride:!0},snow:{id:"snow",name:"Snow",cliCommand:"snow",acpArgs:["--acp"],authRequired:!0,supportsBaseUrlOverride:!0},qoder:{id:"qoder",name:"Qoder",cliCommand:"qodercli",acpArgs:["--acp"],authRequired:!0,supportsBaseUrlOverride:!0},gemini:{id:"gemini",name:"Gemini CLI",cliCommand:"gemini",acpArgs:["--acp"],defaultCliPath:"npx @google/gemini-cli",authRequired:!0,supportsBaseUrlOverride:!1},glm:{id:"glm",name:"GLM Agent",cliCommand:"glm-acp-agent",acpArgs:[],defaultCliPath:"npx glm-acp-agent",authRequired:!0,supportsBaseUrlOverride:!0,apiKeyEnvVar:"ZHIPU_API_KEY"},cline:{id:"cline",name:"Cline",cliCommand:"cline",acpArgs:["--acp"],defaultCliPath:"npx cline",authRequired:!0,supportsBaseUrlOverride:!0},nova:{id:"nova",name:"Nova",cliCommand:"nova",acpArgs:["acp"],defaultCliPath:"npx @compass-ai/nova",authRequired:!0,supportsBaseUrlOverride:!0},openclaw:{id:"openclaw",name:"OpenClaw",cliCommand:"openclaw",acpArgs:["--acp"],authRequired:!0,supportsBaseUrlOverride:!0,apiKeyEnvVar:"OPENCLAW_API_KEY",baseUrlEnvVar:"OPENCLAW_BASE_URL"}};var bc=yx()==="win32";function yc(n){try{let e=bc?`where ${n}`:`which ${n}`;return eg(e,{encoding:"utf8",timeout:5e3,stdio:["pipe","pipe","pipe"]}).trim().split(/\r?\n/)[0]?.trim()||null}catch{return null}}function bx(n,e){let t=o=>{let i=o.match(/^(\d+)\.(\d+)\.(\d+)/);return i?[Number(i[1]),Number(i[2]),Number(i[3])]:[0,0,0]},r=t(n),s=t(e);for(let o=0;o<3;o+=1)if(r[o]!==s[o])return s[o]-r[o];return e.localeCompare(n)}function kx(){if(!bc)return null;let n=[process.env.COPILOT_CACHE_HOME?br(process.env.COPILOT_CACHE_HOME,"pkg","win32-x64"):null,process.env.LOCALAPPDATA?br(process.env.LOCALAPPDATA,"copilot","pkg","win32-x64"):null,process.env.COPILOT_HOME?br(process.env.COPILOT_HOME,"pkg","win32-x64"):null,br(hx(),".copilot","pkg","win32-x64")].filter(e=>!!e);for(let e of n)try{let t=fx(e,{withFileTypes:!0}).filter(r=>r.isDirectory()).map(r=>r.name).sort(bx);for(let r of t){let s=br(e,r,"npm-loader.js");if(tg(s))return s}}catch{}return null}function vx(n){return n.id==="copilot"?kx()??yc(n.cliCommand):yc(n.cliCommand)}function Sx(n){try{let e=n.endsWith("npm-loader.js")?`"${process.execPath}" "${n}" version`:`"${n}" version`;return eg(e,{encoding:"utf8",timeout:5e3,stdio:["pipe","pipe","pipe"]}).trim().match(/(\d+\.\d+[\w.-]*)/)?.[1]??null}catch{return null}}function Tx(n,e){if(!bc)return{cliPath:n,acpArgs:e};if(n.endsWith("npm-loader.js")){let r=e.includes("--no-auto-update");return{cliPath:process.execPath,acpArgs:[n,...e,...r?[]:["--no-auto-update"]]}}let t=`${n}.ps1`;return tg(t)?{cliPath:"powershell.exe",acpArgs:["-NoProfile","-ExecutionPolicy","Bypass","-File",t,...e]}:{cliPath:n,acpArgs:e}}var Rx=6e4,Ds=class{cache=null;configStore=null;setConfigStore(e){this.configStore=e}scan(e=!1){if(!e&&this.cache&&Date.now()-this.cache.timestamp<Rx)return this.cache.agents;let t=[];for(let r of Object.values(hc))t.push(this.detectBackend(r));if(this.configStore?.customAgents)for(let r of Object.values(this.configStore.customAgents))t.push(this.detectCustomAgent(r));return this.cache={agents:t,timestamp:Date.now()},t}list(){return this.cache?this.cache.agents:this.scan()}clearCache(){this.cache=null}detectBackend(e){let t=vx(e),r=this.hasAgentConfig(e.id);if(!t)return{id:e.id,name:e.name,category:"teammate",protocol:"acp",status:"not_installed",authRequired:e.authRequired,hasConfig:r,supportsBaseUrlOverride:e.supportsBaseUrlOverride,capabilities:{supportsMcp:!0,supportsResume:!1,supportsUsageUpdate:e.id==="claude"||e.id==="codex",skillsDirs:e.skillsDirs}};let s=Sx(t);return e.id==="copilot"&&!s?{id:e.id,name:e.name,category:"teammate",protocol:"acp",status:"not_installed",authRequired:e.authRequired,hasConfig:r,supportsBaseUrlOverride:e.supportsBaseUrlOverride,capabilities:{supportsMcp:!0,supportsResume:!1,supportsUsageUpdate:!1,skillsDirs:e.skillsDirs}}:{id:e.id,name:e.name,category:"teammate",protocol:"acp",status:"available",cliPath:t,version:s??void 0,authRequired:e.authRequired,hasConfig:r,supportsBaseUrlOverride:e.supportsBaseUrlOverride,capabilities:{supportsMcp:!0,supportsResume:e.id==="claude"||e.id==="goose"||e.id==="copilot",supportsUsageUpdate:e.id==="claude"||e.id==="codex"||e.id==="copilot",skillsDirs:e.skillsDirs}}}detectCustomAgent(e){let t=yc(e.cliCommand),r=this.hasAgentConfig(e.id);return{id:e.id,name:e.name,category:"teammate",protocol:"acp",status:t?"available":"not_installed",cliPath:t??void 0,authRequired:e.authRequired??!1,hasConfig:r,supportsBaseUrlOverride:e.supportsBaseUrlOverride??!1,capabilities:{supportsMcp:!0,supportsResume:!1,supportsUsageUpdate:!1,skillsDirs:e.skillsDirs}}}hasAgentConfig(e){if(!this.configStore)return!1;let t=this.configStore.agents[e];return!!(t?.apiKey||t?.baseUrl||t?.customCliPath)}buildExternalDescriptor(e){let t=this.list().find(i=>i.id===e);if(!t||t.protocol!=="acp"||t.status!=="available"||!t.cliPath)return null;let r=hc[e],s=this.configStore?.agents[e],o=s?.customCliPath?{cliPath:s.customCliPath,acpArgs:s?.customArgs??r?.acpArgs??[]}:Tx(t.cliPath,s?.customArgs??r?.acpArgs??[]);return{id:e,cliPath:o.cliPath,acpArgs:o.acpArgs,env:s?.env??r?.env,protocol:"acp"}}};var un="1.0.0",k={PARSE_ERROR:-32700,INVALID_REQUEST:-32600,METHOD_NOT_FOUND:-32601,INVALID_PARAMS:-32602,INTERNAL_ERROR:-32603,TURN_ABORTED:-32e3,TURN_TIMEOUT:-32001,LLM_ERROR:-32010,LLM_AUTH_ERROR:-32011,LLM_RATE_LIMIT:-32012,LLM_QUOTA_EXHAUSTED:-32013,LLM_MODEL_NOT_FOUND:-32014,TOOL_INVOKE_FAILED:-32020,TOOL_TIMEOUT:-32021,PROTOCOL_MISMATCH:-32030,REQUEST_DEADLINE_EXCEEDED:-32040,REQUEST_CANCELLED:-32041,REQUEST_DEDUPED:-32042,REQUEST_IDEMPOTENCY_REQUIRED:-32043};function kc(n){if(!n||typeof n!="object")return!1;let e=n;return e.jsonrpc==="2.0"&&typeof e.method=="string"&&e.method.length>0}import{randomUUID as wx}from"node:crypto";var Ax=["settings.list","settings.get","settings.validate","provider.list","config.get","config.tunables","tools.list","todos.list","tasks.list","agents.list","agents.get","agents.processes","agents.scan","session.list","session.get","session.resolve","thread.list","project.list","files.list","files.gitStatus","instructions.list","instructions.read","skills.list","skills.stats","memory.atlas","memory.activity","memory.list","memory.read","memory.search","media.listModels","media.status","pet.status","agent.health","agent.metrics"],xx=new Set(["thread.turn","memory.dream","memory.ingest","media.stt","pet.forge","solo.start","solo.evaluate","product.plan","product.create","product.message"]),Px=["memory.","pet.","usage."],Ix=new Set(["memory.atlas","memory.activity","memory.list","memory.read","memory.search","pet.status"]);function Ns(n){return xx.has(n)?{channel:"task",mutability:"write",defaultTimeoutMs:n==="thread.turn"?3e5:12e4}:Ax.some(e=>n===e||n.startsWith(`${e}.`)||n.startsWith(e))?{channel:"query",mutability:"read",defaultTimeoutMs:1e4}:{channel:"task",mutability:"write",defaultTimeoutMs:3e4}}function ng(n){return Ix.has(n)||Ns(n).mutability==="read"?!1:Px.some(e=>n.startsWith(e))}function vc(n,e={}){let t=e.now??Date.now(),r=Ns(n),s=e.timeoutMs??r.defaultTimeoutMs;return{requestId:e.requestId??wx(),createdAt:t,deadlineAt:t+s,channel:e.channel??r.channel,idempotencyKey:e.idempotencyKey,traceId:e.traceId}}function Os(n,e=Date.now()){let t=n.meta;if(!t||typeof t!="object")return{ok:!1,error:{code:k.INVALID_REQUEST,message:"RPC request meta is required."}};if(typeof t.requestId!="string"||t.requestId.length===0)return{ok:!1,error:{code:k.INVALID_REQUEST,message:"RPC request meta.requestId is required."}};if(t.channel!=="query"&&t.channel!=="task")return{ok:!1,error:{code:k.INVALID_REQUEST,message:"RPC request meta.channel must be query or task."}};if(typeof t.createdAt!="number"||!Number.isFinite(t.createdAt))return{ok:!1,error:{code:k.INVALID_REQUEST,message:"RPC request meta.createdAt is required."}};if(typeof t.deadlineAt!="number"||!Number.isFinite(t.deadlineAt))return{ok:!1,error:{code:k.INVALID_REQUEST,message:"RPC request meta.deadlineAt is required."}};if(t.deadlineAt<=e)return{ok:!1,error:{code:k.REQUEST_DEADLINE_EXCEEDED,message:"RPC request deadline has already expired."}};let r=Ns(n.method).channel;return t.channel!==r?{ok:!1,error:{code:k.INVALID_REQUEST,message:`RPC request channel mismatch: expected ${r}, got ${t.channel}.`}}:ng(n.method)&&(typeof t.idempotencyKey!="string"||t.idempotencyKey.length===0)?{ok:!1,error:{code:k.REQUEST_IDEMPOTENCY_REQUIRED,message:`RPC method ${n.method} requires meta.idempotencyKey.`}}:{ok:!0,meta:t}}var kr=class{now;active=new Map;idempotency=new Map;counters={completedRequests:0,cancelledRequests:0,deadlineExceededRequests:0,dedupedRequests:0,lateResponsesDropped:0,invalidRequests:0};constructor(e={}){this.now=e.now??(()=>Date.now())}begin(e,t){let r=Os({method:e,meta:t},this.now());if(!r.ok)return this.counters.invalidRequests+=1,{status:"rejected",error:r.error};if(t.idempotencyKey){let s=this.idempotency.get(t.idempotencyKey);if(s)return this.counters.dedupedRequests+=1,s.error?{status:"deduped",error:s.error}:{status:"deduped",result:s.result}}return this.active.set(t.requestId,{method:e,meta:t,cancelled:!1,startedAt:this.now()}),{status:"started"}}cancel(e,t="cancelled"){let r=this.active.get(e);return!r||r.cancelled?!1:(r.cancelled=!0,r.cancelReason=t,this.counters.cancelledRequests+=1,!0)}expire(e){return this.active.get(e)?(this.active.delete(e),this.counters.deadlineExceededRequests+=1,!0):!1}settle(e,t,r){let s=this.active.get(e);return s?(this.active.delete(e),s.cancelled?(this.counters.lateResponsesDropped+=1,{accepted:!1,reason:"cancelled"}):s.meta.deadlineAt<=this.now()?(this.counters.deadlineExceededRequests+=1,this.counters.lateResponsesDropped+=1,{accepted:!1,reason:"deadline_exceeded"}):(this.counters.completedRequests+=1,s.meta.idempotencyKey&&this.idempotency.set(s.meta.idempotencyKey,{result:t,error:r,settledAt:this.now()}),{accepted:!0})):{accepted:!1,reason:"unknown"}}metrics(){return{activeRequests:this.active.size,...this.counters}}};var rg=["turn.start","turn.delta","turn.end","turn.error","turn.recovery","turn.tool_call","turn.tool_result","turn.tool_blocked","turn.reasoning_delta","turn.approval_request","turn.skill_instruction","turn.ask_user","turn.media_result","turn.media_progress","turn.plan_update","turn.suggestions","turn.sidechain_started","turn.subagent_delta","turn.sidechain_completed","turn.task_updated","turn.todos_updated","turn.exec_progress","turn.usage_update","team.member.notification","session.info","memory.updated","skills.updated","pet.soul_ready","pet.reaction","pet.growth","pet.state","pet.confirm","pet.forged","system.activity"],sg=["solo.progress","solo.agentDelta","solo.agentUsage","solo.agentDiff","solo.evaluation","product.taskStarted","product.taskOutput","product.taskCompleted","product.taskFailed","product.budgetUpdate","product.checkpointed","product.dagTopology","plan.interrupted"],_x=[...rg,...sg];var ft={INITIALIZE:"initialize",SESSION_NEW:"session/new",SESSION_PROMPT:"session/prompt",SESSION_END:"session/end",SESSION_SET_CONFIG:"session/set_config_option",SESSION_SET_MODEL:"session/set_model",SESSION_SET_MODE:"session/set_mode",SESSION_UPDATE:"session/update",SESSION_REQUEST_PERMISSION:"session/request_permission",FS_READ_TEXT_FILE:"fs/read_text_file",FS_WRITE_TEXT_FILE:"fs/write_text_file"},ye={ABORT:"x/abort",DREAM:"x/dream",AGENTS_LIST:"x/agents.list",SOLO_START:"x/solo.start",SOLO_STATUS:"x/solo.status",SOLO_SELECT:"x/solo.select",SOLO_CANCEL:"x/solo.cancel",PRODUCT_CREATE:"x/product.create",PRODUCT_PLAN:"x/product.plan",PRODUCT_CONFIRM:"x/product.confirm",PRODUCT_MESSAGE:"x/product.message",PRODUCT_RESUME:"x/product.resume",PRODUCT_PAUSE:"x/product.pause",PRODUCT_CANCEL:"x/product.cancel",PRODUCT_ROLLBACK:"x/product.rollback",PRODUCT_STATUS:"x/product.status",SOLO_SUBSCRIBE:"x/solo.subscribe",SOLO_MESSAGE:"x/solo.message",SOLO_EVALUATE:"x/solo.evaluate",PRODUCT_SUBSCRIBE:"x/product.subscribe",TEAM_DELEGATE:"x/team.delegate"},ht={AGENT_MESSAGE_CHUNK:"agent_message_chunk",AGENT_THOUGHT_CHUNK:"agent_thought_chunk",TOOL_CALL:"tool_call",TOOL_CALL_UPDATE:"tool_call_update",PLAN:"plan",USAGE_UPDATE:"usage_update",CONFIG_OPTION_UPDATE:"config_option_update",SESSION_INFO_UPDATE:"session_info_update",AVAILABLE_COMMANDS_UPDATE:"available_commands_update"},Te={X_SUBAGENT_STARTED:"x_subagent_started",X_SUBAGENT_DELTA:"x_subagent_delta",X_SUBAGENT_ENDED:"x_subagent_ended",X_MEDIA_RESULT:"x_media_result",X_MEDIA_PROGRESS:"x_media_progress",X_SKILL_INSTRUCTION:"x_skill_instruction",X_RECOVERY:"x_recovery",X_SIDECHAIN_STARTED:"x_sidechain_started",X_SIDECHAIN_COMPLETED:"x_sidechain_completed",X_SUGGESTIONS:"x_suggestions",X_ASK_USER:"x_ask_user",X_SESSION_INFO:"x_session_info",X_MEMORY_UPDATED:"x_memory_updated",X_TEAM_MEMBER_UPDATE:"x_team_member_update",X_SOLO_STARTED:"x_solo_started",X_SOLO_AGENT_FINISHED:"x_solo_agent_finished",X_SOLO_SELECTED:"x_solo_selected",X_PRODUCT_TASK_STARTED:"x_product_task_started",X_PRODUCT_TASK_COMPLETED:"x_product_task_completed",X_PRODUCT_CHECKPOINT:"x_product_checkpoint"};function vr(n){if(!n||typeof n!="object")return!1;let e=n;return e.jsonrpc==="2.0"&&typeof e.method=="string"&&"id"in e}function Sr(n){if(!n||typeof n!="object")return!1;let e=n;return e.jsonrpc==="2.0"&&typeof e.method=="string"&&!("id"in e)}function Sc(n){if(!n||typeof n!="object")return!1;let e=n;return e.jsonrpc==="2.0"&&"id"in e&&!("method"in e)}var og="openai-codex";var TO={anthropic:{providerFamily:"anthropic"},"amazon-bedrock":{providerFamily:"anthropic"},"kimi-coding":{anthropicToolSchemaMode:"openai-functions",anthropicToolChoiceMode:"openai-string-modes",preserveAnthropicThinkingSignatures:!1},mistral:{transcriptToolCallIdMode:"strict9",transcriptToolCallIdModelHints:["mistral","mixtral","codestral","pixtral","devstral","ministral","mistralai"]},openai:{providerFamily:"openai"},[og]:{providerFamily:"openai"},openrouter:{openAiCompatTurnValidation:!1,providerThoughtSignatureSanitization:!0,providerThoughtSignatureModelHints:["gemini"]},opencode:{openAiCompatTurnValidation:!1,providerThoughtSignatureSanitization:!0,providerThoughtSignatureModelHints:["gemini"]},kilocode:{providerThoughtSignatureSanitization:!0,providerThoughtSignatureModelHints:["gemini"]}};var Ox=1;function Lx(n,e){return{jsonrpc:"2.0",id:Ox++,method:n,params:e,meta:vc(n)}}var $x=["NODE_ENV","HOME","PATH","TERM","OPENAI_API_KEY","OPENAI_BASE_URL","ANTHROPIC_API_KEY","ANTHROPIC_BASE_URL","HTTP_PROXY","HTTPS_PROXY","NO_PROXY","http_proxy","https_proxy","no_proxy"];function jx(n){let e={};for(let t of $x)process.env[t]&&(e[t]=process.env[t]);return n.apiKey&&(e.OPENAI_API_KEY=n.apiKey),n.baseUrl&&(e.OPENAI_BASE_URL=n.baseUrl),e.QLOGICAGENT_MEMBER_ID=n.memberId,e.QLOGICAGENT_MEMBER_NAME=n.name,n.agentType&&(e.QLOGICAGENT_AGENT_TYPE=n.agentType),n.model&&(e.QLOGICAGENT_MODEL=n.model),n.env&&Object.assign(e,n.env),e}var Rc=hi,Ux=yi,_n=bi,ag=ki;function Fx(n){return new Promise(e=>setTimeout(e,n))}var _t=class n{processes=new Map;callbacks;cliBinaryPath;mcpBridgeScriptPath;constructor(e={}){this.callbacks=e;let t=Cx(Tr(import.meta.url.startsWith("file://")?new URL(import.meta.url).pathname.replace(/^\/([A-Z]:)/,"$1"):process.cwd(),"..",".."));this.cliBinaryPath=Tr(t,"dist","cli.js"),this.mcpBridgeScriptPath=Tr(t,"dist","runtime","infra","mcp-bridge-server.js")}slog(e,t,r,s){let i=`[${new Date().toISOString()}] [${e}] [agent:${t}] [${r}] ${s}`;e==="warn"?this.callbacks.log?.warn(i):this.callbacks.log?.info(i)}async spawn(e){if(this.processes.has(e.memberId))throw new Error(`Agent process "${e.memberId}" already spawned`);let t=this.callbacks.log,r=jx(e),s={memberId:e.memberId,name:e.name,pid:-1,cwd:e.cwd,state:"starting",startedAt:Date.now()};if(e.external)return this.spawnAcpAgentWithRetry(e,s,r);let o=[this.cliBinaryPath];e.verbose&&o.push("--verbose"),this.slog("info",e.memberId,"spawn",`spawning ${e.name} in ${e.cwd}`);let i=Tc(process.execPath,o,{cwd:e.cwd,env:r,stdio:["pipe","pipe","pipe"],detached:!1});s.pid=i.pid??-1;let a=new Map;this.processes.set(e.memberId,{handle:s,child:i,pendingRpc:a}),Ls({input:i.stdout,crlfDelay:Number.POSITIVE_INFINITY}).on("line",l=>{let u=l.trim();if(u)try{let d=JSON.parse(u);if("id"in d&&typeof d.id=="number"){let p=a.get(d.id);if(p){clearTimeout(p.timer),a.delete(d.id);let m=d;m.error?p.reject(new Error(m.error.message)):p.resolve(m.result)}}if("method"in d&&!("id"in d)){let p=d;this.captureChildProgress(e.memberId,p.method,p.params),this.callbacks.onNotification?.(e.memberId,p.method,p.params)}}catch{this.slog("warn",e.memberId,"parse",`invalid JSON: ${u.slice(0,200)}`)}}),i.stderr&&Ls({input:i.stderr,crlfDelay:Number.POSITIVE_INFINITY}).on("line",u=>{this.callbacks.log?.debug?.(`[${new Date().toISOString()}] [debug] [agent:${e.memberId}] [stderr] ${u}`)}),i.on("exit",(l,u)=>{s.state!=="killed"&&(s.state=l===0?"completed":"failed"),s.endedAt=Date.now(),l!==0&&!s.error&&(s.error=`Process exited with code ${l} (signal: ${u})`);for(let[p,m]of a)clearTimeout(m.timer),m.reject(new Error(`Agent process exited (code=${l})`)),a.delete(p);this.callbacks.onStateChange?.(e.memberId,s.state),this.callbacks.onExit?.(e.memberId,l,u),this.slog("info",e.memberId,"exit",`exited (code=${l}, signal=${u})`)}),i.on("error",l=>{s.state="failed",s.error=l.message,s.endedAt=Date.now(),this.callbacks.onStateChange?.(e.memberId,"failed"),this.slog("warn",e.memberId,"error",l.message)}),this.callbacks.onStateChange?.(e.memberId,"starting");try{let l=await this.sendRpc(e.memberId,"initialize",{protocolVersion:"1.0",clientInfo:{name:"qlogicagent-team-leader",version:"1.0.0"}},15e3);s.state="ready",this.callbacks.onStateChange?.(e.memberId,"ready"),this.slog("info",e.memberId,"handshake",`initialized (pid=${s.pid})`);let u=l;u&&typeof u.sessionId=="string"&&(s.sessionId=u.sessionId)}catch(l){throw s.state="failed",s.error=`Initialize handshake failed: ${l instanceof Error?l.message:String(l)}`,s.endedAt=Date.now(),this.callbacks.onStateChange?.(e.memberId,"failed"),this.kill(e.memberId),new Error(s.error)}return s}async sendTask(e,t,r){let s=this.processes.get(e);if(!s)throw new Error(`No agent process: ${e}`);s.handle.state="running",this.callbacks.onStateChange?.(e,"running");try{let o;if(s.acpAdapter){let i=s.handle.sessionId??"default",a=await s.acpAdapter.sendPrompt(s.child,i,t,r?.timeout??3e5),c=s.handle.resultText??"";a.usage&&s.usageTracker&&s.usageTracker.onPromptResponseUsage(a.usage),o={content:c,stopReason:a.stopReason}}else{let i={content:t};r?.model&&(i.model=r.model),r?.apiKey&&(i.apiKey=r.apiKey),r?.baseUrl&&(i.baseUrl=r.baseUrl),r?.sessionId&&(i.sessionId=r.sessionId),o=await this.sendRpc(e,"thread.turn",i,r?.timeout??3e5);let a=o;a&&typeof a.content=="string"&&(s.handle.resultText=a.content)}return s.handle.state="completed",s.handle.endedAt=Date.now(),this.callbacks.onStateChange?.(e,"completed"),o}catch(o){throw s.handle.state="failed",s.handle.error=o instanceof Error?o.message:String(o),s.handle.endedAt=Date.now(),this.callbacks.onStateChange?.(e,"failed"),o}}async sendRpc(e,t,r,s=3e4){let o=this.processes.get(e);if(!o)throw new Error(`No agent process: ${e}`);let i=Lx(t,r);return new Promise((a,c)=>{let l=setTimeout(()=>{o.pendingRpc.delete(i.id),c(new Error(`RPC timeout: ${t} (${s}ms)`))},s);o.pendingRpc.set(i.id,{resolve:a,reject:c,timer:l});try{o.child.stdin.write(`${JSON.stringify(i)}
|
|
660
660
|
`)}catch(u){clearTimeout(l),o.pendingRpc.delete(i.id),c(u instanceof Error?u:new Error(String(u)))}})}async sendTaskAsync(e,t,r){let s=this.processes.get(e);if(!s)throw new Error(`No agent process: ${e}`);s.handle.state="running",this.callbacks.onStateChange?.(e,"running");let o={content:t};r?.model&&(o.model=r.model),r?.apiKey&&(o.apiKey=r.apiKey),r?.baseUrl&&(o.baseUrl=r.baseUrl),r?.sessionId&&(o.sessionId=r.sessionId);let i=r?.pingInterval??6e4,a=r?.pingTimeout??1e4,c=r?.timeout??0,l=Date.now(),u=c>0?c:1440*60*1e3,d=this.sendRpc(e,"thread.turn",o,u),p=setInterval(async()=>{if(c>0&&Date.now()-l>c){clearInterval(p),s.handle.state="failed",s.handle.error="Task timed out",s.handle.endedAt=Date.now(),this.callbacks.onStateChange?.(e,"failed");return}try{await this.sendRpc(e,"ping",void 0,a)}catch{this.slog("warn",s.handle.memberId,"heartbeat","ping failed")}},i);try{let m=await d;clearInterval(p),s.handle.state="completed",s.handle.endedAt=Date.now();let h=m;return h&&typeof h.content=="string"&&(s.handle.resultText=h.content),this.callbacks.onStateChange?.(e,"completed"),m}catch(m){throw clearInterval(p),s.handle.state="failed",s.handle.error=m instanceof Error?m.message:String(m),s.handle.endedAt=Date.now(),this.callbacks.onStateChange?.(e,"failed"),m}}async ping(e,t=5e3){let r=this.processes.get(e);if(!r)return!1;if(r.acpAdapter){try{let i=JSON.stringify({jsonrpc:"2.0",method:"notifications/ping",params:{timestamp:Date.now()}})+`
|
|
661
661
|
`;r.child.stdin?.write(i)}catch{return!1}let s=r.handle.lastActivityAt??0,o=Date.now()+t;for(;Date.now()<o;)if(await new Promise(i=>setTimeout(i,500)),(r.handle.lastActivityAt??0)>s)return!0;try{return await this.sendRpc(e,"ping",void 0,Math.min(t,3e3)),!0}catch{return!1}}try{return await this.sendRpc(e,"ping",void 0,t),!0}catch{return!1}}getStatus(e){let t=this.processes.get(e);if(!t)return null;let{handle:r}=t,s=r.state==="starting"||r.state==="ready"||r.state==="running",o=s?Date.now()-r.startedAt:void 0,i=r.lastActivityAt&&s?Math.round((Date.now()-r.lastActivityAt)/1e3):void 0;return{alive:s,state:r.state,runningFor:o,resultText:r.resultText,error:r.error,mediaProgress:r.mediaProgress,lastToolCall:r.lastToolCall,idleFor:i}}captureChildProgress(e,t,r){let s=this.processes.get(e);if(!s)return;let{handle:o}=s;switch(o.lastActivityAt=Date.now(),t){case"turn.media_progress":{let i=r;i&&typeof i.taskId=="string"&&(o.mediaProgress={taskId:i.taskId,mediaType:i.mediaType??"unknown",percent:typeof i.percent=="number"?i.percent:0,status:i.status??"unknown",provider:i.provider,updatedAt:Date.now()});break}case"turn.tool_call":{let i=r;i&&typeof i.name=="string"&&(o.lastToolCall=i.name);break}case"turn.delta":{let i=r;if(i&&typeof i.text=="string"){let a=i.text;o.resultText=`${o.resultText??""}${a}`,o.lastDelta=a.slice(-200)}break}case"turn.tool_result":{r&&o.mediaProgress&&o.mediaProgress.percent>=100&&(o.mediaProgress=void 0);break}}}async spawnAcpAgentWithRetry(e,t,r){let s=null;for(let o=0;o<=Rc;o++)try{if(o>0){this.processes.delete(e.memberId),t.state="starting",t.error=void 0,t.endedAt=void 0;let i=Ux*o;this.slog("info",e.memberId,"spawn",`retry ${o}/${Rc} after ${i}ms`),await Fx(i)}return await this.spawnAcpAgent(e,t,r)}catch(i){s=i instanceof Error?i:new Error(String(i)),this.slog("warn",e.memberId,"spawn",`attempt ${o+1} failed: ${s.message}`)}throw t.state="failed",t.error=`ACP spawn failed after ${Rc+1} attempts: ${s?.message}`,t.endedAt=Date.now(),this.callbacks.onStateChange?.(e.memberId,"failed"),new Error(t.error)}async spawnAcpAgent(e,t,r){let s=this.callbacks.log,o=e.external;o.env&&Object.assign(r,o.env);let i=[...o.acpArgs];this.slog("info",e.memberId,"spawn",`spawning ACP ${e.name} via ${o.cliPath} ${i.join(" ")}`);let a=Tc(o.cliPath,i,{cwd:e.cwd,env:r,stdio:["pipe","pipe","pipe"],detached:!1});t.pid=a.pid??-1;let c=new Map,l=new dn,u=new yr,{server:d,pipePath:p}=this.createMcpIpcServer(e.memberId);r.QLOGICAGENT_PARENT_RPC=p;let m;if(this.callbacks.sessionDir)try{Dx(this.callbacks.sessionDir,{recursive:!0}),m=Mx(Tr(this.callbacks.sessionDir,`${e.memberId}.stderr.log`),{flags:"a"})}catch{}this.processes.set(e.memberId,{handle:t,child:a,pendingRpc:c,acpAdapter:l,usageTracker:u,ipcServer:d,ipcPath:p,stderrStream:m}),l.attach(a,(h,f)=>{h==="usage_update"&&u.onUsageUpdate(f);let y=dn.translateNotification(h,f);y?(this.captureChildProgress(e.memberId,y.method,y.params),this.callbacks.onNotification?.(e.memberId,y.method,y.params)):(this.captureChildProgress(e.memberId,h,f),this.callbacks.onNotification?.(e.memberId,h,f))}),a.stderr&&Ls({input:a.stderr,crlfDelay:Number.POSITIVE_INFINITY}).on("line",f=>{this.callbacks.log?.debug?.(`[${new Date().toISOString()}] [debug] [agent:${e.memberId}] [stderr] ${f}`),m?.write(`${new Date().toISOString()} ${f}
|
|
662
|
-
`)}),a.on("exit",(h,f)=>{l.detach();let y=t.state;if(y!=="killed"&&y!=="completed"&&h!==0){let
|
|
662
|
+
`)}),a.on("exit",(h,f)=>{l.detach();let y=t.state;if(y!=="killed"&&y!=="completed"&&h!==0){let T=this.processes.get(e.memberId)?.runtimeRestartCount??0;if(T<_n){let w=ag*2**T;this.slog("warn",e.memberId,"crash",`crashed (code=${h}), restarting ${T+1}/${_n} after ${w}ms`),this.callbacks.onNotification?.(e.memberId,"agents.error",{agentId:e.memberId,phase:"runtime",error:`Process crashed (code=${h}, signal=${f}), restarting`,retriesLeft:_n-T-1}),setTimeout(()=>{this.attemptRuntimeRestart(e,r,T+1).catch(_=>{this.slog("warn",e.memberId,"restart",`failed: ${_ instanceof Error?_.message:String(_)}`)})},w);return}}y!=="killed"&&(t.state=h===0?"completed":"failed"),t.endedAt=Date.now(),h!==0&&!t.error&&(t.error=`ACP process exited with code ${h} (signal: ${f})`),this.callbacks.onStateChange?.(e.memberId,t.state),this.callbacks.onExit?.(e.memberId,h,f),this.slog("info",e.memberId,"exit",`ACP exited (code=${h}, signal=${f})`)}),a.on("error",h=>{l.detach(),t.state="failed",t.error=h.message,t.endedAt=Date.now(),this.callbacks.onStateChange?.(e.memberId,"failed"),this.callbacks.onNotification?.(e.memberId,"agents.error",{agentId:e.memberId,phase:"spawn",error:h.message,retriesLeft:0}),this.slog("warn",e.memberId,"error",h.message)}),this.callbacks.onStateChange?.(e.memberId,"starting");try{let h=await l.initialize(a);t.state="ready",t.supportsResume=h.agentCapabilities.loadSession===!0,this.callbacks.onStateChange?.(e.memberId,"ready"),this.slog("info",e.memberId,"handshake",`ACP initialized (protocol=${h.protocolVersion}, loadSession=${t.supportsResume}, pid=${t.pid})`);try{let f={cwd:e.cwd},y=[...e.mcpServers??[]],b=this.processes.get(e.memberId),w=h.agentCapabilities.mcpCapabilities?.stdio===!0;b?.ipcPath&&w&&y.push({name:"qlogicagent-tools",command:process.execPath,args:[this.mcpBridgeScriptPath],env:{QLOGICAGENT_PARENT_RPC:b.ipcPath,QLOGICAGENT_SESSION_ID:e.memberId}}),y.length>0&&(f.mcpServers=y),e.systemPrompt&&(f.systemPrompt=e.systemPrompt);let _=await l.createSession(a,f);t.sessionId=_.sessionId,this.slog("info",e.memberId,"session",`session created (id=${_.sessionId})`)}catch(f){this.slog("warn",e.memberId,"session",`session creation failed: ${f instanceof Error?f.message:String(f)}`)}this.startHeartbeat(e.memberId,f=>{this.slog("warn",f,"heartbeat","hang detected \u2014 force-killing"),this.callbacks.onNotification?.(f,"agents.error",{agentId:f,phase:"heartbeat",error:`Agent ${e.name} stopped responding (${n.MAX_MISSED_BEATS} missed heartbeats)`,retriesLeft:0}),this.kill(f)})}catch(h){throw t.state="failed",t.error=`ACP handshake failed: ${h instanceof Error?h.message:String(h)}`,t.endedAt=Date.now(),l.detach(),this.callbacks.onStateChange?.(e.memberId,"failed"),this.callbacks.onNotification?.(e.memberId,"agents.error",{agentId:e.memberId,phase:"handshake",error:t.error,retriesLeft:0}),this.kill(e.memberId),new Error(t.error)}return t}kill(e){let t=this.processes.get(e);if(t){this.stopHeartbeat(e),t.handle.state="killed",t.handle.endedAt=Date.now(),t.acpAdapter?.detach();try{t.ipcServer?.close()}catch{}try{t.stderrStream?.end()}catch{}try{t.child.kill("SIGTERM"),setTimeout(()=>{try{t.child.kill("SIGKILL")}catch{}},1e4)}catch{}this.callbacks.onStateChange?.(e,"killed"),this.slog("info",e,"kill",`killed (pid=${t.handle.pid})`)}}killAll(){for(let e of this.processes.keys())this.kill(e)}getHandle(e){return this.processes.get(e)?.handle}getAllHandles(){return[...this.processes.values()].map(e=>e.handle)}getUsageTracker(e){return this.processes.get(e)?.usageTracker??null}createMcpIpcServer(e){let t=e.replace(/[^a-zA-Z0-9-]/g,"-"),r=process.platform==="win32"?`\\\\.\\pipe\\qlogicagent-mcp-${t}-${Date.now()}`:Tr(Nx(),`qlogicagent-mcp-${t}-${Date.now()}.sock`),s=Ex(o=>{let i="";o.on("data",a=>{i+=a.toString();let c;for(;(c=i.indexOf(`
|
|
663
663
|
`))!==-1;){let l=i.slice(0,c).trim();i=i.slice(c+1),l&&this.handleMcpIpcMessage(e,l,o)}})});return s.listen(r),s.on("error",o=>{this.slog("warn",e,"mcp-ipc",`server error: ${o.message}`)}),{server:s,pipePath:r}}handleMcpIpcMessage(e,t,r){let s;try{s=JSON.parse(t)}catch{return}if(s.method==="mcp.toolCall"&&s.id!==void 0){let o=typeof s.params?.tool=="string"?s.params.tool:"",i=s.params?.arguments??{};if(!this.callbacks.onMcpToolCall){let a=JSON.stringify({jsonrpc:"2.0",id:s.id,error:{code:-32601,message:"No onMcpToolCall handler"}})+`
|
|
664
664
|
`;try{r.write(a)}catch{}return}this.callbacks.onMcpToolCall(e,o,i).then(a=>{let c=JSON.stringify({jsonrpc:"2.0",id:s.id,result:a})+`
|
|
665
665
|
`;try{r.write(c)}catch{}}).catch(a=>{let c=JSON.stringify({jsonrpc:"2.0",id:s.id,error:{code:-32603,message:a instanceof Error?a.message:String(a)}})+`
|
|
666
666
|
`;try{r.write(c)}catch{}})}else if(s.id!==void 0){let o=JSON.stringify({jsonrpc:"2.0",id:s.id,error:{code:-32601,message:`Unknown IPC method: ${s.method}`}})+`
|
|
667
|
-
`;try{r.write(o)}catch{}}}async attemptRuntimeRestart(e,t,r){let s=this.callbacks.log,o=this.processes.get(e.memberId),i=o?.ipcServer,a=o?.ipcPath,c=o?.stderrStream;this.processes.delete(e.memberId);try{let l={memberId:e.memberId,name:e.name,pid:-1,cwd:e.cwd,state:"starting",startedAt:Date.now()},u=e.external,d=[...u.acpArgs];a&&(t.QLOGICAGENT_PARENT_RPC=a);let p=Tc(u.cliPath,d,{cwd:e.cwd,env:t,stdio:["pipe","pipe","pipe"],detached:!1});l.pid=p.pid??-1;let m=new Map,h=new dn,f=new yr;this.processes.set(e.memberId,{handle:l,child:p,pendingRpc:m,acpAdapter:h,usageTracker:f,ipcServer:i,ipcPath:a,stderrStream:c,runtimeRestartCount:r}),h.attach(p,(
|
|
668
|
-
`)}),p.on("exit",(
|
|
667
|
+
`;try{r.write(o)}catch{}}}async attemptRuntimeRestart(e,t,r){let s=this.callbacks.log,o=this.processes.get(e.memberId),i=o?.ipcServer,a=o?.ipcPath,c=o?.stderrStream;this.processes.delete(e.memberId);try{let l={memberId:e.memberId,name:e.name,pid:-1,cwd:e.cwd,state:"starting",startedAt:Date.now()},u=e.external,d=[...u.acpArgs];a&&(t.QLOGICAGENT_PARENT_RPC=a);let p=Tc(u.cliPath,d,{cwd:e.cwd,env:t,stdio:["pipe","pipe","pipe"],detached:!1});l.pid=p.pid??-1;let m=new Map,h=new dn,f=new yr;this.processes.set(e.memberId,{handle:l,child:p,pendingRpc:m,acpAdapter:h,usageTracker:f,ipcServer:i,ipcPath:a,stderrStream:c,runtimeRestartCount:r}),h.attach(p,(T,w)=>{T==="usage_update"&&f.onUsageUpdate(w);let _=dn.translateNotification(T,w);_?(this.captureChildProgress(e.memberId,_.method,_.params),this.callbacks.onNotification?.(e.memberId,_.method,_.params)):(this.captureChildProgress(e.memberId,T,w),this.callbacks.onNotification?.(e.memberId,T,w))}),p.stderr&&Ls({input:p.stderr,crlfDelay:Number.POSITIVE_INFINITY}).on("line",w=>{this.callbacks.log?.debug?.(`[${new Date().toISOString()}] [debug] [agent:${e.memberId}] [stderr] ${w}`),c?.write(`${new Date().toISOString()} ${w}
|
|
668
|
+
`)}),p.on("exit",(T,w)=>{h.detach();let _=l.state;if(_!=="killed"&&_!=="completed"&&T!==0){let D=this.processes.get(e.memberId)?.runtimeRestartCount??r;if(D<_n){let L=ag*2**D;this.slog("warn",e.memberId,"crash",`crashed again (code=${T}), restart ${D+1}/${_n}`),this.callbacks.onNotification?.(e.memberId,"agents.error",{agentId:e.memberId,phase:"runtime",error:`Process crashed (code=${T}), restarting`,retriesLeft:_n-D-1}),setTimeout(()=>{this.attemptRuntimeRestart(e,t,D+1).catch(F=>{this.slog("warn",e.memberId,"restart",`failed: ${F instanceof Error?F.message:String(F)}`)})},L);return}}_!=="killed"&&(l.state=T===0?"completed":"failed"),l.endedAt=Date.now(),T!==0&&!l.error&&(l.error=`ACP process exited with code ${T} (signal: ${w})`),this.callbacks.onStateChange?.(e.memberId,l.state),this.callbacks.onExit?.(e.memberId,T,w)}),p.on("error",T=>{h.detach(),l.state="failed",l.error=T.message,l.endedAt=Date.now(),this.callbacks.onStateChange?.(e.memberId,"failed")}),this.callbacks.onStateChange?.(e.memberId,"starting");let y=await h.initialize(p);l.state="ready",l.supportsResume=y.agentCapabilities.loadSession===!0,this.callbacks.onStateChange?.(e.memberId,"ready"),this.slog("info",e.memberId,"restart",`ACP restarted (attempt=${r}, protocol=${y.protocolVersion}, loadSession=${l.supportsResume}, pid=${l.pid})`);let b=[...e.mcpServers??[]];a&&b.push({name:"qlogicagent-tools",command:process.execPath,args:[this.mcpBridgeScriptPath],env:{QLOGICAGENT_PARENT_RPC:a,QLOGICAGENT_SESSION_ID:e.memberId}});try{if(l.supportsResume&&l.sessionId){let T=await h.resumeSession(p,l.sessionId,{cwd:e.cwd,mcpServers:b.length>0?b:void 0});l.sessionId=T.sessionId,this.slog("info",e.memberId,"session",`session resumed (id=${l.sessionId})`)}else{let T={cwd:e.cwd};b.length>0&&(T.mcpServers=b),e.systemPrompt&&(T.systemPrompt=e.systemPrompt);let w=await h.createSession(p,T);l.sessionId=w.sessionId,this.slog("info",e.memberId,"session",`new session on restart (id=${l.sessionId})`)}}catch{this.slog("warn",e.memberId,"session","session re-creation failed on restart")}this.startHeartbeat(e.memberId,T=>{this.slog("warn",T,"heartbeat","hang detected \u2014 force-killing"),this.callbacks.onNotification?.(T,"agents.error",{agentId:T,phase:"heartbeat",error:`Agent ${e.name} stopped responding`,retriesLeft:0}),this.kill(T)})}catch(l){let u=this.processes.get(e.memberId);u&&(u.handle.state="failed",u.handle.error=`Runtime restart failed: ${l instanceof Error?l.message:String(l)}`,u.handle.endedAt=Date.now()),this.callbacks.onStateChange?.(e.memberId,"failed"),this.callbacks.onNotification?.(e.memberId,"agents.error",{agentId:e.memberId,phase:"runtime",error:`Restart failed after ${r} attempts: ${l instanceof Error?l.message:String(l)}`,retriesLeft:0})}}getMcpIpcPath(e){return this.processes.get(e)?.ipcPath}heartbeatTimers=new Map;missedBeats=new Map;static HEARTBEAT_INTERVAL=3e4;static MAX_MISSED_BEATS=3;startHeartbeat(e,t){this.stopHeartbeat(e),this.missedBeats.set(e,0);let r=setInterval(async()=>{let s=this.processes.get(e);if(!s||s.handle.state==="completed"||s.handle.state==="failed"||s.handle.state==="killed"){this.stopHeartbeat(e);return}if(await this.ping(e,1e4)){this.missedBeats.set(e,0);return}let i=(this.missedBeats.get(e)??0)+1;this.missedBeats.set(e,i),this.slog("warn",e,"heartbeat",`missed (${i}/${n.MAX_MISSED_BEATS})`),i>=n.MAX_MISSED_BEATS&&(this.slog("warn",e,"heartbeat","hang detected, force-killing"),this.stopHeartbeat(e),s.handle.error=`Hang detected: ${i} consecutive heartbeat failures`,this.kill(e),t?.(e))},n.HEARTBEAT_INTERVAL);this.heartbeatTimers.set(e,r)}stopHeartbeat(e){let t=this.heartbeatTimers.get(e);t&&(clearInterval(t),this.heartbeatTimers.delete(e)),this.missedBeats.delete(e)}getMissedBeats(e){return this.missedBeats.get(e)??0}activeCount(){return[...this.processes.values()].filter(e=>e.handle.state==="starting"||e.handle.state==="ready"||e.handle.state==="running").length}remove(e){let t=this.processes.get(e);t&&(this.stopHeartbeat(e),(t.handle.state==="running"||t.handle.state==="starting"||t.handle.state==="ready")&&this.kill(e),this.processes.delete(e))}dispose(){for(let e of this.heartbeatTimers.keys())this.stopHeartbeat(e);for(let e of this.processes.values()){try{e.ipcServer?.close()}catch{}try{e.stderrStream?.end()}catch{}}this.killAll(),this.processes.clear()}};ae();import{join as lg}from"node:path";import{chmod as Xx}from"node:fs/promises";import{readFile as Bx,writeFile as Hx,mkdir as qx,rename as Wx,unlink as Gx}from"node:fs/promises";import{dirname as Kx,join as Vx}from"node:path";import{randomUUID as zx}from"node:crypto";async function Cn(n,e){let t=Kx(n);await qx(t,{recursive:!0});let r=Vx(t,`.tmp-${zx()}`);try{await Hx(r,e,"utf-8");let s;for(let o=0;o<3;o++)try{await Wx(r,n);return}catch(i){if(s=i,i.code!=="EPERM")throw i;await new Promise(a=>setTimeout(a,50*(o+1)))}throw s}catch(s){throw await Gx(r).catch(()=>{}),s}}async function pn(n){try{let e=await Bx(n,"utf-8");return JSON.parse(e)}catch(e){if(e.code==="ENOENT")return;throw e}}async function En(n,e){await Cn(n,JSON.stringify(e,null,2)+`
|
|
669
669
|
`)}var dg="agent-configs.json";function cg(){return lg(q(),dg)}function Yx(n){return lg(Me(n),dg)}function Jx(){return{agents:{}}}var $s=class{data=Jx();cwd;constructor(e){this.cwd=e}async load(){let e=await pn(cg()),t=this.cwd?await pn(Yx(this.cwd)):void 0,r={gatewayUrl:e?.gatewayUrl,agents:{...e?.agents},customAgents:{...e?.customAgents}};if(t){t.gatewayUrl&&(r.gatewayUrl=t.gatewayUrl);for(let[s,o]of Object.entries(t.agents??{}))r.agents[s]={...r.agents[s],...o};for(let[s,o]of Object.entries(t.customAgents??{}))r.customAgents??={},r.customAgents[s]=o}this.data=r}getData(){return this.data}getAgentConfig(e){return this.data.agents[e]??null}async setAgentConfig(e,t){this.data.agents[e]={...this.data.agents[e],...t},await this.save()}async removeAgentConfig(e){delete this.data.agents[e],await this.save()}getGatewayUrl(){return this.data.gatewayUrl}async setGatewayUrl(e){this.data.gatewayUrl=e,await this.save()}registerCustomAgent(e){this.data.customAgents??={},this.data.customAgents[e.id]=e}unregisterCustomAgent(e){this.data.customAgents&&delete this.data.customAgents[e]}getCustomAgents(){return{...this.data.customAgents}}async save(){let e=cg();await En(e,this.data);try{await Xx(e,384)}catch{}}};var ug="memory",pg="Memory",Qx=["add","replace","remove","create_file","write_file","read_file","delete_file","list_files","search","remember","temporal","feedback"],mg={type:"object",properties:{action:{type:"string",enum:Qx,description:["Operation to perform:","","INDEX.md operations (project-level notes, always visible in system prompt):","\xB7 'add' \u2014 Append a note to INDEX.md","\xB7 'replace' \u2014 Replace text in INDEX.md (str_replace semantics)","\xB7 'remove' \u2014 Remove text from INDEX.md","","Topic file operations (project-level, on-demand, for longer content):","\xB7 'create_file' \u2014 Create a new .md topic file","\xB7 'write_file' \u2014 Overwrite an existing topic file","\xB7 'read_file' \u2014 Read a topic file","\xB7 'delete_file' \u2014 Delete a topic file","\xB7 'list_files' \u2014 List all memory topic files","","Long-term memory (user-level, persists across projects):","\xB7 'remember' \u2014 Store a fact/preference/lesson to long-term memory (semantic search)","\xB7 'search' \u2014 Search long-term memory + local keyword match","\xB7 'temporal' \u2014 Query memories by time range ('what happened last week')","","Feedback:","\xB7 'feedback' \u2014 Mark memories as useful/irrelevant/outdated/wrong"].join(`
|
|
670
670
|
`)},content:{type:"string",description:["Content for add/replace/create_file/write_file.","For INDEX.md notes: write concise, factual statements.","For topic files: can be longer (up to 8KB), use markdown formatting."].join(`
|
|
671
671
|
`)},old_text:{type:"string",description:"For 'replace'/'remove': the exact text to find in INDEX.md."},new_text:{type:"string",description:"For 'replace': the replacement text."},file:{type:"string",description:"Filename for file operations (e.g. 'project-notes.md', 'lesson-esbuild.md'). Must be kebab-case .md."},query:{type:"string",description:"For 'search'/'temporal': natural language query to find relevant memories."},days:{type:"number",description:"For 'temporal': look back N days from today (default: 7)."},memory_ids:{type:"array",items:{type:"string"},description:"For 'feedback': IDs of memories to give feedback on."},signal:{type:"string",enum:["useful","irrelevant","outdated","wrong"],description:"For 'feedback': the feedback signal to apply."},category:{type:"string",enum:["preference","personal_fact","lesson","pattern","decision","context"],description:"For 'remember': categorize the memory (helps with future recall precision)."}},required:["action"]},gg=["Manage persistent memory across sessions. Two distinct systems with clear roles:","","## Project memory (INDEX.md + topic files)","Scope: current project / workspace. Visible every turn.","Use for: architecture decisions, file conventions, build commands, known issues, task logs.","Actions: add, replace, remove, create_file, write_file, read_file, delete_file, list_files.","","## Long-term memory (QMemory)","Scope: user-level, persists across all projects. Searched on demand.","Use for: user preferences, personal facts, recurring lessons, communication style, past insights.","Actions: remember, search, temporal, feedback.","","## When to store (guidelines):","- User explicitly says 'remember this' or 'note that' \u2192 store immediately","- User states a preference (style, format, tools, habits) \u2192 remember (long-term)","- Project-specific decision or fact \u2192 add/create_file (project memory)","- A debugging lesson or insight that applies broadly \u2192 remember (long-term)","- DO NOT store: trivial/obvious info, one-off questions, transient state","- DO NOT store: information the user did not share or confirm","","## When to recall:","- Use 'search' when you suspect relevant past context exists for the current task","- Use 'temporal' to find what happened in a specific time period","- Memory is auto-recalled each turn \u2014 manual search is for deeper queries"].join(`
|
|
@@ -709,7 +709,7 @@ ${o}`,action:t}}if(t==="search"){let s=n.query?.trim();if(!s)return{ok:!1,messag
|
|
|
709
709
|
`)?t+e+`
|
|
710
710
|
`:t+`
|
|
711
711
|
`+e+`
|
|
712
|
-
`;Buffer.byteLength(r,"utf-8")<=Ie&&await this.writeIndex(r)}};function cP(n,e){let t=st(n,"..");yt(t)||bg(t,{recursive:!0}),sP(n,e,"utf-8")}function lP(n){return n.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function kg(){return{toolUseCount:0,latestInputTokens:0,cumulativeOutputTokens:0,recentActivities:[]}}function dP(n){return n.latestInputTokens+n.cumulativeOutputTokens}var uP=new Set(["grep","glob","search","Grep","Glob","list_dir","find_files"]),vg=new Set(["read_file","file_read","cat","head","tail","FileRead"]);function pP(n){return{isSearch:uP.has(n)||void 0,isRead:vg.has(n)||void 0}}function mP(n,e){let t=e.file_path??e.path??e.filePath;if(typeof t=="string")return`${vg.has(n)?"Reading":n.includes("write")||n.includes("edit")?"Editing":"Using"} ${t}`;let r=e.command??e.cmd;if(typeof r=="string")return`Running: ${r.length>60?r.slice(0,60)+"\u2026":r}`;let s=e.query??e.pattern??e.search;if(typeof s=="string")return`Searching: ${s}`}function Sg(n,e){n.latestInputTokens=(e.input_tokens??0)+(e.cache_creation_input_tokens??0)+(e.cache_read_input_tokens??0),n.cumulativeOutputTokens+=e.output_tokens??0}function Tg(n,e,t,r){n.toolUseCount++;let s=pP(e),o={toolName:e,input:t,activityDescription:r?.(e,t)??mP(e,t),isSearch:s.isSearch,isRead:s.isRead};for(n.recentActivities.push(o);n.recentActivities.length>5;)n.recentActivities.shift()}function Pc(n){return{toolUseCount:n.toolUseCount,tokenCount:dP(n),lastActivity:n.recentActivities.length>0?n.recentActivities[n.recentActivities.length-1]:void 0,recentActivities:[...n.recentActivities]}}import{randomUUID as Rg}from"node:crypto";function gP(n){let e=new AbortController;return n&&(n.aborted?e.abort(n.reason):n.addEventListener("abort",()=>{e.abort(n.reason)},{once:!0})),e}async function Ic(n){let e=Date.now(),t=[],r={inputTokens:0,outputTokens:0},s=kg(),{promptMessages:o,systemPrompt:i,tools:a,canUseTool:c,transport:l,toolInvoker:u,apiKey:d,model:p,log:m,hooks:h,forkLabel:f,maxTurns:y,temperature:b,parentSignal:S,onEvent:w,onProgress:_,budgetTokens:I,parentDepth:D}=n,L=gP(S),F=`fork-${f}-${Rg().slice(0,8)}`,T=`fork-session-${Rg().slice(0,8)}`;m.info(`[fork:${f}] starting \u2014 ${o.length} initial messages, model=${p}`);let ce=c?{invoke:async(oe,$e,te,Y)=>{let R={};try{R=JSON.parse(te)}catch{}let B=c($e,R);return B.allowed?u.invoke(oe,$e,te,Y):(m.info(`[fork:${f}] tool ${$e} denied: ${B.reason}`),{result:"",error:B.reason})}}:u,le=!0,j;try{let{Agent:oe}=await Promise.resolve().then(()=>(ea(),Fd)),$e=new oe({llmTransport:l,apiKey:d,toolInvoker:ce,log:m,hooks:h,maxRounds:y});for await(let te of $e.run({turnId:F,sessionId:T,messages:o,tools:a,systemPrompt:i,config:{model:p,apiKey:d,temperature:b,maxOutputTokens:n.maxOutputTokens,parentDepth:D}},L.signal)){if(t.push(te),w?.(te),te.type==="end"&&te.usage&&(Sg(s,{input_tokens:te.usage.inputTokens,output_tokens:te.usage.outputTokens}),r.inputTokens+=te.usage.inputTokens,r.outputTokens+=te.usage.outputTokens,te.usage.cacheRead&&(r.cacheRead=(r.cacheRead??0)+te.usage.cacheRead),te.usage.cacheWrite&&(r.cacheWrite=(r.cacheWrite??0)+te.usage.cacheWrite),I&&I>0)){let Y=r.inputTokens+r.outputTokens+(r.reasoningTokens??0);Y>=I&&(m.info(`[fork:${f}] budget exceeded (${Y} / ${I} tokens), aborting`),L.abort("budget_exceeded"))}if(te.type==="tool_call"){let Y={};try{Y=JSON.parse(te.arguments??"{}")}catch{}Tg(s,te.name,Y),_?.(Pc(s))}te.type==="error"&&(le=!1,j=te.error)}}catch(oe){le=!1,j=oe instanceof Error?oe.message:String(oe),m.warn(`[fork:${f}] error: ${j}`)}finally{L.signal.aborted||L.abort("fork_complete")}let ke=Date.now()-e;return m.info(`[fork:${f}] finished in ${ke}ms \u2014 ${t.length} events, usage: prompt=${r.inputTokens} completion=${r.outputTokens}, ok=${le}`),{events:t,totalUsage:r,progress:Pc(s),durationMs:ke,ok:le,error:j}}ji();Li();je();var _c=class{teamBudget={tokensUsed:0,budgetTokens:ai};isTeamBudgetExceeded(){return this.teamBudget.budgetTokens>0&&this.teamBudget.tokensUsed>=this.teamBudget.budgetTokens}recordForkTokens(e){return this.teamBudget.tokensUsed+=e,this.teamBudget.tokensUsed}teamBudgetExceededError(){return`Team budget exceeded (${this.teamBudget.tokensUsed} / ${this.teamBudget.budgetTokens} tokens). No more sub-agents allowed.`}dream={idleMinutes:30,enabled:!1,lastDreamAt:0,cooldownMs:14400*1e3,maxDurationMs:300*1e3};resetAccumulators(){this.teamBudget.tokensUsed=0}},Re=new _c;ae();import{readFile as fP}from"node:fs/promises";import{watch as hP}from"node:fs";import{join as yP}from"node:path";var bP=qe,kP="settings.json";function vP(n){return yP(n,bP,kP)}async function SP(n){try{let e=await fP(n,"utf-8");return JSON.parse(e)}catch{return null}}function TP(n,e,t,r){let s=!1;n.permissionMode&&n.permissionMode!==e.getMode()&&(e.setMode(n.permissionMode),r?.(`settings: permission mode \u2192 ${n.permissionMode}`),s=!0),n.permissionRules&&(e.replaceRules(n.permissionRules),r?.(`settings: ${n.permissionRules.length} permission rules loaded`),s=!0),n.defaultBehavior&&(e.setDefaultBehavior(n.defaultBehavior),r?.(`settings: default behavior \u2192 ${n.defaultBehavior}`),s=!0),s&&t&&t.invoke("config.changed",{sessionId:"",key:"permissions",oldValue:void 0,newValue:n}).catch(()=>{})}function wg(n){let e=vP(n.projectRoot),t=null,r=null,s=async()=>{let o=await SP(e);o&&TP(o,n.ruleEngine,n.hooks,n.log)};s().catch(()=>{});try{t=hP(e,{persistent:!1},o=>{r&&clearTimeout(r),r=setTimeout(()=>{s().catch(()=>{})},200)}),t.on("error",()=>{})}catch{}return()=>{r&&clearTimeout(r),t?.close(),t=null}}var Cc=new Set;function mn(n){return Cc.add(n),()=>{Cc.delete(n)}}async function Ag(){await Promise.all(Array.from(Cc).map(n=>n()))}ae();dt();var Bs="\u65E0\u6CD5\u8FDE\u63A5 llmrouter \u6A21\u578B\u76EE\u5F55",Mn=class extends Error{constructor(e=Bs){super(e),this.name="LlmrouterCatalogUnavailableError"}};function RP(){let n=process.env.QLOGIC_LLMROUTER_BASE_URL?.trim().replace(/\/+$/,"");if(!n)throw new Mn;return n}function wP(){let n={accept:"application/json"},e=process.env.QLOGIC_LLMROUTER_ACCESS_TOKEN?.trim();return e&&(n.authorization=`Bearer ${e}`),n}async function xg(n){let e=RP(),t;try{t=await fetch(`${e}${n}`,{method:"GET",headers:wP(),signal:AbortSignal.timeout(1e4)})}catch{throw new Mn}if(!t.ok)throw new Mn;let r=await t.json().catch(()=>null),s=Array.isArray(r)?r:_P(r)&&Array.isArray(r.data)?r.data:null;if(!s)throw new Mn;return s}async function Hs(){return xg("/ext/model-catalog/providers")}async function AP(){return xg("/ext/model-catalog/models")}function Ec(n){let e={zhipu:"Zhipu GLM","zhipu-openai":"Zhipu GLM OpenAI","zhipu-coding":"Zhipu GLM Coding",volcengine:"Doubao / Volcengine"};return e[n.id]?e[n.id]:n.displayName??n.name??n.id}function qs(n){return n.baseUrl??n.base_url}async function Mc(n){return(await Hs()).find(t=>t.id===n)??null}async function Rr(n){let e=await AP();n.migrateModelIds(xP(e));let t=e.map(PP).filter(r=>!!r);return n.replaceCatalogModels(t),t}function xP(n){let e=new Map;for(let t of n){let r=t.provider??t.owned_by,s=t.public_model??t.publicModel??t.id,o=t.native_model_id??t.nativeModelId??t.id;if(!r||!s||!o)continue;let i=`${r}:${s}`;for(let a of[o,t.id])!a||a===s||e.set(`${r}:${a}`,i)}return e}function PP(n){let e=n.provider??n.owned_by,t=n.public_model??n.publicModel??n.id,r=n.native_model_id??n.nativeModelId??n.id;return!e||!t||!r?null:{id:`${e}:${t}`,provider:e,model:t,displayName:n.display_name??n.displayName??n.name??n.id,purposes:IP(n.purposes,n.category),baseUrl:n.baseUrl??n.base_url,enabled:!0,nativeModelId:r,transport:n.provider_transport??n.providerTransport,contextWindow:n.context_window??n.contextWindow,maxOutput:n.max_output??n.maxOutput,streamRequired:n.stream_required??n.streamRequired,capabilities:n.capabilities,pricing:n.pricing}}function IP(n,e){let t=[...n??[],e].filter(o=>!!o),r=new Set(["textGeneration","smallModel","stt","tts","imageGeneration","imageUnderstanding","videoGeneration","videoUnderstanding","threeDGeneration","embedding","voiceClone","musicGeneration","realtimeAudio","realtimeVideo"]),s=t.filter(o=>r.has(o));return[...new Set(s.length?s:["textGeneration"])]}function _P(n){return!!n&&typeof n=="object"&&!Array.isArray(n)}je();import{join as Dc}from"node:path";import{mkdirSync as CP,existsSync as EP,createWriteStream as MP}from"node:fs";import{pipeline as DP}from"node:stream/promises";import{Readable as NP}from"node:stream";var OP=gi,LP=fi,Pg={"image/png":".png","image/jpeg":".jpg","image/gif":".gif","image/webp":".webp","image/svg+xml":".svg","image/avif":".avif","video/mp4":".mp4","video/webm":".webm","video/quicktime":".mov","audio/mpeg":".mp3","audio/wav":".wav","audio/ogg":".ogg","audio/aac":".aac","audio/mp4":".m4a","audio/flac":".flac","application/pdf":".pdf","model/gltf-binary":".glb","model/gltf+json":".gltf"},Ws=class{projectDir;maxFileSize;timeoutMs;constructor(e){this.projectDir=e?.projectDir??null,this.maxFileSize=e?.maxFileSize??OP,this.timeoutMs=e?.timeoutMs??LP}setProjectDir(e){this.projectDir=e}resolveMediaDir(e){if(!this.projectDir)throw new Error("MediaPersistence requires projectDir \u2014 call setProjectDir() first");if(!e)return Dc(this.projectDir,".qlogicagent","media",$P());let t=e.replace(/[^a-zA-Z0-9_-]/g,"_");return t!==e&&t.length>0&&[...e].filter(s=>!/[a-zA-Z0-9_-]/.test(s)).length>e.length/2&&console.warn(`[media-persistence] sessionId heavily sanitized: "${e}" \u2192 "${t}" \u2014 potential collision risk`),Dc(this.projectDir,".qlogicagent","sessions",t,"media")}async download(e,t){let r=this.resolveMediaDir(t?.sessionId);if(r.length+60>255)throw new Error(`Media path too long (${r.length} chars) \u2014 would exceed OS limit. Use a shorter project path or session ID.`);EP(r)||CP(r,{recursive:!0});let s=new AbortController,o=setTimeout(()=>s.abort(),this.timeoutMs),i="";try{let a=await fetch(e,{signal:s.signal});if(!a.ok)throw new Error(`Download failed: ${a.status} ${a.statusText}`);let c=parseInt(a.headers.get("content-length")??"0",10);if(c>this.maxFileSize)throw new Error(`File too large: ${c} bytes (max: ${this.maxFileSize})`);let l=a.headers.get("content-type")?.split(";")[0].trim()||"application/octet-stream",u=UP(e,l),d=jP(t?.type??FP(l),u);i=Dc(r,d);let p=a.body;if(!p)throw new Error("No response body");let m=MP(i);await DP(NP.fromWeb(p),m);let{size:h}=await import("node:fs/promises").then(f=>f.stat(i));if(h===0)throw await import("node:fs/promises").then(f=>f.unlink(i).catch(()=>{})),new Error("Download produced empty file (connection dropped)");return{remoteUrl:e,localPath:i,bytes:h,mimeType:l}}catch(a){if(i)try{let{unlink:c}=await import("node:fs/promises");await c(i)}catch{}throw a}finally{clearTimeout(o)}}async downloadAll(e,t,r){let s=[];for(let o of e)try{let i=await this.download(o,t);s.push(i)}catch(i){r?.warn(`media-persistence: failed to download ${o}: ${i.message}`)}return s}getMediaDir(e){return this.resolveMediaDir(e)}getProjectDir(){return this.projectDir}};function $P(){let n=new Date;return`${n.getFullYear()}${String(n.getMonth()+1).padStart(2,"0")}${String(n.getDate()).padStart(2,"0")}`}function jP(n,e){let t=new Date,r=`${t.getFullYear()}${String(t.getMonth()+1).padStart(2,"0")}${String(t.getDate()).padStart(2,"0")}_${String(t.getHours()).padStart(2,"0")}${String(t.getMinutes()).padStart(2,"0")}${String(t.getSeconds()).padStart(2,"0")}`,s=Math.random().toString(36).slice(2,6);return`${n}_${r}_${s}${e}`}function UP(n,e){if(Pg[e])return Pg[e];try{let t=new URL(n).pathname,r=t.lastIndexOf(".");if(r>0){let s=t.slice(r).toLowerCase().split("?")[0];if(s.length<=5)return s}}catch{}return".bin"}function FP(n){return n.startsWith("image/")?"image":n.startsWith("video/")?"video":n.startsWith("audio/")?"audio":n.startsWith("model/")?"3d":"file"}import{join as BP}from"node:path";import{readFileSync as HP,writeFileSync as qP,mkdirSync as WP}from"node:fs";var gn=null,Nc=!1;function Ig(n){return BP(n,"skill-stats.json")}function Oc(n){if(gn)return gn;try{gn=JSON.parse(HP(Ig(n),"utf8"))}catch{gn={}}return gn}function GP(n){if(!(!Nc||!gn))try{WP(n,{recursive:!0}),qP(Ig(n),JSON.stringify(gn,null,2),"utf8"),Nc=!1}catch{}}function Gs(n,e,t){let r=Oc(n);r[e]||(r[e]={invokeCount:0,activeCount:0,positiveCount:0,negativeCount:0}),r[e].invokeCount++,r[e].lastUsedAt=new Date().toISOString(),t?r[e].positiveCount++:r[e].negativeCount++,r[e].invokeCount>0&&(r[e].successRate=(r[e].invokeCount-r[e].negativeCount)/r[e].invokeCount),Nc=!0,GP(n)}function _g(n,e){return Oc(n)[e]}function Cg(n){return Oc(n)}import{existsSync as KP,readFileSync as VP,writeFileSync as zP,mkdirSync as Mg,renameSync as XP}from"node:fs";import{join as Lc,dirname as Dg}from"node:path";var Eg=30,YP=90,JP="skill-lifecycle.json";function Ng(n){return Lc(n,JP)}function Be(n){let e=Ng(n);try{return JSON.parse(VP(e,"utf8"))}catch{return{version:1,records:{}}}}function We(n,e){let t=Ng(n);Mg(Dg(t),{recursive:!0});let r=t+".tmp";zP(r,JSON.stringify(e,null,2),"utf8");let{renameSync:s}=xo("node:fs");s(r,t)}function Bt(n,e,t="learned"){return n.records[e]||(n.records[e]={name:e,state:"active",createdAt:new Date().toISOString(),pinned:!1,useCount:0,source:t}),n.records[e]}function $c(n,e){let t=Bt(n,e);t.lastUsedAt=new Date().toISOString(),t.useCount++,t.state==="stale"&&(t.state="active",t.staleAt=void 0)}function jc(n,e){let t=Bt(n,e);t.lastPatchedAt=new Date().toISOString(),t.state==="stale"&&(t.state="active",t.staleAt=void 0)}function Og(n,e){let t=n.records[e];return t?(t.pinned=!0,!0):!1}function Lg(n,e){let t=n.records[e];return t?(t.pinned=!1,!0):!1}function QP(n){let e=[n.lastUsedAt,n.lastViewedAt,n.lastPatchedAt,n.createdAt].filter(Boolean).map(t=>new Date(t));return new Date(Math.max(...e.map(t=>t.getTime())))}function ZP(n){let e=Date.now(),t={transitioned:[],skippedPinned:[]};for(let[r,s]of Object.entries(n.records)){if(s.source==="installed")continue;if(s.pinned){s.state!=="active"&&t.skippedPinned.push(r);continue}let o=QP(s),i=(e-o.getTime())/(1e3*60*60*24);s.state==="active"&&i>=Eg?(s.state="stale",s.staleAt=new Date().toISOString(),t.transitioned.push({name:r,from:"active",to:"stale"})):s.state==="stale"&&i>=YP?(s.state="archived",s.archivedAt=new Date().toISOString(),t.transitioned.push({name:r,from:"stale",to:"archived"})):s.state==="stale"&&i<Eg&&(s.state="active",s.staleAt=void 0,t.transitioned.push({name:r,from:"stale",to:"active"}))}return t}function eI(n,e){let t=Lc(n,e);if(!KP(t))return!1;let r=Lc(n,".archive",e);Mg(Dg(r),{recursive:!0});try{return XP(t,r),!0}catch{return!1}}function $g(n,e){let t=Be(n),r=ZP(t);for(let s of r.transitioned)s.to==="archived"&&eI(e,s.name);return We(n,t),r}function jg(n,e){return Object.values(n.records).filter(t=>t.state===e)}function Ks(n,e){delete n.records[e]}function tI(n){let e=n.replace(/\r\n/g,`
|
|
712
|
+
`;Buffer.byteLength(r,"utf-8")<=Ie&&await this.writeIndex(r)}};function cP(n,e){let t=st(n,"..");yt(t)||bg(t,{recursive:!0}),sP(n,e,"utf-8")}function lP(n){return n.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function kg(){return{toolUseCount:0,latestInputTokens:0,cumulativeOutputTokens:0,recentActivities:[]}}function dP(n){return n.latestInputTokens+n.cumulativeOutputTokens}var uP=new Set(["grep","glob","search","Grep","Glob","list_dir","find_files"]),vg=new Set(["read_file","file_read","cat","head","tail","FileRead"]);function pP(n){return{isSearch:uP.has(n)||void 0,isRead:vg.has(n)||void 0}}function mP(n,e){let t=e.file_path??e.path??e.filePath;if(typeof t=="string")return`${vg.has(n)?"Reading":n.includes("write")||n.includes("edit")?"Editing":"Using"} ${t}`;let r=e.command??e.cmd;if(typeof r=="string")return`Running: ${r.length>60?r.slice(0,60)+"\u2026":r}`;let s=e.query??e.pattern??e.search;if(typeof s=="string")return`Searching: ${s}`}function Sg(n,e){n.latestInputTokens=(e.input_tokens??0)+(e.cache_creation_input_tokens??0)+(e.cache_read_input_tokens??0),n.cumulativeOutputTokens+=e.output_tokens??0}function Tg(n,e,t,r){n.toolUseCount++;let s=pP(e),o={toolName:e,input:t,activityDescription:r?.(e,t)??mP(e,t),isSearch:s.isSearch,isRead:s.isRead};for(n.recentActivities.push(o);n.recentActivities.length>5;)n.recentActivities.shift()}function Pc(n){return{toolUseCount:n.toolUseCount,tokenCount:dP(n),lastActivity:n.recentActivities.length>0?n.recentActivities[n.recentActivities.length-1]:void 0,recentActivities:[...n.recentActivities]}}import{randomUUID as Rg}from"node:crypto";function gP(n){let e=new AbortController;return n&&(n.aborted?e.abort(n.reason):n.addEventListener("abort",()=>{e.abort(n.reason)},{once:!0})),e}async function Ic(n){let e=Date.now(),t=[],r={inputTokens:0,outputTokens:0},s=kg(),{promptMessages:o,systemPrompt:i,tools:a,canUseTool:c,transport:l,toolInvoker:u,apiKey:d,model:p,log:m,hooks:h,forkLabel:f,maxTurns:y,temperature:b,parentSignal:T,onEvent:w,onProgress:_,budgetTokens:I,parentDepth:D}=n,L=gP(T),F=`fork-${f}-${Rg().slice(0,8)}`,S=`fork-session-${Rg().slice(0,8)}`;m.info(`[fork:${f}] starting \u2014 ${o.length} initial messages, model=${p}`);let ce=c?{invoke:async(oe,$e,te,Y)=>{let R={};try{R=JSON.parse(te)}catch{}let B=c($e,R);return B.allowed?u.invoke(oe,$e,te,Y):(m.info(`[fork:${f}] tool ${$e} denied: ${B.reason}`),{result:"",error:B.reason})}}:u,le=!0,j;try{let{Agent:oe}=await Promise.resolve().then(()=>(ea(),Fd)),$e=new oe({llmTransport:l,apiKey:d,toolInvoker:ce,log:m,hooks:h,maxRounds:y});for await(let te of $e.run({turnId:F,sessionId:S,messages:o,tools:a,systemPrompt:i,config:{model:p,apiKey:d,temperature:b,maxOutputTokens:n.maxOutputTokens,parentDepth:D}},L.signal)){if(t.push(te),w?.(te),te.type==="end"&&te.usage&&(Sg(s,{input_tokens:te.usage.inputTokens,output_tokens:te.usage.outputTokens}),r.inputTokens+=te.usage.inputTokens,r.outputTokens+=te.usage.outputTokens,te.usage.cacheRead&&(r.cacheRead=(r.cacheRead??0)+te.usage.cacheRead),te.usage.cacheWrite&&(r.cacheWrite=(r.cacheWrite??0)+te.usage.cacheWrite),I&&I>0)){let Y=r.inputTokens+r.outputTokens+(r.reasoningTokens??0);Y>=I&&(m.info(`[fork:${f}] budget exceeded (${Y} / ${I} tokens), aborting`),L.abort("budget_exceeded"))}if(te.type==="tool_call"){let Y={};try{Y=JSON.parse(te.arguments??"{}")}catch{}Tg(s,te.name,Y),_?.(Pc(s))}te.type==="error"&&(le=!1,j=te.error)}}catch(oe){le=!1,j=oe instanceof Error?oe.message:String(oe),m.warn(`[fork:${f}] error: ${j}`)}finally{L.signal.aborted||L.abort("fork_complete")}let ke=Date.now()-e;return m.info(`[fork:${f}] finished in ${ke}ms \u2014 ${t.length} events, usage: prompt=${r.inputTokens} completion=${r.outputTokens}, ok=${le}`),{events:t,totalUsage:r,progress:Pc(s),durationMs:ke,ok:le,error:j}}ji();Li();je();var _c=class{teamBudget={tokensUsed:0,budgetTokens:ai};isTeamBudgetExceeded(){return this.teamBudget.budgetTokens>0&&this.teamBudget.tokensUsed>=this.teamBudget.budgetTokens}recordForkTokens(e){return this.teamBudget.tokensUsed+=e,this.teamBudget.tokensUsed}teamBudgetExceededError(){return`Team budget exceeded (${this.teamBudget.tokensUsed} / ${this.teamBudget.budgetTokens} tokens). No more sub-agents allowed.`}dream={idleMinutes:30,enabled:!1,lastDreamAt:0,cooldownMs:14400*1e3,maxDurationMs:300*1e3};resetAccumulators(){this.teamBudget.tokensUsed=0}},Re=new _c;ae();import{readFile as fP}from"node:fs/promises";import{watch as hP}from"node:fs";import{join as yP}from"node:path";var bP=qe,kP="settings.json";function vP(n){return yP(n,bP,kP)}async function SP(n){try{let e=await fP(n,"utf-8");return JSON.parse(e)}catch{return null}}function TP(n,e,t,r){let s=!1;n.permissionMode&&n.permissionMode!==e.getMode()&&(e.setMode(n.permissionMode),r?.(`settings: permission mode \u2192 ${n.permissionMode}`),s=!0),n.permissionRules&&(e.replaceRules(n.permissionRules),r?.(`settings: ${n.permissionRules.length} permission rules loaded`),s=!0),n.defaultBehavior&&(e.setDefaultBehavior(n.defaultBehavior),r?.(`settings: default behavior \u2192 ${n.defaultBehavior}`),s=!0),s&&t&&t.invoke("config.changed",{sessionId:"",key:"permissions",oldValue:void 0,newValue:n}).catch(()=>{})}function wg(n){let e=vP(n.projectRoot),t=null,r=null,s=async()=>{let o=await SP(e);o&&TP(o,n.ruleEngine,n.hooks,n.log)};s().catch(()=>{});try{t=hP(e,{persistent:!1},o=>{r&&clearTimeout(r),r=setTimeout(()=>{s().catch(()=>{})},200)}),t.on("error",()=>{})}catch{}return()=>{r&&clearTimeout(r),t?.close(),t=null}}var Cc=new Set;function mn(n){return Cc.add(n),()=>{Cc.delete(n)}}async function Ag(){await Promise.all(Array.from(Cc).map(n=>n()))}ae();dt();var Bs="\u65E0\u6CD5\u8FDE\u63A5 llmrouter \u6A21\u578B\u76EE\u5F55",Mn=class extends Error{constructor(e=Bs){super(e),this.name="LlmrouterCatalogUnavailableError"}};function RP(){let n=process.env.QLOGIC_LLMROUTER_BASE_URL?.trim().replace(/\/+$/,"");if(!n)throw new Mn;return n}function wP(){let n={accept:"application/json"},e=process.env.QLOGIC_LLMROUTER_ACCESS_TOKEN?.trim();return e&&(n.authorization=`Bearer ${e}`),n}async function xg(n){let e=RP(),t;try{t=await fetch(`${e}${n}`,{method:"GET",headers:wP(),signal:AbortSignal.timeout(1e4)})}catch{throw new Mn}if(!t.ok)throw new Mn;let r=await t.json().catch(()=>null),s=Array.isArray(r)?r:_P(r)&&Array.isArray(r.data)?r.data:null;if(!s)throw new Mn;return s}async function Hs(){return xg("/ext/model-catalog/providers")}async function AP(){return xg("/ext/model-catalog/models")}function Ec(n){let e={zhipu:"Zhipu GLM","zhipu-openai":"Zhipu GLM OpenAI","zhipu-coding":"Zhipu GLM Coding",volcengine:"Doubao / Volcengine"};return e[n.id]?e[n.id]:n.displayName??n.name??n.id}function qs(n){return n.baseUrl??n.base_url}async function Mc(n){return(await Hs()).find(t=>t.id===n)??null}async function Rr(n){let e=await AP();n.migrateModelIds(xP(e));let t=e.map(PP).filter(r=>!!r);return n.replaceCatalogModels(t),t}function xP(n){let e=new Map;for(let t of n){let r=t.provider??t.owned_by,s=t.public_model??t.publicModel??t.id,o=t.native_model_id??t.nativeModelId??t.id;if(!r||!s||!o)continue;let i=`${r}:${s}`;for(let a of[o,t.id])!a||a===s||e.set(`${r}:${a}`,i)}return e}function PP(n){let e=n.provider??n.owned_by,t=n.public_model??n.publicModel??n.id,r=n.native_model_id??n.nativeModelId??n.id;return!e||!t||!r?null:{id:`${e}:${t}`,provider:e,model:t,displayName:n.display_name??n.displayName??n.name??n.id,purposes:IP(n.purposes,n.category),baseUrl:n.baseUrl??n.base_url,enabled:!0,nativeModelId:r,transport:n.provider_transport??n.providerTransport,contextWindow:n.context_window??n.contextWindow,maxOutput:n.max_output??n.maxOutput,streamRequired:n.stream_required??n.streamRequired,capabilities:n.capabilities,pricing:n.pricing}}function IP(n,e){let t=[...n??[],e].filter(o=>!!o),r=new Set(["textGeneration","smallModel","stt","tts","imageGeneration","imageUnderstanding","videoGeneration","videoUnderstanding","threeDGeneration","embedding","voiceClone","musicGeneration","realtimeAudio","realtimeVideo"]),s=t.filter(o=>r.has(o));return[...new Set(s.length?s:["textGeneration"])]}function _P(n){return!!n&&typeof n=="object"&&!Array.isArray(n)}je();import{join as Dc}from"node:path";import{mkdirSync as CP,existsSync as EP,createWriteStream as MP}from"node:fs";import{pipeline as DP}from"node:stream/promises";import{Readable as NP}from"node:stream";var OP=gi,LP=fi,Pg={"image/png":".png","image/jpeg":".jpg","image/gif":".gif","image/webp":".webp","image/svg+xml":".svg","image/avif":".avif","video/mp4":".mp4","video/webm":".webm","video/quicktime":".mov","audio/mpeg":".mp3","audio/wav":".wav","audio/ogg":".ogg","audio/aac":".aac","audio/mp4":".m4a","audio/flac":".flac","application/pdf":".pdf","model/gltf-binary":".glb","model/gltf+json":".gltf"},Ws=class{projectDir;maxFileSize;timeoutMs;constructor(e){this.projectDir=e?.projectDir??null,this.maxFileSize=e?.maxFileSize??OP,this.timeoutMs=e?.timeoutMs??LP}setProjectDir(e){this.projectDir=e}resolveMediaDir(e){if(!this.projectDir)throw new Error("MediaPersistence requires projectDir \u2014 call setProjectDir() first");if(!e)return Dc(this.projectDir,".qlogicagent","media",$P());let t=e.replace(/[^a-zA-Z0-9_-]/g,"_");return t!==e&&t.length>0&&[...e].filter(s=>!/[a-zA-Z0-9_-]/.test(s)).length>e.length/2&&console.warn(`[media-persistence] sessionId heavily sanitized: "${e}" \u2192 "${t}" \u2014 potential collision risk`),Dc(this.projectDir,".qlogicagent","sessions",t,"media")}async download(e,t){let r=this.resolveMediaDir(t?.sessionId);if(r.length+60>255)throw new Error(`Media path too long (${r.length} chars) \u2014 would exceed OS limit. Use a shorter project path or session ID.`);EP(r)||CP(r,{recursive:!0});let s=new AbortController,o=setTimeout(()=>s.abort(),this.timeoutMs),i="";try{let a=await fetch(e,{signal:s.signal});if(!a.ok)throw new Error(`Download failed: ${a.status} ${a.statusText}`);let c=parseInt(a.headers.get("content-length")??"0",10);if(c>this.maxFileSize)throw new Error(`File too large: ${c} bytes (max: ${this.maxFileSize})`);let l=a.headers.get("content-type")?.split(";")[0].trim()||"application/octet-stream",u=UP(e,l),d=jP(t?.type??FP(l),u);i=Dc(r,d);let p=a.body;if(!p)throw new Error("No response body");let m=MP(i);await DP(NP.fromWeb(p),m);let{size:h}=await import("node:fs/promises").then(f=>f.stat(i));if(h===0)throw await import("node:fs/promises").then(f=>f.unlink(i).catch(()=>{})),new Error("Download produced empty file (connection dropped)");return{remoteUrl:e,localPath:i,bytes:h,mimeType:l}}catch(a){if(i)try{let{unlink:c}=await import("node:fs/promises");await c(i)}catch{}throw a}finally{clearTimeout(o)}}async downloadAll(e,t,r){let s=[];for(let o of e)try{let i=await this.download(o,t);s.push(i)}catch(i){r?.warn(`media-persistence: failed to download ${o}: ${i.message}`)}return s}getMediaDir(e){return this.resolveMediaDir(e)}getProjectDir(){return this.projectDir}};function $P(){let n=new Date;return`${n.getFullYear()}${String(n.getMonth()+1).padStart(2,"0")}${String(n.getDate()).padStart(2,"0")}`}function jP(n,e){let t=new Date,r=`${t.getFullYear()}${String(t.getMonth()+1).padStart(2,"0")}${String(t.getDate()).padStart(2,"0")}_${String(t.getHours()).padStart(2,"0")}${String(t.getMinutes()).padStart(2,"0")}${String(t.getSeconds()).padStart(2,"0")}`,s=Math.random().toString(36).slice(2,6);return`${n}_${r}_${s}${e}`}function UP(n,e){if(Pg[e])return Pg[e];try{let t=new URL(n).pathname,r=t.lastIndexOf(".");if(r>0){let s=t.slice(r).toLowerCase().split("?")[0];if(s.length<=5)return s}}catch{}return".bin"}function FP(n){return n.startsWith("image/")?"image":n.startsWith("video/")?"video":n.startsWith("audio/")?"audio":n.startsWith("model/")?"3d":"file"}import{join as BP}from"node:path";import{readFileSync as HP,writeFileSync as qP,mkdirSync as WP}from"node:fs";var gn=null,Nc=!1;function Ig(n){return BP(n,"skill-stats.json")}function Oc(n){if(gn)return gn;try{gn=JSON.parse(HP(Ig(n),"utf8"))}catch{gn={}}return gn}function GP(n){if(!(!Nc||!gn))try{WP(n,{recursive:!0}),qP(Ig(n),JSON.stringify(gn,null,2),"utf8"),Nc=!1}catch{}}function Gs(n,e,t){let r=Oc(n);r[e]||(r[e]={invokeCount:0,activeCount:0,positiveCount:0,negativeCount:0}),r[e].invokeCount++,r[e].lastUsedAt=new Date().toISOString(),t?r[e].positiveCount++:r[e].negativeCount++,r[e].invokeCount>0&&(r[e].successRate=(r[e].invokeCount-r[e].negativeCount)/r[e].invokeCount),Nc=!0,GP(n)}function _g(n,e){return Oc(n)[e]}function Cg(n){return Oc(n)}import{existsSync as KP,readFileSync as VP,writeFileSync as zP,mkdirSync as Mg,renameSync as XP}from"node:fs";import{join as Lc,dirname as Dg}from"node:path";var Eg=30,YP=90,JP="skill-lifecycle.json";function Ng(n){return Lc(n,JP)}function Be(n){let e=Ng(n);try{return JSON.parse(VP(e,"utf8"))}catch{return{version:1,records:{}}}}function We(n,e){let t=Ng(n);Mg(Dg(t),{recursive:!0});let r=t+".tmp";zP(r,JSON.stringify(e,null,2),"utf8");let{renameSync:s}=xo("node:fs");s(r,t)}function Bt(n,e,t="learned"){return n.records[e]||(n.records[e]={name:e,state:"active",createdAt:new Date().toISOString(),pinned:!1,useCount:0,source:t}),n.records[e]}function $c(n,e){let t=Bt(n,e);t.lastUsedAt=new Date().toISOString(),t.useCount++,t.state==="stale"&&(t.state="active",t.staleAt=void 0)}function jc(n,e){let t=Bt(n,e);t.lastPatchedAt=new Date().toISOString(),t.state==="stale"&&(t.state="active",t.staleAt=void 0)}function Og(n,e){let t=n.records[e];return t?(t.pinned=!0,!0):!1}function Lg(n,e){let t=n.records[e];return t?(t.pinned=!1,!0):!1}function QP(n){let e=[n.lastUsedAt,n.lastViewedAt,n.lastPatchedAt,n.createdAt].filter(Boolean).map(t=>new Date(t));return new Date(Math.max(...e.map(t=>t.getTime())))}function ZP(n){let e=Date.now(),t={transitioned:[],skippedPinned:[]};for(let[r,s]of Object.entries(n.records)){if(s.source==="installed")continue;if(s.pinned){s.state!=="active"&&t.skippedPinned.push(r);continue}let o=QP(s),i=(e-o.getTime())/(1e3*60*60*24);s.state==="active"&&i>=Eg?(s.state="stale",s.staleAt=new Date().toISOString(),t.transitioned.push({name:r,from:"active",to:"stale"})):s.state==="stale"&&i>=YP?(s.state="archived",s.archivedAt=new Date().toISOString(),t.transitioned.push({name:r,from:"stale",to:"archived"})):s.state==="stale"&&i<Eg&&(s.state="active",s.staleAt=void 0,t.transitioned.push({name:r,from:"stale",to:"active"}))}return t}function eI(n,e){let t=Lc(n,e);if(!KP(t))return!1;let r=Lc(n,".archive",e);Mg(Dg(r),{recursive:!0});try{return XP(t,r),!0}catch{return!1}}function $g(n,e){let t=Be(n),r=ZP(t);for(let s of r.transitioned)s.to==="archived"&&eI(e,s.name);return We(n,t),r}function jg(n,e){return Object.values(n.records).filter(t=>t.state===e)}function Ks(n,e){delete n.records[e]}function tI(n){let e=n.replace(/\r\n/g,`
|
|
713
713
|
`).replace(/\r/g,`
|
|
714
714
|
`);if(!e.startsWith("---"))return;let t=e.indexOf(`
|
|
715
715
|
---`,3);if(t!==-1)return e.slice(4,t)}function nI(n){return n.startsWith('"')&&n.endsWith('"')||n.startsWith("'")&&n.endsWith("'")?n.slice(1,-1):n}function rI(n,e){let t=[],r=e+1;for(;r<n.length;){let s=n[r];if(s.length>0&&!s.startsWith(" ")&&!s.startsWith(" "))break;t.push(s),r+=1}return{value:t.join(`
|
|
@@ -742,12 +742,12 @@ ${c}`:n}import*as V from"node:fs";import*as ee from"node:path";import{randomUUID
|
|
|
742
742
|
`)})}function Zg(){return Qs("tool_guidance",()=>["# Tool Usage Guidance","","You have access to specialized tools. Use them appropriately:","","## Agent Delegation","Use the `agent` tool to delegate complex, multi-step tasks to sub-agents:","- Research/exploration tasks that benefit from focused attention","- File analysis across multiple files that need independent reasoning","- Any task the user explicitly asks you to delegate","- **When the user says 'delegate', 'sub-agent', 'fork', or 'hand off', you MUST use the `agent` tool \u2014 never handle it yourself**","Do NOT use `agent` for simple file reads or single-step operations.","","## Skill System","Use the `skill` tool (unified meta-tool) for all skill operations:","- action 'invoke' \u2014 run a skill by name","- action 'list' \u2014 discover available skills (shows scope: project/global)","- action 'create' \u2014 save a new skill to current project","- action 'promote' \u2014 copy a project skill to global (user-level)","When recalled memories show '[Cross-project skill available]', proactively offer to use or save the skill.","","## Checkpoint","Use the `checkpoint` tool (not raw git commands) to:","- Save workspace state before making changes","- Restore to a previous state if changes go wrong","The checkpoint tool manages git shadow history automatically.","","## Ask User","Use `ask_user` to clarify ambiguous requests before proceeding,","especially for expensive operations like media generation.","","## Project Rules Management","You can create, edit, and delete project rule files at `.qlogicagent/rules/*.md`.","These files are loaded into your system prompt every turn \u2014 changes take effect immediately.","Use this to help users establish coding conventions, workflow guidelines, or project-specific instructions.","When the user asks to 'add a rule', 'set up conventions', or 'configure instructions', write to `.qlogicagent/rules/<descriptive-name>.md`.","You may also create or edit `.qlogicagent/INSTRUCTIONS.md` for a single top-level instruction file."].join(`
|
|
743
743
|
`))}function ef(n){return Qs("language",()=>n?["# Language","",`Always respond in ${n}.`,`Use ${n} for all text output, explanations, and descriptions.`,"Use English only for: code, file paths, tool arguments, variable names, and technical identifiers."].join(`
|
|
744
744
|
`):["# Language","","Respond in the same language as the user's message.","If the user writes in English, respond in English. If in Chinese, respond in Chinese.","Use English only for: code, file paths, tool arguments, variable names, and technical identifiers."].join(`
|
|
745
|
-
`))}je();import{randomUUID as tf}from"node:crypto";async function nf(n,e){let t=new Date(n.lastActiveAt).getTime();if(Date.now()-t<Ll)return{split:!1,activeSessionId:n.sessionId};let o=tf(),i=new Date().toISOString();await et(n.sessionId,{sealedAt:i},e);let a=n.taskSummary?`[\u4E0A\u4E00\u8F6E\u5BF9\u8BDD\u6458\u8981] ${n.taskSummary}`:void 0;return await et(o,{sessionId:o,projectId:n.projectId,type:"group",ownerId:n.ownerId,groupKey:n.groupKey,groupName:n.groupName,groupPlatform:n.groupPlatform,previousSessionId:n.sessionId,carryoverSummary:a},e),{split:!0,activeSessionId:o,sealedSessionId:n.sessionId}}async function rf(n,e){if(n.type!=="group")return{split:!1,activeSessionId:n.sessionId};if(n.turnCount<$l)return{split:!1,activeSessionId:n.sessionId};let t=tf(),r=new Date().toISOString();await et(n.sessionId,{sealedAt:r},e);let s=n.taskSummary?`[\u4E0A\u4E00\u8F6E\u5BF9\u8BDD\u6458\u8981 \u2014 \u56E0\u6D88\u606F\u6570\u8FBE\u5230\u4E0A\u9650\u81EA\u52A8\u5207\u5206] ${n.taskSummary}`:void 0;return await et(t,{sessionId:t,projectId:n.projectId,type:"group",ownerId:n.ownerId,groupKey:n.groupKey,groupName:n.groupName,groupPlatform:n.groupPlatform,previousSessionId:n.sessionId,carryoverSummary:s},e),{split:!0,activeSessionId:t,sealedSessionId:n.sessionId}}import*as Nn from"node:fs";var sf=new Dn,II=[/继续(桌面|电脑|刚才|上次|之前)的/,/接着(桌面|电脑|刚才|上次|之前)的/,/刚才(那个|那件|说的|聊的|做的)/,/上次(说到|聊到|做到|讲到)/,/桌面(端|上)?(那个|那边|的任务|的对话|在做)/,/电脑(端|上)?(那个|那边|的任务|的对话|在做)/,/之前(那个|在做的|讨论的|说的)/,/帮我继续/,/接着(做|干|搞|写|改)/,/continue (from |where |the )?desktop/i,/pick up where/i,/what were we (doing|working on|talking about)/i,/continue (the |our )?(last |previous )?(task|conversation|chat)/i];function _I(n){return!n||n.length<3?!1:II.some(e=>e.test(n))}function of(n){let e=n.params?.turnId??"";this.log(`abort requested for turn ${e}`),this.activeTurn&&(this.activeTurn.abort(),this.activeTurn=null),n.id!==void 0&&this.sendResponse(n.id,{aborted:!0})}function af(n){let e=n.params;if(!e)return;let t=e.approvalId,r=e.decision;if(!t||!r){this.log("[warn] tool.approval.response missing approvalId or decision");return}let s={approvalId:t,decision:r==="approved"?"approved":"denied",updatedInput:e.updatedInput,permissionUpdate:e.permissionUpdate};this.permissionChecker&&this.permissionChecker.resolveApproval(s),n.id!==void 0&&this.sendResponse(n.id,{received:!0})}function cf(n){let e=n.params,t=e?.requestId;if(!t){this.log("[warn] thread.user_response missing requestId"),n.id!==void 0&&this.sendResponse(n.id,{received:!1});return}let r=this.pendingAskUser.get(t);if(!r){this.log(`[warn] thread.user_response: no pending request ${t}`),n.id!==void 0&&this.sendResponse(n.id,{received:!1});return}if(this.pendingAskUser.delete(t),e?.declined===!0)r.resolve(null);else{let o=e?.answers??{};r.resolve(o)}n.id!==void 0&&this.sendResponse(n.id,{received:!0})}async function lf(n){let e=n.params??{},t=e.turnId??to();this.currentTurnId=t;let r=e.sessionId,s=e.messages??[],o=e.tools??[],i=e.config;n.id!==void 0&&this.sendResponse(n.id,{accepted:!0,turnId:t});let a=this.resumedSessionHistory.get(r);if(a&&a.length>0&&(s=[...a,...s]),i?.workdir&&typeof i.workdir=="string"&&this.setActiveWorkdir(i.workdir),!i?.workdir&&r&&i?.projectId){let y=i.projectId;try{let b=sf.getProjectWorkspaceDir(y);this.getActiveProjectRoot()!==b&&(this.log(`[turn] routing session ${r} to project ${y} (${b})`),this.setActiveWorkdir(b))}catch{this.log(`[turn] project ${y} not found, using active project`)}}if(i?.sessionType==="group"&&typeof i?.groupKey=="string"){let y=i.groupKey,b=y.split(":"),
|
|
746
|
-
`):null},"memory INDEX.md may change between turns")]}),ce=[...s].reverse().find(R=>R.role==="user");ce&&pa(r,ce,p,t).catch(()=>{}),await this.mcpReady;let le=At(),j=new Set(le.map(R=>R.function.name)),ke=[...le,...o.filter(R=>!j.has(R.function.name))],oe=s;if(l&&s.length>0){let R=Oe(),B=me().filter(we=>we.status==="active").map(we=>we.name).slice(0,10).join(", ");oe=[{role:"system",content:`[\u6CE8\u610F\uFF1A\u7528\u6237\u4ECE IM \u7AEF\u53D1\u6765\u6D88\u606F\uFF0C\u4F46\u684C\u9762\u7AEF\u5DF2\u8D85\u8FC730\u5206\u949F\u672A\u6D3B\u8DC3\uFF0C\u65E0\u6CD5\u786E\u5B9A\u7528\u6237\u60F3\u5728\u54EA\u4E2A\u9879\u76EE\u4E2D\u5DE5\u4F5C\u3002\u5F53\u524D\u6D3B\u8DC3\u9879\u76EE\uFF1A${R?.name??"\u65E0"}\u3002\u53EF\u7528\u9879\u76EE\uFF1A${B||"\u65E0"}\u3002\u8BF7\u5728\u56DE\u590D\u5F00\u5934\u7B80\u77ED\u8BE2\u95EE\u7528\u6237\u60F3\u5728\u54EA\u4E2A\u9879\u76EE\u4E2D\u7EE7\u7EED\uFF0C\u4F8B\u5982\uFF1A"\u4F60\u60F3\u7EE7\u7EED\u5728\u300CXX\u300D\u9879\u76EE\u4E2D\u5DE5\u4F5C\u5417\uFF1F"]`},...s]}let $e=i?.desktopRecentContext;if(!l&&$e&&$e.length>0&&s.length>0){let R=s[s.length-1],B=R?.role==="user"&&typeof R.content=="string"?R.content:"";if(_I(B)){let U={role:"system",content:"[\u4EE5\u4E0B\u662F\u7528\u6237\u5728\u684C\u9762\u7AEF\u7684\u8FD1\u671F\u5BF9\u8BDD\uFF0C\u4F9B\u4F60\u53C2\u8003\u4EE5\u4FDD\u6301\u4E0A\u4E0B\u6587\u8FDE\u8D2F]"},we={role:"system",content:"[\u684C\u9762\u5BF9\u8BDD\u4E0A\u4E0B\u6587\u7ED3\u675F\uFF0C\u4EE5\u4E0B\u662F\u5F53\u524D IM \u7AEF\u7684\u5BF9\u8BDD]"};oe=[U,...$e,we,...oe],this.log(`[continuation] injected ${$e.length} desktop messages as reference`)}}if(!an(r,p)?.title){let R=typeof ce?.content=="string"?ce.content:Array.isArray(ce?.content)?ce.content.filter(B=>B.type==="text").map(B=>B.text??"").join(""):"";if(R.trim()){let B=null,U=this.resolveClientForPurpose("smallModel");U&&(B=await vu(R,{transport:U.transport,apiKey:U.apiKey,model:U.model})),B||(B=R.trim().slice(0,20)+(R.trim().length>20?"\u2026":"")),await et(r,{title:B},p).catch(()=>{}),this.sendNotification("session.info",{sessionId:r,title:B,projectId:i?.projectId||void 0}),this.log(`[title-gen] generated title for session ${r}: "${B}"`)}}for await(let R of b.run({turnId:t,sessionId:r,messages:oe,tools:ke,systemPrompt:
|
|
745
|
+
`))}je();import{randomUUID as tf}from"node:crypto";async function nf(n,e){let t=new Date(n.lastActiveAt).getTime();if(Date.now()-t<Ll)return{split:!1,activeSessionId:n.sessionId};let o=tf(),i=new Date().toISOString();await et(n.sessionId,{sealedAt:i},e);let a=n.taskSummary?`[\u4E0A\u4E00\u8F6E\u5BF9\u8BDD\u6458\u8981] ${n.taskSummary}`:void 0;return await et(o,{sessionId:o,projectId:n.projectId,type:"group",ownerId:n.ownerId,groupKey:n.groupKey,groupName:n.groupName,groupPlatform:n.groupPlatform,previousSessionId:n.sessionId,carryoverSummary:a},e),{split:!0,activeSessionId:o,sealedSessionId:n.sessionId}}async function rf(n,e){if(n.type!=="group")return{split:!1,activeSessionId:n.sessionId};if(n.turnCount<$l)return{split:!1,activeSessionId:n.sessionId};let t=tf(),r=new Date().toISOString();await et(n.sessionId,{sealedAt:r},e);let s=n.taskSummary?`[\u4E0A\u4E00\u8F6E\u5BF9\u8BDD\u6458\u8981 \u2014 \u56E0\u6D88\u606F\u6570\u8FBE\u5230\u4E0A\u9650\u81EA\u52A8\u5207\u5206] ${n.taskSummary}`:void 0;return await et(t,{sessionId:t,projectId:n.projectId,type:"group",ownerId:n.ownerId,groupKey:n.groupKey,groupName:n.groupName,groupPlatform:n.groupPlatform,previousSessionId:n.sessionId,carryoverSummary:s},e),{split:!0,activeSessionId:t,sealedSessionId:n.sessionId}}import*as Nn from"node:fs";var sf=new Dn,II=[/继续(桌面|电脑|刚才|上次|之前)的/,/接着(桌面|电脑|刚才|上次|之前)的/,/刚才(那个|那件|说的|聊的|做的)/,/上次(说到|聊到|做到|讲到)/,/桌面(端|上)?(那个|那边|的任务|的对话|在做)/,/电脑(端|上)?(那个|那边|的任务|的对话|在做)/,/之前(那个|在做的|讨论的|说的)/,/帮我继续/,/接着(做|干|搞|写|改)/,/continue (from |where |the )?desktop/i,/pick up where/i,/what were we (doing|working on|talking about)/i,/continue (the |our )?(last |previous )?(task|conversation|chat)/i];function _I(n){return!n||n.length<3?!1:II.some(e=>e.test(n))}function of(n){let e=n.params?.turnId??"";this.log(`abort requested for turn ${e}`),this.activeTurn&&(this.activeTurn.abort(),this.activeTurn=null),n.id!==void 0&&this.sendResponse(n.id,{aborted:!0})}function af(n){let e=n.params;if(!e)return;let t=e.approvalId,r=e.decision;if(!t||!r){this.log("[warn] tool.approval.response missing approvalId or decision");return}let s={approvalId:t,decision:r==="approved"?"approved":"denied",updatedInput:e.updatedInput,permissionUpdate:e.permissionUpdate};this.permissionChecker&&this.permissionChecker.resolveApproval(s),n.id!==void 0&&this.sendResponse(n.id,{received:!0})}function cf(n){let e=n.params,t=e?.requestId;if(!t){this.log("[warn] thread.user_response missing requestId"),n.id!==void 0&&this.sendResponse(n.id,{received:!1});return}let r=this.pendingAskUser.get(t);if(!r){this.log(`[warn] thread.user_response: no pending request ${t}`),n.id!==void 0&&this.sendResponse(n.id,{received:!1});return}if(this.pendingAskUser.delete(t),e?.declined===!0)r.resolve(null);else{let o=e?.answers??{};r.resolve(o)}n.id!==void 0&&this.sendResponse(n.id,{received:!0})}async function lf(n){let e=n.params??{},t=e.turnId??to();this.currentTurnId=t;let r=e.sessionId,s=e.messages??[],o=e.tools??[],i=e.config;n.id!==void 0&&this.sendResponse(n.id,{accepted:!0,turnId:t});let a=this.resumedSessionHistory.get(r);if(a&&a.length>0&&(s=[...a,...s]),i?.workdir&&typeof i.workdir=="string"&&this.setActiveWorkdir(i.workdir),!i?.workdir&&r&&i?.projectId){let y=i.projectId;try{let b=sf.getProjectWorkspaceDir(y);this.getActiveProjectRoot()!==b&&(this.log(`[turn] routing session ${r} to project ${y} (${b})`),this.setActiveWorkdir(b))}catch{this.log(`[turn] project ${y} not found, using active project`)}}if(i?.sessionType==="group"&&typeof i?.groupKey=="string"){let y=i.groupKey,b=y.split(":"),T=b.length>=3?b.slice(1).join(":"):y,w=rs(T);if(w)this.setActiveWorkdir(w.workspaceDir),Oe()?.id!==w.id&&ut(w.id);else{let _=i.groupName||T,I=T.replace(/[<>:"/\\|?*\x00-\x1f]/g,"_").trim()||"group",D=Pr.join(q(),"workspaces","groups",I),L=ns({name:_,workspaceDir:D,type:"group",groupId:T});L&&(this.setActiveWorkdir(L.workspaceDir),ut(L.id),this.sendNotification("project.created",{id:L.id,name:L.name,type:"group",groupId:T,workspaceDir:L.workspaceDir}))}}let c=1800*1e3,l=!1,u=i?.projectHint,d=u&&typeof u=="object"&&"name"in u?u:typeof u=="string"?{name:u,updatedAt:Date.now()}:null;if(d&&i?.sessionType!=="group"){let y=Date.now()-d.updatedAt;if(y>c)l=!0,this.log(`[projectHint] stale (${Math.round(y/6e4)}min old), skipping auto-switch`);else{let b=d.name,T=Oe();if(!T||T.name.toLowerCase()!==b.toLowerCase()){let w=me(),_=b.toLowerCase(),I=w.find(D=>D.name.toLowerCase()===_)??w.find(D=>D.name.toLowerCase().includes(_));I&&I.status==="active"&&(ut(I.id),this.setActiveWorkdir(I.workspaceDir))}}}let p=(()=>{let y=i?.projectId;if(y)try{return sf.getProjectWorkspaceDir(y)}catch{}return this.getActiveProjectRoot()})();{let y=X(),b=y.snapshotProviderKeys();this.currentMediaApiKeys=b,mm(this.mediaClient,b,(w,_,I)=>{this.sessionState?.addMediaUsage(w,_,I)},i?.mediaProviders,(w,_,I,D,L)=>{this.sendNotification("turn.media_progress",{turnId:t,taskId:w,mediaType:_,percent:I,status:D,...L?{provider:L}:{}})});let T=y.getActiveModel("textGeneration");T?(ic(lm(T.provider,T.apiKey)),T.keyHandle.release({success:!0})):ic(void 0)}pm(async y=>{let b=`ask-${to().slice(0,8)}`;return new Promise(T=>{this.pendingAskUser.set(b,{resolve:T}),this.sendNotification("turn.ask_user",{requestId:b,questions:y.map(w=>({header:w.header,question:w.question,options:w.options}))})})});let m=new AbortController;this.activeTurn&&(this.activeTurn.abort(),await this.turnDone),this.activeTurn=m;let h;this.turnDone=new Promise(y=>{h=y}),r&&r!==this.currentSessionId&&(this.currentSessionId&&this.currentHooks&&(this.currentHooks.invoke("session.ended",{sessionId:this.currentSessionId}).catch(()=>{}),qg()),this.currentSessionId=r,this.sessionState=new Vt(r),this.sessionTaskDomain=void 0,this.memoryPrefetchState=Ot(),this.enableIdleDream()),this.log(`turn ${t} starting (session: ${r})`),this.sendNotification("turn.start",{turnId:t,model:i?.model??(this.currentModel||void 0),provider:i?.provider||void 0,projectId:i?.projectId||void 0});let f=[...s].reverse().find(y=>y.role==="user");if(this.lastUserMessageForAutoExtract=typeof f?.content=="string"?f.content:void 0,!f||!String(f.content??"").trim()){this.sendNotification("turn.end",{turnId:t,content:"",item:{id:`${t}-end`,type:"message",role:"assistant",text:"",createdAt:new Date().toISOString()}});return}try{let y={provider:i?.provider,model:i?.model,apiKey:i?.apiKey,baseUrl:i?.baseUrl,maxRounds:i?.maxRounds,temperature:i?.temperature,contextWindowTokens:i?.contextWindowTokens,maxOutputTokens:i?.maxOutputTokens,modelMaxOutputTokens:i?.modelMaxOutputTokens,maxConcurrentTools:i?.maxConcurrentTools,mediaProviders:i?.mediaProviders,reasoning:i?.reasoning,promptCacheKey:i?.promptCacheKey,promptCacheRetention:i?.promptCacheRetention,serviceTier:i?.serviceTier,openaiBuiltinTools:i?.openaiBuiltinTools,maxToolCalls:i?.maxToolCalls,parallelToolCalls:i?.parallelToolCalls,textVerbosity:i?.textVerbosity,mcpServers:i?.mcpServers,fallbackModel:X().resolveModelForPurpose("smallModel")??void 0};{let R=y.provider??"",B=y.model??"";R&&B&&X().getModelInfo(R,B)?.streamRequired&&(y.streamRequired=!0)}let b=this.resolveAgent(y);if(this.permissionChecker&&i?.permissions){let R=i.permissions,B=_s(R);this.permissionChecker.ruleEngineRef.setMode(B.mode),B.rules.length>0&&this.permissionChecker.ruleEngineRef.replaceRules(B.rules),B.defaultBehavior&&this.permissionChecker.ruleEngineRef.setDefaultBehavior(B.defaultBehavior),B.mode}if(!b){this.sendNotification("turn.error",{turnId:t,error:{message:"No LLM provider configured. Provide provider/model/apiKey in agent.turn config, or set DEEPSEEK_API_KEY / OPENAI_API_KEY / ANTHROPIC_API_KEY environment variable.",code:"NO_PROVIDER"}});return}let T,w=i?.workdir??this.getActiveProjectRoot();this.setActiveWorkdir(w);try{let R=await Iu(w,this.currentHooks??void 0);R.length>0&&(T=Pu(R))}catch{}let _=s.filter(R=>R.role==="user").map(R=>typeof R.content=="string"?R.content:"").join(" "),{domain:I,source:D}=zg({cwd:w,hostOverride:i?.taskDomain,sessionDomain:this.sessionTaskDomain,userText:_});if(this.sessionTaskDomain=I,D==="auto-detect"&&Yg(_,I)&&Xg(w,I),!this.memdir||this.memdir.getRootPath()!==new Ct(w).getRootPath()){let R=new Ct(w);R.ensureInitialized(),this.memdir=R}let L=this.memdir,F;if(r){let R=an(r,p);R?.carryoverSummary&&(F=R.carryoverSummary)}let S=await Wg({basePrompt:i?.systemPrompt,instructionBlock:T,customSystemPrompt:i?.customSystemPrompt,appendSystemPrompt:i?.appendSystemPrompt,sections:[Jg(w),ef(),Qg(I),Zg(),...F?[wr("carryover",()=>F,"carryover from predecessor session")]:[],wr("memory",()=>{if(!L)return null;let R=L.getIndexForPrompt();return R?["## Your Memory (project-level notes \u2014 always visible)","",R,"","<!-- Use memory(action='remember') for user-level long-term facts/preferences that persist across projects.>","<!-- Use memory(action='add') for project-specific notes that should be visible every turn.>"].join(`
|
|
746
|
+
`):null},"memory INDEX.md may change between turns")]}),ce=[...s].reverse().find(R=>R.role==="user");ce&&pa(r,ce,p,t).catch(()=>{}),await this.mcpReady;let le=At(),j=new Set(le.map(R=>R.function.name)),ke=[...le,...o.filter(R=>!j.has(R.function.name))],oe=s;if(l&&s.length>0){let R=Oe(),B=me().filter(we=>we.status==="active").map(we=>we.name).slice(0,10).join(", ");oe=[{role:"system",content:`[\u6CE8\u610F\uFF1A\u7528\u6237\u4ECE IM \u7AEF\u53D1\u6765\u6D88\u606F\uFF0C\u4F46\u684C\u9762\u7AEF\u5DF2\u8D85\u8FC730\u5206\u949F\u672A\u6D3B\u8DC3\uFF0C\u65E0\u6CD5\u786E\u5B9A\u7528\u6237\u60F3\u5728\u54EA\u4E2A\u9879\u76EE\u4E2D\u5DE5\u4F5C\u3002\u5F53\u524D\u6D3B\u8DC3\u9879\u76EE\uFF1A${R?.name??"\u65E0"}\u3002\u53EF\u7528\u9879\u76EE\uFF1A${B||"\u65E0"}\u3002\u8BF7\u5728\u56DE\u590D\u5F00\u5934\u7B80\u77ED\u8BE2\u95EE\u7528\u6237\u60F3\u5728\u54EA\u4E2A\u9879\u76EE\u4E2D\u7EE7\u7EED\uFF0C\u4F8B\u5982\uFF1A"\u4F60\u60F3\u7EE7\u7EED\u5728\u300CXX\u300D\u9879\u76EE\u4E2D\u5DE5\u4F5C\u5417\uFF1F"]`},...s]}let $e=i?.desktopRecentContext;if(!l&&$e&&$e.length>0&&s.length>0){let R=s[s.length-1],B=R?.role==="user"&&typeof R.content=="string"?R.content:"";if(_I(B)){let U={role:"system",content:"[\u4EE5\u4E0B\u662F\u7528\u6237\u5728\u684C\u9762\u7AEF\u7684\u8FD1\u671F\u5BF9\u8BDD\uFF0C\u4F9B\u4F60\u53C2\u8003\u4EE5\u4FDD\u6301\u4E0A\u4E0B\u6587\u8FDE\u8D2F]"},we={role:"system",content:"[\u684C\u9762\u5BF9\u8BDD\u4E0A\u4E0B\u6587\u7ED3\u675F\uFF0C\u4EE5\u4E0B\u662F\u5F53\u524D IM \u7AEF\u7684\u5BF9\u8BDD]"};oe=[U,...$e,we,...oe],this.log(`[continuation] injected ${$e.length} desktop messages as reference`)}}if(!an(r,p)?.title){let R=typeof ce?.content=="string"?ce.content:Array.isArray(ce?.content)?ce.content.filter(B=>B.type==="text").map(B=>B.text??"").join(""):"";if(R.trim()){let B=null,U=this.resolveClientForPurpose("smallModel");U&&(B=await vu(R,{transport:U.transport,apiKey:U.apiKey,model:U.model})),B||(B=R.trim().slice(0,20)+(R.trim().length>20?"\u2026":"")),await et(r,{title:B},p).catch(()=>{}),this.sendNotification("session.info",{sessionId:r,title:B,projectId:i?.projectId||void 0}),this.log(`[title-gen] generated title for session ${r}: "${B}"`)}}for await(let R of b.run({turnId:t,sessionId:r,messages:oe,tools:ke,systemPrompt:S,config:y},m.signal)){let B=new Date().toISOString();switch(R.type){case"start":break;case"delta":this.sendNotification("turn.delta",{turnId:R.turnId,text:R.text,item:{id:`${t}-delta`,type:"message",role:"assistant",text:R.text,createdAt:B}});break;case"end":if(this.sendNotification("turn.end",{turnId:R.turnId,content:R.content,usage:R.usage,model:R.model,provider:R.provider,item:{id:`${t}-end`,type:"message",role:"assistant",text:R.content,createdAt:B}}),R.usage&&this.sessionState){this.sessionState.addUsage(R.usage,R.model??this.currentModel);let U=this.sessionState.createSnapshot();this.sendNotification("turn.usage_update",{turnId:R.turnId,usage:R.usage,model:R.model??this.currentModel,sessionCostUSD:U.totalInputTokens*3e-6+U.totalOutputTokens*15e-6})}R.content&&(this.lastAssistantMessageForExtract=R.content,pa(r,{role:"assistant",content:R.content},p,t).catch(()=>{}));break;case"error":if(this.sendNotification("turn.error",{turnId:R.turnId,error:{message:R.error,code:R.code}}),R.usage&&this.sessionState){this.sessionState.addUsage(R.usage,this.currentModel);let U=this.sessionState.createSnapshot();this.sendNotification("turn.usage_update",{turnId:R.turnId,usage:R.usage,model:this.currentModel,sessionCostUSD:U.totalInputTokens*3e-6+U.totalOutputTokens*15e-6})}break;case"skill_instruction":if(this.sendNotification("turn.skill_instruction",{turnId:R.turnId,instruction:R.instruction}),R.instruction.type==="skill.create"){let U=R.instruction,fe=Pr.join(p,".qlogicagent","skills"),Et=Pr.join(fe,U.suggestedName),g=Pr.join(Et,"SKILL.md");if(!Nn.existsSync(g)){let v=Vs({name:U.suggestedName,description:U.description,tools:U.tools,body:`# ${U.suggestedName}
|
|
747
747
|
|
|
748
748
|
Auto-learned multi-step workflow using: ${U.tools.join(", ")}.
|
|
749
|
-
`,version:"1.0.0",category:"learned"}),x=zs(v,U.suggestedName);if(x.valid){Nn.mkdirSync(Et,{recursive:!0}),Nn.writeFileSync(g,v,"utf8"),pt();let C=q(),A=Be(C);Bt(A,U.suggestedName,"learned"),We(C,A),this.log(`[skill-auto-persist] Created skill "${U.suggestedName}" from turn ${R.turnId}`)}else this.log(`[skill-auto-persist] Validation failed for "${U.suggestedName}": ${x.errors.join(", ")}`)}}break;case"tool_call":this.sendNotification("turn.tool_call",{turnId:R.turnId,callId:R.callId,name:R.name,arguments:R.arguments,item:{id:R.callId,type:"tool_call",role:"assistant",toolName:R.name,toolCallId:R.callId,arguments:R.arguments,createdAt:B}}),this.sessionState?.recordToolCall();break;case"tool_result":this.sendNotification("turn.tool_result",{turnId:R.turnId,callId:R.callId,name:R.name,ok:R.ok,...R.error?{error:R.error}:{},...R.outputPreview?{outputPreview:R.outputPreview}:{},item:{id:`${R.callId}-result`,type:"tool_result",role:"assistant",toolName:R.name,toolCallId:R.callId,output:R.ok?R.outputPreview??"":R.error,approved:R.ok,createdAt:B}});break;case"tool_blocked":this.sendNotification("turn.tool_blocked",{turnId:R.turnId,callId:R.callId,name:R.name,reason:R.reason,item:{id:`${R.callId}-blocked`,type:"tool_blocked",role:"system",toolName:R.name,toolCallId:R.callId,text:R.reason,approved:!1,createdAt:B}});break;case"recovery":this.sendNotification("turn.recovery",{turnId:R.turnId,action:R.action,...R.detail?{detail:R.detail}:{},item:{id:`${t}-recovery-${to().slice(0,8)}`,type:"recovery",role:"system",strategy:R.action,text:R.detail,createdAt:B}});break;case"plan_update":this.sendNotification("turn.plan_update",{turnId:R.turnId,slug:R.slug,content:R.content,item:{id:`${t}-plan-${to().slice(0,8)}`,type:"plan_update",role:"assistant",text:R.content,createdAt:B}});break;case"reasoning_delta":this.sendNotification("turn.reasoning_delta",{turnId:R.turnId,text:R.text});break;case"suggestions":this.sendNotification("turn.suggestions",{turnId:R.turnId,items:R.items});break;case"media_result":this.sendNotification("turn.media_result",{turnId:R.turnId,mediaType:R.mediaType,url:R.url,...R.model?{model:R.model}:{},...R.provider?{provider:R.provider}:{},...R.taskId?{taskId:R.taskId}:{}});break;case"artifact":this.sendNotification("turn.artifact",{turnId:R.turnId,artifactId:R.artifactId,type:R.artifactType,title:R.title,...R.filePath?{filePath:R.filePath}:{},...R.language?{language:R.language}:{},...R.content?{content:R.content}:{},...R.mimeType?{mimeType:R.mimeType}:{}});break;case"subagent_started":this.sendNotification("turn.subagent_started",{turnId:R.turnId,subagentId:R.subagentId,agentType:R.agentType,...R.prompt?{prompt:R.prompt}:{}});break;case"subagent_ended":this.sendNotification("turn.subagent_ended",{turnId:R.turnId,subagentId:R.subagentId,agentType:R.agentType,ok:R.ok,...R.outputPreview?{outputPreview:R.outputPreview}:{},...R.error?{error:R.error}:{}});break;case"annotations":this.sendNotification("turn.annotations",{turnId:R.turnId,annotations:R.annotations});break;case"heartbeat":this.sendNotification("turn.heartbeat",{turnId:R.turnId,message:R.message});break;case"tool_use_summary":this.sendNotification("turn.tool_use_summary",{turnId:R.turnId,summary:R.summary});break}}if(this.log(`turn ${t} completed`),this.sessionState?.recordTurnCompleted(),this.sessionState){ku(r,this.sessionState.createSnapshot(),{model:this.currentModel,cwd:p,messageCount:s.length},p).catch(()=>{});let R=this.sessionState.createSnapshot();this.sendNotification("session.info",{sessionId:r,model:this.currentModel||void 0,cwd:p,turnCount:R.turnCount,projectId:i?.projectId||void 0});let B=this.resolveClientForPurpose("smallModel");if(B&&Su(r,{sessionId:r,projectId:"",createdAt:"",lastActiveAt:"",turnCount:R.turnCount,messageCount:s.length},s,{transport:B.transport,apiKey:B.apiKey,model:B.model},p),this.generateSuggestions(t,s),this.petAwardXp("turn.end"),this.petReactionAfterTurn(s),i?.sessionType==="group"&&this.sessionState){let U=this.sessionState.createSnapshot(),we=an(r,p);we&&rf({...we,turnCount:U.turnCount},p).then(fe=>{fe.split&&this.sendNotification("session-update",{sessionId:fe.activeSessionId,projectId:i?.projectId??"",title:"",type:"group"})}).catch(()=>{})}}}catch(y){if(m.signal.aborted)this.sendNotification("turn.error",{turnId:t,error:{message:"Turn aborted",code:"ABORTED"}});else{let b=y instanceof Error?y.message:String(y);this.sendNotification("turn.error",{turnId:t,error:{message:b,code:"INTERNAL_ERROR"}})}}finally{this.activeTurn===m&&(this.activeTurn=null),h()}}dt();import{randomUUID as df}from"node:crypto";async function no(n){let e=n.params??{},t=e.turnId??df(),r=e.sessionId,s=e.config,o=s?.memoryRoot??"",i=s?.transcriptDir??"",a=s?.dreamSessionIds??[];n.id!==void 0&&this.sendResponse(n.id,{accepted:!0,turnId:t});let c=new AbortController;this.activeTurn=c,this.log(`dream ${t} starting (session: ${r}, sessions reviewing: ${a.length})`),this.sendNotification("system.activity",{category:"dream",level:"info",title:"\u68A6\u5883\u6574\u7406\u542F\u52A8",detail:`\u6B63\u5728\u56DE\u987E ${a.length} \u4E2A\u4F1A\u8BDD\u7684\u8BB0\u5FC6...`});let l={provider:s?.provider,model:s?.model,apiKey:s?.apiKey,baseUrl:s?.baseUrl,maxRounds:s?.maxRounds,temperature:s?.temperature,contextWindowTokens:s?.contextWindowTokens,maxOutputTokens:s?.maxOutputTokens,modelMaxOutputTokens:s?.modelMaxOutputTokens,reasoning:s?.reasoning,promptCacheKey:s?.promptCacheKey,promptCacheRetention:s?.promptCacheRetention,serviceTier:s?.serviceTier,openaiBuiltinTools:s?.openaiBuiltinTools,maxToolCalls:s?.maxToolCalls,parallelToolCalls:s?.parallelToolCalls,textVerbosity:s?.textVerbosity};{let d=l.provider??"",p=l.model??"";if(d&&p){let m=X().getModelInfo(d,p);m?.streamRequired&&(l.streamRequired=!0),!l.contextWindowTokens&&m?.contextWindow&&(l.contextWindowTokens=m.contextWindow)}}if(!this.resolveAgent(l)){this.sendNotification("turn.start",{turnId:t}),this.sendNotification("turn.error",{turnId:t,error:{message:"No LLM provider configured for dream.",code:"NO_PROVIDER"}});return}this.sendNotification("turn.start",{turnId:t});try{let d={context:{memoryRoot:o,transcriptDir:i,currentSessionId:r,listSessionsSince:async()=>a,currentSessionTurnCount:s?.currentSessionTurnCount??0},triggerConfig:{force:s?.force!==!1},transport:this.currentTransport,toolInvoker:{invoke:async(m,h,f,y)=>{if(h.startsWith("$"))return{result:f};let b=findTool(h);if(!b)return{result:"",error:`Unknown tool: ${h}`};let
|
|
750
|
-
`),error:_.details?.error}}catch(w){return{result:"",error:w instanceof Error?w.message:String(w)}}}},tools:getToolManifest(),apiKey:this.currentApiKey,model:l.model??this.currentModel,log:{info:m=>this.log(m),warn:m=>this.log(`[warn] ${m}`),error:m=>this.log(`[error] ${m}`),debug:m=>{this.verbose&&this.log(`[debug] ${m}`)}},hooks:this.currentHooks??void 0,parentSignal:c.signal,memoryProvider:this.memoryProvider??void 0,memoryUserId:this.memoryUserId||void 0},p=await runDream(d);if(p.ok){if(this.memoryProvider&&this.memoryUserId)try{let m=await runDecayCycle({adapter:this.memoryProvider,userId:this.memoryUserId,memoryRoot:o,log:{info:h=>this.log(h),debug:h=>{this.verbose&&this.log(h)}}});m.ran&&(this.sendNotification("memory.decay.completed",{decayed:m.decayed,archived:m.archived,durationMs:m.durationMs}),this.sendNotification("system.activity",{category:"decay",level:"info",title:"\u8BB0\u5FC6\u8870\u51CF\u5B8C\u6210",detail:`\u8870\u51CF ${m.decayed} \u6761\uFF0C\u5F52\u6863 ${m.archived} \u6761 (${m.durationMs}ms)`}))}catch(m){this.log(`[decay] post-dream decay error: ${m instanceof Error?m.message:String(m)}`)}this.sendNotification("system.activity",{category:"dream",level:"success",title:"\u68A6\u5883\u6574\u7406\u5B8C\u6210",detail:`\u56DE\u987E ${p.sessionsReviewed} \u4E2A\u4F1A\u8BDD\uFF0C\u6574\u7406 ${p.filesTouched.length} \u4E2A\u8BB0\u5FC6\u6587\u4EF6\uFF0C\u8017\u65F6 ${p.durationMs}ms`}),this.sendNotification("turn.end",{turnId:t,content:`Dream consolidation completed. ${p.sessionsReviewed} sessions reviewed, ${p.filesTouched.length} files touched. Duration: ${p.durationMs}ms.`,usage:{inputTokens:0,outputTokens:0}})}else this.sendNotification("system.activity",{category:"dream",level:"error",title:"\u68A6\u5883\u6574\u7406\u5931\u8D25",detail:p.error??"\u672A\u77E5\u9519\u8BEF"}),this.sendNotification("turn.error",{turnId:t,error:{message:p.error??"Dream consolidation failed",code:"DREAM_FAILED"}});this.log(`dream ${t} completed`)}catch(d){if(c.signal.aborted)this.sendNotification("system.activity",{category:"dream",level:"warn",title:"\u68A6\u5883\u6574\u7406\u88AB\u4E2D\u65AD"}),this.sendNotification("turn.error",{turnId:t,error:{message:"Dream aborted",code:"ABORTED"}});else{let p=d instanceof Error?d.message:String(d);this.sendNotification("system.activity",{category:"dream",level:"error",title:"\u68A6\u5883\u6574\u7406\u5F02\u5E38",detail:p}),this.sendNotification("turn.error",{turnId:t,error:{message:p,code:"INTERNAL_ERROR"}})}}finally{this.activeTurn===c&&(this.activeTurn=null)}}import{randomUUID as LI}from"node:crypto";var Ir=class{nodes=new Map;constructor(e){for(let t of e){if(this.nodes.has(t.taskId))throw new Error(`Duplicate task ID: ${t.taskId}`);this.nodes.set(t.taskId,{taskId:t.taskId,assignee:t.assignee,prompt:t.prompt,dependsOn:t.dependsOn??[],status:"pending"})}this.validateDag()}getAllTasks(){return[...this.nodes.values()]}getTask(e){return this.nodes.get(e)}getReadyTasks(){let e=[];for(let t of this.nodes.values()){if(t.status!=="pending")continue;t.dependsOn.every(s=>this.nodes.get(s)?.status==="completed")&&e.push(t)}return e}markRunning(e){let t=this.nodes.get(e);if(!t)throw new Error(`Unknown task: ${e}`);if(t.status!=="pending")throw new Error(`Task ${e} is ${t.status}, cannot start`);t.status="running",t.startedAt=Date.now()}markCompleted(e,t){let r=this.nodes.get(e);if(!r)throw new Error(`Unknown task: ${e}`);if(r.status!=="running")throw new Error(`Task ${e} is ${r.status}, cannot complete`);r.status="completed",r.result=t,r.completedAt=Date.now()}markFailed(e,t){let r=this.nodes.get(e);if(!r)throw new Error(`Unknown task: ${e}`);r.status="failed",r.error=t,r.completedAt=Date.now()}markPaused(e){let t=this.nodes.get(e);if(!t)throw new Error(`Unknown task: ${e}`);t.status==="running"&&(t.status="paused")}resumePaused(e){let t=this.nodes.get(e);if(!t)throw new Error(`Unknown task: ${e}`);t.status==="paused"&&(t.status="pending")}isFinished(){for(let e of this.nodes.values())if(e.status==="running"||e.status==="paused"||e.status==="pending"&&!e.dependsOn.some(r=>this.nodes.get(r)?.status==="failed"))return!1;return!0}isAllCompleted(){return[...this.nodes.values()].every(e=>e.status==="completed")}getBlockedTasks(){return[...this.nodes.values()].filter(e=>e.status!=="pending"?!1:e.dependsOn.some(t=>this.nodes.get(t)?.status==="failed"))}pauseAll(){for(let e of this.nodes.values())e.status==="running"&&(e.status="paused")}resumeAll(){for(let e of this.nodes.values())e.status==="paused"&&(e.status="pending")}serialize(){return[...this.nodes.values()].map(e=>({taskId:e.taskId,assignee:e.assignee,prompt:e.prompt,dependsOn:e.dependsOn,status:e.status,result:e.result,error:e.error,startedAt:e.startedAt,completedAt:e.completedAt}))}restore(e){for(let t of e){let r=this.nodes.get(t.taskId);r&&(r.status=t.status==="running"?"pending":t.status,r.result=t.result,r.error=t.error,r.startedAt=t.startedAt,r.completedAt=t.completedAt)}}addTask(e){if(this.nodes.has(e.taskId))throw new Error(`Task "${e.taskId}" already exists`);for(let r of e.dependsOn??[])if(!this.nodes.has(r))throw new Error(`New task "${e.taskId}" depends on unknown task "${r}"`);let t={taskId:e.taskId,assignee:e.assignee,prompt:e.prompt,dependsOn:e.dependsOn??[],status:"pending"};this.nodes.set(e.taskId,t);try{this.validateDag()}catch(r){throw this.nodes.delete(e.taskId),r}}addTasks(e){let t=[];try{for(let r of e)this.addTask(r),t.push(r.taskId)}catch(r){for(let s of t)this.nodes.delete(s);throw r}}removeTask(e){let t=this.nodes.get(e);if(!t)throw new Error(`Unknown task: ${e}`);if(t.status==="running")throw new Error(`Cannot remove running task "${e}"`);if(t.status==="completed")throw new Error(`Cannot remove completed task "${e}"`);for(let r of this.nodes.values()){let s=r.dependsOn.indexOf(e);s!==-1&&r.dependsOn.splice(s,1)}this.nodes.delete(e)}retryTask(e,t){let r=this.nodes.get(e);if(!r)throw new Error(`Unknown task: ${e}`);if(r.status!=="failed")throw new Error(`Task "${e}" is ${r.status}, only failed tasks can be retried`);r.status="pending",r.error=void 0,r.result=void 0,r.startedAt=void 0,r.completedAt=void 0,t&&(r.prompt=t)}updateTaskPrompt(e,t){let r=this.nodes.get(e);if(!r)throw new Error(`Unknown task: ${e}`);if(r.status!=="pending")throw new Error(`Task "${e}" is ${r.status}, can only update pending tasks`);r.prompt=t}reassignTask(e,t){let r=this.nodes.get(e);if(!r)throw new Error(`Unknown task: ${e}`);if(r.status!=="pending")throw new Error(`Task "${e}" is ${r.status}, can only reassign pending tasks`);r.assignee=t}addDependency(e,t){let r=this.nodes.get(e);if(!r)throw new Error(`Unknown task: ${e}`);if(!this.nodes.has(t))throw new Error(`Unknown dependency task: ${t}`);if(!r.dependsOn.includes(t)){r.dependsOn.push(t);try{this.validateDag()}catch(s){throw r.dependsOn.pop(),s}}}getProgress(){let e=0,t=0,r=0,s=0,o=0;for(let i of this.nodes.values())switch(i.status){case"completed":e++;break;case"running":t++;break;case"failed":r++;break;case"pending":s++;break;case"paused":o++;break}return{total:this.nodes.size,completed:e,running:t,failed:r,pending:s,paused:o}}validateDag(){for(let s of this.nodes.values())for(let o of s.dependsOn)if(!this.nodes.has(o))throw new Error(`Task "${s.taskId}" depends on unknown task "${o}"`);let e=new Set,t=new Set,r=s=>{if(t.has(s))throw new Error(`Cycle detected involving task "${s}"`);if(e.has(s))return;t.add(s);let o=this.nodes.get(s);for(let i of o.dependsOn)r(i);t.delete(s),e.add(s)};for(let s of this.nodes.keys())r(s)}};var _r=class{maxTotalTokens;maxDuration;usedTokens=0;startedAt;warningEmitted=!1;constructor(e){this.maxTotalTokens=e?.maxTotalTokens,this.maxDuration=e?.maxDuration,this.startedAt=Date.now()}addUsage(e,t){this.usedTokens+=e+t}addFromTracker(e){if(!e.hasData())return;let t=e.getUsage();this.usedTokens+=t.totalTokens}getElapsed(){return Date.now()-this.startedAt}getBudget(){return{maxTotalTokens:this.maxTotalTokens,maxDuration:this.maxDuration,usedTokens:this.usedTokens,elapsed:this.getElapsed()}}check(){let e=this.getElapsed();if(this.maxDuration&&e>=this.maxDuration)return{action:"exceeded",percentage:Math.round(e/this.maxDuration*100),usedTokens:this.usedTokens,maxTotalTokens:this.maxTotalTokens,elapsed:e,maxDuration:this.maxDuration};if(this.maxTotalTokens){let r=Math.round(this.usedTokens/this.maxTotalTokens*100);if(this.usedTokens>=this.maxTotalTokens)return{action:"exceeded",percentage:r,usedTokens:this.usedTokens,maxTotalTokens:this.maxTotalTokens,elapsed:e,maxDuration:this.maxDuration};if(r>=80&&!this.warningEmitted)return this.warningEmitted=!0,{action:"warning",percentage:r,usedTokens:this.usedTokens,maxTotalTokens:this.maxTotalTokens,elapsed:e,maxDuration:this.maxDuration}}return{action:"ok",percentage:this.maxTotalTokens?Math.round(this.usedTokens/this.maxTotalTokens*100):0,usedTokens:this.usedTokens,maxTotalTokens:this.maxTotalTokens,elapsed:e,maxDuration:this.maxDuration}}restore(e){this.usedTokens=e.usedTokens,this.startedAt=e.startedAt,this.warningEmitted=e.warningEmitted}serialize(){return{usedTokens:this.usedTokens,startedAt:this.startedAt,warningEmitted:this.warningEmitted}}};import{join as Gc}from"node:path";import{mkdir as CI,readdir as EI}from"node:fs/promises";ae();function uf(n){return Gc(Me(n),"products")}function pf(n,e){return Gc(uf(e),n)}function mf(n,e){return Gc(pf(n,e),"product-state.json")}async function gf(n,e){let t=pf(n.productId,e);await CI(t,{recursive:!0}),await En(mf(n.productId,e),n)}async function Kc(n,e){return pn(mf(n,e))}async function ff(n){let e=uf(n),t;try{t=await EI(e)}catch{return[]}let r=[];for(let s of t){let o=await Kc(s,n);o&&r.push(o)}return r}var Cr=class n{constructor(e={}){this.callbacks=e}callbacks;static DEFAULT_INTERVAL=5*6e4;static LONG_RUNNING_INTERVAL=30*6e4;static LONG_RUNNING_THRESHOLD=2880*6e4;timer=null;lastCheckpointAt=0;cwd;start(e){this.cwd=e,this.stop(),this.timer=setInterval(()=>{let t=this.callbacks.getState?.();t&&this.checkpoint(t).catch(r=>{this.callbacks.log?.warn(`[checkpoint] periodic save failed: ${r instanceof Error?r.message:String(r)}`)})},n.DEFAULT_INTERVAL),this.timer.unref()}stop(){this.timer&&(clearInterval(this.timer),this.timer=null)}getInterval(e){return e>n.LONG_RUNNING_THRESHOLD?n.LONG_RUNNING_INTERVAL:n.DEFAULT_INTERVAL}isDue(e){if(this.lastCheckpointAt===0)return!0;let t=this.getInterval(e);return Date.now()-this.lastCheckpointAt>=t}async checkpoint(e){let t=new Date().toISOString();e.lastCheckpointAt=t,await gf(e,this.cwd),this.lastCheckpointAt=Date.now(),this.callbacks.onCheckpoint?.(e.productId,t),this.callbacks.log?.info(`[checkpoint] saved ${e.productId} at ${t}`)}getLastCheckpointAt(){return this.lastCheckpointAt}};import{execFile as MI}from"node:child_process";import{promisify as DI}from"node:util";import{join as hf}from"node:path";import{mkdir as NI,rm as OI}from"node:fs/promises";var On=DI(MI);async function Er(n){try{let{stdout:e}=await On("git",["rev-parse","--show-toplevel"],{cwd:n,encoding:"utf8"});return e.trim()}catch{return null}}async function ro(n,e,t){let r=hf(n,".worktrees");await NI(r,{recursive:!0});let s=hf(r,e),i=["worktree","add","-B",`solo/${e}`,s];return t?i.push(t):i.push("HEAD"),await On("git",i,{cwd:n,encoding:"utf8"}),s}async function Vc(n){try{await On("git",["add","-A"],{cwd:n});let{stdout:e}=await On("git",["diff","--cached","--stat"],{cwd:n,encoding:"utf8"});return e.trim()}catch{return""}}async function yf(n,e){try{await On("git",["worktree","remove","--force",e],{cwd:n,encoding:"utf8"})}catch{try{await OI(e,{recursive:!0,force:!0})}catch{}}}async function bf(n,e){let{stdout:t}=await On("git",["merge","--no-ff",e,"-m",`solo: merge ${e}`],{cwd:n,encoding:"utf8"});return t.trim()}var so=class{constructor(e,t,r,s={}){this.processManager=e;this.acpDetector=t;this.configStore=r;this.callbacks=s}processManager;acpDetector;configStore;callbacks;sessions=new Map;async create(e){let{name:t,cwd:r,instances:s,tasks:o,budget:i}=e;if(s.length===0)throw new Error("Product requires at least 1 instance");if(o.length===0)throw new Error("Product requires at least 1 task");let a=new Set(s.map(b=>b.name));for(let b of o)if(!a.has(b.assignee))throw new Error(`Task "${b.taskId}" references unknown instance "${b.assignee}"`);let c=`product-${LI().slice(0,8)}`,l=new Ir(o),u=new _r(i),d=new Cr({onCheckpoint:(b,S)=>this.callbacks.onCheckpointed?.(b,S),getState:()=>{let b=this.sessions.get(c);return b?this.buildPersistedState(b):null},log:this.callbacks.log}),p=await Er(r),m=s.map((b,S)=>({instanceId:`${c}:${b.name}:${S}`,name:b.name,agentId:b.agentId,state:"idle"})),h={productId:c,name:t,cwd:r,phase:"active",instances:m,dag:l,budget:u,checkpoint:d,createdAt:new Date().toISOString(),gitRoot:p};this.sessions.set(c,h),d.start(r),this.callbacks.log?.info(`[product] created ${c} "${t}" with ${s.length} instances, ${o.length} tasks`);let f=o.map(b=>({id:b.taskId,label:b.taskId,deps:b.dependsOn??[]})),y=[];for(let b of o)if(b.dependsOn)for(let S of b.dependsOn)y.push({from:S,to:b.taskId});return this.callbacks.onDagTopology?.(c,f,y),setTimeout(()=>this.scheduleNext(h),0),c}async resume(e,t){let r=await Kc(e,t);if(!r)throw new Error(`Product ${e} not found on disk`);let s=new Ir(r.tasks);s.restore(r.tasks);let o=new _r({maxTotalTokens:r.budget.maxTotalTokens,maxDuration:r.budget.maxDuration});o.restore(r.budget);let i=new Cr({onCheckpoint:(u,d)=>this.callbacks.onCheckpointed?.(u,d),getState:()=>{let u=this.sessions.get(e);return u?this.buildPersistedState(u):null},log:this.callbacks.log}),a=await Er(r.cwd),c=r.instances.map((u,d)=>({instanceId:`${e}:${u.name}:${d}`,name:u.name,agentId:u.agentId,state:"idle"})),l={productId:r.productId,name:r.name,cwd:r.cwd,phase:"active",instances:c,dag:s,budget:o,checkpoint:i,createdAt:r.createdAt,gitRoot:a};this.sessions.set(e,l),i.start(r.cwd),this.callbacks.log?.info(`[product] resumed ${e}`),this.scheduleNext(l)}async pause(e){let t=this.sessions.get(e);if(!t)throw new Error(`Product ${e} not found`);if(t.phase!=="active")throw new Error(`Product ${e} is not active`);t.phase="paused",t.dag.pauseAll();for(let r of t.instances)if(r.state==="running"&&r.memberId){try{this.processManager.kill(r.memberId)}catch{}r.state="paused"}await t.checkpoint.checkpoint(this.buildPersistedState(t)),t.checkpoint.stop(),this.callbacks.log?.info(`[product] paused ${e}`)}async checkpoint(e){let t=this.sessions.get(e);if(!t)throw new Error(`Product ${e} not found`);await t.checkpoint.checkpoint(this.buildPersistedState(t))}async delete(e){let t=this.sessions.get(e);if(!t)throw new Error(`Product ${e} not found`);if(t.phase==="active"){t.phase="failed",t.dag.pauseAll();for(let r of t.instances)if(r.state==="running"&&r.memberId){try{this.processManager.kill(r.memberId)}catch{}r.state="failed"}}t.checkpoint.stop(),this.sessions.delete(e),this.callbacks.log?.info(`[product] deleted ${e}`)}async rollback(e,t){let r=this.sessions.get(e);if(!r)throw new Error(`Product ${e} not found`);let s=r.cwd;await this.delete(e),await this.resume(e,s),this.callbacks.log?.info(`[product] rolled back ${e} to checkpoint ${t}`)}getStatus(e){let t=this.sessions.get(e);return t?{productId:t.productId,name:t.name,phase:t.phase,instances:t.instances.map(r=>{let o=(r.memberId?this.processManager.getUsageTracker(r.memberId):null)?.getUsage();return{instanceId:r.instanceId,name:r.name,agentId:r.agentId,state:r.state,worktreePath:r.worktreePath,usage:o&&(o.inputTokens>0||o.outputTokens>0)?{inputTokens:o.inputTokens,outputTokens:o.outputTokens}:void 0}}),tasks:t.dag.getAllTasks().map(r=>({taskId:r.taskId,assignee:r.assignee,status:r.status,result:r.result,error:r.error,startedAt:r.startedAt?new Date(r.startedAt).toISOString():void 0,completedAt:r.completedAt?new Date(r.completedAt).toISOString():void 0})),budget:t.budget.getBudget(),lastCheckpointAt:new Date(t.checkpoint.getLastCheckpointAt()||Date.now()).toISOString()}:null}async list(e){let t=[];for(let s of this.sessions.values()){let o=s.dag.getAllTasks();t.push({productId:s.productId,name:s.name,phase:s.phase,instanceCount:s.instances.length,taskCount:o.length,completedTasks:o.filter(i=>i.status==="completed").length,createdAt:s.createdAt,lastCheckpointAt:new Date(s.checkpoint.getLastCheckpointAt()||Date.now()).toISOString()})}let r=await ff(e);for(let s of r)this.sessions.has(s.productId)||t.push({productId:s.productId,name:s.name,phase:s.phase,instanceCount:s.instances.length,taskCount:s.tasks.length,completedTasks:s.tasks.filter(o=>o.status==="completed").length,createdAt:s.createdAt,lastCheckpointAt:s.lastCheckpointAt});return t}scheduleNext(e){if(e.phase!=="active")return;let t=e.budget.check();if(t.action==="exceeded"){this.callbacks.log?.warn(`[product] ${e.productId} budget exceeded, auto-pausing`),this.pause(e.productId).catch(s=>{this.callbacks.log?.warn(`[product] auto-pause failed: ${s instanceof Error?s.message:String(s)}`)});return}if(t.action==="warning"&&this.callbacks.onBudgetWarning?.(e.productId,t.usedTokens,t.maxTotalTokens,t.percentage),e.dag.isFinished()){this.finishProduct(e);return}let r=e.dag.getReadyTasks();for(let s of r)this.dispatchTask(e,s)}dispatchTask(e,t){let r=e.instances.find(s=>s.name===t.assignee);if(!r){e.dag.markFailed(t.taskId,`No instance found for assignee "${t.assignee}"`),this.callbacks.onTaskFailed?.(e.productId,t.taskId,`No instance for "${t.assignee}"`),this.scheduleNext(e);return}e.dag.markRunning(t.taskId),r.state="running",this.callbacks.onTaskStarted?.(e.productId,t.taskId,t.assignee),this.callbacks.log?.info(`[product] ${e.productId} dispatching task ${t.taskId} to ${t.assignee}`),this.runTask(e,r,t).catch(s=>{this.callbacks.log?.warn(`[product] task dispatch error: ${s instanceof Error?s.message:String(s)}`)})}async runTask(e,t,r){let s=`${e.productId}:${t.name}:${r.taskId}`;t.memberId=s;try{let o=this.acpDetector.buildExternalDescriptor(t.agentId);if(!o)throw new Error(`Agent ${t.agentId} is not available`);let i=e.cwd;if(e.gitRoot){let u=`${e.productId}-${t.name}-${r.taskId}`;try{i=await ro(e.gitRoot,u),t.worktreePath=i}catch{this.callbacks.log?.warn(`[product] worktree creation failed for ${r.taskId}, using project cwd`)}}await this.processManager.spawn({memberId:s,name:`product-${t.name}`,cwd:i,prompt:r.prompt,external:o});let a=await this.processManager.sendTask(s,r.prompt),c=typeof a=="string"?a:JSON.stringify(a),l=this.processManager.getUsageTracker(s);if(l?.hasData()){let u=l.getUsage();e.budget.addUsage(u.inputTokens,u.outputTokens);let d=e.budget.getBudget();this.callbacks.onBudgetUpdate?.(e.productId,d.usedTokens,0,d.elapsed,d.maxTotalTokens)}e.dag.markCompleted(r.taskId,c),t.state="completed",this.callbacks.onTaskCompleted?.(e.productId,r.taskId,c);try{this.processManager.kill(s)}catch{}this.processManager.remove(s)}catch(o){let i=o instanceof Error?o.message:String(o);e.dag.markFailed(r.taskId,i),t.state="failed",this.callbacks.onTaskFailed?.(e.productId,r.taskId,i);try{this.processManager.kill(s)}catch{}try{this.processManager.remove(s)}catch{}}try{await e.checkpoint.checkpoint(this.buildPersistedState(e))}catch(o){this.callbacks.log?.warn(`[product] checkpoint failed: ${o instanceof Error?o.message:String(o)}`)}this.scheduleNext(e)}finishProduct(e){if(e.dag.isAllCompleted()){e.phase="completed";let t=e.dag.getAllTasks(),r=`Product "${e.name}" completed: ${t.length} tasks all done.`;this.callbacks.onCompleted?.(e.productId,r)}else{e.phase="failed";let r=e.dag.getAllTasks().filter(i=>i.status==="failed").length,s=e.dag.getBlockedTasks().length,o=`Product "${e.name}" finished with ${r} failed, ${s} blocked tasks.`;this.callbacks.onCompleted?.(e.productId,o)}e.checkpoint.stop(),e.checkpoint.checkpoint(this.buildPersistedState(e)).catch(t=>{this.callbacks.log?.warn(`[product] final checkpoint failed: ${t instanceof Error?t.message:String(t)}`)}),this.callbacks.log?.info(`[product] ${e.productId} finished (phase=${e.phase})`)}buildPersistedState(e){return{productId:e.productId,name:e.name,phase:e.phase,cwd:e.cwd,instances:e.instances.map(t=>({name:t.name,role:"",agentId:t.agentId})),tasks:e.dag.serialize(),budget:e.budget.serialize(),createdAt:e.createdAt,lastCheckpointAt:new Date(e.checkpoint.getLastCheckpointAt()||Date.now()).toISOString()}}};import{randomUUID as kf}from"node:crypto";function $I(n,e){let t=e?`
|
|
749
|
+
`,version:"1.0.0",category:"learned"}),x=zs(v,U.suggestedName);if(x.valid){Nn.mkdirSync(Et,{recursive:!0}),Nn.writeFileSync(g,v,"utf8"),pt();let C=q(),A=Be(C);Bt(A,U.suggestedName,"learned"),We(C,A),this.log(`[skill-auto-persist] Created skill "${U.suggestedName}" from turn ${R.turnId}`)}else this.log(`[skill-auto-persist] Validation failed for "${U.suggestedName}": ${x.errors.join(", ")}`)}}break;case"tool_call":this.sendNotification("turn.tool_call",{turnId:R.turnId,callId:R.callId,name:R.name,arguments:R.arguments,item:{id:R.callId,type:"tool_call",role:"assistant",toolName:R.name,toolCallId:R.callId,arguments:R.arguments,createdAt:B}}),this.sessionState?.recordToolCall();break;case"tool_result":this.sendNotification("turn.tool_result",{turnId:R.turnId,callId:R.callId,name:R.name,ok:R.ok,...R.error?{error:R.error}:{},...R.outputPreview?{outputPreview:R.outputPreview}:{},item:{id:`${R.callId}-result`,type:"tool_result",role:"assistant",toolName:R.name,toolCallId:R.callId,output:R.ok?R.outputPreview??"":R.error,approved:R.ok,createdAt:B}});break;case"tool_blocked":this.sendNotification("turn.tool_blocked",{turnId:R.turnId,callId:R.callId,name:R.name,reason:R.reason,item:{id:`${R.callId}-blocked`,type:"tool_blocked",role:"system",toolName:R.name,toolCallId:R.callId,text:R.reason,approved:!1,createdAt:B}});break;case"recovery":this.sendNotification("turn.recovery",{turnId:R.turnId,action:R.action,...R.detail?{detail:R.detail}:{},item:{id:`${t}-recovery-${to().slice(0,8)}`,type:"recovery",role:"system",strategy:R.action,text:R.detail,createdAt:B}});break;case"plan_update":this.sendNotification("turn.plan_update",{turnId:R.turnId,slug:R.slug,content:R.content,item:{id:`${t}-plan-${to().slice(0,8)}`,type:"plan_update",role:"assistant",text:R.content,createdAt:B}});break;case"reasoning_delta":this.sendNotification("turn.reasoning_delta",{turnId:R.turnId,text:R.text});break;case"suggestions":this.sendNotification("turn.suggestions",{turnId:R.turnId,items:R.items});break;case"media_result":this.sendNotification("turn.media_result",{turnId:R.turnId,mediaType:R.mediaType,url:R.url,...R.model?{model:R.model}:{},...R.provider?{provider:R.provider}:{},...R.taskId?{taskId:R.taskId}:{}});break;case"artifact":this.sendNotification("turn.artifact",{turnId:R.turnId,artifactId:R.artifactId,type:R.artifactType,title:R.title,...R.filePath?{filePath:R.filePath}:{},...R.language?{language:R.language}:{},...R.content?{content:R.content}:{},...R.mimeType?{mimeType:R.mimeType}:{}});break;case"subagent_started":this.sendNotification("turn.subagent_started",{turnId:R.turnId,subagentId:R.subagentId,agentType:R.agentType,...R.prompt?{prompt:R.prompt}:{}});break;case"subagent_ended":this.sendNotification("turn.subagent_ended",{turnId:R.turnId,subagentId:R.subagentId,agentType:R.agentType,ok:R.ok,...R.outputPreview?{outputPreview:R.outputPreview}:{},...R.error?{error:R.error}:{}});break;case"annotations":this.sendNotification("turn.annotations",{turnId:R.turnId,annotations:R.annotations});break;case"heartbeat":this.sendNotification("turn.heartbeat",{turnId:R.turnId,message:R.message});break;case"tool_use_summary":this.sendNotification("turn.tool_use_summary",{turnId:R.turnId,summary:R.summary});break}}if(this.log(`turn ${t} completed`),this.sessionState?.recordTurnCompleted(),this.sessionState){ku(r,this.sessionState.createSnapshot(),{model:this.currentModel,cwd:p,messageCount:s.length},p).catch(()=>{});let R=this.sessionState.createSnapshot();this.sendNotification("session.info",{sessionId:r,model:this.currentModel||void 0,cwd:p,turnCount:R.turnCount,projectId:i?.projectId||void 0});let B=this.resolveClientForPurpose("smallModel");if(B&&Su(r,{sessionId:r,projectId:"",createdAt:"",lastActiveAt:"",turnCount:R.turnCount,messageCount:s.length},s,{transport:B.transport,apiKey:B.apiKey,model:B.model},p),this.generateSuggestions(t,s),this.petAwardXp("turn.end"),this.petReactionAfterTurn(s),i?.sessionType==="group"&&this.sessionState){let U=this.sessionState.createSnapshot(),we=an(r,p);we&&rf({...we,turnCount:U.turnCount},p).then(fe=>{fe.split&&this.sendNotification("session-update",{sessionId:fe.activeSessionId,projectId:i?.projectId??"",title:"",type:"group"})}).catch(()=>{})}}}catch(y){if(m.signal.aborted)this.sendNotification("turn.error",{turnId:t,error:{message:"Turn aborted",code:"ABORTED"}});else{let b=y instanceof Error?y.message:String(y);this.sendNotification("turn.error",{turnId:t,error:{message:b,code:"INTERNAL_ERROR"}})}}finally{this.activeTurn===m&&(this.activeTurn=null),h()}}dt();import{randomUUID as df}from"node:crypto";async function no(n){let e=n.params??{},t=e.turnId??df(),r=e.sessionId,s=e.config,o=s?.memoryRoot??"",i=s?.transcriptDir??"",a=s?.dreamSessionIds??[];n.id!==void 0&&this.sendResponse(n.id,{accepted:!0,turnId:t});let c=new AbortController;this.activeTurn=c,this.log(`dream ${t} starting (session: ${r}, sessions reviewing: ${a.length})`),this.sendNotification("system.activity",{category:"dream",level:"info",title:"\u68A6\u5883\u6574\u7406\u542F\u52A8",detail:`\u6B63\u5728\u56DE\u987E ${a.length} \u4E2A\u4F1A\u8BDD\u7684\u8BB0\u5FC6...`});let l={provider:s?.provider,model:s?.model,apiKey:s?.apiKey,baseUrl:s?.baseUrl,maxRounds:s?.maxRounds,temperature:s?.temperature,contextWindowTokens:s?.contextWindowTokens,maxOutputTokens:s?.maxOutputTokens,modelMaxOutputTokens:s?.modelMaxOutputTokens,reasoning:s?.reasoning,promptCacheKey:s?.promptCacheKey,promptCacheRetention:s?.promptCacheRetention,serviceTier:s?.serviceTier,openaiBuiltinTools:s?.openaiBuiltinTools,maxToolCalls:s?.maxToolCalls,parallelToolCalls:s?.parallelToolCalls,textVerbosity:s?.textVerbosity};{let d=l.provider??"",p=l.model??"";if(d&&p){let m=X().getModelInfo(d,p);m?.streamRequired&&(l.streamRequired=!0),!l.contextWindowTokens&&m?.contextWindow&&(l.contextWindowTokens=m.contextWindow)}}if(!this.resolveAgent(l)){this.sendNotification("turn.start",{turnId:t}),this.sendNotification("turn.error",{turnId:t,error:{message:"No LLM provider configured for dream.",code:"NO_PROVIDER"}});return}this.sendNotification("turn.start",{turnId:t});try{let d={context:{memoryRoot:o,transcriptDir:i,currentSessionId:r,listSessionsSince:async()=>a,currentSessionTurnCount:s?.currentSessionTurnCount??0},triggerConfig:{force:s?.force!==!1},transport:this.currentTransport,toolInvoker:{invoke:async(m,h,f,y)=>{if(h.startsWith("$"))return{result:f};let b=findTool(h);if(!b)return{result:"",error:`Unknown tool: ${h}`};let T=`tc_${df().slice(0,8)}`;try{let w=JSON.parse(f),_=await b.execute(T,w,y);return{result:_.content.map(D=>D.text??"").join(`
|
|
750
|
+
`),error:_.details?.error}}catch(w){return{result:"",error:w instanceof Error?w.message:String(w)}}}},tools:getToolManifest(),apiKey:this.currentApiKey,model:l.model??this.currentModel,log:{info:m=>this.log(m),warn:m=>this.log(`[warn] ${m}`),error:m=>this.log(`[error] ${m}`),debug:m=>{this.verbose&&this.log(`[debug] ${m}`)}},hooks:this.currentHooks??void 0,parentSignal:c.signal,memoryProvider:this.memoryProvider??void 0,memoryUserId:this.memoryUserId||void 0},p=await runDream(d);if(p.ok){if(this.memoryProvider&&this.memoryUserId)try{let m=await runDecayCycle({adapter:this.memoryProvider,userId:this.memoryUserId,memoryRoot:o,log:{info:h=>this.log(h),debug:h=>{this.verbose&&this.log(h)}}});m.ran&&(this.sendNotification("memory.decay.completed",{decayed:m.decayed,archived:m.archived,durationMs:m.durationMs}),this.sendNotification("system.activity",{category:"decay",level:"info",title:"\u8BB0\u5FC6\u8870\u51CF\u5B8C\u6210",detail:`\u8870\u51CF ${m.decayed} \u6761\uFF0C\u5F52\u6863 ${m.archived} \u6761 (${m.durationMs}ms)`}))}catch(m){this.log(`[decay] post-dream decay error: ${m instanceof Error?m.message:String(m)}`)}this.sendNotification("system.activity",{category:"dream",level:"success",title:"\u68A6\u5883\u6574\u7406\u5B8C\u6210",detail:`\u56DE\u987E ${p.sessionsReviewed} \u4E2A\u4F1A\u8BDD\uFF0C\u6574\u7406 ${p.filesTouched.length} \u4E2A\u8BB0\u5FC6\u6587\u4EF6\uFF0C\u8017\u65F6 ${p.durationMs}ms`}),this.sendNotification("turn.end",{turnId:t,content:`Dream consolidation completed. ${p.sessionsReviewed} sessions reviewed, ${p.filesTouched.length} files touched. Duration: ${p.durationMs}ms.`,usage:{inputTokens:0,outputTokens:0}})}else this.sendNotification("system.activity",{category:"dream",level:"error",title:"\u68A6\u5883\u6574\u7406\u5931\u8D25",detail:p.error??"\u672A\u77E5\u9519\u8BEF"}),this.sendNotification("turn.error",{turnId:t,error:{message:p.error??"Dream consolidation failed",code:"DREAM_FAILED"}});this.log(`dream ${t} completed`)}catch(d){if(c.signal.aborted)this.sendNotification("system.activity",{category:"dream",level:"warn",title:"\u68A6\u5883\u6574\u7406\u88AB\u4E2D\u65AD"}),this.sendNotification("turn.error",{turnId:t,error:{message:"Dream aborted",code:"ABORTED"}});else{let p=d instanceof Error?d.message:String(d);this.sendNotification("system.activity",{category:"dream",level:"error",title:"\u68A6\u5883\u6574\u7406\u5F02\u5E38",detail:p}),this.sendNotification("turn.error",{turnId:t,error:{message:p,code:"INTERNAL_ERROR"}})}}finally{this.activeTurn===c&&(this.activeTurn=null)}}import{randomUUID as LI}from"node:crypto";var Ir=class{nodes=new Map;constructor(e){for(let t of e){if(this.nodes.has(t.taskId))throw new Error(`Duplicate task ID: ${t.taskId}`);this.nodes.set(t.taskId,{taskId:t.taskId,assignee:t.assignee,prompt:t.prompt,dependsOn:t.dependsOn??[],status:"pending"})}this.validateDag()}getAllTasks(){return[...this.nodes.values()]}getTask(e){return this.nodes.get(e)}getReadyTasks(){let e=[];for(let t of this.nodes.values()){if(t.status!=="pending")continue;t.dependsOn.every(s=>this.nodes.get(s)?.status==="completed")&&e.push(t)}return e}markRunning(e){let t=this.nodes.get(e);if(!t)throw new Error(`Unknown task: ${e}`);if(t.status!=="pending")throw new Error(`Task ${e} is ${t.status}, cannot start`);t.status="running",t.startedAt=Date.now()}markCompleted(e,t){let r=this.nodes.get(e);if(!r)throw new Error(`Unknown task: ${e}`);if(r.status!=="running")throw new Error(`Task ${e} is ${r.status}, cannot complete`);r.status="completed",r.result=t,r.completedAt=Date.now()}markFailed(e,t){let r=this.nodes.get(e);if(!r)throw new Error(`Unknown task: ${e}`);r.status="failed",r.error=t,r.completedAt=Date.now()}markPaused(e){let t=this.nodes.get(e);if(!t)throw new Error(`Unknown task: ${e}`);t.status==="running"&&(t.status="paused")}resumePaused(e){let t=this.nodes.get(e);if(!t)throw new Error(`Unknown task: ${e}`);t.status==="paused"&&(t.status="pending")}isFinished(){for(let e of this.nodes.values())if(e.status==="running"||e.status==="paused"||e.status==="pending"&&!e.dependsOn.some(r=>this.nodes.get(r)?.status==="failed"))return!1;return!0}isAllCompleted(){return[...this.nodes.values()].every(e=>e.status==="completed")}getBlockedTasks(){return[...this.nodes.values()].filter(e=>e.status!=="pending"?!1:e.dependsOn.some(t=>this.nodes.get(t)?.status==="failed"))}pauseAll(){for(let e of this.nodes.values())e.status==="running"&&(e.status="paused")}resumeAll(){for(let e of this.nodes.values())e.status==="paused"&&(e.status="pending")}serialize(){return[...this.nodes.values()].map(e=>({taskId:e.taskId,assignee:e.assignee,prompt:e.prompt,dependsOn:e.dependsOn,status:e.status,result:e.result,error:e.error,startedAt:e.startedAt,completedAt:e.completedAt}))}restore(e){for(let t of e){let r=this.nodes.get(t.taskId);r&&(r.status=t.status==="running"?"pending":t.status,r.result=t.result,r.error=t.error,r.startedAt=t.startedAt,r.completedAt=t.completedAt)}}addTask(e){if(this.nodes.has(e.taskId))throw new Error(`Task "${e.taskId}" already exists`);for(let r of e.dependsOn??[])if(!this.nodes.has(r))throw new Error(`New task "${e.taskId}" depends on unknown task "${r}"`);let t={taskId:e.taskId,assignee:e.assignee,prompt:e.prompt,dependsOn:e.dependsOn??[],status:"pending"};this.nodes.set(e.taskId,t);try{this.validateDag()}catch(r){throw this.nodes.delete(e.taskId),r}}addTasks(e){let t=[];try{for(let r of e)this.addTask(r),t.push(r.taskId)}catch(r){for(let s of t)this.nodes.delete(s);throw r}}removeTask(e){let t=this.nodes.get(e);if(!t)throw new Error(`Unknown task: ${e}`);if(t.status==="running")throw new Error(`Cannot remove running task "${e}"`);if(t.status==="completed")throw new Error(`Cannot remove completed task "${e}"`);for(let r of this.nodes.values()){let s=r.dependsOn.indexOf(e);s!==-1&&r.dependsOn.splice(s,1)}this.nodes.delete(e)}retryTask(e,t){let r=this.nodes.get(e);if(!r)throw new Error(`Unknown task: ${e}`);if(r.status!=="failed")throw new Error(`Task "${e}" is ${r.status}, only failed tasks can be retried`);r.status="pending",r.error=void 0,r.result=void 0,r.startedAt=void 0,r.completedAt=void 0,t&&(r.prompt=t)}updateTaskPrompt(e,t){let r=this.nodes.get(e);if(!r)throw new Error(`Unknown task: ${e}`);if(r.status!=="pending")throw new Error(`Task "${e}" is ${r.status}, can only update pending tasks`);r.prompt=t}reassignTask(e,t){let r=this.nodes.get(e);if(!r)throw new Error(`Unknown task: ${e}`);if(r.status!=="pending")throw new Error(`Task "${e}" is ${r.status}, can only reassign pending tasks`);r.assignee=t}addDependency(e,t){let r=this.nodes.get(e);if(!r)throw new Error(`Unknown task: ${e}`);if(!this.nodes.has(t))throw new Error(`Unknown dependency task: ${t}`);if(!r.dependsOn.includes(t)){r.dependsOn.push(t);try{this.validateDag()}catch(s){throw r.dependsOn.pop(),s}}}getProgress(){let e=0,t=0,r=0,s=0,o=0;for(let i of this.nodes.values())switch(i.status){case"completed":e++;break;case"running":t++;break;case"failed":r++;break;case"pending":s++;break;case"paused":o++;break}return{total:this.nodes.size,completed:e,running:t,failed:r,pending:s,paused:o}}validateDag(){for(let s of this.nodes.values())for(let o of s.dependsOn)if(!this.nodes.has(o))throw new Error(`Task "${s.taskId}" depends on unknown task "${o}"`);let e=new Set,t=new Set,r=s=>{if(t.has(s))throw new Error(`Cycle detected involving task "${s}"`);if(e.has(s))return;t.add(s);let o=this.nodes.get(s);for(let i of o.dependsOn)r(i);t.delete(s),e.add(s)};for(let s of this.nodes.keys())r(s)}};var _r=class{maxTotalTokens;maxDuration;usedTokens=0;startedAt;warningEmitted=!1;constructor(e){this.maxTotalTokens=e?.maxTotalTokens,this.maxDuration=e?.maxDuration,this.startedAt=Date.now()}addUsage(e,t){this.usedTokens+=e+t}addFromTracker(e){if(!e.hasData())return;let t=e.getUsage();this.usedTokens+=t.totalTokens}getElapsed(){return Date.now()-this.startedAt}getBudget(){return{maxTotalTokens:this.maxTotalTokens,maxDuration:this.maxDuration,usedTokens:this.usedTokens,elapsed:this.getElapsed()}}check(){let e=this.getElapsed();if(this.maxDuration&&e>=this.maxDuration)return{action:"exceeded",percentage:Math.round(e/this.maxDuration*100),usedTokens:this.usedTokens,maxTotalTokens:this.maxTotalTokens,elapsed:e,maxDuration:this.maxDuration};if(this.maxTotalTokens){let r=Math.round(this.usedTokens/this.maxTotalTokens*100);if(this.usedTokens>=this.maxTotalTokens)return{action:"exceeded",percentage:r,usedTokens:this.usedTokens,maxTotalTokens:this.maxTotalTokens,elapsed:e,maxDuration:this.maxDuration};if(r>=80&&!this.warningEmitted)return this.warningEmitted=!0,{action:"warning",percentage:r,usedTokens:this.usedTokens,maxTotalTokens:this.maxTotalTokens,elapsed:e,maxDuration:this.maxDuration}}return{action:"ok",percentage:this.maxTotalTokens?Math.round(this.usedTokens/this.maxTotalTokens*100):0,usedTokens:this.usedTokens,maxTotalTokens:this.maxTotalTokens,elapsed:e,maxDuration:this.maxDuration}}restore(e){this.usedTokens=e.usedTokens,this.startedAt=e.startedAt,this.warningEmitted=e.warningEmitted}serialize(){return{usedTokens:this.usedTokens,startedAt:this.startedAt,warningEmitted:this.warningEmitted}}};import{join as Gc}from"node:path";import{mkdir as CI,readdir as EI}from"node:fs/promises";ae();function uf(n){return Gc(Me(n),"products")}function pf(n,e){return Gc(uf(e),n)}function mf(n,e){return Gc(pf(n,e),"product-state.json")}async function gf(n,e){let t=pf(n.productId,e);await CI(t,{recursive:!0}),await En(mf(n.productId,e),n)}async function Kc(n,e){return pn(mf(n,e))}async function ff(n){let e=uf(n),t;try{t=await EI(e)}catch{return[]}let r=[];for(let s of t){let o=await Kc(s,n);o&&r.push(o)}return r}var Cr=class n{constructor(e={}){this.callbacks=e}callbacks;static DEFAULT_INTERVAL=5*6e4;static LONG_RUNNING_INTERVAL=30*6e4;static LONG_RUNNING_THRESHOLD=2880*6e4;timer=null;lastCheckpointAt=0;cwd;start(e){this.cwd=e,this.stop(),this.timer=setInterval(()=>{let t=this.callbacks.getState?.();t&&this.checkpoint(t).catch(r=>{this.callbacks.log?.warn(`[checkpoint] periodic save failed: ${r instanceof Error?r.message:String(r)}`)})},n.DEFAULT_INTERVAL),this.timer.unref()}stop(){this.timer&&(clearInterval(this.timer),this.timer=null)}getInterval(e){return e>n.LONG_RUNNING_THRESHOLD?n.LONG_RUNNING_INTERVAL:n.DEFAULT_INTERVAL}isDue(e){if(this.lastCheckpointAt===0)return!0;let t=this.getInterval(e);return Date.now()-this.lastCheckpointAt>=t}async checkpoint(e){let t=new Date().toISOString();e.lastCheckpointAt=t,await gf(e,this.cwd),this.lastCheckpointAt=Date.now(),this.callbacks.onCheckpoint?.(e.productId,t),this.callbacks.log?.info(`[checkpoint] saved ${e.productId} at ${t}`)}getLastCheckpointAt(){return this.lastCheckpointAt}};import{execFile as MI}from"node:child_process";import{promisify as DI}from"node:util";import{join as hf}from"node:path";import{mkdir as NI,rm as OI}from"node:fs/promises";var On=DI(MI);async function Er(n){try{let{stdout:e}=await On("git",["rev-parse","--show-toplevel"],{cwd:n,encoding:"utf8"});return e.trim()}catch{return null}}async function ro(n,e,t){let r=hf(n,".worktrees");await NI(r,{recursive:!0});let s=hf(r,e),i=["worktree","add","-B",`solo/${e}`,s];return t?i.push(t):i.push("HEAD"),await On("git",i,{cwd:n,encoding:"utf8"}),s}async function Vc(n){try{await On("git",["add","-A"],{cwd:n});let{stdout:e}=await On("git",["diff","--cached","--stat"],{cwd:n,encoding:"utf8"});return e.trim()}catch{return""}}async function yf(n,e){try{await On("git",["worktree","remove","--force",e],{cwd:n,encoding:"utf8"})}catch{try{await OI(e,{recursive:!0,force:!0})}catch{}}}async function bf(n,e){let{stdout:t}=await On("git",["merge","--no-ff",e,"-m",`solo: merge ${e}`],{cwd:n,encoding:"utf8"});return t.trim()}var so=class{constructor(e,t,r,s={}){this.processManager=e;this.acpDetector=t;this.configStore=r;this.callbacks=s}processManager;acpDetector;configStore;callbacks;sessions=new Map;async create(e){let{name:t,cwd:r,instances:s,tasks:o,budget:i}=e;if(s.length===0)throw new Error("Product requires at least 1 instance");if(o.length===0)throw new Error("Product requires at least 1 task");let a=new Set(s.map(b=>b.name));for(let b of o)if(!a.has(b.assignee))throw new Error(`Task "${b.taskId}" references unknown instance "${b.assignee}"`);let c=`product-${LI().slice(0,8)}`,l=new Ir(o),u=new _r(i),d=new Cr({onCheckpoint:(b,T)=>this.callbacks.onCheckpointed?.(b,T),getState:()=>{let b=this.sessions.get(c);return b?this.buildPersistedState(b):null},log:this.callbacks.log}),p=await Er(r),m=s.map((b,T)=>({instanceId:`${c}:${b.name}:${T}`,name:b.name,agentId:b.agentId,state:"idle"})),h={productId:c,name:t,cwd:r,phase:"active",instances:m,dag:l,budget:u,checkpoint:d,createdAt:new Date().toISOString(),gitRoot:p};this.sessions.set(c,h),d.start(r),this.callbacks.log?.info(`[product] created ${c} "${t}" with ${s.length} instances, ${o.length} tasks`);let f=o.map(b=>({id:b.taskId,label:b.taskId,deps:b.dependsOn??[]})),y=[];for(let b of o)if(b.dependsOn)for(let T of b.dependsOn)y.push({from:T,to:b.taskId});return this.callbacks.onDagTopology?.(c,f,y),setTimeout(()=>this.scheduleNext(h),0),c}async resume(e,t){let r=await Kc(e,t);if(!r)throw new Error(`Product ${e} not found on disk`);let s=new Ir(r.tasks);s.restore(r.tasks);let o=new _r({maxTotalTokens:r.budget.maxTotalTokens,maxDuration:r.budget.maxDuration});o.restore(r.budget);let i=new Cr({onCheckpoint:(u,d)=>this.callbacks.onCheckpointed?.(u,d),getState:()=>{let u=this.sessions.get(e);return u?this.buildPersistedState(u):null},log:this.callbacks.log}),a=await Er(r.cwd),c=r.instances.map((u,d)=>({instanceId:`${e}:${u.name}:${d}`,name:u.name,agentId:u.agentId,state:"idle"})),l={productId:r.productId,name:r.name,cwd:r.cwd,phase:"active",instances:c,dag:s,budget:o,checkpoint:i,createdAt:r.createdAt,gitRoot:a};this.sessions.set(e,l),i.start(r.cwd),this.callbacks.log?.info(`[product] resumed ${e}`),this.scheduleNext(l)}async pause(e){let t=this.sessions.get(e);if(!t)throw new Error(`Product ${e} not found`);if(t.phase!=="active")throw new Error(`Product ${e} is not active`);t.phase="paused",t.dag.pauseAll();for(let r of t.instances)if(r.state==="running"&&r.memberId){try{this.processManager.kill(r.memberId)}catch{}r.state="paused"}await t.checkpoint.checkpoint(this.buildPersistedState(t)),t.checkpoint.stop(),this.callbacks.log?.info(`[product] paused ${e}`)}async checkpoint(e){let t=this.sessions.get(e);if(!t)throw new Error(`Product ${e} not found`);await t.checkpoint.checkpoint(this.buildPersistedState(t))}async delete(e){let t=this.sessions.get(e);if(!t)throw new Error(`Product ${e} not found`);if(t.phase==="active"){t.phase="failed",t.dag.pauseAll();for(let r of t.instances)if(r.state==="running"&&r.memberId){try{this.processManager.kill(r.memberId)}catch{}r.state="failed"}}t.checkpoint.stop(),this.sessions.delete(e),this.callbacks.log?.info(`[product] deleted ${e}`)}async rollback(e,t){let r=this.sessions.get(e);if(!r)throw new Error(`Product ${e} not found`);let s=r.cwd;await this.delete(e),await this.resume(e,s),this.callbacks.log?.info(`[product] rolled back ${e} to checkpoint ${t}`)}getStatus(e){let t=this.sessions.get(e);return t?{productId:t.productId,name:t.name,phase:t.phase,instances:t.instances.map(r=>{let o=(r.memberId?this.processManager.getUsageTracker(r.memberId):null)?.getUsage();return{instanceId:r.instanceId,name:r.name,agentId:r.agentId,state:r.state,worktreePath:r.worktreePath,usage:o&&(o.inputTokens>0||o.outputTokens>0)?{inputTokens:o.inputTokens,outputTokens:o.outputTokens}:void 0}}),tasks:t.dag.getAllTasks().map(r=>({taskId:r.taskId,assignee:r.assignee,status:r.status,result:r.result,error:r.error,startedAt:r.startedAt?new Date(r.startedAt).toISOString():void 0,completedAt:r.completedAt?new Date(r.completedAt).toISOString():void 0})),budget:t.budget.getBudget(),lastCheckpointAt:new Date(t.checkpoint.getLastCheckpointAt()||Date.now()).toISOString()}:null}async list(e){let t=[];for(let s of this.sessions.values()){let o=s.dag.getAllTasks();t.push({productId:s.productId,name:s.name,phase:s.phase,instanceCount:s.instances.length,taskCount:o.length,completedTasks:o.filter(i=>i.status==="completed").length,createdAt:s.createdAt,lastCheckpointAt:new Date(s.checkpoint.getLastCheckpointAt()||Date.now()).toISOString()})}let r=await ff(e);for(let s of r)this.sessions.has(s.productId)||t.push({productId:s.productId,name:s.name,phase:s.phase,instanceCount:s.instances.length,taskCount:s.tasks.length,completedTasks:s.tasks.filter(o=>o.status==="completed").length,createdAt:s.createdAt,lastCheckpointAt:s.lastCheckpointAt});return t}scheduleNext(e){if(e.phase!=="active")return;let t=e.budget.check();if(t.action==="exceeded"){this.callbacks.log?.warn(`[product] ${e.productId} budget exceeded, auto-pausing`),this.pause(e.productId).catch(s=>{this.callbacks.log?.warn(`[product] auto-pause failed: ${s instanceof Error?s.message:String(s)}`)});return}if(t.action==="warning"&&this.callbacks.onBudgetWarning?.(e.productId,t.usedTokens,t.maxTotalTokens,t.percentage),e.dag.isFinished()){this.finishProduct(e);return}let r=e.dag.getReadyTasks();for(let s of r)this.dispatchTask(e,s)}dispatchTask(e,t){let r=e.instances.find(s=>s.name===t.assignee);if(!r){e.dag.markFailed(t.taskId,`No instance found for assignee "${t.assignee}"`),this.callbacks.onTaskFailed?.(e.productId,t.taskId,`No instance for "${t.assignee}"`),this.scheduleNext(e);return}e.dag.markRunning(t.taskId),r.state="running",this.callbacks.onTaskStarted?.(e.productId,t.taskId,t.assignee),this.callbacks.log?.info(`[product] ${e.productId} dispatching task ${t.taskId} to ${t.assignee}`),this.runTask(e,r,t).catch(s=>{this.callbacks.log?.warn(`[product] task dispatch error: ${s instanceof Error?s.message:String(s)}`)})}async runTask(e,t,r){let s=`${e.productId}:${t.name}:${r.taskId}`;t.memberId=s;try{let o=this.acpDetector.buildExternalDescriptor(t.agentId);if(!o)throw new Error(`Agent ${t.agentId} is not available`);let i=e.cwd;if(e.gitRoot){let u=`${e.productId}-${t.name}-${r.taskId}`;try{i=await ro(e.gitRoot,u),t.worktreePath=i}catch{this.callbacks.log?.warn(`[product] worktree creation failed for ${r.taskId}, using project cwd`)}}await this.processManager.spawn({memberId:s,name:`product-${t.name}`,cwd:i,prompt:r.prompt,external:o});let a=await this.processManager.sendTask(s,r.prompt),c=typeof a=="string"?a:JSON.stringify(a),l=this.processManager.getUsageTracker(s);if(l?.hasData()){let u=l.getUsage();e.budget.addUsage(u.inputTokens,u.outputTokens);let d=e.budget.getBudget();this.callbacks.onBudgetUpdate?.(e.productId,d.usedTokens,0,d.elapsed,d.maxTotalTokens)}e.dag.markCompleted(r.taskId,c),t.state="completed",this.callbacks.onTaskCompleted?.(e.productId,r.taskId,c);try{this.processManager.kill(s)}catch{}this.processManager.remove(s)}catch(o){let i=o instanceof Error?o.message:String(o);e.dag.markFailed(r.taskId,i),t.state="failed",this.callbacks.onTaskFailed?.(e.productId,r.taskId,i);try{this.processManager.kill(s)}catch{}try{this.processManager.remove(s)}catch{}}try{await e.checkpoint.checkpoint(this.buildPersistedState(e))}catch(o){this.callbacks.log?.warn(`[product] checkpoint failed: ${o instanceof Error?o.message:String(o)}`)}this.scheduleNext(e)}finishProduct(e){if(e.dag.isAllCompleted()){e.phase="completed";let t=e.dag.getAllTasks(),r=`Product "${e.name}" completed: ${t.length} tasks all done.`;this.callbacks.onCompleted?.(e.productId,r)}else{e.phase="failed";let r=e.dag.getAllTasks().filter(i=>i.status==="failed").length,s=e.dag.getBlockedTasks().length,o=`Product "${e.name}" finished with ${r} failed, ${s} blocked tasks.`;this.callbacks.onCompleted?.(e.productId,o)}e.checkpoint.stop(),e.checkpoint.checkpoint(this.buildPersistedState(e)).catch(t=>{this.callbacks.log?.warn(`[product] final checkpoint failed: ${t instanceof Error?t.message:String(t)}`)}),this.callbacks.log?.info(`[product] ${e.productId} finished (phase=${e.phase})`)}buildPersistedState(e){return{productId:e.productId,name:e.name,phase:e.phase,cwd:e.cwd,instances:e.instances.map(t=>({name:t.name,role:"",agentId:t.agentId})),tasks:e.dag.serialize(),budget:e.budget.serialize(),createdAt:e.createdAt,lastCheckpointAt:new Date(e.checkpoint.getLastCheckpointAt()||Date.now()).toISOString()}}};import{randomUUID as kf}from"node:crypto";function $I(n,e){let t=e?`
|
|
751
751
|
|
|
752
752
|
Budget constraints: ${e.maxTotalTokens?`max ${e.maxTotalTokens} total tokens`:""}${e.maxDuration?` / max ${Math.round(e.maxDuration/6e4)} minutes`:""}`:"";return`You are a team leader agent managing a software development project.
|
|
753
753
|
|
|
@@ -826,7 +826,7 @@ ${o.memory.join(`
|
|
|
826
826
|
|
|
827
827
|
`)}
|
|
828
828
|
|
|
829
|
-
${t}`)}let c=`solo-${HI().slice(0,8)}`,l={soloId:c,state:"running",task:t,cwd:s,gitRoot:i,agents:[],createdAt:Date.now()};this.sessions.set(c,l),this.persistSession(l),this.callbacks.log?.info(`[solo] starting ${c} with ${r.length} agents`);let u=r.map(async(p,m)=>{let h=`${c}-${p}-${m}`,f=`solo/${h}`,y=`${c}:${p}:${m}`,b;try{b=await ro(i,h)}catch(w){this.callbacks.log?.warn(`[solo] worktree creation failed for ${p}: ${w instanceof Error?w.message:String(w)}`);let _={agentId:p,memberId:y,worktreePath:"",worktreeBranch:f,state:"failed",error:`Worktree creation failed: ${w instanceof Error?w.message:String(w)}`,turns:[]};l.agents.push(_);return}let
|
|
829
|
+
${t}`)}let c=`solo-${HI().slice(0,8)}`,l={soloId:c,state:"running",task:t,cwd:s,gitRoot:i,agents:[],createdAt:Date.now()};this.sessions.set(c,l),this.persistSession(l),this.callbacks.log?.info(`[solo] starting ${c} with ${r.length} agents`);let u=r.map(async(p,m)=>{let h=`${c}-${p}-${m}`,f=`solo/${h}`,y=`${c}:${p}:${m}`,b;try{b=await ro(i,h)}catch(w){this.callbacks.log?.warn(`[solo] worktree creation failed for ${p}: ${w instanceof Error?w.message:String(w)}`);let _={agentId:p,memberId:y,worktreePath:"",worktreeBranch:f,state:"failed",error:`Worktree creation failed: ${w instanceof Error?w.message:String(w)}`,turns:[]};l.agents.push(_);return}let T={agentId:p,memberId:y,worktreePath:b,worktreeBranch:f,state:"pending",turns:[]};l.agents.push(T);try{T.state="running",this.callbacks.onProgress?.(c,p,"running");let w=this.acpDetector.buildExternalDescriptor(p);if(!w)throw new Error(`Agent ${p} is not available or not ACP-compatible`);await this.processManager.spawn({memberId:y,name:`solo-${p}`,cwd:b,prompt:a,external:w});let _=this.processManager.getHandle(y);if(!_||_.state!=="ready")throw new Error(`Agent ${p} spawn did not reach ready state`);let I=await this.processManager.sendTask(y,a);T.state="completed",T.resultText=typeof I=="string"?I:JSON.stringify(I),T.diff=await Vc(b),T.turns.push({role:"user",content:t,timestamp:Date.now()}),T.turns.push({role:"agent",content:T.resultText,timestamp:Date.now()});let D=this.processManager.getUsageTracker(y);if(D?.hasData()){let L=D.getUsage();T.usage={inputTokens:L.inputTokens,outputTokens:L.outputTokens}}this.callbacks.onProgress?.(c,p,"completed"),T.diff&&this.callbacks.onAgentDiff?.(c,p,[{path:".",hunks:T.diff}]),T.usage&&this.callbacks.onAgentUsage?.(c,p,T.usage.inputTokens,T.usage.outputTokens),this.callbacks.log?.info(`[solo] ${p} completed (diff: ${T.diff?"yes":"none"})`)}catch(w){T.state="failed",T.error=w instanceof Error?w.message:String(w),this.callbacks.onProgress?.(c,p,"failed",T.error),this.callbacks.log?.warn(`[solo] ${p} failed: ${T.error}`)}});await Promise.allSettled(u);let d=l.agents.filter(p=>p.state==="completed");if(d.length===0)return l.state="failed",this.persistSession(l),this.callbacks.log?.warn(`[solo] all agents failed for ${c}`),c;for(let p of l.agents)p.state==="completed"&&(p.state="idle");return this.persistSession(l),this.callbacks.log?.info(`[solo] ${d.length}/${l.agents.length} agents ready for interaction`),c}async message(e,t,r,s){let o=this.sessions.get(e);if(!o)throw new Error(`Solo session ${e} not found`);if(o.state!=="running")throw new Error(`Solo session ${e} is not active (state: ${o.state})`);let i=o.agents.filter(l=>l.agentId===t),a=s!==void 0?i[s]:i[0];if(!a)throw new Error(`Agent ${t} not found in solo session ${e}`);if(!["idle","completed"].includes(a.state))throw new Error(`Agent ${t} is not ready for messages (state: ${a.state})`);a.turns.push({role:"user",content:r,timestamp:Date.now()}),a.state="running",this.callbacks.onProgress?.(e,t,"running");try{let l=await this.processManager.sendTask(a.memberId,r),u=typeof l=="string"?l:l?.content??JSON.stringify(l);a.turns.push({role:"agent",content:u,timestamp:Date.now()}),a.resultText=u,a.diff=await Vc(a.worktreePath),a.state="idle";let d=this.processManager.getUsageTracker(a.memberId);if(d?.hasData()){let p=d.getUsage();a.usage={inputTokens:p.inputTokens,outputTokens:p.outputTokens}}return this.callbacks.onProgress?.(e,t,"idle"),this.persistSession(o),{resultText:u}}catch(l){throw a.state="failed",a.error=l instanceof Error?l.message:String(l),this.callbacks.onProgress?.(e,t,"failed",a.error),this.persistSession(o),l}}async triggerEvaluation(e,t,r){let s=this.sessions.get(e);if(!s)throw new Error(`Solo session ${e} not found`);let o=s.agents.filter(c=>c.state==="completed"||c.state==="idle");if(o.length===0)throw new Error(`No agents have completed work in session ${e}`);let i=s.agents.filter(c=>c.agentId===t),a=r!==void 0?i[r]:i[0];if(!a)throw new Error(`Evaluator agent ${t} not found in session ${e}`);if(a.state!=="idle"&&a.state!=="completed")throw new Error(`Evaluator agent ${t} is not ready (state: ${a.state})`);s.state="evaluating",this.callbacks.log?.info(`[solo] user-triggered evaluation for ${e} by ${t} (${o.length} candidates)`);try{let c=await this.evaluate(s,o,a);return s.evaluation=c,s.state="running",this.callbacks.onEvaluation?.(e,c),this.persistSession(s),c}catch(c){throw s.state="running",this.persistSession(s),new Error(`Evaluation failed: ${c instanceof Error?c.message:String(c)}`)}}getStatus(e){let t=this.sessions.get(e);return t?{soloId:t.soloId,state:t.state,agents:t.agents.map(r=>({id:r.agentId,state:r.state,progress:r.state==="running"?"Working...":void 0,resultText:r.resultText,diff:r.diff,usage:r.usage,error:r.error,worktreePath:r.worktreePath})),evaluation:t.evaluation}:null}async cancel(e){let t=this.sessions.get(e);if(!t)throw new Error(`Solo session ${e} not found`);if(t.state!=="running"&&t.state!=="evaluating")throw new Error(`Solo session ${e} is not running (state: ${t.state})`);t.state="cancelled";for(let r of t.agents)if(r.state==="running"||r.state==="pending"||r.state==="idle"){r.state="failed",r.error="Cancelled by user";try{this.processManager.kill(r.memberId)}catch{}}await this.cleanupWorktrees(t),this.callbacks.log?.info(`[solo] cancelled ${e}`)}async select(e){let t=this.sessions.get(e.soloId);if(!t)throw new Error(`Solo session ${e.soloId} not found`);if(t.state!=="completed"&&t.state!=="running")throw new Error(`Solo session ${e.soloId} is not ready for selection (state: ${t.state})`);let r=t.agents.find(o=>o.agentId===e.winnerId&&(o.state==="completed"||o.state==="idle"));if(!r)throw new Error(`Agent ${e.winnerId} is not a completed participant in ${e.soloId}`);let s=await bf(t.gitRoot,r.worktreeBranch);return this.callbacks.log?.info(`[solo] merged ${r.worktreeBranch}: ${s}`),t.state="completed",await this.cleanupWorktrees(t),this.persistSession(t),r.worktreeBranch}listSessions(){return[...this.sessions.values()].map(e=>this.getStatus(e.soloId))}async delete(e){let t=this.sessions.get(e);if(!t)throw new Error(`Solo session ${e} not found`);if(t.state==="running"||t.state==="evaluating"){t.state="cancelled";for(let r of t.agents)if(r.state==="running"||r.state==="pending"||r.state==="idle"){r.state="failed",r.error="Deleted";try{this.processManager.kill(r.memberId)}catch{}}await this.cleanupWorktrees(t)}this.sessions.delete(e),await Jc(e,t?.cwd),this.callbacks.log?.info(`[solo] deleted ${e}`)}async evaluate(e,t,r){if(t.length===1)return{winnerId:t[0].agentId,reasoning:`Only one agent (${t[0].agentId}) completed successfully.`};let s=["# Task Evaluation","","## Original Task",e.task,"","## Agent Results",""];for(let a of t)s.push(`### Agent: ${a.agentId}`,"","**Result:**",a.resultText??"(no output)","","**Changes (git diff stat):**",a.diff||"(no changes)","");s.push("## Instructions","","Review all agent results above. Select the best implementation and explain your reasoning.","Respond in this exact format:","","WINNER: <agent-id>","REASONING: <your explanation>");let o=s.join(`
|
|
830
830
|
`),i=r.memberId;try{let a=await this.processManager.sendTask(i,o),c=typeof a=="string"?a:JSON.stringify(a);return this.parseEvaluationResponse(c,t)}catch{return{winnerId:t[0].agentId,reasoning:"Evaluation failed; defaulting to first completed agent."}}}parseEvaluationResponse(e,t){let r=e.match(/WINNER:\s*(\S+)/i),s=e.match(/REASONING:\s*(.+)/is),o=t.map(a=>a.agentId),i=r?.[1];if(i&&o.includes(i))return{winnerId:i,reasoning:s?.[1]?.trim()||"Selected by leader evaluation."};for(let a of o)if(e.includes(a))return{winnerId:a,reasoning:s?.[1]?.trim()||e.slice(0,500)};return{winnerId:t[0].agentId,reasoning:`Could not parse evaluation. Full response: ${e.slice(0,500)}`}}async cleanupWorktrees(e){for(let t of e.agents)if(t.worktreePath)try{try{this.processManager.kill(t.memberId)}catch{}this.processManager.remove(t.memberId),await yf(e.gitRoot,t.worktreePath)}catch(r){this.callbacks.log?.warn(`[solo] failed to clean worktree for ${t.agentId}: ${r instanceof Error?r.message:String(r)}`)}}};ae();function Ye(){if(!this.soloEvaluator){let n=new _t({log:{info:t=>process.stderr.write(`[solo:pm] ${t}
|
|
831
831
|
`),warn:t=>process.stderr.write(`[solo:pm] WARN ${t}
|
|
832
832
|
`)},onNotification:(t,r,s)=>{(r==="agents.error"||r==="agents.status")&&this.sendNotification(r,s),this.sendNotification("team.member.notification",{memberId:t,method:r,params:s})},onStateChange:(t,r)=>{let s=n.getHandle(t),i=n.getUsageTracker(t)?.getUsage();this.emitAgentStatus(t,r,{missedBeats:n.getMissedBeats(t),lastActivityAt:s?.lastActivityAt,usage:i&&i.totalTokens>0?{inputTokens:i.inputTokens,outputTokens:i.outputTokens,totalTokens:i.totalTokens}:void 0})},onMcpToolCall:(t,r,s)=>this.handleMcpToolCall(t,r,s),sessionDir:eh.join(q(),"agent-logs")}),e={log:{info:t=>process.stderr.write(`${t}
|
|
@@ -849,7 +849,7 @@ ${c||"(\u65E0)"}`].join(`
|
|
|
849
849
|
`),u="";try{for await(let h of s.transport.stream({model:s.model,messages:[{role:"user",content:l}],temperature:.1,maxTokens:900,tools:[]},s.apiKey))h.type==="delta"&&(u+=h.text)}catch{return null}let d=WI(u),m=(Array.isArray(d?.memories)?d.memories:[]).map(h=>({id:`candidate-${Bh()}`,text:typeof h?.text=="string"?h.text.trim().slice(0,1400):"",category:lo(h?.category),importance:Dr(h?.importance,.1,1,.65),confidence:Dr(h?.confidence,.05,1,.65),source:typeof h?.source=="string"&&h.source.trim()?h.source.trim().slice(0,80):"manual",eventDate:typeof h?.eventDate=="string"?h.eventDate.trim().slice(0,32):"",tags:uo(h?.tags),relatedMemoryIds:Array.isArray(h?.relatedMemoryIds)?h.relatedMemoryIds.filter(f=>typeof f=="string").slice(0,8):[],evidence:[...o?[{type:"text",excerpt:o.slice(0,500)}]:[],...i.map(f=>({type:f.type,filename:f.filename,mimeType:f.mimeType}))],requiresConfirmation:h?.requiresConfirmation!==!1,reason:typeof h?.reason=="string"?h.reason.trim().slice(0,300):""})).filter(h=>h.text.length>=6);return m.length>0?m:null}async function Hh(n,e,t){let r=typeof e?.text=="string"?e.text.trim():"",s=Array.isArray(e?.attachments)?e.attachments.map(Zc):[],o=await GI(n,[r,...s.map(el)].join(`
|
|
850
850
|
`),t),i=e?.autoExtract===!1?null:await VI(n,e,o);return{candidates:i??KI(e,o),relatedMemories:o,extractor:i?"llm":"deterministic"}}async function qh(n,e,t){let r=0;for(let s of t){let o=typeof s?.text=="string"?s.text.trim():"";if(!o)continue;let i=uo([...s.tags??[],...(s.relatedMemoryIds??[]).map(c=>`related:${c}`)]),a={text:o,category:lo(s.category),importance:Dr(s.importance,.1,1,.6),event_date:typeof s.eventDate=="string"?s.eventDate:"",tags:i};if(typeof n.memoryProvider.ingestExtracted=="function"){let c=await n.memoryProvider.ingestExtracted([a],e,{source:typeof s.source=="string"&&s.source.trim()?s.source.trim():"manual"});r+=c?.memoriesAdded??0}else{let c=await n.memoryProvider.addText(o,e,{category:a.category,importance:a.importance,source:typeof s.source=="string"&&s.source.trim()?s.source.trim():"manual",tags:i});r+=c?.memoriesAdded??0}}return r}function Ln(n,e){let r=(typeof e=="string"&&e.trim()?e:typeof n.memoryUserId=="string"&&n.memoryUserId.trim()?n.memoryUserId:"").trim();return r||null}function Fh(){return{totalCount:0,records:[],buckets:[],clusters:[],windowCursor:null,timeRange:null,stats:{formed:0,insights:0,preferences:0}}}function zI(n,e){let t=0,r=0;for(let s of e??[])s?.kind==="category"&&((s.label==="insight"||s.label==="lesson")&&(t+=Number(s.count??0)),s.label==="preference"&&(r+=Number(s.count??0)));return{formed:n,insights:t,preferences:r}}async function Wh(n){let e=[];this.memdir&&e.push({id:"memdir",type:"file",path:xc(this.getActiveProjectRoot())}),this.memoryProvider&&e.push({id:"local",type:"vector"}),n.id!==void 0&&this.sendResponse(n.id,{sources:e})}async function Gh(n){let e=n.params;if(this.ensureMemoryProvider?.(),!this.memoryProvider||typeof this.memoryProvider.getAtlas!="function"){n.id!==void 0&&this.sendResponse(n.id,Fh());return}try{let t=Ln(this,e?.userId);if(!t){n.id!==void 0&&this.sendResponse(n.id,Fh());return}let r=this.memoryProvider.getAtlas(t,{pageSize:e?.pageSize??360,windowStartAt:e?.windowStartAt,windowEndAt:e?.windowEndAt,windowCenterAt:e?.windowCenterAt,bucketCount:e?.bucketCount??96,clusterLimit:e?.clusterLimit??48,activeOnly:!0}),s=(r.records??[]).map(a=>({id:a.id,text:a.text,category:a.category,importance:a.importance,confidence:a.confidence,source:a.source,sessionId:a.sessionId,eventDate:a.eventDate,tags:a.tags,createdAt:a.createdAt,updatedAt:a.updatedAt,accessCount:a.accessCount,lastAccessedAt:a.lastAccessedAt,isArchived:a.isArchived})),o=Number(r.totalCount??s.length),i=r.clusters??[];n.id!==void 0&&this.sendResponse(n.id,{totalCount:o,records:s,buckets:r.buckets??[],clusters:i,windowCursor:r.windowCursor??null,timeRange:r.timeRange??null,stats:zI(o,i)})}catch(t){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:k.INTERNAL_ERROR,message:t instanceof Error?t.message:String(t)})}}async function Kh(n){let e=n.params;if(this.ensureMemoryProvider?.(),!this.memoryProvider||typeof this.memoryProvider.getActivitySummary!="function"){n.id!==void 0&&this.sendResponse(n.id,{dailyCounts:[],highlights:[]});return}try{let t=Ln(this,e?.userId);if(!t){n.id!==void 0&&this.sendResponse(n.id,{dailyCounts:[],highlights:[]});return}let r=this.memoryProvider.getActivitySummary(t,e?.days??180);n.id!==void 0&&this.sendResponse(n.id,r)}catch(t){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:k.INTERNAL_ERROR,message:t instanceof Error?t.message:String(t)})}}async function Vh(n){let e=n.params;if(this.ensureMemoryProvider?.(),!this.memoryProvider||typeof this.memoryProvider.addText!="function"){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:k.INTERNAL_ERROR,message:"Long-term memory provider is not initialized."});return}let t=typeof e?.text=="string"?e.text.trim():"";if(!t){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:k.INVALID_PARAMS,message:"text is required."});return}let r=Ln(this,e?.userId);if(!r){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:k.INVALID_PARAMS,message:"llmrouter user id is required for long-term memory."});return}let s=new Set(["fact","preference","insight","lesson","decision","plan","event","general"]),o=typeof e?.category=="string"&&s.has(e.category)?e.category:"general",i=typeof e?.importance=="number"&&Number.isFinite(e.importance)?Math.max(.1,Math.min(1,e.importance)):.6;try{let{candidates:a}=await Hh(this,{...e,text:t,category:o,importance:i,source:typeof e?.source=="string"&&e.source.trim()?e.source.trim():"manual",autoExtract:e?.autoExtract??!0},r),c=await qh(this,r,a);n.id!==void 0&&this.sendResponse(n.id,{ok:!0,memoriesAdded:c}),this.sendNotification?.("memory.updated",{source:"local",target:"atlas"})}catch(a){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:k.INTERNAL_ERROR,message:a instanceof Error?a.message:String(a)})}}async function zh(n){let e=n.params;if(this.ensureMemoryProvider?.(),!this.memoryProvider){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:k.INTERNAL_ERROR,message:"Long-term memory provider is not initialized."});return}let t=typeof e?.text=="string"?e.text.trim():"",r=Array.isArray(e?.attachments)?e.attachments:[];if(!t&&r.length===0){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:k.INVALID_PARAMS,message:"text or attachments are required."});return}let s=Ln(this,e?.userId);if(!s){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:k.INVALID_PARAMS,message:"llmrouter user id is required for long-term memory."});return}try{let o=await Hh(this,e??{},s);n.id!==void 0&&this.sendResponse(n.id,{ok:!0,candidates:o.candidates,relatedMemories:o.relatedMemories,extractor:o.extractor})}catch(o){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:k.INTERNAL_ERROR,message:o instanceof Error?o.message:String(o)})}}async function Xh(n){let e=n.params;if(this.ensureMemoryProvider?.(),!this.memoryProvider||typeof this.memoryProvider.addText!="function"){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:k.INTERNAL_ERROR,message:"Long-term memory provider is not initialized."});return}let t=Ln(this,e?.userId);if(!t){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:k.INVALID_PARAMS,message:"llmrouter user id is required for long-term memory."});return}let r=Array.isArray(e?.candidates)?e.candidates:[];if(r.length===0){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:k.INVALID_PARAMS,message:"candidates are required."});return}try{let s=await qh(this,t,r);n.id!==void 0&&this.sendResponse(n.id,{ok:!0,memoriesAdded:s}),this.sendNotification?.("memory.updated",{source:"local",target:"atlas"})}catch(s){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:k.INTERNAL_ERROR,message:s instanceof Error?s.message:String(s)})}}async function Yh(n){let e=n.params,t=e?.source??"memdir",r=e?.target??"index";if(t==="memdir"||t==="local"){if(!this.memdir){n.id!==void 0&&this.sendResponse(n.id,{source:"memdir",target:r,content:""});return}try{if(r==="index"){let s=this.memdir.getIndexRaw();n.id!==void 0&&this.sendResponse(n.id,{source:"memdir",target:"index",content:s})}else{let s=await this.memdir.readFile(r);n.id!==void 0&&this.sendResponse(n.id,{source:"memdir",target:r,content:s.content??""})}}catch{n.id!==void 0&&this.sendResponse(n.id,{source:"memdir",target:r,content:""})}}else n.id!==void 0&&this.sendResponse(n.id,void 0,{code:k.INVALID_PARAMS,message:`Unknown memory source: ${t}`})}async function Jh(n){let e=n.params,t=e?.target??"index",r=e?.content;if(r==null){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:k.INVALID_PARAMS,message:"content is required."});return}if(!this.memdir){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:k.INTERNAL_ERROR,message:"Memory system not initialized."});return}try{if(t==="index"){let s=await this.memdir.addToIndex(r);n.id!==void 0&&this.sendResponse(n.id,{ok:s.ok,target:"index",message:s.message})}else{let s=await this.memdir.writeFile(t,r);n.id!==void 0&&this.sendResponse(n.id,{ok:s.ok,target:t,message:s.message})}this.sendNotification("memory.updated",{target:t,source:"rpc"})}catch(s){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:k.INTERNAL_ERROR,message:s instanceof Error?s.message:String(s)})}}async function Qh(n){let e=n.params;if(!e?.query){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:k.INVALID_PARAMS,message:"query is required."});return}if(this.memoryProvider){let t=Ln(this,e.userId);if(!t){n.id!==void 0&&this.sendResponse(n.id,{results:[]});return}try{let r=await this.memoryProvider.search(e.query,t,{limit:e.limit??10});n.id!==void 0&&this.sendResponse(n.id,{results:r.map(s=>({id:s.blockId??"",text:s.text,score:s.score,source:"local",metadata:s.metadata}))})}catch(r){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:k.INTERNAL_ERROR,message:r instanceof Error?r.message:String(r)})}}else if(this.memdir)try{let t=await this.memdir.searchLocal(e.query);n.id!==void 0&&this.sendResponse(n.id,{results:t.slice(0,e.limit??10).map((r,s)=>({id:`memdir-${s}`,text:r.snippet,score:r.score,source:"memdir",metadata:{file:r.file}}))})}catch{n.id!==void 0&&this.sendResponse(n.id,{results:[]})}else n.id!==void 0&&this.sendResponse(n.id,{results:[]})}async function Zh(n){let e=n.params;if(!e?.match){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:k.INVALID_PARAMS,message:"match is required."});return}let t=e.source??"memdir";if(t==="memdir"||t==="local"){if(!this.memdir){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:k.INTERNAL_ERROR,message:"Memory system not initialized."});return}let r=e.target??"index";try{if(r==="index"){let s=await this.memdir.removeFromIndex(e.match);n.id!==void 0&&this.sendResponse(n.id,{ok:s.ok,removedCount:s.ok?1:0,message:s.message}),s.ok&&this.sendNotification("memory.updated",{source:"memdir",target:"index"})}else{let s=await this.memdir.deleteFile(r);n.id!==void 0&&this.sendResponse(n.id,{ok:s.ok,removedCount:s.ok?1:0,message:s.message}),s.ok&&this.sendNotification("memory.updated",{source:"memdir",target:r})}}catch(s){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:k.INTERNAL_ERROR,message:s instanceof Error?s.message:String(s)})}}else if(t==="vector"&&this.memoryProvider)try{await this.memoryProvider.remove(e.match),n.id!==void 0&&this.sendResponse(n.id,{ok:!0,removedCount:1,message:"Removed from local memory."}),this.sendNotification("memory.updated",{source:"local"})}catch(r){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:k.INTERNAL_ERROR,message:r instanceof Error?r.message:String(r)})}else n.id!==void 0&&this.sendResponse(n.id,void 0,{code:k.INVALID_PARAMS,message:`Unknown or unavailable source: ${t}`})}async function ey(n){let e=n.params,t=typeof e?.id=="string"?e.id.trim():"";if(!t){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:k.INVALID_PARAMS,message:"id is required."});return}if(this.ensureMemoryProvider?.(),!this.memoryProvider||typeof this.memoryProvider.update!="function"){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:k.INTERNAL_ERROR,message:"Long-term memory provider does not support updates."});return}try{let r=await this.memoryProvider.update(t,{text:typeof e?.text=="string"?e.text:void 0,category:typeof e?.category=="string"?lo(e.category):void 0,importance:typeof e?.importance=="number"?Dr(e.importance,.1,1,.6):void 0,source:typeof e?.source=="string"?e.source.trim().slice(0,80):void 0,eventDate:typeof e?.eventDate=="string"?e.eventDate.trim().slice(0,32):void 0,tags:Array.isArray(e?.tags)?uo(e.tags):void 0});n.id!==void 0&&this.sendResponse(n.id,{ok:r,updated:r?1:0}),r&&this.sendNotification("memory.updated",{source:"local",target:"atlas"})}catch(r){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:k.INTERNAL_ERROR,message:r instanceof Error?r.message:String(r)})}}ae();dt();import*as Ht from"node:fs";import*as tl from"node:path";je();function ty(n){let e=n.params,r=At(e?.includeDeferred??!1).map(s=>({name:s.function.name,description:s.function.description??"",parameters:s.function.parameters,source:"builtin"}));if(e?.category){let s=r.filter(o=>o.name.startsWith(e.category)||o.description.toLowerCase().includes(e.category.toLowerCase()));n.id!==void 0&&this.sendResponse(n.id,{tools:s,total:s.length})}else n.id!==void 0&&this.sendResponse(n.id,{tools:r,total:r.length})}function ny(n){let e=X().listProviderDefs(),t=new Map;for(let s of e){let o=s.group??s.id;t.has(o)||t.set(o,[]);let i=!!X().resolveProviderApiKey(s.id);t.get(o).push({id:s.id,name:s.name,transport:s.transport,baseUrl:s.baseUrl,defaultModel:s.defaultModel,modelCount:s.models?.length??0,available:i})}let r=[...t.entries()].map(([s,o])=>({group:s,variants:o}));n.id!==void 0&&this.sendResponse(n.id,{providers:r})}function ry(n){try{let t=X().exportConfig();n.id!==void 0&&this.sendResponse(n.id,{config:{providers:t.providers,models:t.models,bindings:t.bindings},paths:{userSettings:lt(),agentHome:q()}})}catch(e){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:k.INTERNAL_ERROR,message:e instanceof Error?e.message:String(e)})}}var XI=new Set(["providers","models","bindings","provider","model","apiKey","baseUrl","providerKeys"]);async function sy(n){let e=n.params;if(!e?.updates||typeof e.updates!="object"){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:k.INVALID_PARAMS,message:"updates (object) is required."});return}let t=[],r={};for(let[s,o]of Object.entries(e.updates))XI.has(s)?t.push({key:s,reason:"Use settings.* RPC methods for model/key management"}):r[s]=o;if(t.length>0&&Object.keys(r).length===0){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:k.INVALID_PARAMS,message:`Rejected keys: ${t.map(s=>s.key).join(", ")}. Use settings.* RPC for model management.`});return}try{let s=lt(),o={};try{let i=await Ht.promises.readFile(s,"utf-8");o=JSON.parse(i)}catch{}Object.assign(o,r),await Ht.promises.mkdir(tl.dirname(s),{recursive:!0}),await Ht.promises.writeFile(s,JSON.stringify(o,null,2),"utf-8"),n.id!==void 0&&this.sendResponse(n.id,{ok:!0,applied:Object.keys(r),rejected:t})}catch(s){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:k.INTERNAL_ERROR,message:s instanceof Error?s.message:String(s)})}}function oy(n){try{let e=Ri(),t=lt(),r={};try{let s=Ht.readFileSync(t,"utf-8"),o=JSON.parse(s);o.tunables&&typeof o.tunables=="object"&&(r=o.tunables)}catch{}n.id!==void 0&&this.sendResponse(n.id,{defaults:e,overrides:r})}catch(e){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:k.INTERNAL_ERROR,message:e instanceof Error?e.message:String(e)})}}async function iy(n){let e=n.params,t=e?.key,r=e?.value;if(!t||typeof t!="string"){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:k.INVALID_PARAMS,message:"Missing required param: key (string)"});return}let s=Ri();if(!(t in s)){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:k.INVALID_PARAMS,message:`Unknown tunable key: "${t}". Valid keys: ${Object.keys(s).join(", ")}`});return}let o=typeof s[t];if(r==null||typeof r!==o){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:k.INVALID_PARAMS,message:`Invalid value for "${t}": expected ${o}, got ${typeof r}`});return}try{let i=lt(),a={};try{let c=await Ht.promises.readFile(i,"utf-8");a=JSON.parse(c)}catch{}(!a.tunables||typeof a.tunables!="object")&&(a.tunables={}),a.tunables[t]=r,await Ht.promises.mkdir(tl.dirname(i),{recursive:!0}),await Ht.promises.writeFile(i,JSON.stringify(a,null,2),"utf-8"),t==="teamBudgetTokens"&&typeof r=="number"&&(Re.teamBudget.budgetTokens=r),n.id!==void 0&&this.sendResponse(n.id,{ok:!0,key:t,value:r})}catch(i){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:k.INTERNAL_ERROR,message:i instanceof Error?i.message:String(i)})}}async function ay(n){let e=tt("task");if(!e){n.id!==void 0&&this.sendResponse(n.id,{items:[],summary:sr([])});return}try{let s=(await e.execute("rpc-todos-list",{action:"list"},void 0)).details?.taskList??[];n.id!==void 0&&this.sendResponse(n.id,{items:s,summary:sr(s)})}catch{n.id!==void 0&&this.sendResponse(n.id,{items:[],summary:sr([])})}}function cy(n){let t=n.params?.lifecycle??"all",r=this.taskStore.getAllTasks(),s=t==="all"?r:r.filter(o=>o.lifecycle===t);n.id!==void 0&&this.sendResponse(n.id,{tasks:s.map(o=>({taskId:o.taskId,type:o.type,lifecycle:o.lifecycle,label:o.label}))})}function ly(n){let e=n.params;if(!e?.taskId){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:k.INVALID_PARAMS,message:"taskId is required."});return}let r=this.taskStore.getAllTasks().find(s=>s.taskId===e.taskId);if(!r){n.id!==void 0&&this.sendResponse(n.id,{ok:!1,message:`Task ${e.taskId} not found.`});return}if(r.lifecycle!=="running"&&r.lifecycle!=="pending"){n.id!==void 0&&this.sendResponse(n.id,{ok:!1,message:`Task ${e.taskId} is already ${r.lifecycle}.`});return}this.taskStore.updateTask(e.taskId,s=>(s.lifecycle="cancelled",s)),n.id!==void 0&&this.sendResponse(n.id,{ok:!0,message:`Task ${e.taskId} cancelled.`})}ae();import*as dy from"node:fs";import*as po from"node:path";import{randomUUID as YI}from"node:crypto";async function uy(n){try{let e=n.params,t=await this.ensureAgentConfigStore();this.acpDetector.setConfigStore(t.getData());let r=this.acpDetector.scan(e?.force);n.id!==void 0&&this.sendResponse(n.id,r)}catch(e){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:k.INTERNAL_ERROR,message:e instanceof Error?e.message:String(e)})}}async function py(n){try{let e=await this.ensureAgentConfigStore();this.acpDetector.setConfigStore(e.getData());let t=this.acpDetector.list();n.id!==void 0&&this.sendResponse(n.id,t)}catch(e){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:k.INTERNAL_ERROR,message:e instanceof Error?e.message:String(e)})}}async function my(n){try{let e=n.params;if(!e?.action||!e?.agent){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:k.INVALID_PARAMS,message:"action and agent are required."});return}let t=await this.ensureAgentConfigStore();switch(e.action){case"register":t.registerCustomAgent(e.agent);break;case"unregister":t.unregisterCustomAgent(e.agent.id);break;case"update":t.registerCustomAgent(e.agent);break}this.acpDetector.setConfigStore(t.getData()),this.acpDetector.clearCache(),n.id!==void 0&&this.sendResponse(n.id,{ok:!0})}catch(e){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:k.INTERNAL_ERROR,message:e instanceof Error?e.message:String(e)})}}async function gy(n){try{let e=n.params;if(!e?.agentId){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:k.INVALID_PARAMS,message:"agentId is required."});return}let t=await this.ensureAgentConfigStore(),{agentId:r,...s}=e;await t.setAgentConfig(r,s),this.acpDetector.setConfigStore(t.getData()),n.id!==void 0&&this.sendResponse(n.id,{ok:!0})}catch(e){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:k.INTERNAL_ERROR,message:e instanceof Error?e.message:String(e)})}}async function fy(n){try{let e=n.params;if(!e?.agentId){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:k.INVALID_PARAMS,message:"agentId is required."});return}let r=(await this.ensureAgentConfigStore()).getAgentConfig(e.agentId);n.id!==void 0&&this.sendResponse(n.id,r)}catch(e){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:k.INTERNAL_ERROR,message:e instanceof Error?e.message:String(e)})}}async function hy(n){try{let e=n.params;if(!e?.agentId){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:k.INVALID_PARAMS,message:"agentId is required."});return}let t=await this.ensureAgentConfigStore();await t.removeAgentConfig(e.agentId),this.acpDetector.setConfigStore(t.getData()),n.id!==void 0&&this.sendResponse(n.id,{ok:!0})}catch(e){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:k.INTERNAL_ERROR,message:e instanceof Error?e.message:String(e)})}}async function yy(n){try{let e=n.params;if(!e?.url){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:k.INVALID_PARAMS,message:"url is required."});return}await(await this.ensureAgentConfigStore()).setGatewayUrl(e.url),n.id!==void 0&&this.sendResponse(n.id,{ok:!0})}catch(e){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:k.INTERNAL_ERROR,message:e instanceof Error?e.message:String(e)})}}async function by(n){try{let t=(await this.ensureAgentConfigStore()).getGatewayUrl();n.id!==void 0&&this.sendResponse(n.id,{url:t})}catch(e){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:k.INTERNAL_ERROR,message:e instanceof Error?e.message:String(e)})}}async function ky(n){try{let t=(await this.ensureAgentConfigStore()).getData(),r=Object.entries(t.agents).map(([s,o])=>({agentId:s,hasApiKey:!!o.apiKey,hasBaseUrl:!!o.baseUrl,hasModel:!!o.model}));n.id!==void 0&&this.sendResponse(n.id,r)}catch(e){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:k.INTERNAL_ERROR,message:e instanceof Error?e.message:String(e)})}}function vy(n){try{let e=[],t=(r,s)=>{if(r)for(let o of r.getAllHandles())e.push({memberId:o.memberId,name:o.name,pid:o.pid,state:o.state,startedAt:o.startedAt,endedAt:o.endedAt,source:s})};t(this.soloProcessManager,"solo"),t(this.productProcessManager,"product"),n.id!==void 0&&this.sendResponse(n.id,e)}catch(e){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:k.INTERNAL_ERROR,message:e instanceof Error?e.message:String(e)})}}function Sy(n){try{let e=n.params;if(!e?.memberId){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:k.INVALID_PARAMS,message:"memberId is required."});return}let t=!1;for(let r of[this.soloProcessManager,this.productProcessManager])if(r?.getHandle(e.memberId)){r.kill(e.memberId),t=!0;break}n.id!==void 0&&this.sendResponse(n.id,{ok:t})}catch(e){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:k.INTERNAL_ERROR,message:e instanceof Error?e.message:String(e)})}}async function Ty(n){try{let e=n.params;if(!e?.agentId){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:k.INVALID_PARAMS,message:"agentId is required."});return}let t=po.join(q(),"agent-logs"),r=po.join(t,`${e.agentId}.stderr.log`),s="";try{s=dy.readFileSync(r,"utf-8")}catch{}e.tail&&e.tail>0&&s&&(s=s.split(`
|
|
851
851
|
`).slice(-e.tail).join(`
|
|
852
|
-
`)),n.id!==void 0&&this.sendResponse(n.id,{log:s})}catch(e){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:k.INTERNAL_ERROR,message:e instanceof Error?e.message:String(e)})}}async function Ry(n){try{let e=n.params;if(!e?.agentId){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:k.INVALID_PARAMS,message:"agentId is required."});return}let t=await this.ensureAgentConfigStore();this.acpDetector.setConfigStore(t.getData());let s=this.acpDetector.list().find(i=>i.id===e.agentId);if(!s){n.id!==void 0&&this.sendResponse(n.id,{ok:!1,error:`Agent ${e.agentId} not found`,durationMs:0});return}if(s.status==="not_installed"){n.id!==void 0&&this.sendResponse(n.id,{ok:!1,error:`Agent ${e.agentId} is not installed`,durationMs:0});return}let o=Date.now();n.id!==void 0&&this.sendResponse(n.id,{ok:s.status==="available",version:s.version,capabilities:s.capabilities,error:s.status!=="available"?`Agent status: ${s.status}`:void 0,durationMs:Date.now()-o})}catch(e){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:k.INTERNAL_ERROR,message:e instanceof Error?e.message:String(e)})}}async function wy(n){let e=null,t="";try{let r=n.params??{},s=typeof r.agentId=="string"?r.agentId.trim():"",o=typeof r.prompt=="string"?r.prompt:"";if(!s||!o.trim()){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:k.INVALID_PARAMS,message:"agentId and prompt are required."});return}let i=await this.ensureAgentConfigStore();this.acpDetector.setConfigStore(i.getData()),this.acpDetector.scan(!1);let a=this.acpDetector.buildExternalDescriptor(s);if(!a){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:k.INVALID_PARAMS,message:`Agent ${s} is not available or not ACP-compatible.`});return}let c=typeof r.cwd=="string"&&r.cwd?r.cwd:typeof this.getActiveProjectRoot=="function"?this.getActiveProjectRoot():process.cwd(),l=typeof r.timeoutMs=="number"&&r.timeoutMs>0?r.timeoutMs:3e5;t=`chat-${s}-${YI().slice(0,8)}`;let u=[];e=new _t({onNotification:(h,f,y)=>{if(f!=="turn.delta")return;let b=typeof y?.text=="string"?y.text:"";b&&u.push(b)},onMcpToolCall:async(h,f,y)=>typeof this.handleMcpToolCall=="function"?this.handleMcpToolCall(h,f,y):{ok:!1,error:"MCP tool call unavailable"},log:{info:h=>this.log?.(`[agents.prompt] ${h}`),warn:h=>this.log?.(`[agents.prompt] WARN: ${h}`),debug:h=>this.log?.(`[agents.prompt] ${h}`)},sessionDir:po.join(q(),"agent-logs")}),await e.spawn({memberId:t,name:`chat-${s}`,cwd:c,prompt:o,external:a,systemPrompt:typeof r.systemPrompt=="string"?r.systemPrompt:void 0});let d=await e.sendTask(t,o,{
|
|
852
|
+
`)),n.id!==void 0&&this.sendResponse(n.id,{log:s})}catch(e){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:k.INTERNAL_ERROR,message:e instanceof Error?e.message:String(e)})}}async function Ry(n){try{let e=n.params;if(!e?.agentId){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:k.INVALID_PARAMS,message:"agentId is required."});return}let t=await this.ensureAgentConfigStore();this.acpDetector.setConfigStore(t.getData());let s=this.acpDetector.list().find(i=>i.id===e.agentId);if(!s){n.id!==void 0&&this.sendResponse(n.id,{ok:!1,error:`Agent ${e.agentId} not found`,durationMs:0});return}if(s.status==="not_installed"){n.id!==void 0&&this.sendResponse(n.id,{ok:!1,error:`Agent ${e.agentId} is not installed`,durationMs:0});return}let o=Date.now();n.id!==void 0&&this.sendResponse(n.id,{ok:s.status==="available",version:s.version,capabilities:s.capabilities,error:s.status!=="available"?`Agent status: ${s.status}`:void 0,durationMs:Date.now()-o})}catch(e){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:k.INTERNAL_ERROR,message:e instanceof Error?e.message:String(e)})}}async function wy(n){let e=null,t="";try{let r=n.params??{},s=typeof r.agentId=="string"?r.agentId.trim():"",o=typeof r.prompt=="string"?r.prompt:"";if(!s||!o.trim()){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:k.INVALID_PARAMS,message:"agentId and prompt are required."});return}let i=await this.ensureAgentConfigStore();this.acpDetector.setConfigStore(i.getData()),this.acpDetector.scan(!1);let a=this.acpDetector.buildExternalDescriptor(s);if(!a){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:k.INVALID_PARAMS,message:`Agent ${s} is not available or not ACP-compatible.`});return}let c=typeof r.cwd=="string"&&r.cwd?r.cwd:typeof this.getActiveProjectRoot=="function"?this.getActiveProjectRoot():process.cwd(),l=typeof r.timeoutMs=="number"&&r.timeoutMs>0?r.timeoutMs:3e5;t=`chat-${s}-${YI().slice(0,8)}`;let u=[];e=new _t({onNotification:(h,f,y)=>{if(f!=="turn.delta")return;let b=typeof y?.text=="string"?y.text:"";b&&u.push(b)},onMcpToolCall:async(h,f,y)=>typeof this.handleMcpToolCall=="function"?this.handleMcpToolCall(h,f,y):{ok:!1,error:"MCP tool call unavailable"},log:{info:h=>this.log?.(`[agents.prompt] ${h}`),warn:h=>this.log?.(`[agents.prompt] WARN: ${h}`),debug:h=>this.log?.(`[agents.prompt] ${h}`)},sessionDir:po.join(q(),"agent-logs")}),await e.spawn({memberId:t,name:`chat-${s}`,cwd:c,prompt:o,external:a,systemPrompt:typeof r.systemPrompt=="string"?r.systemPrompt:void 0});let d=await e.sendTask(t,o,{timeout:l}),p=u.join("")||(typeof d?.content=="string"?d.content:""),m=e.getUsageTracker(t)?.getUsage();n.id!==void 0&&this.sendResponse(n.id,{ok:!0,agentId:s,content:p,stopReason:d?.stopReason,usage:m?{inputTokens:m.inputTokens,outputTokens:m.outputTokens,totalTokens:m.totalTokens,cacheRead:m.cachedReadTokens,thoughtTokens:m.thoughtTokens,cost:m.cost}:void 0})}catch(r){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:k.INTERNAL_ERROR,message:r instanceof Error?r.message:String(r)})}finally{if(e&&t){try{e.kill(t)}catch{}try{e.dispose()}catch{}}}}import{isAsyncMediaTransport as Ay}from"@xiaozhiclaw/provider-core";dt();async function xy(n){try{if(!this.mediaClient){n.id!==void 0&&this.sendResponse(n.id,{models:[]});return}let e=await this.mediaClient.listModels();n.id!==void 0&&this.sendResponse(n.id,{models:e})}catch(e){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:k.INTERNAL_ERROR,message:e instanceof Error?e.message:String(e)})}}async function Py(n){let e=n.params;if(!e?.taskId){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:k.INVALID_PARAMS,message:"taskId is required."});return}try{if(!this.mediaClient||!Ay(this.mediaClient)){n.id!==void 0&&this.sendResponse(n.id,{ok:!1,message:"Media client does not support async cancel."});return}await this.mediaClient.cancel(e.taskId),n.id!==void 0&&this.sendResponse(n.id,{ok:!0})}catch(t){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:k.INTERNAL_ERROR,message:t instanceof Error?t.message:String(t)})}}async function Iy(n){let e=n.params;if(!e?.taskId){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:k.INVALID_PARAMS,message:"taskId is required."});return}try{if(!this.mediaClient||!Ay(this.mediaClient)){n.id!==void 0&&this.sendResponse(n.id,{status:"unknown",message:"Media client does not support status queries."});return}let t=await this.mediaClient.queryStatus(e.taskId);n.id!==void 0&&this.sendResponse(n.id,t)}catch(t){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:k.INTERNAL_ERROR,message:t instanceof Error?t.message:String(t)})}}async function _y(n){let e=n.params;if(!e?.audioBase64){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:k.INVALID_PARAMS,message:"audioBase64 is required."});return}let r=X().getActiveModel("stt");if(!r){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:k.INTERNAL_ERROR,message:"STT not configured. Add an STT model and bind it in settings."});return}let{apiKey:s,model:o,baseUrl:i,keyHandle:a}=r;if(!i){a.release({success:!1}),n.id!==void 0&&this.sendResponse(n.id,void 0,{code:k.INTERNAL_ERROR,message:"STT baseUrl not configured. Set baseUrl on the STT model entry."});return}try{let c=`----STTBoundary${Date.now()}`,l=[];l.push(`--${c}\r
|
|
853
853
|
Content-Disposition: form-data; name="model"\r
|
|
854
854
|
\r
|
|
855
855
|
${o}`),l.push(`--${c}\r
|
|
@@ -860,7 +860,7 @@ Content-Disposition: form-data; name="prompt"\r
|
|
|
860
860
|
\r
|
|
861
861
|
\u8BF7\u7528${e.language==="zh"?"\u4E2D\u6587":"\u82F1\u6587"}\u8F6C\u5F55`),l.push(`--${c}--`);let u=l.join(`\r
|
|
862
862
|
`)+`\r
|
|
863
|
-
`,d=await fetch(i,{method:"POST",headers:{Authorization:`Bearer ${s}`,"Content-Type":`multipart/form-data; boundary=${c}`},body:u});if(!d.ok){let m=await d.text();a.release({success:!1,errorCode:d.status}),n.id!==void 0&&this.sendResponse(n.id,void 0,{code:k.INTERNAL_ERROR,message:`STT API error (${d.status}): ${m.slice(0,200)}`});return}let p=await d.json();a.release({success:!0}),n.id!==void 0&&this.sendResponse(n.id,{text:p.text??"",model:p.model})}catch(c){a.release({success:!1}),n.id!==void 0&&this.sendResponse(n.id,void 0,{code:k.INTERNAL_ERROR,message:c instanceof Error?c.message:String(c)})}}dt();function JI(n){return n.length<=8?"****":`${n.slice(0,3)}***${n.slice(-4)}`}function ct(n,e,t,r=k.INTERNAL_ERROR){if(e.id!==void 0){if(typeof n.sendError=="function"){n.sendError(e.id,r,t);return}n.sendResponse(e.id,void 0,{code:r,message:t})}}function mo(n,e){ct(n,e,Bs)}function QI(n){let e={};for(let t of n)for(let r of t.purposes)e[r]??=[],e[r].push(t);return e}async function nl(){let n=X(),e=await Rr(n);return n.save(),e}async function Cy(n){try{let e=(await Hs()).map(t=>({id:t.id,displayName:Ec(t),baseUrl:qs(t)??"",modelCount:t.models?.length??0}));n.id!==void 0&&this.sendResponse(n.id,{providers:e})}catch{mo(this,n)}}async function Ey(n){let e=n.params;if(!e?.providerId||!e?.key){ct(this,n,"Required: providerId (string), key (string)",k.INVALID_PARAMS);return}let{providerId:t,key:r,label:s}=e;try{let o=await Mc(t);if(!o){ct(this,n,`Unknown provider: ${t}`,k.INVALID_PARAMS);return}let i=X();if(i.getProviderStatus(t)?.keys.some(l=>l.key===r)){n.id!==void 0&&this.sendResponse(n.id,{ok:!1,error:"\u8BE5 Key \u5DF2\u5B58\u5728\uFF0C\u65E0\u9700\u91CD\u590D\u6DFB\u52A0"});return}i.addProvider(t,{baseUrl:qs(o)});let c=i.addKey(t,r,{label:s});await nl();for(let l of Zn)if(!i.getBinding(l)){let u=i.listModels({purpose:l,provider:t,enabledOnly:!0});u.length>0&&i.setBinding(l,u[0].id)}i.setKeyHealth(c,"healthy"),i.save(),n.id!==void 0&&this.sendResponse(n.id,{ok:!0,keyId:c,providerId:t})}catch(o){let i=o instanceof Error?o.message:Bs;ct(this,n,i)}}function My(n){let e=n.params;if(!e?.keyId){ct(this,n,"Required: keyId (string)",k.INVALID_PARAMS);return}let t=X();t.removeKey(e.keyId),t.save(),n.id!==void 0&&this.sendResponse(n.id,{ok:!0})}function Dy(n){let e=n.params;if(!e?.keyId||typeof e.enabled!="boolean"){ct(this,n,"Required: keyId (string), enabled (boolean)",k.INVALID_PARAMS);return}let t=X();t.updateKey(e.keyId,{enabled:e.enabled}),t.save(),n.id!==void 0&&this.sendResponse(n.id,{ok:!0})}function Ny(n){let e=n.params;if(!e?.modelId||typeof e.enabled!="boolean"){ct(this,n,"Required: modelId (string), enabled (boolean)",k.INVALID_PARAMS);return}let t=X();e.enabled?t.enableModel(e.modelId):t.disableModel(e.modelId),t.save(),n.id!==void 0&&this.sendResponse(n.id,{ok:!0})}async function Oy(n){let e=n.params;try{await nl();let t=X(),r=new Set(t.getAllProviderStatus().filter(o=>o.keys.length>0).map(o=>o.providerId)),s=t.listModels({purpose:e?.purpose,provider:e?.provider}).filter(o=>t.hasConfiguredKeyForProviderVariant(o.provider));n.id!==void 0&&this.sendResponse(n.id,{models:s,grouped:QI(s),configuredProviderIds:[...r]})}catch{mo(this,n)}}function Ly(n){let e=n.params;if(!e?.purpose||!e?.modelId){ct(this,n,"Required: purpose (string), modelId (string)",k.INVALID_PARAMS);return}try{let t=X();t.setBinding(e.purpose,e.modelId),t.save(),n.id!==void 0&&this.sendResponse(n.id,{ok:!0})}catch(t){ct(this,n,t instanceof Error?t.message:String(t),k.INVALID_PARAMS)}}function $y(n){let e=n.params;if(!e?.purpose){ct(this,n,"Required: purpose (string)",k.INVALID_PARAMS);return}let t=X(),r=t.getBinding(e.purpose);n.id!==void 0&&this.sendResponse(n.id,{model:r?{id:r.id,provider:r.provider,model:r.model,displayName:r.displayName,purposes:r.purposes,enabled:r.enabled}:null,available:t.isAvailable(e.purpose)})}async function jy(n){try{let e=await Hs(),t=new Map(e.map(a=>[a.id,Ec(a)]));await nl();let r=X(),s=r.getAllProviderStatus().map(a=>({providerId:a.providerId,displayName:t.get(a.providerId)??a.providerId,baseUrl:a.baseUrl,keyCount:a.keys.length,healthyKeys:a.keys.filter(c=>c.healthStatus==="healthy"&&c.enabled).length,totalKeys:a.keys.length,keys:a.keys.map(c=>({id:c.id,label:c.label,maskedKey:JI(c.key),enabled:c.enabled,health:c.healthStatus}))})),o=r.getAllBindings(),i={};for(let a of Zn){let c=o[a];i[a]={bound:!!c,modelId:c?.id,modelName:c?.displayName,available:r.isAvailable(a)}}n.id!==void 0&&this.sendResponse(n.id,{providers:s,purposes:i})}catch{mo(this,n)}}async function Uy(n){try{let e=X();e.load(),await Rr(e),e.save(),n.id!==void 0&&this.sendResponse(n.id,{ok:!0,catalogRefreshed:!0})}catch{mo(this,n)}}async function Fy(n){let e=n.params;if(!e?.providerId||!e?.apiKey){ct(this,n,"providerId and apiKey required",k.INVALID_PARAMS);return}try{let t=await Mc(e.providerId),r=e.baseUrl||(t?qs(t):void 0);if(!r){ct(this,n,`Unknown provider: ${e.providerId}`,k.INVALID_PARAMS);return}let s=`${r.replace(/\/$/,"")}/models`,o=await fetch(s,{method:"GET",headers:{Authorization:`Bearer ${e.apiKey}`},signal:AbortSignal.timeout(1e4)});if(o.ok){n.id!==void 0&&this.sendResponse(n.id,{valid:!0,status:o.status});return}let i=await o.text().catch(()=>"");n.id!==void 0&&this.sendResponse(n.id,{valid:!1,status:o.status,error:i.slice(0,500)})}catch(t){let r=t instanceof Error?t.message:String(t);n.id!==void 0&&this.sendResponse(n.id,{valid:!1,status:0,error:r})}}ko();ho();il();yo();bo();function ml(n){let e=Ce.getNextAbility(n.level);return{level:n.level,experience:n.experience,xpNeeded:Ce.xpForLevel(n.level),abilities:Ce.getUnlockedAbilities(n.level).map(t=>t.name),nextAbility:e?{name:e.name,level:e.unlockedAtLevel}:void 0}}async function eb(n){let e=n.params,t=this.getActiveProjectRoot(),r=new Qt(t),s=r.load();if(s){this.sendNotification("pet.soul_ready",{name:s.name,species:s.species,personality:s.personality,catchphrase:s.catchphrase,stats:s.stats,rarity:s.rarity,breed:s.breed,breedColors:s.breedColors}),n.id!==void 0&&this.sendResponse(n.id,{ok:!0,soul:s,growth:ml(s)});return}let o=this.deviceId??"default-user";try{let i=this.createPetSoulGenerator?.(),a=await r.hatch(o,i,e?.breed);this.sendNotification("pet.soul_ready",{name:a.name,species:a.species,personality:a.personality,catchphrase:a.catchphrase,stats:a.stats,rarity:a.rarity,breed:a.breed,breedColors:a.breedColors}),this.sendNotification("pet.growth",{level:a.level,experience:a.experience,xpNeeded:Ce.xpForLevel(a.level),abilities:Ce.getUnlockedAbilities(a.level).map(c=>c.name)}),n.id!==void 0&&this.sendResponse(n.id,{ok:!0,soul:a,growth:ml(a)})}catch(i){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:k.INTERNAL_ERROR,message:i.message??"Failed to hatch pet"})}}async function tb(n){let t=n.params?.action??"pat",r=this.getActiveProjectRoot(),s=new Qt(r),o=s.load();if(!o){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:k.INVALID_PARAMS,message:"Pet not hatched yet"});return}let i=Ce.xpForEvent(`interact.${t}`),{newLevel:a,newXp:c,events:l,statBoosts:u}=Ce.processXpGain(o,i);o.level=a,o.experience=c;for(let[b,S]of Object.entries(u)){let w=b;o.stats[w]=Math.min(10,o.stats[w]+(S??0))}s.updateSoul(o),this.sendNotification("pet.state",{state:"happy"});let d=Ce.getUnlockedAbilities(a).map(b=>b.name),p=Ce.getNextAbility(a);this.sendNotification("pet.growth",{level:a,experience:c,xpNeeded:Ce.xpForLevel(a),abilities:d,nextAbility:p?{name:p.name,level:p.unlockedAtLevel}:void 0});for(let b of l)b.type==="molt"?this.sendNotification("pet.reaction",{text:`\u2728 \u8131\u58F3\u4E86\uFF01\u7B2C ${b.moltStage} \u6B21\u8715\u53D8`,style:"excited"}):b.type==="ability_unlock"&&b.ability&&this.sendNotification("pet.reaction",{text:`\u{1F389} \u89E3\u9501\u65B0\u80FD\u529B\uFF1A${b.ability.name}`,style:"excited"});let m=null,h="excited";try{let b=[],S=this.getActiveProjectRoot?.()??"";if(S){let L=S.split(/[\\/]/).pop()??S;b.push(`\u7528\u6237\u6B63\u5728\u9879\u76EE\u300C${L}\u300D\u4E2D\u5DE5\u4F5C`)}if(this.sessionState){let L=this.sessionState.turnCount??0;L>0&&b.push(`\u672C\u6B21\u4F1A\u8BDD\u5DF2\u8FDB\u884C\u4E86 ${L} \u8F6E\u5BF9\u8BDD`)}if(this.memoryProvider&&this.memoryUserId)try{let L=this.memoryProvider.getActivitySummary(this.memoryUserId,7);if(L?.highlights?.length){let F=L.highlights.slice(0,3).map(T=>T.text);b.push(`\u7528\u6237\u8FD1\u671F\u8BB0\u5FC6\u4EAE\u70B9: ${F.join("\uFF1B")}`)}}catch{}let w=new Date().getHours(),_=w<6?"\u6DF1\u591C":w<9?"\u65E9\u6668":w<12?"\u4E0A\u5348":w<14?"\u4E2D\u5348":w<18?"\u4E0B\u5348":w<22?"\u665A\u4E0A":"\u6DF1\u591C";b.push(`\u5F53\u524D\u65F6\u6BB5: ${_}`);let I=t==="pat"?"\u7528\u6237\u6478\u4E86\u6478\u4F60":t==="feed"?"\u7528\u6237\u5582\u4E86\u4F60\u4E1C\u897F":`\u7528\u6237\u5BF9\u4F60\u505A\u4E86\u300C${t}\u300D`;b.push(I);let D=b.join("\u3002");if(this.createSmallLLMCall){let L=this.createSmallLLMCall();if(L){let F=await fo({turnSummary:D,soul:o},L);F&&(m=F.text,h=F.style)}}}catch{}if(!m){let b=go("session.created");m=b?.text??null,h=b?.style??"excited"}let f=[],y=new Date().getHours();y>=22||y<6?f.push({label:"\u5E2E\u6211\u6574\u7406\u4ECA\u5929\u7684\u8FDB\u5EA6",action:"summarize-today"}):this.sessionState?.turnCount&&this.sessionState.turnCount>5&&f.push({label:"\u7EE7\u7EED\u521A\u624D\u7684\u5BF9\u8BDD",action:"resume-session"}),t==="click"&&f.push({label:"\u6709\u4EC0\u4E48\u80FD\u5E2E\u4F60\u7684\uFF1F",action:"start-chat"}),m&&this.sendNotification("pet.reaction",{text:m,style:h,actions:f.length>0?f:void 0}),n.id!==void 0&&this.sendResponse(n.id,{ok:!0,action:t,level:a,experience:c,events:l.map(b=>({type:b.type,level:b.level})),reaction:m?{text:m,style:h,actions:f.length>0?f:void 0}:null})}async function nb(n){let e=this.getActiveProjectRoot(),r=new Qt(e).load();if(n.id!==void 0&&this.sendResponse(n.id,{ok:!0,soul:r??null,growth:r?ml(r):null}),r){this.sendNotification("pet.soul_ready",{name:r.name,species:r.species,personality:r.personality,catchphrase:r.catchphrase,stats:r.stats,rarity:r.rarity,breed:r.breed,breedColors:r.breedColors});let s=Ce.getUnlockedAbilities(r.level).map(i=>i.name),o=Ce.getNextAbility(r.level);this.sendNotification("pet.growth",{level:r.level,experience:r.experience,xpNeeded:Ce.xpForLevel(r.level),abilities:s,nextAbility:o?{name:o.name,level:o.unlockedAtLevel}:void 0})}}async function rb(n){let e=n.params;if(!e?.description&&!e?.imageBase64){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:k.INVALID_PARAMS,message:"Provide description or imageBase64"});return}typeof this.ensureModelRegistryHydrated=="function"&&await this.ensureModelRegistryHydrated(),this.sendNotification("pet.state",{state:"building"}),this.sendNotification("pet.reaction",{text:"\u6B63\u5728\u5B75\u5316\u4F60\u7684\u4E13\u5C5E\u5BA0\u7269...",style:"thinking"});try{let t=e.description?.slice(0,10)??"\u81EA\u5B9A\u4E49\u5BA0\u7269",r=e.description??"";e.imageBase64&&(r=await this.forgeAnalyzeImage(e.imageBase64,e.description),this.sendNotification("pet.reaction",{text:"\u5206\u6790\u5B8C\u6210\uFF0C\u6B63\u5728\u751F\u6210\u9AA8\u67B6...",style:"thinking"}));let s=await this.forgeGenerateSkeleton(r),o=qt(s),i=Fn(o),a=0;for(;i.length>0&&a<2;){a++,this.sendNotification("pet.reaction",{text:`\u9AA8\u67B6\u7F3A\u5C11 ${i.join("\u3001")}\uFF0C\u91CD\u65B0\u751F\u6210 (${a}/${2})...`,style:"thinking",duration:3e3});let m=`\u4E0A\u6B21\u751F\u6210\u7F3A\u5C11\u4EE5\u4E0B\u90E8\u4F4D: ${i.join(", ")}\u3002\u8BF7\u786E\u4FDD\u6240\u6709 id \u5C5E\u6027\u90FD\u5B58\u5728\u3002`;s=await this.forgeGenerateSkeleton(r+`
|
|
863
|
+
`,d=await fetch(i,{method:"POST",headers:{Authorization:`Bearer ${s}`,"Content-Type":`multipart/form-data; boundary=${c}`},body:u});if(!d.ok){let m=await d.text();a.release({success:!1,errorCode:d.status}),n.id!==void 0&&this.sendResponse(n.id,void 0,{code:k.INTERNAL_ERROR,message:`STT API error (${d.status}): ${m.slice(0,200)}`});return}let p=await d.json();a.release({success:!0}),n.id!==void 0&&this.sendResponse(n.id,{text:p.text??"",model:p.model})}catch(c){a.release({success:!1}),n.id!==void 0&&this.sendResponse(n.id,void 0,{code:k.INTERNAL_ERROR,message:c instanceof Error?c.message:String(c)})}}dt();function JI(n){return n.length<=8?"****":`${n.slice(0,3)}***${n.slice(-4)}`}function ct(n,e,t,r=k.INTERNAL_ERROR){if(e.id!==void 0){if(typeof n.sendError=="function"){n.sendError(e.id,r,t);return}n.sendResponse(e.id,void 0,{code:r,message:t})}}function mo(n,e){ct(n,e,Bs)}function QI(n){let e={};for(let t of n)for(let r of t.purposes)e[r]??=[],e[r].push(t);return e}async function nl(){let n=X(),e=await Rr(n);return n.save(),e}async function Cy(n){try{let e=(await Hs()).map(t=>({id:t.id,displayName:Ec(t),baseUrl:qs(t)??"",modelCount:t.models?.length??0}));n.id!==void 0&&this.sendResponse(n.id,{providers:e})}catch{mo(this,n)}}async function Ey(n){let e=n.params;if(!e?.providerId||!e?.key){ct(this,n,"Required: providerId (string), key (string)",k.INVALID_PARAMS);return}let{providerId:t,key:r,label:s}=e;try{let o=await Mc(t);if(!o){ct(this,n,`Unknown provider: ${t}`,k.INVALID_PARAMS);return}let i=X();if(i.getProviderStatus(t)?.keys.some(l=>l.key===r)){n.id!==void 0&&this.sendResponse(n.id,{ok:!1,error:"\u8BE5 Key \u5DF2\u5B58\u5728\uFF0C\u65E0\u9700\u91CD\u590D\u6DFB\u52A0"});return}i.addProvider(t,{baseUrl:qs(o)});let c=i.addKey(t,r,{label:s});await nl();for(let l of Zn)if(!i.getBinding(l)){let u=i.listModels({purpose:l,provider:t,enabledOnly:!0});u.length>0&&i.setBinding(l,u[0].id)}i.setKeyHealth(c,"healthy"),i.save(),n.id!==void 0&&this.sendResponse(n.id,{ok:!0,keyId:c,providerId:t})}catch(o){let i=o instanceof Error?o.message:Bs;ct(this,n,i)}}function My(n){let e=n.params;if(!e?.keyId){ct(this,n,"Required: keyId (string)",k.INVALID_PARAMS);return}let t=X();t.removeKey(e.keyId),t.save(),n.id!==void 0&&this.sendResponse(n.id,{ok:!0})}function Dy(n){let e=n.params;if(!e?.keyId||typeof e.enabled!="boolean"){ct(this,n,"Required: keyId (string), enabled (boolean)",k.INVALID_PARAMS);return}let t=X();t.updateKey(e.keyId,{enabled:e.enabled}),t.save(),n.id!==void 0&&this.sendResponse(n.id,{ok:!0})}function Ny(n){let e=n.params;if(!e?.modelId||typeof e.enabled!="boolean"){ct(this,n,"Required: modelId (string), enabled (boolean)",k.INVALID_PARAMS);return}let t=X();e.enabled?t.enableModel(e.modelId):t.disableModel(e.modelId),t.save(),n.id!==void 0&&this.sendResponse(n.id,{ok:!0})}async function Oy(n){let e=n.params;try{await nl();let t=X(),r=new Set(t.getAllProviderStatus().filter(o=>o.keys.length>0).map(o=>o.providerId)),s=t.listModels({purpose:e?.purpose,provider:e?.provider}).filter(o=>t.hasConfiguredKeyForProviderVariant(o.provider));n.id!==void 0&&this.sendResponse(n.id,{models:s,grouped:QI(s),configuredProviderIds:[...r]})}catch{mo(this,n)}}function Ly(n){let e=n.params;if(!e?.purpose||!e?.modelId){ct(this,n,"Required: purpose (string), modelId (string)",k.INVALID_PARAMS);return}try{let t=X();t.setBinding(e.purpose,e.modelId),t.save(),n.id!==void 0&&this.sendResponse(n.id,{ok:!0})}catch(t){ct(this,n,t instanceof Error?t.message:String(t),k.INVALID_PARAMS)}}function $y(n){let e=n.params;if(!e?.purpose){ct(this,n,"Required: purpose (string)",k.INVALID_PARAMS);return}let t=X(),r=t.getBinding(e.purpose);n.id!==void 0&&this.sendResponse(n.id,{model:r?{id:r.id,provider:r.provider,model:r.model,displayName:r.displayName,purposes:r.purposes,enabled:r.enabled}:null,available:t.isAvailable(e.purpose)})}async function jy(n){try{let e=await Hs(),t=new Map(e.map(a=>[a.id,Ec(a)]));await nl();let r=X(),s=r.getAllProviderStatus().map(a=>({providerId:a.providerId,displayName:t.get(a.providerId)??a.providerId,baseUrl:a.baseUrl,keyCount:a.keys.length,healthyKeys:a.keys.filter(c=>c.healthStatus==="healthy"&&c.enabled).length,totalKeys:a.keys.length,keys:a.keys.map(c=>({id:c.id,label:c.label,maskedKey:JI(c.key),enabled:c.enabled,health:c.healthStatus}))})),o=r.getAllBindings(),i={};for(let a of Zn){let c=o[a];i[a]={bound:!!c,modelId:c?.id,modelName:c?.displayName,available:r.isAvailable(a)}}n.id!==void 0&&this.sendResponse(n.id,{providers:s,purposes:i})}catch{mo(this,n)}}async function Uy(n){try{let e=X();e.load(),await Rr(e),e.save(),n.id!==void 0&&this.sendResponse(n.id,{ok:!0,catalogRefreshed:!0})}catch{mo(this,n)}}async function Fy(n){let e=n.params;if(!e?.providerId||!e?.apiKey){ct(this,n,"providerId and apiKey required",k.INVALID_PARAMS);return}try{let t=await Mc(e.providerId),r=e.baseUrl||(t?qs(t):void 0);if(!r){ct(this,n,`Unknown provider: ${e.providerId}`,k.INVALID_PARAMS);return}let s=`${r.replace(/\/$/,"")}/models`,o=await fetch(s,{method:"GET",headers:{Authorization:`Bearer ${e.apiKey}`},signal:AbortSignal.timeout(1e4)});if(o.ok){n.id!==void 0&&this.sendResponse(n.id,{valid:!0,status:o.status});return}let i=await o.text().catch(()=>"");n.id!==void 0&&this.sendResponse(n.id,{valid:!1,status:o.status,error:i.slice(0,500)})}catch(t){let r=t instanceof Error?t.message:String(t);n.id!==void 0&&this.sendResponse(n.id,{valid:!1,status:0,error:r})}}ko();ho();il();yo();bo();function ml(n){let e=Ce.getNextAbility(n.level);return{level:n.level,experience:n.experience,xpNeeded:Ce.xpForLevel(n.level),abilities:Ce.getUnlockedAbilities(n.level).map(t=>t.name),nextAbility:e?{name:e.name,level:e.unlockedAtLevel}:void 0}}async function eb(n){let e=n.params,t=this.getActiveProjectRoot(),r=new Qt(t),s=r.load();if(s){this.sendNotification("pet.soul_ready",{name:s.name,species:s.species,personality:s.personality,catchphrase:s.catchphrase,stats:s.stats,rarity:s.rarity,breed:s.breed,breedColors:s.breedColors}),n.id!==void 0&&this.sendResponse(n.id,{ok:!0,soul:s,growth:ml(s)});return}let o=this.deviceId??"default-user";try{let i=this.createPetSoulGenerator?.(),a=await r.hatch(o,i,e?.breed);this.sendNotification("pet.soul_ready",{name:a.name,species:a.species,personality:a.personality,catchphrase:a.catchphrase,stats:a.stats,rarity:a.rarity,breed:a.breed,breedColors:a.breedColors}),this.sendNotification("pet.growth",{level:a.level,experience:a.experience,xpNeeded:Ce.xpForLevel(a.level),abilities:Ce.getUnlockedAbilities(a.level).map(c=>c.name)}),n.id!==void 0&&this.sendResponse(n.id,{ok:!0,soul:a,growth:ml(a)})}catch(i){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:k.INTERNAL_ERROR,message:i.message??"Failed to hatch pet"})}}async function tb(n){let t=n.params?.action??"pat",r=this.getActiveProjectRoot(),s=new Qt(r),o=s.load();if(!o){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:k.INVALID_PARAMS,message:"Pet not hatched yet"});return}let i=Ce.xpForEvent(`interact.${t}`),{newLevel:a,newXp:c,events:l,statBoosts:u}=Ce.processXpGain(o,i);o.level=a,o.experience=c;for(let[b,T]of Object.entries(u)){let w=b;o.stats[w]=Math.min(10,o.stats[w]+(T??0))}s.updateSoul(o),this.sendNotification("pet.state",{state:"happy"});let d=Ce.getUnlockedAbilities(a).map(b=>b.name),p=Ce.getNextAbility(a);this.sendNotification("pet.growth",{level:a,experience:c,xpNeeded:Ce.xpForLevel(a),abilities:d,nextAbility:p?{name:p.name,level:p.unlockedAtLevel}:void 0});for(let b of l)b.type==="molt"?this.sendNotification("pet.reaction",{text:`\u2728 \u8131\u58F3\u4E86\uFF01\u7B2C ${b.moltStage} \u6B21\u8715\u53D8`,style:"excited"}):b.type==="ability_unlock"&&b.ability&&this.sendNotification("pet.reaction",{text:`\u{1F389} \u89E3\u9501\u65B0\u80FD\u529B\uFF1A${b.ability.name}`,style:"excited"});let m=null,h="excited";try{let b=[],T=this.getActiveProjectRoot?.()??"";if(T){let L=T.split(/[\\/]/).pop()??T;b.push(`\u7528\u6237\u6B63\u5728\u9879\u76EE\u300C${L}\u300D\u4E2D\u5DE5\u4F5C`)}if(this.sessionState){let L=this.sessionState.turnCount??0;L>0&&b.push(`\u672C\u6B21\u4F1A\u8BDD\u5DF2\u8FDB\u884C\u4E86 ${L} \u8F6E\u5BF9\u8BDD`)}if(this.memoryProvider&&this.memoryUserId)try{let L=this.memoryProvider.getActivitySummary(this.memoryUserId,7);if(L?.highlights?.length){let F=L.highlights.slice(0,3).map(S=>S.text);b.push(`\u7528\u6237\u8FD1\u671F\u8BB0\u5FC6\u4EAE\u70B9: ${F.join("\uFF1B")}`)}}catch{}let w=new Date().getHours(),_=w<6?"\u6DF1\u591C":w<9?"\u65E9\u6668":w<12?"\u4E0A\u5348":w<14?"\u4E2D\u5348":w<18?"\u4E0B\u5348":w<22?"\u665A\u4E0A":"\u6DF1\u591C";b.push(`\u5F53\u524D\u65F6\u6BB5: ${_}`);let I=t==="pat"?"\u7528\u6237\u6478\u4E86\u6478\u4F60":t==="feed"?"\u7528\u6237\u5582\u4E86\u4F60\u4E1C\u897F":`\u7528\u6237\u5BF9\u4F60\u505A\u4E86\u300C${t}\u300D`;b.push(I);let D=b.join("\u3002");if(this.createSmallLLMCall){let L=this.createSmallLLMCall();if(L){let F=await fo({turnSummary:D,soul:o},L);F&&(m=F.text,h=F.style)}}}catch{}if(!m){let b=go("session.created");m=b?.text??null,h=b?.style??"excited"}let f=[],y=new Date().getHours();y>=22||y<6?f.push({label:"\u5E2E\u6211\u6574\u7406\u4ECA\u5929\u7684\u8FDB\u5EA6",action:"summarize-today"}):this.sessionState?.turnCount&&this.sessionState.turnCount>5&&f.push({label:"\u7EE7\u7EED\u521A\u624D\u7684\u5BF9\u8BDD",action:"resume-session"}),t==="click"&&f.push({label:"\u6709\u4EC0\u4E48\u80FD\u5E2E\u4F60\u7684\uFF1F",action:"start-chat"}),m&&this.sendNotification("pet.reaction",{text:m,style:h,actions:f.length>0?f:void 0}),n.id!==void 0&&this.sendResponse(n.id,{ok:!0,action:t,level:a,experience:c,events:l.map(b=>({type:b.type,level:b.level})),reaction:m?{text:m,style:h,actions:f.length>0?f:void 0}:null})}async function nb(n){let e=this.getActiveProjectRoot(),r=new Qt(e).load();if(n.id!==void 0&&this.sendResponse(n.id,{ok:!0,soul:r??null,growth:r?ml(r):null}),r){this.sendNotification("pet.soul_ready",{name:r.name,species:r.species,personality:r.personality,catchphrase:r.catchphrase,stats:r.stats,rarity:r.rarity,breed:r.breed,breedColors:r.breedColors});let s=Ce.getUnlockedAbilities(r.level).map(i=>i.name),o=Ce.getNextAbility(r.level);this.sendNotification("pet.growth",{level:r.level,experience:r.experience,xpNeeded:Ce.xpForLevel(r.level),abilities:s,nextAbility:o?{name:o.name,level:o.unlockedAtLevel}:void 0})}}async function rb(n){let e=n.params;if(!e?.description&&!e?.imageBase64){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:k.INVALID_PARAMS,message:"Provide description or imageBase64"});return}typeof this.ensureModelRegistryHydrated=="function"&&await this.ensureModelRegistryHydrated(),this.sendNotification("pet.state",{state:"building"}),this.sendNotification("pet.reaction",{text:"\u6B63\u5728\u5B75\u5316\u4F60\u7684\u4E13\u5C5E\u5BA0\u7269...",style:"thinking"});try{let t=e.description?.slice(0,10)??"\u81EA\u5B9A\u4E49\u5BA0\u7269",r=e.description??"";e.imageBase64&&(r=await this.forgeAnalyzeImage(e.imageBase64,e.description),this.sendNotification("pet.reaction",{text:"\u5206\u6790\u5B8C\u6210\uFF0C\u6B63\u5728\u751F\u6210\u9AA8\u67B6...",style:"thinking"}));let s=await this.forgeGenerateSkeleton(r),o=qt(s),i=Fn(o),a=0;for(;i.length>0&&a<2;){a++,this.sendNotification("pet.reaction",{text:`\u9AA8\u67B6\u7F3A\u5C11 ${i.join("\u3001")}\uFF0C\u91CD\u65B0\u751F\u6210 (${a}/${2})...`,style:"thinking",duration:3e3});let m=`\u4E0A\u6B21\u751F\u6210\u7F3A\u5C11\u4EE5\u4E0B\u90E8\u4F4D: ${i.join(", ")}\u3002\u8BF7\u786E\u4FDD\u6240\u6709 id \u5C5E\u6027\u90FD\u5B58\u5728\u3002`;s=await this.forgeGenerateSkeleton(r+`
|
|
864
864
|
|
|
865
865
|
`+m),o=qt(s),i=Fn(o)}i.length>0&&this.sendNotification("pet.reaction",{text:"\u9AA8\u67B6\u4E0D\u5B8C\u6574\uFF0C\u90E8\u5206\u52A8\u753B\u53EF\u80FD\u7F3A\u5931\uFF0C\u7EE7\u7EED\u751F\u6210...",style:"normal",duration:3e3}),this.sendNotification("pet.reaction",{text:"\u9AA8\u67B6\u751F\u6210\u5B8C\u6210\uFF0C\u5F00\u59CB\u6E32\u67D3\u5404\u72B6\u6001...",style:"thinking"});let c=["idle","thinking","working","done","happy","error","sleeping","eating"],l={baseSvg:o,parts:$n(o),colors:Un(o),characterDesc:r},u={};for(let m of c)u[m]=jn(l,m),this.sendNotification("pet.reaction",{text:`\u6E32\u67D3 ${m} \u72B6\u6001... (${Object.keys(u).length}/${c.length})`,style:"thinking",duration:2e3});let d=Ur(u.idle,u,{threshold:6});if(!d.passedAll&&d.retryStates.length>0&&(this.sendNotification("pet.reaction",{text:`\u4E00\u81F4\u6027\u68C0\u67E5\uFF1A${d.retryStates.length} \u4E2A\u72B6\u6001\u9700\u4F18\u5316...`,style:"thinking",duration:3e3}),d.overallScore<4)){let m=Fr(r,"all","\u9AA8\u67B6\u7ED3\u6784\u4E0D\u5B8C\u6574\u5BFC\u81F4\u591A\u72B6\u6001\u4E00\u81F4\u6027\u5DEE",1);s=await this.forgeGenerateSkeleton(m);let h={baseSvg:qt(s),parts:$n(qt(s)),colors:Un(qt(s)),characterDesc:r};for(let f of c)u[f]=jn(h,f)}let p={version:1,name:t,author:"user-generated",created:new Date().toISOString(),generator:"xiaozhi-pet-forge-v2-skeleton",source:{type:e.imageBase64?"image":"text",prompt:e.description},dimensions:{width:200,height:200},states:Object.fromEntries(c.map(m=>[m,{file:`states/${m}.svg`,loop:m!=="done"&&m!=="happy"&&m!=="eating",...m==="done"||m==="happy"?{duration:3e3}:m==="eating"?{duration:4e3}:{}}])),eyeTracking:{enabled:!0,pupils:[".left-eye .pupil",".right-eye .pupil"],maxOffset:3},colors:l.colors,consistency:{score:d.overallScore,method:"skeleton-parameterized"}};Lr(p),this.sendNotification("pet.reaction",{text:`\u2705 \u5BA0\u7269\u300C${t}\u300D\u5DF2\u953B\u9020\u5B8C\u6210\uFF01\u4E00\u81F4\u6027\u8BC4\u5206 ${d.overallScore.toFixed(1)}/10`,style:"excited"}),this.sendNotification("pet.state",{state:"done"}),this.sendNotification("pet.forged",{name:t,svgs:u}),n.id!==void 0&&this.sendResponse(n.id,{ok:!0,manifest:p,svgs:u,status:"complete",consistency:{score:d.overallScore,passedAll:d.passedAll}})}catch(t){this.sendNotification("pet.state",{state:"error"}),this.sendNotification("pet.reaction",{text:"\u953B\u9020\u5931\u8D25\u4E86...",style:"normal"}),n.id!==void 0&&this.sendResponse(n.id,void 0,{code:k.INTERNAL_ERROR,message:t.message??"Forge failed"})}}var h_=f_(import.meta.url);function y_(){for(let n of["../package.json","../../package.json"])try{return h_(n).version}catch{}return"0.0.0"}var sb=y_();function T_(n){let e=n.pathname.split("/").filter(Boolean),r=(e[e.length-1]??"").replace(/\.md$/i,"").replace(/[^a-zA-Z0-9_-]/g,"-");return/^(skill|readme|index|install|main)$/i.test(r)&&e.length>=2?e[e.length-2].replace(/[^a-zA-Z0-9_-]/g,"-"):r||""}var vo=class n{running=!1;startedAt=Date.now();rpcContract=new kr;rpcIds=new Map;rpcDeadlineTimers=new Map;activeTurn=null;turnDone=Promise.resolve();verbose;transport;registry;mediaClient;agent=null;lastLlmConfigKey="";currentSessionId="";currentTurnId="";currentHooks=null;mcpManager=null;mcpReady=Promise.resolve();pluginLoader=null;permissionChecker=null;permissionUnregister=null;currentTransport=null;currentApiKey="";currentModel="";currentProvider="";currentBaseUrl="";sessionState=null;currentMediaApiKeys=null;taskStore=new ds;mediaPersistence=new Ws;memoryPrefetchState=Ot();memoryProvider=null;memoryUserId="";lastUserMessageForAutoExtract;lastAssistantMessageForExtract;memdir=null;fileWatcher=null;pendingAskUser=new Map;sessionTaskDomain;acpDetector=new Ds;agentConfigStore=null;soloEvaluator=null;productOrchestrator=null;productPlanner=null;soloProcessManager=null;productProcessManager=null;acpServer=null;acpSessionHistory=new Map;resumedSessionHistory=new Map;idleDreamTimer=null;modelRegistryHydration=null;constructor(e){this.verbose=e.verbose,this.registry=new b_,this.mediaClient=new k_({registry:this.registry}),X().onChange(()=>{this.lastLlmConfigKey=""}),this.ensureModelRegistryHydrated().catch(()=>{});let t=Number(process.env.QLOGICAGENT_IDLE_DREAM_MS);t>0&&(Re.dream.idleMinutes=t/6e4);let r=Number(process.env.QLOGICAGENT_DREAM_COOLDOWN_MS);r>=0&&(Re.dream.cooldownMs=r),this.transport=e.transport??new bn({verbose:e.verbose}),this.taskStore.onTaskChange((s,o)=>{o&&this.sendNotification("task.updated",{taskId:s,type:o.type,lifecycle:o.lifecycle,label:o.label})}),ym({log:{info:s=>this.log(s),warn:s=>this.log(`[warn] ${s}`),error:s=>this.log(`[error] ${s}`),debug:s=>{e.verbose&&this.log(`[debug] ${s}`)}},onExecProgress:s=>{this.sendNotification("turn.exec_progress",{output:s.output,elapsedTimeSeconds:s.elapsedTimeSeconds,totalLines:s.totalLines,totalBytes:s.totalBytes})}})}getActiveProjectRoot(){let e=Oe();return e?.workspaceDir?e.workspaceDir:process.cwd()}async ensureModelRegistryHydrated(){return this.modelRegistryHydration||(this.modelRegistryHydration=(async()=>{let e=X();e.load(),await Rr(e),e.save()})().catch(e=>{this.modelRegistryHydration=null;let t=e instanceof Error?e.message:String(e);throw this.log(`[model-registry] failed to refresh llmrouter catalog: ${t}`),e})),this.modelRegistryHydration}setActiveWorkdir(e){e!==this.getActiveProjectRoot()&&(gm(e),this.mediaPersistence.setProjectDir(e))}start(){this.running=!0,this.log("qlogicagent started, waiting for JSON-RPC messages..."),this.transport.onMessage(e=>{if(this.acpServer){if(Sc(e)||Sr(e)){this.acpServer.dispatchMessage(e);return}if(vr(e)){let t=e.method;if(t==="initialize"||t.startsWith("session/")||t.startsWith("x/")||t.startsWith("fs/")){this.acpServer.dispatchMessage(e);return}}}if(!kc(e)){this.log("[warn] ignoring non-request message");return}this.handleMessage(e)}),this.transport.onClose(()=>{this.log("transport closed, shutting down"),this.stop()}),this.transport.start()}stop(){if(this.running){this.running=!1,this.cancelIdleDreamTimer();for(let e of this.rpcDeadlineTimers.values())clearTimeout(e);this.rpcDeadlineTimers.clear(),this.rpcIds.clear(),this.currentSessionId&&this.currentHooks&&(this.currentHooks.invoke("stop",{sessionId:this.currentSessionId,reason:"shutdown"}).catch(()=>{}),this.currentHooks.invoke("session.ended",{sessionId:this.currentSessionId}).catch(()=>{}));try{Ag().catch(()=>{}),this.fileWatcher&&(this.fileWatcher.stop(),this.fileWatcher=null),this.mcpManager&&(this.mcpManager.disconnectAll().catch(()=>{}),this.mcpManager=null),this.permissionUnregister&&(this.permissionUnregister(),this.permissionUnregister=null),this.activeTurn&&(this.activeTurn.abort(),this.activeTurn=null),this.transport.close()}catch(e){this.currentSessionId&&this.currentHooks&&this.currentHooks.invoke("stop.failed",{sessionId:this.currentSessionId,reason:"cleanup_error",error:e.message}).catch(()=>{})}this.log("stopped")}}methodHandlers=new Map([["initialize",e=>this.handleInitialize(e)],["agent.ping",e=>this.handlePing(e)],["agent.health",e=>this.handleHealth(e)],["agent.metrics",e=>this.handleMetrics(e)],["agent.cancel",e=>this.handleCancel(e)],["thread.turn",e=>lf.call(this,e)],["memory.dream",e=>no.call(this,e)],["agent.abort",e=>of.call(this,e)],["tool.approval.response",e=>af.call(this,e)],["thread.user_response",e=>cf.call(this,e)],["thread.list",e=>Nf.call(this,e)],["session.resume",e=>Wf.call(this,e)],["thread.create",e=>Df.call(this,e)],["session.getInfo",e=>Gf.call(this,e)],["session.create",e=>Of.call(this,e)],["session.resolve",e=>Lf.call(this,e)],["session.list",e=>$f.call(this,e)],["session.get",e=>jf.call(this,e)],["session.getMessages",e=>Uf.call(this,e)],["session.update",e=>Ff.call(this,e)],["session.delete",e=>Bf.call(this,e)],["session.deleteAll",e=>Hf.call(this,e)],["session.archive",e=>qf.call(this,e)],["memory.list",e=>Wh.call(this,e)],["memory.atlas",e=>Gh.call(this,e)],["memory.activity",e=>Kh.call(this,e)],["memory.ingest",e=>zh.call(this,e)],["memory.commit",e=>Xh.call(this,e)],["memory.addManual",e=>Vh.call(this,e)],["memory.read",e=>Yh.call(this,e)],["memory.write",e=>Jh.call(this,e)],["memory.search",e=>Qh.call(this,e)],["memory.delete",e=>Zh.call(this,e)],["memory.update",e=>ey.call(this,e)],["tools.list",e=>ty.call(this,e)],["media.listModels",e=>xy.call(this,e)],["media.cancel",e=>Py.call(this,e)],["media.status",e=>Iy.call(this,e)],["media.stt",e=>_y.call(this,e)],["settings.listProviders",e=>Cy.call(this,e)],["settings.addKey",e=>Ey.call(this,e)],["settings.removeKey",e=>My.call(this,e)],["settings.toggleKey",e=>Dy.call(this,e)],["settings.toggleModel",e=>Ny.call(this,e)],["settings.listModels",e=>Oy.call(this,e)],["settings.setActiveModel",e=>Ly.call(this,e)],["settings.getActiveModel",e=>$y.call(this,e)],["settings.getOverview",e=>jy.call(this,e)],["settings.refreshModels",e=>Uy.call(this,e)],["settings.validateKey",e=>Fy.call(this,e)],["provider.list",e=>ny.call(this,e)],["config.get",e=>ry.call(this,e)],["config.update",e=>sy.call(this,e)],["config.tunables",e=>oy.call(this,e)],["config.updateTunable",e=>iy.call(this,e)],["todos.list",e=>ay.call(this,e)],["tasks.list",e=>cy.call(this,e)],["tasks.cancel",e=>ly.call(this,e)],["agents.scan",e=>uy.call(this,e)],["agents.list",e=>py.call(this,e)],["agents.prompt",e=>wy.call(this,e)],["agents.config",e=>my.call(this,e)],["agents.setConfig",e=>gy.call(this,e)],["agents.getConfig",e=>fy.call(this,e)],["agents.removeConfig",e=>hy.call(this,e)],["agents.setGateway",e=>yy.call(this,e)],["agents.getGateway",e=>by.call(this,e)],["agents.processes",e=>vy.call(this,e)],["agents.kill",e=>Sy.call(this,e)],["agents.listConfigured",e=>ky.call(this,e)],["agents.getLog",e=>Ty.call(this,e)],["agents.testConnection",e=>Ry.call(this,e)],["solo.start",e=>th.call(this,e)],["solo.status",e=>nh.call(this,e)],["solo.cancel",e=>rh.call(this,e)],["solo.select",e=>sh.call(this,e)],["solo.list",e=>oh.call(this,e)],["solo.delete",e=>ih.call(this,e)],["solo.message",e=>ah.call(this,e)],["solo.evaluate",e=>ch.call(this,e)],["product.plan",e=>Sf.call(this,e)],["product.confirm",e=>Tf.call(this,e)],["product.message",e=>Rf.call(this,e)],["product.create",e=>wf.call(this,e)],["product.resume",e=>Af.call(this,e)],["product.pause",e=>xf.call(this,e)],["product.checkpoint",e=>Pf.call(this,e)],["product.status",e=>If.call(this,e)],["product.list",e=>_f.call(this,e)],["product.delete",e=>Cf.call(this,e)],["product.cancel",e=>Ef.call(this,e)],["product.rollback",e=>Mf.call(this,e)],["project.create",e=>vh.call(this,e)],["project.list",e=>Sh.call(this,e)],["project.delete",e=>Th.call(this,e)],["project.purgeAll",e=>Rh.call(this,e)],["project.rename",e=>wh.call(this,e)],["project.archive",e=>Ah.call(this,e)],["project.unarchive",e=>xh.call(this,e)],["project.update",e=>Ih.call(this,e)],["project.archiveByGroup",e=>Ph.call(this,e)],["session.switchProject",e=>Kf.call(this,e)],["session.focus",e=>zf.call(this,e)],["session.moveToProject",e=>Xf.call(this,e)],["session.getState",e=>Vf.call(this,e)],["files.list",e=>Eh.call(this,e)],["files.create",e=>Mh.call(this,e)],["files.rename",e=>Dh.call(this,e)],["files.delete",e=>Nh.call(this,e)],["files.gitStatus",e=>Oh.call(this,e)],["instructions.list",e=>Lh.call(this,e)],["instructions.read",e=>$h.call(this,e)],["instructions.write",e=>jh.call(this,e)],["instructions.delete",e=>Uh.call(this,e)],["skills.list",e=>dh.call(this,e)],["skills.activate",e=>uh.call(this,e)],["skills.deactivate",e=>ph.call(this,e)],["skills.delete",e=>mh.call(this,e)],["skills.promote",e=>gh.call(this,e)],["skills.stats",e=>fh.call(this,e)],["skills.pin",e=>hh.call(this,e)],["skills.unpin",e=>yh.call(this,e)],["skills.curator",e=>bh.call(this,e)],["skills.lifecycle",e=>kh.call(this,e)],["pet.hatch",e=>eb.call(this,e)],["pet.interact",e=>tb.call(this,e)],["pet.status",e=>nb.call(this,e)],["pet.forge",e=>rb.call(this,e)],["pet.confirm_response",e=>this.handlePetConfirmResponse(e)]]);handleMessage(e){if(e.id!==void 0){let r=Os(e);if(!r.ok){this.sendContractError(e.id,r.error);return}let s=this.rpcContract.begin(e.method,r.meta);if(s.status==="rejected"){this.sendContractError(e.id,s.error);return}if(s.status==="deduped"){this.sendContractErrorOrResult(e.id,s.result,s.error);return}this.rpcIds.set(e.id,r.meta),this.scheduleRpcDeadline(e.id,e.method,r.meta)}let t=this.methodHandlers.get(e.method);t?t(e):e.id!==void 0&&this.sendResponse(e.id,void 0,{code:k.METHOD_NOT_FOUND,message:`Unknown method: ${e.method}`})}handleInitialize(e){let t=e.params,r=t?.protocolVersion??"unknown",s=t?.host?.name??t?.hostName??"unknown",o=t?.host?.version??t?.hostVersion??"?",i=r.split(".")[0],a=un.split(".")[0];if(i!==a){this.log(`[initialize] protocol mismatch: host=${r} agent=${un}`),e.id!==void 0&&this.sendResponse(e.id,void 0,{code:k.PROTOCOL_MISMATCH,message:`Protocol version mismatch: host=${r}, agent=${un}`});return}this.log(`[initialize] host=${s} v${o}`),e.id!==void 0&&this.sendResponse(e.id,{protocolVersion:un,agent:{name:"qlogicagent",version:"0.1.0"},capabilities:{tools:At().map(c=>c.function.name),streaming:!0,threads:!0,notifications:["turn.start","turn.delta","turn.end","turn.error","turn.recovery","turn.tool_call","turn.tool_result","turn.tool_blocked","turn.reasoning_delta","turn.plan_update","turn.suggestions","turn.subagent_started","turn.subagent_delta","turn.subagent_ended","turn.media_result","turn.todos_updated","task.updated","turn.exec_progress","turn.artifact","tool.approval.request","turn.skill_instruction","turn.ask_user","memory.updated","session.info","permission.rule_updated","team.updated","turn.usage_update","pong"],methods:[...Bg]}}),this.ensureDefaultProject()}ensureDefaultProject(){let e=Oe();if(e)e.workspaceDir&&this.setActiveWorkdir(e.workspaceDir);else{let t=ee.join(q(),"workspaces","default");V.existsSync(t)||V.mkdirSync(t,{recursive:!0});let r=eu(t);Qc(t),this.setActiveWorkdir(t),this.sendNotification("project.created",{id:r.id,name:r.name,workspaceDir:r.workspaceDir,type:r.type})}this.ensureDefaultProjectDir();{let t=this.getActiveProjectRoot(),r=new Ct(t);r.ensureInitialized(),this.memdir=r}}ensureDefaultProjectDir(){let t=me().find(r=>r.type==="default"&&r.status==="active");t&&(V.existsSync(t.workspaceDir)||V.mkdirSync(t.workspaceDir,{recursive:!0}))}handlePing(e){e.id!==void 0&&this.sendResponse(e.id,{status:"ok"}),this.sendNotification("pong",{})}handleHealth(e){e.id!==void 0&&this.sendResponse(e.id,{ok:!0,status:this.running?"healthy":"stopping",uptimeMs:Date.now()-this.startedAt,protocolVersion:un,version:sb})}handleMetrics(e){e.id!==void 0&&this.sendResponse(e.id,{rpc:this.rpcContract.metrics()})}handleCancel(e){let t=e.params,r=t?.requestId,s=typeof r=="string"?this.rpcContract.cancel(r,t?.reason??"host-cancelled"):!1;s&&this.activeTurn&&this.activeTurn.abort(),e.id!==void 0&&this.sendResponse(e.id,{ok:!0,cancelled:s})}static SUGGESTION_PROMPT=`[SUGGESTION MODE]
|
|
866
866
|
Based on the conversation, suggest 1-3 short follow-up actions the user might naturally do next.
|
|
@@ -894,9 +894,9 @@ ${t?`\u7528\u6237\u8865\u5145\u63CF\u8FF0\uFF1A${t}`:""}
|
|
|
894
894
|
|
|
895
895
|
\u76F4\u63A5\u8F93\u51FA SVG \u4EE3\u7801\uFF1A`,i="";for await(let c of r.transport.stream({model:r.model,messages:[{role:"user",content:o}],maxTokens:4e3},r.apiKey))c.type==="delta"&&(i+=c.text);let a=i.match(/<svg[\s\S]*?<\/svg>/i);if(!a)throw new Error(`Failed to generate SVG for state: ${t}`);return a[0]}async forgeGenerateSkeleton(e){let{buildSkeletonPrompt:t}=await Promise.resolve().then(()=>(yo(),Jy)),r=this.resolveClientForPurpose("textGeneration");if(!r)throw new Error("No model available for skeleton generation");let s=t(e),o="";for await(let a of r.transport.stream({model:r.model,messages:[{role:"user",content:s}],maxTokens:6e3},r.apiKey))a.type==="delta"&&(o+=a.text);let i=o.match(/<svg[\s\S]*?<\/svg>/i);if(!i)throw new Error("Failed to generate skeleton SVG");return i[0]}async forgeScoreConsistency(e,t,r,s){let{buildConsistencyPrompt:o,parseConsistencyResponse:i}=await Promise.resolve().then(()=>(bo(),Zy)),a=this.resolveClientForPurpose("imageUnderstanding");if(!a)throw new Error("No vision model available for consistency scoring");let c=o(s,r),l=`data:image/svg+xml;base64,${Buffer.from(e).toString("base64")}`,u=`data:image/svg+xml;base64,${Buffer.from(t).toString("base64")}`,d="";for await(let p of a.transport.stream({model:a.model,messages:[{role:"user",content:c,imageUrls:[l,u]}],maxTokens:200},a.apiKey))p.type==="delta"&&(d+=p.text);return i(d)}async petAwardXp(e){try{let{PetSoulService:t}=await Promise.resolve().then(()=>(ko(),pl)),{PetGrowthEngine:r}=await Promise.resolve().then(()=>(ho(),Ky)),s=this.getActiveProjectRoot(),o=new t(s),i=o.load();if(!i)return;let a=r.xpForEvent(e),{newLevel:c,newXp:l,events:u,statBoosts:d}=r.processXpGain(i,a);i.level=c,i.experience=l;for(let[p,m]of Object.entries(d)){let h=p;i.stats[h]=Math.min(10,i.stats[h]+(m??0))}o.updateSoul(i),this.sendNotification("pet.growth",{level:c,experience:l,xpNeeded:r.xpForLevel(c)});for(let p of u)p.type==="molt"?this.sendNotification("pet.reaction",{text:`\u2728 \u8131\u58F3\u4E86\uFF01\u7B2C ${p.moltStage} \u6B21\u8715\u53D8`,style:"excited"}):p.type==="ability_unlock"&&p.ability&&this.sendNotification("pet.reaction",{text:`\u{1F389} \u89E3\u9501\uFF1A${p.ability.name}`,style:"excited"})}catch{}}isPetActive(){try{let e=xo("node:fs"),t=xo("node:path"),r=this.getActiveProjectRoot(),s=t.join(r,".qlogicagent","pet","soul.json");return e.existsSync(s)}catch{return!1}}pendingConfirms=new Map;async requestPetConfirm(e,t,r,s=3e4){let o=`confirm_${Date.now()}_${Math.random().toString(36).slice(2,8)}`;return this.sendNotification("pet.confirm",{confirmId:o,toolName:e,description:t,risk:r,timeoutMs:s}),new Promise(i=>{let a=setTimeout(()=>{this.pendingConfirms.delete(o),i(!1)},s+2e3);this.pendingConfirms.set(o,c=>{clearTimeout(a),i(c)})})}handlePetConfirmResponse(e){let{confirmId:t,approved:r}=e.params;this.permissionChecker&&this.permissionChecker.resolveApproval({approvalId:t,decision:r?"approved":"denied"});let s=this.pendingConfirms.get(t);s&&(this.pendingConfirms.delete(t),s(!!r)),e.id!=null&&this.sendResponse(e.id,{ok:!0})}async petReactionAfterTurn(e){try{let{maybeGenerateReaction:t,generateLLMReaction:r,PetSoulService:s}=await Promise.resolve().then(()=>(ko(),pl)),o=this.getActiveProjectRoot(),a=new s(o).load();if(a){let l=this.resolveClientForPurpose("smallModel");if(l){let u=[...e].reverse().find(m=>m.role==="assistant"),d=typeof u?.content=="string"?u.content.slice(0,100):"\u5B8C\u6210\u4E86\u4E00\u4E2A\u4EFB\u52A1",p=await r({turnSummary:d,soul:a},async(m,h)=>{let f="";for await(let y of l.transport.stream({model:l.model,messages:[{role:"user",content:m}],maxTokens:h},l.apiKey))y.type==="delta"&&(f+=y.text);return f.trim()||null});if(p){this.sendNotification("pet.reaction",{text:p.text,style:p.style,duration:1e4});return}}}let c=t("turn.end");c&&this.sendNotification("pet.reaction",{text:c.text,style:c.style,duration:1e4})}catch{}}ensureMemoryProvider(){if(!this.memoryProvider)try{let e=ua(this.getActiveProjectRoot()),t=da(e);if(t.provider){this.memoryProvider=t.provider;let r=process.env.QLOGIC_LLMROUTER_USER_ID?.trim();r&&(this.memoryUserId=r)}}catch{}}resolveAgent(e){let t=e.provider,r=e.model,s=e.apiKey,o=e.baseUrl;if(!t||!s){let v=X().getActiveModel("textGeneration");v&&(t=t??v.provider,r=r??v.model,s=s??v.apiKey,o=o??v.baseUrl,v.keyHandle.release({success:!0}),this.log(`[resolveAgent] from ModelRegistry: ${t}/${r}`))}if(!t||!s)return null;r=r??X().getProviderDefaultModel(t)??"";let i=`${t}:${r}:${s.slice(0,8)}:${o??""}`;if(this.agent&&this.lastLlmConfigKey===i)return e.model=r,e.provider=t,e.apiKey=s,o&&(e.baseUrl=o),this.agent;e.model=r,e.provider=t,e.apiKey=s,o&&(e.baseUrl=o);let a=ob({provider:t,model:r,apiKey:s,baseUrl:o},this.registry);v_()&&(a.transport=S_(a.transport,this.currentSessionId||"default"));let c={info:g=>this.log(g),warn:g=>this.log(`[warn] ${g}`),error:g=>this.log(`[error] ${g}`),debug:g=>{this.verbose&&this.log(`[debug] ${g}`)}},l={invoke:async(g,v,x,C)=>{if(v.startsWith("$"))return{result:x};let A=tt(v);if(!A)return{result:"",error:`Unknown tool: ${v}`};let $=`tc_${vt().slice(0,8)}`;try{let N=JSON.parse(x),M=await A.execute($,N,C),W=[],ie=M.content.map(ge=>{if(ge.type==="image"&&ge.data){let Mt=ge.mimeType||"image/png";return W.push(`data:${Mt};base64,${ge.data}`),"[Image]"}return ge.text??""}).join(`
|
|
896
896
|
`);W.length>0&&(M.imageUrls=[...W,...M.imageUrls??[]]);let Z=M.details?.error,ne=Z?ie:void 0,pe=M.details?.type,He=pe?.split("_")[0];if(pe==="three_d_generate"&&(He="3d"),He&&["image","tts","video","music","3d"].includes(He)){let ge=M.details?.mediaUrls??[],Mt=He;for(let St of ge)this.sendNotification("turn.media_result",{turnId:g,mediaType:Mt,url:St,model:M.details?.model,provider:M.details?.provider,...M.details?.durationMs?{durationSeconds:M.details.durationMs/1e3}:{},...M.details?.taskId?{taskId:M.details.taskId}:{}});if(ge.length>0)try{let St=await this.mediaPersistence.downloadAll(ge,{type:He,sessionId:this.currentSessionId||void 0},{warn:Ge=>this.log(Ge)});if(St.length>0){for(let Ge of St)ie=ie.replaceAll(Ge.remoteUrl,Ge.localPath);this.sendNotification("turn.media_persisted",{turnId:g,files:St.map(Ge=>({remoteUrl:Ge.remoteUrl,localPath:Ge.localPath,bytes:Ge.bytes,mimeType:Ge.mimeType}))})}}catch{}}if(pe==="task"&&!Z&&M.details?.taskList)try{let ge=M.details;ge?.taskList&&this.sendNotification("turn.todos_updated",{turnId:g,items:ge.taskList,summary:{total:ge.total??ge.taskList.length,completed:ge.completed??0,inProgress:ge.inProgress??0,notStarted:ge.notStarted??0}})}catch{}let Ee=Array.isArray(M.details?.matches)?M.details.matches:void 0,Wt=M.imageUrls;return{result:ie,error:ne,toolReferences:Ee,imageUrls:Wt}}catch(N){return{result:"",error:N instanceof Error?N.message:String(N)}}}},u=Bd(c);this.currentHooks=u,this.taskStore.setHooks(u,this.currentSessionId??""),um({onTaskCreated:g=>{u.invoke("task.created",{sessionId:this.currentSessionId??"",taskId:String(g.id),taskType:"planning",label:g.title}).catch(()=>{})},onTaskCompleted:g=>{u.invoke("task.completed",{sessionId:this.currentSessionId??"",taskId:String(g.id),taskType:"planning",label:g.title}).catch(()=>{})}});let d=ua(this.getActiveProjectRoot()),p=da(d);if(p.provider){this.memoryProvider=p.provider;let g=process.env.QLOGIC_LLMROUTER_USER_ID?.trim();this.memoryUserId=g||this.memoryUserId,this.memoryUserId&&zd(u,{memoryProvider:p.provider,localMemoryProvider:p.provider,userId:this.memoryUserId,log:{debug:v=>c.debug(v),warn:v=>c.warn(v)},getLastUserMessage:()=>this.lastUserMessageForAutoExtract,getLastAssistantMessage:()=>this.lastAssistantMessageForExtract,llmExtract:async v=>{let x=this.resolveClientForPurpose("smallModel");if(!x)return null;try{let C="";for await(let A of x.transport.stream({model:x.model,messages:[{role:"user",content:v}],tools:[],maxTokens:512},x.apiKey))A.type==="delta"&&(C+=A.text);return C.trim()||null}catch{return null}}},this.memoryPrefetchState),c.info("[memory] local provider initialized")}else p.error&&c.warn(`[memory] provider unavailable: ${p.error}`);iu(u,{currentCwd:this.getActiveProjectRoot(),log:{debug:g=>c.debug(g),warn:g=>c.warn(g)}}),Pd(u,c,{transport:a.transport,apiKey:a.apiKey});let m=e?.mcpServers,h=lc(m??{}),f=pd();try{if(V.existsSync(f)){let g=JSON.parse(V.readFileSync(f,"utf8")),v=lc(g),x=new Set(h.map(C=>C.name));h=[...h,...v.filter(C=>!x.has(C.name))]}}catch{}if(h.length>0){this.mcpManager&&this.mcpManager.disconnectAll().catch(()=>{}),this.mcpManager=new xs({servers:h,log:c}),mn(async()=>{await this.mcpManager?.disconnectAll()});let g=()=>this.mcpManager;Pe(bm(g)),Pe(km(g)),Pe(Wm({listServers:async()=>{let v=this.mcpManager;return v?v.getConnectedServers().map(C=>({name:C,status:"connected",transport:"stdio",toolCount:0,resourceCount:0,promptCount:0})):[]},listTools:async v=>{if(!this.mcpManager)return[];let C=`mcp__${v.replace(/[^a-zA-Z0-9_]/g,"_").toLowerCase()}__`;return zt().filter(A=>A.startsWith(C)).map(A=>({name:A.slice(C.length),prefixedName:A}))},callTool:async(v,x,C,A)=>{let N=`mcp__${v.replace(/[^a-zA-Z0-9_]/g,"_").toLowerCase()}__`+x,M=tt(N);if(!M)return{success:!1,error:`Tool not found: ${N}`};try{return{success:!0,content:(await M.execute(`mcp_${Date.now()}`,C??{},A)).content.map(Z=>Z.text??"").join(`
|
|
897
|
-
`)}}catch(W){return{success:!1,error:W.message}}},listResources:async v=>{let x=this.mcpManager;return x?(await x.listResources(v)).map(A=>({uri:A.uri,name:A.name,mimeType:A.mimeType,description:A.description,server:A.server})):[]},readResource:async(v,x)=>{let C=this.mcpManager;if(!C)throw new Error("MCP not initialized");return(await C.readResource(v,x)).map($=>({uri:$.uri,mimeType:$.mimeType,text:$.text}))},authenticate:async()=>({status:"unsupported",message:"OAuth not yet implemented in McpManager"})})),this.mcpReady=this.mcpManager.connectAll().then(()=>{this.mcpManager?.injectTools(),c.info(`[mcp] ${this.mcpManager?.getToolCount()??0} tools from ${this.mcpManager?.getConnectedServers().length??0} servers`)}).catch(v=>{c.warn(`[mcp] connection error: ${v instanceof Error?v.message:v}`)})}let y=[],b=dd();V.existsSync(b)&&y.push(b);let
|
|
897
|
+
`)}}catch(W){return{success:!1,error:W.message}}},listResources:async v=>{let x=this.mcpManager;return x?(await x.listResources(v)).map(A=>({uri:A.uri,name:A.name,mimeType:A.mimeType,description:A.description,server:A.server})):[]},readResource:async(v,x)=>{let C=this.mcpManager;if(!C)throw new Error("MCP not initialized");return(await C.readResource(v,x)).map($=>({uri:$.uri,mimeType:$.mimeType,text:$.text}))},authenticate:async()=>({status:"unsupported",message:"OAuth not yet implemented in McpManager"})})),this.mcpReady=this.mcpManager.connectAll().then(()=>{this.mcpManager?.injectTools(),c.info(`[mcp] ${this.mcpManager?.getToolCount()??0} tools from ${this.mcpManager?.getConnectedServers().length??0} servers`)}).catch(v=>{c.warn(`[mcp] connection error: ${v instanceof Error?v.message:v}`)})}let y=[],b=dd();V.existsSync(b)&&y.push(b);let T=e?.pluginPaths;if(Array.isArray(T))for(let g of T)typeof g=="string"&&V.existsSync(g)&&y.push(g);Rm(y,c).then(g=>{if(g.length===0)return;this.pluginLoader=new Ps({pluginDirs:g,hookRegistry:u,log:c}),this.pluginLoader.loadAll().then(x=>{c.info(`[plugins] ${x.length} loaded, ${this.pluginLoader?.getPluginSkills().length??0} skills`)}).catch(x=>{c.warn(`[plugins] load error: ${x instanceof Error?x.message:x}`)});let v=this.pluginLoader;u.register({point:"turn.submitted",handler:async()=>(await v.discoverNew(),await v.refreshActivations(),{action:"continue"}),label:"plugin-activation-refresh",priority:50})}).catch(g=>{c.warn(`[plugins] marketplace resolve error: ${g instanceof Error?g.message:g}`)});let w=e?.permissions,_=_s(w),I=new Is(_);if(_.mode,Oe()?.type==="group"){let g=rm();for(let v of g)I.addRule(v);oc(!0),c.info(`[permissions] group security mode active: ${g.length} rules injected`)}else oc(!1);this.permissionUnregister&&this.permissionUnregister(),this.permissionChecker=new Ms({ruleEngine:I,hookRegistry:u,auditLogger:new Es(this.getActiveProjectRoot()),sessionId:this.currentSessionId,getTurnId:()=>this.currentTurnId,onRequestApproval:async g=>{if(this.acpServer&&this.acpServer.sessionId)try{let v=await this.acpServer.requestPermission({sessionId:this.acpServer.sessionId,permissionId:g.approvalId,toolCall:{callId:g.callId,toolName:g.toolName,arguments:g.arguments?JSON.stringify(g.arguments):""},message:g.message,options:[{id:"allow",label:"Allow"},{id:"deny",label:"Deny"},{id:"allowAlways",label:"Always allow",persistent:!0}]});return{approvalId:g.approvalId,decision:v.optionId==="allow"||v.optionId==="allowAlways"?"approved":"denied"}}catch{return{approvalId:g.approvalId,decision:"denied"}}if(this.sendNotification("tool.approval.request",{approvalId:g.approvalId,callId:g.callId,toolName:g.toolName,arguments:g.arguments?JSON.stringify(g.arguments):"",message:g.message,suggestions:g.suggestions?.map(v=>`${v.pattern}:${v.behavior}`)}),this.isPetActive()){let v=g.toolName.match(/delete|rm|drop|reset|force/i)?"high":g.toolName.match(/write|exec|bash|shell|move/i)?"medium":"low";this.sendNotification("pet.confirm",{confirmId:g.approvalId,toolName:g.toolName,description:g.message??`\u5141\u8BB8\u6267\u884C ${g.toolName}\uFF1F`,risk:v,timeoutMs:3e4})}return new Promise(()=>{})},onPermissionUpdate:g=>{c.info(`[permissions] rule saved: ${g.pattern} \u2192 ${g.behavior}`),this.sendNotification("permission.rule_updated",{pattern:g.pattern,behavior:g.behavior})},onDenied:(g,v)=>{c.warn(`[permissions] blocked "${g}": ${v}`)}});let L=At();this.permissionChecker.setToolMeta(L),this.permissionUnregister=this.permissionChecker.register();let F=Tt(this.getActiveProjectRoot()),S=[F,Dt(),...Array.isArray(e?.skillPaths)?e.skillPaths:[]];Pe(Om({listSkills:()=>{let g=[];this.pluginLoader&&g.push(...this.pluginLoader.getPluginSkills());let v=e?.skillPaths;if(Array.isArray(v)){for(let x of v)if(typeof x=="string"){let C=ee.basename(x);g.some(A=>A.name===C)||g.push({name:C,source:"gateway",filePath:ee.join(x,"SKILL.md"),baseDir:x})}}return g},listSkillsFull:async g=>{let v=[],x=new Set,C=Dt();for(let A of S)try{let $=await V.promises.readdir(A,{withFileTypes:!0});for(let N of $){if(!N.isDirectory())continue;let M=ee.join(A,N.name,"SKILL.md");try{let W=await V.promises.readFile(M,"utf8"),ie=ee.basename(A);if(g&&ie!==g)continue;x.add(ie);let Z=A===C?"global":A===F?"project":"config",pe=W.match(/^---\n[\s\S]*?^version:\s*(\S+)/m)?.[1],He=W.startsWith(`---
|
|
898
898
|
`)?W.indexOf("---",4):-1,ge=(He>=0?W.slice(He+3).trimStart():W).split(`
|
|
899
|
-
`).find(Mt=>Mt.trim()&&!Mt.startsWith("#"))?.trim()??`Skill from ${ie}`;v.push({name:N.name,description:ge,category:ie,scope:Z,version:pe})}catch{}}}catch{}if(this.pluginLoader)for(let A of this.pluginLoader.getPluginSkills())g&&A.source!==g||(x.add(A.source??"plugin"),v.push({name:A.name,description:`Plugin skill (${A.source})`,category:A.source,scope:"plugin"}));return{skills:v,categories:[...x]}},readSkillContent:async g=>{for(let v of
|
|
899
|
+
`).find(Mt=>Mt.trim()&&!Mt.startsWith("#"))?.trim()??`Skill from ${ie}`;v.push({name:N.name,description:ge,category:ie,scope:Z,version:pe})}catch{}}}catch{}if(this.pluginLoader)for(let A of this.pluginLoader.getPluginSkills())g&&A.source!==g||(x.add(A.source??"plugin"),v.push({name:A.name,description:`Plugin skill (${A.source})`,category:A.source,scope:"plugin"}));return{skills:v,categories:[...x]}},readSkillContent:async g=>{for(let v of S){let x=ee.join(v,g,"SKILL.md");try{return await V.promises.readFile(x,"utf8")}catch{}}return null},viewSkill:async(g,v)=>{for(let x of S){let C=v?ee.join(x,g,v):ee.join(x,g,"SKILL.md");try{let A=await V.promises.readFile(C,"utf8");return{name:g,content:A}}catch{}}return null},executeSkillSubturn:async(g,v,x,C)=>{let A=`skill_${g}_${vt().slice(0,8)}`,$=this.agent;if(!$)return"[skill] Cannot execute: no LLM provider configured";let N=q(),M=this.currentSessionId??"skill";this.currentHooks?.invoke("subagent.started",{sessionId:M,turnId:A,subagentId:A,agentType:`skill:${g}`}).catch(()=>{});let W=new Set(["skill","agent"]),ie=At().filter(Ee=>!W.has(Ee.function.name)),Z=x??`Execute skill "${g}" instructions.`,ne=[],pe;for await(let Ee of $.run({turnId:A,sessionId:M,messages:[{role:"user",content:Z}],tools:ie,systemPrompt:v,config:{parentDepth:1,maxRounds:5}},C)){if(Ee.type==="end"&&Ee.content){this.currentHooks?.invoke("subagent.stopped",{sessionId:M,turnId:A,subagentId:A,agentType:`skill:${g}`,reason:"normal"}).catch(()=>{}),Gs(N,g,!0);let Wt=Be(N);return $c(Wt,g),We(N,Wt),Ee.content}if(Ee.type==="delta"&&Ee.text&&ne.push(Ee.text),Ee.type==="error"){pe=Ee.error;break}}if(this.currentHooks?.invoke("subagent.stopped",{sessionId:M,turnId:A,subagentId:A,agentType:`skill:${g}`,reason:pe?"error":"normal",error:pe}).catch(()=>{}),pe)return Gs(N,g,!1),`[skill "${g}"] error: ${pe}`;Gs(N,g,!0);let He=Be(N);return $c(He,g),We(N,He),ne.join("")||`[skill "${g}"] completed (no output)`},manageSkill:async g=>{let v=this.getActiveProjectRoot(),x=Tt(v),C=ee.join(x,g.name),A=ee.join(C,"SKILL.md"),$=q();switch(g.action){case"create":{let N=g.content??"",W=Bc(N,g.name,`Skill: ${g.name}`)??N,ie=zs(W,g.name);if(!ie.valid)return{success:!1,message:`Skill validation failed: ${ie.errors.join("; ")}`};let Z=Be($);if(Z.records[g.name]?.pinned&&V.existsSync(A))return{success:!1,message:`Skill "${g.name}" is pinned. Unpin it first.`};if(await V.promises.mkdir(C,{recursive:!0}),await V.promises.writeFile(A,W,"utf8"),this.sendNotification("turn.skill_instruction",{turnId:`skill-create-${Date.now()}`,instruction:{name:g.name,category:g.category??"learned",content:W,scope:"project"}}),pt(),Bt(Z,g.name,"created"),We($,Z),this.memoryProvider&&this.memoryUserId){let pe=W.split(`
|
|
900
900
|
`).slice(0,3).join(" ").slice(0,200),He=v?ee.basename(v):"unknown";this.memoryProvider.ingestExtracted([{text:`Learned skill "${g.name}" in project "${He}": ${pe}`,category:"skill-learning"}],this.memoryUserId).catch(()=>{})}let ne=v?` (project-scoped). To make it available across all projects, use: skill promote name:"${g.name}"`:"";return{success:!0,message:`Skill "${g.name}" created${ne}`,path:C}}case"edit":{let N=Be($);if(N.records[g.name]?.pinned)return{success:!1,message:`Skill "${g.name}" is pinned. Unpin it first.`};let M=g.content??"",ie=Bc(M,g.name)??M;return await V.promises.writeFile(A,ie,"utf8"),jc(N,g.name),We($,N),this.sendNotification("turn.skill_instruction",{turnId:`skill-edit-${Date.now()}`,instruction:{name:g.name,category:g.category??"learned",content:ie,scope:"project"}}),{success:!0,message:`Skill "${g.name}" updated`,path:A}}case"patch":{let N=Be($);if(N.records[g.name]?.pinned)return{success:!1,message:`Skill "${g.name}" is pinned. Unpin it first.`};let M=await V.promises.readFile(A,"utf8");if(!g.oldString||!M.includes(g.oldString))return{success:!1,message:"oldString not found in SKILL.md"};let W=M.replace(g.oldString,g.newString??"");return await V.promises.writeFile(A,W,"utf8"),jc(N,g.name),We($,N),this.sendNotification("turn.skill_instruction",{turnId:`skill-patch-${Date.now()}`,instruction:{name:g.name,category:g.category??"learned",content:W,scope:"project"}}),{success:!0,message:`Skill "${g.name}" patched`,path:A}}case"delete":{let N=Be($);return N.records[g.name]?.pinned?{success:!1,message:`Skill "${g.name}" is pinned. Unpin it first.`}:(await V.promises.rm(C,{recursive:!0,force:!0}),Ks(N,g.name),We($,N),this.sendNotification("turn.skill_instruction",{turnId:`skill-delete-${Date.now()}`,instruction:{name:g.name,category:g.category??"learned",action:"delete",scope:"project"}}),pt(),{success:!0,message:`Skill "${g.name}" deleted`})}default:return{success:!1,message:`Unknown action: ${g.action}`}}},promoteSkill:async g=>{let v=Tt(this.getActiveProjectRoot()),x=ee.join(v,g,"SKILL.md");try{await V.promises.access(x)}catch{return{success:!1,message:`Skill "${g}" not found in project skills. Cannot promote.`}}let C=Dt(),A=ee.join(C,g);await V.promises.mkdir(A,{recursive:!0});let $=ee.join(v,g),N=await V.promises.readdir($);for(let M of N){let W=await V.promises.readFile(ee.join($,M));await V.promises.writeFile(ee.join(A,M),W)}return this.sendNotification("turn.skill_instruction",{turnId:`skill-promote-${Date.now()}`,instruction:{name:g,category:"promoted",content:await V.promises.readFile(x,"utf8"),scope:"global"}}),await V.promises.rm($,{recursive:!0,force:!0}),this.sendNotification("turn.skill_instruction",{turnId:`skill-promote-cleanup-${Date.now()}`,instruction:{name:g,category:"learned",action:"delete",scope:"project"}}),pt(),{success:!0,message:`Skill "${g}" promoted to global (user-level) and removed from project scope. It will now be available across all projects.`,path:A}},installSkill:async(g,v)=>{let x;try{if(x=new URL(g),!["http:","https:"].includes(x.protocol))return{success:!1,message:`Invalid URL scheme: ${x.protocol}. Only http/https allowed.`}}catch{return{success:!1,message:`Invalid URL: ${g}`}}let C=v??T_(x);if(!C)return{success:!1,message:"Cannot derive skill name from URL. Please provide 'name' parameter."};try{let A=await fetch(g,{signal:AbortSignal.timeout(3e4)});if(!A.ok)return{success:!1,message:`Download failed: HTTP ${A.status} ${A.statusText}`};let $=A.headers.get("content-length");if($&&parseInt($,10)>512e3)return{success:!1,message:"Content too large (>512KB). Skill files should be small markdown documents."};let N=await A.text();if(!N.trim())return{success:!1,message:"Downloaded content is empty."};if(N.length>512e3)return{success:!1,message:"Content too large (>512KB). Skill files should be small markdown documents."};if(N.trimStart().startsWith("<!DOCTYPE")||N.trimStart().startsWith("<html"))return{success:!1,message:"URL returned an HTML page, not a raw markdown file. Use a raw/direct download link."};let M=Dt(),W=ee.join(M,C);return await V.promises.mkdir(W,{recursive:!0}),await V.promises.writeFile(ee.join(W,"SKILL.md"),N,"utf8"),this.sendNotification("turn.skill_instruction",{turnId:`skill-install-${Date.now()}`,instruction:{name:C,category:"installed",content:N,scope:"global"}}),pt(),{success:!0,message:`Skill "${C}" installed from ${x.host}. Available globally across all projects.`,path:W}}catch(A){return{success:!1,message:`Install failed: ${A instanceof Error?A.message:String(A)}`}}}})),Pe(jm({abortSignal:void 0,currentForkDepth:0,forkAgent:async g=>{let v=Qr(g.agent);if(!v)return{agentId:"",status:"failed",error:`Unknown agent type: ${g.agent}`};if(!this.agent||!this.currentTransport||!this.currentApiKey||!this.currentModel)return{agentId:"",status:"failed",error:"No LLM provider configured"};let x=zt(),C=Oi(x,v),$=At().filter(ne=>C.includes(ne.function.name)),N=ba($,!0),M=g.maxTurns??v.maxTurns??200;if(Re.isTeamBudgetExceeded())return{agentId:`fork-${g.agent}-budget-exceeded`,status:"failed",output:void 0,error:Re.teamBudgetExceededError(),tokensUsed:0};let W=await Ic({promptMessages:[{role:"user",content:g.prompt}],tools:N,transport:this.currentTransport,toolInvoker:l,apiKey:this.currentApiKey,model:this.currentModel,log:c,hooks:u,forkLabel:`agent-${g.agent}`,maxTurns:M,parentSignal:g.abortSignal,parentDepth:0,onEvent:ne=>{ne.type==="delta"&&ne.text&&this.sendNotification("turn.subagent_delta",{agentType:g.agent,text:ne.text})}}),ie=W.events.filter(ne=>ne.type==="end"&&"content"in ne).map(ne=>ne.content??"").join("")||W.events.filter(ne=>ne.type==="delta"&&"text"in ne).map(ne=>ne.text).join(""),Z=W.totalUsage.inputTokens+W.totalUsage.outputTokens;return Re.recordForkTokens(Z),{agentId:`fork-${g.agent}-${vt().slice(0,8)}`,status:W.ok?"completed":"failed",output:ie||void 0,error:W.error,tokensUsed:Z}}}));let ce=lt(),le=new Map([["model",{key:"model",value:this.currentModel??"",type:"string",description:"Default LLM model"}],["language",{key:"language",value:"zh-cn",type:"string",description:"UI / response language"}],["verbose",{key:"verbose",value:this.verbose,type:"boolean",description:"Enable verbose logging"}],["maxRounds",{key:"maxRounds",value:25,type:"number",description:"Default max tool-call rounds per turn"}],["theme",{key:"theme",value:"auto",type:"enum",description:"Color theme",options:["auto","light","dark"]}]]),j=async()=>{try{return JSON.parse(await V.promises.readFile(ce,"utf8"))}catch{return{}}},ke=async g=>{await V.promises.mkdir(ee.dirname(ce),{recursive:!0}),await V.promises.writeFile(ce,JSON.stringify(g,null,2),"utf8")};Pe(Um({getConfig:async g=>{let v=le.get(g);if(!v)return{success:!1,error:`Unknown key: ${g}`};let x=await j(),C=g in x?x[g]:v.value;return{success:!0,setting:{...v,value:C,readOnly:fr.includes(g)}}},setConfig:async(g,v)=>{let x=le.get(g);if(!x)return{success:!1,error:`Unknown key: ${g}`};let C=await j(),A=g in C?C[g]:x.value;return C[g]=v,await ke(C),{success:!0,previousValue:A,setting:{...x,value:v}}},listConfig:async()=>{let g=await j();return{success:!0,settings:[...le.values()].map(x=>({...x,value:x.key in g?g[x.key]:x.value,readOnly:fr.includes(x.key)}))}},resetConfig:async g=>{let v=le.get(g);if(!v)return{success:!1,error:`Unknown key: ${g}`};let x=await j();return delete x[g],await ke(x),{success:!0,setting:v}},isValidKey:g=>le.has(g)}));let oe=new Map,$e=g=>{let v=/^(\d+)([smhd])$/.exec(g.trim());if(!v)return null;let x=parseInt(v[1],10),C=v[2];return x*({s:1e3,m:6e4,h:36e5,d:864e5}[C]??6e4)},te=g=>{g.timerId&&clearTimeout(g.timerId);let v=$e(g.schedule);if(!v)return;let x=Date.now(),C=v-x%v||v;g.timerId=setTimeout(()=>{g.lastRunAt=new Date().toISOString(),g.repeat.completed++,g.lastStatus="success",c.info(`[cron] triggered job ${g.id} (${g.name})`),this.sendNotification("system.activity",{category:"cron",level:"info",title:`\u5B9A\u65F6\u4EFB\u52A1\u89E6\u53D1: ${g.name}`,detail:`\u8C03\u5EA6 ${g.scheduleDisplay}\uFF0C\u7B2C ${g.repeat.completed} \u6B21\u6267\u884C`}),g.repeat.times===null||g.repeat.completed<g.repeat.times?te(g):(g.state="paused",g.enabled=!1,this.sendNotification("system.activity",{category:"cron",level:"info",title:`\u5B9A\u65F6\u4EFB\u52A1\u5B8C\u6210: ${g.name}`,detail:`\u5DF2\u8FBE\u5230\u6700\u5927\u6267\u884C\u6B21\u6570 (${g.repeat.completed}\u6B21)`}))},C),g.nextRunAt=new Date(x+C).toISOString()};mn(async()=>{for(let g of oe.values())g.timerId&&clearTimeout(g.timerId)}),Pe(Bm({createJob:async g=>{let v=`cron_${vt().slice(0,8)}`,x={id:v,name:g.name??`Job ${v}`,prompt:g.prompt,schedule:g.schedule,scheduleDisplay:g.schedule,state:"scheduled",enabled:!0,repeat:{times:g.repeat??null,completed:0},allowedTools:g.allowedTools};return oe.set(v,x),te(x),{success:!0,job:{...x,timerId:void 0}}},listJobs:async()=>({success:!0,jobs:[...oe.values()].map(v=>({...v,timerId:void 0}))}),getJob:async g=>{let v=oe.get(g);return v?{success:!0,job:{...v,timerId:void 0}}:{success:!1,error:`Job not found: ${g}`}},updateJob:async(g,v)=>{let x=oe.get(g);return x?(v.prompt!==void 0&&(x.prompt=v.prompt),v.schedule!==void 0&&(x.schedule=v.schedule,x.scheduleDisplay=v.schedule),v.name!==void 0&&(x.name=v.name),v.enabled!==void 0&&(x.enabled=v.enabled,x.state=v.enabled?"scheduled":"paused"),v.repeat!==void 0&&(x.repeat.times=v.repeat),v.allowedTools!==void 0&&(x.allowedTools=v.allowedTools),x.enabled?te(x):x.timerId&&(clearTimeout(x.timerId),x.timerId=void 0),{success:!0,job:{...x,timerId:void 0}}):{success:!1,error:`Job not found: ${g}`}},deleteJob:async g=>{let v=oe.get(g);return v?(v.timerId&&clearTimeout(v.timerId),oe.delete(g),{success:!0}):{success:!1,error:`Job not found: ${g}`}},pauseJob:async g=>{let v=oe.get(g);return v?(v.state="paused",v.enabled=!1,v.timerId&&(clearTimeout(v.timerId),v.timerId=void 0),{success:!0,job:{...v,timerId:void 0}}):{success:!1,error:`Job not found: ${g}`}},resumeJob:async g=>{let v=oe.get(g);return v?(v.state="scheduled",v.enabled=!0,te(v),{success:!0,job:{...v,timerId:void 0}}):{success:!1,error:`Job not found: ${g}`}},triggerJob:async g=>{let v=oe.get(g);return v?(v.lastRunAt=new Date().toISOString(),v.repeat.completed++,v.lastStatus="success",{success:!0,job:{...v,timerId:void 0}}):{success:!1,error:`Job not found: ${g}`}},validateSchedule:g=>$e(g)!==null||/^\d{1,2}\s/.test(g)?null:`Invalid schedule: ${g}. Use shorthand (5m, 1h, 1d) or cron expression.`}));let Y=new Map;mn(async()=>{for(let g of Y.values())g.cleanup();Y.clear()}),Pe(Hm({startMonitor:async g=>{if(Y.has(g.monitorId))return{action:"start",success:!1,error:`Monitor "${g.monitorId}" already exists.`};let v={monitorId:g.monitorId,source:g.source,target:g.target,conditions:g.conditions,startedAt:Date.now(),timeoutSeconds:g.timeoutSeconds,eventCount:0},x=()=>{};if(g.source==="file")try{let C=V.watch(g.target,{persistent:!1},()=>{v.eventCount++,c.info(`[monitor] file change detected: ${g.target}`)});x=()=>C.close()}catch{return{action:"start",success:!1,error:`Cannot watch: ${g.target}`}}if(g.timeoutSeconds>0){let C=setTimeout(()=>{let $=Y.get(g.monitorId);$&&($.cleanup(),Y.delete(g.monitorId))},g.timeoutSeconds*1e3),A=x;x=()=>{clearTimeout(C),A()}}return Y.set(g.monitorId,{info:v,cleanup:x}),{action:"start",success:!0,monitorId:g.monitorId}},stopMonitor:async g=>{let v=Y.get(g);return v?(v.cleanup(),Y.delete(g),{action:"stop",success:!0,monitorId:g}):{action:"stop",success:!1,error:`Monitor "${g}" not found.`}},listMonitors:async()=>[...Y.values()].map(g=>g.info)}));let R=new Map,B={info:g=>c.info(g),warn:g=>c.warn(g)},U=new _t({onNotification:(g,v,x)=>{this.sendNotification("team.member.notification",{memberId:g,method:v,params:x})},onStateChange:(g,v)=>{this.sendNotification("team.member.state",{memberId:g,state:v});let x=U.getHandle(g),A=U.getUsageTracker(g)?.getUsage();this.emitAgentStatus(g,v,{missedBeats:U.getMissedBeats(g),lastActivityAt:x?.lastActivityAt,usage:A&&A.totalTokens>0?{inputTokens:A.inputTokens,outputTokens:A.outputTokens,totalTokens:A.totalTokens}:void 0})},onExit:(g,v,x)=>{for(let C of R.values()){let A=C.members.find($=>$.cwd&&`team-${C.name}-${$.name}`.replace(/[^a-zA-Z0-9-]/g,"-").toLowerCase()===g.replace(/^team-/,""));A&&(A.isActive=!1)}c.info(`[team] member ${g} exited (code=${v}, signal=${x})`)},onMcpToolCall:(g,v,x)=>this.handleMcpToolCall(g,v,x),log:{info:g=>c.info(g),warn:g=>c.warn(g),debug:g=>c.debug(g)},sessionDir:ee.join(q(),"agent-logs")});mn(async()=>{U.dispose()}),Pe(qm({createTeam:async g=>{if(R.has(g.teamName))return{success:!1,error:`Team "${g.teamName}" already exists.`};let v=await ar(),x=[];for(let A of g.members??[]){let $={...A,isActive:!0};if(v){let N=`team-${g.teamName}-${A.name}`.replace(/[^a-zA-Z0-9-]/g,"-").toLowerCase(),M=await Pp(v,N,B);M?($.worktreePath=M.worktreePath,$.worktreeBranch=M.branch,$.cwd=M.worktreePath,c.info(`[team] provisioned worktree for ${A.name}: ${M.worktreePath}`)):($.cwd=process.cwd(),c.warn(`[team] worktree provision failed for ${A.name}, using shared cwd`))}else $.cwd=process.cwd();x.push($)}let C={name:g.teamName,description:g.description,leadId:this.currentSessionId??"default",members:x,createdAt:new Date().toISOString()};R.set(g.teamName,C);for(let A of x){if(!A.cwd)continue;let $=`team-${g.teamName}-${A.name}`.replace(/[^a-zA-Z0-9-]/g,"-").toLowerCase();try{await U.spawn({memberId:$,name:A.name,cwd:A.cwd,prompt:`You are the "${A.name}" team member. Role: ${A.role}.`,agentType:A.role,verbose:this.verbose}),c.info(`[team] spawned child process for ${A.name} in ${A.cwd}`)}catch(N){c.warn(`[team] failed to spawn child process for ${A.name}: ${N instanceof Error?N.message:String(N)}`),A.isActive=!1}}return this.sendNotification("team.updated",{teamName:g.teamName,action:"created",members:C.members.map(A=>({agentName:A.name,role:A.role,worktreePath:A.worktreePath,pid:U.getHandle(`team-${g.teamName}-${A.name}`.replace(/[^a-zA-Z0-9-]/g,"-").toLowerCase())?.pid}))}),{success:!0,team:C}},deleteTeam:async g=>{let v=R.get(g);if(!v)return{success:!1,error:`Team "${g}" not found.`};for(let C of v.members){let A=`team-${g}-${C.name}`.replace(/[^a-zA-Z0-9-]/g,"-").toLowerCase();U.kill(A),U.remove(A)}let x=await ar();if(x)for(let C of v.members)C.worktreePath&&C.worktreeBranch&&(await Ip(x,C.worktreePath,C.worktreeBranch,B),c.info(`[team] cleaned up worktree for ${C.name}: ${C.worktreePath}`));return R.delete(g),this.sendNotification("team.updated",{teamName:g,action:"destroyed",members:[]}),{success:!0}},listTeams:async()=>({success:!0,teams:[...R.values()]}),getTeamStatus:async g=>{let v=R.get(g);if(!v)return{success:!1,error:`Team "${g}" not found.`};let x={};for(let C of v.members){let A=`team-${g}-${C.name}`.replace(/[^a-zA-Z0-9-]/g,"-").toLowerCase(),$=U.getStatus(A);$&&(C.isActive=$.alive,x[C.name]={mediaProgress:$.mediaProgress,lastToolCall:$.lastToolCall,idleFor:$.idleFor,runningFor:$.runningFor})}return{success:!0,team:v,memberProgress:x}}}));{let g=this.memdir;Pe({name:ug,label:pg,description:gg,parameters:mg,execute:async(v,x)=>{let C=await fg(x,{memdir:g,provider:this.memoryUserId?this.memoryProvider??void 0:void 0,localProvider:this.memoryUserId?this.memoryProvider??void 0:void 0,userId:this.memoryUserId});return{content:[{type:"text",text:C.message}],details:{type:"memory",action:C.action,ok:C.ok}}}})}Xd(u,{getMemdir:()=>this.memdir,log:{debug:g=>c.debug(g),warn:g=>c.warn(g)}},this.memoryPrefetchState);{let g=e?.workdir??process.cwd(),v=Vm(g,this.currentSessionId||"default");Pe(Km(v))}Pe(zm({sendNotification:async g=>(c.info(`[notify] ${g.title??""}: ${g.message}`),{delivered:!0,channel:g.channel??"cli"})})),Pe(Xm({sendMessage:async g=>(c.info(`[send_message] ${g.senderId} \u2192 ${g.to}: ${g.message}`),{success:!0,recipients:[g.to]}),getSenderId:()=>this.currentSessionId??"default",listTeammates:()=>[]}));{let g=e?.workdir??process.cwd(),v,x=()=>(v||(v=So.createContext({...{readFile:async A=>V.promises.readFile(ee.resolve(g,A),"utf8"),writeFile:async(A,$)=>{await V.promises.writeFile(ee.resolve(g,A),$,"utf8")},editFile:async(A,$)=>{let N=await V.promises.readFile(ee.resolve(g,A),"utf8");for(let M of $)N=N.replace(M.oldText,M.newText);return await V.promises.writeFile(ee.resolve(g,A),N,"utf8"),N},exec:async A=>{let $=await import("node:child_process");return new Promise(N=>{$.execFile("bash",["-c",A],{cwd:g,timeout:3e4},(M,W,ie)=>{N({stdout:W?.toString()??"",stderr:ie?.toString()??"",exitCode:M?M.code??1:0})})})},glob:async A=>{try{let{globSync:$}=await import("node:fs");return $(A,{cwd:g})}catch{return[]}},grep:async(A,$)=>{let N=[],M=ee.resolve(g,$??".");try{let W=await import("node:child_process"),ie=await new Promise(Z=>{W.execFile("grep",["-rn",A,M,"--include=*"],{timeout:1e4},(ne,pe)=>Z(pe?.toString()??""))});for(let Z of ie.split(`
|
|
901
901
|
`).filter(Boolean).slice(0,100)){let ne=Z.match(/^(.+?):(\d+):(.*)$/);ne&&N.push({file:ne[1],line:parseInt(ne[2]),text:ne[3]})}}catch{}return N},console:{log:(...A)=>A.map(String).join(" ")}},setTimeout,clearTimeout,Promise,JSON,Math,Date,Array,Object,String,Number,Boolean,RegExp,Map,Set,Error,Buffer})),v);Pe(Qm({executeInVm:async C=>{let A=Date.now();try{let $=x(),N=await So.runInContext(`(async () => { ${C} })()`,$,{timeout:3e4});return{output:N!==void 0?String(N):"",duration:Date.now()-A}}catch($){return{output:"",error:$ instanceof Error?$.message:String($),duration:Date.now()-A}}},resetVm:()=>{v=void 0}}))}{let g=e?.workdir??process.cwd();Pe(Zm({executeOperation:async v=>{switch(v.operation){case"goToDefinition":case"findReferences":return{type:"locations",locations:[]};case"hover":return{type:"hover",hover:null};case"documentSymbol":return{type:"symbols",symbols:[]};case"diagnostics":return{type:"diagnostics",diagnostics:[]};case"completion":return{type:"completions",completions:[]};case"signatureHelp":return{type:"signatureHelp",signatures:[]};case"rename":return{type:"rename",edits:[]};case"codeAction":return{type:"codeActions",actions:[]};default:return{type:"locations",locations:[]}}},resolvePath:v=>ee.isAbsolute(v)?v:ee.resolve(g,v)}))}let we=e?.workdir??process.cwd(),fe=wg({projectRoot:we,ruleEngine:I,hooks:u,log:g=>c.info(`[settings] ${g}`)});mn(async()=>{fe()}),this.currentSessionId&&u.invoke("session.created",{sessionId:this.currentSessionId}).catch(()=>{}),this.fileWatcher&&this.fileWatcher.stop();let Et=e?.workdir??process.cwd();return Ru({projectRoot:Et,sessionId:this.currentSessionId,hooks:u,log:g=>c.debug(g),onInstructionCacheReset:_u}).then(g=>{this.fileWatcher=g,mn(async()=>{this.fileWatcher?.stop()})}).catch(g=>{c.warn(`[file-watcher] init error: ${g instanceof Error?g.message:g}`)}),this.agent=new tr({llmTransport:a.transport,apiKey:a.apiKey,toolInvoker:l,log:c,hooks:u,maxRounds:e.maxRounds,verbose:this.verbose,projectRoot:this.getActiveProjectRoot()}),this.lastLlmConfigKey=i,this.currentTransport=a.transport,this.currentApiKey=a.apiKey,this.currentModel=r,this.currentProvider=t,this.currentBaseUrl=o??"",this.log(`created Agent (provider: ${t}, model: ${r})`),this.agent}static STATE_TO_STATUS={starting:"spawning",ready:"available",running:"running",completed:"available",failed:"failed",killed:"unavailable"};emitAgentStatus(e,t,r){let s=n.STATE_TO_STATUS[t]??"unavailable",o={agentId:e,status:s};(r?.missedBeats!==void 0||r?.lastActivityAt!==void 0)&&(o.health={missedBeats:r.missedBeats??0,lastActiveAt:r.lastActivityAt?new Date(r.lastActivityAt).toISOString():new Date().toISOString()}),r?.usage&&(o.usage=r.usage),this.sendNotification("agents.status",o)}async handleMcpToolCall(e,t,r){let s=tt(t);if(!s)return`Error: Unknown tool "${t}"`;let o=`mcp_${e}_${vt().slice(0,8)}`;try{return(await s.execute(o,r)).content.map(a=>a.text??"").join(`
|
|
902
902
|
`)||"OK"}catch(i){return`Error: ${i instanceof Error?i.message:String(i)}`}}async ensureAgentConfigStore(){return this.agentConfigStore||(this.agentConfigStore=new $s(this.getActiveProjectRoot()),await this.agentConfigStore.load(),this.acpDetector.setConfigStore(this.agentConfigStore.getData())),this.agentConfigStore}sendResponse(e,t,r){let s=this.rpcIds.get(e);if(s){let i=this.rpcContract.settle(s.requestId,t,r);if(this.clearRpcLifecycle(e),!i.accepted){this.log(`[rpc] dropped late response id=${String(e)} requestId=${s.requestId} reason=${i.reason}`);return}}let o={jsonrpc:"2.0",id:e};r?o.error=r:o.result=t,this.writeStdout(o)}sendContractError(e,t){let r={jsonrpc:"2.0",id:e,error:t};this.writeStdout(r)}sendContractErrorOrResult(e,t,r){if(r){this.sendContractError(e,r);return}let s={jsonrpc:"2.0",id:e,result:t};this.writeStdout(s)}scheduleRpcDeadline(e,t,r){let s=Math.max(0,r.deadlineAt-Date.now()),o=setTimeout(()=>{if(!this.rpcIds.has(e))return;let i=this.rpcContract.expire(r.requestId);this.clearRpcLifecycle(e),i&&(this.log(`[rpc] deadline exceeded method=${t} id=${String(e)} requestId=${r.requestId}`),this.writeStdout({jsonrpc:"2.0",id:e,error:{code:k.REQUEST_DEADLINE_EXCEEDED,message:`RPC request deadline exceeded: ${t}.`}}))},s);o.unref?.(),this.rpcDeadlineTimers.set(e,o)}clearRpcLifecycle(e){let t=this.rpcDeadlineTimers.get(e);t&&clearTimeout(t),this.rpcDeadlineTimers.delete(e),this.rpcIds.delete(e)}sendNotification(e,t){if(this.acpServer&&this.acpServer.sessionId)Fg(this.acpServer,this.acpServer.sessionId,e,t);else{let r={jsonrpc:"2.0",method:e,params:t};this.writeStdout(r)}e==="turn.end"&&this.resetIdleDreamTimer(),e==="turn.start"&&this.cancelIdleDreamTimer()}writeStdout(e){this.transport.send(e)}log(e){this.verbose&&process.stderr.write(`${JSON.stringify({ts:new Date().toISOString(),level:"info",service:"qlogicagent",message:e})}
|