qlogicagent 1.2.0 → 1.2.1

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 CHANGED
@@ -22,7 +22,7 @@ ${g}`},b=[...o,...c,f,...p],h=Date.now()-n,k=b.reduce((x,R)=>x+this.config.estim
22
22
  `,e+=Vd,e}async function hi(r,e,t,n=ai){if(r.length<=n||mi(r))return r;let o=await gi(r,e,t);return o?fi(o):r.slice(0,n)+`
23
23
  ...[truncated ${r.length-n} chars]`}function Yd(r){let e=[],t=[];for(let n of r)n.role==="tool"&&typeof n.content=="string"&&n.tool_call_id?mi(n.content)||t.push({toolCallId:n.tool_call_id,content:n.content,size:n.content.length}):n.role==="assistant"&&t.length>0&&(e.push(t),t=[]);return t.length>0&&e.push(t),e}function Xd(r,e){let t=[],n=[],o=[];for(let s of r){let i=e.replacements.get(s.toolCallId);i!==void 0?t.push({...s,replacement:i}):e.seenIds.has(s.toolCallId)?n.push(s):o.push(s)}return{mustReapply:t,frozen:n,fresh:o}}function Qd(r,e,t){let n=[...r].sort((i,a)=>a.size-i.size),o=[],s=e+r.reduce((i,a)=>i+a.size,0);for(let i of n){if(s<=t)break;o.push(i),s-=i.size}return o}async function yi(r,e,t,n=li){let o=Yd(r);if(o.length===0)return{messages:r,newlyReplacedCount:0};let s=new Map,i=[];for(let c of o){let{mustReapply:d,frozen:p,fresh:m}=Xd(c,e);for(let k of d)s.set(k.toolCallId,k.replacement);if(m.length===0){for(let k of c)e.seenIds.add(k.toolCallId);continue}let g=p.reduce((k,x)=>k+x.size,0),f=m.reduce((k,x)=>k+x.size,0),b=g+f>n?Qd(m,g,n):[],h=new Set(b.map(k=>k.toolCallId));for(let k of c)h.has(k.toolCallId)||e.seenIds.add(k.toolCallId);b.length>0&&i.push(...b)}if(s.size===0&&i.length===0)return{messages:r,newlyReplacedCount:0};let a=await Promise.all(i.map(async c=>{let d=await gi(c.content,c.toolCallId,t);return{candidate:c,result:d}})),l=0;for(let{candidate:c,result:d}of a){if(e.seenIds.add(c.toolCallId),!d)continue;let p=fi(d);s.set(c.toolCallId,p),e.replacements.set(c.toolCallId,p),l++}return s.size===0?{messages:r,newlyReplacedCount:0}:{messages:r.map(c=>{if(c.role!=="tool"||!c.tool_call_id)return c;let d=s.get(c.tool_call_id);return d===void 0?c:{...c,content:d}}),newlyReplacedCount:l}}var zd,ui,Vd,Jo=q(()=>{"use strict";gn();zd="tool-results",ui="<persisted-output>",Vd="</persisted-output>"});function tp(r){try{return JSON.parse(r)}catch{return}}var Zd,ep,fn,bi=q(()=>{"use strict";Ct();Jo();Zd=new Set(["read_file","file_read","FileRead","grep","Grep","glob","Glob","search","list_dir","find_files","web_fetch","web_search","WebFetch","WebSearch"]),ep=new Set(["bash","execute_command","Bash","shell"]),fn=class{tools=[];hasErrored=!1;erroredToolDescription="";discarded=!1;siblingAbortController;progressResolve;config;concurrencySafe;constructor(e){this.config=e,this.concurrencySafe=e.concurrencySafeTools??Zd,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(o=>o.status==="executing"),n=this.config.maxConcurrentTools;return n&&n>0&&t.length>=n?!1:t.length===0||e&&t.every(o=>o.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 n=t?.command??t?.file_path??t?.pattern??"";if(typeof n=="string"&&n.length>0){let o=n.length>40?n.slice(0,40)+"\u2026":n;return`${e.toolCall.function.name}(${o})`}return e.toolCall.function.name}createSyntheticError(e,t){let n=this.erroredToolDescription,o=t==="user_interrupted"?"User rejected tool use":t==="discarded"?"Streaming fallback - tool execution discarded":n?`Cancelled: parallel tool call ${n} errored`:"Cancelled: parallel tool call errored";return{callId:e.id,toolName:e.toolCall.function.name,ok:!1,error:o,message:kt(e.id,{ok:!1,error:o})}}async executeTool(e){e.status="executing";let n=(async()=>{let o=this.getAbortReason();if(o){e.results.push(this.createSyntheticError(e,o)),e.status="completed";return}let{toolInvoker:s,hooks:i,sessionId:a,turnId:l,log:u}=this.config,c=e.toolCall.function.name,d=!1,p=e.toolCall.function.arguments;if(i)try{let k=await i.invoke("tool.before_invoke",{sessionId:a,turnId:l,callId:e.id,toolName:c,arguments:tp(p)});if(k.action==="abort"){let x=k.reason??"blocked by policy";u.info(`tool ${c} blocked: ${x}`),e.results.push({callId:e.id,toolName:c,ok:!1,error:x,blocked:!0,blockReason:x,message:kt(e.id,{ok:!1,error:x})}),e.status="completed";return}k.action==="continue"&&k.context?.arguments&&(p=JSON.stringify(k.context.arguments))}catch{}let m=await s.invoke(l,c,p,this.siblingAbortController.signal),g=this.getAbortReason();if(g&&!d){e.results.push(this.createSyntheticError(e,g)),e.status="completed";return}let f=!m.error,b=m.result;f&&b&&b.length>5e4&&(b=await hi(b,e.id,a));let h=kt(e.id,{ok:f,payload:b,error:m.error});f||(d=!0,ep.has(c)&&(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:l,callId:e.id,toolName:c,ok:f,...m.error?{error:m.error}:{}}).catch(()=>{}),e.results.push({callId:e.id,toolName:c,ok:f,error:m.error,message:h}),e.status="completed"})();e.promise=n,n.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(n=>n.status==="executing"&&n.promise).map(n=>n.promise),t=new Promise(n=>{this.progressResolve=n});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{readFile as np}from"node:fs/promises";function Xe(r){let e=typeof r.content=="string"?r.content:r.content!=null?JSON.stringify(r.content):"";return Math.ceil(e.length/4)}function Qe(r){let e=0;for(let t of r)e+=Xe(t);return e}function wi(r){if(!r)return 128e3;if(r in Yo)return Yo[r];let e=r.toLowerCase();for(let[t,n]of Object.entries(Yo))if(e.startsWith(t.toLowerCase()))return n;return 128e3}function rp(r,e){return async(t,n)=>{let o=e?.transport,s=e?.apiKey;if(!o||!s)return r.debug("[context-compression] no LLM transport for summarization \u2014 using sync fallback"),Xo(t);try{let i="",a=e?.model??op;for await(let l of o.stream({model:a,messages:[{role:"system",content:"You are a precise conversation summarizer."},{role:"user",content:n}],maxTokens:2e3,temperature:.3},s,AbortSignal.timeout(3e4)))l.type==="delta"&&(i+=l.text);return i||(r.warn("[context-compression] empty summary response"),Xo(t))}catch(i){return r.warn({err:i.message},"[context-compression] summarize call error \u2014 using fallback"),Xo(t)}}}function Xo(r){let e=r.filter(n=>n.role==="user"),t=e.slice(0,10).map(n=>{let o=typeof n.content=="string"?n.content:JSON.stringify(n.content??"");return`- ${o.slice(0,200)}${o.length>200?"...":""}`});return`User requests (${e.length} messages):
24
24
  ${t.join(`
25
- `)}`}function sp(){return yo(new Ye(Qo),new Ne(20,Xe),new ct(Xe))}function Ti(r,e){let t=bo(new Ye(Qo),new Ne(20,Xe),new Tt({protectedHeadExchanges:1,protectedTailMessages:8,summarize:r,estimateTokens:Xe}),new ct(Xe));return new wt({inner:t,estimateTokens:Xe,onCacheInvalidated:e?.onCacheInvalidated})}function xi(r,e){let t=e?.budget??cn({modelContextWindow:wi(e?.model)}),o=(e?.pipeline??sp()).compress(r,t);if(o.droppedCount>0){let s=Qe(r),i=Qe(o.messages);vi.record({timestamp:Date.now(),strategy:o.strategy,tokensBefore:s,tokensAfter:i,droppedCount:o.droppedCount,latencyMs:o.metrics?.latencyMs??0,usedLlm:!1,cacheInvalidated:o.metrics?.cacheInvalidated??!1,tier:Rt(s,t)})}return o.droppedCount>0&&Zo?.(o.droppedCount,Qe(o.messages)),o}async function ip(r,e,t){let n=t??cn({modelContextWindow:wi(e.model)}),o=Qe(r),s=Rt(o,n),i;switch(s){case"none":i={messages:r,droppedCount:0,strategy:"none"};break;case"trim-only":i=new Ye(Qo).compress(r,n);break;case"sliding-window":{i=await Ti(e.summarize).compressAsync(r,n);break}case"llm-summarize":{let a=e.pipeline??Ti(e.summarize);i=St(a)?await a.compressAsync(r,n):a.compress(r,n);break}}return i.droppedCount>0&&(i={...i,messages:await To(i.messages,r,{maxFiles:5,maxTokenBudget:5e4,readFile:async a=>{try{return await np(a,"utf-8")}catch{return null}}})}),ap(r,i,n),i}function ap(r,e,t){if(e.droppedCount>0||e.metrics?.usedLlm){let n=e.metrics?.tokensBefore||Qe(r),o=e.metrics?.tokensAfter||Qe(e.messages);vi.record({timestamp:Date.now(),strategy:e.strategy,tokensBefore:n,tokensAfter:o,droppedCount:e.droppedCount,latencyMs:e.metrics?.latencyMs??0,usedLlm:e.metrics?.usedLlm??!1,cacheInvalidated:e.metrics?.cacheInvalidated??!1,tier:Rt(n,t)})}if(e.droppedCount>0){let n=e.metrics?.tokensAfter||Qe(e.messages);Zo?.(e.droppedCount,n)}}function lp(r,e){let t=rp(r,e),n={id:"builtin-compressor",label:"4-Layer Compression Funnel (built-in)",async compressAsync(o,s,i){return ip(o,{budget:s,model:i?.model,sessionId:i?.sessionId,summarize:t},s)}};ki.register(n),ki.activate(n.id),r.info(`[context-compression] registered context engine: ${n.id}`)}function Si(r,e,t){lp(e,t),r.register({point:"context.before_compact",priority:50,label:"context-compression-bridge",handler:(n,o)=>{let s=o.messageCount;return s&&s>0&&e.debug(`[context-compression] before_compact: ${s} messages entering compression`),{action:"continue"}}}),Zo=(n,o)=>{e.debug(`[context-compression] after_compact: removed ${n}, ${o} tokens remaining`),r.invoke("context.after_compact",{sessionId:"",turnId:"",removedCount:n,tokenCount:o}).catch(()=>{})}}var Yo,Qo,op,vi,ki,Zo,er=q(()=>{"use strict";Ct();Yo={"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};Qo=8e3,op="deepseek-v4-flash",vi=new vt(200),ki=new xt;Zo=null});function Ri(r,e,t){let n=t-e;return`[Budget] ${Math.round(r)}% used (${e.toLocaleString()} / ${t.toLocaleString()} tokens). ${n.toLocaleString()} tokens remaining. `+(r>=90?"Wrap up your current task \u2014 you are near the token limit.":"Continue working \u2014 do not summarize prematurely.")}var _i=q(()=>{"use strict"});var Ci={};Rs(Ci,{resolveToolEligibility:()=>mp});function up(r,e){if(cp.some(t=>t.test(r)))return!0;if(e)for(let t of e)try{if(new RegExp(t,"i").test(r))return!0}catch{}return!1}function dp(r,e){let t=r.function.name,n=r.meta,o=[];return e.blockedToolNames?.includes(t)?(o.push("policy_blocked"),{level:5,reasons:o}):n?.isReadOnly?(o.push("always_allowed"),{level:1,reasons:o}):n?.requiresApproval?(o.push("approval_required"),{level:4,reasons:o}):n?.isDangerous||up(t,e.dangerousPatterns)?(o.push("dangerous_tool"),{level:3,reasons:o}):{level:2,reasons:o}}function pp(r){switch(r){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 mp(r,e={}){let t=new Map,n=[],o=[],s=[];for(let i of r){let a=i.function.name,{level:l,reasons:u}=dp(i,e),c=pp(l),d={toolName:a,status:c,permissionLevel:l,approvalRequired:l===4,reasonCodes:u};t.set(a,d),l===5?o.push(d):(n.push(i),l===4&&s.push(d))}return{eligibleTools:n,blockedTools:o,approvalRequiredTools:s,eligibilityByName:t}}var cp,Ai=q(()=>{"use strict";cp=[/^(?:bash|shell|exec|terminal|run_command)$/i,/^(?:write_file|delete_file|move_file|create_directory)$/i,/^(?:git_push|git_reset|git_force)$/i]});function hp(r){let e=r.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 yp(r){let e=r.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 bp(r){return typeof r=="number"&&Number.isFinite(r)&&r>=1?Math.min(Math.round(r),100):Xs}function Mi(r){let e=r.message.toLowerCase();return r.status===413||e.includes("prompt_too_long")||e.includes("context_length_exceeded")||e.includes("maximum context length")}function kp(r){return r==="length"||r==="max_tokens"}function Pi(r){let e=r.message.toLowerCase();return(e.includes("image")||e.includes("media")||e.includes("file too large")||e.includes("payload too large"))&&(r.status===413||e.includes("too large")||e.includes("size"))}function Tp(r){let e=r.headers;if(!e)return null;let t=e["retry-after"]??e["Retry-After"];if(!t)return null;let n=parseInt(t,10);return!isNaN(n)&&n>0?n*1e3:null}function wp(r){if(r.status!==400)return null;let e=r.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),n=parseInt(e[3],10);if(isNaN(t)||isNaN(n))return null;let o=n-t-1e3;return o>=3e3?o:null}function vp(r){return r.filter(e=>e.role!=="assistant"?!0:!(typeof e.content=="string"&&e.content.trim()===""))}async function*Ii(r,e,t,n){let{turnId:o,sessionId:s,messages:i,tools:a,model:l,apiKey:u,temperature:c,hooks:d,signal:p}=r,m={sessionId:s,turnId:o},g=r.maxTurns??0,f=r.querySource,{resolveToolEligibility:b}=await Promise.resolve().then(()=>(Ai(),Ci)),h=b(a,r.toolEligibilityContext),k=h.eligibleTools;for(let z of h.blockedTools)yield{type:"tool_blocked",turnId:o,callId:"",name:z.toolName,reason:"blocked-by-policy"};if(!k.length){yield*xp(o,l,i,u,c,p,e,n);return}let x=bp(r.maxRounds),R={contextWindowTokens:r.contextWindowTokens??Zs,responseBufferTokens:ei,maxOutputTokens:r.maxOutputTokens??ti,abortSignal:p,reactiveCompactEnabled:!0,outputEscalationEnabled:!0},E=new Set,F=0,U=k,D,w={messages:[...i],maxOutputTokensRecoveryCount:0,hasAttemptedReactiveCompact:!1,maxOutputTokensOverride:void 0,turnCount:1,transition:void 0,guardState:jo(R),reactiveCompactState:zo(),toolLoopState:pn({maxRounds:x,replayMessages:[...i]}).state,consecutiveFailedRounds:0,finalText:"",totalUsage:{prompt:0,completion:0},collapseStore:xo(),currentModel:l,consecutive529Errors:0,consecutiveApiRetries:0,stopHookActive:void 0,lastResponseId:void 0,snipRemovedIds:new Set,contentReplacementState:di(),budgetContinuationCount:0},ge=Math.max(g*5,200),H=0;for(;;){if(H++,H>ge){n.info(`hard iteration cap reached (${ge}), forcing completion`);let S=w.finalText||tr(w.messages,n);yield{type:"end",turnId:o,content:S,usage:w.totalUsage,model:w.currentModel};return}let{messages:z,maxOutputTokensRecoveryCount:fe,hasAttemptedReactiveCompact:te,maxOutputTokensOverride:le,turnCount:G,guardState:N,reactiveCompactState:pe,collapseStore:Ee}=w,{toolLoopState:me}=w;if(D){try{let S=await D;S&&(yield{type:"tool_use_summary",turnId:o,summary:S})}catch{}D=void 0}if(r.refreshTools&&G>1){let S=r.refreshTools();S!==U&&(U=S,n.debug(`tools refreshed: ${S.length} tools`))}if(Ho(N,R)){n.info(`turn aborted by guard at turn ${G}`),yield{type:"error",turnId:o,error:"Turn aborted",code:"ABORTED",usage:w.totalUsage};return}let y=Bo(N,R);if(y.level==="blocking"){y.reason==="prompt_too_long"&&ut(pe)&&(pe.attemptedThisTurn=!0,N.hasAttemptedReactiveCompact=!0,n.info(`token budget blocking (${y.reason}), reactive compact needed`),yield{type:"recovery",turnId:o,action:"reactive_compact",detail:"token budget pre-check"}),n.info(`token budget blocking (${y.reason}), ending tool loop`);break}y.level==="warning"&&n.info(`token budget warning: ${y.usagePercent}% used, ${y.remainingTokens} remaining`);let T;{let S=await yi(z,w.contentReplacementState,s);T=S.messages,S.newlyReplacedCount>0&&(n.info(`tool-result-budget: persisted ${S.newlyReplacedCount} oversized tool results`),yield{type:"recovery",turnId:o,action:"tool_result_budget",detail:`${S.newlyReplacedCount} persisted`})}{let S=wo(T,w.snipRemovedIds);T=S.messages,S.removedCount>0&&(n.info(`snip: removed ${S.removedCount} messages, freed ~${S.tokensFreed} tokens`),yield{type:"recovery",turnId:o,action:"snip",detail:`${S.removedCount} messages`})}{let A=new Ne().compress(T,0);A.droppedCount>0&&(T=A.messages,n.info(`microcompact: cleared ${A.droppedCount} old tool results`))}if(T=So(T,Ee).messages,N.promptTokens>0){let S=xi(T,{budget:R.contextWindowTokens*.75,model:w.currentModel});S.droppedCount>0&&(T=S.messages,n.info(`autocompact: ${S.strategy}, dropped ${S.droppedCount}`),yield{type:"recovery",turnId:o,action:"autocompact",detail:`${S.strategy}: ${S.droppedCount} dropped`},w.hasAttemptedReactiveCompact=!1,d?.invoke("context.after_compact",{...m,removedCount:S.droppedCount}).catch(()=>{}))}T=vp(T);let v=_o({tools:U,toolChoice:r.toolChoice??"auto"}),_=pn({maxRounds:x,replayMessages:T,lastStopReason:me.lastStopReason,options:{stopReason:me.lastStopReason}}),C=v.extraSystemPrompt?[{role:"system",content:v.extraSystemPrompt},..._.state.replayMessages]:_.state.replayMessages;me=_.state,_.recoveryActions.length>0&&n.debug(`tool loop recovery: ${_.recoveryActions.map(S=>S.detail??S.kind).join("; ")}`),n.debug(`turn ${G}, messages: ${C.length}`),d?.invoke("turn.before_inference",{...m,model:w.currentModel}).catch(()=>{});let I=!1,V=[],j=new Map,se="stop",X,P=null,ne=!1,ie=[],we=[];try{for await(let S of e.stream({model:w.currentModel,messages:C,tools:v.tools,toolChoice:v.normalizedToolChoice??"auto",temperature:c,maxTokens:(le??N.currentMaxOutputTokens)||void 0,streamRequired:r.streamRequired,previousResponseId:w.lastResponseId,reasoning:r.reasoning,promptCacheKey:r.promptCacheKey,promptCacheRetention:r.promptCacheRetention,serviceTier:r.serviceTier,openaiBuiltinTools:r.openaiBuiltinTools,maxToolCalls:r.maxToolCalls,parallelToolCalls:r.parallelToolCalls,textVerbosity:r.textVerbosity},u,p))switch(S.type){case"delta":V.push(S.text),I||(yield{type:"delta",turnId:o,text:S.text});break;case"tool_call_delta":I=!0,Vo(j,S);break;case"reasoning_delta":ie.push(S.text);break;case"reasoning_block_complete":S.signature&&we.push({thinking:ie.join(""),signature:S.signature}),ie.length=0;break;case"usage":X={prompt:S.promptTokens,completion:S.completionTokens,reasoning:S.reasoningTokens,cacheRead:S.cacheReadTokens,cacheCreation:S.cacheCreationTokens};break;case"response_id":w.lastResponseId=S.id;break;case"annotations":yield{type:"annotations",turnId:o,annotations:S.annotations};break;case"builtin_tool_status":yield{type:"heartbeat",turnId:o,message:`${S.toolType}: ${S.event}`};break;case"done":se=S.finishReason;break}if(I||d?.invoke("turn.after_inference",{...m,model:w.currentModel}).catch(()=>{}),r.postSamplingHooks&&r.postSamplingHooks.length>0){let S=w.currentModel;for(let A of r.postSamplingHooks)try{A({messages:[...T],model:S,sessionId:s})}catch{}}}catch(S){if(S instanceof _t&&r.fallbackModel){n.info(`model fallback triggered: ${S.originalModel} \u2192 ${S.fallbackModel}`),yield{type:"recovery",turnId:o,action:"model_fallback",detail:`${S.originalModel} \u2192 ${S.fallbackModel}`},w={...w,currentModel:S.fallbackModel,consecutive529Errors:0,consecutiveApiRetries:0,transition:void 0};continue}let A=S instanceof Error?S.message:String(S),O=typeof S?.status=="number"?S.status:void 0;if(!O&&A&&(A.includes("ECONNRESET")||A.includes("EPIPE"))){let oe=(w.consecutiveApiRetries??0)+1;if(oe>At){n.info(`stale connection retry limit reached (${At}), aborting`),yield{type:"error",turnId:o,error:A,code:"RETRIES_EXHAUSTED",usage:w.totalUsage};return}n.info(`stale connection (${A.includes("ECONNRESET")?"ECONNRESET":"EPIPE"}): retrying`),yield{type:"recovery",turnId:o,action:"stale_connection_retry",detail:A.slice(0,80)},w={...w,consecutiveApiRetries:oe,transition:void 0};continue}let Y=wp({status:O,message:A});if(Y!==null){n.info(`max_tokens overflow: adjusting to ${Y}`),N.currentMaxOutputTokens=Y,w={...w,maxOutputTokensOverride:Y,transition:void 0};continue}if(Lo(O)){if(w.consecutive529Errors++,w.consecutive529Errors>=ii&&r.fallbackModel&&w.currentModel!==r.fallbackModel){n.info(`529 \xD7 ${w.consecutive529Errors}: triggering fallback to ${r.fallbackModel}`),yield{type:"recovery",turnId:o,action:"model_fallback",detail:`529 \xD7 ${w.consecutive529Errors}`},w={...w,currentModel:r.fallbackModel,consecutive529Errors:0,transition:void 0};continue}if($o()){let oe=mn(w.consecutive529Errors);n.info(`persistent retry: waiting ${oe}ms (attempt ${w.consecutive529Errors})`);let K=oe;for(;K>0;){if(p?.aborted){yield{type:"error",turnId:o,error:"Aborted during retry wait",code:"ABORTED",usage:w.totalUsage};return}yield{type:"heartbeat",turnId:o,message:`Retrying in ${Math.ceil(K/1e3)}s (${O})`};let he=Math.min(K,si);await new Promise(Ou=>setTimeout(Ou,he)),K-=he}w={...w,transition:void 0};continue}if(Oo(f)){let K=Tp({status:O,message:A})??mn(w.consecutive529Errors);n.info(`transient ${O}: retry in ${K}ms`),yield{type:"recovery",turnId:o,action:"retry",detail:`${O} retry in ${K}ms`},await new Promise(he=>setTimeout(he,K)),w={...w,transition:void 0};continue}n.info(`background source ${f}: not retrying ${O}`)}P={status:O,message:A}}if(P&&d?.invoke("turn.after_inference",{...m,model:w.currentModel,response:{error:P.message}}).catch(()=>{}),P)if(Mi(P))ne=!0,n.info(`withheld prompt_too_long error (status=${P.status})`);else if(Pi(P))ne=!0,n.info(`withheld media_size error (status=${P.status})`);else{let S=Wo({status:P.status??500,message:P.message},N,R);if(S.action==="reactive_compact"&&ut(pe)&&(pe.attemptedThisTurn=!0,N.hasAttemptedReactiveCompact=!0,yield{type:"recovery",turnId:o,action:"reactive_compact",detail:`API ${P.status??500}: ${P.message}`}),S.action==="retry"){let O=(w.consecutiveApiRetries??0)+1;if(O>At){n.info(`API retry limit reached (${At}), aborting`);let Y=lt(P.status,P.message);yield{type:"error",turnId:o,error:P.message,code:Y,usage:w.totalUsage};return}yield{type:"recovery",turnId:o,action:"retry",detail:S.reason},w={...w,consecutiveApiRetries:O,transition:void 0};continue}let A=lt(P.status,P.message);d?.invoke("stop.failure",{sessionId:s,reason:A,error:P.message}).catch(()=>{}),yield{type:"error",turnId:o,error:P.message,code:A,usage:w.totalUsage};return}X&&(w.totalUsage.prompt+=X.prompt,w.totalUsage.completion+=X.completion,X.reasoning&&(w.totalUsage.reasoning=(w.totalUsage.reasoning??0)+X.reasoning),X.cacheRead&&(w.totalUsage.cacheRead=(w.totalUsage.cacheRead??0)+X.cacheRead),X.cacheCreation&&(w.totalUsage.cacheCreation=(w.totalUsage.cacheCreation??0)+X.cacheCreation)),X?.prompt&&(N.promptTokens=X.prompt);let an=V.join("");an&&(w.finalText=an);let Oe=[...j.values()].map(S=>({id:S.id||`tc_${o}_${G}_${Math.random().toString(36).slice(2,8)}`,type:"function",function:{name:S.name,arguments:S.arguments}}));if(Oe.length===0&&!I){if(ne&&P&&Mi(P)){if(w.transition?.reason!=="collapse_drain_retry"){let A=Ro(T,Ee);if(A.committed>0){n.info(`collapse drain: committed ${A.committed} stages`),yield{type:"recovery",turnId:o,action:"collapse_drain",detail:`${A.committed} stages committed`},w={...w,messages:A.messages,transition:{reason:"collapse_drain_retry",committed:A.committed}};continue}}if(ut(pe)){pe.attemptedThisTurn=!0,N.hasAttemptedReactiveCompact=!0,n.info("withheld 413: reactive compact attempt"),yield{type:"recovery",turnId:o,action:"reactive_compact",detail:"withheld prompt_too_long"},w={...w,hasAttemptedReactiveCompact:!0,transition:{reason:"reactive_compact_retry"}};continue}n.info("withheld 413: recovery exhausted, surfacing error"),d?.invoke("stop.failure",{sessionId:s,reason:"prompt_too_long",error:P.message}).catch(()=>{}),yield{type:"error",turnId:o,error:P.message,code:"PROMPT_TOO_LONG",usage:w.totalUsage};return}if(ne&&P&&Pi(P)){if(ut(pe)){pe.attemptedThisTurn=!0,N.hasAttemptedReactiveCompact=!0,n.info("withheld media error: reactive compact strip-retry"),yield{type:"recovery",turnId:o,action:"reactive_compact",detail:"media error strip-retry"},w={...w,hasAttemptedReactiveCompact:!0,transition:{reason:"reactive_compact_retry"}};continue}n.info("withheld media error: recovery exhausted"),d?.invoke("stop.failure",{sessionId:s,reason:"media_error",error:P.message}).catch(()=>{}),yield{type:"error",turnId:o,error:P.message,code:"IMAGE_ERROR",usage:w.totalUsage};return}if(kp(se)){N.consecutiveTruncations+=1;let A=r.modelMaxOutputTokens??ni,O=Go(N,R,A);if(O.shouldEscalate&&le===void 0){N.currentMaxOutputTokens=O.newMax,n.info(`max_output_tokens escalate: ${O.newMax} tokens`),yield{type:"recovery",turnId:o,action:"output_escalation",detail:`${O.newMax} tokens`},w={...w,maxOutputTokensOverride:ri,transition:{reason:"max_output_tokens_escalate"}};continue}if(fe<oi){let Y={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."};n.info(`max_output_tokens recovery #${fe+1}`),yield{type:"recovery",turnId:o,action:"max_output_tokens_recovery",detail:`attempt ${fe+1}`},w={...w,messages:[...T,Y],maxOutputTokensRecoveryCount:fe+1,maxOutputTokensOverride:void 0,transition:{reason:"max_output_tokens_recovery",attempt:fe+1}};continue}n.info("max_output_tokens recovery exhausted, completing with partial content")}else N.consecutiveTruncations=0;if(me=dn(me,{replayMessages:z,lastStopReason:"completed"}),d){let A=await d.invoke("stop",{sessionId:s,reason:"completed"});if(A.action==="prevent"){n.info(`stop hook prevented continuation: ${A.reason??"no reason"}`),yield{type:"end",turnId:o,content:w.finalText,usage:w.totalUsage,model:w.currentModel};return}if(A.action==="abort"){let O=A.reason??"Stop hook requested continuation";n.info(`stop hook blocking: ${O}`);let Y={role:"user",content:O},oe={role:"assistant",content:w.finalText,...we.length>0&&{thinkingBlocks:[...we]}};w={...w,messages:[...z,oe,Y],stopHookActive:!0,transition:{reason:"stop_hook_blocking"}};continue}}if(r.tokenBudget&&r.tokenBudget>0&&w.budgetContinuationCount<5){let A=w.totalUsage.prompt+w.totalUsage.completion+(w.totalUsage.reasoning??0),O=A/r.tokenBudget*100;if(O<90){let Y=w.budgetContinuationCount+1,oe={role:"user",content:Ri(O,A,r.tokenBudget)};n.info(`token budget continuation #${Y}: ${Math.round(O)}% used`),yield{type:"recovery",turnId:o,action:"budget_continuation",detail:`${Math.round(O)}% used (#${Y})`};let K={role:"assistant",content:w.finalText,...we.length>0&&{thinkingBlocks:[...we]}};w={...w,messages:[...z,K,oe],budgetContinuationCount:Y,transition:{reason:"token_budget_continuation"}};continue}}if(F>0){let A={ok:!0,toolCallCount:F,distinctToolCount:E.size,multiStep:F>=2,hasSubAgent:!1,feedback:null,existingSkillName:null},O=un(A,{tools:[...E]});O&&(yield{type:"skill_instruction",turnId:o,instruction:O})}yield{type:"end",turnId:o,content:w.finalText,usage:w.totalUsage,model:w.currentModel};return}for(let S of Oe){let A=S.function.arguments,O=U.find(Y=>Y.function.name===S.function.name);if(O?.backfillObservableInput)try{let Y=JSON.parse(S.function.arguments),oe={...Y};O.backfillObservableInput(oe),Object.keys(oe).some(he=>!(he in Y))&&(A=JSON.stringify(oe))}catch{}yield{type:"tool_call",turnId:o,callId:S.id,name:S.function.name,arguments:A}}let Iu=we.length===0&&ie.length>0?ie.join(""):void 0;z.push(go(Oe,w.finalText||void 0,we.length>0?we:void 0,Iu)),me=Eo(me,{replayMessages:z,pendingToolCallIds:Oe.map(S=>S.id),completedToolCallIds:me.completedToolCallIds,lastStopReason:"tool_calls"});let xs=[];try{let S=new fn({toolInvoker:t,hooks:d,sessionId:s,turnId:o,log:n,signal:p,maxConcurrentTools:r?.maxConcurrentTools});for(let A of Oe)S.addTool(A);for await(let A of S.getRemainingResults()){A.blocked&&(yield{type:"tool_blocked",turnId:o,callId:A.callId,name:A.toolName,reason:A.blockReason??"blocked"}),z.push(A.message),xs.push(A.callId),E.add(A.toolName),F++;let O=typeof A.message?.content=="string"?A.message.content:"",Y=A.ok&&O?O.slice(0,2e3):void 0;if(yield{type:"tool_result",turnId:o,callId:A.callId,name:A.toolName,ok:A.ok,error:A.error,outputPreview:Y},A.ok){let oe=Oe.find(K=>K.id===A.callId);if(oe){if(A.toolName==="plan_mode")try{let K=JSON.parse(oe.function.arguments);K.action==="exit"&&typeof K.plan=="string"&&K.plan.length>0&&(yield{type:"plan_update",turnId:o,slug:"approved-plan",content:K.plan})}catch{}if(fp.has(A.toolName))try{let K=JSON.parse(oe.function.arguments),he=typeof K.file_path=="string"?K.file_path:typeof K.filePath=="string"?K.filePath:typeof K.path=="string"?K.path:void 0;he&&(yield{type:"artifact",turnId:o,artifactId:`artifact-${A.callId}`,artifactType:hp(he),title:he.split(/[\\/]/).pop()||he,filePath:he,language:yp(he)})}catch{}}}}}catch(S){let A=S instanceof Error?S.message:String(S);yield{type:"error",turnId:o,error:A,code:"TOOL_EXECUTION_ERROR",usage:w.totalUsage};return}if(me=dn(me,{replayMessages:z,completedToolCallIds:[...me.completedToolCallIds,...xs],lastStopReason:"tool_calls"}),r.generateToolUseSummary&&Oe.length>0){let S=Oe.map(A=>({name:A.function.name,arguments:A.function.arguments}));D=r.generateToolUseSummary(S).catch(()=>null)}let Ss=z.slice(-Oe.length),Eu=Ss.length>0&&Ss.every(S=>{let A=S?.content;return typeof A!="string"?!1:A.startsWith("Error: ")}),bt=w.consecutiveFailedRounds;if(Eu){if(bt+=1,bt>=Qs&&w.finalText){n.info(`early exit: ${bt} consecutive failed rounds, returning partial response`),yield{type:"end",turnId:o,content:w.finalText,usage:w.totalUsage,model:w.currentModel};return}}else bt=0;let po=G+1;if(g>0&&po>g){if(n.info(`max turns reached (${g}), completing`),d){let A=await d.invoke("stop",{sessionId:s,reason:"max_turns"});if(A.action==="abort"){let O=A.reason??"Stop hook requested continuation after max_turns",Y={role:"assistant",content:w.finalText,...we.length>0&&{thinkingBlocks:[...we]}};w={...w,messages:[...z,Y,{role:"user",content:O}],stopHookActive:!0,transition:{reason:"stop_hook_blocking"}};continue}}let S=w.finalText||tr(z,n);yield{type:"end",turnId:o,content:S,usage:w.totalUsage,model:w.currentModel};return}if(po>x){if(n.info(`tool loop budget exhausted (${x} rounds), returning`),F>0){let A={ok:!0,toolCallCount:F,distinctToolCount:E.size,multiStep:F>=2,hasSubAgent:!1,feedback:null,existingSkillName:null},O=un(A,{tools:[...E]});O&&(yield{type:"skill_instruction",turnId:o,instruction:O})}let S=w.finalText||tr(z,n);yield{type:"end",turnId:o,content:S,usage:w.totalUsage,model:w.currentModel};return}w={messages:z,maxOutputTokensRecoveryCount:0,hasAttemptedReactiveCompact:!1,maxOutputTokensOverride:void 0,turnCount:po,transition:{reason:"next_turn"},guardState:N,reactiveCompactState:pe,toolLoopState:me,consecutiveFailedRounds:bt,finalText:w.finalText,totalUsage:w.totalUsage,collapseStore:Ee,currentModel:w.currentModel,consecutive529Errors:0,consecutiveApiRetries:0,stopHookActive:w.stopHookActive,lastResponseId:w.lastResponseId,snipRemovedIds:w.snipRemovedIds,contentReplacementState:w.contentReplacementState,budgetContinuationCount:0}}}function tr(r,e){let t=[];for(let n=r.length-1;n>=0;n--){let o=r[n];if(o.role==="tool"&&typeof o.content=="string")t.unshift(o.content.slice(0,500));else if(o.role==="assistant"){if(typeof o.content=="string"&&o.content.trim())return e.info("synthesizeFallbackContent: found assistant text, using it"),o.content;break}else break}return t.length>0?(e.info(`synthesizeFallbackContent: synthesized from ${t.length} tool result(s)`),t.join(`
25
+ `)}`}function sp(){return yo(new Ye(Qo),new Ne(20,Xe),new ct(Xe))}function Ti(r,e){let t=bo(new Ye(Qo),new Ne(20,Xe),new Tt({protectedHeadExchanges:1,protectedTailMessages:8,summarize:r,estimateTokens:Xe}),new ct(Xe));return new wt({inner:t,estimateTokens:Xe,onCacheInvalidated:e?.onCacheInvalidated})}function xi(r,e){let t=e?.budget??cn({modelContextWindow:wi(e?.model)}),o=(e?.pipeline??sp()).compress(r,t);if(o.droppedCount>0){let s=Qe(r),i=Qe(o.messages);vi.record({timestamp:Date.now(),strategy:o.strategy,tokensBefore:s,tokensAfter:i,droppedCount:o.droppedCount,latencyMs:o.metrics?.latencyMs??0,usedLlm:!1,cacheInvalidated:o.metrics?.cacheInvalidated??!1,tier:Rt(s,t)})}return o.droppedCount>0&&Zo?.(o.droppedCount,Qe(o.messages)),o}async function ip(r,e,t){let n=t??cn({modelContextWindow:wi(e.model)}),o=Qe(r),s=Rt(o,n),i;switch(s){case"none":i={messages:r,droppedCount:0,strategy:"none"};break;case"trim-only":i=new Ye(Qo).compress(r,n);break;case"sliding-window":{i=await Ti(e.summarize).compressAsync(r,n);break}case"llm-summarize":{let a=e.pipeline??Ti(e.summarize);i=St(a)?await a.compressAsync(r,n):a.compress(r,n);break}}return i.droppedCount>0&&(i={...i,messages:await To(i.messages,r,{maxFiles:5,maxTokenBudget:5e4,readFile:async a=>{try{return await np(a,"utf-8")}catch{return null}}})}),ap(r,i,n),i}function ap(r,e,t){if(e.droppedCount>0||e.metrics?.usedLlm){let n=e.metrics?.tokensBefore||Qe(r),o=e.metrics?.tokensAfter||Qe(e.messages);vi.record({timestamp:Date.now(),strategy:e.strategy,tokensBefore:n,tokensAfter:o,droppedCount:e.droppedCount,latencyMs:e.metrics?.latencyMs??0,usedLlm:e.metrics?.usedLlm??!1,cacheInvalidated:e.metrics?.cacheInvalidated??!1,tier:Rt(n,t)})}if(e.droppedCount>0){let n=e.metrics?.tokensAfter||Qe(e.messages);Zo?.(e.droppedCount,n)}}function lp(r,e){let t=rp(r,e),n={id:"builtin-compressor",label:"4-Layer Compression Funnel (built-in)",async compressAsync(o,s,i){return ip(o,{budget:s,model:i?.model,sessionId:i?.sessionId,summarize:t},s)}};ki.register(n),ki.activate(n.id),r.info(`[context-compression] registered context engine: ${n.id}`)}function Si(r,e,t){lp(e,t),r.register({point:"context.before_compact",priority:50,label:"context-compression-bridge",handler:(n,o)=>{let s=o.messageCount;return s&&s>0&&e.debug(`[context-compression] before_compact: ${s} messages entering compression`),{action:"continue"}}}),Zo=(n,o)=>{e.debug(`[context-compression] after_compact: removed ${n}, ${o} tokens remaining`),r.invoke("context.after_compact",{sessionId:"",turnId:"",removedCount:n,tokenCount:o}).catch(()=>{})}}var Yo,Qo,op,vi,ki,Zo,er=q(()=>{"use strict";Ct();Yo={"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};Qo=8e3,op="deepseek-v4-flash",vi=new vt(200),ki=new xt;Zo=null});function Ri(r,e,t){let n=t-e;return`[Budget] ${Math.round(r)}% used (${e.toLocaleString()} / ${t.toLocaleString()} tokens). ${n.toLocaleString()} tokens remaining. `+(r>=90?"Wrap up your current task \u2014 you are near the token limit.":"Continue working \u2014 do not summarize prematurely.")}var _i=q(()=>{"use strict"});var Ci={};Rs(Ci,{resolveToolEligibility:()=>mp});function up(r,e){if(cp.some(t=>t.test(r)))return!0;if(e)for(let t of e)try{if(new RegExp(t,"i").test(r))return!0}catch{}return!1}function dp(r,e){let t=r.function.name,n=r.meta,o=[];return e.blockedToolNames?.includes(t)?(o.push("policy_blocked"),{level:5,reasons:o}):n?.isReadOnly?(o.push("always_allowed"),{level:1,reasons:o}):n?.requiresApproval?(o.push("approval_required"),{level:4,reasons:o}):n?.isDangerous||up(t,e.dangerousPatterns)?(o.push("dangerous_tool"),{level:3,reasons:o}):{level:2,reasons:o}}function pp(r){switch(r){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 mp(r,e={}){let t=new Map,n=[],o=[],s=[];for(let i of r){let a=i.function.name,{level:l,reasons:u}=dp(i,e),c=pp(l),d={toolName:a,status:c,permissionLevel:l,approvalRequired:l===4,reasonCodes:u};t.set(a,d),l===5?o.push(d):(n.push(i),l===4&&s.push(d))}return{eligibleTools:n,blockedTools:o,approvalRequiredTools:s,eligibilityByName:t}}var cp,Ai=q(()=>{"use strict";cp=[/^(?:bash|shell|exec|terminal|run_command)$/i,/^(?:write_file|delete_file|move_file|create_directory)$/i,/^(?:git_push|git_reset|git_force)$/i]});function hp(r){let e=r.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 yp(r){let e=r.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 bp(r){return typeof r=="number"&&Number.isFinite(r)&&r>=1?Math.min(Math.round(r),100):Xs}function Mi(r){let e=r.message.toLowerCase();return r.status===413||e.includes("prompt_too_long")||e.includes("context_length_exceeded")||e.includes("maximum context length")}function kp(r){return r==="length"||r==="max_tokens"}function Pi(r){let e=r.message.toLowerCase();return(e.includes("image")||e.includes("media")||e.includes("file too large")||e.includes("payload too large"))&&(r.status===413||e.includes("too large")||e.includes("size"))}function Tp(r){let e=r.headers;if(!e)return null;let t=e["retry-after"]??e["Retry-After"];if(!t)return null;let n=parseInt(t,10);return!isNaN(n)&&n>0?n*1e3:null}function wp(r){if(r.status!==400)return null;let e=r.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),n=parseInt(e[3],10);if(isNaN(t)||isNaN(n))return null;let o=n-t-1e3;return o>=3e3?o:null}function vp(r){return r.filter(e=>e.role!=="assistant"?!0:!(typeof e.content=="string"&&e.content.trim()===""))}async function*Ii(r,e,t,n){let{turnId:o,sessionId:s,messages:i,tools:a,model:l,apiKey:u,temperature:c,hooks:d,signal:p}=r,m={sessionId:s,turnId:o},g=r.maxTurns??0,f=r.querySource,{resolveToolEligibility:b}=await Promise.resolve().then(()=>(Ai(),Ci)),h=b(a,r.toolEligibilityContext),k=h.eligibleTools;for(let z of h.blockedTools)yield{type:"tool_blocked",turnId:o,callId:"",name:z.toolName,reason:"blocked-by-policy"};if(!k.length){yield*xp(o,l,i,u,c,p,e,n);return}let x=bp(r.maxRounds),R={contextWindowTokens:r.contextWindowTokens??Zs,responseBufferTokens:ei,maxOutputTokens:r.maxOutputTokens??ti,abortSignal:p,reactiveCompactEnabled:!0,outputEscalationEnabled:!0},E=new Set,F=0,U=k,D,w={messages:[...i],maxOutputTokensRecoveryCount:0,hasAttemptedReactiveCompact:!1,maxOutputTokensOverride:void 0,turnCount:1,transition:void 0,guardState:jo(R),reactiveCompactState:zo(),toolLoopState:pn({maxRounds:x,replayMessages:[...i]}).state,consecutiveFailedRounds:0,finalText:"",totalUsage:{prompt:0,completion:0},collapseStore:xo(),currentModel:l,consecutive529Errors:0,consecutiveApiRetries:0,stopHookActive:void 0,lastResponseId:void 0,snipRemovedIds:new Set,contentReplacementState:di(),budgetContinuationCount:0},ge=Math.max(g*5,200),H=0;for(;;){if(H++,H>ge){n.info(`hard iteration cap reached (${ge}), forcing completion`);let S=w.finalText||tr(w.messages,n);yield{type:"end",turnId:o,content:S,usage:w.totalUsage,model:w.currentModel};return}let{messages:z,maxOutputTokensRecoveryCount:fe,hasAttemptedReactiveCompact:te,maxOutputTokensOverride:le,turnCount:G,guardState:N,reactiveCompactState:pe,collapseStore:Ee}=w,{toolLoopState:me}=w;if(D){try{let S=await D;S&&(yield{type:"tool_use_summary",turnId:o,summary:S})}catch{}D=void 0}if(r.refreshTools&&G>1){let S=r.refreshTools();S!==U&&(U=S,n.debug(`tools refreshed: ${S.length} tools`))}if(Ho(N,R)){n.info(`turn aborted by guard at turn ${G}`),yield{type:"error",turnId:o,error:"Turn aborted",code:"ABORTED",usage:w.totalUsage};return}let y=Bo(N,R);if(y.level==="blocking"){y.reason==="prompt_too_long"&&ut(pe)&&(pe.attemptedThisTurn=!0,N.hasAttemptedReactiveCompact=!0,n.info(`token budget blocking (${y.reason}), reactive compact needed`),yield{type:"recovery",turnId:o,action:"reactive_compact",detail:"token budget pre-check"}),n.info(`token budget blocking (${y.reason}), ending tool loop`);break}y.level==="warning"&&n.info(`token budget warning: ${y.usagePercent}% used, ${y.remainingTokens} remaining`);let T;{let S=await yi(z,w.contentReplacementState,s);T=S.messages,S.newlyReplacedCount>0&&(n.info(`tool-result-budget: persisted ${S.newlyReplacedCount} oversized tool results`),yield{type:"recovery",turnId:o,action:"tool_result_budget",detail:`${S.newlyReplacedCount} persisted`})}{let S=wo(T,w.snipRemovedIds);T=S.messages,S.removedCount>0&&(n.info(`snip: removed ${S.removedCount} messages, freed ~${S.tokensFreed} tokens`),yield{type:"recovery",turnId:o,action:"snip",detail:`${S.removedCount} messages`})}{let A=new Ne().compress(T,0);A.droppedCount>0&&(T=A.messages,n.info(`microcompact: cleared ${A.droppedCount} old tool results`))}if(T=So(T,Ee).messages,N.promptTokens>0){let S=xi(T,{budget:R.contextWindowTokens*.75,model:w.currentModel});S.droppedCount>0&&(T=S.messages,n.info(`autocompact: ${S.strategy}, dropped ${S.droppedCount}`),yield{type:"recovery",turnId:o,action:"autocompact",detail:`${S.strategy}: ${S.droppedCount} dropped`},w.hasAttemptedReactiveCompact=!1,d?.invoke("context.after_compact",{...m,removedCount:S.droppedCount}).catch(()=>{}))}T=vp(T);let v=_o({tools:U,toolChoice:r.toolChoice??"auto"}),_=pn({maxRounds:x,replayMessages:T,lastStopReason:me.lastStopReason,options:{stopReason:me.lastStopReason}}),C=v.extraSystemPrompt?[{role:"system",content:v.extraSystemPrompt},..._.state.replayMessages]:_.state.replayMessages;me=_.state,_.recoveryActions.length>0&&n.debug(`tool loop recovery: ${_.recoveryActions.map(S=>S.detail??S.kind).join("; ")}`),n.debug(`turn ${G}, messages: ${C.length}`),d?.invoke("turn.before_inference",{...m,model:w.currentModel}).catch(()=>{});let I=!1,V=[],j=new Map,re="stop",X,P=null,se=!1,ie=[],we=[];try{for await(let S of e.stream({model:w.currentModel,messages:C,tools:v.tools,toolChoice:v.normalizedToolChoice??"auto",temperature:c,maxTokens:(le??N.currentMaxOutputTokens)||void 0,streamRequired:r.streamRequired,previousResponseId:w.lastResponseId,reasoning:r.reasoning,promptCacheKey:r.promptCacheKey,promptCacheRetention:r.promptCacheRetention,serviceTier:r.serviceTier,openaiBuiltinTools:r.openaiBuiltinTools,maxToolCalls:r.maxToolCalls,parallelToolCalls:r.parallelToolCalls,textVerbosity:r.textVerbosity},u,p))switch(S.type){case"delta":V.push(S.text),I||(yield{type:"delta",turnId:o,text:S.text});break;case"tool_call_delta":I=!0,Vo(j,S);break;case"reasoning_delta":ie.push(S.text);break;case"reasoning_block_complete":S.signature&&we.push({thinking:ie.join(""),signature:S.signature}),ie.length=0;break;case"usage":X={prompt:S.promptTokens,completion:S.completionTokens,reasoning:S.reasoningTokens,cacheRead:S.cacheReadTokens,cacheCreation:S.cacheCreationTokens};break;case"response_id":w.lastResponseId=S.id;break;case"annotations":yield{type:"annotations",turnId:o,annotations:S.annotations};break;case"builtin_tool_status":yield{type:"heartbeat",turnId:o,message:`${S.toolType}: ${S.event}`};break;case"done":re=S.finishReason;break}if(I||d?.invoke("turn.after_inference",{...m,model:w.currentModel}).catch(()=>{}),r.postSamplingHooks&&r.postSamplingHooks.length>0){let S=w.currentModel;for(let A of r.postSamplingHooks)try{A({messages:[...T],model:S,sessionId:s})}catch{}}}catch(S){if(S instanceof _t&&r.fallbackModel){n.info(`model fallback triggered: ${S.originalModel} \u2192 ${S.fallbackModel}`),yield{type:"recovery",turnId:o,action:"model_fallback",detail:`${S.originalModel} \u2192 ${S.fallbackModel}`},w={...w,currentModel:S.fallbackModel,consecutive529Errors:0,consecutiveApiRetries:0,transition:void 0};continue}let A=S instanceof Error?S.message:String(S),O=typeof S?.status=="number"?S.status:void 0;if(!O&&A&&(A.includes("ECONNRESET")||A.includes("EPIPE"))){let ne=(w.consecutiveApiRetries??0)+1;if(ne>At){n.info(`stale connection retry limit reached (${At}), aborting`),yield{type:"error",turnId:o,error:A,code:"RETRIES_EXHAUSTED",usage:w.totalUsage};return}n.info(`stale connection (${A.includes("ECONNRESET")?"ECONNRESET":"EPIPE"}): retrying`),yield{type:"recovery",turnId:o,action:"stale_connection_retry",detail:A.slice(0,80)},w={...w,consecutiveApiRetries:ne,transition:void 0};continue}let Y=wp({status:O,message:A});if(Y!==null){n.info(`max_tokens overflow: adjusting to ${Y}`),N.currentMaxOutputTokens=Y,w={...w,maxOutputTokensOverride:Y,transition:void 0};continue}if(Lo(O)){if(w.consecutive529Errors++,w.consecutive529Errors>=ii&&r.fallbackModel&&w.currentModel!==r.fallbackModel){n.info(`529 \xD7 ${w.consecutive529Errors}: triggering fallback to ${r.fallbackModel}`),yield{type:"recovery",turnId:o,action:"model_fallback",detail:`529 \xD7 ${w.consecutive529Errors}`},w={...w,currentModel:r.fallbackModel,consecutive529Errors:0,transition:void 0};continue}if($o()){let ne=mn(w.consecutive529Errors);n.info(`persistent retry: waiting ${ne}ms (attempt ${w.consecutive529Errors})`);let K=ne;for(;K>0;){if(p?.aborted){yield{type:"error",turnId:o,error:"Aborted during retry wait",code:"ABORTED",usage:w.totalUsage};return}yield{type:"heartbeat",turnId:o,message:`Retrying in ${Math.ceil(K/1e3)}s (${O})`};let he=Math.min(K,si);await new Promise(Ou=>setTimeout(Ou,he)),K-=he}w={...w,transition:void 0};continue}if(Oo(f)){let K=Tp({status:O,message:A})??mn(w.consecutive529Errors);n.info(`transient ${O}: retry in ${K}ms`),yield{type:"recovery",turnId:o,action:"retry",detail:`${O} retry in ${K}ms`},await new Promise(he=>setTimeout(he,K)),w={...w,transition:void 0};continue}n.info(`background source ${f}: not retrying ${O}`)}P={status:O,message:A}}if(P&&d?.invoke("turn.after_inference",{...m,model:w.currentModel,response:{error:P.message}}).catch(()=>{}),P)if(Mi(P))se=!0,n.info(`withheld prompt_too_long error (status=${P.status})`);else if(Pi(P))se=!0,n.info(`withheld media_size error (status=${P.status})`);else{let S=Wo({status:P.status??500,message:P.message},N,R);if(S.action==="reactive_compact"&&ut(pe)&&(pe.attemptedThisTurn=!0,N.hasAttemptedReactiveCompact=!0,yield{type:"recovery",turnId:o,action:"reactive_compact",detail:`API ${P.status??500}: ${P.message}`}),S.action==="retry"){let O=(w.consecutiveApiRetries??0)+1;if(O>At){n.info(`API retry limit reached (${At}), aborting`);let Y=lt(P.status,P.message);yield{type:"error",turnId:o,error:P.message,code:Y,usage:w.totalUsage};return}yield{type:"recovery",turnId:o,action:"retry",detail:S.reason},w={...w,consecutiveApiRetries:O,transition:void 0};continue}let A=lt(P.status,P.message);d?.invoke("stop.failure",{sessionId:s,reason:A,error:P.message}).catch(()=>{}),yield{type:"error",turnId:o,error:P.message,code:A,usage:w.totalUsage};return}X&&(w.totalUsage.prompt+=X.prompt,w.totalUsage.completion+=X.completion,X.reasoning&&(w.totalUsage.reasoning=(w.totalUsage.reasoning??0)+X.reasoning),X.cacheRead&&(w.totalUsage.cacheRead=(w.totalUsage.cacheRead??0)+X.cacheRead),X.cacheCreation&&(w.totalUsage.cacheCreation=(w.totalUsage.cacheCreation??0)+X.cacheCreation)),X?.prompt&&(N.promptTokens=X.prompt);let an=V.join("");an&&(w.finalText=an);let Oe=[...j.values()].map(S=>({id:S.id||`tc_${o}_${G}_${Math.random().toString(36).slice(2,8)}`,type:"function",function:{name:S.name,arguments:S.arguments}}));if(Oe.length===0&&!I){if(se&&P&&Mi(P)){if(w.transition?.reason!=="collapse_drain_retry"){let A=Ro(T,Ee);if(A.committed>0){n.info(`collapse drain: committed ${A.committed} stages`),yield{type:"recovery",turnId:o,action:"collapse_drain",detail:`${A.committed} stages committed`},w={...w,messages:A.messages,transition:{reason:"collapse_drain_retry",committed:A.committed}};continue}}if(ut(pe)){pe.attemptedThisTurn=!0,N.hasAttemptedReactiveCompact=!0,n.info("withheld 413: reactive compact attempt"),yield{type:"recovery",turnId:o,action:"reactive_compact",detail:"withheld prompt_too_long"},w={...w,hasAttemptedReactiveCompact:!0,transition:{reason:"reactive_compact_retry"}};continue}n.info("withheld 413: recovery exhausted, surfacing error"),d?.invoke("stop.failure",{sessionId:s,reason:"prompt_too_long",error:P.message}).catch(()=>{}),yield{type:"error",turnId:o,error:P.message,code:"PROMPT_TOO_LONG",usage:w.totalUsage};return}if(se&&P&&Pi(P)){if(ut(pe)){pe.attemptedThisTurn=!0,N.hasAttemptedReactiveCompact=!0,n.info("withheld media error: reactive compact strip-retry"),yield{type:"recovery",turnId:o,action:"reactive_compact",detail:"media error strip-retry"},w={...w,hasAttemptedReactiveCompact:!0,transition:{reason:"reactive_compact_retry"}};continue}n.info("withheld media error: recovery exhausted"),d?.invoke("stop.failure",{sessionId:s,reason:"media_error",error:P.message}).catch(()=>{}),yield{type:"error",turnId:o,error:P.message,code:"IMAGE_ERROR",usage:w.totalUsage};return}if(kp(re)){N.consecutiveTruncations+=1;let A=r.modelMaxOutputTokens??ni,O=Go(N,R,A);if(O.shouldEscalate&&le===void 0){N.currentMaxOutputTokens=O.newMax,n.info(`max_output_tokens escalate: ${O.newMax} tokens`),yield{type:"recovery",turnId:o,action:"output_escalation",detail:`${O.newMax} tokens`},w={...w,maxOutputTokensOverride:ri,transition:{reason:"max_output_tokens_escalate"}};continue}if(fe<oi){let Y={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."};n.info(`max_output_tokens recovery #${fe+1}`),yield{type:"recovery",turnId:o,action:"max_output_tokens_recovery",detail:`attempt ${fe+1}`},w={...w,messages:[...T,Y],maxOutputTokensRecoveryCount:fe+1,maxOutputTokensOverride:void 0,transition:{reason:"max_output_tokens_recovery",attempt:fe+1}};continue}n.info("max_output_tokens recovery exhausted, completing with partial content")}else N.consecutiveTruncations=0;if(me=dn(me,{replayMessages:z,lastStopReason:"completed"}),d){let A=await d.invoke("stop",{sessionId:s,reason:"completed"});if(A.action==="prevent"){n.info(`stop hook prevented continuation: ${A.reason??"no reason"}`),yield{type:"end",turnId:o,content:w.finalText,usage:w.totalUsage,model:w.currentModel};return}if(A.action==="abort"){let O=A.reason??"Stop hook requested continuation";n.info(`stop hook blocking: ${O}`);let Y={role:"user",content:O},ne={role:"assistant",content:w.finalText,...we.length>0&&{thinkingBlocks:[...we]}};w={...w,messages:[...z,ne,Y],stopHookActive:!0,transition:{reason:"stop_hook_blocking"}};continue}}if(r.tokenBudget&&r.tokenBudget>0&&w.budgetContinuationCount<5){let A=w.totalUsage.prompt+w.totalUsage.completion+(w.totalUsage.reasoning??0),O=A/r.tokenBudget*100;if(O<90){let Y=w.budgetContinuationCount+1,ne={role:"user",content:Ri(O,A,r.tokenBudget)};n.info(`token budget continuation #${Y}: ${Math.round(O)}% used`),yield{type:"recovery",turnId:o,action:"budget_continuation",detail:`${Math.round(O)}% used (#${Y})`};let K={role:"assistant",content:w.finalText,...we.length>0&&{thinkingBlocks:[...we]}};w={...w,messages:[...z,K,ne],budgetContinuationCount:Y,transition:{reason:"token_budget_continuation"}};continue}}if(F>0){let A={ok:!0,toolCallCount:F,distinctToolCount:E.size,multiStep:F>=2,hasSubAgent:!1,feedback:null,existingSkillName:null},O=un(A,{tools:[...E]});O&&(yield{type:"skill_instruction",turnId:o,instruction:O})}yield{type:"end",turnId:o,content:w.finalText,usage:w.totalUsage,model:w.currentModel};return}for(let S of Oe){let A=S.function.arguments,O=U.find(Y=>Y.function.name===S.function.name);if(O?.backfillObservableInput)try{let Y=JSON.parse(S.function.arguments),ne={...Y};O.backfillObservableInput(ne),Object.keys(ne).some(he=>!(he in Y))&&(A=JSON.stringify(ne))}catch{}yield{type:"tool_call",turnId:o,callId:S.id,name:S.function.name,arguments:A}}let Iu=we.length===0&&ie.length>0?ie.join(""):void 0;z.push(go(Oe,w.finalText||void 0,we.length>0?we:void 0,Iu)),me=Eo(me,{replayMessages:z,pendingToolCallIds:Oe.map(S=>S.id),completedToolCallIds:me.completedToolCallIds,lastStopReason:"tool_calls"});let xs=[];try{let S=new fn({toolInvoker:t,hooks:d,sessionId:s,turnId:o,log:n,signal:p,maxConcurrentTools:r?.maxConcurrentTools});for(let A of Oe)S.addTool(A);for await(let A of S.getRemainingResults()){A.blocked&&(yield{type:"tool_blocked",turnId:o,callId:A.callId,name:A.toolName,reason:A.blockReason??"blocked"}),z.push(A.message),xs.push(A.callId),E.add(A.toolName),F++;let O=typeof A.message?.content=="string"?A.message.content:"",Y=A.ok&&O?O.slice(0,2e3):void 0;if(yield{type:"tool_result",turnId:o,callId:A.callId,name:A.toolName,ok:A.ok,error:A.error,outputPreview:Y},A.ok){let ne=Oe.find(K=>K.id===A.callId);if(ne){if(A.toolName==="plan_mode")try{let K=JSON.parse(ne.function.arguments);K.action==="exit"&&typeof K.plan=="string"&&K.plan.length>0&&(yield{type:"plan_update",turnId:o,slug:"approved-plan",content:K.plan})}catch{}if(fp.has(A.toolName))try{let K=JSON.parse(ne.function.arguments),he=typeof K.file_path=="string"?K.file_path:typeof K.filePath=="string"?K.filePath:typeof K.path=="string"?K.path:void 0;he&&(yield{type:"artifact",turnId:o,artifactId:`artifact-${A.callId}`,artifactType:hp(he),title:he.split(/[\\/]/).pop()||he,filePath:he,language:yp(he)})}catch{}}}}}catch(S){let A=S instanceof Error?S.message:String(S);yield{type:"error",turnId:o,error:A,code:"TOOL_EXECUTION_ERROR",usage:w.totalUsage};return}if(me=dn(me,{replayMessages:z,completedToolCallIds:[...me.completedToolCallIds,...xs],lastStopReason:"tool_calls"}),r.generateToolUseSummary&&Oe.length>0){let S=Oe.map(A=>({name:A.function.name,arguments:A.function.arguments}));D=r.generateToolUseSummary(S).catch(()=>null)}let Ss=z.slice(-Oe.length),Eu=Ss.length>0&&Ss.every(S=>{let A=S?.content;return typeof A!="string"?!1:A.startsWith("Error: ")}),bt=w.consecutiveFailedRounds;if(Eu){if(bt+=1,bt>=Qs&&w.finalText){n.info(`early exit: ${bt} consecutive failed rounds, returning partial response`),yield{type:"end",turnId:o,content:w.finalText,usage:w.totalUsage,model:w.currentModel};return}}else bt=0;let po=G+1;if(g>0&&po>g){if(n.info(`max turns reached (${g}), completing`),d){let A=await d.invoke("stop",{sessionId:s,reason:"max_turns"});if(A.action==="abort"){let O=A.reason??"Stop hook requested continuation after max_turns",Y={role:"assistant",content:w.finalText,...we.length>0&&{thinkingBlocks:[...we]}};w={...w,messages:[...z,Y,{role:"user",content:O}],stopHookActive:!0,transition:{reason:"stop_hook_blocking"}};continue}}let S=w.finalText||tr(z,n);yield{type:"end",turnId:o,content:S,usage:w.totalUsage,model:w.currentModel};return}if(po>x){if(n.info(`tool loop budget exhausted (${x} rounds), returning`),F>0){let A={ok:!0,toolCallCount:F,distinctToolCount:E.size,multiStep:F>=2,hasSubAgent:!1,feedback:null,existingSkillName:null},O=un(A,{tools:[...E]});O&&(yield{type:"skill_instruction",turnId:o,instruction:O})}let S=w.finalText||tr(z,n);yield{type:"end",turnId:o,content:S,usage:w.totalUsage,model:w.currentModel};return}w={messages:z,maxOutputTokensRecoveryCount:0,hasAttemptedReactiveCompact:!1,maxOutputTokensOverride:void 0,turnCount:po,transition:{reason:"next_turn"},guardState:N,reactiveCompactState:pe,toolLoopState:me,consecutiveFailedRounds:bt,finalText:w.finalText,totalUsage:w.totalUsage,collapseStore:Ee,currentModel:w.currentModel,consecutive529Errors:0,consecutiveApiRetries:0,stopHookActive:w.stopHookActive,lastResponseId:w.lastResponseId,snipRemovedIds:w.snipRemovedIds,contentReplacementState:w.contentReplacementState,budgetContinuationCount:0}}}function tr(r,e){let t=[];for(let n=r.length-1;n>=0;n--){let o=r[n];if(o.role==="tool"&&typeof o.content=="string")t.unshift(o.content.slice(0,500));else if(o.role==="assistant"){if(typeof o.content=="string"&&o.content.trim())return e.info("synthesizeFallbackContent: found assistant text, using it"),o.content;break}else break}return t.length>0?(e.info(`synthesizeFallbackContent: synthesized from ${t.length} tool result(s)`),t.join(`
26
26
 
27
27
  `)):""}async function*xp(r,e,t,n,o,s,i,a){let l=[],u;a.debug(`single LLM round, messages: ${t.length}`);for await(let c of i.stream({model:e,messages:t,temperature:o},n,s))switch(c.type){case"delta":l.push(c.text),yield{type:"delta",turnId:r,text:c.text};break;case"usage":u={prompt:c.promptTokens,completion:c.completionTokens,reasoning:c.reasoningTokens,cacheRead:c.cacheReadTokens,cacheCreation:c.cacheCreationTokens};break;case"done":break}yield{type:"end",turnId:r,content:l.join(""),usage:u??{prompt:0,completion:0},model:e}}var fp,Ei=q(()=>{"use strict";qo();Ct();bi();er();_i();Jo();gn();fp=new Set(["write","edit","patch","apply_patch"])});var Li={};Rs(Li,{Agent:()=>Mt});var Mt,nr=q(()=>{"use strict";Ct();Ei();gn();Mt=class{transport;apiKey;toolInvoker;log;hooks;maxRounds;constructor(e){this.transport=e.llmTransport,this.apiKey=e.apiKey,this.toolInvoker=e.toolInvoker,this.log=e.log,this.hooks=e.hooks,this.maxRounds=Math.min(e.maxRounds??25,100)}async*run(e,t){let{turnId:n,messages:o,tools:s,systemPrompt:i,config:a}=e,l={sessionId:e.sessionId,turnId:n};yield{type:"start",turnId:n},this.hooks?.invoke("turn.submitted",{...l,prompt:o[o.length-1]?.content??void 0}).catch(()=>{});let u=Po(o),c=[];if(i&&c.push({role:"system",content:i}),c.push(...u),this.hooks){let m=u.filter(f=>f.role==="user").pop(),g=typeof m?.content=="string"?m.content.slice(0,500):void 0;if(g)try{let f=await this.hooks.invoke("memory.before_recall",{sessionId:e.sessionId,turnId:n,query:g}),b=f?.context?.recalledMemories;if(b&&b.length>0){let h=b.map(k=>`- ${k.text}`).join(`
28
28
  `);c.splice(i?1:0,0,{role:"system",content:`[Recalled from long-term memory]
@@ -269,8 +269,8 @@ describe: Show workflow steps and variables.`},workflow:{type:"string",descripti
269
269
  `)||"(no output)"}],details:a.isError?{type:"mcp",error:"tool_error"}:{type:"mcp"}}}catch(a){let l=a instanceof Error?a.message:String(a);return{content:[{type:"text",text:`MCP tool error: ${l}`}],details:{type:"mcp",error:l}}}}}}};function Cy(r){return r.replace(/[^a-zA-Z0-9_]/g,"_").toLowerCase()}var Kn=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 o={name:t.name,url:t.url,headers:t.headers,initTimeoutMs:t.initTimeoutMs};this.clients.set(t.name,new qn(o))}else{if(!t.command){this.log.warn(`[mcp] server "${t.name}" is type "stdio" but has no command, skipping`);continue}let o={name:t.name,command:t.command,args:t.args,env:t.env,initTimeoutMs:t.initTimeoutMs};this.clients.set(t.name,new Vn(o))}}}async connectAll(){let e=Array.from(this.clients.entries()).map(async([t,n])=>{try{await n.connect(),this.log.info(`[mcp] connected to ${t} (${n.info.name} v${n.info.version})`),n.setOnToolsChanged(()=>{this.log.info(`[mcp] tools changed on ${t}, re-injecting`),this.injected&&this.reinjectTools(t,n)})}catch(o){this.log.warn(`[mcp] failed to connect to ${t}: ${o instanceof Error?o.message:o}`)}});await Promise.allSettled(e)}injectTools(){this.injected=!0;for(let[e,t]of this.clients){if(!t.isConnected)continue;let n=t.toPortableTools();Rr(n),this.log.info(`[mcp] injected ${n.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(([,o])=>o):Array.from(this.clients.entries());return(await Promise.all(t.map(async([o,s])=>{if(!s?.isConnected||!s.listResources)return[];try{return(await s.listResources()).map(a=>({...a,server:o}))}catch{return this.log.warn(`[mcp] failed to list resources from ${o}`),[]}}))).flat()}async readResource(e,t){let n=this.clients.get(e);if(!n?.isConnected)throw new Error(`MCP server "${e}" is not connected`);if(!n.readResource)throw new Error(`MCP server "${e}" does not support resources`);return n.readResource(t)}reinjectTools(e,t){if(!this.injected)return;let n=`mcp__${e.replace(/[^a-zA-Z0-9_]/g,"_").toLowerCase()}__`;for(let s of Be())s.startsWith(n)&&On(s);let o=t.toPortableTools();Rr(o),this.log.info(`[mcp] re-injected ${o.length} tools from ${e}`)}};function is(r){if(!r||typeof r!="object")return[];let e=r,t=[],n=e.mcpServers??e.servers??e;for(let[o,s]of Object.entries(n)){if(!s||typeof s!="object")continue;let i=s;if(typeof i.url=="string"){t.push({name:o,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:o,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 Ay={type:"object",properties:{server:{type:"string",description:"MCP server name to list resources from. Omit to list from all connected servers."}}};function Rc(r){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:Ay,shouldDefer:!0,isConcurrencySafe:!0,isReadOnly:!0,searchHint:"mcp resource list browse discover",execute:async(e,t)=>{let n=r();if(!n)return{content:[{type:"text",text:"No MCP servers configured."}],details:{type:"list_mcp_resources",count:0}};let o=await n.listResources(t.server);if(o.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 s=new Map;for(let a of o){let l=s.get(a.server)??[];l.push(a),s.set(a.server,l)}let i=[];for(let[a,l]of s){i.push(`Server: ${a} (${l.length} resources)`);for(let u of l){let c=u.mimeType?` [${u.mimeType}]`:"",d=u.description?` \u2014 ${u.description}`:"";i.push(` ${u.name}: ${u.uri}${c}${d}`)}i.push("")}return{content:[{type:"text",text:i.join(`
270
270
  `).trim()}],details:{type:"list_mcp_resources",count:o.length}}}}}var My={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 _c(r){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:My,shouldDefer:!0,isConcurrencySafe:!0,isReadOnly:!0,searchHint:"mcp resource read fetch content",execute:async(e,t)=>{let n=r();if(!n)return{content:[{type:"text",text:"No MCP servers configured."}],details:{error:"no_mcp"}};try{let o=await n.readResource(t.server,t.uri);if(o.length===0)return{content:[{type:"text",text:`Resource "${t.uri}" returned no content.`}],details:{type:"read_mcp_resource",empty:!0}};let s=[];for(let i of o)if(i.text){let a=i.mimeType?` (${i.mimeType})`:"";s.push({type:"text",text:`--- ${i.uri}${a} ---
271
271
  ${i.text}`})}else if(i.blob){let a=Math.ceil(i.blob.length*3/4/1024);s.push({type:"text",text:`--- ${i.uri} (binary, ~${a}KB, ${i.mimeType??"unknown"}) ---
272
- [Binary content not displayed. Use appropriate tool to process.]`})}return s.length===0?{content:[{type:"text",text:`Resource "${t.uri}" has no readable content.`}],details:{type:"read_mcp_resource",empty:!0}}:{content:s,details:{type:"read_mcp_resource",uri:t.uri,server:t.server,contentCount:o.length}}}catch(o){return{content:[{type:"text",text:`Error reading resource: ${o.message}`}],details:{error:o.message}}}}}}import*as Ve from"node:fs";import*as Jn from"node:path";import{pathToFileURL as Py}from"node:url";var Cc={preToolUse:"tool.before_invoke",postToolUse:"tool.after_invoke",onTurnStart:"turn.submitted",onTurnEnd:"turn.completed",onSessionEnd:"session.ended"};var Yn=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(!Ve.existsSync(e))continue;let t;try{t=Ve.readdirSync(e,{withFileTypes:!0})}catch{continue}for(let n of t){if(!n.isDirectory()||n.name.startsWith(".")||n.name.startsWith("_"))continue;let o=Jn.join(e,n.name);await this.loadPlugin(n.name,o)}}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 refreshActivations(){let e=Date.now();for(let[t,n]of this.activations){if(e-n.lastCheckAt<n.ttlMs)continue;let o;try{o=await n.checkFn()}catch(s){this.log.warn(`[plugins] ${t}: check_fn error: ${s instanceof Error?s.message:s}`),o=n.lastResult}if(n.lastCheckAt=e,o!==n.lastResult){if(n.lastResult=o,o&&!n.active){for(let s of n.tools)ce(s);n.active=!0,this.log.info(`[plugins] ${t}: reactivated (${n.tools.length} tools)`)}else if(!o&&n.active){for(let s of n.tools)On(s.name);for(let s of n.hookUnregisterFns)s();n.active=!1,this.log.info(`[plugins] ${t}: deactivated`)}}}}async loadPlugin(e,t){let n=["index.js","index.mjs"],o=null;for(let f of n){let b=Jn.join(t,f);if(Ve.existsSync(b)){o=b;break}}if(!o){this.log.warn(`[plugins] ${e}: no index.js found, skipping`);return}let s=0,i=0,a=0,l=[],u=[],c=null,d=6e4,p={},m=Jn.join(t,"config.json");if(Ve.existsSync(m))try{p=JSON.parse(Ve.readFileSync(m,"utf8"))}catch{}let g={pluginName:e,registerTool:f=>{ce(f),l.push(f),s++},registerHook:(f,b)=>{let h=Cc[f];if(!h){this.log.warn(`[plugins] ${e}: unknown hook phase "${f}"`);return}let k=this.config.hookRegistry.register({point:h,handler:b,label:`plugin:${e}:${f}`,priority:200});u.push(k),i++},registerSkill:f=>{this.pluginSkills.push(f),a++},getConfig:()=>p,setActivationCheck:(f,b)=>{c=f,b!==void 0&&(d=b)}};try{let b=await import(Py(o).href);if(typeof b.register!="function"){this.log.warn(`[plugins] ${e}: no register() export, skipping`);return}await b.register(g),c&&this.activations.set(e,{checkFn:c,ttlMs:d,lastCheckAt:Date.now(),lastResult:!0,tools:l,hookUnregisterFns:u,active:!0}),this.loaded.push({name:e,directory:t,toolCount:s,hookCount:i,skillCount:a}),this.log.info(`[plugins] ${e}: ${s} tools, ${i} hooks, ${a} skills`)}catch(f){this.log.warn(`[plugins] ${e}: load error: ${f instanceof Error?f.message:f}`)}}};import*as re from"node:fs";import*as Kt from"node:path";function as(){return Fi()}function Ac(){return Kt.join(as(),"installed_plugins.json")}function Mc(){let r=Ac();if(!re.existsSync(r))return{version:1,plugins:[]};try{return JSON.parse(re.readFileSync(r,"utf-8"))}catch{return{version:1,plugins:[]}}}function Iy(r){let e=as();re.existsSync(e)||re.mkdirSync(e,{recursive:!0}),re.writeFileSync(Ac(),JSON.stringify(r,null,2),"utf-8")}function Ey(r,e){return!(e.blocklist?.includes(r)||e.allowlist&&!e.allowlist.includes(r))}async function Oy(r,e,t){let{execFile:n}=await import("node:child_process"),{promisify:o}=await import("node:util"),s=o(n),i=as(),a=e?`${r}@${e}`:r;try{let{stdout:l}=await s("npm",["pack",a,"--pack-destination",i],{timeout:6e4,cwd:i}),u=l.trim().split(`
273
- `).pop()?.trim();if(!u)return t.warn(`[marketplace] npm pack returned no output for ${a}`),null;let c=Kt.join(i,u),p=u.match(/^(.+)-(\d+\.\d+\.\d+.*)\.tgz$/)?.[2]??"0.0.0",m=Kt.join(i,`${r}@${p}`);re.existsSync(m)||re.mkdirSync(m,{recursive:!0}),await s("tar",["xzf",c,"-C",m,"--strip-components=1"],{timeout:3e4});try{re.unlinkSync(c)}catch{}let g=Kt.join(m,"package.json");if(re.existsSync(g))try{await s("npm",["install","--production","--no-save"],{cwd:m,timeout:12e4})}catch(f){t.warn(`[marketplace] npm install for ${r} failed: ${f.message}`)}return t.info(`[marketplace] installed ${r}@${p} from npm`),{name:r,version:p,installPath:m}}catch(l){return t.warn(`[marketplace] failed to install ${a} from npm: ${l.message}`),null}}function Ly(){return Mc().plugins.filter(e=>re.existsSync(e.installPath)).map(e=>e.installPath)}async function $y(r,e){let t=Mc(),n=[];for(let o of r.enabledPlugins){let s=o.specifier.split("/").pop()??o.specifier;if(!Ey(s,r)){e.warn(`[marketplace] plugin "${s}" blocked by enterprise policy`);continue}let i=t.plugins.find(l=>l.source.specifier===o.specifier&&l.source.type===o.type);if(i&&re.existsSync(i.installPath)&&(!o.version||i.version===o.version)){n.push(i.installPath);continue}let a=null;switch(o.type){case"npm":a=await Oy(o.specifier,o.version,e);break;case"git":case"url":e.warn(`[marketplace] ${o.type} source not yet implemented for "${o.specifier}"`);break}if(a){let l={name:a.name,version:a.version,source:o,installPath:a.installPath,installedAt:new Date().toISOString()};t.plugins=t.plugins.filter(u=>!(u.source.specifier===o.specifier&&u.source.type===o.type)),t.plugins.push(l),n.push(a.installPath)}}return Iy(t),n}function Dy(){let r=Bi();if(!re.existsSync(r))return null;try{return JSON.parse(re.readFileSync(r,"utf-8"))}catch{return null}}async function Pc(r,e){let t=[...r],n=Ly();t.push(...n);let o=Dy();if(o&&o.enabledPlugins.length>0)try{let s=await $y(o,e),i=new Set(t);for(let a of s)i.has(a)||t.push(a)}catch(s){e.warn(`[marketplace] failed to update plugins: ${s.message}`)}return t}var Xn=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:n}=e;switch(this.mode){case"bypassPermissions":return{behavior:"allow",decisionReason:{type:"mode",mode:"bypassPermissions"}};case"dontAsk":return{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:o,regex:s}of this.compiledPatterns)if(s.test(t))return Ny(o,e);return n?.isReadOnly?{behavior:"allow",decisionReason:{type:"tool_check",reason:"isReadOnly"}}:n?.requiresApproval?{behavior:"ask",message:`Tool "${t}" requires approval`,toolName:t,input:e.arguments,decisionReason:{type:"tool_check",reason:"requiresApproval"}}:n?.isDangerous?{behavior:"ask",message:`Tool "${t}" is marked dangerous`,toolName:t,input:e.arguments,decisionReason:{type:"tool_check",reason:"isDangerous"}}:this.mode==="acceptEdits"?/write|edit|create|delete|move|rename|patch/i.test(t)?{behavior:"allow",decisionReason:{type:"mode",mode:"acceptEdits"}}:{behavior:"ask",message:`Tool "${t}" needs approval in acceptEdits mode`,toolName:t,input:e.arguments,decisionReason:{type:"mode",mode:"acceptEdits"}}: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:Uy(t.pattern)}))}};function ls(r){if(!r||typeof r!="object")return{mode:"default",rules:[],defaultBehavior:"allow"};let e=r,t=[];for(let a of["allow","deny","ask"]){let l=e[a];if(Array.isArray(l))for(let u of l)typeof u=="string"&&t.push({pattern:u,behavior:a,source:"config"})}if(Array.isArray(e.rules)){for(let a of e.rules)if(a&&typeof a=="object"){let l=a,u=l.pattern,c=l.behavior??l.action;typeof u=="string"&&typeof c=="string"&&(c==="allow"||c==="deny"||c==="ask")&&t.push({pattern:u,behavior:c,reason:typeof l.reason=="string"?l.reason:void 0,source:typeof l.source=="string"?l.source:"config"})}}let n=e.mode,o=typeof n=="string"&&Fy(n)?n:"default",s=e.default??e.defaultBehavior,i=typeof s=="string"&&jy(s)?s:"allow";return{mode:o,rules:t,defaultBehavior:i}}function Uy(r){let t=r.replace(/[.+^${}()|[\]\\]/g,"\\$&").replace(/\*+/g,".*");return new RegExp(`^${t}$`,"i")}function Ny(r,e){let t={type:"rule",rule:r};return r.behavior==="allow"?{behavior:"allow",decisionReason:t}:r.behavior==="deny"?{behavior:"deny",message:r.reason??`Tool "${e.toolName}" denied by rule "${r.pattern}"`,decisionReason:t}:{behavior:"ask",message:r.reason??`Tool "${e.toolName}" requires approval (rule "${r.pattern}")`,toolName:e.toolName,input:e.arguments,decisionReason:t}}function Fy(r){return r==="default"||r==="bypassPermissions"||r==="acceptEdits"||r==="dontAsk"||r==="plan"}function jy(r){return r==="allow"||r==="deny"||r==="ask"}import{randomUUID as Ky}from"node:crypto";var By=new Set(["node --version","npm --version","npx --version","pnpm --version","yarn --version","bun --version","deno --version","python --version","python3 --version","pip --version","ruby --version","go version","rustc --version","cargo --version","java -version","javac -version","dotnet --version","gcc --version","g++ --version","clang --version","git --version","docker --version","--help","-h"]),Ic=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","tsc --noEmit","eslint","prettier","oxlint"]),Wy=[/\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],Ec=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 Oc(r,e,t){let n=r.trim();if(!n)return{decision:"allow",reason:"empty command"};let o=Br(n)??Wr(n)??void 0;for(let u of Wy)if(u.test(n))return{decision:"deny",reason:`matches dangerous pattern: ${u.source}`,destructiveWarning:o};for(let u of By)if(n===u||n.startsWith(u+" "))return{decision:"allow",reason:`known safe command: ${u}`,destructiveWarning:o};let s=n.split(/\s+/),i=s[0],a=s.length>1?`${s[0]} ${s[1]}`:i;return Ic.has(i)||Ic.has(a)?{decision:"allow",reason:`known safe command: ${i}`,destructiveWarning:o}:e&&t&&e.startsWith(t)&&(Ec.has(i)||Ec.has(a))?{decision:"allow",reason:`safe in project: ${a}`,destructiveWarning:o}:{decision:"defer",reason:"unknown command \u2014 needs LLM classification",destructiveWarning:o}}function Gy(r){let e=Object.keys(r).sort(),t={};for(let n of e){let o=r[n];typeof o=="string"?t[n]=o.replace(/\s+/g," ").trim():t[n]=o}return JSON.stringify(t)}function cs(r,e){return`${r}::${Gy(e)}`}var Hy=500,Qn=class{cache=new Map;get(e,t){let n=cs(e,t),o=this.cache.get(n);if(o)return o.hitCount++,o}set(e,t,n){if(this.cache.size>=Hy){let s=this.cache.keys().next().value;s!==void 0&&this.cache.delete(s)}let o=cs(e,t);this.cache.set(o,{shouldBlock:n.shouldBlock,reason:n.reason,classifiedAt:Date.now(),hitCount:0})}has(e,t){return this.cache.has(cs(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 zy=new Set(["read","search","instructions","think","todo","memory","skill_list","skill_view","tool_search","plan_mode","lsp","brief","web_search","checkpoint"]);function Jt(r){return zy.has(r)}var Lc=`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.
272
+ [Binary content not displayed. Use appropriate tool to process.]`})}return s.length===0?{content:[{type:"text",text:`Resource "${t.uri}" has no readable content.`}],details:{type:"read_mcp_resource",empty:!0}}:{content:s,details:{type:"read_mcp_resource",uri:t.uri,server:t.server,contentCount:o.length}}}catch(o){return{content:[{type:"text",text:`Error reading resource: ${o.message}`}],details:{error:o.message}}}}}}import*as Ve from"node:fs";import*as Jn from"node:path";import{pathToFileURL as Py}from"node:url";var Cc={preToolUse:"tool.before_invoke",postToolUse:"tool.after_invoke",onTurnStart:"turn.submitted",onTurnEnd:"turn.completed",onSessionEnd:"session.ended"};var Yn=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(!Ve.existsSync(e))continue;let t;try{t=Ve.readdirSync(e,{withFileTypes:!0})}catch{continue}for(let n of t){if(!n.isDirectory()||n.name.startsWith(".")||n.name.startsWith("_"))continue;let o=Jn.join(e,n.name);await this.loadPlugin(n.name,o)}}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 refreshActivations(){let e=Date.now();for(let[t,n]of this.activations){if(e-n.lastCheckAt<n.ttlMs)continue;let o;try{o=await n.checkFn()}catch(s){this.log.warn(`[plugins] ${t}: check_fn error: ${s instanceof Error?s.message:s}`),o=n.lastResult}if(n.lastCheckAt=e,o!==n.lastResult){if(n.lastResult=o,o&&!n.active){for(let s of n.tools)ce(s);n.active=!0,this.log.info(`[plugins] ${t}: reactivated (${n.tools.length} tools)`)}else if(!o&&n.active){for(let s of n.tools)On(s.name);for(let s of n.hookUnregisterFns)s();n.active=!1,this.log.info(`[plugins] ${t}: deactivated`)}}}}async loadPlugin(e,t){let n=["index.js","index.mjs"],o=null;for(let f of n){let b=Jn.join(t,f);if(Ve.existsSync(b)){o=b;break}}if(!o){this.log.warn(`[plugins] ${e}: no index.js found, skipping`);return}let s=0,i=0,a=0,l=[],u=[],c=null,d=6e4,p={},m=Jn.join(t,"config.json");if(Ve.existsSync(m))try{p=JSON.parse(Ve.readFileSync(m,"utf8"))}catch{}let g={pluginName:e,registerTool:f=>{ce(f),l.push(f),s++},registerHook:(f,b)=>{let h=Cc[f];if(!h){this.log.warn(`[plugins] ${e}: unknown hook phase "${f}"`);return}let k=this.config.hookRegistry.register({point:h,handler:b,label:`plugin:${e}:${f}`,priority:200});u.push(k),i++},registerSkill:f=>{this.pluginSkills.push(f),a++},getConfig:()=>p,setActivationCheck:(f,b)=>{c=f,b!==void 0&&(d=b)}};try{let b=await import(Py(o).href);if(typeof b.register!="function"){this.log.warn(`[plugins] ${e}: no register() export, skipping`);return}await b.register(g),c&&this.activations.set(e,{checkFn:c,ttlMs:d,lastCheckAt:Date.now(),lastResult:!0,tools:l,hookUnregisterFns:u,active:!0}),this.loaded.push({name:e,directory:t,toolCount:s,hookCount:i,skillCount:a}),this.log.info(`[plugins] ${e}: ${s} tools, ${i} hooks, ${a} skills`)}catch(f){this.log.warn(`[plugins] ${e}: load error: ${f instanceof Error?f.message:f}`)}}};import*as oe from"node:fs";import*as Kt from"node:path";function as(){return Fi()}function Ac(){return Kt.join(as(),"installed_plugins.json")}function Mc(){let r=Ac();if(!oe.existsSync(r))return{version:1,plugins:[]};try{return JSON.parse(oe.readFileSync(r,"utf-8"))}catch{return{version:1,plugins:[]}}}function Iy(r){let e=as();oe.existsSync(e)||oe.mkdirSync(e,{recursive:!0}),oe.writeFileSync(Ac(),JSON.stringify(r,null,2),"utf-8")}function Ey(r,e){return!(e.blocklist?.includes(r)||e.allowlist&&!e.allowlist.includes(r))}async function Oy(r,e,t){let{execFile:n}=await import("node:child_process"),{promisify:o}=await import("node:util"),s=o(n),i=as(),a=e?`${r}@${e}`:r;try{let{stdout:l}=await s("npm",["pack",a,"--pack-destination",i],{timeout:6e4,cwd:i}),u=l.trim().split(`
273
+ `).pop()?.trim();if(!u)return t.warn(`[marketplace] npm pack returned no output for ${a}`),null;let c=Kt.join(i,u),p=u.match(/^(.+)-(\d+\.\d+\.\d+.*)\.tgz$/)?.[2]??"0.0.0",m=Kt.join(i,`${r}@${p}`);oe.existsSync(m)||oe.mkdirSync(m,{recursive:!0}),await s("tar",["xzf",c,"-C",m,"--strip-components=1"],{timeout:3e4});try{oe.unlinkSync(c)}catch{}let g=Kt.join(m,"package.json");if(oe.existsSync(g))try{await s("npm",["install","--production","--no-save"],{cwd:m,timeout:12e4})}catch(f){t.warn(`[marketplace] npm install for ${r} failed: ${f.message}`)}return t.info(`[marketplace] installed ${r}@${p} from npm`),{name:r,version:p,installPath:m}}catch(l){return t.warn(`[marketplace] failed to install ${a} from npm: ${l.message}`),null}}function Ly(){return Mc().plugins.filter(e=>oe.existsSync(e.installPath)).map(e=>e.installPath)}async function $y(r,e){let t=Mc(),n=[];for(let o of r.enabledPlugins){let s=o.specifier.split("/").pop()??o.specifier;if(!Ey(s,r)){e.warn(`[marketplace] plugin "${s}" blocked by enterprise policy`);continue}let i=t.plugins.find(l=>l.source.specifier===o.specifier&&l.source.type===o.type);if(i&&oe.existsSync(i.installPath)&&(!o.version||i.version===o.version)){n.push(i.installPath);continue}let a=null;switch(o.type){case"npm":a=await Oy(o.specifier,o.version,e);break;case"git":case"url":e.warn(`[marketplace] ${o.type} source not yet implemented for "${o.specifier}"`);break}if(a){let l={name:a.name,version:a.version,source:o,installPath:a.installPath,installedAt:new Date().toISOString()};t.plugins=t.plugins.filter(u=>!(u.source.specifier===o.specifier&&u.source.type===o.type)),t.plugins.push(l),n.push(a.installPath)}}return Iy(t),n}function Dy(){let r=Bi();if(!oe.existsSync(r))return null;try{return JSON.parse(oe.readFileSync(r,"utf-8"))}catch{return null}}async function Pc(r,e){let t=[...r],n=Ly();t.push(...n);let o=Dy();if(o&&o.enabledPlugins.length>0)try{let s=await $y(o,e),i=new Set(t);for(let a of s)i.has(a)||t.push(a)}catch(s){e.warn(`[marketplace] failed to update plugins: ${s.message}`)}return t}var Xn=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:n}=e;switch(this.mode){case"bypassPermissions":return{behavior:"allow",decisionReason:{type:"mode",mode:"bypassPermissions"}};case"dontAsk":return{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:o,regex:s}of this.compiledPatterns)if(s.test(t))return Ny(o,e);return n?.isReadOnly?{behavior:"allow",decisionReason:{type:"tool_check",reason:"isReadOnly"}}:n?.requiresApproval?{behavior:"ask",message:`Tool "${t}" requires approval`,toolName:t,input:e.arguments,decisionReason:{type:"tool_check",reason:"requiresApproval"}}:n?.isDangerous?{behavior:"ask",message:`Tool "${t}" is marked dangerous`,toolName:t,input:e.arguments,decisionReason:{type:"tool_check",reason:"isDangerous"}}:this.mode==="acceptEdits"?/write|edit|create|delete|move|rename|patch/i.test(t)?{behavior:"allow",decisionReason:{type:"mode",mode:"acceptEdits"}}:{behavior:"ask",message:`Tool "${t}" needs approval in acceptEdits mode`,toolName:t,input:e.arguments,decisionReason:{type:"mode",mode:"acceptEdits"}}: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:Uy(t.pattern)}))}};function ls(r){if(!r||typeof r!="object")return{mode:"default",rules:[],defaultBehavior:"allow"};let e=r,t=[];for(let a of["allow","deny","ask"]){let l=e[a];if(Array.isArray(l))for(let u of l)typeof u=="string"&&t.push({pattern:u,behavior:a,source:"config"})}if(Array.isArray(e.rules)){for(let a of e.rules)if(a&&typeof a=="object"){let l=a,u=l.pattern,c=l.behavior??l.action;typeof u=="string"&&typeof c=="string"&&(c==="allow"||c==="deny"||c==="ask")&&t.push({pattern:u,behavior:c,reason:typeof l.reason=="string"?l.reason:void 0,source:typeof l.source=="string"?l.source:"config"})}}let n=e.mode,o=typeof n=="string"&&Fy(n)?n:"default",s=e.default??e.defaultBehavior,i=typeof s=="string"&&jy(s)?s:"allow";return{mode:o,rules:t,defaultBehavior:i}}function Uy(r){let t=r.replace(/[.+^${}()|[\]\\]/g,"\\$&").replace(/\*+/g,".*");return new RegExp(`^${t}$`,"i")}function Ny(r,e){let t={type:"rule",rule:r};return r.behavior==="allow"?{behavior:"allow",decisionReason:t}:r.behavior==="deny"?{behavior:"deny",message:r.reason??`Tool "${e.toolName}" denied by rule "${r.pattern}"`,decisionReason:t}:{behavior:"ask",message:r.reason??`Tool "${e.toolName}" requires approval (rule "${r.pattern}")`,toolName:e.toolName,input:e.arguments,decisionReason:t}}function Fy(r){return r==="default"||r==="bypassPermissions"||r==="acceptEdits"||r==="dontAsk"||r==="plan"}function jy(r){return r==="allow"||r==="deny"||r==="ask"}import{randomUUID as Ky}from"node:crypto";var By=new Set(["node --version","npm --version","npx --version","pnpm --version","yarn --version","bun --version","deno --version","python --version","python3 --version","pip --version","ruby --version","go version","rustc --version","cargo --version","java -version","javac -version","dotnet --version","gcc --version","g++ --version","clang --version","git --version","docker --version","--help","-h"]),Ic=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","tsc --noEmit","eslint","prettier","oxlint"]),Wy=[/\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],Ec=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 Oc(r,e,t){let n=r.trim();if(!n)return{decision:"allow",reason:"empty command"};let o=Br(n)??Wr(n)??void 0;for(let u of Wy)if(u.test(n))return{decision:"deny",reason:`matches dangerous pattern: ${u.source}`,destructiveWarning:o};for(let u of By)if(n===u||n.startsWith(u+" "))return{decision:"allow",reason:`known safe command: ${u}`,destructiveWarning:o};let s=n.split(/\s+/),i=s[0],a=s.length>1?`${s[0]} ${s[1]}`:i;return Ic.has(i)||Ic.has(a)?{decision:"allow",reason:`known safe command: ${i}`,destructiveWarning:o}:e&&t&&e.startsWith(t)&&(Ec.has(i)||Ec.has(a))?{decision:"allow",reason:`safe in project: ${a}`,destructiveWarning:o}:{decision:"defer",reason:"unknown command \u2014 needs LLM classification",destructiveWarning:o}}function Gy(r){let e=Object.keys(r).sort(),t={};for(let n of e){let o=r[n];typeof o=="string"?t[n]=o.replace(/\s+/g," ").trim():t[n]=o}return JSON.stringify(t)}function cs(r,e){return`${r}::${Gy(e)}`}var Hy=500,Qn=class{cache=new Map;get(e,t){let n=cs(e,t),o=this.cache.get(n);if(o)return o.hitCount++,o}set(e,t,n){if(this.cache.size>=Hy){let s=this.cache.keys().next().value;s!==void 0&&this.cache.delete(s)}let o=cs(e,t);this.cache.set(o,{shouldBlock:n.shouldBlock,reason:n.reason,classifiedAt:Date.now(),hitCount:0})}has(e,t){return this.cache.has(cs(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 zy=new Set(["read","search","instructions","think","todo","memory","skill_list","skill_view","tool_search","plan_mode","lsp","brief","web_search","checkpoint"]);function Jt(r){return zy.has(r)}var Lc=`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.
274
274
 
275
275
  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).
276
276
 
@@ -424,9 +424,9 @@ Based on the conversation, suggest 1-3 short follow-up actions the user might na
424
424
  Be specific: "run the tests" beats "continue".
425
425
  Stay silent if the next step isn't obvious.
426
426
  Reply with ONLY a JSON array: [{"text":"short suggestion"}]. No explanation.`;async generateSuggestions(e,t,n,o,s){if(t.filter(u=>u.role==="assistant").length<1)return;let l=[...t.slice(-6),{role:"user",content:r.SUGGESTION_PROMPT}];try{let u="";for await(let d of n.stream({model:s,messages:l,temperature:.3,maxTokens:200},o))d.type==="delta"&&(u+=d.text);let c=u.match(/\[[\s\S]*\]/);if(c){let d=JSON.parse(c[0]),p=Array.isArray(d)?d.filter(m=>typeof m.text=="string"&&m.text.length>0).slice(0,5):[];p.length>0&&this.sendNotification("turn.suggestions",{turnId:e,items:p})}}catch{}}async handleDream(e){let t=e.params??{},n=t.turnId??ve(),o=t.sessionId,s=t.config,i=s?.memoryRoot??"",a=s?.transcriptDir??"",l=s?.dreamSessionIds??[];e.id!==void 0&&this.sendResponse(e.id,{accepted:!0,turnId:n});let u=new AbortController;this.activeTurn=u,this.log(`dream ${n} starting (session: ${o}, sessions reviewing: ${l.length})`);let c={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 p=c.provider??"",m=c.model??"";p&&m&&this.registry.getModelInfo(p,m)?.streamRequired&&(c.streamRequired=!0)}if(!this.resolveAgent(c)){this.sendNotification("turn.start",{turnId:n}),this.sendNotification("turn.error",{turnId:n,error:"No LLM provider configured for dream.",code:"NO_PROVIDER"});return}this.sendNotification("turn.start",{turnId:n});try{let p={context:{memoryRoot:i,transcriptDir:a,currentSessionId:o,listSessionsSince:async()=>l},triggerConfig:{force:!0},transport:this.currentTransport,toolInvoker:{invoke:async(g,f,b,h)=>{if(f.startsWith("$"))return{result:b};let k=ke(f);if(!k)return{result:"",error:`Unknown tool: ${f}`};let x=`tc_${ve().slice(0,8)}`;try{let R=JSON.parse(b),E=await k.execute(x,R,h);return{result:E.content.map(U=>U.text??"").join(`
427
- `),error:E.details?.error}}catch(R){return{result:"",error:R instanceof Error?R.message:String(R)}}}},tools:We(),apiKey:this.currentApiKey,model:c.model??this.currentModel,log:{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}`)}},hooks:this.currentHooks??void 0,parentSignal:u.signal,qmemoryAdapter:this.qmemoryAdapter??void 0,qmemoryUserId:this.qmemoryUserId||void 0},m=await _a(p);m.ok?this.sendNotification("turn.end",{turnId:n,content:`Dream consolidation completed. ${m.sessionsReviewed} sessions reviewed, ${m.filesTouched.length} files touched. Duration: ${m.durationMs}ms.`,usage:{prompt:0,completion:0}}):this.sendNotification("turn.error",{turnId:n,error:m.error??"Dream consolidation failed",code:"DREAM_FAILED"}),this.log(`dream ${n} completed`)}catch(p){if(u.signal.aborted)this.sendNotification("turn.error",{turnId:n,error:"Dream aborted",code:"ABORTED"});else{let m=p instanceof Error?p.message:String(p);this.sendNotification("turn.error",{turnId:n,error:m,code:"INTERNAL_ERROR"})}}finally{this.activeTurn===u&&(this.activeTurn=null)}}resolveAgent(e){let t=`${e.provider??""}:${e.model??""}:${e.apiKey?.slice(0,8)??""}:${e.baseUrl??""}`;if(this.agent&&this.lastLlmConfigKey===t)return this.agent;let n=e.provider,o=e.model,s=e.apiKey,i=e.baseUrl;if(!n||!s){let y=pr(this.registry);y&&(n=n??y.providerId,s=s??y.apiKey,o=o??y.defaultModel,this.log(`auto-detected provider: ${n}, model: ${o}`))}if(!n||!s){let y=this.loadSettingsSync();y&&(n=n??y.provider,s=s??y.apiKey,o=o??y.model,n&&s&&this.log(`loaded provider from settings.json: ${n}, model: ${o}`))}if(!n||!s)return null;o=o??this.registry.getProvider(n)?.defaultModel??"";let a=dr({provider:n,model:o,apiKey:s,baseUrl:i},this.registry);mr()&&(a.transport=gr(a.transport,this.currentSessionId||"default"));let l={info:y=>this.log(y),warn:y=>this.log(`[warn] ${y}`),error:y=>this.log(`[error] ${y}`),debug:y=>{this.verbose&&this.log(`[debug] ${y}`)}},u={invoke:async(y,T,v,_)=>{if(T.startsWith("$"))return{result:v};let C=ke(T);if(!C)return{result:"",error:`Unknown tool: ${T}`};let I=`tc_${ve().slice(0,8)}`;try{let V=JSON.parse(v),j=await C.execute(I,V,_),se=j.content.map(ie=>ie.text??"").join(`
428
- `),X=j.details?.error,P=j.details?.type,ne=P?.split("_")[0];if(ne&&["image","tts","video","music"].includes(ne)){let ie=j.details?.mediaUrls??[],we=ne==="music"?"tts":ne;for(let an of ie)this.sendNotification("turn.media_result",{turnId:y,mediaType:we,url:an,model:j.details?.model,provider:j.details?.provider,...j.details?.durationMs?{durationSeconds:j.details.durationMs/1e3}:{},...j.details?.taskId?{taskId:j.details.taskId}:{}})}if(P==="todo"&&!X)try{let ie=JSON.parse(se);ie.todoList&&this.sendNotification("turn.todos_updated",{turnId:y,items:ie.todoList,summary:{total:ie.total??ie.todoList.length,completed:ie.completed??0,inProgress:ie.inProgress??0,notStarted:ie.notStarted??0}})}catch{}return{result:se,error:X}}catch(V){return{result:"",error:V instanceof Error?V.message:String(V)}}}},c=sa(l);this.currentHooks=c,this.taskStore.setHooks(c,this.currentSessionId??"");let d=(process.env.QMEMORY_BASE_URL??process.env.QLOGICAGENT_QMEMORY_BASE_URL??"").trim().replace(/\/+$/,"");if(d){let y=la({baseUrl:d,apiKey:(process.env.QMEMORY_API_KEY??"").trim()||void 0,timeoutMs:5e3});this.qmemoryAdapter=y,this.qmemoryUserId=this.currentSessionId??"default",ia(c,{memoryProvider:y,userId:this.currentSessionId??"default",log:{debug:T=>l.debug(T),warn:T=>l.warn(T)}},this.memoryPrefetchState)}Si(c,l,{transport:a.transport,apiKey:a.apiKey});let p=e?.mcpServers,m=is(p??{}),g=ji();try{if($.existsSync(g)){let y=JSON.parse($.readFileSync(g,"utf8")),T=is(y),v=new Set(m.map(_=>_.name));m=[...m,...T.filter(_=>!v.has(_.name))]}}catch{}if(m.length>0){this.mcpManager&&this.mcpManager.disconnectAll().catch(()=>{}),this.mcpManager=new Kn({servers:m,log:l}),it(async()=>{await this.mcpManager?.disconnectAll()});let y=()=>this.mcpManager;ce(Rc(y)),ce(_c(y)),ce(Yc({listServers:async()=>{let T=this.mcpManager;return T?T.getConnectedServers().map(_=>({name:_,status:"connected",transport:"stdio",toolCount:0,resourceCount:0,promptCount:0})):[]},listTools:async T=>{if(!this.mcpManager)return[];let _=`mcp__${T.replace(/[^a-zA-Z0-9_]/g,"_").toLowerCase()}__`;return Be().filter(C=>C.startsWith(_)).map(C=>({name:C.slice(_.length),prefixedName:C}))},callTool:async(T,v,_,C)=>{let V=`mcp__${T.replace(/[^a-zA-Z0-9_]/g,"_").toLowerCase()}__`+v,j=ke(V);if(!j)return{success:!1,error:`Tool not found: ${V}`};try{return{success:!0,content:(await j.execute(`mcp_${Date.now()}`,_??{},C)).content.map(P=>P.text??"").join(`
429
- `)}}catch(se){return{success:!1,error:se.message}}},listResources:async T=>{let v=this.mcpManager;return v?(await v.listResources(T)).map(C=>({uri:C.uri,name:C.name,mimeType:C.mimeType,description:C.description,server:C.server})):[]},readResource:async(T,v)=>{let _=this.mcpManager;if(!_)throw new Error("MCP not initialized");return(await _.readResource(T,v)).map(I=>({uri:I.uri,mimeType:I.mimeType,text:I.text}))},authenticate:async()=>({status:"unsupported",message:"OAuth not yet implemented in McpManager"})})),this.mcpManager.connectAll().then(()=>{this.mcpManager?.injectTools(),l.info(`[mcp] ${this.mcpManager?.getToolCount()??0} tools from ${this.mcpManager?.getConnectedServers().length??0} servers`)}).catch(T=>{l.warn(`[mcp] connection error: ${T instanceof Error?T.message:T}`)})}let f=[],b=Di();$.existsSync(b)&&f.push(b);let h=e?.pluginPaths;if(Array.isArray(h))for(let y of h)typeof y=="string"&&$.existsSync(y)&&f.push(y);Pc(f,l).then(y=>{if(y.length===0)return;this.pluginLoader=new Yn({pluginDirs:y,hookRegistry:c,log:l}),this.pluginLoader.loadAll().then(v=>{l.info(`[plugins] ${v.length} loaded, ${this.pluginLoader?.getPluginSkills().length??0} skills`)}).catch(v=>{l.warn(`[plugins] load error: ${v instanceof Error?v.message:v}`)});let T=this.pluginLoader;c.register({point:"turn.submitted",handler:async()=>(await T.refreshActivations(),{action:"continue"}),label:"plugin-activation-refresh",priority:50})}).catch(y=>{l.warn(`[plugins] marketplace resolve error: ${y instanceof Error?y.message:y}`)});let k=e?.permissions,x=ls(k),R=new Xn(x);this.permissionUnregister&&this.permissionUnregister(),this.permissionChecker=new Zn({ruleEngine:R,hookRegistry:c,onRequestApproval:async y=>(this.sendNotification("tool.approval.request",{approvalId:y.approvalId,callId:y.callId,toolName:y.toolName,arguments:y.arguments?JSON.stringify(y.arguments):"",message:y.message,suggestions:y.suggestions?.map(T=>`${T.pattern}:${T.behavior}`)}),new Promise(()=>{})),onPermissionUpdate:y=>{l.info(`[permissions] rule saved: ${y.pattern} \u2192 ${y.behavior}`),this.sendNotification("permission.rule_updated",{pattern:y.pattern,behavior:y.behavior})},onDenied:(y,T)=>{l.warn(`[permissions] blocked "${y}": ${T}`)}});let E=We();this.permissionChecker.setToolMeta(E),this.permissionUnregister=this.permissionChecker.register();let F=[rr(),...Array.isArray(e?.skillPaths)?e.skillPaths:[]];ce(Bc({listSkills:()=>{let y=[];this.pluginLoader&&y.push(...this.pluginLoader.getPluginSkills());let T=e?.skillPaths;if(Array.isArray(T)){for(let v of T)if(typeof v=="string"){let _=J.basename(v);y.some(C=>C.name===_)||y.push({name:_,source:"gateway",filePath:J.join(v,"SKILL.md"),baseDir:v})}}return y},listSkillsFull:async y=>{let T=[],v=new Set;for(let _ of F)try{let C=await $.promises.readdir(_,{withFileTypes:!0});for(let I of C){if(!I.isDirectory())continue;let V=J.join(_,I.name,"SKILL.md");try{await $.promises.access(V);let j=J.basename(_);if(y&&j!==y)continue;v.add(j),T.push({name:I.name,description:`Skill from ${_}`,category:j})}catch{}}}catch{}if(this.pluginLoader)for(let _ of this.pluginLoader.getPluginSkills())y&&_.source!==y||(v.add(_.source??"plugin"),T.push({name:_.name,description:`Plugin skill (${_.source})`,category:_.source}));return{skills:T,categories:[...v]}},readSkillContent:async y=>{for(let T of F){let v=J.join(T,y,"SKILL.md");try{return await $.promises.readFile(v,"utf8")}catch{}}return null},viewSkill:async(y,T)=>{for(let v of F){let _=T?J.join(v,y,T):J.join(v,y,"SKILL.md");try{let C=await $.promises.readFile(_,"utf8");return{name:y,content:C}}catch{}}return null},executeSkillSubturn:async(y,T,v,_)=>{let C=`skill_${y}_${ve().slice(0,8)}`,I=this.agent;if(!I)return"[skill] Cannot execute: no LLM provider configured";let V=this.currentSessionId??"skill";this.currentHooks?.invoke("subagent.started",{sessionId:V,turnId:C,subagentId:C,agentType:`skill:${y}`}).catch(()=>{});let j=We(),se=v??`Execute skill "${y}" instructions.`,X=[],P;for await(let ne of I.run({turnId:C,sessionId:V,messages:[{role:"user",content:se}],tools:j,systemPrompt:T,config:{parentDepth:1}},_)){if(ne.type==="end"&&ne.content)return this.currentHooks?.invoke("subagent.stopped",{sessionId:V,turnId:C,subagentId:C,agentType:`skill:${y}`,reason:"normal"}).catch(()=>{}),ne.content;if(ne.type==="delta"&&ne.text&&X.push(ne.text),ne.type==="error"){P=ne.error;break}}return this.currentHooks?.invoke("subagent.stopped",{sessionId:V,turnId:C,subagentId:C,agentType:`skill:${y}`,reason:P?"error":"normal",error:P}).catch(()=>{}),P?`[skill "${y}"] error: ${P}`:X.join("")||`[skill "${y}"] completed (no output)`},manageSkill:async y=>{let T=J.join(F[0]??rr(),y.name),v=J.join(T,"SKILL.md");switch(y.action){case"create":return await $.promises.mkdir(T,{recursive:!0}),await $.promises.writeFile(v,y.content??"","utf8"),{success:!0,message:`Skill "${y.name}" created`,path:T};case"edit":return await $.promises.writeFile(v,y.content??"","utf8"),{success:!0,message:`Skill "${y.name}" updated`,path:v};case"patch":{let _=await $.promises.readFile(v,"utf8");return!y.oldString||!_.includes(y.oldString)?{success:!1,message:"oldString not found in SKILL.md"}:(await $.promises.writeFile(v,_.replace(y.oldString,y.newString??""),"utf8"),{success:!0,message:`Skill "${y.name}" patched`,path:v})}case"delete":return await $.promises.rm(T,{recursive:!0,force:!0}),{success:!0,message:`Skill "${y.name}" deleted`};default:return{success:!1,message:`Unknown action: ${y.action}`}}}})),ce(Hc({abortSignal:void 0,currentForkDepth:0,forkAgent:async y=>{let T=No(y.agent);if(!T)return{agentId:"",status:"failed",error:`Unknown agent type: ${y.agent}`};if(!this.agent||!this.currentTransport||!this.currentApiKey||!this.currentModel)return{agentId:"",status:"failed",error:"No LLM provider configured"};let v=Be(),_=Do(v,T),I=We().filter(P=>_.includes(P.function.name)),V=Sr(I,!0),j=y.maxTurns??T.maxTurns??200,se=await Rn({promptMessages:[{role:"user",content:y.prompt}],tools:V,transport:this.currentTransport,toolInvoker:u,apiKey:this.currentApiKey,model:this.currentModel,log:l,hooks:c,forkLabel:`agent-${y.agent}`,maxTurns:j,parentSignal:y.abortSignal,parentDepth:0,onEvent:P=>{P.type==="delta"&&P.text&&this.sendNotification("turn.subagent_delta",{agentType:y.agent,text:P.text})}}),X=se.events.filter(P=>P.type==="end"&&"content"in P).map(P=>P.content??"").join("")||se.events.filter(P=>P.type==="delta"&&"text"in P).map(P=>P.text).join("");return{agentId:`fork-${y.agent}-${ve().slice(0,8)}`,status:se.ok?"completed":"failed",output:X||void 0,error:se.error,tokensUsed:se.totalUsage.prompt+se.totalUsage.completion}}}));let U=dt(),D=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"]}]]),w=async()=>{try{return JSON.parse(await $.promises.readFile(U,"utf8"))}catch{return{}}},ge=async y=>{await $.promises.mkdir(J.dirname(U),{recursive:!0}),await $.promises.writeFile(U,JSON.stringify(y,null,2),"utf8")};ce(zc({getConfig:async y=>{let T=D.get(y);if(!T)return{success:!1,error:`Unknown key: ${y}`};let v=await w(),_=y in v?v[y]:T.value;return{success:!0,setting:{...T,value:_,readOnly:Yt.includes(y)}}},setConfig:async(y,T)=>{let v=D.get(y);if(!v)return{success:!1,error:`Unknown key: ${y}`};let _=await w(),C=y in _?_[y]:v.value;return _[y]=T,await ge(_),{success:!0,previousValue:C,setting:{...v,value:T}}},listConfig:async()=>{let y=await w();return{success:!0,settings:[...D.values()].map(v=>({...v,value:v.key in y?y[v.key]:v.value,readOnly:Yt.includes(v.key)}))}},resetConfig:async y=>{let T=D.get(y);if(!T)return{success:!1,error:`Unknown key: ${y}`};let v=await w();return delete v[y],await ge(v),{success:!0,setting:T}},isValidKey:y=>D.has(y)}));let H=new Map,z=y=>{let T=/^(\d+)([smhd])$/.exec(y.trim());if(!T)return null;let v=parseInt(T[1],10),_=T[2];return v*({s:1e3,m:6e4,h:36e5,d:864e5}[_]??6e4)},fe=y=>{y.timerId&&clearTimeout(y.timerId);let T=z(y.schedule);T&&(y.timerId=setTimeout(()=>{y.lastRunAt=new Date().toISOString(),y.repeat.completed++,y.lastStatus="success",l.info(`[cron] triggered job ${y.id} (${y.name})`),y.repeat.times===null||y.repeat.completed<y.repeat.times?fe(y):(y.state="paused",y.enabled=!1)},T),y.nextRunAt=new Date(Date.now()+T).toISOString())};it(async()=>{for(let y of H.values())y.timerId&&clearTimeout(y.timerId)}),ce(qc({createJob:async y=>{let T=`cron_${ve().slice(0,8)}`,v={id:T,name:y.name??`Job ${T}`,prompt:y.prompt,schedule:y.schedule,scheduleDisplay:y.schedule,state:"scheduled",enabled:!0,repeat:{times:y.repeat??null,completed:0},allowedTools:y.allowedTools};return H.set(T,v),fe(v),{success:!0,job:{...v,timerId:void 0}}},listJobs:async()=>({success:!0,jobs:[...H.values()].map(T=>({...T,timerId:void 0}))}),getJob:async y=>{let T=H.get(y);return T?{success:!0,job:{...T,timerId:void 0}}:{success:!1,error:`Job not found: ${y}`}},updateJob:async(y,T)=>{let v=H.get(y);return v?(T.prompt!==void 0&&(v.prompt=T.prompt),T.schedule!==void 0&&(v.schedule=T.schedule,v.scheduleDisplay=T.schedule),T.name!==void 0&&(v.name=T.name),T.enabled!==void 0&&(v.enabled=T.enabled,v.state=T.enabled?"scheduled":"paused"),T.repeat!==void 0&&(v.repeat.times=T.repeat),T.allowedTools!==void 0&&(v.allowedTools=T.allowedTools),v.enabled?fe(v):v.timerId&&(clearTimeout(v.timerId),v.timerId=void 0),{success:!0,job:{...v,timerId:void 0}}):{success:!1,error:`Job not found: ${y}`}},deleteJob:async y=>{let T=H.get(y);return T?(T.timerId&&clearTimeout(T.timerId),H.delete(y),{success:!0}):{success:!1,error:`Job not found: ${y}`}},pauseJob:async y=>{let T=H.get(y);return T?(T.state="paused",T.enabled=!1,T.timerId&&(clearTimeout(T.timerId),T.timerId=void 0),{success:!0,job:{...T,timerId:void 0}}):{success:!1,error:`Job not found: ${y}`}},resumeJob:async y=>{let T=H.get(y);return T?(T.state="scheduled",T.enabled=!0,fe(T),{success:!0,job:{...T,timerId:void 0}}):{success:!1,error:`Job not found: ${y}`}},triggerJob:async y=>{let T=H.get(y);return T?(T.lastRunAt=new Date().toISOString(),T.repeat.completed++,T.lastStatus="success",{success:!0,job:{...T,timerId:void 0}}):{success:!1,error:`Job not found: ${y}`}},validateSchedule:y=>z(y)!==null||/^\d{1,2}\s/.test(y)?null:`Invalid schedule: ${y}. Use shorthand (5m, 1h, 1d) or cron expression.`}));let te=new Map;it(async()=>{for(let y of te.values())y.cleanup();te.clear()}),ce(Kc({startMonitor:async y=>{if(te.has(y.monitorId))return{action:"start",success:!1,error:`Monitor "${y.monitorId}" already exists.`};let T={monitorId:y.monitorId,source:y.source,target:y.target,conditions:y.conditions,startedAt:Date.now(),timeoutSeconds:y.timeoutSeconds,eventCount:0},v=()=>{};if(y.source==="file")try{let _=$.watch(y.target,{persistent:!1},()=>{T.eventCount++,l.info(`[monitor] file change detected: ${y.target}`)});v=()=>_.close()}catch{return{action:"start",success:!1,error:`Cannot watch: ${y.target}`}}if(y.timeoutSeconds>0){let _=setTimeout(()=>{let I=te.get(y.monitorId);I&&(I.cleanup(),te.delete(y.monitorId))},y.timeoutSeconds*1e3),C=v;v=()=>{clearTimeout(_),C()}}return te.set(y.monitorId,{info:T,cleanup:v}),{action:"start",success:!0,monitorId:y.monitorId}},stopMonitor:async y=>{let T=te.get(y);return T?(T.cleanup(),te.delete(y),{action:"stop",success:!0,monitorId:y}):{action:"stop",success:!1,error:`Monitor "${y}" not found.`}},listMonitors:async()=>[...te.values()].map(y=>y.info)}));let le=new Map,G={info:y=>l.info(y),warn:y=>l.warn(y)},N=new ft({onNotification:(y,T,v)=>{this.sendNotification("team.member.notification",{memberId:y,method:T,params:v})},onStateChange:(y,T)=>{this.sendNotification("team.member.state",{memberId:y,state:T});let v=N.getHandle(y),C=N.getUsageTracker(y)?.getUsage();this.emitAgentStatus(y,T,{missedBeats:N.getMissedBeats(y),lastActivityAt:v?.lastActivityAt,usage:C&&C.totalTokens>0?{inputTokens:C.inputTokens,outputTokens:C.outputTokens,totalTokens:C.totalTokens}:void 0})},onExit:(y,T,v)=>{for(let _ of le.values()){let C=_.members.find(I=>I.cwd&&`team-${_.name}-${I.name}`.replace(/[^a-zA-Z0-9-]/g,"-").toLowerCase()===y.replace(/^team-/,""));C&&(C.isActive=!1)}l.info(`[team] member ${y} exited (code=${T}, signal=${v})`)},onMcpToolCall:(y,T,v)=>this.handleMcpToolCall(y,T,v),log:{info:y=>l.info(y),warn:y=>l.warn(y),debug:y=>l.debug(y)},sessionDir:J.join(B(),"agent-logs")});it(async()=>{N.dispose()}),ce(Jc({createTeam:async y=>{if(le.has(y.teamName))return{success:!1,error:`Team "${y.teamName}" already exists.`};let T=await Vt(),v=[];for(let C of y.members??[]){let I={...C,isActive:!0};if(T){let V=`team-${y.teamName}-${C.name}`.replace(/[^a-zA-Z0-9-]/g,"-").toLowerCase(),j=await jl(T,V,G);j?(I.worktreePath=j.worktreePath,I.worktreeBranch=j.branch,I.cwd=j.worktreePath,l.info(`[team] provisioned worktree for ${C.name}: ${j.worktreePath}`)):(I.cwd=process.cwd(),l.warn(`[team] worktree provision failed for ${C.name}, using shared cwd`))}else I.cwd=process.cwd();v.push(I)}let _={name:y.teamName,description:y.description,leadId:this.currentSessionId??"default",members:v,createdAt:new Date().toISOString()};le.set(y.teamName,_);for(let C of v){if(!C.cwd)continue;let I=`team-${y.teamName}-${C.name}`.replace(/[^a-zA-Z0-9-]/g,"-").toLowerCase();try{await N.spawn({memberId:I,name:C.name,cwd:C.cwd,prompt:`You are the "${C.name}" team member. Role: ${C.role}.`,agentType:C.role,verbose:this.verbose}),l.info(`[team] spawned child process for ${C.name} in ${C.cwd}`)}catch(V){l.warn(`[team] failed to spawn child process for ${C.name}: ${V instanceof Error?V.message:String(V)}`),C.isActive=!1}}return this.sendNotification("team.updated",{teamName:y.teamName,action:"created",members:_.members.map(C=>({agentName:C.name,role:C.role,worktreePath:C.worktreePath,pid:N.getHandle(`team-${y.teamName}-${C.name}`.replace(/[^a-zA-Z0-9-]/g,"-").toLowerCase())?.pid}))}),{success:!0,team:_}},deleteTeam:async y=>{let T=le.get(y);if(!T)return{success:!1,error:`Team "${y}" not found.`};for(let _ of T.members){let C=`team-${y}-${_.name}`.replace(/[^a-zA-Z0-9-]/g,"-").toLowerCase();N.kill(C),N.remove(C)}let v=await Vt();if(v)for(let _ of T.members)_.worktreePath&&_.worktreeBranch&&(await Bl(v,_.worktreePath,_.worktreeBranch,G),l.info(`[team] cleaned up worktree for ${_.name}: ${_.worktreePath}`));return le.delete(y),this.sendNotification("team.updated",{teamName:y,action:"destroyed",members:[]}),{success:!0}},listTeams:async()=>({success:!0,teams:[...le.values()]}),getTeamStatus:async y=>{let T=le.get(y);if(!T)return{success:!1,error:`Team "${y}" not found.`};let v={};for(let _ of T.members){let C=`team-${y}-${_.name}`.replace(/[^a-zA-Z0-9-]/g,"-").toLowerCase(),I=N.getStatus(C);I&&(_.isActive=I.alive,v[_.name]={mediaProgress:I.mediaProgress,lastToolCall:I.lastToolCall,idleFor:I.idleFor,runningFor:I.runningFor})}return{success:!0,team:T,memberProgress:v}}}));{let y=new ao({persistToDisk:!0});y.loadFromDiskSync();let T={providerId:"null",search:async()=>[],ingest:async()=>{}},v=this.qmemoryAdapter??T;ce({name:yu,label:Tu,description:ku,parameters:bu,execute:async(_,C)=>{let I=await wu(C,{provider:v,store:y,userId:this.qmemoryUserId||this.currentSessionId||"default",sessionId:this.currentSessionId});return{content:[{type:"text",text:I.message}],details:{type:"memory",action:I.action,ok:I.ok}}}})}{let y=e?.workdir??process.cwd(),T=Zc(y,this.currentSessionId||"default");ce(Qc(T))}let pe=e?.workdir??process.cwd(),Ee=Su({projectRoot:pe,ruleEngine:R,hooks:c,log:y=>l.info(`[settings] ${y}`)});it(async()=>{Ee()}),this.currentSessionId&&c.invoke("session.created",{sessionId:this.currentSessionId}).catch(()=>{}),this.fileWatcher&&this.fileWatcher.stop();let me=e?.workdir??process.cwd();return La({projectRoot:me,sessionId:this.currentSessionId,hooks:c,log:y=>l.debug(y),onInstructionCacheReset:Fa}).then(y=>{this.fileWatcher=y,it(async()=>{this.fileWatcher?.stop()})}).catch(y=>{l.warn(`[file-watcher] init error: ${y instanceof Error?y.message:y}`)}),this.agent=new Mt({llmTransport:a.transport,apiKey:a.apiKey,toolInvoker:u,log:l,hooks:c,maxRounds:e.maxRounds,verbose:this.verbose}),this.lastLlmConfigKey=t,this.currentTransport=a.transport,this.currentApiKey=a.apiKey,this.currentModel=o,this.log(`created Agent (provider: ${n}, model: ${o})`),this.agent}loadSettingsSync(){try{let e=dt();if(!$.existsSync(e))return;let t=$.readFileSync(e,"utf-8"),n=JSON.parse(t);return{provider:n.provider,model:n.model,apiKey:n.apiKey,baseUrl:n.baseUrl}}catch{return}}handleSessionGetInfo(e){let t=this.currentSessionId||"default",n=this.sessionState?.createSnapshot(),o={sessionId:t,model:this.currentModel||void 0,cwd:process.cwd(),paths:{sessionDir:$i(t),agentHome:B(),settings:dt()},usage:n?{turnCount:n.turnCount,inputTokens:n.totalInputTokens,outputTokens:n.totalOutputTokens}:void 0};e.id!==void 0&&this.sendResponse(e.id,o)}async handleMemoryList(e){let t=[],n=J.join(B(),"memory.json");$.existsSync(n)&&t.push({id:"local",type:"json",path:n}),this.qmemoryAdapter&&t.push({id:"qmemory",type:"vector"}),e.id!==void 0&&this.sendResponse(e.id,{sources:t})}async handleMemoryRead(e){let t=e.params,n=t?.source??"local",o=t?.target??"memory";if(n==="local")try{let s=J.join(B(),"memory.json"),i=await $.promises.readFile(s,"utf-8"),a=JSON.parse(i);e.id!==void 0&&this.sendResponse(e.id,{source:"local",target:o,content:a[o]??""})}catch{e.id!==void 0&&this.sendResponse(e.id,{source:"local",target:o,content:""})}else e.id!==void 0&&this.sendResponse(e.id,void 0,{code:M.INVALID_PARAMS,message:`Unknown memory source: ${n}`})}async handleMemoryWrite(e){let t=e.params,n=t?.target??"memory",o=t?.content;if(n!=="memory"&&n!=="user"){e.id!==void 0&&this.sendResponse(e.id,void 0,{code:M.INVALID_PARAMS,message:`Invalid memory target: ${n}. Must be "memory" or "user".`});return}if(o==null){e.id!==void 0&&this.sendResponse(e.id,void 0,{code:M.INVALID_PARAMS,message:"content is required."});return}try{let s=J.join(B(),"memory.json"),i={};try{let a=await $.promises.readFile(s,"utf-8");i=JSON.parse(a)}catch{}i[n]=o,i.savedAt=new Date().toISOString(),await $.promises.mkdir(B(),{recursive:!0}),await $.promises.writeFile(s,JSON.stringify(i,null,2),"utf-8"),e.id!==void 0&&this.sendResponse(e.id,{ok:!0,target:n}),this.sendNotification("memory.updated",{target:n,source:"rpc"})}catch(s){e.id!==void 0&&this.sendResponse(e.id,void 0,{code:M.INTERNAL_ERROR,message:s instanceof Error?s.message:String(s)})}}handleToolsList(e){let t=e.params,o=We(t?.includeDeferred??!1).map(s=>({name:s.function.name,description:s.function.description??"",parameters:s.function.parameters,source:"builtin"}));if(t?.category){let s=o.filter(i=>i.name.startsWith(t.category)||i.description.toLowerCase().includes(t.category.toLowerCase()));e.id!==void 0&&this.sendResponse(e.id,{tools:s,total:s.length})}else e.id!==void 0&&this.sendResponse(e.id,{tools:o,total:o.length})}handleMediaListModels(e){let n=e.params?.mediaType,s=this.mediaClient.listMediaModels(n).map(i=>({providerId:i.providerId,providerName:i.providerDef.name,modelId:i.modelInfo.id,modelName:i.modelInfo.name,mediaType:i.mediaType,capabilities:i.modelInfo.mediaCapabilities}));e.id!==void 0&&this.sendResponse(e.id,{models:s})}async handleMediaCancel(e){let t=e.params;if(!t?.taskId){e.id!==void 0&&this.sendResponse(e.id,void 0,{code:M.INVALID_PARAMS,message:"taskId is required."});return}let n=t.provider??"doubao",o=this.mediaClient.getTransport(n);if(!o){e.id!==void 0&&this.sendResponse(e.id,{ok:!1,message:`No transport for provider: ${n}`});return}if(!fr(o)){e.id!==void 0&&this.sendResponse(e.id,{ok:!1,message:`Provider ${n} does not support task cancellation.`});return}try{let s=this.resolveMediaApiKey(n);if(!s){e.id!==void 0&&this.sendResponse(e.id,{ok:!1,message:`No API key for provider: ${n}`});return}await o.deleteVideoTask(t.taskId,s),e.id!==void 0&&this.sendResponse(e.id,{ok:!0,taskId:t.taskId,message:"Task cancelled."})}catch(s){e.id!==void 0&&this.sendResponse(e.id,{ok:!1,message:s instanceof Error?s.message:String(s)})}}async handleMediaStatus(e){let t=e.params;if(!t?.taskId){e.id!==void 0&&this.sendResponse(e.id,void 0,{code:M.INVALID_PARAMS,message:"taskId is required."});return}let n=t.provider??"doubao",o=this.mediaClient.getTransport(n);if(!o){e.id!==void 0&&this.sendResponse(e.id,{ok:!1,message:`No transport for provider: ${n}`});return}if(!fr(o)){e.id!==void 0&&this.sendResponse(e.id,{ok:!1,message:`Provider ${n} does not support task status queries.`});return}try{let s=this.resolveMediaApiKey(n);if(!s){e.id!==void 0&&this.sendResponse(e.id,{ok:!1,message:`No API key for provider: ${n}`});return}if(o.getTaskStatus){let{status:u,task:c}=await o.getTaskStatus(t.taskId,s);e.id!==void 0&&this.sendResponse(e.id,{ok:!0,taskId:t.taskId,status:u,task:c});return}let i=await o.listVideoTasks(s,{limit:100}),l=(i.data??i.tasks??[]).find(u=>u.id===t.taskId||u.task_id===t.taskId);e.id!==void 0&&this.sendResponse(e.id,{ok:!0,taskId:t.taskId,...l?{status:l.status,task:l}:{status:"unknown",message:"Task not found in recent list."}})}catch(s){e.id!==void 0&&this.sendResponse(e.id,{ok:!1,message:s instanceof Error?s.message:String(s)})}}resolveMediaApiKey(e){return this.currentMediaApiKeys?.[e]}handleProviderList(e){let t=this.registry.listProviders(),n=new Map;for(let s of t){let i=s.group??s.id;n.has(i)||n.set(i,[]);let a=!!this.registry.resolveApiKey(s.id);n.get(i).push({id:s.id,name:s.name,transport:s.transport,baseUrl:s.baseUrl,defaultModel:s.defaultModel,modelCount:s.models?.length??0,available:a})}let o=[...n.entries()].map(([s,i])=>({group:s,variants:i}));e.id!==void 0&&this.sendResponse(e.id,{providers:o})}handleConfigGet(e){try{let t=dt(),n={};if($.existsSync(t)){let o=$.readFileSync(t,"utf-8");n=JSON.parse(o)}e.id!==void 0&&this.sendResponse(e.id,{config:n,paths:{userSettings:t,agentHome:B()}})}catch(t){e.id!==void 0&&this.sendResponse(e.id,void 0,{code:M.INTERNAL_ERROR,message:t instanceof Error?t.message:String(t)})}}async handleConfigUpdate(e){let t=e.params;if(!t?.updates||typeof t.updates!="object"){e.id!==void 0&&this.sendResponse(e.id,void 0,{code:M.INVALID_PARAMS,message:"updates (object) is required."});return}try{let n=dt(),o={};try{let s=await $.promises.readFile(n,"utf-8");o=JSON.parse(s)}catch{}Object.assign(o,t.updates),await $.promises.mkdir(J.dirname(n),{recursive:!0}),await $.promises.writeFile(n,JSON.stringify(o,null,2),"utf-8"),e.id!==void 0&&this.sendResponse(e.id,{ok:!0})}catch(n){e.id!==void 0&&this.sendResponse(e.id,void 0,{code:M.INTERNAL_ERROR,message:n instanceof Error?n.message:String(n)})}}async handleTodosList(e){let t=ke("todo");if(!t){e.id!==void 0&&this.sendResponse(e.id,{items:[],summary:mt([])});return}try{let o=(await t.execute("rpc-todos-list",{action:"list"},void 0)).content.map(a=>a.text??"").join(""),i=JSON.parse(o).todoList??[];e.id!==void 0&&this.sendResponse(e.id,{items:i,summary:mt(i)})}catch{e.id!==void 0&&this.sendResponse(e.id,{items:[],summary:mt([])})}}async handleMemorySearch(e){let t=e.params;if(!t?.query){e.id!==void 0&&this.sendResponse(e.id,void 0,{code:M.INVALID_PARAMS,message:"query is required."});return}if(!this.qmemoryAdapter){try{let n=J.join(B(),"memory.json"),o=await $.promises.readFile(n,"utf-8"),s=JSON.parse(o),i=[],a=t.query.toLowerCase();for(let[l,u]of Object.entries(s)){if(typeof u!="string")continue;let c=u.split(`
427
+ `),error:E.details?.error}}catch(R){return{result:"",error:R instanceof Error?R.message:String(R)}}}},tools:We(),apiKey:this.currentApiKey,model:c.model??this.currentModel,log:{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}`)}},hooks:this.currentHooks??void 0,parentSignal:u.signal,qmemoryAdapter:this.qmemoryAdapter??void 0,qmemoryUserId:this.qmemoryUserId||void 0},m=await _a(p);m.ok?this.sendNotification("turn.end",{turnId:n,content:`Dream consolidation completed. ${m.sessionsReviewed} sessions reviewed, ${m.filesTouched.length} files touched. Duration: ${m.durationMs}ms.`,usage:{prompt:0,completion:0}}):this.sendNotification("turn.error",{turnId:n,error:m.error??"Dream consolidation failed",code:"DREAM_FAILED"}),this.log(`dream ${n} completed`)}catch(p){if(u.signal.aborted)this.sendNotification("turn.error",{turnId:n,error:"Dream aborted",code:"ABORTED"});else{let m=p instanceof Error?p.message:String(p);this.sendNotification("turn.error",{turnId:n,error:m,code:"INTERNAL_ERROR"})}}finally{this.activeTurn===u&&(this.activeTurn=null)}}resolveAgent(e){let t=`${e.provider??""}:${e.model??""}:${e.apiKey?.slice(0,8)??""}:${e.baseUrl??""}`;if(this.agent&&this.lastLlmConfigKey===t)return this.agent;let n=e.provider,o=e.model,s=e.apiKey,i=e.baseUrl;if(!n||!s){let y=pr(this.registry);y&&(n=n??y.providerId,s=s??y.apiKey,o=o??y.defaultModel,this.log(`auto-detected provider: ${n}, model: ${o}`))}if(!n||!s){let y=this.loadSettingsSync();y&&(n=n??y.provider,s=s??y.apiKey,o=o??y.model,n&&s&&this.log(`loaded provider from settings.json: ${n}, model: ${o}`))}if(!n||!s)return null;o=o??this.registry.getProvider(n)?.defaultModel??"";let a=dr({provider:n,model:o,apiKey:s,baseUrl:i},this.registry);mr()&&(a.transport=gr(a.transport,this.currentSessionId||"default"));let l={info:y=>this.log(y),warn:y=>this.log(`[warn] ${y}`),error:y=>this.log(`[error] ${y}`),debug:y=>{this.verbose&&this.log(`[debug] ${y}`)}},u={invoke:async(y,T,v,_)=>{if(T.startsWith("$"))return{result:v};let C=ke(T);if(!C)return{result:"",error:`Unknown tool: ${T}`};let I=`tc_${ve().slice(0,8)}`;try{let V=JSON.parse(v),j=await C.execute(I,V,_),re=j.content.map(ie=>ie.text??"").join(`
428
+ `),X=j.details?.error,P=j.details?.type,se=P?.split("_")[0];if(se&&["image","tts","video","music"].includes(se)){let ie=j.details?.mediaUrls??[],we=se;for(let an of ie)this.sendNotification("turn.media_result",{turnId:y,mediaType:we,url:an,model:j.details?.model,provider:j.details?.provider,...j.details?.durationMs?{durationSeconds:j.details.durationMs/1e3}:{},...j.details?.taskId?{taskId:j.details.taskId}:{}})}if(P==="todo"&&!X)try{let ie=JSON.parse(re);ie.todoList&&this.sendNotification("turn.todos_updated",{turnId:y,items:ie.todoList,summary:{total:ie.total??ie.todoList.length,completed:ie.completed??0,inProgress:ie.inProgress??0,notStarted:ie.notStarted??0}})}catch{}return{result:re,error:X}}catch(V){return{result:"",error:V instanceof Error?V.message:String(V)}}}},c=sa(l);this.currentHooks=c,this.taskStore.setHooks(c,this.currentSessionId??"");let d=(process.env.QMEMORY_BASE_URL??process.env.QLOGICAGENT_QMEMORY_BASE_URL??"").trim().replace(/\/+$/,"");if(d){let y=la({baseUrl:d,apiKey:(process.env.QMEMORY_API_KEY??"").trim()||void 0,timeoutMs:5e3});this.qmemoryAdapter=y,this.qmemoryUserId=this.currentSessionId??"default",ia(c,{memoryProvider:y,userId:this.currentSessionId??"default",log:{debug:T=>l.debug(T),warn:T=>l.warn(T)}},this.memoryPrefetchState)}Si(c,l,{transport:a.transport,apiKey:a.apiKey});let p=e?.mcpServers,m=is(p??{}),g=ji();try{if($.existsSync(g)){let y=JSON.parse($.readFileSync(g,"utf8")),T=is(y),v=new Set(m.map(_=>_.name));m=[...m,...T.filter(_=>!v.has(_.name))]}}catch{}if(m.length>0){this.mcpManager&&this.mcpManager.disconnectAll().catch(()=>{}),this.mcpManager=new Kn({servers:m,log:l}),it(async()=>{await this.mcpManager?.disconnectAll()});let y=()=>this.mcpManager;ce(Rc(y)),ce(_c(y)),ce(Yc({listServers:async()=>{let T=this.mcpManager;return T?T.getConnectedServers().map(_=>({name:_,status:"connected",transport:"stdio",toolCount:0,resourceCount:0,promptCount:0})):[]},listTools:async T=>{if(!this.mcpManager)return[];let _=`mcp__${T.replace(/[^a-zA-Z0-9_]/g,"_").toLowerCase()}__`;return Be().filter(C=>C.startsWith(_)).map(C=>({name:C.slice(_.length),prefixedName:C}))},callTool:async(T,v,_,C)=>{let V=`mcp__${T.replace(/[^a-zA-Z0-9_]/g,"_").toLowerCase()}__`+v,j=ke(V);if(!j)return{success:!1,error:`Tool not found: ${V}`};try{return{success:!0,content:(await j.execute(`mcp_${Date.now()}`,_??{},C)).content.map(P=>P.text??"").join(`
429
+ `)}}catch(re){return{success:!1,error:re.message}}},listResources:async T=>{let v=this.mcpManager;return v?(await v.listResources(T)).map(C=>({uri:C.uri,name:C.name,mimeType:C.mimeType,description:C.description,server:C.server})):[]},readResource:async(T,v)=>{let _=this.mcpManager;if(!_)throw new Error("MCP not initialized");return(await _.readResource(T,v)).map(I=>({uri:I.uri,mimeType:I.mimeType,text:I.text}))},authenticate:async()=>({status:"unsupported",message:"OAuth not yet implemented in McpManager"})})),this.mcpManager.connectAll().then(()=>{this.mcpManager?.injectTools(),l.info(`[mcp] ${this.mcpManager?.getToolCount()??0} tools from ${this.mcpManager?.getConnectedServers().length??0} servers`)}).catch(T=>{l.warn(`[mcp] connection error: ${T instanceof Error?T.message:T}`)})}let f=[],b=Di();$.existsSync(b)&&f.push(b);let h=e?.pluginPaths;if(Array.isArray(h))for(let y of h)typeof y=="string"&&$.existsSync(y)&&f.push(y);Pc(f,l).then(y=>{if(y.length===0)return;this.pluginLoader=new Yn({pluginDirs:y,hookRegistry:c,log:l}),this.pluginLoader.loadAll().then(v=>{l.info(`[plugins] ${v.length} loaded, ${this.pluginLoader?.getPluginSkills().length??0} skills`)}).catch(v=>{l.warn(`[plugins] load error: ${v instanceof Error?v.message:v}`)});let T=this.pluginLoader;c.register({point:"turn.submitted",handler:async()=>(await T.refreshActivations(),{action:"continue"}),label:"plugin-activation-refresh",priority:50})}).catch(y=>{l.warn(`[plugins] marketplace resolve error: ${y instanceof Error?y.message:y}`)});let k=e?.permissions,x=ls(k),R=new Xn(x);this.permissionUnregister&&this.permissionUnregister(),this.permissionChecker=new Zn({ruleEngine:R,hookRegistry:c,onRequestApproval:async y=>(this.sendNotification("tool.approval.request",{approvalId:y.approvalId,callId:y.callId,toolName:y.toolName,arguments:y.arguments?JSON.stringify(y.arguments):"",message:y.message,suggestions:y.suggestions?.map(T=>`${T.pattern}:${T.behavior}`)}),new Promise(()=>{})),onPermissionUpdate:y=>{l.info(`[permissions] rule saved: ${y.pattern} \u2192 ${y.behavior}`),this.sendNotification("permission.rule_updated",{pattern:y.pattern,behavior:y.behavior})},onDenied:(y,T)=>{l.warn(`[permissions] blocked "${y}": ${T}`)}});let E=We();this.permissionChecker.setToolMeta(E),this.permissionUnregister=this.permissionChecker.register();let F=[rr(),...Array.isArray(e?.skillPaths)?e.skillPaths:[]];ce(Bc({listSkills:()=>{let y=[];this.pluginLoader&&y.push(...this.pluginLoader.getPluginSkills());let T=e?.skillPaths;if(Array.isArray(T)){for(let v of T)if(typeof v=="string"){let _=J.basename(v);y.some(C=>C.name===_)||y.push({name:_,source:"gateway",filePath:J.join(v,"SKILL.md"),baseDir:v})}}return y},listSkillsFull:async y=>{let T=[],v=new Set;for(let _ of F)try{let C=await $.promises.readdir(_,{withFileTypes:!0});for(let I of C){if(!I.isDirectory())continue;let V=J.join(_,I.name,"SKILL.md");try{await $.promises.access(V);let j=J.basename(_);if(y&&j!==y)continue;v.add(j),T.push({name:I.name,description:`Skill from ${_}`,category:j})}catch{}}}catch{}if(this.pluginLoader)for(let _ of this.pluginLoader.getPluginSkills())y&&_.source!==y||(v.add(_.source??"plugin"),T.push({name:_.name,description:`Plugin skill (${_.source})`,category:_.source}));return{skills:T,categories:[...v]}},readSkillContent:async y=>{for(let T of F){let v=J.join(T,y,"SKILL.md");try{return await $.promises.readFile(v,"utf8")}catch{}}return null},viewSkill:async(y,T)=>{for(let v of F){let _=T?J.join(v,y,T):J.join(v,y,"SKILL.md");try{let C=await $.promises.readFile(_,"utf8");return{name:y,content:C}}catch{}}return null},executeSkillSubturn:async(y,T,v,_)=>{let C=`skill_${y}_${ve().slice(0,8)}`,I=this.agent;if(!I)return"[skill] Cannot execute: no LLM provider configured";let V=this.currentSessionId??"skill";this.currentHooks?.invoke("subagent.started",{sessionId:V,turnId:C,subagentId:C,agentType:`skill:${y}`}).catch(()=>{});let j=We(),re=v??`Execute skill "${y}" instructions.`,X=[],P;for await(let se of I.run({turnId:C,sessionId:V,messages:[{role:"user",content:re}],tools:j,systemPrompt:T,config:{parentDepth:1}},_)){if(se.type==="end"&&se.content)return this.currentHooks?.invoke("subagent.stopped",{sessionId:V,turnId:C,subagentId:C,agentType:`skill:${y}`,reason:"normal"}).catch(()=>{}),se.content;if(se.type==="delta"&&se.text&&X.push(se.text),se.type==="error"){P=se.error;break}}return this.currentHooks?.invoke("subagent.stopped",{sessionId:V,turnId:C,subagentId:C,agentType:`skill:${y}`,reason:P?"error":"normal",error:P}).catch(()=>{}),P?`[skill "${y}"] error: ${P}`:X.join("")||`[skill "${y}"] completed (no output)`},manageSkill:async y=>{let T=J.join(F[0]??rr(),y.name),v=J.join(T,"SKILL.md");switch(y.action){case"create":return await $.promises.mkdir(T,{recursive:!0}),await $.promises.writeFile(v,y.content??"","utf8"),{success:!0,message:`Skill "${y.name}" created`,path:T};case"edit":return await $.promises.writeFile(v,y.content??"","utf8"),{success:!0,message:`Skill "${y.name}" updated`,path:v};case"patch":{let _=await $.promises.readFile(v,"utf8");return!y.oldString||!_.includes(y.oldString)?{success:!1,message:"oldString not found in SKILL.md"}:(await $.promises.writeFile(v,_.replace(y.oldString,y.newString??""),"utf8"),{success:!0,message:`Skill "${y.name}" patched`,path:v})}case"delete":return await $.promises.rm(T,{recursive:!0,force:!0}),{success:!0,message:`Skill "${y.name}" deleted`};default:return{success:!1,message:`Unknown action: ${y.action}`}}}})),ce(Hc({abortSignal:void 0,currentForkDepth:0,forkAgent:async y=>{let T=No(y.agent);if(!T)return{agentId:"",status:"failed",error:`Unknown agent type: ${y.agent}`};if(!this.agent||!this.currentTransport||!this.currentApiKey||!this.currentModel)return{agentId:"",status:"failed",error:"No LLM provider configured"};let v=Be(),_=Do(v,T),I=We().filter(P=>_.includes(P.function.name)),V=Sr(I,!0),j=y.maxTurns??T.maxTurns??200,re=await Rn({promptMessages:[{role:"user",content:y.prompt}],tools:V,transport:this.currentTransport,toolInvoker:u,apiKey:this.currentApiKey,model:this.currentModel,log:l,hooks:c,forkLabel:`agent-${y.agent}`,maxTurns:j,parentSignal:y.abortSignal,parentDepth:0,onEvent:P=>{P.type==="delta"&&P.text&&this.sendNotification("turn.subagent_delta",{agentType:y.agent,text:P.text})}}),X=re.events.filter(P=>P.type==="end"&&"content"in P).map(P=>P.content??"").join("")||re.events.filter(P=>P.type==="delta"&&"text"in P).map(P=>P.text).join("");return{agentId:`fork-${y.agent}-${ve().slice(0,8)}`,status:re.ok?"completed":"failed",output:X||void 0,error:re.error,tokensUsed:re.totalUsage.prompt+re.totalUsage.completion}}}));let U=dt(),D=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"]}]]),w=async()=>{try{return JSON.parse(await $.promises.readFile(U,"utf8"))}catch{return{}}},ge=async y=>{await $.promises.mkdir(J.dirname(U),{recursive:!0}),await $.promises.writeFile(U,JSON.stringify(y,null,2),"utf8")};ce(zc({getConfig:async y=>{let T=D.get(y);if(!T)return{success:!1,error:`Unknown key: ${y}`};let v=await w(),_=y in v?v[y]:T.value;return{success:!0,setting:{...T,value:_,readOnly:Yt.includes(y)}}},setConfig:async(y,T)=>{let v=D.get(y);if(!v)return{success:!1,error:`Unknown key: ${y}`};let _=await w(),C=y in _?_[y]:v.value;return _[y]=T,await ge(_),{success:!0,previousValue:C,setting:{...v,value:T}}},listConfig:async()=>{let y=await w();return{success:!0,settings:[...D.values()].map(v=>({...v,value:v.key in y?y[v.key]:v.value,readOnly:Yt.includes(v.key)}))}},resetConfig:async y=>{let T=D.get(y);if(!T)return{success:!1,error:`Unknown key: ${y}`};let v=await w();return delete v[y],await ge(v),{success:!0,setting:T}},isValidKey:y=>D.has(y)}));let H=new Map,z=y=>{let T=/^(\d+)([smhd])$/.exec(y.trim());if(!T)return null;let v=parseInt(T[1],10),_=T[2];return v*({s:1e3,m:6e4,h:36e5,d:864e5}[_]??6e4)},fe=y=>{y.timerId&&clearTimeout(y.timerId);let T=z(y.schedule);T&&(y.timerId=setTimeout(()=>{y.lastRunAt=new Date().toISOString(),y.repeat.completed++,y.lastStatus="success",l.info(`[cron] triggered job ${y.id} (${y.name})`),y.repeat.times===null||y.repeat.completed<y.repeat.times?fe(y):(y.state="paused",y.enabled=!1)},T),y.nextRunAt=new Date(Date.now()+T).toISOString())};it(async()=>{for(let y of H.values())y.timerId&&clearTimeout(y.timerId)}),ce(qc({createJob:async y=>{let T=`cron_${ve().slice(0,8)}`,v={id:T,name:y.name??`Job ${T}`,prompt:y.prompt,schedule:y.schedule,scheduleDisplay:y.schedule,state:"scheduled",enabled:!0,repeat:{times:y.repeat??null,completed:0},allowedTools:y.allowedTools};return H.set(T,v),fe(v),{success:!0,job:{...v,timerId:void 0}}},listJobs:async()=>({success:!0,jobs:[...H.values()].map(T=>({...T,timerId:void 0}))}),getJob:async y=>{let T=H.get(y);return T?{success:!0,job:{...T,timerId:void 0}}:{success:!1,error:`Job not found: ${y}`}},updateJob:async(y,T)=>{let v=H.get(y);return v?(T.prompt!==void 0&&(v.prompt=T.prompt),T.schedule!==void 0&&(v.schedule=T.schedule,v.scheduleDisplay=T.schedule),T.name!==void 0&&(v.name=T.name),T.enabled!==void 0&&(v.enabled=T.enabled,v.state=T.enabled?"scheduled":"paused"),T.repeat!==void 0&&(v.repeat.times=T.repeat),T.allowedTools!==void 0&&(v.allowedTools=T.allowedTools),v.enabled?fe(v):v.timerId&&(clearTimeout(v.timerId),v.timerId=void 0),{success:!0,job:{...v,timerId:void 0}}):{success:!1,error:`Job not found: ${y}`}},deleteJob:async y=>{let T=H.get(y);return T?(T.timerId&&clearTimeout(T.timerId),H.delete(y),{success:!0}):{success:!1,error:`Job not found: ${y}`}},pauseJob:async y=>{let T=H.get(y);return T?(T.state="paused",T.enabled=!1,T.timerId&&(clearTimeout(T.timerId),T.timerId=void 0),{success:!0,job:{...T,timerId:void 0}}):{success:!1,error:`Job not found: ${y}`}},resumeJob:async y=>{let T=H.get(y);return T?(T.state="scheduled",T.enabled=!0,fe(T),{success:!0,job:{...T,timerId:void 0}}):{success:!1,error:`Job not found: ${y}`}},triggerJob:async y=>{let T=H.get(y);return T?(T.lastRunAt=new Date().toISOString(),T.repeat.completed++,T.lastStatus="success",{success:!0,job:{...T,timerId:void 0}}):{success:!1,error:`Job not found: ${y}`}},validateSchedule:y=>z(y)!==null||/^\d{1,2}\s/.test(y)?null:`Invalid schedule: ${y}. Use shorthand (5m, 1h, 1d) or cron expression.`}));let te=new Map;it(async()=>{for(let y of te.values())y.cleanup();te.clear()}),ce(Kc({startMonitor:async y=>{if(te.has(y.monitorId))return{action:"start",success:!1,error:`Monitor "${y.monitorId}" already exists.`};let T={monitorId:y.monitorId,source:y.source,target:y.target,conditions:y.conditions,startedAt:Date.now(),timeoutSeconds:y.timeoutSeconds,eventCount:0},v=()=>{};if(y.source==="file")try{let _=$.watch(y.target,{persistent:!1},()=>{T.eventCount++,l.info(`[monitor] file change detected: ${y.target}`)});v=()=>_.close()}catch{return{action:"start",success:!1,error:`Cannot watch: ${y.target}`}}if(y.timeoutSeconds>0){let _=setTimeout(()=>{let I=te.get(y.monitorId);I&&(I.cleanup(),te.delete(y.monitorId))},y.timeoutSeconds*1e3),C=v;v=()=>{clearTimeout(_),C()}}return te.set(y.monitorId,{info:T,cleanup:v}),{action:"start",success:!0,monitorId:y.monitorId}},stopMonitor:async y=>{let T=te.get(y);return T?(T.cleanup(),te.delete(y),{action:"stop",success:!0,monitorId:y}):{action:"stop",success:!1,error:`Monitor "${y}" not found.`}},listMonitors:async()=>[...te.values()].map(y=>y.info)}));let le=new Map,G={info:y=>l.info(y),warn:y=>l.warn(y)},N=new ft({onNotification:(y,T,v)=>{this.sendNotification("team.member.notification",{memberId:y,method:T,params:v})},onStateChange:(y,T)=>{this.sendNotification("team.member.state",{memberId:y,state:T});let v=N.getHandle(y),C=N.getUsageTracker(y)?.getUsage();this.emitAgentStatus(y,T,{missedBeats:N.getMissedBeats(y),lastActivityAt:v?.lastActivityAt,usage:C&&C.totalTokens>0?{inputTokens:C.inputTokens,outputTokens:C.outputTokens,totalTokens:C.totalTokens}:void 0})},onExit:(y,T,v)=>{for(let _ of le.values()){let C=_.members.find(I=>I.cwd&&`team-${_.name}-${I.name}`.replace(/[^a-zA-Z0-9-]/g,"-").toLowerCase()===y.replace(/^team-/,""));C&&(C.isActive=!1)}l.info(`[team] member ${y} exited (code=${T}, signal=${v})`)},onMcpToolCall:(y,T,v)=>this.handleMcpToolCall(y,T,v),log:{info:y=>l.info(y),warn:y=>l.warn(y),debug:y=>l.debug(y)},sessionDir:J.join(B(),"agent-logs")});it(async()=>{N.dispose()}),ce(Jc({createTeam:async y=>{if(le.has(y.teamName))return{success:!1,error:`Team "${y.teamName}" already exists.`};let T=await Vt(),v=[];for(let C of y.members??[]){let I={...C,isActive:!0};if(T){let V=`team-${y.teamName}-${C.name}`.replace(/[^a-zA-Z0-9-]/g,"-").toLowerCase(),j=await jl(T,V,G);j?(I.worktreePath=j.worktreePath,I.worktreeBranch=j.branch,I.cwd=j.worktreePath,l.info(`[team] provisioned worktree for ${C.name}: ${j.worktreePath}`)):(I.cwd=process.cwd(),l.warn(`[team] worktree provision failed for ${C.name}, using shared cwd`))}else I.cwd=process.cwd();v.push(I)}let _={name:y.teamName,description:y.description,leadId:this.currentSessionId??"default",members:v,createdAt:new Date().toISOString()};le.set(y.teamName,_);for(let C of v){if(!C.cwd)continue;let I=`team-${y.teamName}-${C.name}`.replace(/[^a-zA-Z0-9-]/g,"-").toLowerCase();try{await N.spawn({memberId:I,name:C.name,cwd:C.cwd,prompt:`You are the "${C.name}" team member. Role: ${C.role}.`,agentType:C.role,verbose:this.verbose}),l.info(`[team] spawned child process for ${C.name} in ${C.cwd}`)}catch(V){l.warn(`[team] failed to spawn child process for ${C.name}: ${V instanceof Error?V.message:String(V)}`),C.isActive=!1}}return this.sendNotification("team.updated",{teamName:y.teamName,action:"created",members:_.members.map(C=>({agentName:C.name,role:C.role,worktreePath:C.worktreePath,pid:N.getHandle(`team-${y.teamName}-${C.name}`.replace(/[^a-zA-Z0-9-]/g,"-").toLowerCase())?.pid}))}),{success:!0,team:_}},deleteTeam:async y=>{let T=le.get(y);if(!T)return{success:!1,error:`Team "${y}" not found.`};for(let _ of T.members){let C=`team-${y}-${_.name}`.replace(/[^a-zA-Z0-9-]/g,"-").toLowerCase();N.kill(C),N.remove(C)}let v=await Vt();if(v)for(let _ of T.members)_.worktreePath&&_.worktreeBranch&&(await Bl(v,_.worktreePath,_.worktreeBranch,G),l.info(`[team] cleaned up worktree for ${_.name}: ${_.worktreePath}`));return le.delete(y),this.sendNotification("team.updated",{teamName:y,action:"destroyed",members:[]}),{success:!0}},listTeams:async()=>({success:!0,teams:[...le.values()]}),getTeamStatus:async y=>{let T=le.get(y);if(!T)return{success:!1,error:`Team "${y}" not found.`};let v={};for(let _ of T.members){let C=`team-${y}-${_.name}`.replace(/[^a-zA-Z0-9-]/g,"-").toLowerCase(),I=N.getStatus(C);I&&(_.isActive=I.alive,v[_.name]={mediaProgress:I.mediaProgress,lastToolCall:I.lastToolCall,idleFor:I.idleFor,runningFor:I.runningFor})}return{success:!0,team:T,memberProgress:v}}}));{let y=new ao({persistToDisk:!0});y.loadFromDiskSync();let T={providerId:"null",search:async()=>[],ingest:async()=>{}},v=this.qmemoryAdapter??T;ce({name:yu,label:Tu,description:ku,parameters:bu,execute:async(_,C)=>{let I=await wu(C,{provider:v,store:y,userId:this.qmemoryUserId||this.currentSessionId||"default",sessionId:this.currentSessionId});return{content:[{type:"text",text:I.message}],details:{type:"memory",action:I.action,ok:I.ok}}}})}{let y=e?.workdir??process.cwd(),T=Zc(y,this.currentSessionId||"default");ce(Qc(T))}let pe=e?.workdir??process.cwd(),Ee=Su({projectRoot:pe,ruleEngine:R,hooks:c,log:y=>l.info(`[settings] ${y}`)});it(async()=>{Ee()}),this.currentSessionId&&c.invoke("session.created",{sessionId:this.currentSessionId}).catch(()=>{}),this.fileWatcher&&this.fileWatcher.stop();let me=e?.workdir??process.cwd();return La({projectRoot:me,sessionId:this.currentSessionId,hooks:c,log:y=>l.debug(y),onInstructionCacheReset:Fa}).then(y=>{this.fileWatcher=y,it(async()=>{this.fileWatcher?.stop()})}).catch(y=>{l.warn(`[file-watcher] init error: ${y instanceof Error?y.message:y}`)}),this.agent=new Mt({llmTransport:a.transport,apiKey:a.apiKey,toolInvoker:u,log:l,hooks:c,maxRounds:e.maxRounds,verbose:this.verbose}),this.lastLlmConfigKey=t,this.currentTransport=a.transport,this.currentApiKey=a.apiKey,this.currentModel=o,this.log(`created Agent (provider: ${n}, model: ${o})`),this.agent}loadSettingsSync(){try{let e=dt();if(!$.existsSync(e))return;let t=$.readFileSync(e,"utf-8"),n=JSON.parse(t);return{provider:n.provider,model:n.model,apiKey:n.apiKey,baseUrl:n.baseUrl}}catch{return}}handleSessionGetInfo(e){let t=this.currentSessionId||"default",n=this.sessionState?.createSnapshot(),o={sessionId:t,model:this.currentModel||void 0,cwd:process.cwd(),paths:{sessionDir:$i(t),agentHome:B(),settings:dt()},usage:n?{turnCount:n.turnCount,inputTokens:n.totalInputTokens,outputTokens:n.totalOutputTokens}:void 0};e.id!==void 0&&this.sendResponse(e.id,o)}async handleMemoryList(e){let t=[],n=J.join(B(),"memory.json");$.existsSync(n)&&t.push({id:"local",type:"json",path:n}),this.qmemoryAdapter&&t.push({id:"qmemory",type:"vector"}),e.id!==void 0&&this.sendResponse(e.id,{sources:t})}async handleMemoryRead(e){let t=e.params,n=t?.source??"local",o=t?.target??"memory";if(n==="local")try{let s=J.join(B(),"memory.json"),i=await $.promises.readFile(s,"utf-8"),a=JSON.parse(i);e.id!==void 0&&this.sendResponse(e.id,{source:"local",target:o,content:a[o]??""})}catch{e.id!==void 0&&this.sendResponse(e.id,{source:"local",target:o,content:""})}else e.id!==void 0&&this.sendResponse(e.id,void 0,{code:M.INVALID_PARAMS,message:`Unknown memory source: ${n}`})}async handleMemoryWrite(e){let t=e.params,n=t?.target??"memory",o=t?.content;if(n!=="memory"&&n!=="user"){e.id!==void 0&&this.sendResponse(e.id,void 0,{code:M.INVALID_PARAMS,message:`Invalid memory target: ${n}. Must be "memory" or "user".`});return}if(o==null){e.id!==void 0&&this.sendResponse(e.id,void 0,{code:M.INVALID_PARAMS,message:"content is required."});return}try{let s=J.join(B(),"memory.json"),i={};try{let a=await $.promises.readFile(s,"utf-8");i=JSON.parse(a)}catch{}i[n]=o,i.savedAt=new Date().toISOString(),await $.promises.mkdir(B(),{recursive:!0}),await $.promises.writeFile(s,JSON.stringify(i,null,2),"utf-8"),e.id!==void 0&&this.sendResponse(e.id,{ok:!0,target:n}),this.sendNotification("memory.updated",{target:n,source:"rpc"})}catch(s){e.id!==void 0&&this.sendResponse(e.id,void 0,{code:M.INTERNAL_ERROR,message:s instanceof Error?s.message:String(s)})}}handleToolsList(e){let t=e.params,o=We(t?.includeDeferred??!1).map(s=>({name:s.function.name,description:s.function.description??"",parameters:s.function.parameters,source:"builtin"}));if(t?.category){let s=o.filter(i=>i.name.startsWith(t.category)||i.description.toLowerCase().includes(t.category.toLowerCase()));e.id!==void 0&&this.sendResponse(e.id,{tools:s,total:s.length})}else e.id!==void 0&&this.sendResponse(e.id,{tools:o,total:o.length})}handleMediaListModels(e){let n=e.params?.mediaType,s=this.mediaClient.listMediaModels(n).map(i=>({providerId:i.providerId,providerName:i.providerDef.name,modelId:i.modelInfo.id,modelName:i.modelInfo.name,mediaType:i.mediaType,capabilities:i.modelInfo.mediaCapabilities}));e.id!==void 0&&this.sendResponse(e.id,{models:s})}async handleMediaCancel(e){let t=e.params;if(!t?.taskId){e.id!==void 0&&this.sendResponse(e.id,void 0,{code:M.INVALID_PARAMS,message:"taskId is required."});return}let n=t.provider??"doubao",o=this.mediaClient.getTransport(n);if(!o){e.id!==void 0&&this.sendResponse(e.id,{ok:!1,message:`No transport for provider: ${n}`});return}if(!fr(o)){e.id!==void 0&&this.sendResponse(e.id,{ok:!1,message:`Provider ${n} does not support task cancellation.`});return}try{let s=this.resolveMediaApiKey(n);if(!s){e.id!==void 0&&this.sendResponse(e.id,{ok:!1,message:`No API key for provider: ${n}`});return}await o.deleteVideoTask(t.taskId,s),e.id!==void 0&&this.sendResponse(e.id,{ok:!0,taskId:t.taskId,message:"Task cancelled."})}catch(s){e.id!==void 0&&this.sendResponse(e.id,{ok:!1,message:s instanceof Error?s.message:String(s)})}}async handleMediaStatus(e){let t=e.params;if(!t?.taskId){e.id!==void 0&&this.sendResponse(e.id,void 0,{code:M.INVALID_PARAMS,message:"taskId is required."});return}let n=t.provider??"doubao",o=this.mediaClient.getTransport(n);if(!o){e.id!==void 0&&this.sendResponse(e.id,{ok:!1,message:`No transport for provider: ${n}`});return}if(!fr(o)){e.id!==void 0&&this.sendResponse(e.id,{ok:!1,message:`Provider ${n} does not support task status queries.`});return}try{let s=this.resolveMediaApiKey(n);if(!s){e.id!==void 0&&this.sendResponse(e.id,{ok:!1,message:`No API key for provider: ${n}`});return}if(o.getTaskStatus){let{status:u,task:c}=await o.getTaskStatus(t.taskId,s);e.id!==void 0&&this.sendResponse(e.id,{ok:!0,taskId:t.taskId,status:u,task:c});return}let i=await o.listVideoTasks(s,{limit:100}),l=(i.data??i.tasks??[]).find(u=>u.id===t.taskId||u.task_id===t.taskId);e.id!==void 0&&this.sendResponse(e.id,{ok:!0,taskId:t.taskId,...l?{status:l.status,task:l}:{status:"unknown",message:"Task not found in recent list."}})}catch(s){e.id!==void 0&&this.sendResponse(e.id,{ok:!1,message:s instanceof Error?s.message:String(s)})}}resolveMediaApiKey(e){return this.currentMediaApiKeys?.[e]}handleProviderList(e){let t=this.registry.listProviders(),n=new Map;for(let s of t){let i=s.group??s.id;n.has(i)||n.set(i,[]);let a=!!this.registry.resolveApiKey(s.id);n.get(i).push({id:s.id,name:s.name,transport:s.transport,baseUrl:s.baseUrl,defaultModel:s.defaultModel,modelCount:s.models?.length??0,available:a})}let o=[...n.entries()].map(([s,i])=>({group:s,variants:i}));e.id!==void 0&&this.sendResponse(e.id,{providers:o})}handleConfigGet(e){try{let t=dt(),n={};if($.existsSync(t)){let o=$.readFileSync(t,"utf-8");n=JSON.parse(o)}e.id!==void 0&&this.sendResponse(e.id,{config:n,paths:{userSettings:t,agentHome:B()}})}catch(t){e.id!==void 0&&this.sendResponse(e.id,void 0,{code:M.INTERNAL_ERROR,message:t instanceof Error?t.message:String(t)})}}async handleConfigUpdate(e){let t=e.params;if(!t?.updates||typeof t.updates!="object"){e.id!==void 0&&this.sendResponse(e.id,void 0,{code:M.INVALID_PARAMS,message:"updates (object) is required."});return}try{let n=dt(),o={};try{let s=await $.promises.readFile(n,"utf-8");o=JSON.parse(s)}catch{}Object.assign(o,t.updates),await $.promises.mkdir(J.dirname(n),{recursive:!0}),await $.promises.writeFile(n,JSON.stringify(o,null,2),"utf-8"),e.id!==void 0&&this.sendResponse(e.id,{ok:!0})}catch(n){e.id!==void 0&&this.sendResponse(e.id,void 0,{code:M.INTERNAL_ERROR,message:n instanceof Error?n.message:String(n)})}}async handleTodosList(e){let t=ke("todo");if(!t){e.id!==void 0&&this.sendResponse(e.id,{items:[],summary:mt([])});return}try{let o=(await t.execute("rpc-todos-list",{action:"list"},void 0)).content.map(a=>a.text??"").join(""),i=JSON.parse(o).todoList??[];e.id!==void 0&&this.sendResponse(e.id,{items:i,summary:mt(i)})}catch{e.id!==void 0&&this.sendResponse(e.id,{items:[],summary:mt([])})}}async handleMemorySearch(e){let t=e.params;if(!t?.query){e.id!==void 0&&this.sendResponse(e.id,void 0,{code:M.INVALID_PARAMS,message:"query is required."});return}if(!this.qmemoryAdapter){try{let n=J.join(B(),"memory.json"),o=await $.promises.readFile(n,"utf-8"),s=JSON.parse(o),i=[],a=t.query.toLowerCase();for(let[l,u]of Object.entries(s)){if(typeof u!="string")continue;let c=u.split(`
430
430
  \xA7
431
431
  `).filter(d=>d.trim());for(let d=0;d<c.length;d++)c[d].toLowerCase().includes(a)&&i.push({id:`local-${l}-${d}`,text:c[d],score:1,source:"local"})}e.id!==void 0&&this.sendResponse(e.id,{results:i.slice(0,t.limit??10)})}catch{e.id!==void 0&&this.sendResponse(e.id,{results:[]})}return}try{let n=t.userId??(this.qmemoryUserId||"default"),o=await this.qmemoryAdapter.search(t.query,n,{limit:t.limit??10});e.id!==void 0&&this.sendResponse(e.id,{results:o.map(s=>({id:s.blockId??"",text:s.text,score:s.score,source:"qmemory",metadata:s.metadata}))})}catch(n){e.id!==void 0&&this.sendResponse(e.id,void 0,{code:M.INTERNAL_ERROR,message:n instanceof Error?n.message:String(n)})}}async handleMemoryDelete(e){let t=e.params;if(!t?.match){e.id!==void 0&&this.sendResponse(e.id,void 0,{code:M.INVALID_PARAMS,message:"match is required."});return}let n=t.source??"local";if(n==="local"){let o=t.target??"memory";try{let s=J.join(B(),"memory.json"),i=await $.promises.readFile(s,"utf-8"),a=JSON.parse(i),u=(a[o]??"").split(`
432
432
  \xA7
package/dist/index.js CHANGED
@@ -21,7 +21,7 @@ ${g}`},b=[...o,...c,f,...p],h=Date.now()-n,k=b.reduce((x,R)=>x+this.config.estim
21
21
  `,e+=Bd,e}async function yi(r,e,t,n=li){if(r.length<=n||gi(r))return r;let o=await fi(r,e,t);return o?hi(o):r.slice(0,n)+`
22
22
  ...[truncated ${r.length-n} chars]`}function zd(r){let e=[],t=[];for(let n of r)n.role==="tool"&&typeof n.content=="string"&&n.tool_call_id?gi(n.content)||t.push({toolCallId:n.tool_call_id,content:n.content,size:n.content.length}):n.role==="assistant"&&t.length>0&&(e.push(t),t=[]);return t.length>0&&e.push(t),e}function Vd(r,e){let t=[],n=[],o=[];for(let s of r){let i=e.replacements.get(s.toolCallId);i!==void 0?t.push({...s,replacement:i}):e.seenIds.has(s.toolCallId)?n.push(s):o.push(s)}return{mustReapply:t,frozen:n,fresh:o}}function qd(r,e,t){let n=[...r].sort((i,a)=>a.size-i.size),o=[],s=e+r.reduce((i,a)=>i+a.size,0);for(let i of n){if(s<=t)break;o.push(i),s-=i.size}return o}async function bi(r,e,t,n=ci){let o=zd(r);if(o.length===0)return{messages:r,newlyReplacedCount:0};let s=new Map,i=[];for(let c of o){let{mustReapply:d,frozen:p,fresh:m}=Vd(c,e);for(let k of d)s.set(k.toolCallId,k.replacement);if(m.length===0){for(let k of c)e.seenIds.add(k.toolCallId);continue}let g=p.reduce((k,x)=>k+x.size,0),f=m.reduce((k,x)=>k+x.size,0),b=g+f>n?qd(m,g,n):[],h=new Set(b.map(k=>k.toolCallId));for(let k of c)h.has(k.toolCallId)||e.seenIds.add(k.toolCallId);b.length>0&&i.push(...b)}if(s.size===0&&i.length===0)return{messages:r,newlyReplacedCount:0};let a=await Promise.all(i.map(async c=>{let d=await fi(c.content,c.toolCallId,t);return{candidate:c,result:d}})),l=0;for(let{candidate:c,result:d}of a){if(e.seenIds.add(c.toolCallId),!d)continue;let p=hi(d);s.set(c.toolCallId,p),e.replacements.set(c.toolCallId,p),l++}return s.size===0?{messages:r,newlyReplacedCount:0}:{messages:r.map(c=>{if(c.role!=="tool"||!c.tool_call_id)return c;let d=s.get(c.tool_call_id);return d===void 0?c:{...c,content:d}}),newlyReplacedCount:l}}var jd,di,Bd,Xo=q(()=>{"use strict";gn();jd="tool-results",di="<persisted-output>",Bd="</persisted-output>"});function Yd(r){try{return JSON.parse(r)}catch{return}}var Kd,Jd,fn,ki=q(()=>{"use strict";ut();Xo();Kd=new Set(["read_file","file_read","FileRead","grep","Grep","glob","Glob","search","list_dir","find_files","web_fetch","web_search","WebFetch","WebSearch"]),Jd=new Set(["bash","execute_command","Bash","shell"]),fn=class{tools=[];hasErrored=!1;erroredToolDescription="";discarded=!1;siblingAbortController;progressResolve;config;concurrencySafe;constructor(e){this.config=e,this.concurrencySafe=e.concurrencySafeTools??Kd,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(o=>o.status==="executing"),n=this.config.maxConcurrentTools;return n&&n>0&&t.length>=n?!1:t.length===0||e&&t.every(o=>o.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 n=t?.command??t?.file_path??t?.pattern??"";if(typeof n=="string"&&n.length>0){let o=n.length>40?n.slice(0,40)+"\u2026":n;return`${e.toolCall.function.name}(${o})`}return e.toolCall.function.name}createSyntheticError(e,t){let n=this.erroredToolDescription,o=t==="user_interrupted"?"User rejected tool use":t==="discarded"?"Streaming fallback - tool execution discarded":n?`Cancelled: parallel tool call ${n} errored`:"Cancelled: parallel tool call errored";return{callId:e.id,toolName:e.toolCall.function.name,ok:!1,error:o,message:wt(e.id,{ok:!1,error:o})}}async executeTool(e){e.status="executing";let n=(async()=>{let o=this.getAbortReason();if(o){e.results.push(this.createSyntheticError(e,o)),e.status="completed";return}let{toolInvoker:s,hooks:i,sessionId:a,turnId:l,log:u}=this.config,c=e.toolCall.function.name,d=!1,p=e.toolCall.function.arguments;if(i)try{let k=await i.invoke("tool.before_invoke",{sessionId:a,turnId:l,callId:e.id,toolName:c,arguments:Yd(p)});if(k.action==="abort"){let x=k.reason??"blocked by policy";u.info(`tool ${c} blocked: ${x}`),e.results.push({callId:e.id,toolName:c,ok:!1,error:x,blocked:!0,blockReason:x,message:wt(e.id,{ok:!1,error:x})}),e.status="completed";return}k.action==="continue"&&k.context?.arguments&&(p=JSON.stringify(k.context.arguments))}catch{}let m=await s.invoke(l,c,p,this.siblingAbortController.signal),g=this.getAbortReason();if(g&&!d){e.results.push(this.createSyntheticError(e,g)),e.status="completed";return}let f=!m.error,b=m.result;f&&b&&b.length>5e4&&(b=await yi(b,e.id,a));let h=wt(e.id,{ok:f,payload:b,error:m.error});f||(d=!0,Jd.has(c)&&(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:l,callId:e.id,toolName:c,ok:f,...m.error?{error:m.error}:{}}).catch(()=>{}),e.results.push({callId:e.id,toolName:c,ok:f,error:m.error,message:h}),e.status="completed"})();e.promise=n,n.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(n=>n.status==="executing"&&n.promise).map(n=>n.promise),t=new Promise(n=>{this.progressResolve=n});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{readFile as Xd}from"node:fs/promises";function Xe(r){let e=typeof r.content=="string"?r.content:r.content!=null?JSON.stringify(r.content):"";return Math.ceil(e.length/4)}function Qe(r){let e=0;for(let t of r)e+=Xe(t);return e}function vi(r){if(!r)return 128e3;if(r in Qo)return Qo[r];let e=r.toLowerCase();for(let[t,n]of Object.entries(Qo))if(e.startsWith(t.toLowerCase()))return n;return 128e3}function Zd(r,e){return async(t,n)=>{let o=e?.transport,s=e?.apiKey;if(!o||!s)return r.debug("[context-compression] no LLM transport for summarization \u2014 using sync fallback"),Zo(t);try{let i="",a=e?.model??Qd;for await(let l of o.stream({model:a,messages:[{role:"system",content:"You are a precise conversation summarizer."},{role:"user",content:n}],maxTokens:2e3,temperature:.3},s,AbortSignal.timeout(3e4)))l.type==="delta"&&(i+=l.text);return i||(r.warn("[context-compression] empty summary response"),Zo(t))}catch(i){return r.warn({err:i.message},"[context-compression] summarize call error \u2014 using fallback"),Zo(t)}}}function Zo(r){let e=r.filter(n=>n.role==="user"),t=e.slice(0,10).map(n=>{let o=typeof n.content=="string"?n.content:JSON.stringify(n.content??"");return`- ${o.slice(0,200)}${o.length>200?"...":""}`});return`User requests (${e.length} messages):
23
23
  ${t.join(`
24
- `)}`}function ep(){return ko(new Ye(er),new Ne(20,Xe),new lt(Xe))}function wi(r,e){let t=To(new Ye(er),new Ne(20,Xe),new vt({protectedHeadExchanges:1,protectedTailMessages:8,summarize:r,estimateTokens:Xe}),new lt(Xe));return new xt({inner:t,estimateTokens:Xe,onCacheInvalidated:e?.onCacheInvalidated})}function Si(r,e){let t=e?.budget??un({modelContextWindow:vi(e?.model)}),o=(e?.pipeline??ep()).compress(r,t);if(o.droppedCount>0){let s=Qe(r),i=Qe(o.messages);xi.record({timestamp:Date.now(),strategy:o.strategy,tokensBefore:s,tokensAfter:i,droppedCount:o.droppedCount,latencyMs:o.metrics?.latencyMs??0,usedLlm:!1,cacheInvalidated:o.metrics?.cacheInvalidated??!1,tier:Ct(s,t)})}return o.droppedCount>0&&tr?.(o.droppedCount,Qe(o.messages)),o}async function tp(r,e,t){let n=t??un({modelContextWindow:vi(e.model)}),o=Qe(r),s=Ct(o,n),i;switch(s){case"none":i={messages:r,droppedCount:0,strategy:"none"};break;case"trim-only":i=new Ye(er).compress(r,n);break;case"sliding-window":{i=await wi(e.summarize).compressAsync(r,n);break}case"llm-summarize":{let a=e.pipeline??wi(e.summarize);i=_t(a)?await a.compressAsync(r,n):a.compress(r,n);break}}return i.droppedCount>0&&(i={...i,messages:await vo(i.messages,r,{maxFiles:5,maxTokenBudget:5e4,readFile:async a=>{try{return await Xd(a,"utf-8")}catch{return null}}})}),np(r,i,n),i}function np(r,e,t){if(e.droppedCount>0||e.metrics?.usedLlm){let n=e.metrics?.tokensBefore||Qe(r),o=e.metrics?.tokensAfter||Qe(e.messages);xi.record({timestamp:Date.now(),strategy:e.strategy,tokensBefore:n,tokensAfter:o,droppedCount:e.droppedCount,latencyMs:e.metrics?.latencyMs??0,usedLlm:e.metrics?.usedLlm??!1,cacheInvalidated:e.metrics?.cacheInvalidated??!1,tier:Ct(n,t)})}if(e.droppedCount>0){let n=e.metrics?.tokensAfter||Qe(e.messages);tr?.(e.droppedCount,n)}}function op(r,e){let t=Zd(r,e),n={id:"builtin-compressor",label:"4-Layer Compression Funnel (built-in)",async compressAsync(o,s,i){return tp(o,{budget:s,model:i?.model,sessionId:i?.sessionId,summarize:t},s)}};Ti.register(n),Ti.activate(n.id),r.info(`[context-compression] registered context engine: ${n.id}`)}function Ri(r,e,t){op(e,t),r.register({point:"context.before_compact",priority:50,label:"context-compression-bridge",handler:(n,o)=>{let s=o.messageCount;return s&&s>0&&e.debug(`[context-compression] before_compact: ${s} messages entering compression`),{action:"continue"}}}),tr=(n,o)=>{e.debug(`[context-compression] after_compact: removed ${n}, ${o} tokens remaining`),r.invoke("context.after_compact",{sessionId:"",turnId:"",removedCount:n,tokenCount:o}).catch(()=>{})}}var Qo,er,Qd,xi,Ti,tr,nr=q(()=>{"use strict";ut();Qo={"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};er=8e3,Qd="deepseek-v4-flash",xi=new St(200),Ti=new Rt;tr=null});function _i(r,e,t){let n=t-e;return`[Budget] ${Math.round(r)}% used (${e.toLocaleString()} / ${t.toLocaleString()} tokens). ${n.toLocaleString()} tokens remaining. `+(r>=90?"Wrap up your current task \u2014 you are near the token limit.":"Continue working \u2014 do not summarize prematurely.")}var Ci=q(()=>{"use strict"});var Ai={};_s(Ai,{resolveToolEligibility:()=>lp});function sp(r,e){if(rp.some(t=>t.test(r)))return!0;if(e)for(let t of e)try{if(new RegExp(t,"i").test(r))return!0}catch{}return!1}function ip(r,e){let t=r.function.name,n=r.meta,o=[];return e.blockedToolNames?.includes(t)?(o.push("policy_blocked"),{level:5,reasons:o}):n?.isReadOnly?(o.push("always_allowed"),{level:1,reasons:o}):n?.requiresApproval?(o.push("approval_required"),{level:4,reasons:o}):n?.isDangerous||sp(t,e.dangerousPatterns)?(o.push("dangerous_tool"),{level:3,reasons:o}):{level:2,reasons:o}}function ap(r){switch(r){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 lp(r,e={}){let t=new Map,n=[],o=[],s=[];for(let i of r){let a=i.function.name,{level:l,reasons:u}=ip(i,e),c=ap(l),d={toolName:a,status:c,permissionLevel:l,approvalRequired:l===4,reasonCodes:u};t.set(a,d),l===5?o.push(d):(n.push(i),l===4&&s.push(d))}return{eligibleTools:n,blockedTools:o,approvalRequiredTools:s,eligibilityByName:t}}var rp,Mi=q(()=>{"use strict";rp=[/^(?:bash|shell|exec|terminal|run_command)$/i,/^(?:write_file|delete_file|move_file|create_directory)$/i,/^(?:git_push|git_reset|git_force)$/i]});function dp(r){let e=r.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 pp(r){let e=r.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 mp(r){return typeof r=="number"&&Number.isFinite(r)&&r>=1?Math.min(Math.round(r),100):Qs}function Pi(r){let e=r.message.toLowerCase();return r.status===413||e.includes("prompt_too_long")||e.includes("context_length_exceeded")||e.includes("maximum context length")}function gp(r){return r==="length"||r==="max_tokens"}function Ii(r){let e=r.message.toLowerCase();return(e.includes("image")||e.includes("media")||e.includes("file too large")||e.includes("payload too large"))&&(r.status===413||e.includes("too large")||e.includes("size"))}function fp(r){let e=r.headers;if(!e)return null;let t=e["retry-after"]??e["Retry-After"];if(!t)return null;let n=parseInt(t,10);return!isNaN(n)&&n>0?n*1e3:null}function hp(r){if(r.status!==400)return null;let e=r.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),n=parseInt(e[3],10);if(isNaN(t)||isNaN(n))return null;let o=n-t-1e3;return o>=3e3?o:null}function yp(r){return r.filter(e=>e.role!=="assistant"?!0:!(typeof e.content=="string"&&e.content.trim()===""))}async function*Ei(r,e,t,n){let{turnId:o,sessionId:s,messages:i,tools:a,model:l,apiKey:u,temperature:c,hooks:d,signal:p}=r,m={sessionId:s,turnId:o},g=r.maxTurns??0,f=r.querySource,{resolveToolEligibility:b}=await Promise.resolve().then(()=>(Mi(),Ai)),h=b(a,r.toolEligibilityContext),k=h.eligibleTools;for(let z of h.blockedTools)yield{type:"tool_blocked",turnId:o,callId:"",name:z.toolName,reason:"blocked-by-policy"};if(!k.length){yield*bp(o,l,i,u,c,p,e,n);return}let x=mp(r.maxRounds),R={contextWindowTokens:r.contextWindowTokens??ei,responseBufferTokens:ti,maxOutputTokens:r.maxOutputTokens??ni,abortSignal:p,reactiveCompactEnabled:!0,outputEscalationEnabled:!0},E=new Set,F=0,U=k,D,w={messages:[...i],maxOutputTokensRecoveryCount:0,hasAttemptedReactiveCompact:!1,maxOutputTokensOverride:void 0,turnCount:1,transition:void 0,guardState:Wo(R),reactiveCompactState:qo(),toolLoopState:pn({maxRounds:x,replayMessages:[...i]}).state,consecutiveFailedRounds:0,finalText:"",totalUsage:{prompt:0,completion:0},collapseStore:Ro(),currentModel:l,consecutive529Errors:0,consecutiveApiRetries:0,stopHookActive:void 0,lastResponseId:void 0,snipRemovedIds:new Set,contentReplacementState:pi(),budgetContinuationCount:0},ge=Math.max(g*5,200),H=0;for(;;){if(H++,H>ge){n.info(`hard iteration cap reached (${ge}), forcing completion`);let S=w.finalText||or(w.messages,n);yield{type:"end",turnId:o,content:S,usage:w.totalUsage,model:w.currentModel};return}let{messages:z,maxOutputTokensRecoveryCount:fe,hasAttemptedReactiveCompact:te,maxOutputTokensOverride:le,turnCount:G,guardState:N,reactiveCompactState:pe,collapseStore:Ee}=w,{toolLoopState:me}=w;if(D){try{let S=await D;S&&(yield{type:"tool_use_summary",turnId:o,summary:S})}catch{}D=void 0}if(r.refreshTools&&G>1){let S=r.refreshTools();S!==U&&(U=S,n.debug(`tools refreshed: ${S.length} tools`))}if(Vo(N,R)){n.info(`turn aborted by guard at turn ${G}`),yield{type:"error",turnId:o,error:"Turn aborted",code:"ABORTED",usage:w.totalUsage};return}let y=Go(N,R);if(y.level==="blocking"){y.reason==="prompt_too_long"&&ct(pe)&&(pe.attemptedThisTurn=!0,N.hasAttemptedReactiveCompact=!0,n.info(`token budget blocking (${y.reason}), reactive compact needed`),yield{type:"recovery",turnId:o,action:"reactive_compact",detail:"token budget pre-check"}),n.info(`token budget blocking (${y.reason}), ending tool loop`);break}y.level==="warning"&&n.info(`token budget warning: ${y.usagePercent}% used, ${y.remainingTokens} remaining`);let T;{let S=await bi(z,w.contentReplacementState,s);T=S.messages,S.newlyReplacedCount>0&&(n.info(`tool-result-budget: persisted ${S.newlyReplacedCount} oversized tool results`),yield{type:"recovery",turnId:o,action:"tool_result_budget",detail:`${S.newlyReplacedCount} persisted`})}{let S=xo(T,w.snipRemovedIds);T=S.messages,S.removedCount>0&&(n.info(`snip: removed ${S.removedCount} messages, freed ~${S.tokensFreed} tokens`),yield{type:"recovery",turnId:o,action:"snip",detail:`${S.removedCount} messages`})}{let A=new Ne().compress(T,0);A.droppedCount>0&&(T=A.messages,n.info(`microcompact: cleared ${A.droppedCount} old tool results`))}if(T=_o(T,Ee).messages,N.promptTokens>0){let S=Si(T,{budget:R.contextWindowTokens*.75,model:w.currentModel});S.droppedCount>0&&(T=S.messages,n.info(`autocompact: ${S.strategy}, dropped ${S.droppedCount}`),yield{type:"recovery",turnId:o,action:"autocompact",detail:`${S.strategy}: ${S.droppedCount} dropped`},w.hasAttemptedReactiveCompact=!1,d?.invoke("context.after_compact",{...m,removedCount:S.droppedCount}).catch(()=>{}))}T=yp(T);let v=Ao({tools:U,toolChoice:r.toolChoice??"auto"}),_=pn({maxRounds:x,replayMessages:T,lastStopReason:me.lastStopReason,options:{stopReason:me.lastStopReason}}),C=v.extraSystemPrompt?[{role:"system",content:v.extraSystemPrompt},..._.state.replayMessages]:_.state.replayMessages;me=_.state,_.recoveryActions.length>0&&n.debug(`tool loop recovery: ${_.recoveryActions.map(S=>S.detail??S.kind).join("; ")}`),n.debug(`turn ${G}, messages: ${C.length}`),d?.invoke("turn.before_inference",{...m,model:w.currentModel}).catch(()=>{});let I=!1,V=[],j=new Map,se="stop",X,P=null,ne=!1,ie=[],we=[];try{for await(let S of e.stream({model:w.currentModel,messages:C,tools:v.tools,toolChoice:v.normalizedToolChoice??"auto",temperature:c,maxTokens:(le??N.currentMaxOutputTokens)||void 0,streamRequired:r.streamRequired,previousResponseId:w.lastResponseId,reasoning:r.reasoning,promptCacheKey:r.promptCacheKey,promptCacheRetention:r.promptCacheRetention,serviceTier:r.serviceTier,openaiBuiltinTools:r.openaiBuiltinTools,maxToolCalls:r.maxToolCalls,parallelToolCalls:r.parallelToolCalls,textVerbosity:r.textVerbosity},u,p))switch(S.type){case"delta":V.push(S.text),I||(yield{type:"delta",turnId:o,text:S.text});break;case"tool_call_delta":I=!0,Ko(j,S);break;case"reasoning_delta":ie.push(S.text);break;case"reasoning_block_complete":S.signature&&we.push({thinking:ie.join(""),signature:S.signature}),ie.length=0;break;case"usage":X={prompt:S.promptTokens,completion:S.completionTokens,reasoning:S.reasoningTokens,cacheRead:S.cacheReadTokens,cacheCreation:S.cacheCreationTokens};break;case"response_id":w.lastResponseId=S.id;break;case"annotations":yield{type:"annotations",turnId:o,annotations:S.annotations};break;case"builtin_tool_status":yield{type:"heartbeat",turnId:o,message:`${S.toolType}: ${S.event}`};break;case"done":se=S.finishReason;break}if(I||d?.invoke("turn.after_inference",{...m,model:w.currentModel}).catch(()=>{}),r.postSamplingHooks&&r.postSamplingHooks.length>0){let S=w.currentModel;for(let A of r.postSamplingHooks)try{A({messages:[...T],model:S,sessionId:s})}catch{}}}catch(S){if(S instanceof Mt&&r.fallbackModel){n.info(`model fallback triggered: ${S.originalModel} \u2192 ${S.fallbackModel}`),yield{type:"recovery",turnId:o,action:"model_fallback",detail:`${S.originalModel} \u2192 ${S.fallbackModel}`},w={...w,currentModel:S.fallbackModel,consecutive529Errors:0,consecutiveApiRetries:0,transition:void 0};continue}let A=S instanceof Error?S.message:String(S),O=typeof S?.status=="number"?S.status:void 0;if(!O&&A&&(A.includes("ECONNRESET")||A.includes("EPIPE"))){let oe=(w.consecutiveApiRetries??0)+1;if(oe>Pt){n.info(`stale connection retry limit reached (${Pt}), aborting`),yield{type:"error",turnId:o,error:A,code:"RETRIES_EXHAUSTED",usage:w.totalUsage};return}n.info(`stale connection (${A.includes("ECONNRESET")?"ECONNRESET":"EPIPE"}): retrying`),yield{type:"recovery",turnId:o,action:"stale_connection_retry",detail:A.slice(0,80)},w={...w,consecutiveApiRetries:oe,transition:void 0};continue}let Y=hp({status:O,message:A});if(Y!==null){n.info(`max_tokens overflow: adjusting to ${Y}`),N.currentMaxOutputTokens=Y,w={...w,maxOutputTokensOverride:Y,transition:void 0};continue}if(Do(O)){if(w.consecutive529Errors++,w.consecutive529Errors>=ai&&r.fallbackModel&&w.currentModel!==r.fallbackModel){n.info(`529 \xD7 ${w.consecutive529Errors}: triggering fallback to ${r.fallbackModel}`),yield{type:"recovery",turnId:o,action:"model_fallback",detail:`529 \xD7 ${w.consecutive529Errors}`},w={...w,currentModel:r.fallbackModel,consecutive529Errors:0,transition:void 0};continue}if(Uo()){let oe=mn(w.consecutive529Errors);n.info(`persistent retry: waiting ${oe}ms (attempt ${w.consecutive529Errors})`);let K=oe;for(;K>0;){if(p?.aborted){yield{type:"error",turnId:o,error:"Aborted during retry wait",code:"ABORTED",usage:w.totalUsage};return}yield{type:"heartbeat",turnId:o,message:`Retrying in ${Math.ceil(K/1e3)}s (${O})`};let he=Math.min(K,ii);await new Promise(Mu=>setTimeout(Mu,he)),K-=he}w={...w,transition:void 0};continue}if($o(f)){let K=fp({status:O,message:A})??mn(w.consecutive529Errors);n.info(`transient ${O}: retry in ${K}ms`),yield{type:"recovery",turnId:o,action:"retry",detail:`${O} retry in ${K}ms`},await new Promise(he=>setTimeout(he,K)),w={...w,transition:void 0};continue}n.info(`background source ${f}: not retrying ${O}`)}P={status:O,message:A}}if(P&&d?.invoke("turn.after_inference",{...m,model:w.currentModel,response:{error:P.message}}).catch(()=>{}),P)if(Pi(P))ne=!0,n.info(`withheld prompt_too_long error (status=${P.status})`);else if(Ii(P))ne=!0,n.info(`withheld media_size error (status=${P.status})`);else{let S=Ho({status:P.status??500,message:P.message},N,R);if(S.action==="reactive_compact"&&ct(pe)&&(pe.attemptedThisTurn=!0,N.hasAttemptedReactiveCompact=!0,yield{type:"recovery",turnId:o,action:"reactive_compact",detail:`API ${P.status??500}: ${P.message}`}),S.action==="retry"){let O=(w.consecutiveApiRetries??0)+1;if(O>Pt){n.info(`API retry limit reached (${Pt}), aborting`);let Y=at(P.status,P.message);yield{type:"error",turnId:o,error:P.message,code:Y,usage:w.totalUsage};return}yield{type:"recovery",turnId:o,action:"retry",detail:S.reason},w={...w,consecutiveApiRetries:O,transition:void 0};continue}let A=at(P.status,P.message);d?.invoke("stop.failure",{sessionId:s,reason:A,error:P.message}).catch(()=>{}),yield{type:"error",turnId:o,error:P.message,code:A,usage:w.totalUsage};return}X&&(w.totalUsage.prompt+=X.prompt,w.totalUsage.completion+=X.completion,X.reasoning&&(w.totalUsage.reasoning=(w.totalUsage.reasoning??0)+X.reasoning),X.cacheRead&&(w.totalUsage.cacheRead=(w.totalUsage.cacheRead??0)+X.cacheRead),X.cacheCreation&&(w.totalUsage.cacheCreation=(w.totalUsage.cacheCreation??0)+X.cacheCreation)),X?.prompt&&(N.promptTokens=X.prompt);let ln=V.join("");ln&&(w.finalText=ln);let Oe=[...j.values()].map(S=>({id:S.id||`tc_${o}_${G}_${Math.random().toString(36).slice(2,8)}`,type:"function",function:{name:S.name,arguments:S.arguments}}));if(Oe.length===0&&!I){if(ne&&P&&Pi(P)){if(w.transition?.reason!=="collapse_drain_retry"){let A=Co(T,Ee);if(A.committed>0){n.info(`collapse drain: committed ${A.committed} stages`),yield{type:"recovery",turnId:o,action:"collapse_drain",detail:`${A.committed} stages committed`},w={...w,messages:A.messages,transition:{reason:"collapse_drain_retry",committed:A.committed}};continue}}if(ct(pe)){pe.attemptedThisTurn=!0,N.hasAttemptedReactiveCompact=!0,n.info("withheld 413: reactive compact attempt"),yield{type:"recovery",turnId:o,action:"reactive_compact",detail:"withheld prompt_too_long"},w={...w,hasAttemptedReactiveCompact:!0,transition:{reason:"reactive_compact_retry"}};continue}n.info("withheld 413: recovery exhausted, surfacing error"),d?.invoke("stop.failure",{sessionId:s,reason:"prompt_too_long",error:P.message}).catch(()=>{}),yield{type:"error",turnId:o,error:P.message,code:"PROMPT_TOO_LONG",usage:w.totalUsage};return}if(ne&&P&&Ii(P)){if(ct(pe)){pe.attemptedThisTurn=!0,N.hasAttemptedReactiveCompact=!0,n.info("withheld media error: reactive compact strip-retry"),yield{type:"recovery",turnId:o,action:"reactive_compact",detail:"media error strip-retry"},w={...w,hasAttemptedReactiveCompact:!0,transition:{reason:"reactive_compact_retry"}};continue}n.info("withheld media error: recovery exhausted"),d?.invoke("stop.failure",{sessionId:s,reason:"media_error",error:P.message}).catch(()=>{}),yield{type:"error",turnId:o,error:P.message,code:"IMAGE_ERROR",usage:w.totalUsage};return}if(gp(se)){N.consecutiveTruncations+=1;let A=r.modelMaxOutputTokens??oi,O=zo(N,R,A);if(O.shouldEscalate&&le===void 0){N.currentMaxOutputTokens=O.newMax,n.info(`max_output_tokens escalate: ${O.newMax} tokens`),yield{type:"recovery",turnId:o,action:"output_escalation",detail:`${O.newMax} tokens`},w={...w,maxOutputTokensOverride:si,transition:{reason:"max_output_tokens_escalate"}};continue}if(fe<ri){let Y={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."};n.info(`max_output_tokens recovery #${fe+1}`),yield{type:"recovery",turnId:o,action:"max_output_tokens_recovery",detail:`attempt ${fe+1}`},w={...w,messages:[...T,Y],maxOutputTokensRecoveryCount:fe+1,maxOutputTokensOverride:void 0,transition:{reason:"max_output_tokens_recovery",attempt:fe+1}};continue}n.info("max_output_tokens recovery exhausted, completing with partial content")}else N.consecutiveTruncations=0;if(me=dn(me,{replayMessages:z,lastStopReason:"completed"}),d){let A=await d.invoke("stop",{sessionId:s,reason:"completed"});if(A.action==="prevent"){n.info(`stop hook prevented continuation: ${A.reason??"no reason"}`),yield{type:"end",turnId:o,content:w.finalText,usage:w.totalUsage,model:w.currentModel};return}if(A.action==="abort"){let O=A.reason??"Stop hook requested continuation";n.info(`stop hook blocking: ${O}`);let Y={role:"user",content:O},oe={role:"assistant",content:w.finalText,...we.length>0&&{thinkingBlocks:[...we]}};w={...w,messages:[...z,oe,Y],stopHookActive:!0,transition:{reason:"stop_hook_blocking"}};continue}}if(r.tokenBudget&&r.tokenBudget>0&&w.budgetContinuationCount<5){let A=w.totalUsage.prompt+w.totalUsage.completion+(w.totalUsage.reasoning??0),O=A/r.tokenBudget*100;if(O<90){let Y=w.budgetContinuationCount+1,oe={role:"user",content:_i(O,A,r.tokenBudget)};n.info(`token budget continuation #${Y}: ${Math.round(O)}% used`),yield{type:"recovery",turnId:o,action:"budget_continuation",detail:`${Math.round(O)}% used (#${Y})`};let K={role:"assistant",content:w.finalText,...we.length>0&&{thinkingBlocks:[...we]}};w={...w,messages:[...z,K,oe],budgetContinuationCount:Y,transition:{reason:"token_budget_continuation"}};continue}}if(F>0){let A={ok:!0,toolCallCount:F,distinctToolCount:E.size,multiStep:F>=2,hasSubAgent:!1,feedback:null,existingSkillName:null},O=At(A,{tools:[...E]});O&&(yield{type:"skill_instruction",turnId:o,instruction:O})}yield{type:"end",turnId:o,content:w.finalText,usage:w.totalUsage,model:w.currentModel};return}for(let S of Oe){let A=S.function.arguments,O=U.find(Y=>Y.function.name===S.function.name);if(O?.backfillObservableInput)try{let Y=JSON.parse(S.function.arguments),oe={...Y};O.backfillObservableInput(oe),Object.keys(oe).some(he=>!(he in Y))&&(A=JSON.stringify(oe))}catch{}yield{type:"tool_call",turnId:o,callId:S.id,name:S.function.name,arguments:A}}let Cu=we.length===0&&ie.length>0?ie.join(""):void 0;z.push(ho(Oe,w.finalText||void 0,we.length>0?we:void 0,Cu)),me=Lo(me,{replayMessages:z,pendingToolCallIds:Oe.map(S=>S.id),completedToolCallIds:me.completedToolCallIds,lastStopReason:"tool_calls"});let Ss=[];try{let S=new fn({toolInvoker:t,hooks:d,sessionId:s,turnId:o,log:n,signal:p,maxConcurrentTools:r?.maxConcurrentTools});for(let A of Oe)S.addTool(A);for await(let A of S.getRemainingResults()){A.blocked&&(yield{type:"tool_blocked",turnId:o,callId:A.callId,name:A.toolName,reason:A.blockReason??"blocked"}),z.push(A.message),Ss.push(A.callId),E.add(A.toolName),F++;let O=typeof A.message?.content=="string"?A.message.content:"",Y=A.ok&&O?O.slice(0,2e3):void 0;if(yield{type:"tool_result",turnId:o,callId:A.callId,name:A.toolName,ok:A.ok,error:A.error,outputPreview:Y},A.ok){let oe=Oe.find(K=>K.id===A.callId);if(oe){if(A.toolName==="plan_mode")try{let K=JSON.parse(oe.function.arguments);K.action==="exit"&&typeof K.plan=="string"&&K.plan.length>0&&(yield{type:"plan_update",turnId:o,slug:"approved-plan",content:K.plan})}catch{}if(up.has(A.toolName))try{let K=JSON.parse(oe.function.arguments),he=typeof K.file_path=="string"?K.file_path:typeof K.filePath=="string"?K.filePath:typeof K.path=="string"?K.path:void 0;he&&(yield{type:"artifact",turnId:o,artifactId:`artifact-${A.callId}`,artifactType:dp(he),title:he.split(/[\\/]/).pop()||he,filePath:he,language:pp(he)})}catch{}}}}}catch(S){let A=S instanceof Error?S.message:String(S);yield{type:"error",turnId:o,error:A,code:"TOOL_EXECUTION_ERROR",usage:w.totalUsage};return}if(me=dn(me,{replayMessages:z,completedToolCallIds:[...me.completedToolCallIds,...Ss],lastStopReason:"tool_calls"}),r.generateToolUseSummary&&Oe.length>0){let S=Oe.map(A=>({name:A.function.name,arguments:A.function.arguments}));D=r.generateToolUseSummary(S).catch(()=>null)}let Rs=z.slice(-Oe.length),Au=Rs.length>0&&Rs.every(S=>{let A=S?.content;return typeof A!="string"?!1:A.startsWith("Error: ")}),Tt=w.consecutiveFailedRounds;if(Au){if(Tt+=1,Tt>=Zs&&w.finalText){n.info(`early exit: ${Tt} consecutive failed rounds, returning partial response`),yield{type:"end",turnId:o,content:w.finalText,usage:w.totalUsage,model:w.currentModel};return}}else Tt=0;let go=G+1;if(g>0&&go>g){if(n.info(`max turns reached (${g}), completing`),d){let A=await d.invoke("stop",{sessionId:s,reason:"max_turns"});if(A.action==="abort"){let O=A.reason??"Stop hook requested continuation after max_turns",Y={role:"assistant",content:w.finalText,...we.length>0&&{thinkingBlocks:[...we]}};w={...w,messages:[...z,Y,{role:"user",content:O}],stopHookActive:!0,transition:{reason:"stop_hook_blocking"}};continue}}let S=w.finalText||or(z,n);yield{type:"end",turnId:o,content:S,usage:w.totalUsage,model:w.currentModel};return}if(go>x){if(n.info(`tool loop budget exhausted (${x} rounds), returning`),F>0){let A={ok:!0,toolCallCount:F,distinctToolCount:E.size,multiStep:F>=2,hasSubAgent:!1,feedback:null,existingSkillName:null},O=At(A,{tools:[...E]});O&&(yield{type:"skill_instruction",turnId:o,instruction:O})}let S=w.finalText||or(z,n);yield{type:"end",turnId:o,content:S,usage:w.totalUsage,model:w.currentModel};return}w={messages:z,maxOutputTokensRecoveryCount:0,hasAttemptedReactiveCompact:!1,maxOutputTokensOverride:void 0,turnCount:go,transition:{reason:"next_turn"},guardState:N,reactiveCompactState:pe,toolLoopState:me,consecutiveFailedRounds:Tt,finalText:w.finalText,totalUsage:w.totalUsage,collapseStore:Ee,currentModel:w.currentModel,consecutive529Errors:0,consecutiveApiRetries:0,stopHookActive:w.stopHookActive,lastResponseId:w.lastResponseId,snipRemovedIds:w.snipRemovedIds,contentReplacementState:w.contentReplacementState,budgetContinuationCount:0}}}function or(r,e){let t=[];for(let n=r.length-1;n>=0;n--){let o=r[n];if(o.role==="tool"&&typeof o.content=="string")t.unshift(o.content.slice(0,500));else if(o.role==="assistant"){if(typeof o.content=="string"&&o.content.trim())return e.info("synthesizeFallbackContent: found assistant text, using it"),o.content;break}else break}return t.length>0?(e.info(`synthesizeFallbackContent: synthesized from ${t.length} tool result(s)`),t.join(`
24
+ `)}`}function ep(){return ko(new Ye(er),new Ne(20,Xe),new lt(Xe))}function wi(r,e){let t=To(new Ye(er),new Ne(20,Xe),new vt({protectedHeadExchanges:1,protectedTailMessages:8,summarize:r,estimateTokens:Xe}),new lt(Xe));return new xt({inner:t,estimateTokens:Xe,onCacheInvalidated:e?.onCacheInvalidated})}function Si(r,e){let t=e?.budget??un({modelContextWindow:vi(e?.model)}),o=(e?.pipeline??ep()).compress(r,t);if(o.droppedCount>0){let s=Qe(r),i=Qe(o.messages);xi.record({timestamp:Date.now(),strategy:o.strategy,tokensBefore:s,tokensAfter:i,droppedCount:o.droppedCount,latencyMs:o.metrics?.latencyMs??0,usedLlm:!1,cacheInvalidated:o.metrics?.cacheInvalidated??!1,tier:Ct(s,t)})}return o.droppedCount>0&&tr?.(o.droppedCount,Qe(o.messages)),o}async function tp(r,e,t){let n=t??un({modelContextWindow:vi(e.model)}),o=Qe(r),s=Ct(o,n),i;switch(s){case"none":i={messages:r,droppedCount:0,strategy:"none"};break;case"trim-only":i=new Ye(er).compress(r,n);break;case"sliding-window":{i=await wi(e.summarize).compressAsync(r,n);break}case"llm-summarize":{let a=e.pipeline??wi(e.summarize);i=_t(a)?await a.compressAsync(r,n):a.compress(r,n);break}}return i.droppedCount>0&&(i={...i,messages:await vo(i.messages,r,{maxFiles:5,maxTokenBudget:5e4,readFile:async a=>{try{return await Xd(a,"utf-8")}catch{return null}}})}),np(r,i,n),i}function np(r,e,t){if(e.droppedCount>0||e.metrics?.usedLlm){let n=e.metrics?.tokensBefore||Qe(r),o=e.metrics?.tokensAfter||Qe(e.messages);xi.record({timestamp:Date.now(),strategy:e.strategy,tokensBefore:n,tokensAfter:o,droppedCount:e.droppedCount,latencyMs:e.metrics?.latencyMs??0,usedLlm:e.metrics?.usedLlm??!1,cacheInvalidated:e.metrics?.cacheInvalidated??!1,tier:Ct(n,t)})}if(e.droppedCount>0){let n=e.metrics?.tokensAfter||Qe(e.messages);tr?.(e.droppedCount,n)}}function op(r,e){let t=Zd(r,e),n={id:"builtin-compressor",label:"4-Layer Compression Funnel (built-in)",async compressAsync(o,s,i){return tp(o,{budget:s,model:i?.model,sessionId:i?.sessionId,summarize:t},s)}};Ti.register(n),Ti.activate(n.id),r.info(`[context-compression] registered context engine: ${n.id}`)}function Ri(r,e,t){op(e,t),r.register({point:"context.before_compact",priority:50,label:"context-compression-bridge",handler:(n,o)=>{let s=o.messageCount;return s&&s>0&&e.debug(`[context-compression] before_compact: ${s} messages entering compression`),{action:"continue"}}}),tr=(n,o)=>{e.debug(`[context-compression] after_compact: removed ${n}, ${o} tokens remaining`),r.invoke("context.after_compact",{sessionId:"",turnId:"",removedCount:n,tokenCount:o}).catch(()=>{})}}var Qo,er,Qd,xi,Ti,tr,nr=q(()=>{"use strict";ut();Qo={"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};er=8e3,Qd="deepseek-v4-flash",xi=new St(200),Ti=new Rt;tr=null});function _i(r,e,t){let n=t-e;return`[Budget] ${Math.round(r)}% used (${e.toLocaleString()} / ${t.toLocaleString()} tokens). ${n.toLocaleString()} tokens remaining. `+(r>=90?"Wrap up your current task \u2014 you are near the token limit.":"Continue working \u2014 do not summarize prematurely.")}var Ci=q(()=>{"use strict"});var Ai={};_s(Ai,{resolveToolEligibility:()=>lp});function sp(r,e){if(rp.some(t=>t.test(r)))return!0;if(e)for(let t of e)try{if(new RegExp(t,"i").test(r))return!0}catch{}return!1}function ip(r,e){let t=r.function.name,n=r.meta,o=[];return e.blockedToolNames?.includes(t)?(o.push("policy_blocked"),{level:5,reasons:o}):n?.isReadOnly?(o.push("always_allowed"),{level:1,reasons:o}):n?.requiresApproval?(o.push("approval_required"),{level:4,reasons:o}):n?.isDangerous||sp(t,e.dangerousPatterns)?(o.push("dangerous_tool"),{level:3,reasons:o}):{level:2,reasons:o}}function ap(r){switch(r){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 lp(r,e={}){let t=new Map,n=[],o=[],s=[];for(let i of r){let a=i.function.name,{level:l,reasons:u}=ip(i,e),c=ap(l),d={toolName:a,status:c,permissionLevel:l,approvalRequired:l===4,reasonCodes:u};t.set(a,d),l===5?o.push(d):(n.push(i),l===4&&s.push(d))}return{eligibleTools:n,blockedTools:o,approvalRequiredTools:s,eligibilityByName:t}}var rp,Mi=q(()=>{"use strict";rp=[/^(?:bash|shell|exec|terminal|run_command)$/i,/^(?:write_file|delete_file|move_file|create_directory)$/i,/^(?:git_push|git_reset|git_force)$/i]});function dp(r){let e=r.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 pp(r){let e=r.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 mp(r){return typeof r=="number"&&Number.isFinite(r)&&r>=1?Math.min(Math.round(r),100):Qs}function Pi(r){let e=r.message.toLowerCase();return r.status===413||e.includes("prompt_too_long")||e.includes("context_length_exceeded")||e.includes("maximum context length")}function gp(r){return r==="length"||r==="max_tokens"}function Ii(r){let e=r.message.toLowerCase();return(e.includes("image")||e.includes("media")||e.includes("file too large")||e.includes("payload too large"))&&(r.status===413||e.includes("too large")||e.includes("size"))}function fp(r){let e=r.headers;if(!e)return null;let t=e["retry-after"]??e["Retry-After"];if(!t)return null;let n=parseInt(t,10);return!isNaN(n)&&n>0?n*1e3:null}function hp(r){if(r.status!==400)return null;let e=r.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),n=parseInt(e[3],10);if(isNaN(t)||isNaN(n))return null;let o=n-t-1e3;return o>=3e3?o:null}function yp(r){return r.filter(e=>e.role!=="assistant"?!0:!(typeof e.content=="string"&&e.content.trim()===""))}async function*Ei(r,e,t,n){let{turnId:o,sessionId:s,messages:i,tools:a,model:l,apiKey:u,temperature:c,hooks:d,signal:p}=r,m={sessionId:s,turnId:o},g=r.maxTurns??0,f=r.querySource,{resolveToolEligibility:b}=await Promise.resolve().then(()=>(Mi(),Ai)),h=b(a,r.toolEligibilityContext),k=h.eligibleTools;for(let z of h.blockedTools)yield{type:"tool_blocked",turnId:o,callId:"",name:z.toolName,reason:"blocked-by-policy"};if(!k.length){yield*bp(o,l,i,u,c,p,e,n);return}let x=mp(r.maxRounds),R={contextWindowTokens:r.contextWindowTokens??ei,responseBufferTokens:ti,maxOutputTokens:r.maxOutputTokens??ni,abortSignal:p,reactiveCompactEnabled:!0,outputEscalationEnabled:!0},E=new Set,F=0,U=k,D,w={messages:[...i],maxOutputTokensRecoveryCount:0,hasAttemptedReactiveCompact:!1,maxOutputTokensOverride:void 0,turnCount:1,transition:void 0,guardState:Wo(R),reactiveCompactState:qo(),toolLoopState:pn({maxRounds:x,replayMessages:[...i]}).state,consecutiveFailedRounds:0,finalText:"",totalUsage:{prompt:0,completion:0},collapseStore:Ro(),currentModel:l,consecutive529Errors:0,consecutiveApiRetries:0,stopHookActive:void 0,lastResponseId:void 0,snipRemovedIds:new Set,contentReplacementState:pi(),budgetContinuationCount:0},ge=Math.max(g*5,200),H=0;for(;;){if(H++,H>ge){n.info(`hard iteration cap reached (${ge}), forcing completion`);let S=w.finalText||or(w.messages,n);yield{type:"end",turnId:o,content:S,usage:w.totalUsage,model:w.currentModel};return}let{messages:z,maxOutputTokensRecoveryCount:fe,hasAttemptedReactiveCompact:te,maxOutputTokensOverride:le,turnCount:G,guardState:N,reactiveCompactState:pe,collapseStore:Ee}=w,{toolLoopState:me}=w;if(D){try{let S=await D;S&&(yield{type:"tool_use_summary",turnId:o,summary:S})}catch{}D=void 0}if(r.refreshTools&&G>1){let S=r.refreshTools();S!==U&&(U=S,n.debug(`tools refreshed: ${S.length} tools`))}if(Vo(N,R)){n.info(`turn aborted by guard at turn ${G}`),yield{type:"error",turnId:o,error:"Turn aborted",code:"ABORTED",usage:w.totalUsage};return}let y=Go(N,R);if(y.level==="blocking"){y.reason==="prompt_too_long"&&ct(pe)&&(pe.attemptedThisTurn=!0,N.hasAttemptedReactiveCompact=!0,n.info(`token budget blocking (${y.reason}), reactive compact needed`),yield{type:"recovery",turnId:o,action:"reactive_compact",detail:"token budget pre-check"}),n.info(`token budget blocking (${y.reason}), ending tool loop`);break}y.level==="warning"&&n.info(`token budget warning: ${y.usagePercent}% used, ${y.remainingTokens} remaining`);let T;{let S=await bi(z,w.contentReplacementState,s);T=S.messages,S.newlyReplacedCount>0&&(n.info(`tool-result-budget: persisted ${S.newlyReplacedCount} oversized tool results`),yield{type:"recovery",turnId:o,action:"tool_result_budget",detail:`${S.newlyReplacedCount} persisted`})}{let S=xo(T,w.snipRemovedIds);T=S.messages,S.removedCount>0&&(n.info(`snip: removed ${S.removedCount} messages, freed ~${S.tokensFreed} tokens`),yield{type:"recovery",turnId:o,action:"snip",detail:`${S.removedCount} messages`})}{let A=new Ne().compress(T,0);A.droppedCount>0&&(T=A.messages,n.info(`microcompact: cleared ${A.droppedCount} old tool results`))}if(T=_o(T,Ee).messages,N.promptTokens>0){let S=Si(T,{budget:R.contextWindowTokens*.75,model:w.currentModel});S.droppedCount>0&&(T=S.messages,n.info(`autocompact: ${S.strategy}, dropped ${S.droppedCount}`),yield{type:"recovery",turnId:o,action:"autocompact",detail:`${S.strategy}: ${S.droppedCount} dropped`},w.hasAttemptedReactiveCompact=!1,d?.invoke("context.after_compact",{...m,removedCount:S.droppedCount}).catch(()=>{}))}T=yp(T);let v=Ao({tools:U,toolChoice:r.toolChoice??"auto"}),_=pn({maxRounds:x,replayMessages:T,lastStopReason:me.lastStopReason,options:{stopReason:me.lastStopReason}}),C=v.extraSystemPrompt?[{role:"system",content:v.extraSystemPrompt},..._.state.replayMessages]:_.state.replayMessages;me=_.state,_.recoveryActions.length>0&&n.debug(`tool loop recovery: ${_.recoveryActions.map(S=>S.detail??S.kind).join("; ")}`),n.debug(`turn ${G}, messages: ${C.length}`),d?.invoke("turn.before_inference",{...m,model:w.currentModel}).catch(()=>{});let I=!1,V=[],j=new Map,re="stop",X,P=null,se=!1,ie=[],we=[];try{for await(let S of e.stream({model:w.currentModel,messages:C,tools:v.tools,toolChoice:v.normalizedToolChoice??"auto",temperature:c,maxTokens:(le??N.currentMaxOutputTokens)||void 0,streamRequired:r.streamRequired,previousResponseId:w.lastResponseId,reasoning:r.reasoning,promptCacheKey:r.promptCacheKey,promptCacheRetention:r.promptCacheRetention,serviceTier:r.serviceTier,openaiBuiltinTools:r.openaiBuiltinTools,maxToolCalls:r.maxToolCalls,parallelToolCalls:r.parallelToolCalls,textVerbosity:r.textVerbosity},u,p))switch(S.type){case"delta":V.push(S.text),I||(yield{type:"delta",turnId:o,text:S.text});break;case"tool_call_delta":I=!0,Ko(j,S);break;case"reasoning_delta":ie.push(S.text);break;case"reasoning_block_complete":S.signature&&we.push({thinking:ie.join(""),signature:S.signature}),ie.length=0;break;case"usage":X={prompt:S.promptTokens,completion:S.completionTokens,reasoning:S.reasoningTokens,cacheRead:S.cacheReadTokens,cacheCreation:S.cacheCreationTokens};break;case"response_id":w.lastResponseId=S.id;break;case"annotations":yield{type:"annotations",turnId:o,annotations:S.annotations};break;case"builtin_tool_status":yield{type:"heartbeat",turnId:o,message:`${S.toolType}: ${S.event}`};break;case"done":re=S.finishReason;break}if(I||d?.invoke("turn.after_inference",{...m,model:w.currentModel}).catch(()=>{}),r.postSamplingHooks&&r.postSamplingHooks.length>0){let S=w.currentModel;for(let A of r.postSamplingHooks)try{A({messages:[...T],model:S,sessionId:s})}catch{}}}catch(S){if(S instanceof Mt&&r.fallbackModel){n.info(`model fallback triggered: ${S.originalModel} \u2192 ${S.fallbackModel}`),yield{type:"recovery",turnId:o,action:"model_fallback",detail:`${S.originalModel} \u2192 ${S.fallbackModel}`},w={...w,currentModel:S.fallbackModel,consecutive529Errors:0,consecutiveApiRetries:0,transition:void 0};continue}let A=S instanceof Error?S.message:String(S),O=typeof S?.status=="number"?S.status:void 0;if(!O&&A&&(A.includes("ECONNRESET")||A.includes("EPIPE"))){let ne=(w.consecutiveApiRetries??0)+1;if(ne>Pt){n.info(`stale connection retry limit reached (${Pt}), aborting`),yield{type:"error",turnId:o,error:A,code:"RETRIES_EXHAUSTED",usage:w.totalUsage};return}n.info(`stale connection (${A.includes("ECONNRESET")?"ECONNRESET":"EPIPE"}): retrying`),yield{type:"recovery",turnId:o,action:"stale_connection_retry",detail:A.slice(0,80)},w={...w,consecutiveApiRetries:ne,transition:void 0};continue}let Y=hp({status:O,message:A});if(Y!==null){n.info(`max_tokens overflow: adjusting to ${Y}`),N.currentMaxOutputTokens=Y,w={...w,maxOutputTokensOverride:Y,transition:void 0};continue}if(Do(O)){if(w.consecutive529Errors++,w.consecutive529Errors>=ai&&r.fallbackModel&&w.currentModel!==r.fallbackModel){n.info(`529 \xD7 ${w.consecutive529Errors}: triggering fallback to ${r.fallbackModel}`),yield{type:"recovery",turnId:o,action:"model_fallback",detail:`529 \xD7 ${w.consecutive529Errors}`},w={...w,currentModel:r.fallbackModel,consecutive529Errors:0,transition:void 0};continue}if(Uo()){let ne=mn(w.consecutive529Errors);n.info(`persistent retry: waiting ${ne}ms (attempt ${w.consecutive529Errors})`);let K=ne;for(;K>0;){if(p?.aborted){yield{type:"error",turnId:o,error:"Aborted during retry wait",code:"ABORTED",usage:w.totalUsage};return}yield{type:"heartbeat",turnId:o,message:`Retrying in ${Math.ceil(K/1e3)}s (${O})`};let he=Math.min(K,ii);await new Promise(Mu=>setTimeout(Mu,he)),K-=he}w={...w,transition:void 0};continue}if($o(f)){let K=fp({status:O,message:A})??mn(w.consecutive529Errors);n.info(`transient ${O}: retry in ${K}ms`),yield{type:"recovery",turnId:o,action:"retry",detail:`${O} retry in ${K}ms`},await new Promise(he=>setTimeout(he,K)),w={...w,transition:void 0};continue}n.info(`background source ${f}: not retrying ${O}`)}P={status:O,message:A}}if(P&&d?.invoke("turn.after_inference",{...m,model:w.currentModel,response:{error:P.message}}).catch(()=>{}),P)if(Pi(P))se=!0,n.info(`withheld prompt_too_long error (status=${P.status})`);else if(Ii(P))se=!0,n.info(`withheld media_size error (status=${P.status})`);else{let S=Ho({status:P.status??500,message:P.message},N,R);if(S.action==="reactive_compact"&&ct(pe)&&(pe.attemptedThisTurn=!0,N.hasAttemptedReactiveCompact=!0,yield{type:"recovery",turnId:o,action:"reactive_compact",detail:`API ${P.status??500}: ${P.message}`}),S.action==="retry"){let O=(w.consecutiveApiRetries??0)+1;if(O>Pt){n.info(`API retry limit reached (${Pt}), aborting`);let Y=at(P.status,P.message);yield{type:"error",turnId:o,error:P.message,code:Y,usage:w.totalUsage};return}yield{type:"recovery",turnId:o,action:"retry",detail:S.reason},w={...w,consecutiveApiRetries:O,transition:void 0};continue}let A=at(P.status,P.message);d?.invoke("stop.failure",{sessionId:s,reason:A,error:P.message}).catch(()=>{}),yield{type:"error",turnId:o,error:P.message,code:A,usage:w.totalUsage};return}X&&(w.totalUsage.prompt+=X.prompt,w.totalUsage.completion+=X.completion,X.reasoning&&(w.totalUsage.reasoning=(w.totalUsage.reasoning??0)+X.reasoning),X.cacheRead&&(w.totalUsage.cacheRead=(w.totalUsage.cacheRead??0)+X.cacheRead),X.cacheCreation&&(w.totalUsage.cacheCreation=(w.totalUsage.cacheCreation??0)+X.cacheCreation)),X?.prompt&&(N.promptTokens=X.prompt);let ln=V.join("");ln&&(w.finalText=ln);let Oe=[...j.values()].map(S=>({id:S.id||`tc_${o}_${G}_${Math.random().toString(36).slice(2,8)}`,type:"function",function:{name:S.name,arguments:S.arguments}}));if(Oe.length===0&&!I){if(se&&P&&Pi(P)){if(w.transition?.reason!=="collapse_drain_retry"){let A=Co(T,Ee);if(A.committed>0){n.info(`collapse drain: committed ${A.committed} stages`),yield{type:"recovery",turnId:o,action:"collapse_drain",detail:`${A.committed} stages committed`},w={...w,messages:A.messages,transition:{reason:"collapse_drain_retry",committed:A.committed}};continue}}if(ct(pe)){pe.attemptedThisTurn=!0,N.hasAttemptedReactiveCompact=!0,n.info("withheld 413: reactive compact attempt"),yield{type:"recovery",turnId:o,action:"reactive_compact",detail:"withheld prompt_too_long"},w={...w,hasAttemptedReactiveCompact:!0,transition:{reason:"reactive_compact_retry"}};continue}n.info("withheld 413: recovery exhausted, surfacing error"),d?.invoke("stop.failure",{sessionId:s,reason:"prompt_too_long",error:P.message}).catch(()=>{}),yield{type:"error",turnId:o,error:P.message,code:"PROMPT_TOO_LONG",usage:w.totalUsage};return}if(se&&P&&Ii(P)){if(ct(pe)){pe.attemptedThisTurn=!0,N.hasAttemptedReactiveCompact=!0,n.info("withheld media error: reactive compact strip-retry"),yield{type:"recovery",turnId:o,action:"reactive_compact",detail:"media error strip-retry"},w={...w,hasAttemptedReactiveCompact:!0,transition:{reason:"reactive_compact_retry"}};continue}n.info("withheld media error: recovery exhausted"),d?.invoke("stop.failure",{sessionId:s,reason:"media_error",error:P.message}).catch(()=>{}),yield{type:"error",turnId:o,error:P.message,code:"IMAGE_ERROR",usage:w.totalUsage};return}if(gp(re)){N.consecutiveTruncations+=1;let A=r.modelMaxOutputTokens??oi,O=zo(N,R,A);if(O.shouldEscalate&&le===void 0){N.currentMaxOutputTokens=O.newMax,n.info(`max_output_tokens escalate: ${O.newMax} tokens`),yield{type:"recovery",turnId:o,action:"output_escalation",detail:`${O.newMax} tokens`},w={...w,maxOutputTokensOverride:si,transition:{reason:"max_output_tokens_escalate"}};continue}if(fe<ri){let Y={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."};n.info(`max_output_tokens recovery #${fe+1}`),yield{type:"recovery",turnId:o,action:"max_output_tokens_recovery",detail:`attempt ${fe+1}`},w={...w,messages:[...T,Y],maxOutputTokensRecoveryCount:fe+1,maxOutputTokensOverride:void 0,transition:{reason:"max_output_tokens_recovery",attempt:fe+1}};continue}n.info("max_output_tokens recovery exhausted, completing with partial content")}else N.consecutiveTruncations=0;if(me=dn(me,{replayMessages:z,lastStopReason:"completed"}),d){let A=await d.invoke("stop",{sessionId:s,reason:"completed"});if(A.action==="prevent"){n.info(`stop hook prevented continuation: ${A.reason??"no reason"}`),yield{type:"end",turnId:o,content:w.finalText,usage:w.totalUsage,model:w.currentModel};return}if(A.action==="abort"){let O=A.reason??"Stop hook requested continuation";n.info(`stop hook blocking: ${O}`);let Y={role:"user",content:O},ne={role:"assistant",content:w.finalText,...we.length>0&&{thinkingBlocks:[...we]}};w={...w,messages:[...z,ne,Y],stopHookActive:!0,transition:{reason:"stop_hook_blocking"}};continue}}if(r.tokenBudget&&r.tokenBudget>0&&w.budgetContinuationCount<5){let A=w.totalUsage.prompt+w.totalUsage.completion+(w.totalUsage.reasoning??0),O=A/r.tokenBudget*100;if(O<90){let Y=w.budgetContinuationCount+1,ne={role:"user",content:_i(O,A,r.tokenBudget)};n.info(`token budget continuation #${Y}: ${Math.round(O)}% used`),yield{type:"recovery",turnId:o,action:"budget_continuation",detail:`${Math.round(O)}% used (#${Y})`};let K={role:"assistant",content:w.finalText,...we.length>0&&{thinkingBlocks:[...we]}};w={...w,messages:[...z,K,ne],budgetContinuationCount:Y,transition:{reason:"token_budget_continuation"}};continue}}if(F>0){let A={ok:!0,toolCallCount:F,distinctToolCount:E.size,multiStep:F>=2,hasSubAgent:!1,feedback:null,existingSkillName:null},O=At(A,{tools:[...E]});O&&(yield{type:"skill_instruction",turnId:o,instruction:O})}yield{type:"end",turnId:o,content:w.finalText,usage:w.totalUsage,model:w.currentModel};return}for(let S of Oe){let A=S.function.arguments,O=U.find(Y=>Y.function.name===S.function.name);if(O?.backfillObservableInput)try{let Y=JSON.parse(S.function.arguments),ne={...Y};O.backfillObservableInput(ne),Object.keys(ne).some(he=>!(he in Y))&&(A=JSON.stringify(ne))}catch{}yield{type:"tool_call",turnId:o,callId:S.id,name:S.function.name,arguments:A}}let Cu=we.length===0&&ie.length>0?ie.join(""):void 0;z.push(ho(Oe,w.finalText||void 0,we.length>0?we:void 0,Cu)),me=Lo(me,{replayMessages:z,pendingToolCallIds:Oe.map(S=>S.id),completedToolCallIds:me.completedToolCallIds,lastStopReason:"tool_calls"});let Ss=[];try{let S=new fn({toolInvoker:t,hooks:d,sessionId:s,turnId:o,log:n,signal:p,maxConcurrentTools:r?.maxConcurrentTools});for(let A of Oe)S.addTool(A);for await(let A of S.getRemainingResults()){A.blocked&&(yield{type:"tool_blocked",turnId:o,callId:A.callId,name:A.toolName,reason:A.blockReason??"blocked"}),z.push(A.message),Ss.push(A.callId),E.add(A.toolName),F++;let O=typeof A.message?.content=="string"?A.message.content:"",Y=A.ok&&O?O.slice(0,2e3):void 0;if(yield{type:"tool_result",turnId:o,callId:A.callId,name:A.toolName,ok:A.ok,error:A.error,outputPreview:Y},A.ok){let ne=Oe.find(K=>K.id===A.callId);if(ne){if(A.toolName==="plan_mode")try{let K=JSON.parse(ne.function.arguments);K.action==="exit"&&typeof K.plan=="string"&&K.plan.length>0&&(yield{type:"plan_update",turnId:o,slug:"approved-plan",content:K.plan})}catch{}if(up.has(A.toolName))try{let K=JSON.parse(ne.function.arguments),he=typeof K.file_path=="string"?K.file_path:typeof K.filePath=="string"?K.filePath:typeof K.path=="string"?K.path:void 0;he&&(yield{type:"artifact",turnId:o,artifactId:`artifact-${A.callId}`,artifactType:dp(he),title:he.split(/[\\/]/).pop()||he,filePath:he,language:pp(he)})}catch{}}}}}catch(S){let A=S instanceof Error?S.message:String(S);yield{type:"error",turnId:o,error:A,code:"TOOL_EXECUTION_ERROR",usage:w.totalUsage};return}if(me=dn(me,{replayMessages:z,completedToolCallIds:[...me.completedToolCallIds,...Ss],lastStopReason:"tool_calls"}),r.generateToolUseSummary&&Oe.length>0){let S=Oe.map(A=>({name:A.function.name,arguments:A.function.arguments}));D=r.generateToolUseSummary(S).catch(()=>null)}let Rs=z.slice(-Oe.length),Au=Rs.length>0&&Rs.every(S=>{let A=S?.content;return typeof A!="string"?!1:A.startsWith("Error: ")}),Tt=w.consecutiveFailedRounds;if(Au){if(Tt+=1,Tt>=Zs&&w.finalText){n.info(`early exit: ${Tt} consecutive failed rounds, returning partial response`),yield{type:"end",turnId:o,content:w.finalText,usage:w.totalUsage,model:w.currentModel};return}}else Tt=0;let go=G+1;if(g>0&&go>g){if(n.info(`max turns reached (${g}), completing`),d){let A=await d.invoke("stop",{sessionId:s,reason:"max_turns"});if(A.action==="abort"){let O=A.reason??"Stop hook requested continuation after max_turns",Y={role:"assistant",content:w.finalText,...we.length>0&&{thinkingBlocks:[...we]}};w={...w,messages:[...z,Y,{role:"user",content:O}],stopHookActive:!0,transition:{reason:"stop_hook_blocking"}};continue}}let S=w.finalText||or(z,n);yield{type:"end",turnId:o,content:S,usage:w.totalUsage,model:w.currentModel};return}if(go>x){if(n.info(`tool loop budget exhausted (${x} rounds), returning`),F>0){let A={ok:!0,toolCallCount:F,distinctToolCount:E.size,multiStep:F>=2,hasSubAgent:!1,feedback:null,existingSkillName:null},O=At(A,{tools:[...E]});O&&(yield{type:"skill_instruction",turnId:o,instruction:O})}let S=w.finalText||or(z,n);yield{type:"end",turnId:o,content:S,usage:w.totalUsage,model:w.currentModel};return}w={messages:z,maxOutputTokensRecoveryCount:0,hasAttemptedReactiveCompact:!1,maxOutputTokensOverride:void 0,turnCount:go,transition:{reason:"next_turn"},guardState:N,reactiveCompactState:pe,toolLoopState:me,consecutiveFailedRounds:Tt,finalText:w.finalText,totalUsage:w.totalUsage,collapseStore:Ee,currentModel:w.currentModel,consecutive529Errors:0,consecutiveApiRetries:0,stopHookActive:w.stopHookActive,lastResponseId:w.lastResponseId,snipRemovedIds:w.snipRemovedIds,contentReplacementState:w.contentReplacementState,budgetContinuationCount:0}}}function or(r,e){let t=[];for(let n=r.length-1;n>=0;n--){let o=r[n];if(o.role==="tool"&&typeof o.content=="string")t.unshift(o.content.slice(0,500));else if(o.role==="assistant"){if(typeof o.content=="string"&&o.content.trim())return e.info("synthesizeFallbackContent: found assistant text, using it"),o.content;break}else break}return t.length>0?(e.info(`synthesizeFallbackContent: synthesized from ${t.length} tool result(s)`),t.join(`
25
25
 
26
26
  `)):""}async function*bp(r,e,t,n,o,s,i,a){let l=[],u;a.debug(`single LLM round, messages: ${t.length}`);for await(let c of i.stream({model:e,messages:t,temperature:o},n,s))switch(c.type){case"delta":l.push(c.text),yield{type:"delta",turnId:r,text:c.text};break;case"usage":u={prompt:c.promptTokens,completion:c.completionTokens,reasoning:c.reasoningTokens,cacheRead:c.cacheReadTokens,cacheCreation:c.cacheCreationTokens};break;case"done":break}yield{type:"end",turnId:r,content:l.join(""),usage:u??{prompt:0,completion:0},model:e}}var up,Oi=q(()=>{"use strict";Jo();ut();ki();nr();Ci();Xo();gn();up=new Set(["write","edit","patch","apply_patch"])});var $i={};_s($i,{Agent:()=>dt});var dt,hn=q(()=>{"use strict";ut();Oi();gn();dt=class{transport;apiKey;toolInvoker;log;hooks;maxRounds;constructor(e){this.transport=e.llmTransport,this.apiKey=e.apiKey,this.toolInvoker=e.toolInvoker,this.log=e.log,this.hooks=e.hooks,this.maxRounds=Math.min(e.maxRounds??25,100)}async*run(e,t){let{turnId:n,messages:o,tools:s,systemPrompt:i,config:a}=e,l={sessionId:e.sessionId,turnId:n};yield{type:"start",turnId:n},this.hooks?.invoke("turn.submitted",{...l,prompt:o[o.length-1]?.content??void 0}).catch(()=>{});let u=Eo(o),c=[];if(i&&c.push({role:"system",content:i}),c.push(...u),this.hooks){let m=u.filter(f=>f.role==="user").pop(),g=typeof m?.content=="string"?m.content.slice(0,500):void 0;if(g)try{let f=await this.hooks.invoke("memory.before_recall",{sessionId:e.sessionId,turnId:n,query:g}),b=f?.context?.recalledMemories;if(b&&b.length>0){let h=b.map(k=>`- ${k.text}`).join(`
27
27
  `);c.splice(i?1:0,0,{role:"system",content:`[Recalled from long-term memory]
@@ -268,8 +268,8 @@ describe: Show workflow steps and variables.`},workflow:{type:"string",descripti
268
268
  `)||"(no output)"}],details:a.isError?{type:"mcp",error:"tool_error"}:{type:"mcp"}}}catch(a){let l=a instanceof Error?a.message:String(a);return{content:[{type:"text",text:`MCP tool error: ${l}`}],details:{type:"mcp",error:l}}}}}}};function Sy(r){return r.replace(/[^a-zA-Z0-9_]/g,"_").toLowerCase()}var Xn=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 o={name:t.name,url:t.url,headers:t.headers,initTimeoutMs:t.initTimeoutMs};this.clients.set(t.name,new Yn(o))}else{if(!t.command){this.log.warn(`[mcp] server "${t.name}" is type "stdio" but has no command, skipping`);continue}let o={name:t.name,command:t.command,args:t.args,env:t.env,initTimeoutMs:t.initTimeoutMs};this.clients.set(t.name,new Jn(o))}}}async connectAll(){let e=Array.from(this.clients.entries()).map(async([t,n])=>{try{await n.connect(),this.log.info(`[mcp] connected to ${t} (${n.info.name} v${n.info.version})`),n.setOnToolsChanged(()=>{this.log.info(`[mcp] tools changed on ${t}, re-injecting`),this.injected&&this.reinjectTools(t,n)})}catch(o){this.log.warn(`[mcp] failed to connect to ${t}: ${o instanceof Error?o.message:o}`)}});await Promise.allSettled(e)}injectTools(){this.injected=!0;for(let[e,t]of this.clients){if(!t.isConnected)continue;let n=t.toPortableTools();Rr(n),this.log.info(`[mcp] injected ${n.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(([,o])=>o):Array.from(this.clients.entries());return(await Promise.all(t.map(async([o,s])=>{if(!s?.isConnected||!s.listResources)return[];try{return(await s.listResources()).map(a=>({...a,server:o}))}catch{return this.log.warn(`[mcp] failed to list resources from ${o}`),[]}}))).flat()}async readResource(e,t){let n=this.clients.get(e);if(!n?.isConnected)throw new Error(`MCP server "${e}" is not connected`);if(!n.readResource)throw new Error(`MCP server "${e}" does not support resources`);return n.readResource(t)}reinjectTools(e,t){if(!this.injected)return;let n=`mcp__${e.replace(/[^a-zA-Z0-9_]/g,"_").toLowerCase()}__`;for(let s of Be())s.startsWith(n)&&Dn(s);let o=t.toPortableTools();Rr(o),this.log.info(`[mcp] re-injected ${o.length} tools from ${e}`)}};function is(r){if(!r||typeof r!="object")return[];let e=r,t=[],n=e.mcpServers??e.servers??e;for(let[o,s]of Object.entries(n)){if(!s||typeof s!="object")continue;let i=s;if(typeof i.url=="string"){t.push({name:o,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:o,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 Ry={type:"object",properties:{server:{type:"string",description:"MCP server name to list resources from. Omit to list from all connected servers."}}};function Rc(r){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:Ry,shouldDefer:!0,isConcurrencySafe:!0,isReadOnly:!0,searchHint:"mcp resource list browse discover",execute:async(e,t)=>{let n=r();if(!n)return{content:[{type:"text",text:"No MCP servers configured."}],details:{type:"list_mcp_resources",count:0}};let o=await n.listResources(t.server);if(o.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 s=new Map;for(let a of o){let l=s.get(a.server)??[];l.push(a),s.set(a.server,l)}let i=[];for(let[a,l]of s){i.push(`Server: ${a} (${l.length} resources)`);for(let u of l){let c=u.mimeType?` [${u.mimeType}]`:"",d=u.description?` \u2014 ${u.description}`:"";i.push(` ${u.name}: ${u.uri}${c}${d}`)}i.push("")}return{content:[{type:"text",text:i.join(`
269
269
  `).trim()}],details:{type:"list_mcp_resources",count:o.length}}}}}var _y={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 _c(r){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:_y,shouldDefer:!0,isConcurrencySafe:!0,isReadOnly:!0,searchHint:"mcp resource read fetch content",execute:async(e,t)=>{let n=r();if(!n)return{content:[{type:"text",text:"No MCP servers configured."}],details:{error:"no_mcp"}};try{let o=await n.readResource(t.server,t.uri);if(o.length===0)return{content:[{type:"text",text:`Resource "${t.uri}" returned no content.`}],details:{type:"read_mcp_resource",empty:!0}};let s=[];for(let i of o)if(i.text){let a=i.mimeType?` (${i.mimeType})`:"";s.push({type:"text",text:`--- ${i.uri}${a} ---
270
270
  ${i.text}`})}else if(i.blob){let a=Math.ceil(i.blob.length*3/4/1024);s.push({type:"text",text:`--- ${i.uri} (binary, ~${a}KB, ${i.mimeType??"unknown"}) ---
271
- [Binary content not displayed. Use appropriate tool to process.]`})}return s.length===0?{content:[{type:"text",text:`Resource "${t.uri}" has no readable content.`}],details:{type:"read_mcp_resource",empty:!0}}:{content:s,details:{type:"read_mcp_resource",uri:t.uri,server:t.server,contentCount:o.length}}}catch(o){return{content:[{type:"text",text:`Error reading resource: ${o.message}`}],details:{error:o.message}}}}}}import*as Ve from"node:fs";import*as Qn from"node:path";import{pathToFileURL as Cy}from"node:url";var Cc={preToolUse:"tool.before_invoke",postToolUse:"tool.after_invoke",onTurnStart:"turn.submitted",onTurnEnd:"turn.completed",onSessionEnd:"session.ended"};var Zn=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(!Ve.existsSync(e))continue;let t;try{t=Ve.readdirSync(e,{withFileTypes:!0})}catch{continue}for(let n of t){if(!n.isDirectory()||n.name.startsWith(".")||n.name.startsWith("_"))continue;let o=Qn.join(e,n.name);await this.loadPlugin(n.name,o)}}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 refreshActivations(){let e=Date.now();for(let[t,n]of this.activations){if(e-n.lastCheckAt<n.ttlMs)continue;let o;try{o=await n.checkFn()}catch(s){this.log.warn(`[plugins] ${t}: check_fn error: ${s instanceof Error?s.message:s}`),o=n.lastResult}if(n.lastCheckAt=e,o!==n.lastResult){if(n.lastResult=o,o&&!n.active){for(let s of n.tools)ce(s);n.active=!0,this.log.info(`[plugins] ${t}: reactivated (${n.tools.length} tools)`)}else if(!o&&n.active){for(let s of n.tools)Dn(s.name);for(let s of n.hookUnregisterFns)s();n.active=!1,this.log.info(`[plugins] ${t}: deactivated`)}}}}async loadPlugin(e,t){let n=["index.js","index.mjs"],o=null;for(let f of n){let b=Qn.join(t,f);if(Ve.existsSync(b)){o=b;break}}if(!o){this.log.warn(`[plugins] ${e}: no index.js found, skipping`);return}let s=0,i=0,a=0,l=[],u=[],c=null,d=6e4,p={},m=Qn.join(t,"config.json");if(Ve.existsSync(m))try{p=JSON.parse(Ve.readFileSync(m,"utf8"))}catch{}let g={pluginName:e,registerTool:f=>{ce(f),l.push(f),s++},registerHook:(f,b)=>{let h=Cc[f];if(!h){this.log.warn(`[plugins] ${e}: unknown hook phase "${f}"`);return}let k=this.config.hookRegistry.register({point:h,handler:b,label:`plugin:${e}:${f}`,priority:200});u.push(k),i++},registerSkill:f=>{this.pluginSkills.push(f),a++},getConfig:()=>p,setActivationCheck:(f,b)=>{c=f,b!==void 0&&(d=b)}};try{let b=await import(Cy(o).href);if(typeof b.register!="function"){this.log.warn(`[plugins] ${e}: no register() export, skipping`);return}await b.register(g),c&&this.activations.set(e,{checkFn:c,ttlMs:d,lastCheckAt:Date.now(),lastResult:!0,tools:l,hookUnregisterFns:u,active:!0}),this.loaded.push({name:e,directory:t,toolCount:s,hookCount:i,skillCount:a}),this.log.info(`[plugins] ${e}: ${s} tools, ${i} hooks, ${a} skills`)}catch(f){this.log.warn(`[plugins] ${e}: load error: ${f instanceof Error?f.message:f}`)}}};import*as re from"node:fs";import*as Jt from"node:path";function as(){return ji()}function Ac(){return Jt.join(as(),"installed_plugins.json")}function Mc(){let r=Ac();if(!re.existsSync(r))return{version:1,plugins:[]};try{return JSON.parse(re.readFileSync(r,"utf-8"))}catch{return{version:1,plugins:[]}}}function Ay(r){let e=as();re.existsSync(e)||re.mkdirSync(e,{recursive:!0}),re.writeFileSync(Ac(),JSON.stringify(r,null,2),"utf-8")}function My(r,e){return!(e.blocklist?.includes(r)||e.allowlist&&!e.allowlist.includes(r))}async function Py(r,e,t){let{execFile:n}=await import("node:child_process"),{promisify:o}=await import("node:util"),s=o(n),i=as(),a=e?`${r}@${e}`:r;try{let{stdout:l}=await s("npm",["pack",a,"--pack-destination",i],{timeout:6e4,cwd:i}),u=l.trim().split(`
272
- `).pop()?.trim();if(!u)return t.warn(`[marketplace] npm pack returned no output for ${a}`),null;let c=Jt.join(i,u),p=u.match(/^(.+)-(\d+\.\d+\.\d+.*)\.tgz$/)?.[2]??"0.0.0",m=Jt.join(i,`${r}@${p}`);re.existsSync(m)||re.mkdirSync(m,{recursive:!0}),await s("tar",["xzf",c,"-C",m,"--strip-components=1"],{timeout:3e4});try{re.unlinkSync(c)}catch{}let g=Jt.join(m,"package.json");if(re.existsSync(g))try{await s("npm",["install","--production","--no-save"],{cwd:m,timeout:12e4})}catch(f){t.warn(`[marketplace] npm install for ${r} failed: ${f.message}`)}return t.info(`[marketplace] installed ${r}@${p} from npm`),{name:r,version:p,installPath:m}}catch(l){return t.warn(`[marketplace] failed to install ${a} from npm: ${l.message}`),null}}function Iy(){return Mc().plugins.filter(e=>re.existsSync(e.installPath)).map(e=>e.installPath)}async function Ey(r,e){let t=Mc(),n=[];for(let o of r.enabledPlugins){let s=o.specifier.split("/").pop()??o.specifier;if(!My(s,r)){e.warn(`[marketplace] plugin "${s}" blocked by enterprise policy`);continue}let i=t.plugins.find(l=>l.source.specifier===o.specifier&&l.source.type===o.type);if(i&&re.existsSync(i.installPath)&&(!o.version||i.version===o.version)){n.push(i.installPath);continue}let a=null;switch(o.type){case"npm":a=await Py(o.specifier,o.version,e);break;case"git":case"url":e.warn(`[marketplace] ${o.type} source not yet implemented for "${o.specifier}"`);break}if(a){let l={name:a.name,version:a.version,source:o,installPath:a.installPath,installedAt:new Date().toISOString()};t.plugins=t.plugins.filter(u=>!(u.source.specifier===o.specifier&&u.source.type===o.type)),t.plugins.push(l),n.push(a.installPath)}}return Ay(t),n}function Oy(){let r=Wi();if(!re.existsSync(r))return null;try{return JSON.parse(re.readFileSync(r,"utf-8"))}catch{return null}}async function Pc(r,e){let t=[...r],n=Iy();t.push(...n);let o=Oy();if(o&&o.enabledPlugins.length>0)try{let s=await Ey(o,e),i=new Set(t);for(let a of s)i.has(a)||t.push(a)}catch(s){e.warn(`[marketplace] failed to update plugins: ${s.message}`)}return t}var eo=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:n}=e;switch(this.mode){case"bypassPermissions":return{behavior:"allow",decisionReason:{type:"mode",mode:"bypassPermissions"}};case"dontAsk":return{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:o,regex:s}of this.compiledPatterns)if(s.test(t))return $y(o,e);return n?.isReadOnly?{behavior:"allow",decisionReason:{type:"tool_check",reason:"isReadOnly"}}:n?.requiresApproval?{behavior:"ask",message:`Tool "${t}" requires approval`,toolName:t,input:e.arguments,decisionReason:{type:"tool_check",reason:"requiresApproval"}}:n?.isDangerous?{behavior:"ask",message:`Tool "${t}" is marked dangerous`,toolName:t,input:e.arguments,decisionReason:{type:"tool_check",reason:"isDangerous"}}:this.mode==="acceptEdits"?/write|edit|create|delete|move|rename|patch/i.test(t)?{behavior:"allow",decisionReason:{type:"mode",mode:"acceptEdits"}}:{behavior:"ask",message:`Tool "${t}" needs approval in acceptEdits mode`,toolName:t,input:e.arguments,decisionReason:{type:"mode",mode:"acceptEdits"}}: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:Ly(t.pattern)}))}};function ls(r){if(!r||typeof r!="object")return{mode:"default",rules:[],defaultBehavior:"allow"};let e=r,t=[];for(let a of["allow","deny","ask"]){let l=e[a];if(Array.isArray(l))for(let u of l)typeof u=="string"&&t.push({pattern:u,behavior:a,source:"config"})}if(Array.isArray(e.rules)){for(let a of e.rules)if(a&&typeof a=="object"){let l=a,u=l.pattern,c=l.behavior??l.action;typeof u=="string"&&typeof c=="string"&&(c==="allow"||c==="deny"||c==="ask")&&t.push({pattern:u,behavior:c,reason:typeof l.reason=="string"?l.reason:void 0,source:typeof l.source=="string"?l.source:"config"})}}let n=e.mode,o=typeof n=="string"&&Dy(n)?n:"default",s=e.default??e.defaultBehavior,i=typeof s=="string"&&Uy(s)?s:"allow";return{mode:o,rules:t,defaultBehavior:i}}function Ly(r){let t=r.replace(/[.+^${}()|[\]\\]/g,"\\$&").replace(/\*+/g,".*");return new RegExp(`^${t}$`,"i")}function $y(r,e){let t={type:"rule",rule:r};return r.behavior==="allow"?{behavior:"allow",decisionReason:t}:r.behavior==="deny"?{behavior:"deny",message:r.reason??`Tool "${e.toolName}" denied by rule "${r.pattern}"`,decisionReason:t}:{behavior:"ask",message:r.reason??`Tool "${e.toolName}" requires approval (rule "${r.pattern}")`,toolName:e.toolName,input:e.arguments,decisionReason:t}}function Dy(r){return r==="default"||r==="bypassPermissions"||r==="acceptEdits"||r==="dontAsk"||r==="plan"}function Uy(r){return r==="allow"||r==="deny"||r==="ask"}import{randomUUID as zy}from"node:crypto";var Ny=new Set(["node --version","npm --version","npx --version","pnpm --version","yarn --version","bun --version","deno --version","python --version","python3 --version","pip --version","ruby --version","go version","rustc --version","cargo --version","java -version","javac -version","dotnet --version","gcc --version","g++ --version","clang --version","git --version","docker --version","--help","-h"]),Ic=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","tsc --noEmit","eslint","prettier","oxlint"]),Fy=[/\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],Ec=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 Oc(r,e,t){let n=r.trim();if(!n)return{decision:"allow",reason:"empty command"};let o=Br(n)??Wr(n)??void 0;for(let u of Fy)if(u.test(n))return{decision:"deny",reason:`matches dangerous pattern: ${u.source}`,destructiveWarning:o};for(let u of Ny)if(n===u||n.startsWith(u+" "))return{decision:"allow",reason:`known safe command: ${u}`,destructiveWarning:o};let s=n.split(/\s+/),i=s[0],a=s.length>1?`${s[0]} ${s[1]}`:i;return Ic.has(i)||Ic.has(a)?{decision:"allow",reason:`known safe command: ${i}`,destructiveWarning:o}:e&&t&&e.startsWith(t)&&(Ec.has(i)||Ec.has(a))?{decision:"allow",reason:`safe in project: ${a}`,destructiveWarning:o}:{decision:"defer",reason:"unknown command \u2014 needs LLM classification",destructiveWarning:o}}function jy(r){let e=Object.keys(r).sort(),t={};for(let n of e){let o=r[n];typeof o=="string"?t[n]=o.replace(/\s+/g," ").trim():t[n]=o}return JSON.stringify(t)}function cs(r,e){return`${r}::${jy(e)}`}var By=500,to=class{cache=new Map;get(e,t){let n=cs(e,t),o=this.cache.get(n);if(o)return o.hitCount++,o}set(e,t,n){if(this.cache.size>=By){let s=this.cache.keys().next().value;s!==void 0&&this.cache.delete(s)}let o=cs(e,t);this.cache.set(o,{shouldBlock:n.shouldBlock,reason:n.reason,classifiedAt:Date.now(),hitCount:0})}has(e,t){return this.cache.has(cs(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 Wy=new Set(["read","search","instructions","think","todo","memory","skill_list","skill_view","tool_search","plan_mode","lsp","brief","web_search","checkpoint"]);function Yt(r){return Wy.has(r)}var Lc=`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.
271
+ [Binary content not displayed. Use appropriate tool to process.]`})}return s.length===0?{content:[{type:"text",text:`Resource "${t.uri}" has no readable content.`}],details:{type:"read_mcp_resource",empty:!0}}:{content:s,details:{type:"read_mcp_resource",uri:t.uri,server:t.server,contentCount:o.length}}}catch(o){return{content:[{type:"text",text:`Error reading resource: ${o.message}`}],details:{error:o.message}}}}}}import*as Ve from"node:fs";import*as Qn from"node:path";import{pathToFileURL as Cy}from"node:url";var Cc={preToolUse:"tool.before_invoke",postToolUse:"tool.after_invoke",onTurnStart:"turn.submitted",onTurnEnd:"turn.completed",onSessionEnd:"session.ended"};var Zn=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(!Ve.existsSync(e))continue;let t;try{t=Ve.readdirSync(e,{withFileTypes:!0})}catch{continue}for(let n of t){if(!n.isDirectory()||n.name.startsWith(".")||n.name.startsWith("_"))continue;let o=Qn.join(e,n.name);await this.loadPlugin(n.name,o)}}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 refreshActivations(){let e=Date.now();for(let[t,n]of this.activations){if(e-n.lastCheckAt<n.ttlMs)continue;let o;try{o=await n.checkFn()}catch(s){this.log.warn(`[plugins] ${t}: check_fn error: ${s instanceof Error?s.message:s}`),o=n.lastResult}if(n.lastCheckAt=e,o!==n.lastResult){if(n.lastResult=o,o&&!n.active){for(let s of n.tools)ce(s);n.active=!0,this.log.info(`[plugins] ${t}: reactivated (${n.tools.length} tools)`)}else if(!o&&n.active){for(let s of n.tools)Dn(s.name);for(let s of n.hookUnregisterFns)s();n.active=!1,this.log.info(`[plugins] ${t}: deactivated`)}}}}async loadPlugin(e,t){let n=["index.js","index.mjs"],o=null;for(let f of n){let b=Qn.join(t,f);if(Ve.existsSync(b)){o=b;break}}if(!o){this.log.warn(`[plugins] ${e}: no index.js found, skipping`);return}let s=0,i=0,a=0,l=[],u=[],c=null,d=6e4,p={},m=Qn.join(t,"config.json");if(Ve.existsSync(m))try{p=JSON.parse(Ve.readFileSync(m,"utf8"))}catch{}let g={pluginName:e,registerTool:f=>{ce(f),l.push(f),s++},registerHook:(f,b)=>{let h=Cc[f];if(!h){this.log.warn(`[plugins] ${e}: unknown hook phase "${f}"`);return}let k=this.config.hookRegistry.register({point:h,handler:b,label:`plugin:${e}:${f}`,priority:200});u.push(k),i++},registerSkill:f=>{this.pluginSkills.push(f),a++},getConfig:()=>p,setActivationCheck:(f,b)=>{c=f,b!==void 0&&(d=b)}};try{let b=await import(Cy(o).href);if(typeof b.register!="function"){this.log.warn(`[plugins] ${e}: no register() export, skipping`);return}await b.register(g),c&&this.activations.set(e,{checkFn:c,ttlMs:d,lastCheckAt:Date.now(),lastResult:!0,tools:l,hookUnregisterFns:u,active:!0}),this.loaded.push({name:e,directory:t,toolCount:s,hookCount:i,skillCount:a}),this.log.info(`[plugins] ${e}: ${s} tools, ${i} hooks, ${a} skills`)}catch(f){this.log.warn(`[plugins] ${e}: load error: ${f instanceof Error?f.message:f}`)}}};import*as oe from"node:fs";import*as Jt from"node:path";function as(){return ji()}function Ac(){return Jt.join(as(),"installed_plugins.json")}function Mc(){let r=Ac();if(!oe.existsSync(r))return{version:1,plugins:[]};try{return JSON.parse(oe.readFileSync(r,"utf-8"))}catch{return{version:1,plugins:[]}}}function Ay(r){let e=as();oe.existsSync(e)||oe.mkdirSync(e,{recursive:!0}),oe.writeFileSync(Ac(),JSON.stringify(r,null,2),"utf-8")}function My(r,e){return!(e.blocklist?.includes(r)||e.allowlist&&!e.allowlist.includes(r))}async function Py(r,e,t){let{execFile:n}=await import("node:child_process"),{promisify:o}=await import("node:util"),s=o(n),i=as(),a=e?`${r}@${e}`:r;try{let{stdout:l}=await s("npm",["pack",a,"--pack-destination",i],{timeout:6e4,cwd:i}),u=l.trim().split(`
272
+ `).pop()?.trim();if(!u)return t.warn(`[marketplace] npm pack returned no output for ${a}`),null;let c=Jt.join(i,u),p=u.match(/^(.+)-(\d+\.\d+\.\d+.*)\.tgz$/)?.[2]??"0.0.0",m=Jt.join(i,`${r}@${p}`);oe.existsSync(m)||oe.mkdirSync(m,{recursive:!0}),await s("tar",["xzf",c,"-C",m,"--strip-components=1"],{timeout:3e4});try{oe.unlinkSync(c)}catch{}let g=Jt.join(m,"package.json");if(oe.existsSync(g))try{await s("npm",["install","--production","--no-save"],{cwd:m,timeout:12e4})}catch(f){t.warn(`[marketplace] npm install for ${r} failed: ${f.message}`)}return t.info(`[marketplace] installed ${r}@${p} from npm`),{name:r,version:p,installPath:m}}catch(l){return t.warn(`[marketplace] failed to install ${a} from npm: ${l.message}`),null}}function Iy(){return Mc().plugins.filter(e=>oe.existsSync(e.installPath)).map(e=>e.installPath)}async function Ey(r,e){let t=Mc(),n=[];for(let o of r.enabledPlugins){let s=o.specifier.split("/").pop()??o.specifier;if(!My(s,r)){e.warn(`[marketplace] plugin "${s}" blocked by enterprise policy`);continue}let i=t.plugins.find(l=>l.source.specifier===o.specifier&&l.source.type===o.type);if(i&&oe.existsSync(i.installPath)&&(!o.version||i.version===o.version)){n.push(i.installPath);continue}let a=null;switch(o.type){case"npm":a=await Py(o.specifier,o.version,e);break;case"git":case"url":e.warn(`[marketplace] ${o.type} source not yet implemented for "${o.specifier}"`);break}if(a){let l={name:a.name,version:a.version,source:o,installPath:a.installPath,installedAt:new Date().toISOString()};t.plugins=t.plugins.filter(u=>!(u.source.specifier===o.specifier&&u.source.type===o.type)),t.plugins.push(l),n.push(a.installPath)}}return Ay(t),n}function Oy(){let r=Wi();if(!oe.existsSync(r))return null;try{return JSON.parse(oe.readFileSync(r,"utf-8"))}catch{return null}}async function Pc(r,e){let t=[...r],n=Iy();t.push(...n);let o=Oy();if(o&&o.enabledPlugins.length>0)try{let s=await Ey(o,e),i=new Set(t);for(let a of s)i.has(a)||t.push(a)}catch(s){e.warn(`[marketplace] failed to update plugins: ${s.message}`)}return t}var eo=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:n}=e;switch(this.mode){case"bypassPermissions":return{behavior:"allow",decisionReason:{type:"mode",mode:"bypassPermissions"}};case"dontAsk":return{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:o,regex:s}of this.compiledPatterns)if(s.test(t))return $y(o,e);return n?.isReadOnly?{behavior:"allow",decisionReason:{type:"tool_check",reason:"isReadOnly"}}:n?.requiresApproval?{behavior:"ask",message:`Tool "${t}" requires approval`,toolName:t,input:e.arguments,decisionReason:{type:"tool_check",reason:"requiresApproval"}}:n?.isDangerous?{behavior:"ask",message:`Tool "${t}" is marked dangerous`,toolName:t,input:e.arguments,decisionReason:{type:"tool_check",reason:"isDangerous"}}:this.mode==="acceptEdits"?/write|edit|create|delete|move|rename|patch/i.test(t)?{behavior:"allow",decisionReason:{type:"mode",mode:"acceptEdits"}}:{behavior:"ask",message:`Tool "${t}" needs approval in acceptEdits mode`,toolName:t,input:e.arguments,decisionReason:{type:"mode",mode:"acceptEdits"}}: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:Ly(t.pattern)}))}};function ls(r){if(!r||typeof r!="object")return{mode:"default",rules:[],defaultBehavior:"allow"};let e=r,t=[];for(let a of["allow","deny","ask"]){let l=e[a];if(Array.isArray(l))for(let u of l)typeof u=="string"&&t.push({pattern:u,behavior:a,source:"config"})}if(Array.isArray(e.rules)){for(let a of e.rules)if(a&&typeof a=="object"){let l=a,u=l.pattern,c=l.behavior??l.action;typeof u=="string"&&typeof c=="string"&&(c==="allow"||c==="deny"||c==="ask")&&t.push({pattern:u,behavior:c,reason:typeof l.reason=="string"?l.reason:void 0,source:typeof l.source=="string"?l.source:"config"})}}let n=e.mode,o=typeof n=="string"&&Dy(n)?n:"default",s=e.default??e.defaultBehavior,i=typeof s=="string"&&Uy(s)?s:"allow";return{mode:o,rules:t,defaultBehavior:i}}function Ly(r){let t=r.replace(/[.+^${}()|[\]\\]/g,"\\$&").replace(/\*+/g,".*");return new RegExp(`^${t}$`,"i")}function $y(r,e){let t={type:"rule",rule:r};return r.behavior==="allow"?{behavior:"allow",decisionReason:t}:r.behavior==="deny"?{behavior:"deny",message:r.reason??`Tool "${e.toolName}" denied by rule "${r.pattern}"`,decisionReason:t}:{behavior:"ask",message:r.reason??`Tool "${e.toolName}" requires approval (rule "${r.pattern}")`,toolName:e.toolName,input:e.arguments,decisionReason:t}}function Dy(r){return r==="default"||r==="bypassPermissions"||r==="acceptEdits"||r==="dontAsk"||r==="plan"}function Uy(r){return r==="allow"||r==="deny"||r==="ask"}import{randomUUID as zy}from"node:crypto";var Ny=new Set(["node --version","npm --version","npx --version","pnpm --version","yarn --version","bun --version","deno --version","python --version","python3 --version","pip --version","ruby --version","go version","rustc --version","cargo --version","java -version","javac -version","dotnet --version","gcc --version","g++ --version","clang --version","git --version","docker --version","--help","-h"]),Ic=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","tsc --noEmit","eslint","prettier","oxlint"]),Fy=[/\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],Ec=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 Oc(r,e,t){let n=r.trim();if(!n)return{decision:"allow",reason:"empty command"};let o=Br(n)??Wr(n)??void 0;for(let u of Fy)if(u.test(n))return{decision:"deny",reason:`matches dangerous pattern: ${u.source}`,destructiveWarning:o};for(let u of Ny)if(n===u||n.startsWith(u+" "))return{decision:"allow",reason:`known safe command: ${u}`,destructiveWarning:o};let s=n.split(/\s+/),i=s[0],a=s.length>1?`${s[0]} ${s[1]}`:i;return Ic.has(i)||Ic.has(a)?{decision:"allow",reason:`known safe command: ${i}`,destructiveWarning:o}:e&&t&&e.startsWith(t)&&(Ec.has(i)||Ec.has(a))?{decision:"allow",reason:`safe in project: ${a}`,destructiveWarning:o}:{decision:"defer",reason:"unknown command \u2014 needs LLM classification",destructiveWarning:o}}function jy(r){let e=Object.keys(r).sort(),t={};for(let n of e){let o=r[n];typeof o=="string"?t[n]=o.replace(/\s+/g," ").trim():t[n]=o}return JSON.stringify(t)}function cs(r,e){return`${r}::${jy(e)}`}var By=500,to=class{cache=new Map;get(e,t){let n=cs(e,t),o=this.cache.get(n);if(o)return o.hitCount++,o}set(e,t,n){if(this.cache.size>=By){let s=this.cache.keys().next().value;s!==void 0&&this.cache.delete(s)}let o=cs(e,t);this.cache.set(o,{shouldBlock:n.shouldBlock,reason:n.reason,classifiedAt:Date.now(),hitCount:0})}has(e,t){return this.cache.has(cs(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 Wy=new Set(["read","search","instructions","think","todo","memory","skill_list","skill_view","tool_search","plan_mode","lsp","brief","web_search","checkpoint"]);function Yt(r){return Wy.has(r)}var Lc=`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.
273
273
 
274
274
  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).
275
275
 
@@ -423,9 +423,9 @@ Based on the conversation, suggest 1-3 short follow-up actions the user might na
423
423
  Be specific: "run the tests" beats "continue".
424
424
  Stay silent if the next step isn't obvious.
425
425
  Reply with ONLY a JSON array: [{"text":"short suggestion"}]. No explanation.`;async generateSuggestions(e,t,n,o,s){if(t.filter(u=>u.role==="assistant").length<1)return;let l=[...t.slice(-6),{role:"user",content:r.SUGGESTION_PROMPT}];try{let u="";for await(let d of n.stream({model:s,messages:l,temperature:.3,maxTokens:200},o))d.type==="delta"&&(u+=d.text);let c=u.match(/\[[\s\S]*\]/);if(c){let d=JSON.parse(c[0]),p=Array.isArray(d)?d.filter(m=>typeof m.text=="string"&&m.text.length>0).slice(0,5):[];p.length>0&&this.sendNotification("turn.suggestions",{turnId:e,items:p})}}catch{}}async handleDream(e){let t=e.params??{},n=t.turnId??ve(),o=t.sessionId,s=t.config,i=s?.memoryRoot??"",a=s?.transcriptDir??"",l=s?.dreamSessionIds??[];e.id!==void 0&&this.sendResponse(e.id,{accepted:!0,turnId:n});let u=new AbortController;this.activeTurn=u,this.log(`dream ${n} starting (session: ${o}, sessions reviewing: ${l.length})`);let c={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 p=c.provider??"",m=c.model??"";p&&m&&this.registry.getModelInfo(p,m)?.streamRequired&&(c.streamRequired=!0)}if(!this.resolveAgent(c)){this.sendNotification("turn.start",{turnId:n}),this.sendNotification("turn.error",{turnId:n,error:"No LLM provider configured for dream.",code:"NO_PROVIDER"});return}this.sendNotification("turn.start",{turnId:n});try{let p={context:{memoryRoot:i,transcriptDir:a,currentSessionId:o,listSessionsSince:async()=>l},triggerConfig:{force:!0},transport:this.currentTransport,toolInvoker:{invoke:async(g,f,b,h)=>{if(f.startsWith("$"))return{result:b};let k=ke(f);if(!k)return{result:"",error:`Unknown tool: ${f}`};let x=`tc_${ve().slice(0,8)}`;try{let R=JSON.parse(b),E=await k.execute(x,R,h);return{result:E.content.map(U=>U.text??"").join(`
426
- `),error:E.details?.error}}catch(R){return{result:"",error:R instanceof Error?R.message:String(R)}}}},tools:We(),apiKey:this.currentApiKey,model:c.model??this.currentModel,log:{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}`)}},hooks:this.currentHooks??void 0,parentSignal:u.signal,qmemoryAdapter:this.qmemoryAdapter??void 0,qmemoryUserId:this.qmemoryUserId||void 0},m=await _a(p);m.ok?this.sendNotification("turn.end",{turnId:n,content:`Dream consolidation completed. ${m.sessionsReviewed} sessions reviewed, ${m.filesTouched.length} files touched. Duration: ${m.durationMs}ms.`,usage:{prompt:0,completion:0}}):this.sendNotification("turn.error",{turnId:n,error:m.error??"Dream consolidation failed",code:"DREAM_FAILED"}),this.log(`dream ${n} completed`)}catch(p){if(u.signal.aborted)this.sendNotification("turn.error",{turnId:n,error:"Dream aborted",code:"ABORTED"});else{let m=p instanceof Error?p.message:String(p);this.sendNotification("turn.error",{turnId:n,error:m,code:"INTERNAL_ERROR"})}}finally{this.activeTurn===u&&(this.activeTurn=null)}}resolveAgent(e){let t=`${e.provider??""}:${e.model??""}:${e.apiKey?.slice(0,8)??""}:${e.baseUrl??""}`;if(this.agent&&this.lastLlmConfigKey===t)return this.agent;let n=e.provider,o=e.model,s=e.apiKey,i=e.baseUrl;if(!n||!s){let y=_n(this.registry);y&&(n=n??y.providerId,s=s??y.apiKey,o=o??y.defaultModel,this.log(`auto-detected provider: ${n}, model: ${o}`))}if(!n||!s){let y=this.loadSettingsSync();y&&(n=n??y.provider,s=s??y.apiKey,o=o??y.model,n&&s&&this.log(`loaded provider from settings.json: ${n}, model: ${o}`))}if(!n||!s)return null;o=o??this.registry.getProvider(n)?.defaultModel??"";let a=Rn({provider:n,model:o,apiKey:s,baseUrl:i},this.registry);pr()&&(a.transport=mr(a.transport,this.currentSessionId||"default"));let l={info:y=>this.log(y),warn:y=>this.log(`[warn] ${y}`),error:y=>this.log(`[error] ${y}`),debug:y=>{this.verbose&&this.log(`[debug] ${y}`)}},u={invoke:async(y,T,v,_)=>{if(T.startsWith("$"))return{result:v};let C=ke(T);if(!C)return{result:"",error:`Unknown tool: ${T}`};let I=`tc_${ve().slice(0,8)}`;try{let V=JSON.parse(v),j=await C.execute(I,V,_),se=j.content.map(ie=>ie.text??"").join(`
427
- `),X=j.details?.error,P=j.details?.type,ne=P?.split("_")[0];if(ne&&["image","tts","video","music"].includes(ne)){let ie=j.details?.mediaUrls??[],we=ne==="music"?"tts":ne;for(let ln of ie)this.sendNotification("turn.media_result",{turnId:y,mediaType:we,url:ln,model:j.details?.model,provider:j.details?.provider,...j.details?.durationMs?{durationSeconds:j.details.durationMs/1e3}:{},...j.details?.taskId?{taskId:j.details.taskId}:{}})}if(P==="todo"&&!X)try{let ie=JSON.parse(se);ie.todoList&&this.sendNotification("turn.todos_updated",{turnId:y,items:ie.todoList,summary:{total:ie.total??ie.todoList.length,completed:ie.completed??0,inProgress:ie.inProgress??0,notStarted:ie.notStarted??0}})}catch{}return{result:se,error:X}}catch(V){return{result:"",error:V instanceof Error?V.message:String(V)}}}},c=fr(l);this.currentHooks=c,this.taskStore.setHooks(c,this.currentSessionId??"");let d=(process.env.QMEMORY_BASE_URL??process.env.QLOGICAGENT_QMEMORY_BASE_URL??"").trim().replace(/\/+$/,"");if(d){let y=la({baseUrl:d,apiKey:(process.env.QMEMORY_API_KEY??"").trim()||void 0,timeoutMs:5e3});this.qmemoryAdapter=y,this.qmemoryUserId=this.currentSessionId??"default",ia(c,{memoryProvider:y,userId:this.currentSessionId??"default",log:{debug:T=>l.debug(T),warn:T=>l.warn(T)}},this.memoryPrefetchState)}Ri(c,l,{transport:a.transport,apiKey:a.apiKey});let p=e?.mcpServers,m=is(p??{}),g=Bi();try{if($.existsSync(g)){let y=JSON.parse($.readFileSync(g,"utf8")),T=is(y),v=new Set(m.map(_=>_.name));m=[...m,...T.filter(_=>!v.has(_.name))]}}catch{}if(m.length>0){this.mcpManager&&this.mcpManager.disconnectAll().catch(()=>{}),this.mcpManager=new Xn({servers:m,log:l}),it(async()=>{await this.mcpManager?.disconnectAll()});let y=()=>this.mcpManager;ce(Rc(y)),ce(_c(y)),ce(Yc({listServers:async()=>{let T=this.mcpManager;return T?T.getConnectedServers().map(_=>({name:_,status:"connected",transport:"stdio",toolCount:0,resourceCount:0,promptCount:0})):[]},listTools:async T=>{if(!this.mcpManager)return[];let _=`mcp__${T.replace(/[^a-zA-Z0-9_]/g,"_").toLowerCase()}__`;return Be().filter(C=>C.startsWith(_)).map(C=>({name:C.slice(_.length),prefixedName:C}))},callTool:async(T,v,_,C)=>{let V=`mcp__${T.replace(/[^a-zA-Z0-9_]/g,"_").toLowerCase()}__`+v,j=ke(V);if(!j)return{success:!1,error:`Tool not found: ${V}`};try{return{success:!0,content:(await j.execute(`mcp_${Date.now()}`,_??{},C)).content.map(P=>P.text??"").join(`
428
- `)}}catch(se){return{success:!1,error:se.message}}},listResources:async T=>{let v=this.mcpManager;return v?(await v.listResources(T)).map(C=>({uri:C.uri,name:C.name,mimeType:C.mimeType,description:C.description,server:C.server})):[]},readResource:async(T,v)=>{let _=this.mcpManager;if(!_)throw new Error("MCP not initialized");return(await _.readResource(T,v)).map(I=>({uri:I.uri,mimeType:I.mimeType,text:I.text}))},authenticate:async()=>({status:"unsupported",message:"OAuth not yet implemented in McpManager"})})),this.mcpManager.connectAll().then(()=>{this.mcpManager?.injectTools(),l.info(`[mcp] ${this.mcpManager?.getToolCount()??0} tools from ${this.mcpManager?.getConnectedServers().length??0} servers`)}).catch(T=>{l.warn(`[mcp] connection error: ${T instanceof Error?T.message:T}`)})}let f=[],b=Ui();$.existsSync(b)&&f.push(b);let h=e?.pluginPaths;if(Array.isArray(h))for(let y of h)typeof y=="string"&&$.existsSync(y)&&f.push(y);Pc(f,l).then(y=>{if(y.length===0)return;this.pluginLoader=new Zn({pluginDirs:y,hookRegistry:c,log:l}),this.pluginLoader.loadAll().then(v=>{l.info(`[plugins] ${v.length} loaded, ${this.pluginLoader?.getPluginSkills().length??0} skills`)}).catch(v=>{l.warn(`[plugins] load error: ${v instanceof Error?v.message:v}`)});let T=this.pluginLoader;c.register({point:"turn.submitted",handler:async()=>(await T.refreshActivations(),{action:"continue"}),label:"plugin-activation-refresh",priority:50})}).catch(y=>{l.warn(`[plugins] marketplace resolve error: ${y instanceof Error?y.message:y}`)});let k=e?.permissions,x=ls(k),R=new eo(x);this.permissionUnregister&&this.permissionUnregister(),this.permissionChecker=new no({ruleEngine:R,hookRegistry:c,onRequestApproval:async y=>(this.sendNotification("tool.approval.request",{approvalId:y.approvalId,callId:y.callId,toolName:y.toolName,arguments:y.arguments?JSON.stringify(y.arguments):"",message:y.message,suggestions:y.suggestions?.map(T=>`${T.pattern}:${T.behavior}`)}),new Promise(()=>{})),onPermissionUpdate:y=>{l.info(`[permissions] rule saved: ${y.pattern} \u2192 ${y.behavior}`),this.sendNotification("permission.rule_updated",{pattern:y.pattern,behavior:y.behavior})},onDenied:(y,T)=>{l.warn(`[permissions] blocked "${y}": ${T}`)}});let E=We();this.permissionChecker.setToolMeta(E),this.permissionUnregister=this.permissionChecker.register();let F=[sr(),...Array.isArray(e?.skillPaths)?e.skillPaths:[]];ce(Bc({listSkills:()=>{let y=[];this.pluginLoader&&y.push(...this.pluginLoader.getPluginSkills());let T=e?.skillPaths;if(Array.isArray(T)){for(let v of T)if(typeof v=="string"){let _=J.basename(v);y.some(C=>C.name===_)||y.push({name:_,source:"gateway",filePath:J.join(v,"SKILL.md"),baseDir:v})}}return y},listSkillsFull:async y=>{let T=[],v=new Set;for(let _ of F)try{let C=await $.promises.readdir(_,{withFileTypes:!0});for(let I of C){if(!I.isDirectory())continue;let V=J.join(_,I.name,"SKILL.md");try{await $.promises.access(V);let j=J.basename(_);if(y&&j!==y)continue;v.add(j),T.push({name:I.name,description:`Skill from ${_}`,category:j})}catch{}}}catch{}if(this.pluginLoader)for(let _ of this.pluginLoader.getPluginSkills())y&&_.source!==y||(v.add(_.source??"plugin"),T.push({name:_.name,description:`Plugin skill (${_.source})`,category:_.source}));return{skills:T,categories:[...v]}},readSkillContent:async y=>{for(let T of F){let v=J.join(T,y,"SKILL.md");try{return await $.promises.readFile(v,"utf8")}catch{}}return null},viewSkill:async(y,T)=>{for(let v of F){let _=T?J.join(v,y,T):J.join(v,y,"SKILL.md");try{let C=await $.promises.readFile(_,"utf8");return{name:y,content:C}}catch{}}return null},executeSkillSubturn:async(y,T,v,_)=>{let C=`skill_${y}_${ve().slice(0,8)}`,I=this.agent;if(!I)return"[skill] Cannot execute: no LLM provider configured";let V=this.currentSessionId??"skill";this.currentHooks?.invoke("subagent.started",{sessionId:V,turnId:C,subagentId:C,agentType:`skill:${y}`}).catch(()=>{});let j=We(),se=v??`Execute skill "${y}" instructions.`,X=[],P;for await(let ne of I.run({turnId:C,sessionId:V,messages:[{role:"user",content:se}],tools:j,systemPrompt:T,config:{parentDepth:1}},_)){if(ne.type==="end"&&ne.content)return this.currentHooks?.invoke("subagent.stopped",{sessionId:V,turnId:C,subagentId:C,agentType:`skill:${y}`,reason:"normal"}).catch(()=>{}),ne.content;if(ne.type==="delta"&&ne.text&&X.push(ne.text),ne.type==="error"){P=ne.error;break}}return this.currentHooks?.invoke("subagent.stopped",{sessionId:V,turnId:C,subagentId:C,agentType:`skill:${y}`,reason:P?"error":"normal",error:P}).catch(()=>{}),P?`[skill "${y}"] error: ${P}`:X.join("")||`[skill "${y}"] completed (no output)`},manageSkill:async y=>{let T=J.join(F[0]??sr(),y.name),v=J.join(T,"SKILL.md");switch(y.action){case"create":return await $.promises.mkdir(T,{recursive:!0}),await $.promises.writeFile(v,y.content??"","utf8"),{success:!0,message:`Skill "${y.name}" created`,path:T};case"edit":return await $.promises.writeFile(v,y.content??"","utf8"),{success:!0,message:`Skill "${y.name}" updated`,path:v};case"patch":{let _=await $.promises.readFile(v,"utf8");return!y.oldString||!_.includes(y.oldString)?{success:!1,message:"oldString not found in SKILL.md"}:(await $.promises.writeFile(v,_.replace(y.oldString,y.newString??""),"utf8"),{success:!0,message:`Skill "${y.name}" patched`,path:v})}case"delete":return await $.promises.rm(T,{recursive:!0,force:!0}),{success:!0,message:`Skill "${y.name}" deleted`};default:return{success:!1,message:`Unknown action: ${y.action}`}}}})),ce(Hc({abortSignal:void 0,currentForkDepth:0,forkAgent:async y=>{let T=jo(y.agent);if(!T)return{agentId:"",status:"failed",error:`Unknown agent type: ${y.agent}`};if(!this.agent||!this.currentTransport||!this.currentApiKey||!this.currentModel)return{agentId:"",status:"failed",error:"No LLM provider configured"};let v=Be(),_=No(v,T),I=We().filter(P=>_.includes(P.function.name)),V=Sr(I,!0),j=y.maxTurns??T.maxTurns??200,se=await An({promptMessages:[{role:"user",content:y.prompt}],tools:V,transport:this.currentTransport,toolInvoker:u,apiKey:this.currentApiKey,model:this.currentModel,log:l,hooks:c,forkLabel:`agent-${y.agent}`,maxTurns:j,parentSignal:y.abortSignal,parentDepth:0,onEvent:P=>{P.type==="delta"&&P.text&&this.sendNotification("turn.subagent_delta",{agentType:y.agent,text:P.text})}}),X=se.events.filter(P=>P.type==="end"&&"content"in P).map(P=>P.content??"").join("")||se.events.filter(P=>P.type==="delta"&&"text"in P).map(P=>P.text).join("");return{agentId:`fork-${y.agent}-${ve().slice(0,8)}`,status:se.ok?"completed":"failed",output:X||void 0,error:se.error,tokensUsed:se.totalUsage.prompt+se.totalUsage.completion}}}));let U=pt(),D=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"]}]]),w=async()=>{try{return JSON.parse(await $.promises.readFile(U,"utf8"))}catch{return{}}},ge=async y=>{await $.promises.mkdir(J.dirname(U),{recursive:!0}),await $.promises.writeFile(U,JSON.stringify(y,null,2),"utf8")};ce(zc({getConfig:async y=>{let T=D.get(y);if(!T)return{success:!1,error:`Unknown key: ${y}`};let v=await w(),_=y in v?v[y]:T.value;return{success:!0,setting:{...T,value:_,readOnly:Xt.includes(y)}}},setConfig:async(y,T)=>{let v=D.get(y);if(!v)return{success:!1,error:`Unknown key: ${y}`};let _=await w(),C=y in _?_[y]:v.value;return _[y]=T,await ge(_),{success:!0,previousValue:C,setting:{...v,value:T}}},listConfig:async()=>{let y=await w();return{success:!0,settings:[...D.values()].map(v=>({...v,value:v.key in y?y[v.key]:v.value,readOnly:Xt.includes(v.key)}))}},resetConfig:async y=>{let T=D.get(y);if(!T)return{success:!1,error:`Unknown key: ${y}`};let v=await w();return delete v[y],await ge(v),{success:!0,setting:T}},isValidKey:y=>D.has(y)}));let H=new Map,z=y=>{let T=/^(\d+)([smhd])$/.exec(y.trim());if(!T)return null;let v=parseInt(T[1],10),_=T[2];return v*({s:1e3,m:6e4,h:36e5,d:864e5}[_]??6e4)},fe=y=>{y.timerId&&clearTimeout(y.timerId);let T=z(y.schedule);T&&(y.timerId=setTimeout(()=>{y.lastRunAt=new Date().toISOString(),y.repeat.completed++,y.lastStatus="success",l.info(`[cron] triggered job ${y.id} (${y.name})`),y.repeat.times===null||y.repeat.completed<y.repeat.times?fe(y):(y.state="paused",y.enabled=!1)},T),y.nextRunAt=new Date(Date.now()+T).toISOString())};it(async()=>{for(let y of H.values())y.timerId&&clearTimeout(y.timerId)}),ce(qc({createJob:async y=>{let T=`cron_${ve().slice(0,8)}`,v={id:T,name:y.name??`Job ${T}`,prompt:y.prompt,schedule:y.schedule,scheduleDisplay:y.schedule,state:"scheduled",enabled:!0,repeat:{times:y.repeat??null,completed:0},allowedTools:y.allowedTools};return H.set(T,v),fe(v),{success:!0,job:{...v,timerId:void 0}}},listJobs:async()=>({success:!0,jobs:[...H.values()].map(T=>({...T,timerId:void 0}))}),getJob:async y=>{let T=H.get(y);return T?{success:!0,job:{...T,timerId:void 0}}:{success:!1,error:`Job not found: ${y}`}},updateJob:async(y,T)=>{let v=H.get(y);return v?(T.prompt!==void 0&&(v.prompt=T.prompt),T.schedule!==void 0&&(v.schedule=T.schedule,v.scheduleDisplay=T.schedule),T.name!==void 0&&(v.name=T.name),T.enabled!==void 0&&(v.enabled=T.enabled,v.state=T.enabled?"scheduled":"paused"),T.repeat!==void 0&&(v.repeat.times=T.repeat),T.allowedTools!==void 0&&(v.allowedTools=T.allowedTools),v.enabled?fe(v):v.timerId&&(clearTimeout(v.timerId),v.timerId=void 0),{success:!0,job:{...v,timerId:void 0}}):{success:!1,error:`Job not found: ${y}`}},deleteJob:async y=>{let T=H.get(y);return T?(T.timerId&&clearTimeout(T.timerId),H.delete(y),{success:!0}):{success:!1,error:`Job not found: ${y}`}},pauseJob:async y=>{let T=H.get(y);return T?(T.state="paused",T.enabled=!1,T.timerId&&(clearTimeout(T.timerId),T.timerId=void 0),{success:!0,job:{...T,timerId:void 0}}):{success:!1,error:`Job not found: ${y}`}},resumeJob:async y=>{let T=H.get(y);return T?(T.state="scheduled",T.enabled=!0,fe(T),{success:!0,job:{...T,timerId:void 0}}):{success:!1,error:`Job not found: ${y}`}},triggerJob:async y=>{let T=H.get(y);return T?(T.lastRunAt=new Date().toISOString(),T.repeat.completed++,T.lastStatus="success",{success:!0,job:{...T,timerId:void 0}}):{success:!1,error:`Job not found: ${y}`}},validateSchedule:y=>z(y)!==null||/^\d{1,2}\s/.test(y)?null:`Invalid schedule: ${y}. Use shorthand (5m, 1h, 1d) or cron expression.`}));let te=new Map;it(async()=>{for(let y of te.values())y.cleanup();te.clear()}),ce(Kc({startMonitor:async y=>{if(te.has(y.monitorId))return{action:"start",success:!1,error:`Monitor "${y.monitorId}" already exists.`};let T={monitorId:y.monitorId,source:y.source,target:y.target,conditions:y.conditions,startedAt:Date.now(),timeoutSeconds:y.timeoutSeconds,eventCount:0},v=()=>{};if(y.source==="file")try{let _=$.watch(y.target,{persistent:!1},()=>{T.eventCount++,l.info(`[monitor] file change detected: ${y.target}`)});v=()=>_.close()}catch{return{action:"start",success:!1,error:`Cannot watch: ${y.target}`}}if(y.timeoutSeconds>0){let _=setTimeout(()=>{let I=te.get(y.monitorId);I&&(I.cleanup(),te.delete(y.monitorId))},y.timeoutSeconds*1e3),C=v;v=()=>{clearTimeout(_),C()}}return te.set(y.monitorId,{info:T,cleanup:v}),{action:"start",success:!0,monitorId:y.monitorId}},stopMonitor:async y=>{let T=te.get(y);return T?(T.cleanup(),te.delete(y),{action:"stop",success:!0,monitorId:y}):{action:"stop",success:!1,error:`Monitor "${y}" not found.`}},listMonitors:async()=>[...te.values()].map(y=>y.info)}));let le=new Map,G={info:y=>l.info(y),warn:y=>l.warn(y)},N=new yt({onNotification:(y,T,v)=>{this.sendNotification("team.member.notification",{memberId:y,method:T,params:v})},onStateChange:(y,T)=>{this.sendNotification("team.member.state",{memberId:y,state:T});let v=N.getHandle(y),C=N.getUsageTracker(y)?.getUsage();this.emitAgentStatus(y,T,{missedBeats:N.getMissedBeats(y),lastActivityAt:v?.lastActivityAt,usage:C&&C.totalTokens>0?{inputTokens:C.inputTokens,outputTokens:C.outputTokens,totalTokens:C.totalTokens}:void 0})},onExit:(y,T,v)=>{for(let _ of le.values()){let C=_.members.find(I=>I.cwd&&`team-${_.name}-${I.name}`.replace(/[^a-zA-Z0-9-]/g,"-").toLowerCase()===y.replace(/^team-/,""));C&&(C.isActive=!1)}l.info(`[team] member ${y} exited (code=${T}, signal=${v})`)},onMcpToolCall:(y,T,v)=>this.handleMcpToolCall(y,T,v),log:{info:y=>l.info(y),warn:y=>l.warn(y),debug:y=>l.debug(y)},sessionDir:J.join(B(),"agent-logs")});it(async()=>{N.dispose()}),ce(Jc({createTeam:async y=>{if(le.has(y.teamName))return{success:!1,error:`Team "${y.teamName}" already exists.`};let T=await qt(),v=[];for(let C of y.members??[]){let I={...C,isActive:!0};if(T){let V=`team-${y.teamName}-${C.name}`.replace(/[^a-zA-Z0-9-]/g,"-").toLowerCase(),j=await jl(T,V,G);j?(I.worktreePath=j.worktreePath,I.worktreeBranch=j.branch,I.cwd=j.worktreePath,l.info(`[team] provisioned worktree for ${C.name}: ${j.worktreePath}`)):(I.cwd=process.cwd(),l.warn(`[team] worktree provision failed for ${C.name}, using shared cwd`))}else I.cwd=process.cwd();v.push(I)}let _={name:y.teamName,description:y.description,leadId:this.currentSessionId??"default",members:v,createdAt:new Date().toISOString()};le.set(y.teamName,_);for(let C of v){if(!C.cwd)continue;let I=`team-${y.teamName}-${C.name}`.replace(/[^a-zA-Z0-9-]/g,"-").toLowerCase();try{await N.spawn({memberId:I,name:C.name,cwd:C.cwd,prompt:`You are the "${C.name}" team member. Role: ${C.role}.`,agentType:C.role,verbose:this.verbose}),l.info(`[team] spawned child process for ${C.name} in ${C.cwd}`)}catch(V){l.warn(`[team] failed to spawn child process for ${C.name}: ${V instanceof Error?V.message:String(V)}`),C.isActive=!1}}return this.sendNotification("team.updated",{teamName:y.teamName,action:"created",members:_.members.map(C=>({agentName:C.name,role:C.role,worktreePath:C.worktreePath,pid:N.getHandle(`team-${y.teamName}-${C.name}`.replace(/[^a-zA-Z0-9-]/g,"-").toLowerCase())?.pid}))}),{success:!0,team:_}},deleteTeam:async y=>{let T=le.get(y);if(!T)return{success:!1,error:`Team "${y}" not found.`};for(let _ of T.members){let C=`team-${y}-${_.name}`.replace(/[^a-zA-Z0-9-]/g,"-").toLowerCase();N.kill(C),N.remove(C)}let v=await qt();if(v)for(let _ of T.members)_.worktreePath&&_.worktreeBranch&&(await Bl(v,_.worktreePath,_.worktreeBranch,G),l.info(`[team] cleaned up worktree for ${_.name}: ${_.worktreePath}`));return le.delete(y),this.sendNotification("team.updated",{teamName:y,action:"destroyed",members:[]}),{success:!0}},listTeams:async()=>({success:!0,teams:[...le.values()]}),getTeamStatus:async y=>{let T=le.get(y);if(!T)return{success:!1,error:`Team "${y}" not found.`};let v={};for(let _ of T.members){let C=`team-${y}-${_.name}`.replace(/[^a-zA-Z0-9-]/g,"-").toLowerCase(),I=N.getStatus(C);I&&(_.isActive=I.alive,v[_.name]={mediaProgress:I.mediaProgress,lastToolCall:I.lastToolCall,idleFor:I.idleFor,runningFor:I.runningFor})}return{success:!0,team:T,memberProgress:v}}}));{let y=new uo({persistToDisk:!0});y.loadFromDiskSync();let T={providerId:"null",search:async()=>[],ingest:async()=>{}},v=this.qmemoryAdapter??T;ce({name:yu,label:Tu,description:ku,parameters:bu,execute:async(_,C)=>{let I=await wu(C,{provider:v,store:y,userId:this.qmemoryUserId||this.currentSessionId||"default",sessionId:this.currentSessionId});return{content:[{type:"text",text:I.message}],details:{type:"memory",action:I.action,ok:I.ok}}}})}{let y=e?.workdir??process.cwd(),T=Zc(y,this.currentSessionId||"default");ce(Qc(T))}let pe=e?.workdir??process.cwd(),Ee=Su({projectRoot:pe,ruleEngine:R,hooks:c,log:y=>l.info(`[settings] ${y}`)});it(async()=>{Ee()}),this.currentSessionId&&c.invoke("session.created",{sessionId:this.currentSessionId}).catch(()=>{}),this.fileWatcher&&this.fileWatcher.stop();let me=e?.workdir??process.cwd();return La({projectRoot:me,sessionId:this.currentSessionId,hooks:c,log:y=>l.debug(y),onInstructionCacheReset:Fa}).then(y=>{this.fileWatcher=y,it(async()=>{this.fileWatcher?.stop()})}).catch(y=>{l.warn(`[file-watcher] init error: ${y instanceof Error?y.message:y}`)}),this.agent=new dt({llmTransport:a.transport,apiKey:a.apiKey,toolInvoker:u,log:l,hooks:c,maxRounds:e.maxRounds,verbose:this.verbose}),this.lastLlmConfigKey=t,this.currentTransport=a.transport,this.currentApiKey=a.apiKey,this.currentModel=o,this.log(`created Agent (provider: ${n}, model: ${o})`),this.agent}loadSettingsSync(){try{let e=pt();if(!$.existsSync(e))return;let t=$.readFileSync(e,"utf-8"),n=JSON.parse(t);return{provider:n.provider,model:n.model,apiKey:n.apiKey,baseUrl:n.baseUrl}}catch{return}}handleSessionGetInfo(e){let t=this.currentSessionId||"default",n=this.sessionState?.createSnapshot(),o={sessionId:t,model:this.currentModel||void 0,cwd:process.cwd(),paths:{sessionDir:Di(t),agentHome:B(),settings:pt()},usage:n?{turnCount:n.turnCount,inputTokens:n.totalInputTokens,outputTokens:n.totalOutputTokens}:void 0};e.id!==void 0&&this.sendResponse(e.id,o)}async handleMemoryList(e){let t=[],n=J.join(B(),"memory.json");$.existsSync(n)&&t.push({id:"local",type:"json",path:n}),this.qmemoryAdapter&&t.push({id:"qmemory",type:"vector"}),e.id!==void 0&&this.sendResponse(e.id,{sources:t})}async handleMemoryRead(e){let t=e.params,n=t?.source??"local",o=t?.target??"memory";if(n==="local")try{let s=J.join(B(),"memory.json"),i=await $.promises.readFile(s,"utf-8"),a=JSON.parse(i);e.id!==void 0&&this.sendResponse(e.id,{source:"local",target:o,content:a[o]??""})}catch{e.id!==void 0&&this.sendResponse(e.id,{source:"local",target:o,content:""})}else e.id!==void 0&&this.sendResponse(e.id,void 0,{code:M.INVALID_PARAMS,message:`Unknown memory source: ${n}`})}async handleMemoryWrite(e){let t=e.params,n=t?.target??"memory",o=t?.content;if(n!=="memory"&&n!=="user"){e.id!==void 0&&this.sendResponse(e.id,void 0,{code:M.INVALID_PARAMS,message:`Invalid memory target: ${n}. Must be "memory" or "user".`});return}if(o==null){e.id!==void 0&&this.sendResponse(e.id,void 0,{code:M.INVALID_PARAMS,message:"content is required."});return}try{let s=J.join(B(),"memory.json"),i={};try{let a=await $.promises.readFile(s,"utf-8");i=JSON.parse(a)}catch{}i[n]=o,i.savedAt=new Date().toISOString(),await $.promises.mkdir(B(),{recursive:!0}),await $.promises.writeFile(s,JSON.stringify(i,null,2),"utf-8"),e.id!==void 0&&this.sendResponse(e.id,{ok:!0,target:n}),this.sendNotification("memory.updated",{target:n,source:"rpc"})}catch(s){e.id!==void 0&&this.sendResponse(e.id,void 0,{code:M.INTERNAL_ERROR,message:s instanceof Error?s.message:String(s)})}}handleToolsList(e){let t=e.params,o=We(t?.includeDeferred??!1).map(s=>({name:s.function.name,description:s.function.description??"",parameters:s.function.parameters,source:"builtin"}));if(t?.category){let s=o.filter(i=>i.name.startsWith(t.category)||i.description.toLowerCase().includes(t.category.toLowerCase()));e.id!==void 0&&this.sendResponse(e.id,{tools:s,total:s.length})}else e.id!==void 0&&this.sendResponse(e.id,{tools:o,total:o.length})}handleMediaListModels(e){let n=e.params?.mediaType,s=this.mediaClient.listMediaModels(n).map(i=>({providerId:i.providerId,providerName:i.providerDef.name,modelId:i.modelInfo.id,modelName:i.modelInfo.name,mediaType:i.mediaType,capabilities:i.modelInfo.mediaCapabilities}));e.id!==void 0&&this.sendResponse(e.id,{models:s})}async handleMediaCancel(e){let t=e.params;if(!t?.taskId){e.id!==void 0&&this.sendResponse(e.id,void 0,{code:M.INVALID_PARAMS,message:"taskId is required."});return}let n=t.provider??"doubao",o=this.mediaClient.getTransport(n);if(!o){e.id!==void 0&&this.sendResponse(e.id,{ok:!1,message:`No transport for provider: ${n}`});return}if(!gr(o)){e.id!==void 0&&this.sendResponse(e.id,{ok:!1,message:`Provider ${n} does not support task cancellation.`});return}try{let s=this.resolveMediaApiKey(n);if(!s){e.id!==void 0&&this.sendResponse(e.id,{ok:!1,message:`No API key for provider: ${n}`});return}await o.deleteVideoTask(t.taskId,s),e.id!==void 0&&this.sendResponse(e.id,{ok:!0,taskId:t.taskId,message:"Task cancelled."})}catch(s){e.id!==void 0&&this.sendResponse(e.id,{ok:!1,message:s instanceof Error?s.message:String(s)})}}async handleMediaStatus(e){let t=e.params;if(!t?.taskId){e.id!==void 0&&this.sendResponse(e.id,void 0,{code:M.INVALID_PARAMS,message:"taskId is required."});return}let n=t.provider??"doubao",o=this.mediaClient.getTransport(n);if(!o){e.id!==void 0&&this.sendResponse(e.id,{ok:!1,message:`No transport for provider: ${n}`});return}if(!gr(o)){e.id!==void 0&&this.sendResponse(e.id,{ok:!1,message:`Provider ${n} does not support task status queries.`});return}try{let s=this.resolveMediaApiKey(n);if(!s){e.id!==void 0&&this.sendResponse(e.id,{ok:!1,message:`No API key for provider: ${n}`});return}if(o.getTaskStatus){let{status:u,task:c}=await o.getTaskStatus(t.taskId,s);e.id!==void 0&&this.sendResponse(e.id,{ok:!0,taskId:t.taskId,status:u,task:c});return}let i=await o.listVideoTasks(s,{limit:100}),l=(i.data??i.tasks??[]).find(u=>u.id===t.taskId||u.task_id===t.taskId);e.id!==void 0&&this.sendResponse(e.id,{ok:!0,taskId:t.taskId,...l?{status:l.status,task:l}:{status:"unknown",message:"Task not found in recent list."}})}catch(s){e.id!==void 0&&this.sendResponse(e.id,{ok:!1,message:s instanceof Error?s.message:String(s)})}}resolveMediaApiKey(e){return this.currentMediaApiKeys?.[e]}handleProviderList(e){let t=this.registry.listProviders(),n=new Map;for(let s of t){let i=s.group??s.id;n.has(i)||n.set(i,[]);let a=!!this.registry.resolveApiKey(s.id);n.get(i).push({id:s.id,name:s.name,transport:s.transport,baseUrl:s.baseUrl,defaultModel:s.defaultModel,modelCount:s.models?.length??0,available:a})}let o=[...n.entries()].map(([s,i])=>({group:s,variants:i}));e.id!==void 0&&this.sendResponse(e.id,{providers:o})}handleConfigGet(e){try{let t=pt(),n={};if($.existsSync(t)){let o=$.readFileSync(t,"utf-8");n=JSON.parse(o)}e.id!==void 0&&this.sendResponse(e.id,{config:n,paths:{userSettings:t,agentHome:B()}})}catch(t){e.id!==void 0&&this.sendResponse(e.id,void 0,{code:M.INTERNAL_ERROR,message:t instanceof Error?t.message:String(t)})}}async handleConfigUpdate(e){let t=e.params;if(!t?.updates||typeof t.updates!="object"){e.id!==void 0&&this.sendResponse(e.id,void 0,{code:M.INVALID_PARAMS,message:"updates (object) is required."});return}try{let n=pt(),o={};try{let s=await $.promises.readFile(n,"utf-8");o=JSON.parse(s)}catch{}Object.assign(o,t.updates),await $.promises.mkdir(J.dirname(n),{recursive:!0}),await $.promises.writeFile(n,JSON.stringify(o,null,2),"utf-8"),e.id!==void 0&&this.sendResponse(e.id,{ok:!0})}catch(n){e.id!==void 0&&this.sendResponse(e.id,void 0,{code:M.INTERNAL_ERROR,message:n instanceof Error?n.message:String(n)})}}async handleTodosList(e){let t=ke("todo");if(!t){e.id!==void 0&&this.sendResponse(e.id,{items:[],summary:ft([])});return}try{let o=(await t.execute("rpc-todos-list",{action:"list"},void 0)).content.map(a=>a.text??"").join(""),i=JSON.parse(o).todoList??[];e.id!==void 0&&this.sendResponse(e.id,{items:i,summary:ft(i)})}catch{e.id!==void 0&&this.sendResponse(e.id,{items:[],summary:ft([])})}}async handleMemorySearch(e){let t=e.params;if(!t?.query){e.id!==void 0&&this.sendResponse(e.id,void 0,{code:M.INVALID_PARAMS,message:"query is required."});return}if(!this.qmemoryAdapter){try{let n=J.join(B(),"memory.json"),o=await $.promises.readFile(n,"utf-8"),s=JSON.parse(o),i=[],a=t.query.toLowerCase();for(let[l,u]of Object.entries(s)){if(typeof u!="string")continue;let c=u.split(`
426
+ `),error:E.details?.error}}catch(R){return{result:"",error:R instanceof Error?R.message:String(R)}}}},tools:We(),apiKey:this.currentApiKey,model:c.model??this.currentModel,log:{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}`)}},hooks:this.currentHooks??void 0,parentSignal:u.signal,qmemoryAdapter:this.qmemoryAdapter??void 0,qmemoryUserId:this.qmemoryUserId||void 0},m=await _a(p);m.ok?this.sendNotification("turn.end",{turnId:n,content:`Dream consolidation completed. ${m.sessionsReviewed} sessions reviewed, ${m.filesTouched.length} files touched. Duration: ${m.durationMs}ms.`,usage:{prompt:0,completion:0}}):this.sendNotification("turn.error",{turnId:n,error:m.error??"Dream consolidation failed",code:"DREAM_FAILED"}),this.log(`dream ${n} completed`)}catch(p){if(u.signal.aborted)this.sendNotification("turn.error",{turnId:n,error:"Dream aborted",code:"ABORTED"});else{let m=p instanceof Error?p.message:String(p);this.sendNotification("turn.error",{turnId:n,error:m,code:"INTERNAL_ERROR"})}}finally{this.activeTurn===u&&(this.activeTurn=null)}}resolveAgent(e){let t=`${e.provider??""}:${e.model??""}:${e.apiKey?.slice(0,8)??""}:${e.baseUrl??""}`;if(this.agent&&this.lastLlmConfigKey===t)return this.agent;let n=e.provider,o=e.model,s=e.apiKey,i=e.baseUrl;if(!n||!s){let y=_n(this.registry);y&&(n=n??y.providerId,s=s??y.apiKey,o=o??y.defaultModel,this.log(`auto-detected provider: ${n}, model: ${o}`))}if(!n||!s){let y=this.loadSettingsSync();y&&(n=n??y.provider,s=s??y.apiKey,o=o??y.model,n&&s&&this.log(`loaded provider from settings.json: ${n}, model: ${o}`))}if(!n||!s)return null;o=o??this.registry.getProvider(n)?.defaultModel??"";let a=Rn({provider:n,model:o,apiKey:s,baseUrl:i},this.registry);pr()&&(a.transport=mr(a.transport,this.currentSessionId||"default"));let l={info:y=>this.log(y),warn:y=>this.log(`[warn] ${y}`),error:y=>this.log(`[error] ${y}`),debug:y=>{this.verbose&&this.log(`[debug] ${y}`)}},u={invoke:async(y,T,v,_)=>{if(T.startsWith("$"))return{result:v};let C=ke(T);if(!C)return{result:"",error:`Unknown tool: ${T}`};let I=`tc_${ve().slice(0,8)}`;try{let V=JSON.parse(v),j=await C.execute(I,V,_),re=j.content.map(ie=>ie.text??"").join(`
427
+ `),X=j.details?.error,P=j.details?.type,se=P?.split("_")[0];if(se&&["image","tts","video","music"].includes(se)){let ie=j.details?.mediaUrls??[],we=se;for(let ln of ie)this.sendNotification("turn.media_result",{turnId:y,mediaType:we,url:ln,model:j.details?.model,provider:j.details?.provider,...j.details?.durationMs?{durationSeconds:j.details.durationMs/1e3}:{},...j.details?.taskId?{taskId:j.details.taskId}:{}})}if(P==="todo"&&!X)try{let ie=JSON.parse(re);ie.todoList&&this.sendNotification("turn.todos_updated",{turnId:y,items:ie.todoList,summary:{total:ie.total??ie.todoList.length,completed:ie.completed??0,inProgress:ie.inProgress??0,notStarted:ie.notStarted??0}})}catch{}return{result:re,error:X}}catch(V){return{result:"",error:V instanceof Error?V.message:String(V)}}}},c=fr(l);this.currentHooks=c,this.taskStore.setHooks(c,this.currentSessionId??"");let d=(process.env.QMEMORY_BASE_URL??process.env.QLOGICAGENT_QMEMORY_BASE_URL??"").trim().replace(/\/+$/,"");if(d){let y=la({baseUrl:d,apiKey:(process.env.QMEMORY_API_KEY??"").trim()||void 0,timeoutMs:5e3});this.qmemoryAdapter=y,this.qmemoryUserId=this.currentSessionId??"default",ia(c,{memoryProvider:y,userId:this.currentSessionId??"default",log:{debug:T=>l.debug(T),warn:T=>l.warn(T)}},this.memoryPrefetchState)}Ri(c,l,{transport:a.transport,apiKey:a.apiKey});let p=e?.mcpServers,m=is(p??{}),g=Bi();try{if($.existsSync(g)){let y=JSON.parse($.readFileSync(g,"utf8")),T=is(y),v=new Set(m.map(_=>_.name));m=[...m,...T.filter(_=>!v.has(_.name))]}}catch{}if(m.length>0){this.mcpManager&&this.mcpManager.disconnectAll().catch(()=>{}),this.mcpManager=new Xn({servers:m,log:l}),it(async()=>{await this.mcpManager?.disconnectAll()});let y=()=>this.mcpManager;ce(Rc(y)),ce(_c(y)),ce(Yc({listServers:async()=>{let T=this.mcpManager;return T?T.getConnectedServers().map(_=>({name:_,status:"connected",transport:"stdio",toolCount:0,resourceCount:0,promptCount:0})):[]},listTools:async T=>{if(!this.mcpManager)return[];let _=`mcp__${T.replace(/[^a-zA-Z0-9_]/g,"_").toLowerCase()}__`;return Be().filter(C=>C.startsWith(_)).map(C=>({name:C.slice(_.length),prefixedName:C}))},callTool:async(T,v,_,C)=>{let V=`mcp__${T.replace(/[^a-zA-Z0-9_]/g,"_").toLowerCase()}__`+v,j=ke(V);if(!j)return{success:!1,error:`Tool not found: ${V}`};try{return{success:!0,content:(await j.execute(`mcp_${Date.now()}`,_??{},C)).content.map(P=>P.text??"").join(`
428
+ `)}}catch(re){return{success:!1,error:re.message}}},listResources:async T=>{let v=this.mcpManager;return v?(await v.listResources(T)).map(C=>({uri:C.uri,name:C.name,mimeType:C.mimeType,description:C.description,server:C.server})):[]},readResource:async(T,v)=>{let _=this.mcpManager;if(!_)throw new Error("MCP not initialized");return(await _.readResource(T,v)).map(I=>({uri:I.uri,mimeType:I.mimeType,text:I.text}))},authenticate:async()=>({status:"unsupported",message:"OAuth not yet implemented in McpManager"})})),this.mcpManager.connectAll().then(()=>{this.mcpManager?.injectTools(),l.info(`[mcp] ${this.mcpManager?.getToolCount()??0} tools from ${this.mcpManager?.getConnectedServers().length??0} servers`)}).catch(T=>{l.warn(`[mcp] connection error: ${T instanceof Error?T.message:T}`)})}let f=[],b=Ui();$.existsSync(b)&&f.push(b);let h=e?.pluginPaths;if(Array.isArray(h))for(let y of h)typeof y=="string"&&$.existsSync(y)&&f.push(y);Pc(f,l).then(y=>{if(y.length===0)return;this.pluginLoader=new Zn({pluginDirs:y,hookRegistry:c,log:l}),this.pluginLoader.loadAll().then(v=>{l.info(`[plugins] ${v.length} loaded, ${this.pluginLoader?.getPluginSkills().length??0} skills`)}).catch(v=>{l.warn(`[plugins] load error: ${v instanceof Error?v.message:v}`)});let T=this.pluginLoader;c.register({point:"turn.submitted",handler:async()=>(await T.refreshActivations(),{action:"continue"}),label:"plugin-activation-refresh",priority:50})}).catch(y=>{l.warn(`[plugins] marketplace resolve error: ${y instanceof Error?y.message:y}`)});let k=e?.permissions,x=ls(k),R=new eo(x);this.permissionUnregister&&this.permissionUnregister(),this.permissionChecker=new no({ruleEngine:R,hookRegistry:c,onRequestApproval:async y=>(this.sendNotification("tool.approval.request",{approvalId:y.approvalId,callId:y.callId,toolName:y.toolName,arguments:y.arguments?JSON.stringify(y.arguments):"",message:y.message,suggestions:y.suggestions?.map(T=>`${T.pattern}:${T.behavior}`)}),new Promise(()=>{})),onPermissionUpdate:y=>{l.info(`[permissions] rule saved: ${y.pattern} \u2192 ${y.behavior}`),this.sendNotification("permission.rule_updated",{pattern:y.pattern,behavior:y.behavior})},onDenied:(y,T)=>{l.warn(`[permissions] blocked "${y}": ${T}`)}});let E=We();this.permissionChecker.setToolMeta(E),this.permissionUnregister=this.permissionChecker.register();let F=[sr(),...Array.isArray(e?.skillPaths)?e.skillPaths:[]];ce(Bc({listSkills:()=>{let y=[];this.pluginLoader&&y.push(...this.pluginLoader.getPluginSkills());let T=e?.skillPaths;if(Array.isArray(T)){for(let v of T)if(typeof v=="string"){let _=J.basename(v);y.some(C=>C.name===_)||y.push({name:_,source:"gateway",filePath:J.join(v,"SKILL.md"),baseDir:v})}}return y},listSkillsFull:async y=>{let T=[],v=new Set;for(let _ of F)try{let C=await $.promises.readdir(_,{withFileTypes:!0});for(let I of C){if(!I.isDirectory())continue;let V=J.join(_,I.name,"SKILL.md");try{await $.promises.access(V);let j=J.basename(_);if(y&&j!==y)continue;v.add(j),T.push({name:I.name,description:`Skill from ${_}`,category:j})}catch{}}}catch{}if(this.pluginLoader)for(let _ of this.pluginLoader.getPluginSkills())y&&_.source!==y||(v.add(_.source??"plugin"),T.push({name:_.name,description:`Plugin skill (${_.source})`,category:_.source}));return{skills:T,categories:[...v]}},readSkillContent:async y=>{for(let T of F){let v=J.join(T,y,"SKILL.md");try{return await $.promises.readFile(v,"utf8")}catch{}}return null},viewSkill:async(y,T)=>{for(let v of F){let _=T?J.join(v,y,T):J.join(v,y,"SKILL.md");try{let C=await $.promises.readFile(_,"utf8");return{name:y,content:C}}catch{}}return null},executeSkillSubturn:async(y,T,v,_)=>{let C=`skill_${y}_${ve().slice(0,8)}`,I=this.agent;if(!I)return"[skill] Cannot execute: no LLM provider configured";let V=this.currentSessionId??"skill";this.currentHooks?.invoke("subagent.started",{sessionId:V,turnId:C,subagentId:C,agentType:`skill:${y}`}).catch(()=>{});let j=We(),re=v??`Execute skill "${y}" instructions.`,X=[],P;for await(let se of I.run({turnId:C,sessionId:V,messages:[{role:"user",content:re}],tools:j,systemPrompt:T,config:{parentDepth:1}},_)){if(se.type==="end"&&se.content)return this.currentHooks?.invoke("subagent.stopped",{sessionId:V,turnId:C,subagentId:C,agentType:`skill:${y}`,reason:"normal"}).catch(()=>{}),se.content;if(se.type==="delta"&&se.text&&X.push(se.text),se.type==="error"){P=se.error;break}}return this.currentHooks?.invoke("subagent.stopped",{sessionId:V,turnId:C,subagentId:C,agentType:`skill:${y}`,reason:P?"error":"normal",error:P}).catch(()=>{}),P?`[skill "${y}"] error: ${P}`:X.join("")||`[skill "${y}"] completed (no output)`},manageSkill:async y=>{let T=J.join(F[0]??sr(),y.name),v=J.join(T,"SKILL.md");switch(y.action){case"create":return await $.promises.mkdir(T,{recursive:!0}),await $.promises.writeFile(v,y.content??"","utf8"),{success:!0,message:`Skill "${y.name}" created`,path:T};case"edit":return await $.promises.writeFile(v,y.content??"","utf8"),{success:!0,message:`Skill "${y.name}" updated`,path:v};case"patch":{let _=await $.promises.readFile(v,"utf8");return!y.oldString||!_.includes(y.oldString)?{success:!1,message:"oldString not found in SKILL.md"}:(await $.promises.writeFile(v,_.replace(y.oldString,y.newString??""),"utf8"),{success:!0,message:`Skill "${y.name}" patched`,path:v})}case"delete":return await $.promises.rm(T,{recursive:!0,force:!0}),{success:!0,message:`Skill "${y.name}" deleted`};default:return{success:!1,message:`Unknown action: ${y.action}`}}}})),ce(Hc({abortSignal:void 0,currentForkDepth:0,forkAgent:async y=>{let T=jo(y.agent);if(!T)return{agentId:"",status:"failed",error:`Unknown agent type: ${y.agent}`};if(!this.agent||!this.currentTransport||!this.currentApiKey||!this.currentModel)return{agentId:"",status:"failed",error:"No LLM provider configured"};let v=Be(),_=No(v,T),I=We().filter(P=>_.includes(P.function.name)),V=Sr(I,!0),j=y.maxTurns??T.maxTurns??200,re=await An({promptMessages:[{role:"user",content:y.prompt}],tools:V,transport:this.currentTransport,toolInvoker:u,apiKey:this.currentApiKey,model:this.currentModel,log:l,hooks:c,forkLabel:`agent-${y.agent}`,maxTurns:j,parentSignal:y.abortSignal,parentDepth:0,onEvent:P=>{P.type==="delta"&&P.text&&this.sendNotification("turn.subagent_delta",{agentType:y.agent,text:P.text})}}),X=re.events.filter(P=>P.type==="end"&&"content"in P).map(P=>P.content??"").join("")||re.events.filter(P=>P.type==="delta"&&"text"in P).map(P=>P.text).join("");return{agentId:`fork-${y.agent}-${ve().slice(0,8)}`,status:re.ok?"completed":"failed",output:X||void 0,error:re.error,tokensUsed:re.totalUsage.prompt+re.totalUsage.completion}}}));let U=pt(),D=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"]}]]),w=async()=>{try{return JSON.parse(await $.promises.readFile(U,"utf8"))}catch{return{}}},ge=async y=>{await $.promises.mkdir(J.dirname(U),{recursive:!0}),await $.promises.writeFile(U,JSON.stringify(y,null,2),"utf8")};ce(zc({getConfig:async y=>{let T=D.get(y);if(!T)return{success:!1,error:`Unknown key: ${y}`};let v=await w(),_=y in v?v[y]:T.value;return{success:!0,setting:{...T,value:_,readOnly:Xt.includes(y)}}},setConfig:async(y,T)=>{let v=D.get(y);if(!v)return{success:!1,error:`Unknown key: ${y}`};let _=await w(),C=y in _?_[y]:v.value;return _[y]=T,await ge(_),{success:!0,previousValue:C,setting:{...v,value:T}}},listConfig:async()=>{let y=await w();return{success:!0,settings:[...D.values()].map(v=>({...v,value:v.key in y?y[v.key]:v.value,readOnly:Xt.includes(v.key)}))}},resetConfig:async y=>{let T=D.get(y);if(!T)return{success:!1,error:`Unknown key: ${y}`};let v=await w();return delete v[y],await ge(v),{success:!0,setting:T}},isValidKey:y=>D.has(y)}));let H=new Map,z=y=>{let T=/^(\d+)([smhd])$/.exec(y.trim());if(!T)return null;let v=parseInt(T[1],10),_=T[2];return v*({s:1e3,m:6e4,h:36e5,d:864e5}[_]??6e4)},fe=y=>{y.timerId&&clearTimeout(y.timerId);let T=z(y.schedule);T&&(y.timerId=setTimeout(()=>{y.lastRunAt=new Date().toISOString(),y.repeat.completed++,y.lastStatus="success",l.info(`[cron] triggered job ${y.id} (${y.name})`),y.repeat.times===null||y.repeat.completed<y.repeat.times?fe(y):(y.state="paused",y.enabled=!1)},T),y.nextRunAt=new Date(Date.now()+T).toISOString())};it(async()=>{for(let y of H.values())y.timerId&&clearTimeout(y.timerId)}),ce(qc({createJob:async y=>{let T=`cron_${ve().slice(0,8)}`,v={id:T,name:y.name??`Job ${T}`,prompt:y.prompt,schedule:y.schedule,scheduleDisplay:y.schedule,state:"scheduled",enabled:!0,repeat:{times:y.repeat??null,completed:0},allowedTools:y.allowedTools};return H.set(T,v),fe(v),{success:!0,job:{...v,timerId:void 0}}},listJobs:async()=>({success:!0,jobs:[...H.values()].map(T=>({...T,timerId:void 0}))}),getJob:async y=>{let T=H.get(y);return T?{success:!0,job:{...T,timerId:void 0}}:{success:!1,error:`Job not found: ${y}`}},updateJob:async(y,T)=>{let v=H.get(y);return v?(T.prompt!==void 0&&(v.prompt=T.prompt),T.schedule!==void 0&&(v.schedule=T.schedule,v.scheduleDisplay=T.schedule),T.name!==void 0&&(v.name=T.name),T.enabled!==void 0&&(v.enabled=T.enabled,v.state=T.enabled?"scheduled":"paused"),T.repeat!==void 0&&(v.repeat.times=T.repeat),T.allowedTools!==void 0&&(v.allowedTools=T.allowedTools),v.enabled?fe(v):v.timerId&&(clearTimeout(v.timerId),v.timerId=void 0),{success:!0,job:{...v,timerId:void 0}}):{success:!1,error:`Job not found: ${y}`}},deleteJob:async y=>{let T=H.get(y);return T?(T.timerId&&clearTimeout(T.timerId),H.delete(y),{success:!0}):{success:!1,error:`Job not found: ${y}`}},pauseJob:async y=>{let T=H.get(y);return T?(T.state="paused",T.enabled=!1,T.timerId&&(clearTimeout(T.timerId),T.timerId=void 0),{success:!0,job:{...T,timerId:void 0}}):{success:!1,error:`Job not found: ${y}`}},resumeJob:async y=>{let T=H.get(y);return T?(T.state="scheduled",T.enabled=!0,fe(T),{success:!0,job:{...T,timerId:void 0}}):{success:!1,error:`Job not found: ${y}`}},triggerJob:async y=>{let T=H.get(y);return T?(T.lastRunAt=new Date().toISOString(),T.repeat.completed++,T.lastStatus="success",{success:!0,job:{...T,timerId:void 0}}):{success:!1,error:`Job not found: ${y}`}},validateSchedule:y=>z(y)!==null||/^\d{1,2}\s/.test(y)?null:`Invalid schedule: ${y}. Use shorthand (5m, 1h, 1d) or cron expression.`}));let te=new Map;it(async()=>{for(let y of te.values())y.cleanup();te.clear()}),ce(Kc({startMonitor:async y=>{if(te.has(y.monitorId))return{action:"start",success:!1,error:`Monitor "${y.monitorId}" already exists.`};let T={monitorId:y.monitorId,source:y.source,target:y.target,conditions:y.conditions,startedAt:Date.now(),timeoutSeconds:y.timeoutSeconds,eventCount:0},v=()=>{};if(y.source==="file")try{let _=$.watch(y.target,{persistent:!1},()=>{T.eventCount++,l.info(`[monitor] file change detected: ${y.target}`)});v=()=>_.close()}catch{return{action:"start",success:!1,error:`Cannot watch: ${y.target}`}}if(y.timeoutSeconds>0){let _=setTimeout(()=>{let I=te.get(y.monitorId);I&&(I.cleanup(),te.delete(y.monitorId))},y.timeoutSeconds*1e3),C=v;v=()=>{clearTimeout(_),C()}}return te.set(y.monitorId,{info:T,cleanup:v}),{action:"start",success:!0,monitorId:y.monitorId}},stopMonitor:async y=>{let T=te.get(y);return T?(T.cleanup(),te.delete(y),{action:"stop",success:!0,monitorId:y}):{action:"stop",success:!1,error:`Monitor "${y}" not found.`}},listMonitors:async()=>[...te.values()].map(y=>y.info)}));let le=new Map,G={info:y=>l.info(y),warn:y=>l.warn(y)},N=new yt({onNotification:(y,T,v)=>{this.sendNotification("team.member.notification",{memberId:y,method:T,params:v})},onStateChange:(y,T)=>{this.sendNotification("team.member.state",{memberId:y,state:T});let v=N.getHandle(y),C=N.getUsageTracker(y)?.getUsage();this.emitAgentStatus(y,T,{missedBeats:N.getMissedBeats(y),lastActivityAt:v?.lastActivityAt,usage:C&&C.totalTokens>0?{inputTokens:C.inputTokens,outputTokens:C.outputTokens,totalTokens:C.totalTokens}:void 0})},onExit:(y,T,v)=>{for(let _ of le.values()){let C=_.members.find(I=>I.cwd&&`team-${_.name}-${I.name}`.replace(/[^a-zA-Z0-9-]/g,"-").toLowerCase()===y.replace(/^team-/,""));C&&(C.isActive=!1)}l.info(`[team] member ${y} exited (code=${T}, signal=${v})`)},onMcpToolCall:(y,T,v)=>this.handleMcpToolCall(y,T,v),log:{info:y=>l.info(y),warn:y=>l.warn(y),debug:y=>l.debug(y)},sessionDir:J.join(B(),"agent-logs")});it(async()=>{N.dispose()}),ce(Jc({createTeam:async y=>{if(le.has(y.teamName))return{success:!1,error:`Team "${y.teamName}" already exists.`};let T=await qt(),v=[];for(let C of y.members??[]){let I={...C,isActive:!0};if(T){let V=`team-${y.teamName}-${C.name}`.replace(/[^a-zA-Z0-9-]/g,"-").toLowerCase(),j=await jl(T,V,G);j?(I.worktreePath=j.worktreePath,I.worktreeBranch=j.branch,I.cwd=j.worktreePath,l.info(`[team] provisioned worktree for ${C.name}: ${j.worktreePath}`)):(I.cwd=process.cwd(),l.warn(`[team] worktree provision failed for ${C.name}, using shared cwd`))}else I.cwd=process.cwd();v.push(I)}let _={name:y.teamName,description:y.description,leadId:this.currentSessionId??"default",members:v,createdAt:new Date().toISOString()};le.set(y.teamName,_);for(let C of v){if(!C.cwd)continue;let I=`team-${y.teamName}-${C.name}`.replace(/[^a-zA-Z0-9-]/g,"-").toLowerCase();try{await N.spawn({memberId:I,name:C.name,cwd:C.cwd,prompt:`You are the "${C.name}" team member. Role: ${C.role}.`,agentType:C.role,verbose:this.verbose}),l.info(`[team] spawned child process for ${C.name} in ${C.cwd}`)}catch(V){l.warn(`[team] failed to spawn child process for ${C.name}: ${V instanceof Error?V.message:String(V)}`),C.isActive=!1}}return this.sendNotification("team.updated",{teamName:y.teamName,action:"created",members:_.members.map(C=>({agentName:C.name,role:C.role,worktreePath:C.worktreePath,pid:N.getHandle(`team-${y.teamName}-${C.name}`.replace(/[^a-zA-Z0-9-]/g,"-").toLowerCase())?.pid}))}),{success:!0,team:_}},deleteTeam:async y=>{let T=le.get(y);if(!T)return{success:!1,error:`Team "${y}" not found.`};for(let _ of T.members){let C=`team-${y}-${_.name}`.replace(/[^a-zA-Z0-9-]/g,"-").toLowerCase();N.kill(C),N.remove(C)}let v=await qt();if(v)for(let _ of T.members)_.worktreePath&&_.worktreeBranch&&(await Bl(v,_.worktreePath,_.worktreeBranch,G),l.info(`[team] cleaned up worktree for ${_.name}: ${_.worktreePath}`));return le.delete(y),this.sendNotification("team.updated",{teamName:y,action:"destroyed",members:[]}),{success:!0}},listTeams:async()=>({success:!0,teams:[...le.values()]}),getTeamStatus:async y=>{let T=le.get(y);if(!T)return{success:!1,error:`Team "${y}" not found.`};let v={};for(let _ of T.members){let C=`team-${y}-${_.name}`.replace(/[^a-zA-Z0-9-]/g,"-").toLowerCase(),I=N.getStatus(C);I&&(_.isActive=I.alive,v[_.name]={mediaProgress:I.mediaProgress,lastToolCall:I.lastToolCall,idleFor:I.idleFor,runningFor:I.runningFor})}return{success:!0,team:T,memberProgress:v}}}));{let y=new uo({persistToDisk:!0});y.loadFromDiskSync();let T={providerId:"null",search:async()=>[],ingest:async()=>{}},v=this.qmemoryAdapter??T;ce({name:yu,label:Tu,description:ku,parameters:bu,execute:async(_,C)=>{let I=await wu(C,{provider:v,store:y,userId:this.qmemoryUserId||this.currentSessionId||"default",sessionId:this.currentSessionId});return{content:[{type:"text",text:I.message}],details:{type:"memory",action:I.action,ok:I.ok}}}})}{let y=e?.workdir??process.cwd(),T=Zc(y,this.currentSessionId||"default");ce(Qc(T))}let pe=e?.workdir??process.cwd(),Ee=Su({projectRoot:pe,ruleEngine:R,hooks:c,log:y=>l.info(`[settings] ${y}`)});it(async()=>{Ee()}),this.currentSessionId&&c.invoke("session.created",{sessionId:this.currentSessionId}).catch(()=>{}),this.fileWatcher&&this.fileWatcher.stop();let me=e?.workdir??process.cwd();return La({projectRoot:me,sessionId:this.currentSessionId,hooks:c,log:y=>l.debug(y),onInstructionCacheReset:Fa}).then(y=>{this.fileWatcher=y,it(async()=>{this.fileWatcher?.stop()})}).catch(y=>{l.warn(`[file-watcher] init error: ${y instanceof Error?y.message:y}`)}),this.agent=new dt({llmTransport:a.transport,apiKey:a.apiKey,toolInvoker:u,log:l,hooks:c,maxRounds:e.maxRounds,verbose:this.verbose}),this.lastLlmConfigKey=t,this.currentTransport=a.transport,this.currentApiKey=a.apiKey,this.currentModel=o,this.log(`created Agent (provider: ${n}, model: ${o})`),this.agent}loadSettingsSync(){try{let e=pt();if(!$.existsSync(e))return;let t=$.readFileSync(e,"utf-8"),n=JSON.parse(t);return{provider:n.provider,model:n.model,apiKey:n.apiKey,baseUrl:n.baseUrl}}catch{return}}handleSessionGetInfo(e){let t=this.currentSessionId||"default",n=this.sessionState?.createSnapshot(),o={sessionId:t,model:this.currentModel||void 0,cwd:process.cwd(),paths:{sessionDir:Di(t),agentHome:B(),settings:pt()},usage:n?{turnCount:n.turnCount,inputTokens:n.totalInputTokens,outputTokens:n.totalOutputTokens}:void 0};e.id!==void 0&&this.sendResponse(e.id,o)}async handleMemoryList(e){let t=[],n=J.join(B(),"memory.json");$.existsSync(n)&&t.push({id:"local",type:"json",path:n}),this.qmemoryAdapter&&t.push({id:"qmemory",type:"vector"}),e.id!==void 0&&this.sendResponse(e.id,{sources:t})}async handleMemoryRead(e){let t=e.params,n=t?.source??"local",o=t?.target??"memory";if(n==="local")try{let s=J.join(B(),"memory.json"),i=await $.promises.readFile(s,"utf-8"),a=JSON.parse(i);e.id!==void 0&&this.sendResponse(e.id,{source:"local",target:o,content:a[o]??""})}catch{e.id!==void 0&&this.sendResponse(e.id,{source:"local",target:o,content:""})}else e.id!==void 0&&this.sendResponse(e.id,void 0,{code:M.INVALID_PARAMS,message:`Unknown memory source: ${n}`})}async handleMemoryWrite(e){let t=e.params,n=t?.target??"memory",o=t?.content;if(n!=="memory"&&n!=="user"){e.id!==void 0&&this.sendResponse(e.id,void 0,{code:M.INVALID_PARAMS,message:`Invalid memory target: ${n}. Must be "memory" or "user".`});return}if(o==null){e.id!==void 0&&this.sendResponse(e.id,void 0,{code:M.INVALID_PARAMS,message:"content is required."});return}try{let s=J.join(B(),"memory.json"),i={};try{let a=await $.promises.readFile(s,"utf-8");i=JSON.parse(a)}catch{}i[n]=o,i.savedAt=new Date().toISOString(),await $.promises.mkdir(B(),{recursive:!0}),await $.promises.writeFile(s,JSON.stringify(i,null,2),"utf-8"),e.id!==void 0&&this.sendResponse(e.id,{ok:!0,target:n}),this.sendNotification("memory.updated",{target:n,source:"rpc"})}catch(s){e.id!==void 0&&this.sendResponse(e.id,void 0,{code:M.INTERNAL_ERROR,message:s instanceof Error?s.message:String(s)})}}handleToolsList(e){let t=e.params,o=We(t?.includeDeferred??!1).map(s=>({name:s.function.name,description:s.function.description??"",parameters:s.function.parameters,source:"builtin"}));if(t?.category){let s=o.filter(i=>i.name.startsWith(t.category)||i.description.toLowerCase().includes(t.category.toLowerCase()));e.id!==void 0&&this.sendResponse(e.id,{tools:s,total:s.length})}else e.id!==void 0&&this.sendResponse(e.id,{tools:o,total:o.length})}handleMediaListModels(e){let n=e.params?.mediaType,s=this.mediaClient.listMediaModels(n).map(i=>({providerId:i.providerId,providerName:i.providerDef.name,modelId:i.modelInfo.id,modelName:i.modelInfo.name,mediaType:i.mediaType,capabilities:i.modelInfo.mediaCapabilities}));e.id!==void 0&&this.sendResponse(e.id,{models:s})}async handleMediaCancel(e){let t=e.params;if(!t?.taskId){e.id!==void 0&&this.sendResponse(e.id,void 0,{code:M.INVALID_PARAMS,message:"taskId is required."});return}let n=t.provider??"doubao",o=this.mediaClient.getTransport(n);if(!o){e.id!==void 0&&this.sendResponse(e.id,{ok:!1,message:`No transport for provider: ${n}`});return}if(!gr(o)){e.id!==void 0&&this.sendResponse(e.id,{ok:!1,message:`Provider ${n} does not support task cancellation.`});return}try{let s=this.resolveMediaApiKey(n);if(!s){e.id!==void 0&&this.sendResponse(e.id,{ok:!1,message:`No API key for provider: ${n}`});return}await o.deleteVideoTask(t.taskId,s),e.id!==void 0&&this.sendResponse(e.id,{ok:!0,taskId:t.taskId,message:"Task cancelled."})}catch(s){e.id!==void 0&&this.sendResponse(e.id,{ok:!1,message:s instanceof Error?s.message:String(s)})}}async handleMediaStatus(e){let t=e.params;if(!t?.taskId){e.id!==void 0&&this.sendResponse(e.id,void 0,{code:M.INVALID_PARAMS,message:"taskId is required."});return}let n=t.provider??"doubao",o=this.mediaClient.getTransport(n);if(!o){e.id!==void 0&&this.sendResponse(e.id,{ok:!1,message:`No transport for provider: ${n}`});return}if(!gr(o)){e.id!==void 0&&this.sendResponse(e.id,{ok:!1,message:`Provider ${n} does not support task status queries.`});return}try{let s=this.resolveMediaApiKey(n);if(!s){e.id!==void 0&&this.sendResponse(e.id,{ok:!1,message:`No API key for provider: ${n}`});return}if(o.getTaskStatus){let{status:u,task:c}=await o.getTaskStatus(t.taskId,s);e.id!==void 0&&this.sendResponse(e.id,{ok:!0,taskId:t.taskId,status:u,task:c});return}let i=await o.listVideoTasks(s,{limit:100}),l=(i.data??i.tasks??[]).find(u=>u.id===t.taskId||u.task_id===t.taskId);e.id!==void 0&&this.sendResponse(e.id,{ok:!0,taskId:t.taskId,...l?{status:l.status,task:l}:{status:"unknown",message:"Task not found in recent list."}})}catch(s){e.id!==void 0&&this.sendResponse(e.id,{ok:!1,message:s instanceof Error?s.message:String(s)})}}resolveMediaApiKey(e){return this.currentMediaApiKeys?.[e]}handleProviderList(e){let t=this.registry.listProviders(),n=new Map;for(let s of t){let i=s.group??s.id;n.has(i)||n.set(i,[]);let a=!!this.registry.resolveApiKey(s.id);n.get(i).push({id:s.id,name:s.name,transport:s.transport,baseUrl:s.baseUrl,defaultModel:s.defaultModel,modelCount:s.models?.length??0,available:a})}let o=[...n.entries()].map(([s,i])=>({group:s,variants:i}));e.id!==void 0&&this.sendResponse(e.id,{providers:o})}handleConfigGet(e){try{let t=pt(),n={};if($.existsSync(t)){let o=$.readFileSync(t,"utf-8");n=JSON.parse(o)}e.id!==void 0&&this.sendResponse(e.id,{config:n,paths:{userSettings:t,agentHome:B()}})}catch(t){e.id!==void 0&&this.sendResponse(e.id,void 0,{code:M.INTERNAL_ERROR,message:t instanceof Error?t.message:String(t)})}}async handleConfigUpdate(e){let t=e.params;if(!t?.updates||typeof t.updates!="object"){e.id!==void 0&&this.sendResponse(e.id,void 0,{code:M.INVALID_PARAMS,message:"updates (object) is required."});return}try{let n=pt(),o={};try{let s=await $.promises.readFile(n,"utf-8");o=JSON.parse(s)}catch{}Object.assign(o,t.updates),await $.promises.mkdir(J.dirname(n),{recursive:!0}),await $.promises.writeFile(n,JSON.stringify(o,null,2),"utf-8"),e.id!==void 0&&this.sendResponse(e.id,{ok:!0})}catch(n){e.id!==void 0&&this.sendResponse(e.id,void 0,{code:M.INTERNAL_ERROR,message:n instanceof Error?n.message:String(n)})}}async handleTodosList(e){let t=ke("todo");if(!t){e.id!==void 0&&this.sendResponse(e.id,{items:[],summary:ft([])});return}try{let o=(await t.execute("rpc-todos-list",{action:"list"},void 0)).content.map(a=>a.text??"").join(""),i=JSON.parse(o).todoList??[];e.id!==void 0&&this.sendResponse(e.id,{items:i,summary:ft(i)})}catch{e.id!==void 0&&this.sendResponse(e.id,{items:[],summary:ft([])})}}async handleMemorySearch(e){let t=e.params;if(!t?.query){e.id!==void 0&&this.sendResponse(e.id,void 0,{code:M.INVALID_PARAMS,message:"query is required."});return}if(!this.qmemoryAdapter){try{let n=J.join(B(),"memory.json"),o=await $.promises.readFile(n,"utf-8"),s=JSON.parse(o),i=[],a=t.query.toLowerCase();for(let[l,u]of Object.entries(s)){if(typeof u!="string")continue;let c=u.split(`
429
429
  \xA7
430
430
  `).filter(d=>d.trim());for(let d=0;d<c.length;d++)c[d].toLowerCase().includes(a)&&i.push({id:`local-${l}-${d}`,text:c[d],score:1,source:"local"})}e.id!==void 0&&this.sendResponse(e.id,{results:i.slice(0,t.limit??10)})}catch{e.id!==void 0&&this.sendResponse(e.id,{results:[]})}return}try{let n=t.userId??(this.qmemoryUserId||"default"),o=await this.qmemoryAdapter.search(t.query,n,{limit:t.limit??10});e.id!==void 0&&this.sendResponse(e.id,{results:o.map(s=>({id:s.blockId??"",text:s.text,score:s.score,source:"qmemory",metadata:s.metadata}))})}catch(n){e.id!==void 0&&this.sendResponse(e.id,void 0,{code:M.INTERNAL_ERROR,message:n instanceof Error?n.message:String(n)})}}async handleMemoryDelete(e){let t=e.params;if(!t?.match){e.id!==void 0&&this.sendResponse(e.id,void 0,{code:M.INVALID_PARAMS,message:"match is required."});return}let n=t.source??"local";if(n==="local"){let o=t.target??"memory";try{let s=J.join(B(),"memory.json"),i=await $.promises.readFile(s,"utf-8"),a=JSON.parse(i),u=(a[o]??"").split(`
431
431
  \xA7
@@ -305,7 +305,7 @@ export type TurnEvent = {
305
305
  } | {
306
306
  type: "media_result";
307
307
  turnId: string;
308
- mediaType: "image" | "tts" | "video";
308
+ mediaType: "image" | "tts" | "video" | "music";
309
309
  url: string;
310
310
  model?: string;
311
311
  provider?: string;
@@ -155,7 +155,7 @@ export interface TurnAnnotationsNotification {
155
155
  [key: string]: unknown;
156
156
  }>;
157
157
  }
158
- export type MediaResultType = "image" | "tts" | "video";
158
+ export type MediaResultType = "image" | "tts" | "video" | "music";
159
159
  /** Structured media generation result — enables media preview cards. */
160
160
  export interface TurnMediaResultNotification {
161
161
  turnId: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "qlogicagent",
3
- "version": "1.2.0",
3
+ "version": "1.2.1",
4
4
  "description": "XiaozhiClaw Agent CLI — subprocess architecture (JSON-RPC over stdio)",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",