qlogicagent 2.10.21 → 2.10.22
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/agent.js +8 -8
- package/dist/cli.js +147 -147
- package/dist/index.js +145 -145
- package/dist/types/runtime/infra/model-registry.d.ts +2 -0
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -1,41 +1,41 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
var
|
|
2
|
+
var Eb=Object.defineProperty;var Mo=(n=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(n,{get:(e,t)=>(typeof require<"u"?require:e)[t]}):n)(function(n){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+n+'" is not supported')});var X=(n,e)=>()=>(n&&(e=n(n=0)),e);var en=(n,e)=>{for(var t in e)Eb(n,t,{get:e[t],enumerable:!0})};import{cleanSchemaForGemini as lE}from"@xiaozhiclaw/provider-core/gemini-schema-utils";function No(n,e,t,r){return{role:"assistant",content:e||null,tool_calls:n,...t&&t.length>0?{thinkingBlocks:t}:{},...r?{reasoning_content:r}:{}}}function Kt(n,e){let t=e.ok?typeof e.payload=="string"?e.payload:JSON.stringify(e.payload??""):`Error: ${e.error??"Tool execution failed"}`;return{role:"tool",tool_call_id:n,content:t,...!e.ok&&{is_error:!0},...e.toolReferences?.length?{toolReferences:e.toolReferences}:{},...e.imageUrls?.length?{imageUrls:e.imageUrls}:{}}}var xl=X(()=>{"use strict"});function rn(n,e){if(!n)return!1;let t=n.toLowerCase();return e.some(r=>r instanceof RegExp?r.test(t):t.includes(r))}function Vb(n){return rn(n,nn.format)}function Pl(n){return rn(n,nn.rateLimit)}function zb(n){return rn(n,nn.timeout)}function Xb(n){return Mb.test(n)}function Do(n){let e=n.toLowerCase();return e?n.length>Ob?Db.test(e):rn(e,nn.billing)?!0:Nb.test(n)?e.includes("upgrade")||e.includes("credits")||e.includes("payment")||e.includes("plan"):!1:!1}function Il(n){return rn(n,nn.authPermanent)}function Yb(n){return rn(n,nn.auth)}function _l(n){return rn(n,nn.overloaded)}function tn(n,e){return e.some(t=>n.includes(t))}function Jb(n){return tn(n,jb)||tn(n,Ub)&&n.includes("limit")||n.includes("billing hard limit")||n.includes("hard limit reached")||n.includes("maximum allowed")&&n.includes("limit")}function Qb(n){let e=tn(n,Fb),t=n.includes("spend limit")||n.includes("spending limit"),r=tn(n,qb);return tn(n,Bb)&&tn(n,Hb)||e&&(n.includes("usage limit")||t)||e&&n.includes("limit")&&n.includes("reset")||r&&n.includes("limit")&&(t||tn(n,Wb))}function Zb(n){return n.trim().toLowerCase().replace(Kb,"").trim()}function El(n){let e=Zb(n);return!e||Jb(e)?"billing":Pl(e)||Qb(e)?"rate_limit":"billing"}function ev(n){return Gb.test(n)?El(n):null}function Cl(n){let e=n.match(Lb);if(!e)return null;let t=Number(e[1]);return Number.isFinite(t)?{code:t,rest:(e[2]??"").trim()}:null}function tv(n){if(!n)return!1;let e=n.toLowerCase();return e.includes('"type":"api_error"')&&e.includes("internal server error")}function nv(n){let e=n.trim();if(!e)return!1;let t=Cl(e);return t?$b.has(t.code):!1}function Ml(n,e){return typeof n!="number"||!Number.isFinite(n)?null:n===402?e?El(e):"billing":n===429?"rate_limit":n===401||n===403?e&&Il(e)?"auth_permanent":"auth":n===408?"timeout":n===503?e&&_l(e)?"overloaded":"timeout":n===502||n===504?"timeout":n===529?"overloaded":n===400?e&&Do(e)?"billing":"format":null}function rv(n){if(!n)return!1;let e=n.toLowerCase();return!!(e.includes("unknown model")||e.includes("model not found")||e.includes("model_not_found")||e.includes("not_found_error")||e.includes("does not exist")&&e.includes("model")||e.includes("invalid model")&&!e.includes("invalid model reference")||/models\/[^\s]+ is not found/i.test(n)||/\b404\b/.test(n)&&/not[-_ ]?found/i.test(n))}function sv(n){if(!n)return!1;let e=n.toLowerCase();return e.includes("session not found")||e.includes("session does not exist")||e.includes("session expired")||e.includes("session invalid")||e.includes("conversation not found")||e.includes("conversation does not exist")||e.includes("conversation expired")||e.includes("conversation invalid")||e.includes("no such session")||e.includes("invalid session")||e.includes("session id not found")||e.includes("conversation id not found")}function Nl(n){if(sv(n))return"session_expired";if(rv(n))return"model_not_found";let e=ev(n);return e||(Xb(n)?Do(n)?"billing":"rate_limit":Pl(n)?"rate_limit":_l(n)?"overloaded":nv(n)?Cl(n.trim())?.code===529?"overloaded":"timeout":tv(n)?"timeout":Vb(n)?"format":Do(n)?"billing":zb(n)?"timeout":Il(n)?"auth_permanent":Yb(n)?"auth":null)}var Mb,nn,Nb,Db,Ob,Lb,$b,jb,Ub,Fb,Bb,Hb,qb,Wb,Gb,Kb,Dl=X(()=>{"use strict";Mb=/\b(?:daily|weekly|monthly)(?:\/(?:daily|weekly|monthly))* (?:usage )?limit(?:s)?(?: (?:exhausted|reached|exceeded))?\b/i,nn={rateLimit:[/rate[_ ]limit|too many requests|429/,"model_cooldown","exceeded your current quota","resource has been exhausted","quota exceeded","resource_exhausted","usage limit",/\btpm\b/i,"tokens per minute","tokens per day"],overloaded:[/overloaded_error|"type"\s*:\s*"overloaded_error"/i,"overloaded",/service[_ ]unavailable.*(?:overload|capacity|high[_ ]demand)|(?:overload|capacity|high[_ ]demand).*service[_ ]unavailable/i,"high demand"],timeout:["timeout","timed out","service unavailable","deadline exceeded","context deadline exceeded","connection error","network error","network request failed","fetch failed","socket hang up",/\beconn(?:refused|reset|aborted)\b/i,/\benotfound\b/i,/\beai_again\b/i,/without sending (?:any )?chunks?/i,/\bstop reason:\s*(?:abort|error|network_error)\b/i,/\breason:\s*(?:abort|error|network_error)\b/i,/\bunhandled stop reason:\s*(?:abort|error|network_error)\b/i],billing:[/["']?(?:status|code)["']?\s*[:=]\s*402\b|\bhttp\s*402\b|\berror(?:\s+code)?\s*[:=]?\s*402\b|\b(?:got|returned|received)\s+(?:a\s+)?402\b|^\s*402\s+payment/i,"payment required","insufficient credits",/insufficient[_ ]quota/i,"credit balance","plans & billing","insufficient balance"],authPermanent:[/api[_ ]?key[_ ]?(?:revoked|invalid|deactivated|deleted)/i,"invalid_api_key","key has been disabled","key has been revoked","account has been deactivated",/could not (?:authenticate|validate).*(?:api[_ ]?key|credentials)/i,"permission_error","not allowed for this organization"],auth:[/invalid[_ ]?api[_ ]?key/,"incorrect api key","invalid token","authentication","re-authenticate","oauth token refresh failed","unauthorized","forbidden","access denied","insufficient permissions","insufficient permission",/missing scopes?:/i,"expired","token has expired",/\b401\b/,/\b403\b/,"no credentials found","no api key found"],format:["string should match pattern","tool_use.id","tool_use_id","messages.1.content.1.tool_use.id","invalid request format",/tool call id was.*must be/i]},Nb=/^(?:error[:\s-]+)?billing(?:\s+error)?(?:[:\s-]+|$)|^(?:error[:\s-]+)?(?:credit balance|insufficient credits?|payment required|http\s*402\b)/i,Db=/["']?(?:status|code)["']?\s*[:=]\s*402\b|\bhttp\s*402\b|\berror(?:\s+code)?\s*[:=]?\s*402\b|^\s*402\s+payment/i,Ob=512,Lb=/^(?:http\s*)?(\d{3})(?:\s+([\s\S]+))?$/i,$b=new Set([500,502,503,504,521,522,523,524,529]),jb=["insufficient credits","insufficient quota","credit balance","insufficient balance","plans & billing","add more credits","top up"],Ub=["upgrade your plan","upgrade plan","current plan","subscription"],Fb=["daily","weekly","monthly"],Bb=["try again","retry","temporary","cooldown"],Hb=["usage limit","rate limit","organization usage"],qb=["organization","workspace"],Wb=["billing period","exceeded","reached","exhausted"],Gb=/["']?(?:status|code)["']?\s*[:=]\s*402\b|\bhttp\s*402\b|\berror(?:\s+code)?\s*[:=]?\s*402\b|\b(?:got|returned|received)\s+(?:a\s+)?402\b|^\s*402\s+payment required\b/i,Kb=/^(?:error[:\s-]+)?(?:(?:http\s*)?402(?:\s+payment required)?|payment required)(?:[:\s-]+|$)/i});function Sn(n,e){let t=Ml(n,e)??(e?Nl(e):null);return t?ov[t]:typeof n=="number"&&n>=400&&n<500?"NON_RETRYABLE_CONTENT":"RETRYABLE_TRANSIENT"}function Oo(n){return iv.has(n)}var ov,iv,Ol=X(()=>{"use strict";Dl();ov={timeout:"RETRYABLE_TRANSIENT",overloaded:"RETRYABLE_TRANSIENT",rate_limit:"RETRYABLE_DEGRADED",auth:"NON_RETRYABLE_AUTH",auth_permanent:"NON_RETRYABLE_AUTH",billing:"NON_RETRYABLE_QUOTA",format:"NON_RETRYABLE_CONTENT",model_not_found:"NON_RETRYABLE_CONTENT",session_expired:"NON_RETRYABLE_CONTENT",unknown:"RETRYABLE_TRANSIENT"},iv=new Set(["RETRYABLE_TRANSIENT","RETRYABLE_DEGRADED","TOOL_EXECUTION_FAILED"])});function Jn(n){return typeof n.compressAsync=="function"}function av(n,e){if(n.length<=e)return n;let t=n.slice(0,e);if(n.trimStart().startsWith("{")||n.trimStart().startsWith("[")){let o=Math.max(t.lastIndexOf("},"),t.lastIndexOf("],"),t.lastIndexOf(`}
|
|
3
3
|
`),t.lastIndexOf(`]
|
|
4
4
|
`));if(o>e*.5)return t.slice(0,o+1)+`
|
|
5
5
|
[...truncated: ${n.length-o-1} chars omitted]`}let s=t.lastIndexOf(`
|
|
6
6
|
`);return s>e*.7?t.slice(0,s)+`
|
|
7
7
|
[...truncated: ${n.length-s} chars omitted]`:t+`
|
|
8
8
|
[...truncated: ${n.length-e} chars omitted]`}function Lo(...n){return{compress(e,t){let r=e,s=0,o=[];for(let i of n){let a=i.compress(r,t);r=a.messages,s+=a.droppedCount,a.droppedCount>0&&o.push(a.strategy)}return{messages:r,droppedCount:s,strategy:o.length>0?o.join("+"):"none"}}}}function $o(...n){return{compress(e,t){let r=e,s=0,o=[];for(let i of n){let a=i.compress(r,t);r=a.messages,s+=a.droppedCount,a.droppedCount>0&&o.push(a.strategy)}return{messages:r,droppedCount:s,strategy:o.length>0?o.join("+"):"none"}},async compressAsync(e,t){let r=e,s=0,o=[],i=0,a=!1,c=!1;for(let l of n){let d=Jn(l)?await l.compressAsync(r,t):l.compress(r,t);r=d.messages,s+=d.droppedCount,d.droppedCount>0&&o.push(d.strategy),d.metrics&&(i+=d.metrics.latencyMs,a=a||d.metrics.usedLlm,c=c||!!d.metrics.cacheInvalidated)}return{messages:r,droppedCount:s,strategy:o.length>0?o.join("+"):"none",metrics:i>0||a?{tokensBefore:0,tokensAfter:0,compressionRatio:0,latencyMs:i,usedLlm:a,cacheInvalidated:c}:void 0}}}}function $l(n,e){let t=n.filter(i=>i.role==="user"),r=n.filter(i=>i.tool_calls!=null),s=n.filter(i=>i.role==="tool"),o=["You are a conversation summarizer. Produce a structured summary of the conversation history below.","","## Instructions","Analyze the conversation and produce a summary with these sections:","","### 1. Primary Objective","What is the user's main goal or task? State it in one sentence.","","### 2. Key Decisions Made","List the important decisions, choices, or conclusions reached during the conversation.","","### 3. Current Progress",`Describe the current state. ${r.length>0?`${r.length} tool calls and ${s.length} tool results were exchanged.`:"No tools were used."}`,"","### 4. Pending Tasks","List any tasks that are in-progress or planned but not yet completed.","","### 5. Important Context","MUST preserve verbatim: IP addresses, file paths, URLs, port numbers, credentials/tokens, specific numeric values, version numbers, proper nouns, identifiers, and any user-provided data points. These MUST appear exactly as stated in the original conversation.","","### 6. All User Messages",`List ALL ${t.length} user messages chronologically, each as 1-2 sentences capturing the core request. Include exact values, identifiers, keywords, or secrets the user mentioned or asked you to remember. Do NOT omit any user message \u2014 every user request must be traceable in this summary.`,"","### 7. Error & Recovery History","Summarize any errors encountered and how they were resolved.","","### 8. User Preferences Expressed","Note any stated preferences about style, approach, or constraints.","","### 9. Technical State","Note file paths, variable names, API endpoints, or configuration values that were discussed.","","### 10. Conversation Flow","Briefly describe the overall flow: what happened first, what changed, where we are now."];return e?.taskContext&&o.push("","## Additional Context",e.taskContext),o.push("","## Conversation to Summarize","",...n.map(i=>{let a=typeof i.content=="string"?i.content:JSON.stringify(i.content??""),c=i.role==="user"?a:a.length>2e3?a.slice(0,2e3)+"...":a;return`[${i.role}]: ${c}`}),"","## Output Format","Respond with a concise summary covering all 10 sections above. Use markdown headers.","Keep the total summary under 1000 words. Focus on actionable information and exact user requests."),o.join(`
|
|
9
|
-
`)}function Vr(n={}){let e={...jl,...n},t=Math.floor(e.modelContextWindow*e.targetUsageRatio);return Math.max(e.minBudget,Math.min(t,e.maxBudget))}function Qn(n,e){let t=n/e;return t<=.8?"none":t<=1?"trim-only":t<=1.5?"sliding-window":"llm-summarize"}function
|
|
9
|
+
`)}function Vr(n={}){let e={...jl,...n},t=Math.floor(e.modelContextWindow*e.targetUsageRatio);return Math.max(e.minBudget,Math.min(t,e.maxBudget))}function Qn(n,e){let t=n/e;return t<=.8?"none":t<=1?"trim-only":t<=1.5?"sliding-window":"llm-summarize"}function cv(n){let e=[],t=[];for(let r of n)r.role==="system"?e.push(r):t.push(r);return{system:e,nonSystem:t}}function jo(n){let e=typeof n.content=="string"?n.content:n.content!=null?JSON.stringify(n.content):"";return Math.ceil(e.length/4)}function Kr(n){let e=Math.min(n.length,5),t=[];for(let r=0;r<e;r++){let s=n[r],o=typeof s.content=="string"?s.content.slice(0,200):"";t.push(`${s.role}:${o}`)}return t.join("|")}function dv(n){let e=new Map;for(let t=0;t<n.length;t++){let r=n[t];if(r.tool_calls&&Array.isArray(r.tool_calls))for(let s of r.tool_calls){let o=s.function?.name??"";if(/read|edit|write|file/i.test(o)&&s.function?.arguments)try{let i=JSON.parse(s.function.arguments),a=i.path??i.filePath??i.file_path??i.file;a&&typeof a=="string"&&e.set(a,t)}catch{}}r.role==="tool"&&r.name&&/read|edit|write|file/i.test(r.name)}return[...e.entries()].sort((t,r)=>r[1]-t[1]).map(([t])=>t)}async function Uo(n,e,t){let r=t.estimateTokens??(p=>Math.ceil(p.length/4)),s=dv(e);if(s.length===0)return n;let o=n.map(p=>typeof p.content=="string"?p.content:"").join(`
|
|
10
10
|
`),i=s.filter(p=>!o.includes(p));if(i.length===0)return n;let a=t.maxTokenBudget,c=[],l=0;for(let p of i){if(l>=t.maxFiles||a<=0)break;let m=await t.readFile(p);if(!m)continue;let h=r(m);h>a||(a-=h,l++,c.push({role:"system",content:`[Post-compact file recovery: ${p}]
|
|
11
11
|
|
|
12
|
-
${m}`}))}if(c.length===0)return n;let d=[...n],u=-1;for(let p=0;p<d.length;p++)d[p].role==="system"&&(u=p);return d.splice(u+1,0,...c),d}function Fo(n,e,t=jo){if(e.size===0)return{messages:n,tokensFreed:0,removedCount:0};let r=0,s=0,o=[];for(let a of n){let c=a.tool_call_id??"";if(c&&e.has(c)){r+=t(a),s++,e.delete(c);continue}o.push(a)}let i=s>0?{role:"system",content:`[${s} messages removed by snip]`}:void 0;return{messages:o,tokensFreed:r,removedCount:s,boundaryMessage:i}}var Ll,Tn,sn,Vn,zn,jl,Xn,Yn,
|
|
12
|
+
${m}`}))}if(c.length===0)return n;let d=[...n],u=-1;for(let p=0;p<d.length;p++)d[p].role==="system"&&(u=p);return d.splice(u+1,0,...c),d}function Fo(n,e,t=jo){if(e.size===0)return{messages:n,tokensFreed:0,removedCount:0};let r=0,s=0,o=[];for(let a of n){let c=a.tool_call_id??"";if(c&&e.has(c)){r+=t(a),s++,e.delete(c);continue}o.push(a)}let i=s>0?{role:"system",content:`[${s} messages removed by snip]`}:void 0;return{messages:o,tokensFreed:r,removedCount:s,boundaryMessage:i}}var Ll,Tn,sn,Vn,zn,jl,Xn,Yn,lv,Vt,Bo=X(()=>{"use strict";Ll=4,Tn=class{constructor(e){this.estimateTokens=e}estimateTokens;compress(e,t){let r=[],s=[];for(let d of e)d.role==="system"?r.push(d):s.push(d);let o=t;for(let d of r)o-=this.estimateTokens(d);let i;for(let d of s)if(d.role==="user"){i=d;break}if(i&&(o-=this.estimateTokens(i)),o<=0)return{messages:i?[...r,i]:r,droppedCount:s.length-(i?1:0),strategy:"sliding-window"};let a=[],c=0;for(let d=s.length-1;d>=0;d--){let u=s[d];if(u===i)continue;let p=this.estimateTokens(u);if(o-p<0&&c>=Ll)break;if(o-p<0&&c<Ll){a.unshift(u),c++;continue}o-=p,a.unshift(u),c++}let l=[...r];return i&&!a.includes(i)&&l.push(i),l.push(...a),{messages:l,droppedCount:s.length-(a.length+(i&&!a.includes(i)?1:0)),strategy:"sliding-window"}}},sn=class{constructor(e=8e3){this.maxToolResultChars=e}maxToolResultChars;compress(e,t){let r=0;return{messages:e.map(o=>o.role!=="tool"||typeof o.content!="string"||o.content.length<=this.maxToolResultChars?o:(r++,{...o,content:av(o.content,this.maxToolResultChars)})),droppedCount:r,strategy:"tool-result-trim"}}};Vn=class{config;constructor(e){this.config={protectedHeadExchanges:e.protectedHeadExchanges,protectedTailMessages:e.protectedTailMessages,summarize:e.summarize,estimateTokens:e.estimateTokens??jo,taskContext:e.taskContext}}compress(e,t){return{messages:e,droppedCount:0,strategy:"head-tail-protected"}}async compressAsync(e,t){let r=Date.now(),{system:s,nonSystem:o}=cv(e),i=e.reduce((_,I)=>_+this.config.estimateTokens(I),0);if(i<=t)return{messages:e,droppedCount:0,strategy:"head-tail-protected"};let a=0,c=0;for(let _=0;_<o.length&&(o[_].role==="user"&&c++,!(c>this.config.protectedHeadExchanges));_++)a=_+1;let l=Math.max(this.config.protectedTailMessages,Math.floor(o.length*.4)),d=Math.max(a,o.length-l);if(d<=a)return{messages:e,droppedCount:0,strategy:"head-tail-protected"};let u=o.slice(0,a),p=o.slice(a,d),m=o.slice(d),h=$l(p,{taskContext:this.config.taskContext}),f=await this.config.summarize(p,h),y={role:"system",content:`[Conversation summary \u2014 ${p.length} messages compressed]
|
|
13
13
|
|
|
14
|
-
${f}`},b=[...s,...u,y,...m],k=Date.now()-r,A=b.reduce((_,I)=>_+this.config.estimateTokens(I),0);return{messages:b,droppedCount:p.length,strategy:"head-tail-protected",metrics:{tokensBefore:i,tokensAfter:A,compressionRatio:i>0?A/i:1,latencyMs:k,usedLlm:!0,cacheInvalidated:!0}}}},zn=class{config;constructor(e){this.config=e}compress(e,t){let r=Kr(e),s=this.config.inner.compress(e,t),o=Kr(s.messages),i=r!==o&&s.droppedCount>0;return i&&this.config.onCacheInvalidated?.({droppedCount:s.droppedCount,strategy:s.strategy}),{...s,metrics:{...s.metrics??{tokensBefore:0,tokensAfter:0,compressionRatio:0,latencyMs:0,usedLlm:!1},cacheInvalidated:i}}}async compressAsync(e,t){let r=Kr(e),s=Jn(this.config.inner)?await this.config.inner.compressAsync(e,t):this.config.inner.compress(e,t),o=Kr(s.messages),i=r!==o&&s.droppedCount>0;return i&&this.config.onCacheInvalidated?.({droppedCount:s.droppedCount,strategy:s.strategy}),{...s,metrics:{...s.metrics??{tokensBefore:0,tokensAfter:0,compressionRatio:0,latencyMs:0,usedLlm:!1},cacheInvalidated:i}}}},jl={modelContextWindow:128e3,targetUsageRatio:.75,minBudget:16e3,maxBudget:12e4};Xn=class{events=[];maxEvents;constructor(e=100){this.maxEvents=e}record(e){this.events.push(e),this.events.length>this.maxEvents&&this.events.shift()}snapshot(){let e=this.events.length;if(e===0)return{totalCompressions:0,totalLlmCalls:0,totalCacheInvalidations:0,averageCompressionRatio:1,averageLatencyMs:0,totalTokensSaved:0,recentEvents:[]};let t=0,r=0,s=0,o=0,i=0;for(let a of this.events)t+=a.tokensBefore>0?a.tokensAfter/a.tokensBefore:1,r+=a.latencyMs,s+=Math.max(0,a.tokensBefore-a.tokensAfter),a.usedLlm&&o++,a.cacheInvalidated&&i++;return{totalCompressions:e,totalLlmCalls:o,totalCacheInvalidations:i,averageCompressionRatio:t/e,averageLatencyMs:r/e,totalTokensSaved:s,recentEvents:this.events.slice(-10)}}reset(){this.events.length=0}},Yn=class{engines=new Map;activeId;register(e){this.engines.set(e.id,e)}activate(e){return this.engines.has(e)?(this.activeId=e,!0):!1}getActive(){return this.activeId?this.engines.get(this.activeId):void 0}listEngines(){return Array.from(this.engines.values()).map(e=>({id:e.id,label:e.label,active:e.id===this.activeId}))}};
|
|
15
|
-
`).map(l=>l.replace(/^\s*-\s*/,"").trim()).filter(Boolean);if(Jr(c)===t)return s.name}}catch{}}}catch{}return null}function Uv(n){if(!Ei(n))return 0;try{return Xl(n,{withFileTypes:!0}).filter(e=>e.isDirectory()&&Ei(Ci(n,e.name,"SKILL.md"))).length}catch{return 0}}function Fv(n,e){return!(!n.ok||n.existingSkillName||!n.multiStep||n.toolCallCount<ii||n.distinctToolCount<ai||Date.now()-Yl<ci||e?.projectSkillsDir&&(Uv(e.projectSkillsDir)>=oi||e.tools.length>0&&jv(e.tools,e.projectSkillsDir))||e?.projectRoot&&e.tools.length>0&&!Ql(e.projectRoot,e.tools))}function Bv(n){return n.existingSkillName?n.feedback==="negative":!1}function Qr(n,e){return Bv(n)?{type:"skill.improve",skillName:n.existingSkillName,reason:"negative user feedback on existing skill execution"}:Fv(n,e)?(Yl=Date.now(),{type:"skill.create",suggestedName:e.suggestedName??`auto-skill-${e.tools.slice(0,3).join("-")}`,description:`Multi-step orchestration using ${e.tools.join(", ")}`,tools:e.tools,stepCount:n.toolCallCount}):null}var Yl,Ov,Zl=X(()=>{"use strict";je();Yl=0,Ov="skill-patterns.json"});function ed(n){return n.function&&typeof n.function=="object"&&typeof n.function.name=="string"?n.function.name.trim():typeof n.name=="string"?n.name.trim():""}function Hv(n){return n==="enabled-eligible"||n==="installed-awaiting-approval"}function qv(n){return new Map((n??[]).map(e=>[e.toolName,e]))}function Wv(n){if(!n.eligibility?.length)return[...n.tools];let e=qv(n.eligibility);return n.tools.filter(t=>{let r=ed(t);if(!r)return!1;let s=e.get(r);return!s||Hv(s.status)})}function Gv(n){let e=[],t=n.compatibility??{},r=n.toolChoice;if(n.thinkingEnabled&&t.requireAutoWhenThinking){let s=typeof r=="object"&&r&&!Array.isArray(r)?String(r.type??""):r;s&&s!=="auto"&&s!=="none"&&(e.push("tool_choice downgraded to auto because thinking mode requires auto/none compatibility."),r="auto")}if(r==="required"&&t.allowRequiredToolChoice===!1){let s=t.requiredFallback??"auto";e.push(`tool_choice=required is not supported by this provider; downgraded to ${s}.`),r=s}if(r&&typeof r=="object"&&!Array.isArray(r)&&r.type==="function"&&t.allowNamedToolChoice===!1){let s=t.namedFallback??"required";e.push(`named tool_choice is not supported by this provider; downgraded to ${s}.`),r=s}return{normalizedToolChoice:r,warnings:e}}function Mi(n){let e=Gv({toolChoice:n.toolChoice,thinkingEnabled:n.thinkingEnabled,compatibility:n.compatibility}),t=e.normalizedToolChoice,r=[...e.warnings],s=Wv({tools:n.tools,eligibility:n.eligibility});if(!t||t==="auto")return{tools:s,normalizedToolChoice:t,warnings:r};if(t==="none")return{tools:[],normalizedToolChoice:"none",warnings:r};if(t==="required"){if(s.length===0)throw new Error("tool_choice=required but no tools were provided");return{tools:s,normalizedToolChoice:"required",extraSystemPrompt:"You must call one of the available tools before responding.",warnings:r}}if(typeof t=="object"&&!Array.isArray(t)&&t.type==="function"){let o=t.function??void 0,i=typeof o?.name=="string"?o.name.trim():"";if(!i)throw new Error("tool_choice.function.name is required");let a=s.filter(c=>ed(c)===i);if(a.length===0)throw new Error(`tool_choice requested unknown tool: ${i}`);return{tools:a,normalizedToolChoice:{type:"function",function:{name:i}},extraSystemPrompt:`You must call the ${i} tool before responding.`,warnings:r}}return{tools:s,normalizedToolChoice:t,warnings:r}}var td=X(()=>{"use strict"});function nd(n){return n==null?[]:typeof n=="string"?n.length>0?[{type:"text",text:n}]:[]:Array.isArray(n)?n:[{type:"text",text:String(n)}]}function zv(n,e){return{...n,content:[...nd(n.content),...nd(e.content)]}}function Xv(n){if(!n||typeof n!="object")return!1;if(n.function&&typeof n.function=="object"){let e=n.function.name;if(typeof e=="string"&&e.length>0)return!0}return typeof n.name=="string"&&n.name.length>0}function Yv(n){return new Set((n??Kv).map(e=>e.trim().toLowerCase()))}function Jv(n,e){return n?Yv(e).has(n.trim().toLowerCase()):!1}function Ni(n){if(!Array.isArray(n)||n.length===0)return[...n];let e=n.map(a=>{if(a.role==="assistant"&&Array.isArray(a.tool_calls)){let c=a.tool_calls.filter(l=>Xv(l));return{...a,...c.length>0?{tool_calls:c}:{tool_calls:void 0}}}return{...a}}),t=new Set;for(let a of e)if(!(a.role!=="assistant"||!Array.isArray(a.tool_calls)))for(let c of a.tool_calls)typeof c.id=="string"&&c.id&&t.add(c.id);let r=e.filter(a=>a.role!=="tool"?!0:!!(a.tool_call_id&&t.has(a.tool_call_id))),s=new Set;for(let a of r)a.role==="tool"&&typeof a.tool_call_id=="string"&&a.tool_call_id&&s.add(a.tool_call_id);let o=[];for(let a of r){if(a.role==="assistant"&&Array.isArray(a.tool_calls)&&a.tool_calls.length>0){let c=a.tool_calls.filter(l=>typeof l.id=="string"&&s.has(l.id));if(c.length===0){let{tool_calls:l,...d}=a;d.content!=null&&d.content!==""&&o.push(d);continue}if(c.length<a.tool_calls.length){o.push({...a,tool_calls:c});continue}}o.push(a)}let i=[];for(let a of o){let c=i.length>0?i[i.length-1]:void 0;if(a.role==="user"&&c?.role==="user"){i[i.length-1]=zv(c,a);continue}i.push(a)}return i}function Di(n,e){return Jv(e?.stopReason,e?.forcedStopReasons)?n.map(t=>{if(t.role!=="assistant")return{...t};let r={...t};for(let s of Vv)delete r[s];return r}):[...n]}function Oi(n,e){let t=e?.placeholderToolResult??"Error: Tool loop interrupted before the tool result was replayed.",r=new Set;for(let o of n)o.role==="tool"&&typeof o.tool_call_id=="string"&&o.tool_call_id&&r.add(o.tool_call_id);let s=[];for(let o of n)if(s.push({...o}),!(o.role!=="assistant"||!Array.isArray(o.tool_calls)||o.tool_calls.length===0))for(let i of o.tool_calls)typeof i.id!="string"||!i.id||r.has(i.id)||(r.add(i.id),s.push({role:"tool",tool_call_id:i.id,content:t}));return s}function Li(n,e){let t=Ni(n),r=Di(t,e);return Oi(r,e)}var Kv,Vv,$i=X(()=>{"use strict";Kv=["stop","aborted","timeout","cancelled","interrupted","error"],Vv=["tool_calls","toolCalls","function_call","functionCall","raw_tool_calls","rawToolCalls"]});function Qv(n){let e=new Set,t=new Set;for(let r of n){if(r.role==="assistant"&&Array.isArray(r.tool_calls))for(let s of r.tool_calls)typeof s.id=="string"&&s.id&&e.add(s.id);r.role==="tool"&&typeof r.tool_call_id=="string"&&r.tool_call_id&&t.add(r.tool_call_id)}return[...e].filter(r=>!t.has(r))}function Zv(n){let e=new Set;for(let t of n)t.role==="tool"&&typeof t.tool_call_id=="string"&&t.tool_call_id&&e.add(t.tool_call_id);return[...e]}function ek(n){return{round:n.round??0,maxRounds:n.maxRounds,pendingToolCallIds:[...n.pendingToolCallIds??[]],completedToolCallIds:[...n.completedToolCallIds??[]],lastStopReason:n.lastStopReason,replayMessages:[...n.replayMessages??[]]}}function ji(n,e){return{round:n.round+1,maxRounds:n.maxRounds,pendingToolCallIds:[...e.pendingToolCallIds??n.pendingToolCallIds],completedToolCallIds:[...e.completedToolCallIds??n.completedToolCallIds],lastStopReason:e.lastStopReason??n.lastStopReason,replayMessages:[...e.replayMessages??n.replayMessages]}}function Zr(n,e){return{round:n.round,maxRounds:n.maxRounds,pendingToolCallIds:[],completedToolCallIds:[...e.completedToolCallIds??n.completedToolCallIds],lastStopReason:e.lastStopReason??n.lastStopReason,replayMessages:[...e.replayMessages??n.replayMessages]}}function es(n){let e=[],t=Ni(n.replayMessages);t.length!==n.replayMessages.length&&e.push({kind:"drop-orphan-tool-result",detail:"Removed orphan tool results or invalid assistant tool calls."});let r=Di(t,n.options);r.some((o,i)=>o!==t[i])&&e.push({kind:"strip-forced-stop-tool-metadata",detail:"Removed assistant tool-call metadata after forced stop."});let s=Oi(r,n.options);return s.length>r.length&&e.push({kind:"inject-placeholder-tool-result",detail:"Injected placeholder tool result for pending tool calls."}),{state:ek({maxRounds:n.maxRounds,round:n.round,lastStopReason:n.lastStopReason,replayMessages:s,pendingToolCallIds:Qv(s),completedToolCallIds:Zv(s)}),recoveryActions:e}}var rd=X(()=>{"use strict";$i()});function Ui(n){return n?tk.has(n):!0}function Fi(n){return n===429||n===529}function ts(n,e=500,t=32e3){let r=Math.min(e*Math.pow(2,n-1),t);return r+Math.floor(Math.random()*r*.25)}function ns(){let n=process.env.QLOGICAGENT_PERSISTENT_RETRY;return n==="1"||n==="true"}var tk,xE,Zn,sd=X(()=>{"use strict";tk=new Set(["main","sdk","agent","compact","hook","verification","side_question"]);xE={maxBackoffMs:300*1e3,resetCapMs:360*60*1e3,heartbeatIntervalMs:3e4};Zn=class extends Error{constructor(t,r){super(`Model fallback triggered: ${t} -> ${r}`);this.originalModel=t;this.fallbackModel=r;this.name="FallbackTriggeredError"}originalModel;fallbackModel}});function Bi(n,e){if(e.allowedTools&&e.allowedTools.length>0){let t=new Set(e.allowedTools);return n.filter(r=>t.has(r))}if(e.toolAccessMode==="none")return[];if(e.toolAccessMode==="read-only"){let t=new Set(["file_edit","create_file","write_file","replace_string_in_file","multi_replace_string_in_file","create_directory","delete_file","rename_file","move_file","exec","run_in_terminal","run_command","git_commit","git_push","patch"]);return n.filter(r=>!t.has(r))}return e.canFork?[...n]:n.filter(t=>t!=="agent")}var Hi=X(()=>{"use strict";je()});function qi(){return[...od]}function rs(n){return od.find(e=>e.name===n)}var nk,rk,sk,ok,ik,ak,od,Wi=X(()=>{"use strict";nk={name:"general",label:"General Purpose",description:"A general-purpose sub-agent that can perform any task with full tool access.",maxTurns:200,toolAccessMode:"full",canFork:!1},rk={name:"explore",label:"Explore",description:"Fast read-only codebase exploration. Search files, read code, analyze structure. Cannot write or execute.",maxTurns:50,toolAccessMode:"read-only",allowedTools:["read_file","search","web_search","web_fetch","think","memory","tool_search"],canFork:!1},sk={name:"plan",label:"Plan",description:"Planning mode. Explore, analyze, and produce a structured plan. Cannot write files or execute commands.",maxTurns:80,toolAccessMode:"read-only",allowedTools:["read_file","search","web_search","web_fetch","think","memory","task","tool_search"],canFork:!1},ok={name:"code",label:"Code",description:"A coding sub-agent with full tool access for implementation tasks.",maxTurns:200,toolAccessMode:"full",canFork:!0},ik={name:"research",label:"Research",description:"Web research and information gathering. Searches the web, fetches pages, and synthesizes findings.",maxTurns:30,toolAccessMode:"read-only",allowedTools:["web_search","web_fetch","read_file","search","think","memory"],canFork:!1},ak={name:"verify",label:"Verify",description:"Verification agent. Runs tests, checks build output, validates changes are correct.",maxTurns:40,toolAccessMode:"full",allowedTools:["exec","read_file","search","think"],canFork:!1},od=[nk,rk,sk,ok,ik,ak]});var id=X(()=>{"use strict"});function Gi(n){return{promptTokens:0,hasAttemptedReactiveCompact:!1,currentMaxOutputTokens:n.maxOutputTokens,consecutiveTruncations:0,aborted:n.abortSignal?.aborted??!1}}function Ki(n,e){if(n.aborted)return{level:"blocking",usagePercent:100,reason:"budget_exhausted"};let t=e.contextWindowTokens-e.responseBufferTokens-n.currentMaxOutputTokens,r=t>0?n.promptTokens/t*100:100;return n.promptTokens>=t?n.hasAttemptedReactiveCompact||!e.reactiveCompactEnabled?{level:"blocking",usagePercent:r,reason:"prompt_too_long"}:{level:"blocking",usagePercent:r,reason:"prompt_too_long"}:r>=85?{level:"warning",usagePercent:r,remainingTokens:t-n.promptTokens}:{level:"ok"}}function Vi(n,e,t){let r=n.message?.toLowerCase()??"",s=n.status??0;return s===413||r.includes("prompt_too_long")||r.includes("context_length_exceeded")?!e.hasAttemptedReactiveCompact&&t.reactiveCompactEnabled?{action:"reactive_compact"}:{action:"abort",reason:"prompt_too_long_unrecoverable"}:s>=500&&s<600?{action:"retry",reason:`server_error_${s}`}:s===429?{action:"retry",reason:"rate_limited"}:s===401||s===403?{action:"abort",reason:"auth_error"}:s===404?{action:"abort",reason:"model_not_found"}:{action:"abort",reason:r||"unknown_error"}}function zi(n,e,t){if(!e.outputEscalationEnabled)return{shouldEscalate:!1,newMax:n.currentMaxOutputTokens};if(n.consecutiveTruncations>=3)return{shouldEscalate:!1,newMax:n.currentMaxOutputTokens};let r=Math.min(n.currentMaxOutputTokens*2,t);return r<=n.currentMaxOutputTokens?{shouldEscalate:!1,newMax:n.currentMaxOutputTokens}:{shouldEscalate:!0,newMax:r}}function Xi(n,e){return n.aborted?!0:e.abortSignal?.aborted?(n.aborted=!0,!0):!1}var ad=X(()=>{"use strict"});function Yi(){return{consecutiveFailures:0,attemptedThisTurn:!1,lastCompactAt:null,toolsAtLastCompact:[]}}function An(n,e=ck){return!(n.attemptedThisTurn||n.consecutiveFailures>=e.maxConsecutiveFailures)}var ck,cd=X(()=>{"use strict";ck={maxConsecutiveFailures:3,minMessagesAfterCompact:4,targetUsagePercent:50}});var er=X(()=>{"use strict";xl();Ol();Bo();Bo();Bl();Zl();td();$i();rd();sd();Hi();Wi();id();ad();cd()});import{mkdir as dk,writeFile as uk}from"fs/promises";import{join as ld}from"path";import{tmpdir as pk}from"os";function ud(){return{seenIds:new Set,replacements:new Map}}function pd(n){return ld(pk(),"qlogicagent-sessions",n,mk)}async function fk(n){try{await dk(pd(n),{recursive:!0})}catch{}}function hk(n,e){let t=e.replace(/[^a-zA-Z0-9_-]/g,"_");return ld(pd(n),`${t}.txt`)}function yk(n,e){if(n.length<=e)return{preview:n,hasMore:!1};let r=n.slice(0,e).lastIndexOf(`
|
|
16
|
-
`),s=r>e*.5?r:e;return{preview:n.slice(0,s),hasMore:!0}}function md(n){return n.includes(dd)}async function gd(n,e,t){await
|
|
14
|
+
${f}`},b=[...s,...u,y,...m],k=Date.now()-r,A=b.reduce((_,I)=>_+this.config.estimateTokens(I),0);return{messages:b,droppedCount:p.length,strategy:"head-tail-protected",metrics:{tokensBefore:i,tokensAfter:A,compressionRatio:i>0?A/i:1,latencyMs:k,usedLlm:!0,cacheInvalidated:!0}}}},zn=class{config;constructor(e){this.config=e}compress(e,t){let r=Kr(e),s=this.config.inner.compress(e,t),o=Kr(s.messages),i=r!==o&&s.droppedCount>0;return i&&this.config.onCacheInvalidated?.({droppedCount:s.droppedCount,strategy:s.strategy}),{...s,metrics:{...s.metrics??{tokensBefore:0,tokensAfter:0,compressionRatio:0,latencyMs:0,usedLlm:!1},cacheInvalidated:i}}}async compressAsync(e,t){let r=Kr(e),s=Jn(this.config.inner)?await this.config.inner.compressAsync(e,t):this.config.inner.compress(e,t),o=Kr(s.messages),i=r!==o&&s.droppedCount>0;return i&&this.config.onCacheInvalidated?.({droppedCount:s.droppedCount,strategy:s.strategy}),{...s,metrics:{...s.metrics??{tokensBefore:0,tokensAfter:0,compressionRatio:0,latencyMs:0,usedLlm:!1},cacheInvalidated:i}}}},jl={modelContextWindow:128e3,targetUsageRatio:.75,minBudget:16e3,maxBudget:12e4};Xn=class{events=[];maxEvents;constructor(e=100){this.maxEvents=e}record(e){this.events.push(e),this.events.length>this.maxEvents&&this.events.shift()}snapshot(){let e=this.events.length;if(e===0)return{totalCompressions:0,totalLlmCalls:0,totalCacheInvalidations:0,averageCompressionRatio:1,averageLatencyMs:0,totalTokensSaved:0,recentEvents:[]};let t=0,r=0,s=0,o=0,i=0;for(let a of this.events)t+=a.tokensBefore>0?a.tokensAfter/a.tokensBefore:1,r+=a.latencyMs,s+=Math.max(0,a.tokensBefore-a.tokensAfter),a.usedLlm&&o++,a.cacheInvalidated&&i++;return{totalCompressions:e,totalLlmCalls:o,totalCacheInvalidations:i,averageCompressionRatio:t/e,averageLatencyMs:r/e,totalTokensSaved:s,recentEvents:this.events.slice(-10)}}reset(){this.events.length=0}},Yn=class{engines=new Map;activeId;register(e){this.engines.set(e.id,e)}activate(e){return this.engines.has(e)?(this.activeId=e,!0):!1}getActive(){return this.activeId?this.engines.get(this.activeId):void 0}listEngines(){return Array.from(this.engines.values()).map(e=>({id:e.id,label:e.label,active:e.id===this.activeId}))}};lv=new Set(["file_read","read","Read","bash","shell","Bash","grep","search","Grep","grep_search","glob","Glob","file_search","web_search","WebSearch","web_fetch","WebFetch","file_edit","edit","Edit","file_write","write","Write"]),Vt=class{constructor(e=20,t=jo){this.preserveRecentCount=e;this.estimateTokens=t}preserveRecentCount;estimateTokens;compress(e,t){if(e.length<=this.preserveRecentCount)return{messages:e,droppedCount:0,strategy:"micro-compact"};let r=e.length-this.preserveRecentCount,s=0,o=0;return{messages:e.map((a,c)=>{if(c>=r||a.role!=="tool"||typeof a.content!="string"||!a.name||!lv.has(a.name)||a.content.length<=200)return a;let l=this.estimateTokens(a);return o+=l,s++,{...a,content:`[result cleared \u2014 ${a.content.length} chars]`}}),droppedCount:s,strategy:"micro-compact",metrics:s>0?{tokensBefore:0,tokensAfter:0,compressionRatio:0,latencyMs:0,usedLlm:!1,cacheInvalidated:!1}:void 0}}}});function Ho(){return{stages:[]}}function qo(n,e,t){let r=t?.thresholdMessages??40;if(n.filter(a=>a.role!=="system").length<=r)return{messages:n,stagedCount:0};let o=Ul(n,e),i=uv(o,e,r);if(i.length===0)return{messages:o,stagedCount:0};for(let a of i)e.stages.push(a);return o=Ul(n,e),{messages:o,stagedCount:i.length}}function Wo(n,e){let t=0;for(let r of e.stages)r.committed||(r.committed=!0,t++);return t===0?{messages:n,committed:0}:{messages:Fl(n,e),committed:t}}function Ul(n,e){return e.stages.filter(r=>r.committed).length===0?n:Fl(n,e)}function Fl(n,e){let t=e.stages.filter(s=>s.committed).sort((s,o)=>o.range[0]-s.range[0]),r=[...n];for(let s of t){let[o,i]=s.range;if(o>=r.length)continue;let a=Math.min(i,r.length),c={role:"system",content:s.summary};r.splice(o,a-o,c)}return r}function uv(n,e,t){let r=Math.max(0,n.length-Math.floor(t/2)),s=[],o=new Set(e.stages.map(c=>`${c.range[0]}-${c.range[1]}`)),i=-1,a=0;for(let c=0;c<r;c++){let l=n[c];if(l.role==="tool"||l.role==="assistant"&&typeof l.content=="string"&&l.content==="")i<0&&(i=c),a++;else{if(a>=3){let u=`${i}-${i+a}`;o.has(u)||s.push({id:`collapse_${i}_${i+a}`,range:[i,i+a],summary:`[${a} tool results collapsed]`,committed:!1})}i=-1,a=0}}if(a>=3){let c=`${i}-${i+a}`;o.has(c)||s.push({id:`collapse_${i}_${i+a}`,range:[i,i+a],summary:`[${a} tool results collapsed]`,committed:!1})}return s}var Bl=X(()=>{"use strict"});function _i(){return{maxRoundsLimit:100,defaultMaxRounds:25,defaultTemperature:0,maxToolBudgetCap:100,defaultToolBudget:Go,maxConsecutiveFailures:Ko,maxIdenticalCallRepeats:Vo,defaultContextWindowTokens:zo,responseBufferTokens:Xo,defaultMaxOutputTokens:Yo,defaultModelMaxOutputTokens:Jo,maxOutputTokensRecoveryLimit:Qo,escalatedMaxOutputTokens:Zo,diminishingReturnsThreshold:Xr,diminishingReturnsMinContinuations:ei,defaultMaxResultSizeChars:ti,maxToolResultsPerMessageChars:ni,toolResultPreviewBytes:Yr,heartbeatIntervalMs:ri,max529Retries:si,maxApiRetries:Rn,persistentRetryMaxBackoffMs:pv,persistentRetryResetCapMs:mv,compressionTargetUsageRatio:gv,compressionMinBudget:fv,compressionMaxBudget:hv,reactiveCompactMaxFailures:yv,reactiveCompactMinMessages:bv,reactiveCompactTargetPercent:vv,maxSkillsPerProject:oi,maxSkillsGlobal:Hl,minToolCallsForSkill:ii,minDistinctToolsForSkill:ai,skillCreationCooldownMs:ci,skillInjectionMaxChars:kv,skillInjectionMaxCount:Sv,skillRecallMaxSkills:li,skillRecallMaxContentChars:di,skillRecallCacheTtlMs:ui,maxForkDepth:pi,maxSessions:gi,taskSummaryTurnThreshold:fi,taskSummaryRegenInterval:hi,maxIncludeDepth:yi,maxInstructionChars:Tv,instructionsMaxFileSize:bi,instructionsMaxDirSize:vi,mediaMaxDownloadSize:ki,mediaMaxUploadSize:Rv,mediaDownloadTimeoutMs:Si,acpMaxSpawnRetries:Ti,acpRetryBackoffBase:Ri,acpRuntimeRestartMax:Ai,acpRuntimeRestartBackoffBase:wi,taskPollIntervalMs:Av,taskStoppedDisplayMs:wv,taskPanelGraceMs:xv,memoryPrefetchMaxSessionBytes:xi,memoryPrefetchLimitPerRecall:Pi,memoryMaxSurfacedEntries:Ii,dreamMinIntervalHours:Pv,dreamMinSessions:Iv,dreamScanIntervalMs:_v,idleDreamMinutes:Ev,dreamCooldownMs:Cv,dreamMaxDurationMs:Mv,teamBudgetTokens:mi}}var Go,Ko,Vo,zr,zo,Xo,Yo,Jo,Qo,Zo,Xr,ei,ti,ni,Yr,ri,si,Rn,pv,mv,gv,fv,hv,yv,bv,vv,oi,Hl,ii,ai,ci,ql,Wl,kv,Sv,li,di,ui,pi,mi,gi,fi,hi,Gl,Kl,yi,Tv,bi,vi,ki,Rv,Si,Ti,Ri,Ai,wi,Av,wv,xv,xi,Pi,Ii,Pv,Iv,_v,Ev,Cv,Mv,je=X(()=>{"use strict";Go=Math.min(Math.max(1,Number(process.env.TOOL_LOOP_DEFAULT_BUDGET)||25),100),Ko=3,Vo=2,zr=2,zo=128e3,Xo=13e3,Yo=16384,Jo=65536,Qo=3,Zo=65536,Xr=500,ei=3,ti=5e4,ni=2e5,Yr=2e3,ri=3e4,si=3,Rn=2,pv=3e5,mv=216e5,gv=.75,fv=16e3,hv=12e4,yv=3,bv=4,vv=50,oi=20,Hl=50,ii=3,ai=2,ci=300*1e3,ql=3,Wl=720*60*60*1e3,kv=4e3,Sv=5,li=3,di=800,ui=300*1e3,pi=4,mi=0,gi=50,fi=50,hi=30,Gl=3600*1e3,Kl=200,yi=5,Tv=4e4,bi=50*1024,vi=500*1024,ki=500*1024*1024,Rv=50*1024*1024,Si=3e5,Ti=2,Ri=3e3,Ai=3,wi=5e3,Av=1e3,wv=3e3,xv=3e4,xi=60*1024,Pi=10,Ii=100,Pv=24,Iv=5,_v=6e5,Ev=30,Cv=144e5,Mv=3e5});import{existsSync as Ei,readFileSync as zl,writeFileSync as Nv,readdirSync as Xl,mkdirSync as Dv}from"node:fs";import{join as Ci,dirname as Ov}from"node:path";function Jl(n){return Ci(n,".qlogicagent",Lv)}function $v(n){let e=Jl(n);try{return JSON.parse(zl(e,"utf8"))}catch{return{version:1,patterns:{}}}}function Vl(n,e){let t=Jl(n);Dv(Ov(t),{recursive:!0}),Nv(t,JSON.stringify(e,null,2),"utf8")}function jv(n){let e=Date.now()-Wl;for(let[t,r]of Object.entries(n.patterns))new Date(r.lastSeen).getTime()<e&&delete n.patterns[t]}function Ql(n,e){if(e.length===0)return!1;let t=Jr(e),r=$v(n);jv(r);let s=new Date().toISOString(),o=r.patterns[t];if(o||(o={signature:t,count:0,firstSeen:s,lastSeen:s,promoted:!1},r.patterns[t]=o),o.promoted)return Vl(n,r),!1;o.count++,o.lastSeen=s;let i=o.count>=ql;return i&&(o.promoted=!0),Vl(n,r),i}function Jr(n){return[...n].sort().join("+")}function Uv(n,e){if(!Ei(e))return null;let t=Jr(n);try{let r=Xl(e,{withFileTypes:!0});for(let s of r){if(!s.isDirectory())continue;let o=Ci(e,s.name,"SKILL.md");try{let a=zl(o,"utf8").match(/^tools:\s*\n((?:\s+-\s+\S+\n?)+)/m);if(a){let c=a[1].split(`
|
|
15
|
+
`).map(l=>l.replace(/^\s*-\s*/,"").trim()).filter(Boolean);if(Jr(c)===t)return s.name}}catch{}}}catch{}return null}function Fv(n){if(!Ei(n))return 0;try{return Xl(n,{withFileTypes:!0}).filter(e=>e.isDirectory()&&Ei(Ci(n,e.name,"SKILL.md"))).length}catch{return 0}}function Bv(n,e){return!(!n.ok||n.existingSkillName||!n.multiStep||n.toolCallCount<ii||n.distinctToolCount<ai||Date.now()-Yl<ci||e?.projectSkillsDir&&(Fv(e.projectSkillsDir)>=oi||e.tools.length>0&&Uv(e.tools,e.projectSkillsDir))||e?.projectRoot&&e.tools.length>0&&!Ql(e.projectRoot,e.tools))}function Hv(n){return n.existingSkillName?n.feedback==="negative":!1}function Qr(n,e){return Hv(n)?{type:"skill.improve",skillName:n.existingSkillName,reason:"negative user feedback on existing skill execution"}:Bv(n,e)?(Yl=Date.now(),{type:"skill.create",suggestedName:e.suggestedName??`auto-skill-${e.tools.slice(0,3).join("-")}`,description:`Multi-step orchestration using ${e.tools.join(", ")}`,tools:e.tools,stepCount:n.toolCallCount}):null}var Yl,Lv,Zl=X(()=>{"use strict";je();Yl=0,Lv="skill-patterns.json"});function ed(n){return n.function&&typeof n.function=="object"&&typeof n.function.name=="string"?n.function.name.trim():typeof n.name=="string"?n.name.trim():""}function qv(n){return n==="enabled-eligible"||n==="installed-awaiting-approval"}function Wv(n){return new Map((n??[]).map(e=>[e.toolName,e]))}function Gv(n){if(!n.eligibility?.length)return[...n.tools];let e=Wv(n.eligibility);return n.tools.filter(t=>{let r=ed(t);if(!r)return!1;let s=e.get(r);return!s||qv(s.status)})}function Kv(n){let e=[],t=n.compatibility??{},r=n.toolChoice;if(n.thinkingEnabled&&t.requireAutoWhenThinking){let s=typeof r=="object"&&r&&!Array.isArray(r)?String(r.type??""):r;s&&s!=="auto"&&s!=="none"&&(e.push("tool_choice downgraded to auto because thinking mode requires auto/none compatibility."),r="auto")}if(r==="required"&&t.allowRequiredToolChoice===!1){let s=t.requiredFallback??"auto";e.push(`tool_choice=required is not supported by this provider; downgraded to ${s}.`),r=s}if(r&&typeof r=="object"&&!Array.isArray(r)&&r.type==="function"&&t.allowNamedToolChoice===!1){let s=t.namedFallback??"required";e.push(`named tool_choice is not supported by this provider; downgraded to ${s}.`),r=s}return{normalizedToolChoice:r,warnings:e}}function Mi(n){let e=Kv({toolChoice:n.toolChoice,thinkingEnabled:n.thinkingEnabled,compatibility:n.compatibility}),t=e.normalizedToolChoice,r=[...e.warnings],s=Gv({tools:n.tools,eligibility:n.eligibility});if(!t||t==="auto")return{tools:s,normalizedToolChoice:t,warnings:r};if(t==="none")return{tools:[],normalizedToolChoice:"none",warnings:r};if(t==="required"){if(s.length===0)throw new Error("tool_choice=required but no tools were provided");return{tools:s,normalizedToolChoice:"required",extraSystemPrompt:"You must call one of the available tools before responding.",warnings:r}}if(typeof t=="object"&&!Array.isArray(t)&&t.type==="function"){let o=t.function??void 0,i=typeof o?.name=="string"?o.name.trim():"";if(!i)throw new Error("tool_choice.function.name is required");let a=s.filter(c=>ed(c)===i);if(a.length===0)throw new Error(`tool_choice requested unknown tool: ${i}`);return{tools:a,normalizedToolChoice:{type:"function",function:{name:i}},extraSystemPrompt:`You must call the ${i} tool before responding.`,warnings:r}}return{tools:s,normalizedToolChoice:t,warnings:r}}var td=X(()=>{"use strict"});function nd(n){return n==null?[]:typeof n=="string"?n.length>0?[{type:"text",text:n}]:[]:Array.isArray(n)?n:[{type:"text",text:String(n)}]}function Xv(n,e){return{...n,content:[...nd(n.content),...nd(e.content)]}}function Yv(n){if(!n||typeof n!="object")return!1;if(n.function&&typeof n.function=="object"){let e=n.function.name;if(typeof e=="string"&&e.length>0)return!0}return typeof n.name=="string"&&n.name.length>0}function Jv(n){return new Set((n??Vv).map(e=>e.trim().toLowerCase()))}function Qv(n,e){return n?Jv(e).has(n.trim().toLowerCase()):!1}function Ni(n){if(!Array.isArray(n)||n.length===0)return[...n];let e=n.map(a=>{if(a.role==="assistant"&&Array.isArray(a.tool_calls)){let c=a.tool_calls.filter(l=>Yv(l));return{...a,...c.length>0?{tool_calls:c}:{tool_calls:void 0}}}return{...a}}),t=new Set;for(let a of e)if(!(a.role!=="assistant"||!Array.isArray(a.tool_calls)))for(let c of a.tool_calls)typeof c.id=="string"&&c.id&&t.add(c.id);let r=e.filter(a=>a.role!=="tool"?!0:!!(a.tool_call_id&&t.has(a.tool_call_id))),s=new Set;for(let a of r)a.role==="tool"&&typeof a.tool_call_id=="string"&&a.tool_call_id&&s.add(a.tool_call_id);let o=[];for(let a of r){if(a.role==="assistant"&&Array.isArray(a.tool_calls)&&a.tool_calls.length>0){let c=a.tool_calls.filter(l=>typeof l.id=="string"&&s.has(l.id));if(c.length===0){let{tool_calls:l,...d}=a;d.content!=null&&d.content!==""&&o.push(d);continue}if(c.length<a.tool_calls.length){o.push({...a,tool_calls:c});continue}}o.push(a)}let i=[];for(let a of o){let c=i.length>0?i[i.length-1]:void 0;if(a.role==="user"&&c?.role==="user"){i[i.length-1]=Xv(c,a);continue}i.push(a)}return i}function Di(n,e){return Qv(e?.stopReason,e?.forcedStopReasons)?n.map(t=>{if(t.role!=="assistant")return{...t};let r={...t};for(let s of zv)delete r[s];return r}):[...n]}function Oi(n,e){let t=e?.placeholderToolResult??"Error: Tool loop interrupted before the tool result was replayed.",r=new Set;for(let o of n)o.role==="tool"&&typeof o.tool_call_id=="string"&&o.tool_call_id&&r.add(o.tool_call_id);let s=[];for(let o of n)if(s.push({...o}),!(o.role!=="assistant"||!Array.isArray(o.tool_calls)||o.tool_calls.length===0))for(let i of o.tool_calls)typeof i.id!="string"||!i.id||r.has(i.id)||(r.add(i.id),s.push({role:"tool",tool_call_id:i.id,content:t}));return s}function Li(n,e){let t=Ni(n),r=Di(t,e);return Oi(r,e)}var Vv,zv,$i=X(()=>{"use strict";Vv=["stop","aborted","timeout","cancelled","interrupted","error"],zv=["tool_calls","toolCalls","function_call","functionCall","raw_tool_calls","rawToolCalls"]});function Zv(n){let e=new Set,t=new Set;for(let r of n){if(r.role==="assistant"&&Array.isArray(r.tool_calls))for(let s of r.tool_calls)typeof s.id=="string"&&s.id&&e.add(s.id);r.role==="tool"&&typeof r.tool_call_id=="string"&&r.tool_call_id&&t.add(r.tool_call_id)}return[...e].filter(r=>!t.has(r))}function ek(n){let e=new Set;for(let t of n)t.role==="tool"&&typeof t.tool_call_id=="string"&&t.tool_call_id&&e.add(t.tool_call_id);return[...e]}function tk(n){return{round:n.round??0,maxRounds:n.maxRounds,pendingToolCallIds:[...n.pendingToolCallIds??[]],completedToolCallIds:[...n.completedToolCallIds??[]],lastStopReason:n.lastStopReason,replayMessages:[...n.replayMessages??[]]}}function ji(n,e){return{round:n.round+1,maxRounds:n.maxRounds,pendingToolCallIds:[...e.pendingToolCallIds??n.pendingToolCallIds],completedToolCallIds:[...e.completedToolCallIds??n.completedToolCallIds],lastStopReason:e.lastStopReason??n.lastStopReason,replayMessages:[...e.replayMessages??n.replayMessages]}}function Zr(n,e){return{round:n.round,maxRounds:n.maxRounds,pendingToolCallIds:[],completedToolCallIds:[...e.completedToolCallIds??n.completedToolCallIds],lastStopReason:e.lastStopReason??n.lastStopReason,replayMessages:[...e.replayMessages??n.replayMessages]}}function es(n){let e=[],t=Ni(n.replayMessages);t.length!==n.replayMessages.length&&e.push({kind:"drop-orphan-tool-result",detail:"Removed orphan tool results or invalid assistant tool calls."});let r=Di(t,n.options);r.some((o,i)=>o!==t[i])&&e.push({kind:"strip-forced-stop-tool-metadata",detail:"Removed assistant tool-call metadata after forced stop."});let s=Oi(r,n.options);return s.length>r.length&&e.push({kind:"inject-placeholder-tool-result",detail:"Injected placeholder tool result for pending tool calls."}),{state:tk({maxRounds:n.maxRounds,round:n.round,lastStopReason:n.lastStopReason,replayMessages:s,pendingToolCallIds:Zv(s),completedToolCallIds:ek(s)}),recoveryActions:e}}var rd=X(()=>{"use strict";$i()});function Ui(n){return n?nk.has(n):!0}function Fi(n){return n===429||n===529}function ts(n,e=500,t=32e3){let r=Math.min(e*Math.pow(2,n-1),t);return r+Math.floor(Math.random()*r*.25)}function ns(){let n=process.env.QLOGICAGENT_PERSISTENT_RETRY;return n==="1"||n==="true"}var nk,xE,Zn,sd=X(()=>{"use strict";nk=new Set(["main","sdk","agent","compact","hook","verification","side_question"]);xE={maxBackoffMs:300*1e3,resetCapMs:360*60*1e3,heartbeatIntervalMs:3e4};Zn=class extends Error{constructor(t,r){super(`Model fallback triggered: ${t} -> ${r}`);this.originalModel=t;this.fallbackModel=r;this.name="FallbackTriggeredError"}originalModel;fallbackModel}});function Bi(n,e){if(e.allowedTools&&e.allowedTools.length>0){let t=new Set(e.allowedTools);return n.filter(r=>t.has(r))}if(e.toolAccessMode==="none")return[];if(e.toolAccessMode==="read-only"){let t=new Set(["file_edit","create_file","write_file","replace_string_in_file","multi_replace_string_in_file","create_directory","delete_file","rename_file","move_file","exec","run_in_terminal","run_command","git_commit","git_push","patch"]);return n.filter(r=>!t.has(r))}return e.canFork?[...n]:n.filter(t=>t!=="agent")}var Hi=X(()=>{"use strict";je()});function qi(){return[...od]}function rs(n){return od.find(e=>e.name===n)}var rk,sk,ok,ik,ak,ck,od,Wi=X(()=>{"use strict";rk={name:"general",label:"General Purpose",description:"A general-purpose sub-agent that can perform any task with full tool access.",maxTurns:200,toolAccessMode:"full",canFork:!1},sk={name:"explore",label:"Explore",description:"Fast read-only codebase exploration. Search files, read code, analyze structure. Cannot write or execute.",maxTurns:50,toolAccessMode:"read-only",allowedTools:["read_file","search","web_search","web_fetch","think","memory","tool_search"],canFork:!1},ok={name:"plan",label:"Plan",description:"Planning mode. Explore, analyze, and produce a structured plan. Cannot write files or execute commands.",maxTurns:80,toolAccessMode:"read-only",allowedTools:["read_file","search","web_search","web_fetch","think","memory","task","tool_search"],canFork:!1},ik={name:"code",label:"Code",description:"A coding sub-agent with full tool access for implementation tasks.",maxTurns:200,toolAccessMode:"full",canFork:!0},ak={name:"research",label:"Research",description:"Web research and information gathering. Searches the web, fetches pages, and synthesizes findings.",maxTurns:30,toolAccessMode:"read-only",allowedTools:["web_search","web_fetch","read_file","search","think","memory"],canFork:!1},ck={name:"verify",label:"Verify",description:"Verification agent. Runs tests, checks build output, validates changes are correct.",maxTurns:40,toolAccessMode:"full",allowedTools:["exec","read_file","search","think"],canFork:!1},od=[rk,sk,ok,ik,ak,ck]});var id=X(()=>{"use strict"});function Gi(n){return{promptTokens:0,hasAttemptedReactiveCompact:!1,currentMaxOutputTokens:n.maxOutputTokens,consecutiveTruncations:0,aborted:n.abortSignal?.aborted??!1}}function Ki(n,e){if(n.aborted)return{level:"blocking",usagePercent:100,reason:"budget_exhausted"};let t=e.contextWindowTokens-e.responseBufferTokens-n.currentMaxOutputTokens,r=t>0?n.promptTokens/t*100:100;return n.promptTokens>=t?n.hasAttemptedReactiveCompact||!e.reactiveCompactEnabled?{level:"blocking",usagePercent:r,reason:"prompt_too_long"}:{level:"blocking",usagePercent:r,reason:"prompt_too_long"}:r>=85?{level:"warning",usagePercent:r,remainingTokens:t-n.promptTokens}:{level:"ok"}}function Vi(n,e,t){let r=n.message?.toLowerCase()??"",s=n.status??0;return s===413||r.includes("prompt_too_long")||r.includes("context_length_exceeded")?!e.hasAttemptedReactiveCompact&&t.reactiveCompactEnabled?{action:"reactive_compact"}:{action:"abort",reason:"prompt_too_long_unrecoverable"}:s>=500&&s<600?{action:"retry",reason:`server_error_${s}`}:s===429?{action:"retry",reason:"rate_limited"}:s===401||s===403?{action:"abort",reason:"auth_error"}:s===404?{action:"abort",reason:"model_not_found"}:{action:"abort",reason:r||"unknown_error"}}function zi(n,e,t){if(!e.outputEscalationEnabled)return{shouldEscalate:!1,newMax:n.currentMaxOutputTokens};if(n.consecutiveTruncations>=3)return{shouldEscalate:!1,newMax:n.currentMaxOutputTokens};let r=Math.min(n.currentMaxOutputTokens*2,t);return r<=n.currentMaxOutputTokens?{shouldEscalate:!1,newMax:n.currentMaxOutputTokens}:{shouldEscalate:!0,newMax:r}}function Xi(n,e){return n.aborted?!0:e.abortSignal?.aborted?(n.aborted=!0,!0):!1}var ad=X(()=>{"use strict"});function Yi(){return{consecutiveFailures:0,attemptedThisTurn:!1,lastCompactAt:null,toolsAtLastCompact:[]}}function An(n,e=lk){return!(n.attemptedThisTurn||n.consecutiveFailures>=e.maxConsecutiveFailures)}var lk,cd=X(()=>{"use strict";lk={maxConsecutiveFailures:3,minMessagesAfterCompact:4,targetUsagePercent:50}});var er=X(()=>{"use strict";xl();Ol();Bo();Bo();Bl();Zl();td();$i();rd();sd();Hi();Wi();id();ad();cd()});import{mkdir as uk,writeFile as pk}from"fs/promises";import{join as ld}from"path";import{tmpdir as mk}from"os";function ud(){return{seenIds:new Set,replacements:new Map}}function pd(n){return ld(mk(),"qlogicagent-sessions",n,gk)}async function hk(n){try{await uk(pd(n),{recursive:!0})}catch{}}function yk(n,e){let t=e.replace(/[^a-zA-Z0-9_-]/g,"_");return ld(pd(n),`${t}.txt`)}function bk(n,e){if(n.length<=e)return{preview:n,hasMore:!1};let r=n.slice(0,e).lastIndexOf(`
|
|
16
|
+
`),s=r>e*.5?r:e;return{preview:n.slice(0,s),hasMore:!0}}function md(n){return n.includes(dd)}async function gd(n,e,t){await hk(t);let r=yk(t,e);try{await pk(r,n,{encoding:"utf-8",flag:"wx"})}catch(i){if(i.code!=="EEXIST")return null}let{preview:s,hasMore:o}=bk(n,Yr);return{filepath:r,originalSize:n.length,preview:s,hasMore:o}}function fd(n){let e=`${dd}
|
|
17
17
|
`;return e+=`Output too large (${n.originalSize} chars). Full output saved to: ${n.filepath}
|
|
18
18
|
|
|
19
19
|
`,e+=`Preview (first ${Yr} bytes):
|
|
20
20
|
`,e+=n.preview,e+=n.hasMore?`
|
|
21
21
|
...
|
|
22
22
|
`:`
|
|
23
|
-
`,e+=
|
|
24
|
-
...[truncated ${n.length-r} chars]`}function bk(n){let e=[],t=[];for(let r of n)r.role==="tool"&&typeof r.content=="string"&&r.tool_call_id?md(r.content)||t.push({toolCallId:r.tool_call_id,content:r.content,size:r.content.length}):r.role==="assistant"&&t.length>0&&(e.push(t),t=[]);return t.length>0&&e.push(t),e}function vk(n,e){let t=[],r=[],s=[];for(let o of n){let i=e.replacements.get(o.toolCallId);i!==void 0?t.push({...o,replacement:i}):e.seenIds.has(o.toolCallId)?r.push(o):s.push(o)}return{mustReapply:t,frozen:r,fresh:s}}function kk(n,e,t){let r=[...n].sort((i,a)=>a.size-i.size),s=[],o=e+n.reduce((i,a)=>i+a.size,0);for(let i of r){if(o<=t)break;s.push(i),o-=i.size}return s}async function yd(n,e,t,r=ni){let s=bk(n);if(s.length===0)return{messages:n,newlyReplacedCount:0};let o=new Map,i=[];for(let d of s){let{mustReapply:u,frozen:p,fresh:m}=vk(d,e);for(let k of u)o.set(k.toolCallId,k.replacement);if(m.length===0){for(let k of d)e.seenIds.add(k.toolCallId);continue}let h=p.reduce((k,A)=>k+A.size,0),f=m.reduce((k,A)=>k+A.size,0),y=h+f>r?kk(m,h,r):[],b=new Set(y.map(k=>k.toolCallId));for(let k of d)b.has(k.toolCallId)||e.seenIds.add(k.toolCallId);y.length>0&&i.push(...y)}if(o.size===0&&i.length===0)return{messages:n,newlyReplacedCount:0};let a=await Promise.all(i.map(async d=>{let u=await gd(d.content,d.toolCallId,t);return{candidate:d,result:u}})),c=0;for(let{candidate:d,result:u}of a){if(e.seenIds.add(d.toolCallId),!u)continue;let p=fd(u);o.set(d.toolCallId,p),e.replacements.set(d.toolCallId,p),c++}return o.size===0?{messages:n,newlyReplacedCount:0}:{messages:n.map(d=>{if(d.role!=="tool"||!d.tool_call_id)return d;let u=o.get(d.tool_call_id);return u===void 0?d:{...d,content:u}}),newlyReplacedCount:c}}var mk,dd,gk,Ji=X(()=>{"use strict";je();mk="tool-results",dd="<persisted-output>",gk="</persisted-output>"});function Rk(n){try{return JSON.parse(n)}catch{return}}var Sk,Tk,ss,bd=X(()=>{"use strict";er();Ji();Sk=new Set(["read_file","file_read","FileRead","grep","Grep","glob","Glob","search","list_dir","find_files","web_fetch","web_search","WebFetch","WebSearch"]),Tk=new Set(["bash","execute_command","Bash","shell"]),ss=class{tools=[];hasErrored=!1;erroredToolDescription="";discarded=!1;siblingAbortController;progressResolve;config;concurrencySafe;constructor(e){this.config=e,this.concurrencySafe=e.concurrencySafeTools??Sk,this.siblingAbortController=new AbortController,e.signal&&e.signal.addEventListener("abort",()=>{this.siblingAbortController.abort("parent_abort")},{once:!0})}discard(){this.discarded=!0}addTool(e){let t=this.concurrencySafe.has(e.function.name);this.tools.push({id:e.id,toolCall:e,status:"queued",isConcurrencySafe:t,results:[],pendingProgress:[]}),this.processQueue()}canExecuteTool(e){let t=this.tools.filter(s=>s.status==="executing"),r=this.config.maxConcurrentTools;return r&&r>0&&t.length>=r?!1:t.length===0||e&&t.every(s=>s.isConcurrencySafe)}async processQueue(){for(let e of this.tools)if(e.status==="queued"){if(this.canExecuteTool(e.isConcurrencySafe))await this.executeTool(e);else if(!e.isConcurrencySafe)break}}getAbortReason(){return this.discarded?"discarded":this.hasErrored?"sibling_error":this.config.signal?.aborted?"user_interrupted":null}getToolDescription(e){let t;try{t=JSON.parse(e.toolCall.function.arguments)}catch{}let r=t?.command??t?.file_path??t?.pattern??"";if(typeof r=="string"&&r.length>0){let s=r.length>40?r.slice(0,40)+"\u2026":r;return`${e.toolCall.function.name}(${s})`}return e.toolCall.function.name}createSyntheticError(e,t){let r=this.erroredToolDescription,s=t==="user_interrupted"?"User rejected tool use":t==="discarded"?"Streaming fallback - tool execution discarded":r?`Cancelled: parallel tool call ${r} errored`:"Cancelled: parallel tool call errored";return{callId:e.id,toolName:e.toolCall.function.name,ok:!1,error:s,message:Kt(e.id,{ok:!1,error:s})}}async executeTool(e){e.status="executing";let r=(async()=>{let s=this.getAbortReason();if(s){e.results.push(this.createSyntheticError(e,s)),e.status="completed";return}let{toolInvoker:o,hooks:i,sessionId:a,turnId:c,log:l}=this.config,d=e.toolCall.function.name,u=!1,p=e.toolCall.function.arguments;if(i)try{let k=await i.invoke("tool.before_invoke",{sessionId:a,turnId:c,callId:e.id,toolName:d,arguments:Rk(p)});if(k.action==="abort"){let A=k.reason??"blocked by policy";l.info(`tool ${d} blocked: ${A}`),e.results.push({callId:e.id,toolName:d,ok:!1,error:A,blocked:!0,blockReason:A,message:Kt(e.id,{ok:!1,error:A})}),e.status="completed";return}k.action==="continue"&&k.context?.arguments&&(p=JSON.stringify(k.context.arguments))}catch{}let m=await o.invoke(c,d,p,this.siblingAbortController.signal),h=this.getAbortReason();if(h&&!u){e.results.push(this.createSyntheticError(e,h)),e.status="completed";return}let f=!m.error,y=m.result;f&&y&&y.length>5e4&&(y=await hd(y,e.id,a));let b=Kt(e.id,{ok:f,payload:y,error:m.error,toolReferences:m.toolReferences,imageUrls:m.imageUrls});f||(u=!0,Tk.has(d)&&(this.hasErrored=!0,this.erroredToolDescription=this.getToolDescription(e),this.siblingAbortController.abort("sibling_error"))),i?.invoke(f?"tool.after_invoke":"tool.invoke_failed",{sessionId:a,turnId:c,callId:e.id,toolName:d,ok:f,...m.error?{error:m.error}:{}}).catch(()=>{}),e.results.push({callId:e.id,toolName:d,ok:f,error:m.error,message:b}),e.status="completed"})();e.promise=r,r.finally(()=>{this.processQueue()})}*getCompletedResults(){if(!this.discarded){for(let e of this.tools)if(e.status!=="yielded"){if(e.status==="completed"&&e.results.length>0){e.status="yielded";for(let t of e.results)yield t}else if(e.status==="executing"&&!e.isConcurrencySafe)break}}}async*getRemainingResults(){if(!this.discarded){for(;this.hasUnfinishedTools();){await this.processQueue();for(let e of this.getCompletedResults())yield e;if(this.hasExecutingTools()&&!this.hasCompletedResults()){let e=this.tools.filter(r=>r.status==="executing"&&r.promise).map(r=>r.promise),t=new Promise(r=>{this.progressResolve=r});e.length>0&&await Promise.race([...e,t])}}for(let e of this.getCompletedResults())yield e}}hasCompletedResults(){return this.tools.some(e=>e.status==="completed")}hasExecutingTools(){return this.tools.some(e=>e.status==="executing")}hasUnfinishedTools(){return this.tools.some(e=>e.status!=="yielded")}}});import{homedir as Ak}from"node:os";import{join as xe}from"node:path";import{existsSync as wk}from"node:fs";function q(){return process.env.QLOGICAGENT_HOME||xe(Ak(),qe)}function vd(){return xe(q(),"plugins")}function Dt(){return xe(q(),"skills")}function it(){return xe(q(),"settings.json")}function kd(){return xe(q(),"plugin-cache")}function Sd(){return xe(q(),"mcp.json")}function Td(){return xe(q(),"marketplace.json")}function Rd(){return xe(q(),"workflows")}function Ad(){return xe(q(),"rules")}function Me(n){if(!n)throw new Error("getProjectAgentDir: cwd is required (must not fall back to process.cwd())");return xe(n,qe)}function wd(n){return xe(Me(n),"workflows")}function Tt(n){return xe(Me(n),"skills")}function tr(n){return xe(Me(n),"INSTRUCTIONS.md")}function wn(n){return xe(Me(n),"rules")}function Ot(n){return xe(Me(n),"sessions")}function xd(n,e){let t=xe(Me(n),"checkpoints");return e?xe(t,e):t}function Pd(n){return xe(n,qe,"hooks")}function Id(n,e){return n.filter(t=>t!==e&&wk(xe(t,qe,"skills")))}var qe,ae=X(()=>{"use strict";qe=".qlogicagent"});var os,_d=X(()=>{"use strict";os=class{pools=new Map;runtimeStates=new Map;constructor(e){if(e)for(let t of e){this.pools.set(t.providerId,t);for(let r of t.keys)this.runtimeStates.set(r.id,this.createInitialState())}}acquireKey(e){let t=this.pools.get(e);if(!t||t.keys.length===0)return null;let r=Date.now(),s=this.getHealthyCandidates(t,r);if(s.length===0)return null;let o=this.selectByStrategy(s,t.strategy,r);if(!o)return null;let i=this.runtimeStates.get(o.id);return i.inFlight++,i.totalRequests++,i.lastUsedAt=r,i.requestTimestamps.push(r),{keyId:o.id,apiKey:o.key,providerId:e,release:a=>this.releaseKey(o.id,a)}}releaseKey(e,t){let r=this.runtimeStates.get(e);if(r)if(r.inFlight=Math.max(0,r.inFlight-1),t.success)r.consecutiveErrors=0,r.healthStatus="healthy",t.tokens&&(r.totalTokens+=t.tokens,r.tokenCounts.push(t.tokens));else if(r.consecutiveErrors++,r.lastErrorAt=Date.now(),t.errorCode===429){let s=t.retryAfter?t.retryAfter*1e3:3e4;r.cooldownUntil=Date.now()+s,r.healthStatus="cooldown"}else r.consecutiveErrors>=5?(r.cooldownUntil=Date.now()+6e4,r.healthStatus="cooldown"):r.consecutiveErrors>=3&&(r.healthStatus="degraded")}addProvider(e,t){this.pools.has(e)||this.pools.set(e,{providerId:e,baseUrl:t?.baseUrl,strategy:t?.strategy??"weighted-round-robin",keys:[],rateLimit:t?.rateLimit})}removeProvider(e){let t=this.pools.get(e);if(t){for(let r of t.keys)this.runtimeStates.delete(r.id);this.pools.delete(e)}}addKey(e,t,r){let s=this.pools.get(e);s||(s={providerId:e,strategy:"weighted-round-robin",keys:[]},this.pools.set(e,s));let o=r?.id??crypto.randomUUID(),i={id:o,key:t,label:r?.label,weight:r?.weight??1,enabled:r?.enabled??!0};return s.keys.push(i),this.runtimeStates.set(o,this.createInitialState()),o}removeKey(e){for(let t of this.pools.values()){let r=t.keys.findIndex(s=>s.id===e);if(r!==-1){t.keys.splice(r,1),this.runtimeStates.delete(e);return}}}updateKey(e,t){for(let r of this.pools.values()){let s=r.keys.find(o=>o.id===e);if(s){if(t.label!==void 0&&(s.label=t.label),t.weight!==void 0&&(s.weight=t.weight),t.enabled!==void 0){s.enabled=t.enabled;let o=this.runtimeStates.get(e);o&&(o.healthStatus=t.enabled?"healthy":"disabled")}return}}}setKeyHealth(e,t){let r=this.runtimeStates.get(e);r&&(r.healthStatus=t)}setStrategy(e,t){let r=this.pools.get(e);r&&(r.strategy=t)}setRateLimit(e,t){let r=this.pools.get(e);r&&(r.rateLimit=t)}getPoolStatus(e){let t=this.pools.get(e);return t?this.buildPoolStatus(t):null}getAllStatus(){return[...this.pools.values()].map(e=>this.buildPoolStatus(e))}getProviderIds(){return[...this.pools.keys()]}hasProvider(e){return this.pools.has(e)}hasAvailableKey(e){let t=this.pools.get(e);return t?this.getHealthyCandidates(t,Date.now()).length>0:!1}exportConfig(){return[...this.pools.values()]}reloadConfig(e){let t=new Set;for(let r of e){this.pools.set(r.providerId,r);for(let s of r.keys)t.add(s.id),this.runtimeStates.has(s.id)||this.runtimeStates.set(s.id,this.createInitialState())}for(let r of[...this.pools.keys()])e.some(s=>s.providerId===r)||this.pools.delete(r);for(let r of[...this.runtimeStates.keys()])t.has(r)||this.runtimeStates.delete(r)}createInitialState(){return{inFlight:0,totalRequests:0,totalTokens:0,lastUsedAt:0,lastErrorAt:0,consecutiveErrors:0,cooldownUntil:0,healthStatus:"healthy",requestTimestamps:[],tokenCounts:[]}}getHealthyCandidates(e,t){let r=[];for(let s of e.keys){if(!s.enabled)continue;let o=this.runtimeStates.get(s.id);if(o){if(o.healthStatus==="cooldown")if(t>=o.cooldownUntil)o.healthStatus="healthy",o.consecutiveErrors=0;else continue;o.healthStatus!=="disabled"&&(e.rateLimit?.rpm&&(this.pruneWindow(o.requestTimestamps,t),o.requestTimestamps.length>=e.rateLimit.rpm*.9)||e.rateLimit?.tpm&&(this.pruneWindow(o.tokenCounts,t),o.tokenCounts.reduce((a,c)=>a+c,0)>=e.rateLimit.tpm*.9)||r.push(s))}}return r}selectByStrategy(e,t,r){if(e.length===0)return null;if(e.length===1)return e[0];switch(t){case"weighted-round-robin":return this.weightedRandom(e);case"least-busy":return this.leastBusy(e);case"random":return e[Math.floor(Math.random()*e.length)];default:return this.weightedRandom(e)}}weightedRandom(e){let t=e.reduce((s,o)=>s+o.weight,0),r=Math.random()*t;for(let s of e)if(r-=s.weight,r<=0)return s;return e[e.length-1]}leastBusy(e){let t=1/0,r=e[0];for(let s of e){let i=this.runtimeStates.get(s.id)?.inFlight??0;(i<t||i===t&&s.weight>r.weight)&&(t=i,r=s)}return r}pruneWindow(e,t){let r=t-6e4;for(;e.length>0&&e[0]<r;)e.shift()}buildPoolStatus(e){return{providerId:e.providerId,baseUrl:e.baseUrl,strategy:e.strategy,rateLimit:e.rateLimit,keys:e.keys.map(t=>{let r=this.runtimeStates.get(t.id)??this.createInitialState();return{...t,inFlight:r.inFlight,totalRequests:r.totalRequests,totalTokens:r.totalTokens,lastUsedAt:r.lastUsedAt,lastErrorAt:r.lastErrorAt,consecutiveErrors:r.consecutiveErrors,cooldownUntil:r.cooldownUntil,healthStatus:t.enabled?r.healthStatus:"disabled"}})}}}});var Ed={};en(Ed,{ALL_PURPOSES:()=>rr,ModelRegistry:()=>is,deriveModelPurposes:()=>_k,getModelRegistry:()=>Y,resetModelRegistry:()=>Ik});import*as Ze from"node:fs";import{ProviderRegistry as xk,ProviderVariantResolver as Pk}from"@xiaozhiclaw/provider-core";function Y(){return nr||(nr=new is,nr.load()),nr}function Ik(){nr=null}function _k(n){let e=[];switch((!n.mediaType||n.mediaType==="image_understanding"||n.mediaType==="video_understanding")&&e.push("textGeneration"),(n.vision||n.mediaType==="image_understanding")&&e.push("imageUnderstanding"),n.mediaType==="video_understanding"&&e.push("videoUnderstanding"),n.mediaType){case"image":e.push("imageGeneration");break;case"video":e.push("videoGeneration");break;case"tts":e.push("tts");break;case"stt":e.push("stt");break;case"music":case"music_realtime":e.push("musicGeneration");break;case"voice_clone":e.push("voiceClone");break;case"embedding":e.push("embedding");break;case"3d":e.push("threeDGeneration");break;case"realtime_audio":e.push("realtimeAudio");break}return e.includes("textGeneration")&&e.push("smallModel"),[...new Set(e.length>0?e:["textGeneration"])]}function Ek(n){switch(n){case"openai-chat":case"openai-responses":case"anthropic-messages":case"volcengine-responses":return n;default:return}}function Ck(n,e){switch(n){case"imageUnderstanding":case"videoUnderstanding":case"imageGeneration":case"videoGeneration":case"threeDGeneration":case"stt":case"tts":case"voiceClone":case"musicGeneration":case"realtimeAudio":case"realtimeVideo":case"embedding":return;default:return Ek(e)}}function Mk(n){switch(n){case"imageUnderstanding":case"videoUnderstanding":return["vision"];case"imageGeneration":case"videoGeneration":case"threeDGeneration":case"stt":case"tts":case"voiceClone":case"musicGeneration":case"realtimeAudio":case"realtimeVideo":case"embedding":return["media"];default:return[]}}var rr,is,nr,dt=X(()=>{"use strict";ae();_d();rr=["textGeneration","smallModel","stt","tts","imageGeneration","imageUnderstanding","videoGeneration","videoUnderstanding","threeDGeneration","embedding","voiceClone","musicGeneration","realtimeAudio","realtimeVideo"],is=class{keyPool;coreProviderRegistry=new xk;providerVariantResolver=new Pk(this.coreProviderRegistry);models=new Map;modelEnabledOverrides=new Map;bindings={};settingsPath;changeListeners=[];constructor(e){this.settingsPath=it(),this.keyPool=new os(e?.providers),e?.models&&this.loadModelState(e.models),e?.bindings&&(this.bindings={...e.bindings})}getActiveModel(e){let t=this.bindings[e];if(!t)return null;let r=this.models.get(t);if(!r||!r.enabled)return null;let s=this.resolveTechnicalVariant(r,e),o=s?.provider??r.provider,i=s?.nativeModelId??r.nativeModelId??r.model,a=this.acquireKeyForProviderVariant(o);if(!a)return null;let{keyHandle:c,keyProviderId:l}=a,d=this.getProviderBaseUrl(o),u=this.getProviderBaseUrl(l);return{provider:o,model:i,apiKey:c.apiKey,baseUrl:d??(r.provider===o?r.baseUrl:void 0)??u,keyHandle:c}}peekActiveModel(e){let t=this.bindings[e];return t?this.models.get(t)??null:null}isAvailable(e){let t=this.peekActiveModel(e);return!!t?.enabled&&this.hasAvailableKeyForProviderVariant(t.provider)}resolveModelForPurpose(e){let t=this.peekActiveModel(e);return t?t.model:null}addProvider(e,t){this.keyPool.addProvider(e,t),this.emitChange()}removeProvider(e){this.keyPool.removeProvider(e);for(let[t,r]of this.models)r.provider===e&&this.removeModel(t);this.emitChange()}addKey(e,t,r){let s=this.keyPool.addKey(e,t,r);return this.emitChange(),s}removeKey(e){this.keyPool.removeKey(e),this.emitChange()}updateKey(e,t){this.keyPool.updateKey(e,t),this.emitChange()}setKeyHealth(e,t){this.keyPool.setKeyHealth(e,t),this.emitChange()}setStrategy(e,t){this.keyPool.setStrategy(e,t),this.emitChange()}addModel(e){let t=e.id??`${e.provider}:${e.model}`;return this.models.set(t,{...e,id:t,enabled:this.modelEnabledOverrides.get(t)??e.enabled}),this.emitChange(),t}replaceCatalogModels(e){let t=new Map;for(let r of e)t.set(r.id,{...r,enabled:this.modelEnabledOverrides.get(r.id)??r.enabled});for(let r of this.modelEnabledOverrides.keys())t.has(r)||this.modelEnabledOverrides.delete(r);this.models=t;for(let[r,s]of Object.entries(this.bindings))s&&!this.models.has(s)&&delete this.bindings[r];this.emitChange()}migrateModelIds(e){for(let[t,r]of e){let s=this.modelEnabledOverrides.get(t);s!==void 0&&!this.modelEnabledOverrides.has(r)&&this.modelEnabledOverrides.set(r,s),this.modelEnabledOverrides.delete(t);for(let[o,i]of Object.entries(this.bindings))i===t&&(this.bindings[o]=r)}this.emitChange()}removeModel(e){this.models.delete(e),this.modelEnabledOverrides.delete(e);for(let[t,r]of Object.entries(this.bindings))r===e&&delete this.bindings[t];this.emitChange()}enableModel(e){let t=this.models.get(e);t&&(t.enabled=!0),this.modelEnabledOverrides.set(e,!0),this.emitChange()}disableModel(e){let t=this.models.get(e);t&&(t.enabled=!1),this.modelEnabledOverrides.set(e,!1),this.emitChange()}listModels(e){let t=[...this.models.values()];return e?.purpose&&(t=t.filter(r=>r.purposes.includes(e.purpose))),e?.provider&&(t=t.filter(r=>r.provider===e.provider)),e?.enabledOnly&&(t=t.filter(r=>r.enabled)),t}getModel(e){return this.models.get(e)??null}setBinding(e,t){let r=this.models.get(t);if(!r)throw new Error(`Model "${t}" not found in pool.`);if(!r.purposes.includes(e))throw new Error(`Model "${t}" does not support purpose "${e}".`);this.bindings[e]=t,this.emitChange()}removeBinding(e){delete this.bindings[e],this.emitChange()}getBinding(e){let t=this.bindings[e];return t?this.models.get(t)??null:null}getAllBindings(){let e={};for(let t of rr){let r=this.bindings[t];e[t]=r?this.models.get(r)??null:null}return e}getProviderStatus(e){return this.keyPool.getPoolStatus(e)}getAllProviderStatus(){return this.keyPool.getAllStatus()}save(){let e={};try{Ze.existsSync(this.settingsPath)&&(e=JSON.parse(Ze.readFileSync(this.settingsPath,"utf-8")))}catch{e={}}delete e.provider,delete e.apiKey,delete e.model,delete e.baseUrl;let t={...e,providers:this.keyPool.exportConfig(),models:this.exportModelState(),bindings:{...this.bindings}},r=this.settingsPath.replace(/[/\\][^/\\]+$/,"");Ze.existsSync(r)||Ze.mkdirSync(r,{recursive:!0}),Ze.writeFileSync(this.settingsPath,JSON.stringify(t,null,2),"utf-8")}load(){try{if(!Ze.existsSync(this.settingsPath))return!1;let e=Ze.readFileSync(this.settingsPath,"utf-8"),t=JSON.parse(e);return t.providers&&this.keyPool.reloadConfig(t.providers),this.models.clear(),this.modelEnabledOverrides.clear(),t.models&&this.loadModelState(t.models),this.bindings=t.bindings??{},this.emitChange(),!0}catch{return!1}}exportConfig(){return{providers:this.keyPool.exportConfig(),models:this.exportModelState(),bindings:{...this.bindings}}}getTunable(e){try{if(!Ze.existsSync(this.settingsPath))return;let t=Ze.readFileSync(this.settingsPath,"utf-8");return JSON.parse(t).tunables?.[e]}catch{return}}getModelInfo(e,t){let r=this.listModels({provider:e}).find(s=>s.model===t);if(r)return{id:r.model,name:r.displayName,contextWindow:r.contextWindow,maxOutput:r.maxOutput,streamRequired:r.streamRequired}}getProviderDefaultModel(e){return this.listModels({provider:e,enabledOnly:!0})[0]?.model??this.listModels({provider:e})[0]?.model}hasConfiguredKeyForProviderVariant(e){return this.providerVariantKeyCandidates(e).some(t=>!!this.keyPool.getPoolStatus(t)?.keys.some(s=>s.enabled))}hasAvailableKeyForProviderVariant(e){return this.providerVariantKeyCandidates(e).some(t=>this.keyPool.hasAvailableKey(t))}listProviderDefs(){return this.keyPool.getAllStatus().map(e=>({id:e.providerId,name:e.providerId,transport:"",baseUrl:e.baseUrl??"",defaultModel:this.getProviderDefaultModel(e.providerId),models:this.listModels({provider:e.providerId}).map(t=>({id:t.model,name:t.displayName,contextWindow:t.contextWindow,maxOutput:t.maxOutput,streamRequired:t.streamRequired}))}))}resolveProviderApiKey(e){return this.getKeyForProvider(e)??void 0}onChange(e){return this.changeListeners.push(e),()=>{let t=this.changeListeners.indexOf(e);t>=0&&this.changeListeners.splice(t,1)}}getKeyForProvider(e){let r=this.acquireKeyForProviderVariant(e)?.keyHandle;if(!r)return null;let s=r.apiKey;return r.release({success:!0}),s}snapshotProviderKeys(){let e={};for(let t of this.keyPool.getAllStatus()){let r=this.getKeyForProvider(t.providerId);r&&(e[t.providerId]=r)}return e}getProviderBaseUrl(e){return this.coreProviderRegistry.getProvider(e)?.baseUrl??this.keyPool.getPoolStatus(e)?.baseUrl}acquireKeyForProviderVariant(e){for(let t of this.providerVariantKeyCandidates(e)){let r=this.keyPool.acquireKey(t);if(r)return{keyHandle:r,keyProviderId:t}}return null}resolveTechnicalVariant(e,t){let r=this.providerVariantKeyCandidates(e.provider).filter(o=>this.hasConfiguredKeyForProviderVariant(o));if(r.length===0)return;let s=this.providerVariantResolver.resolveBest({publicModel:e.model,requestedProtocol:Ck(t,e.transport),capabilities:Mk(t),purpose:t,userPreference:{providerIds:r}});if(s)return{provider:s.provider,nativeModelId:s.nativeModelId}}providerVariantKeyCandidates(e){let t=[e],r=this.coreProviderRegistry.getProvider(e),s=r?.group??r?.id??e;for(let o of this.coreProviderRegistry.listProviders())(o.group??o.id)===s&&t.push(o.id);return s!==e&&t.push(s),[...new Set(t)]}loadModelState(e){for(let t of e)typeof t.id!="string"||!t.id||typeof t.enabled=="boolean"&&this.modelEnabledOverrides.set(t.id,t.enabled)}exportModelState(){let e=new Map;for(let[t,r]of this.modelEnabledOverrides)e.set(t,r);for(let t of this.models.values())e.set(t.id,t.enabled);return[...e.entries()].map(([t,r])=>({id:t,enabled:r}))}emitChange(){for(let e of this.changeListeners)try{e()}catch{}}},nr=null});import{readFile as Nk}from"node:fs/promises";function on(n){let e=typeof n.content=="string"?n.content:n.content!=null?JSON.stringify(n.content):"";return Math.ceil(e.length/4)}function an(n){let e=0;for(let t of n)e+=on(t);return e}function Md(n){if(!n)return 128e3;if(n in Qi)return Qi[n];let e=n.toLowerCase();for(let[t,r]of Object.entries(Qi))if(e.startsWith(t.toLowerCase()))return r;return 128e3}function Ok(){return Y().resolveModelForPurpose("textGeneration")??Dk}function Dd(){return ea}function Lk(n,e){return async(t,r)=>{let s=e?.transport,o=e?.apiKey;if(!s||!o)return n.debug("[context-compression] no LLM transport for summarization \u2014 using sync fallback"),Zi(t);try{let i="",a=e?.model??Ok();for await(let c of s.stream({model:a,messages:[{role:"system",content:"You are a precise conversation summarizer."},{role:"user",content:r}],maxTokens:2e3,temperature:.3},o,AbortSignal.timeout(3e4)))c.type==="delta"&&(i+=c.text);return i||(n.warn("[context-compression] empty summary response"),Zi(t))}catch(i){return n.warn({err:i.message},"[context-compression] summarize call error \u2014 using fallback"),Zi(t)}}}function Zi(n){let e=[],t=n.filter(o=>o.role==="user"),r=t.slice(0,20).map(o=>{let i=typeof o.content=="string"?o.content:JSON.stringify(o.content??"");return`- [user]: ${i.slice(0,300)}${i.length>300?"...":""}`});e.push(`## User Requests (${t.length} messages)`),e.push(...r);let s=n.filter(o=>o.role==="assistant");if(s.length>0){let o=s.slice(0,10).map(i=>{let a=typeof i.content=="string"?i.content:JSON.stringify(i.content??"");return`- [assistant]: ${a.slice(0,150)}${a.length>150?"...":""}`});e.push("",`## Assistant Responses (${s.length} total)`),e.push(...o)}return e.join(`
|
|
25
|
-
`)}function $k(){return Lo(new sn(ta),new Vt(20,on),new Tn(on))}function Cd(n,e){let t=$o(new sn(ta),new Vt(20,on),new Vn({protectedHeadExchanges:1,protectedTailMessages:8,summarize:n,estimateTokens:on}),new Tn(on));return new zn({inner:t,estimateTokens:on,onCacheInvalidated:e?.onCacheInvalidated})}function Od(n,e){let t=e?.budget??Vr({modelContextWindow:Md(e?.model)}),s=(e?.pipeline??$k()).compress(n,t);if(s.droppedCount>0){let o=an(n),i=an(s.messages);Nd.record({timestamp:Date.now(),strategy:s.strategy,tokensBefore:o,tokensAfter:i,droppedCount:s.droppedCount,latencyMs:s.metrics?.latencyMs??0,usedLlm:!1,cacheInvalidated:s.metrics?.cacheInvalidated??!1,tier:Qn(o,t)})}return s.droppedCount>0&&na?.(s.droppedCount,an(s.messages)),s}async function jk(n,e,t){let r=t??Vr({modelContextWindow:Md(e.model)}),s=an(n),o=Qn(s,r),i;switch(o){case"none":i={messages:n,droppedCount:0,strategy:"none"};break;case"trim-only":i=new sn(ta).compress(n,r);break;case"sliding-window":{i=await Cd(e.summarize).compressAsync(n,r);break}case"llm-summarize":{let a=e.pipeline??Cd(e.summarize);i=Jn(a)?await a.compressAsync(n,r):a.compress(n,r);break}}return i.droppedCount>0&&(i={...i,messages:await Uo(i.messages,n,{maxFiles:5,maxTokenBudget:5e4,readFile:async a=>{try{return await Nk(a,"utf-8")}catch{return null}}})}),Uk(n,i,r),i}function Uk(n,e,t){if(e.droppedCount>0||e.metrics?.usedLlm){let r=e.metrics?.tokensBefore||an(n),s=e.metrics?.tokensAfter||an(e.messages);Nd.record({timestamp:Date.now(),strategy:e.strategy,tokensBefore:r,tokensAfter:s,droppedCount:e.droppedCount,latencyMs:e.metrics?.latencyMs??0,usedLlm:e.metrics?.usedLlm??!1,cacheInvalidated:e.metrics?.cacheInvalidated??!1,tier:Qn(r,t)})}if(e.droppedCount>0){let r=e.metrics?.tokensAfter||an(e.messages);na?.(e.droppedCount,r)}}function Fk(n,e){let t=Lk(n,e),r={id:"builtin-compressor",label:"4-Layer Compression Funnel (built-in)",async compressAsync(s,o,i){return jk(s,{budget:o,model:i?.model,sessionId:i?.sessionId,summarize:t},o)}};ea.register(r),ea.activate(r.id),n.info(`[context-compression] registered context engine: ${r.id}`)}function Ld(n,e,t){Fk(e,t),n.register({point:"context.before_compact",priority:50,label:"context-compression-bridge",handler:(r,s)=>{let o=s.messageCount;return o&&o>0&&e.debug(`[context-compression] before_compact: ${o} messages entering compression`),{action:"continue"}}}),na=(r,s)=>{e.debug(`[context-compression] after_compact: removed ${r}, ${s} tokens remaining`),n.invoke("context.after_compact",{sessionId:"",turnId:"",removedCount:r,tokenCount:s}).catch(()=>{})}}var Qi,ta,Dk,Nd,ea,na,ra=X(()=>{"use strict";er();dt();Qi={"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};ta=8e3,Dk="deepseek-v4-flash";Nd=new Xn(200),ea=new Yn;na=null});function $d(n,e,t){let r=t-e;return`[Budget] ${Math.round(n)}% used (${e.toLocaleString()} / ${t.toLocaleString()} tokens). ${r.toLocaleString()} tokens remaining. `+(n>=90?"Wrap up your current taskyou are near the token limit.":"Continue workingdo not summarize prematurely.")}var jd=X(()=>{"use strict"});var Ud={};en(Ud,{resolveToolEligibility:()=>Gk});function Hk(n,e){if(Bk.some(t=>t.test(n)))return!0;if(e)for(let t of e)try{if(new RegExp(t,"i").test(n))return!0}catch{}return!1}function qk(n,e){let t=n.function.name,r=n.meta,s=[];return e.blockedToolNames?.includes(t)?(s.push("policy_blocked"),{level:5,reasons:s}):r?.isReadOnly?(s.push("always_allowed"),{level:1,reasons:s}):r?.requiresApproval?(s.push("approval_required"),{level:4,reasons:s}):r?.isDangerous||Hk(t,e.dangerousPatterns)?(s.push("dangerous_tool"),{level:3,reasons:s}):{level:2,reasons:s}}function Wk(n){switch(n){case 1:return"eligible";case 2:return"eligible";case 3:return"dangerous-notify";case 4:return"approval-required";case 5:return"blocked-by-policy"}}function Gk(n,e={}){let t=new Map,r=[],s=[],o=[];for(let i of n){let a=i.function.name,{level:c,reasons:l}=qk(i,e),d=Wk(c),u={toolName:a,status:d,permissionLevel:c,approvalRequired:c===4,reasonCodes:l};t.set(a,u),c===5?s.push(u):(r.push(i),c===4&&o.push(u))}return{eligibleTools:r,blockedTools:s,approvalRequiredTools:o,eligibilityByName:t}}var Bk,Fd=X(()=>{"use strict";Bk=[/^(?:bash|shell|exec|terminal|run_command)$/i,/^(?:write_file|delete_file|move_file|create_directory)$/i,/^(?:git_push|git_reset|git_force)$/i]});import{accumulateToolCalls as zk}from"@xiaozhiclaw/provider-core";function Yk(n){let e=n.split(".").pop()?.toLowerCase()??"";return["png","jpg","jpeg","gif","webp","svg","bmp","ico"].includes(e)?"image":["md","txt","pdf","doc","docx","rtf","html"].includes(e)?"document":["mermaid","mmd","dot","puml","plantuml"].includes(e)?"diagram":["csv","tsv","xlsx","xls"].includes(e)?"table":["ts","tsx","js","jsx","py","rs","go","java","c","cpp","h","cs","rb","sh","sql","json","yaml","yml","toml","xml","css","scss","vue","svelte"].includes(e)?"code":"file"}function Jk(n){let e=n.split(".").pop()?.toLowerCase()??"";return{ts:"typescript",tsx:"typescriptreact",js:"javascript",jsx:"javascriptreact",py:"python",rs:"rust",go:"go",java:"java",c:"c",cpp:"cpp",h:"c",cs:"csharp",rb:"ruby",sh:"shellscript",sql:"sql",json:"json",yaml:"yaml",yml:"yaml",toml:"toml",xml:"xml",html:"html",css:"css",scss:"scss",vue:"vue",svelte:"svelte",md:"markdown"}[e]}function eS(n){if(!Zk.has(n.toolName))return!1;let e=typeof n.message?.content=="string"?n.message.content.trim():"";return e.length>0&&e.length<200&&Qk.test(e)}function Bd(n,e){for(let t=n.length-1;t>=0;t--){let r=n[t];if(!r||r.role!=="tool")continue;let s=typeof r.content=="string"?r.content:"";if(s.startsWith("Error: "))return s.slice(7).trim()}}function tS(n){return typeof n=="number"&&Number.isFinite(n)&&n>=1?Math.min(Math.round(n),100):Go}function Hd(n){let e=n.message.toLowerCase();return n.status===413||e.includes("prompt_too_long")||e.includes("context_length_exceeded")||e.includes("maximum context length")}function nS(n){return n==="length"||n==="max_tokens"}function qd(n){let e=n.message.toLowerCase();return(e.includes("image")||e.includes("media")||e.includes("file too large")||e.includes("payload too large"))&&(n.status===413||e.includes("too large")||e.includes("size"))}function rS(n){let e=n.headers;if(!e)return null;let t=e["retry-after"]??e["Retry-After"];if(!t)return null;let r=parseInt(t,10);return!isNaN(r)&&r>0?r*1e3:null}function sS(n){if(n.status!==400)return null;let e=n.message.match(/input length and `max_tokens` exceed context limit: (\d+) \+ (\d+) > (\d+)/);if(!e?.[1]||!e?.[3])return null;let t=parseInt(e[1],10),r=parseInt(e[3],10);if(isNaN(t)||isNaN(r))return null;let s=r-t-1e3;return s>=3e3?s:null}function oS(n){return n.filter(e=>e.role!=="assistant"?!0:!(typeof e.content=="string"&&e.content.trim()===""))}async function*Wd(n,e,t,r){let{turnId:s,sessionId:o,messages:i,tools:a,model:c,apiKey:l,temperature:d=0,hooks:u,signal:p}=n,m={sessionId:o,turnId:s},h=n.maxTurns??0,f=n.querySource,{resolveToolEligibility:y}=await Promise.resolve().then(()=>(Fd(),Ud)),b=y(a,n.toolEligibilityContext),k=b.eligibleTools;for(let j of b.blockedTools)yield{type:"tool_blocked",turnId:s,callId:"",name:j.toolName,reason:"blocked-by-policy"};if(!k.length){yield*iS(s,c,i,l,d,p,e,r);return}let A=tS(n.maxRounds),_={contextWindowTokens:n.contextWindowTokens??zo,responseBufferTokens:Xo,maxOutputTokens:n.maxOutputTokens??Yo,abortSignal:p,reactiveCompactEnabled:!0,outputEscalationEnabled:!0},I=new Set,N=0,L=k,F,T={messages:[...i],maxOutputTokensRecoveryCount:0,hasAttemptedReactiveCompact:!1,maxOutputTokensOverride:void 0,turnCount:1,transition:void 0,guardState:Gi(_),reactiveCompactState:Yi(),toolLoopState:es({maxRounds:A,replayMessages:[...i]}).state,consecutiveFailedRounds:0,finalText:"",totalUsage:{inputTokens:0,outputTokens:0},collapseStore:Ho(),currentModel:c,consecutive529Errors:0,consecutiveApiRetries:0,stopHookActive:void 0,lastResponseId:void 0,snipRemovedIds:new Set,contentReplacementState:ud(),budgetContinuationCount:0,lastBudgetDeltaTokens:0,lastBudgetGlobalTokens:0,identicalCallCounts:new Map,toolFailureCounts:new Map,fileReadCounts:new Map},ce=Math.max(h*5,200),le=0;for(;;){if(le++,le>ce){r.info(`hard iteration cap reached (${ce}), forcing completion`);let P=T.finalText||sr(T.messages,r);yield{type:"end",turnId:s,content:P,usage:T.totalUsage,model:T.currentModel};return}let{messages:j,maxOutputTokensRecoveryCount:ve,hasAttemptedReactiveCompact:oe,maxOutputTokensOverride:$e,turnCount:te,guardState:J,reactiveCompactState:R,collapseStore:B}=T,{toolLoopState:U}=T;if(F){try{let P=await F;P&&(yield{type:"tool_use_summary",turnId:s,summary:P})}catch{}F=void 0}if(n.refreshTools&&te>1){let P=n.refreshTools();P!==L&&(L=P,r.debug(`tools refreshed: ${P.length} tools`))}if(Xi(J,_)){r.info(`turn aborted by guard at turn ${te}`),yield{type:"error",turnId:s,error:"Turn aborted",code:"ABORTED",usage:T.totalUsage};return}let Ae=Ki(J,_);if(Ae.level==="blocking"){Ae.reason==="prompt_too_long"&&An(R)&&(R.attemptedThisTurn=!0,J.hasAttemptedReactiveCompact=!0,r.info(`token budget blocking (${Ae.reason}), reactive compact needed`),yield{type:"recovery",turnId:s,action:"reactive_compact",detail:"token budget pre-check"}),r.info(`token budget blocking (${Ae.reason}), ending tool loop`);break}Ae.level==="warning"&&r.info(`token budget warning: ${Ae.usagePercent}% used, ${Ae.remainingTokens} remaining`);let fe;{let P=await yd(j,T.contentReplacementState,o);fe=P.messages,P.newlyReplacedCount>0&&(r.info(`tool-result-budget: persisted ${P.newlyReplacedCount} oversized tool results`),yield{type:"recovery",turnId:s,action:"tool_result_budget",detail:`${P.newlyReplacedCount} persisted`})}{let P=Fo(fe,T.snipRemovedIds);fe=P.messages,P.removedCount>0&&(r.info(`snip: removed ${P.removedCount} messages, freed ~${P.tokensFreed} tokens`),yield{type:"recovery",turnId:s,action:"snip",detail:`${P.removedCount} messages`})}{let C=new Vt().compress(fe,0);C.droppedCount>0&&(fe=C.messages,r.info(`microcompact: cleared ${C.droppedCount} old tool results`))}if(fe=qo(fe,B).messages,J.promptTokens>0){let P=_.contextWindowTokens*.75,C=Dd().getActive(),O;C?O=await C.compressAsync(fe,P,{model:T.currentModel,sessionId:o}):O=Od(fe,{budget:P,model:T.currentModel}),O.droppedCount>0&&(fe=O.messages,r.info(`autocompact: ${O.strategy}, dropped ${O.droppedCount}`),yield{type:"recovery",turnId:s,action:"autocompact",detail:`${O.strategy}: ${O.droppedCount} dropped`},T.hasAttemptedReactiveCompact=!1,u?.invoke("context.after_compact",{...m,removedCount:O.droppedCount}).catch(()=>{}))}fe=oS(fe);let Mt=Mi({tools:L,toolChoice:n.toolChoice??"auto"}),g=es({maxRounds:A,replayMessages:fe,lastStopReason:U.lastStopReason,options:{stopReason:U.lastStopReason}}),S=Mt.extraSystemPrompt?[{role:"system",content:Mt.extraSystemPrompt},...g.state.replayMessages]:g.state.replayMessages;U=g.state,g.recoveryActions.length>0&&r.debug(`tool loop recovery: ${g.recoveryActions.map(P=>P.detail??P.kind).join("; ")}`),r.debug(`turn ${te}, messages: ${S.length}`),u?.invoke("turn.before_inference",{...m,model:T.currentModel}).catch(()=>{});let x=!1,E=[],w=new Map,$="stop",D,M=null,W=!1,ie=[],Z=[];try{for await(let P of e.stream({model:T.currentModel,messages:S,tools:Mt.tools,toolChoice:Mt.normalizedToolChoice??"auto",temperature:d,maxTokens:($e??J.currentMaxOutputTokens)||void 0,streamRequired:n.streamRequired,previousResponseId:T.lastResponseId,reasoning:n.reasoning,promptCacheKey:n.promptCacheKey,promptCacheRetention:n.promptCacheRetention,serviceTier:n.serviceTier,openaiBuiltinTools:n.openaiBuiltinTools,maxToolCalls:n.maxToolCalls,parallelToolCalls:n.parallelToolCalls,textVerbosity:n.textVerbosity},l,p))switch(P.type){case"delta":E.push(P.text),x||(yield{type:"delta",turnId:s,text:P.text});break;case"tool_call_delta":x=!0,zk(w,P);break;case"reasoning_delta":ie.push(P.text);break;case"reasoning_block_complete":P.signature&&Z.push({thinking:ie.join(""),signature:P.signature}),ie.length=0;break;case"usage":D={inputTokens:P.promptTokens,outputTokens:P.completionTokens,reasoningTokens:P.reasoningTokens,cacheRead:P.cacheReadTokens,cacheWrite:P.cacheCreationTokens};break;case"response_id":T.lastResponseId=P.id;break;case"annotations":yield{type:"annotations",turnId:s,annotations:P.annotations};break;case"builtin_tool_status":yield{type:"heartbeat",turnId:s,message:`${P.toolType}: ${P.event}`};break;case"done":$=P.finishReason;break}if(x||u?.invoke("turn.after_inference",{...m,model:T.currentModel}).catch(()=>{}),n.postSamplingHooks&&n.postSamplingHooks.length>0){let P=T.currentModel;for(let C of n.postSamplingHooks)try{C({messages:[...fe],model:P,sessionId:o})}catch{}}}catch(P){if(P instanceof Zn&&n.fallbackModel){r.info(`model fallback triggered: ${P.originalModel} \u2192 ${P.fallbackModel}`),yield{type:"recovery",turnId:s,action:"model_fallback",detail:`${P.originalModel} \u2192 ${P.fallbackModel}`},T={...T,currentModel:P.fallbackModel,consecutive529Errors:0,consecutiveApiRetries:0,transition:void 0};continue}let C=P instanceof Error?P.message:String(P),O=typeof P?.status=="number"?P.status:void 0;if(!O&&C&&(C.includes("ECONNRESET")||C.includes("EPIPE"))){let re=(T.consecutiveApiRetries??0)+1;if(re>Rn){r.info(`stale connection retry limit reached (${Rn}), aborting`),yield{type:"error",turnId:s,error:C,code:"RETRIES_EXHAUSTED",usage:T.totalUsage};return}r.info(`stale connection (${C.includes("ECONNRESET")?"ECONNRESET":"EPIPE"}): retrying`),yield{type:"recovery",turnId:s,action:"stale_connection_retry",detail:C.slice(0,80)},T={...T,consecutiveApiRetries:re,transition:void 0};continue}let H=sS({status:O,message:C});if(H!==null){r.info(`max_tokens overflow: adjusting to ${H}`),J.currentMaxOutputTokens=H,T={...T,maxOutputTokensOverride:H,transition:void 0};continue}if(Fi(O)){T.consecutive529Errors++;let re=2,we=n.fallbackModel&&T.currentModel!==n.fallbackModel;if(T.consecutive529Errors>re&&!we&&!ns()){r.info(`transient ${O} \xD7 ${T.consecutive529Errors}: hard limit reached, aborting`),yield{type:"error",turnId:s,error:`API unavailable after ${T.consecutive529Errors} consecutive ${O} errors`,code:"API_ERROR",usage:T.totalUsage};return}if(T.consecutive529Errors>=si&&n.fallbackModel&&T.currentModel!==n.fallbackModel){r.info(`529 \xD7 ${T.consecutive529Errors}: triggering fallback to ${n.fallbackModel}`),yield{type:"recovery",turnId:s,action:"model_fallback",detail:`529 \xD7 ${T.consecutive529Errors}`},T={...T,currentModel:n.fallbackModel,consecutive529Errors:0,transition:void 0};continue}if(ns()){let Q=ts(T.consecutive529Errors);r.info(`persistent retry: waiting ${Q}ms (attempt ${T.consecutive529Errors})`);let he=Q;for(;he>0;){if(p?.aborted){yield{type:"error",turnId:s,error:"Aborted during retry wait",code:"ABORTED",usage:T.totalUsage};return}yield{type:"heartbeat",turnId:s,message:`Retrying in ${Math.ceil(he/1e3)}s (${O})`};let ot=Math.min(he,ri);await new Promise(Co=>setTimeout(Co,ot)),he-=ot}T={...T,transition:void 0};continue}if(Ui(f)){let he=rS({status:O,message:C})??ts(T.consecutive529Errors);r.info(`transient ${O}: retry in ${he}ms`),yield{type:"recovery",turnId:s,action:"retry",detail:`${O} retry in ${he}ms`},await new Promise(ot=>setTimeout(ot,he)),T={...T,transition:void 0};continue}r.info(`background source ${f}: not retrying ${O}`)}M={status:O,message:C}}if(M&&u?.invoke("turn.after_inference",{...m,model:T.currentModel,response:{error:M.message}}).catch(()=>{}),M)if(Hd(M))W=!0,r.info(`withheld prompt_too_long error (status=${M.status})`);else if(qd(M))W=!0,r.info(`withheld media_size error (status=${M.status})`);else{let P=Vi({status:M.status??500,message:M.message},J,_);if(P.action==="reactive_compact"&&An(R)&&(R.attemptedThisTurn=!0,J.hasAttemptedReactiveCompact=!0,yield{type:"recovery",turnId:s,action:"reactive_compact",detail:`API ${M.status??500}: ${M.message}`}),P.action==="retry"){let O=(T.consecutiveApiRetries??0)+1;if(O>Rn){r.info(`API retry limit reached (${Rn}), aborting`);let H=Sn(M.status,M.message);yield{type:"error",turnId:s,error:M.message,code:H,usage:T.totalUsage};return}yield{type:"recovery",turnId:s,action:"retry",detail:P.reason},T={...T,consecutiveApiRetries:O,transition:void 0};continue}let C=Sn(M.status,M.message);u?.invoke("stop.failure",{sessionId:o,reason:C,error:M.message}).catch(()=>{}),yield{type:"error",turnId:s,error:M.message,code:C,usage:T.totalUsage};return}D&&(T.totalUsage.inputTokens+=D.inputTokens,T.totalUsage.outputTokens+=D.outputTokens,D.reasoningTokens&&(T.totalUsage.reasoningTokens=(T.totalUsage.reasoningTokens??0)+D.reasoningTokens),D.cacheRead&&(T.totalUsage.cacheRead=(T.totalUsage.cacheRead??0)+D.cacheRead),D.cacheWrite&&(T.totalUsage.cacheWrite=(T.totalUsage.cacheWrite??0)+D.cacheWrite)),D?.inputTokens&&(J.promptTokens=D.inputTokens);let ne=E.join("");ne&&(T.finalText=ne);let pe=[...w.values()].map(P=>({id:P.id||`tc_${s}_${te}_${Math.random().toString(36).slice(2,8)}`,type:"function",function:{name:P.name,arguments:P.arguments}}));if(pe.length===0&&!x){if(W&&M&&Hd(M)){if(T.transition?.reason!=="collapse_drain_retry"){let O=Wo(fe,B);if(O.committed>0){r.info(`collapse drain: committed ${O.committed} stages`),yield{type:"recovery",turnId:s,action:"collapse_drain",detail:`${O.committed} stages committed`},T={...T,messages:O.messages,transition:{reason:"collapse_drain_retry",committed:O.committed}};continue}}if(An(R)){R.attemptedThisTurn=!0,J.hasAttemptedReactiveCompact=!0,r.info("withheld 413: reactive compact attempt"),yield{type:"recovery",turnId:s,action:"reactive_compact",detail:"withheld prompt_too_long"},T={...T,hasAttemptedReactiveCompact:!0,transition:{reason:"reactive_compact_retry"}};continue}r.info("withheld 413: recovery exhausted, surfacing error"),u?.invoke("stop.failure",{sessionId:o,reason:"prompt_too_long",error:M.message}).catch(()=>{}),yield{type:"error",turnId:s,error:M.message,code:"PROMPT_TOO_LONG",usage:T.totalUsage};return}if(W&&M&&qd(M)){if(An(R)){R.attemptedThisTurn=!0,J.hasAttemptedReactiveCompact=!0,r.info("withheld media error: reactive compact strip-retry"),yield{type:"recovery",turnId:s,action:"reactive_compact",detail:"media error strip-retry"},T={...T,hasAttemptedReactiveCompact:!0,transition:{reason:"reactive_compact_retry"}};continue}r.info("withheld media error: recovery exhausted"),u?.invoke("stop.failure",{sessionId:o,reason:"media_error",error:M.message}).catch(()=>{}),yield{type:"error",turnId:s,error:M.message,code:"IMAGE_ERROR",usage:T.totalUsage};return}if(nS($)){J.consecutiveTruncations+=1;let O=n.modelMaxOutputTokens??Jo,H=zi(J,_,O);if(H.shouldEscalate&&$e===void 0){J.currentMaxOutputTokens=H.newMax,r.info(`max_output_tokens escalate: ${H.newMax} tokens`),yield{type:"recovery",turnId:s,action:"output_escalation",detail:`${H.newMax} tokens`},T={...T,maxOutputTokensOverride:Zo,transition:{reason:"max_output_tokens_escalate"}};continue}if(ve<Qo){let re={role:"user",content:"Output token limit hit. Resume directly \u2014 no apology, no recap of what you were doing. Pick up mid-thought if that is where the cut happened. Break remaining work into smaller pieces."};r.info(`max_output_tokens recovery #${ve+1}`),yield{type:"recovery",turnId:s,action:"max_output_tokens_recovery",detail:`attempt ${ve+1}`},T={...T,messages:[...fe,re],maxOutputTokensRecoveryCount:ve+1,maxOutputTokensOverride:void 0,transition:{reason:"max_output_tokens_recovery",attempt:ve+1}};continue}r.info("max_output_tokens recovery exhausted, completing with partial content")}else J.consecutiveTruncations=0;if(U=Zr(U,{replayMessages:j,lastStopReason:"completed"}),u){let O=await u.invoke("stop",{sessionId:o,reason:"completed"});if(O.action==="prevent"){r.info(`stop hook prevented continuation: ${O.reason??"no reason"}`),yield{type:"end",turnId:s,content:T.finalText,usage:T.totalUsage,model:T.currentModel};return}if(O.action==="abort"){let H=O.reason??"Stop hook requested continuation";r.info(`stop hook blocking: ${H}`);let re={role:"user",content:H},we={role:"assistant",content:T.finalText,...Z.length>0&&{thinkingBlocks:[...Z]}};T={...T,messages:[...j,we,re],stopHookActive:!0,transition:{reason:"stop_hook_blocking"}};continue}}if(n.tokenBudget&&n.tokenBudget>0&&T.budgetContinuationCount<5){let O=T.totalUsage.inputTokens+T.totalUsage.outputTokens+(T.totalUsage.reasoningTokens??0),H=O/n.tokenBudget*100,re=O-T.lastBudgetGlobalTokens,we=T.budgetContinuationCount>=ei&&re<Xr&&T.lastBudgetDeltaTokens<Xr;if(we&&r.info(`token budget early stop: diminishing returns at ${Math.round(H)}% (delta=${re})`),!we&&H<90){let Q=T.budgetContinuationCount+1,he={role:"user",content:$d(H,O,n.tokenBudget)};r.info(`token budget continuation #${Q}: ${Math.round(H)}% used`),yield{type:"recovery",turnId:s,action:"budget_continuation",detail:`${Math.round(H)}% used (#${Q})`};let ot={role:"assistant",content:T.finalText,...Z.length>0&&{thinkingBlocks:[...Z]}};T={...T,messages:[...j,ot,he],budgetContinuationCount:Q,lastBudgetDeltaTokens:re,lastBudgetGlobalTokens:O,transition:{reason:"token_budget_continuation"}};continue}}if(!T.stopHookActive){let O=i.find(Q=>Q.role==="user"),H=typeof O?.content=="string"?O.content:"",re=/创建文件|生成文件|写入|写一个|建一个|新建|重写|改写|create\s+(a\s+)?file|write\s+(a\s+)?file|make\s+(a\s+)?file|修改|改成|把.*改|文件名叫/i.test(H),we=I.has("write")||I.has("edit");if(re&&!we){if(r.info("AP1 action-verification: user requested file action but no write/edit tool was called, injecting nudge"),N>0){let ot=[...j].reverse().find(Co=>Co.role==="tool");ot&&typeof ot.content=="string"&&(ot.content+=`
|
|
23
|
+
`,e+=fk,e}async function hd(n,e,t,r=ti){if(n.length<=r||md(n))return n;let s=await gd(n,e,t);return s?fd(s):n.slice(0,r)+`
|
|
24
|
+
...[truncated ${n.length-r} chars]`}function vk(n){let e=[],t=[];for(let r of n)r.role==="tool"&&typeof r.content=="string"&&r.tool_call_id?md(r.content)||t.push({toolCallId:r.tool_call_id,content:r.content,size:r.content.length}):r.role==="assistant"&&t.length>0&&(e.push(t),t=[]);return t.length>0&&e.push(t),e}function kk(n,e){let t=[],r=[],s=[];for(let o of n){let i=e.replacements.get(o.toolCallId);i!==void 0?t.push({...o,replacement:i}):e.seenIds.has(o.toolCallId)?r.push(o):s.push(o)}return{mustReapply:t,frozen:r,fresh:s}}function Sk(n,e,t){let r=[...n].sort((i,a)=>a.size-i.size),s=[],o=e+n.reduce((i,a)=>i+a.size,0);for(let i of r){if(o<=t)break;s.push(i),o-=i.size}return s}async function yd(n,e,t,r=ni){let s=vk(n);if(s.length===0)return{messages:n,newlyReplacedCount:0};let o=new Map,i=[];for(let d of s){let{mustReapply:u,frozen:p,fresh:m}=kk(d,e);for(let k of u)o.set(k.toolCallId,k.replacement);if(m.length===0){for(let k of d)e.seenIds.add(k.toolCallId);continue}let h=p.reduce((k,A)=>k+A.size,0),f=m.reduce((k,A)=>k+A.size,0),y=h+f>r?Sk(m,h,r):[],b=new Set(y.map(k=>k.toolCallId));for(let k of d)b.has(k.toolCallId)||e.seenIds.add(k.toolCallId);y.length>0&&i.push(...y)}if(o.size===0&&i.length===0)return{messages:n,newlyReplacedCount:0};let a=await Promise.all(i.map(async d=>{let u=await gd(d.content,d.toolCallId,t);return{candidate:d,result:u}})),c=0;for(let{candidate:d,result:u}of a){if(e.seenIds.add(d.toolCallId),!u)continue;let p=fd(u);o.set(d.toolCallId,p),e.replacements.set(d.toolCallId,p),c++}return o.size===0?{messages:n,newlyReplacedCount:0}:{messages:n.map(d=>{if(d.role!=="tool"||!d.tool_call_id)return d;let u=o.get(d.tool_call_id);return u===void 0?d:{...d,content:u}}),newlyReplacedCount:c}}var gk,dd,fk,Ji=X(()=>{"use strict";je();gk="tool-results",dd="<persisted-output>",fk="</persisted-output>"});function Ak(n){try{return JSON.parse(n)}catch{return}}var Tk,Rk,ss,bd=X(()=>{"use strict";er();Ji();Tk=new Set(["read_file","file_read","FileRead","grep","Grep","glob","Glob","search","list_dir","find_files","web_fetch","web_search","WebFetch","WebSearch"]),Rk=new Set(["bash","execute_command","Bash","shell"]),ss=class{tools=[];hasErrored=!1;erroredToolDescription="";discarded=!1;siblingAbortController;progressResolve;config;concurrencySafe;constructor(e){this.config=e,this.concurrencySafe=e.concurrencySafeTools??Tk,this.siblingAbortController=new AbortController,e.signal&&e.signal.addEventListener("abort",()=>{this.siblingAbortController.abort("parent_abort")},{once:!0})}discard(){this.discarded=!0}addTool(e){let t=this.concurrencySafe.has(e.function.name);this.tools.push({id:e.id,toolCall:e,status:"queued",isConcurrencySafe:t,results:[],pendingProgress:[]}),this.processQueue()}canExecuteTool(e){let t=this.tools.filter(s=>s.status==="executing"),r=this.config.maxConcurrentTools;return r&&r>0&&t.length>=r?!1:t.length===0||e&&t.every(s=>s.isConcurrencySafe)}async processQueue(){for(let e of this.tools)if(e.status==="queued"){if(this.canExecuteTool(e.isConcurrencySafe))await this.executeTool(e);else if(!e.isConcurrencySafe)break}}getAbortReason(){return this.discarded?"discarded":this.hasErrored?"sibling_error":this.config.signal?.aborted?"user_interrupted":null}getToolDescription(e){let t;try{t=JSON.parse(e.toolCall.function.arguments)}catch{}let r=t?.command??t?.file_path??t?.pattern??"";if(typeof r=="string"&&r.length>0){let s=r.length>40?r.slice(0,40)+"\u2026":r;return`${e.toolCall.function.name}(${s})`}return e.toolCall.function.name}createSyntheticError(e,t){let r=this.erroredToolDescription,s=t==="user_interrupted"?"User rejected tool use":t==="discarded"?"Streaming fallback - tool execution discarded":r?`Cancelled: parallel tool call ${r} errored`:"Cancelled: parallel tool call errored";return{callId:e.id,toolName:e.toolCall.function.name,ok:!1,error:s,message:Kt(e.id,{ok:!1,error:s})}}async executeTool(e){e.status="executing";let r=(async()=>{let s=this.getAbortReason();if(s){e.results.push(this.createSyntheticError(e,s)),e.status="completed";return}let{toolInvoker:o,hooks:i,sessionId:a,turnId:c,log:l}=this.config,d=e.toolCall.function.name,u=!1,p=e.toolCall.function.arguments;if(i)try{let k=await i.invoke("tool.before_invoke",{sessionId:a,turnId:c,callId:e.id,toolName:d,arguments:Ak(p)});if(k.action==="abort"){let A=k.reason??"blocked by policy";l.info(`tool ${d} blocked: ${A}`),e.results.push({callId:e.id,toolName:d,ok:!1,error:A,blocked:!0,blockReason:A,message:Kt(e.id,{ok:!1,error:A})}),e.status="completed";return}k.action==="continue"&&k.context?.arguments&&(p=JSON.stringify(k.context.arguments))}catch{}let m=await o.invoke(c,d,p,this.siblingAbortController.signal),h=this.getAbortReason();if(h&&!u){e.results.push(this.createSyntheticError(e,h)),e.status="completed";return}let f=!m.error,y=m.result;f&&y&&y.length>5e4&&(y=await hd(y,e.id,a));let b=Kt(e.id,{ok:f,payload:y,error:m.error,toolReferences:m.toolReferences,imageUrls:m.imageUrls});f||(u=!0,Rk.has(d)&&(this.hasErrored=!0,this.erroredToolDescription=this.getToolDescription(e),this.siblingAbortController.abort("sibling_error"))),i?.invoke(f?"tool.after_invoke":"tool.invoke_failed",{sessionId:a,turnId:c,callId:e.id,toolName:d,ok:f,...m.error?{error:m.error}:{}}).catch(()=>{}),e.results.push({callId:e.id,toolName:d,ok:f,error:m.error,message:b}),e.status="completed"})();e.promise=r,r.finally(()=>{this.processQueue()})}*getCompletedResults(){if(!this.discarded){for(let e of this.tools)if(e.status!=="yielded"){if(e.status==="completed"&&e.results.length>0){e.status="yielded";for(let t of e.results)yield t}else if(e.status==="executing"&&!e.isConcurrencySafe)break}}}async*getRemainingResults(){if(!this.discarded){for(;this.hasUnfinishedTools();){await this.processQueue();for(let e of this.getCompletedResults())yield e;if(this.hasExecutingTools()&&!this.hasCompletedResults()){let e=this.tools.filter(r=>r.status==="executing"&&r.promise).map(r=>r.promise),t=new Promise(r=>{this.progressResolve=r});e.length>0&&await Promise.race([...e,t])}}for(let e of this.getCompletedResults())yield e}}hasCompletedResults(){return this.tools.some(e=>e.status==="completed")}hasExecutingTools(){return this.tools.some(e=>e.status==="executing")}hasUnfinishedTools(){return this.tools.some(e=>e.status!=="yielded")}}});import{homedir as wk}from"node:os";import{join as xe}from"node:path";import{existsSync as xk}from"node:fs";function q(){return process.env.QLOGICAGENT_HOME||xe(wk(),qe)}function vd(){return xe(q(),"plugins")}function Dt(){return xe(q(),"skills")}function it(){return xe(q(),"settings.json")}function kd(){return xe(q(),"plugin-cache")}function Sd(){return xe(q(),"mcp.json")}function Td(){return xe(q(),"marketplace.json")}function Rd(){return xe(q(),"workflows")}function Ad(){return xe(q(),"rules")}function Me(n){if(!n)throw new Error("getProjectAgentDir: cwd is required (must not fall back to process.cwd())");return xe(n,qe)}function wd(n){return xe(Me(n),"workflows")}function Tt(n){return xe(Me(n),"skills")}function tr(n){return xe(Me(n),"INSTRUCTIONS.md")}function wn(n){return xe(Me(n),"rules")}function Ot(n){return xe(Me(n),"sessions")}function xd(n,e){let t=xe(Me(n),"checkpoints");return e?xe(t,e):t}function Pd(n){return xe(n,qe,"hooks")}function Id(n,e){return n.filter(t=>t!==e&&xk(xe(t,qe,"skills")))}var qe,ae=X(()=>{"use strict";qe=".qlogicagent"});var os,_d=X(()=>{"use strict";os=class{pools=new Map;runtimeStates=new Map;constructor(e){if(e)for(let t of e){this.pools.set(t.providerId,t);for(let r of t.keys)this.runtimeStates.set(r.id,this.createInitialState())}}acquireKey(e){let t=this.pools.get(e);if(!t||t.keys.length===0)return null;let r=Date.now(),s=this.getHealthyCandidates(t,r);if(s.length===0)return null;let o=this.selectByStrategy(s,t.strategy,r);if(!o)return null;let i=this.runtimeStates.get(o.id);return i.inFlight++,i.totalRequests++,i.lastUsedAt=r,i.requestTimestamps.push(r),{keyId:o.id,apiKey:o.key,providerId:e,release:a=>this.releaseKey(o.id,a)}}releaseKey(e,t){let r=this.runtimeStates.get(e);if(r)if(r.inFlight=Math.max(0,r.inFlight-1),t.success)r.consecutiveErrors=0,r.healthStatus="healthy",t.tokens&&(r.totalTokens+=t.tokens,r.tokenCounts.push(t.tokens));else if(r.consecutiveErrors++,r.lastErrorAt=Date.now(),t.errorCode===429){let s=t.retryAfter?t.retryAfter*1e3:3e4;r.cooldownUntil=Date.now()+s,r.healthStatus="cooldown"}else r.consecutiveErrors>=5?(r.cooldownUntil=Date.now()+6e4,r.healthStatus="cooldown"):r.consecutiveErrors>=3&&(r.healthStatus="degraded")}addProvider(e,t){this.pools.has(e)||this.pools.set(e,{providerId:e,baseUrl:t?.baseUrl,strategy:t?.strategy??"weighted-round-robin",keys:[],rateLimit:t?.rateLimit})}removeProvider(e){let t=this.pools.get(e);if(t){for(let r of t.keys)this.runtimeStates.delete(r.id);this.pools.delete(e)}}addKey(e,t,r){let s=this.pools.get(e);s||(s={providerId:e,strategy:"weighted-round-robin",keys:[]},this.pools.set(e,s));let o=r?.id??crypto.randomUUID(),i={id:o,key:t,label:r?.label,weight:r?.weight??1,enabled:r?.enabled??!0};return s.keys.push(i),this.runtimeStates.set(o,this.createInitialState()),o}removeKey(e){for(let t of this.pools.values()){let r=t.keys.findIndex(s=>s.id===e);if(r!==-1){t.keys.splice(r,1),this.runtimeStates.delete(e);return}}}updateKey(e,t){for(let r of this.pools.values()){let s=r.keys.find(o=>o.id===e);if(s){if(t.label!==void 0&&(s.label=t.label),t.weight!==void 0&&(s.weight=t.weight),t.enabled!==void 0){s.enabled=t.enabled;let o=this.runtimeStates.get(e);o&&(o.healthStatus=t.enabled?"healthy":"disabled")}return}}}setKeyHealth(e,t){let r=this.runtimeStates.get(e);r&&(r.healthStatus=t)}setStrategy(e,t){let r=this.pools.get(e);r&&(r.strategy=t)}setRateLimit(e,t){let r=this.pools.get(e);r&&(r.rateLimit=t)}getPoolStatus(e){let t=this.pools.get(e);return t?this.buildPoolStatus(t):null}getAllStatus(){return[...this.pools.values()].map(e=>this.buildPoolStatus(e))}getProviderIds(){return[...this.pools.keys()]}hasProvider(e){return this.pools.has(e)}hasAvailableKey(e){let t=this.pools.get(e);return t?this.getHealthyCandidates(t,Date.now()).length>0:!1}exportConfig(){return[...this.pools.values()]}reloadConfig(e){let t=new Set;for(let r of e){this.pools.set(r.providerId,r);for(let s of r.keys)t.add(s.id),this.runtimeStates.has(s.id)||this.runtimeStates.set(s.id,this.createInitialState())}for(let r of[...this.pools.keys()])e.some(s=>s.providerId===r)||this.pools.delete(r);for(let r of[...this.runtimeStates.keys()])t.has(r)||this.runtimeStates.delete(r)}createInitialState(){return{inFlight:0,totalRequests:0,totalTokens:0,lastUsedAt:0,lastErrorAt:0,consecutiveErrors:0,cooldownUntil:0,healthStatus:"healthy",requestTimestamps:[],tokenCounts:[]}}getHealthyCandidates(e,t){let r=[];for(let s of e.keys){if(!s.enabled)continue;let o=this.runtimeStates.get(s.id);if(o){if(o.healthStatus==="cooldown")if(t>=o.cooldownUntil)o.healthStatus="healthy",o.consecutiveErrors=0;else continue;o.healthStatus!=="disabled"&&(e.rateLimit?.rpm&&(this.pruneWindow(o.requestTimestamps,t),o.requestTimestamps.length>=e.rateLimit.rpm*.9)||e.rateLimit?.tpm&&(this.pruneWindow(o.tokenCounts,t),o.tokenCounts.reduce((a,c)=>a+c,0)>=e.rateLimit.tpm*.9)||r.push(s))}}return r}selectByStrategy(e,t,r){if(e.length===0)return null;if(e.length===1)return e[0];switch(t){case"weighted-round-robin":return this.weightedRandom(e);case"least-busy":return this.leastBusy(e);case"random":return e[Math.floor(Math.random()*e.length)];default:return this.weightedRandom(e)}}weightedRandom(e){let t=e.reduce((s,o)=>s+o.weight,0),r=Math.random()*t;for(let s of e)if(r-=s.weight,r<=0)return s;return e[e.length-1]}leastBusy(e){let t=1/0,r=e[0];for(let s of e){let i=this.runtimeStates.get(s.id)?.inFlight??0;(i<t||i===t&&s.weight>r.weight)&&(t=i,r=s)}return r}pruneWindow(e,t){let r=t-6e4;for(;e.length>0&&e[0]<r;)e.shift()}buildPoolStatus(e){return{providerId:e.providerId,baseUrl:e.baseUrl,strategy:e.strategy,rateLimit:e.rateLimit,keys:e.keys.map(t=>{let r=this.runtimeStates.get(t.id)??this.createInitialState();return{...t,inFlight:r.inFlight,totalRequests:r.totalRequests,totalTokens:r.totalTokens,lastUsedAt:r.lastUsedAt,lastErrorAt:r.lastErrorAt,consecutiveErrors:r.consecutiveErrors,cooldownUntil:r.cooldownUntil,healthStatus:t.enabled?r.healthStatus:"disabled"}})}}}});var Cd={};en(Cd,{ALL_PURPOSES:()=>rr,ModelRegistry:()=>is,deriveModelPurposes:()=>Ed,getModelRegistry:()=>Y,resetModelRegistry:()=>_k});import*as Ze from"node:fs";import{ProviderRegistry as Pk,ProviderVariantResolver as Ik}from"@xiaozhiclaw/provider-core";function Y(){return nr||(nr=new is,nr.load()),nr}function _k(){nr=null}function Ed(n){let e=[];switch((!n.mediaType||n.mediaType==="image_understanding"||n.mediaType==="video_understanding")&&e.push("textGeneration"),(n.vision||n.mediaType==="image_understanding")&&e.push("imageUnderstanding"),n.mediaType==="video_understanding"&&e.push("videoUnderstanding"),n.mediaType){case"image":e.push("imageGeneration");break;case"video":e.push("videoGeneration");break;case"tts":e.push("tts");break;case"stt":e.push("stt");break;case"music":case"music_realtime":e.push("musicGeneration");break;case"voice_clone":e.push("voiceClone");break;case"embedding":e.push("embedding");break;case"3d":e.push("threeDGeneration");break;case"realtime_audio":e.push("realtimeAudio");break}return e.includes("textGeneration")&&e.push("smallModel"),[...new Set(e.length>0?e:["textGeneration"])]}function Ek(n){switch(n){case"openai-chat":case"openai-responses":case"anthropic-messages":case"volcengine-responses":return n;default:return}}function Ck(n,e){switch(n){case"imageUnderstanding":case"videoUnderstanding":case"imageGeneration":case"videoGeneration":case"threeDGeneration":case"stt":case"tts":case"voiceClone":case"musicGeneration":case"realtimeAudio":case"realtimeVideo":case"embedding":return;default:return Ek(e)}}function Mk(n){switch(n){case"imageUnderstanding":case"videoUnderstanding":return["vision"];case"imageGeneration":case"videoGeneration":case"threeDGeneration":case"stt":case"tts":case"voiceClone":case"musicGeneration":case"realtimeAudio":case"realtimeVideo":case"embedding":return["media"];default:return[]}}var rr,is,nr,dt=X(()=>{"use strict";ae();_d();rr=["textGeneration","smallModel","stt","tts","imageGeneration","imageUnderstanding","videoGeneration","videoUnderstanding","threeDGeneration","embedding","voiceClone","musicGeneration","realtimeAudio","realtimeVideo"],is=class{keyPool;coreProviderRegistry=new Pk;providerVariantResolver=new Ik(this.coreProviderRegistry);models=new Map;modelEnabledOverrides=new Map;bindings={};settingsPath;changeListeners=[];constructor(e){this.settingsPath=it(),this.keyPool=new os(e?.providers),e?.models&&this.loadModelState(e.models),e?.bindings&&(this.bindings={...e.bindings}),this.hydrateCatalogModels()}getActiveModel(e){let t=this.bindings[e];if(!t)return null;let r=this.models.get(t);if(!r||!r.enabled)return null;let s=this.resolveTechnicalVariant(r,e),o=s?.provider??r.provider,i=s?.nativeModelId??r.nativeModelId??r.model,a=this.acquireKeyForProviderVariant(o);if(!a)return null;let{keyHandle:c,keyProviderId:l}=a,d=this.getProviderBaseUrl(o),u=this.getProviderBaseUrl(l);return{provider:o,model:i,apiKey:c.apiKey,baseUrl:d??(r.provider===o?r.baseUrl:void 0)??u,keyHandle:c}}peekActiveModel(e){let t=this.bindings[e];return t?this.models.get(t)??null:null}isAvailable(e){let t=this.peekActiveModel(e);return!!t?.enabled&&this.hasAvailableKeyForProviderVariant(t.provider)}resolveModelForPurpose(e){let t=this.peekActiveModel(e);return t?t.model:null}addProvider(e,t){this.keyPool.addProvider(e,t),this.emitChange()}removeProvider(e){this.keyPool.removeProvider(e);for(let[t,r]of this.models)r.provider===e&&this.removeModel(t);this.emitChange()}addKey(e,t,r){let s=this.keyPool.addKey(e,t,r);return this.emitChange(),s}removeKey(e){this.keyPool.removeKey(e),this.emitChange()}updateKey(e,t){this.keyPool.updateKey(e,t),this.emitChange()}setKeyHealth(e,t){this.keyPool.setKeyHealth(e,t),this.emitChange()}setStrategy(e,t){this.keyPool.setStrategy(e,t),this.emitChange()}addModel(e){let t=e.id??`${e.provider}:${e.model}`;return this.models.set(t,{...e,id:t,enabled:this.modelEnabledOverrides.get(t)??e.enabled}),this.emitChange(),t}replaceCatalogModels(e){let t=new Map;for(let r of e)t.set(r.id,{...r,enabled:this.modelEnabledOverrides.get(r.id)??r.enabled});for(let r of this.modelEnabledOverrides.keys())t.has(r)||this.modelEnabledOverrides.delete(r);this.models=t;for(let[r,s]of Object.entries(this.bindings))s&&!this.models.has(s)&&delete this.bindings[r];this.emitChange()}migrateModelIds(e){for(let[t,r]of e){let s=this.modelEnabledOverrides.get(t);s!==void 0&&!this.modelEnabledOverrides.has(r)&&this.modelEnabledOverrides.set(r,s),this.modelEnabledOverrides.delete(t);for(let[o,i]of Object.entries(this.bindings))i===t&&(this.bindings[o]=r)}this.emitChange()}removeModel(e){this.models.delete(e),this.modelEnabledOverrides.delete(e);for(let[t,r]of Object.entries(this.bindings))r===e&&delete this.bindings[t];this.emitChange()}enableModel(e){let t=this.models.get(e);t&&(t.enabled=!0),this.modelEnabledOverrides.set(e,!0),this.emitChange()}disableModel(e){let t=this.models.get(e);t&&(t.enabled=!1),this.modelEnabledOverrides.set(e,!1),this.emitChange()}listModels(e){let t=[...this.models.values()];return e?.purpose&&(t=t.filter(r=>r.purposes.includes(e.purpose))),e?.provider&&(t=t.filter(r=>r.provider===e.provider)),e?.enabledOnly&&(t=t.filter(r=>r.enabled)),t}getModel(e){return this.models.get(e)??null}setBinding(e,t){let r=this.models.get(t);if(!r)throw new Error(`Model "${t}" not found in pool.`);if(!r.purposes.includes(e))throw new Error(`Model "${t}" does not support purpose "${e}".`);this.bindings[e]=t,this.emitChange()}removeBinding(e){delete this.bindings[e],this.emitChange()}getBinding(e){let t=this.bindings[e];return t?this.models.get(t)??null:null}getAllBindings(){let e={};for(let t of rr){let r=this.bindings[t];e[t]=r?this.models.get(r)??null:null}return e}getProviderStatus(e){return this.keyPool.getPoolStatus(e)}getAllProviderStatus(){return this.keyPool.getAllStatus()}save(){let e={};try{Ze.existsSync(this.settingsPath)&&(e=JSON.parse(Ze.readFileSync(this.settingsPath,"utf-8")))}catch{e={}}delete e.provider,delete e.apiKey,delete e.model,delete e.baseUrl;let t={...e,providers:this.keyPool.exportConfig(),models:this.exportModelState(),bindings:{...this.bindings}},r=this.settingsPath.replace(/[/\\][^/\\]+$/,"");Ze.existsSync(r)||Ze.mkdirSync(r,{recursive:!0}),Ze.writeFileSync(this.settingsPath,JSON.stringify(t,null,2),"utf-8")}load(){try{if(!Ze.existsSync(this.settingsPath))return!1;let e=Ze.readFileSync(this.settingsPath,"utf-8"),t=JSON.parse(e);return t.providers&&this.keyPool.reloadConfig(t.providers),this.models.clear(),this.modelEnabledOverrides.clear(),t.models&&this.loadModelState(t.models),this.hydrateCatalogModels(),this.bindings=t.bindings??{},this.emitChange(),!0}catch{return!1}}exportConfig(){return{providers:this.keyPool.exportConfig(),models:this.exportModelState(),bindings:{...this.bindings}}}getTunable(e){try{if(!Ze.existsSync(this.settingsPath))return;let t=Ze.readFileSync(this.settingsPath,"utf-8");return JSON.parse(t).tunables?.[e]}catch{return}}getModelInfo(e,t){let r=this.listModels({provider:e}).find(s=>s.model===t);if(r)return{id:r.model,name:r.displayName,contextWindow:r.contextWindow,maxOutput:r.maxOutput,streamRequired:r.streamRequired}}getProviderDefaultModel(e){return this.listModels({provider:e,enabledOnly:!0})[0]?.model??this.listModels({provider:e})[0]?.model}hasConfiguredKeyForProviderVariant(e){return this.providerVariantKeyCandidates(e).some(t=>!!this.keyPool.getPoolStatus(t)?.keys.some(s=>s.enabled))}hasAvailableKeyForProviderVariant(e){return this.providerVariantKeyCandidates(e).some(t=>this.keyPool.hasAvailableKey(t))}listProviderDefs(){return this.keyPool.getAllStatus().map(e=>({id:e.providerId,name:e.providerId,transport:"",baseUrl:e.baseUrl??"",defaultModel:this.getProviderDefaultModel(e.providerId),models:this.listModels({provider:e.providerId}).map(t=>({id:t.model,name:t.displayName,contextWindow:t.contextWindow,maxOutput:t.maxOutput,streamRequired:t.streamRequired}))}))}resolveProviderApiKey(e){return this.getKeyForProvider(e)??void 0}onChange(e){return this.changeListeners.push(e),()=>{let t=this.changeListeners.indexOf(e);t>=0&&this.changeListeners.splice(t,1)}}getKeyForProvider(e){let r=this.acquireKeyForProviderVariant(e)?.keyHandle;if(!r)return null;let s=r.apiKey;return r.release({success:!0}),s}snapshotProviderKeys(){let e={};for(let t of this.keyPool.getAllStatus()){let r=this.getKeyForProvider(t.providerId);r&&(e[t.providerId]=r)}return e}getProviderBaseUrl(e){return this.coreProviderRegistry.getProvider(e)?.baseUrl??this.keyPool.getPoolStatus(e)?.baseUrl}acquireKeyForProviderVariant(e){for(let t of this.providerVariantKeyCandidates(e)){let r=this.keyPool.acquireKey(t);if(r)return{keyHandle:r,keyProviderId:t}}return null}resolveTechnicalVariant(e,t){let r=this.providerVariantKeyCandidates(e.provider).filter(o=>this.hasConfiguredKeyForProviderVariant(o));if(r.length===0)return;let s=this.providerVariantResolver.resolveBest({publicModel:e.model,requestedProtocol:Ck(t,e.transport),capabilities:Mk(t),purpose:t,userPreference:{providerIds:r}});if(s)return{provider:s.provider,nativeModelId:s.nativeModelId}}providerVariantKeyCandidates(e){let t=[e],r=this.coreProviderRegistry.getProvider(e),s=r?.group??r?.id??e;for(let o of this.coreProviderRegistry.listProviders())(o.group??o.id)===s&&t.push(o.id);return s!==e&&t.push(s),[...new Set(t)]}loadModelState(e){for(let t of e)typeof t.id!="string"||!t.id||typeof t.enabled=="boolean"&&this.modelEnabledOverrides.set(t.id,t.enabled)}hydrateCatalogModels(){let e=[];for(let r of this.coreProviderRegistry.listProviders())for(let s of this.coreProviderRegistry.listModels(r.id)){let o=s.aliases?.[0]??s.id,i=`${r.id}:${o}`;e.push({id:i,provider:r.id,model:o,displayName:s.name,purposes:Ed(s),baseUrl:r.baseUrl,enabled:this.modelEnabledOverrides.get(i)??!1,nativeModelId:s.id,transport:r.transport,contextWindow:s.contextWindow,maxOutput:s.maxOutput,streamRequired:s.streamRequired,capabilities:[...s.toolCall?["toolCall"]:[],...s.reasoning?["reasoning"]:[],...s.vision?["vision"]:[],...s.mediaType?[s.mediaType]:[]],pricing:{inputPer1M:s.costInput,outputPer1M:s.costOutput,cacheReadPer1M:s.costCacheRead,cacheWritePer1M:s.costCacheWrite}})}let t=new Map;for(let r of e)t.set(r.id,r);this.models=t}pruneInvalidBindings(){for(let[e,t]of Object.entries(this.bindings))t&&!this.models.has(t)&&delete this.bindings[e]}exportModelState(){let e=new Map;for(let[t,r]of this.modelEnabledOverrides)e.set(t,r);for(let t of this.models.values())e.set(t.id,t.enabled);return[...e.entries()].map(([t,r])=>({id:t,enabled:r}))}emitChange(){for(let e of this.changeListeners)try{e()}catch{}}},nr=null});import{readFile as Nk}from"node:fs/promises";function on(n){let e=typeof n.content=="string"?n.content:n.content!=null?JSON.stringify(n.content):"";return Math.ceil(e.length/4)}function an(n){let e=0;for(let t of n)e+=on(t);return e}function Nd(n){if(!n)return 128e3;if(n in Qi)return Qi[n];let e=n.toLowerCase();for(let[t,r]of Object.entries(Qi))if(e.startsWith(t.toLowerCase()))return r;return 128e3}function Ok(){return Y().resolveModelForPurpose("textGeneration")??Dk}function Od(){return ea}function Lk(n,e){return async(t,r)=>{let s=e?.transport,o=e?.apiKey;if(!s||!o)return n.debug("[context-compression] no LLM transport for summarization \u2014 using sync fallback"),Zi(t);try{let i="",a=e?.model??Ok();for await(let c of s.stream({model:a,messages:[{role:"system",content:"You are a precise conversation summarizer."},{role:"user",content:r}],maxTokens:2e3,temperature:.3},o,AbortSignal.timeout(3e4)))c.type==="delta"&&(i+=c.text);return i||(n.warn("[context-compression] empty summary response"),Zi(t))}catch(i){return n.warn({err:i.message},"[context-compression] summarize call error \u2014 using fallback"),Zi(t)}}}function Zi(n){let e=[],t=n.filter(o=>o.role==="user"),r=t.slice(0,20).map(o=>{let i=typeof o.content=="string"?o.content:JSON.stringify(o.content??"");return`- [user]: ${i.slice(0,300)}${i.length>300?"...":""}`});e.push(`## User Requests (${t.length} messages)`),e.push(...r);let s=n.filter(o=>o.role==="assistant");if(s.length>0){let o=s.slice(0,10).map(i=>{let a=typeof i.content=="string"?i.content:JSON.stringify(i.content??"");return`- [assistant]: ${a.slice(0,150)}${a.length>150?"...":""}`});e.push("",`## Assistant Responses (${s.length} total)`),e.push(...o)}return e.join(`
|
|
25
|
+
`)}function $k(){return Lo(new sn(ta),new Vt(20,on),new Tn(on))}function Md(n,e){let t=$o(new sn(ta),new Vt(20,on),new Vn({protectedHeadExchanges:1,protectedTailMessages:8,summarize:n,estimateTokens:on}),new Tn(on));return new zn({inner:t,estimateTokens:on,onCacheInvalidated:e?.onCacheInvalidated})}function Ld(n,e){let t=e?.budget??Vr({modelContextWindow:Nd(e?.model)}),s=(e?.pipeline??$k()).compress(n,t);if(s.droppedCount>0){let o=an(n),i=an(s.messages);Dd.record({timestamp:Date.now(),strategy:s.strategy,tokensBefore:o,tokensAfter:i,droppedCount:s.droppedCount,latencyMs:s.metrics?.latencyMs??0,usedLlm:!1,cacheInvalidated:s.metrics?.cacheInvalidated??!1,tier:Qn(o,t)})}return s.droppedCount>0&&na?.(s.droppedCount,an(s.messages)),s}async function jk(n,e,t){let r=t??Vr({modelContextWindow:Nd(e.model)}),s=an(n),o=Qn(s,r),i;switch(o){case"none":i={messages:n,droppedCount:0,strategy:"none"};break;case"trim-only":i=new sn(ta).compress(n,r);break;case"sliding-window":{i=await Md(e.summarize).compressAsync(n,r);break}case"llm-summarize":{let a=e.pipeline??Md(e.summarize);i=Jn(a)?await a.compressAsync(n,r):a.compress(n,r);break}}return i.droppedCount>0&&(i={...i,messages:await Uo(i.messages,n,{maxFiles:5,maxTokenBudget:5e4,readFile:async a=>{try{return await Nk(a,"utf-8")}catch{return null}}})}),Uk(n,i,r),i}function Uk(n,e,t){if(e.droppedCount>0||e.metrics?.usedLlm){let r=e.metrics?.tokensBefore||an(n),s=e.metrics?.tokensAfter||an(e.messages);Dd.record({timestamp:Date.now(),strategy:e.strategy,tokensBefore:r,tokensAfter:s,droppedCount:e.droppedCount,latencyMs:e.metrics?.latencyMs??0,usedLlm:e.metrics?.usedLlm??!1,cacheInvalidated:e.metrics?.cacheInvalidated??!1,tier:Qn(r,t)})}if(e.droppedCount>0){let r=e.metrics?.tokensAfter||an(e.messages);na?.(e.droppedCount,r)}}function Fk(n,e){let t=Lk(n,e),r={id:"builtin-compressor",label:"4-Layer Compression Funnel (built-in)",async compressAsync(s,o,i){return jk(s,{budget:o,model:i?.model,sessionId:i?.sessionId,summarize:t},o)}};ea.register(r),ea.activate(r.id),n.info(`[context-compression] registered context engine: ${r.id}`)}function $d(n,e,t){Fk(e,t),n.register({point:"context.before_compact",priority:50,label:"context-compression-bridge",handler:(r,s)=>{let o=s.messageCount;return o&&o>0&&e.debug(`[context-compression] before_compact: ${o} messages entering compression`),{action:"continue"}}}),na=(r,s)=>{e.debug(`[context-compression] after_compact: removed ${r}, ${s} tokens remaining`),n.invoke("context.after_compact",{sessionId:"",turnId:"",removedCount:r,tokenCount:s}).catch(()=>{})}}var Qi,ta,Dk,Dd,ea,na,ra=X(()=>{"use strict";er();dt();Qi={"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};ta=8e3,Dk="deepseek-v4-flash";Dd=new Xn(200),ea=new Yn;na=null});function jd(n,e,t){let r=t-e;return`[Budget] ${Math.round(n)}% used (${e.toLocaleString()} / ${t.toLocaleString()} tokens). ${r.toLocaleString()} tokens remaining. `+(n>=90?"Wrap up your current taskyou are near the token limit.":"Continue workingdo not summarize prematurely.")}var Ud=X(()=>{"use strict"});var Fd={};en(Fd,{resolveToolEligibility:()=>Gk});function Hk(n,e){if(Bk.some(t=>t.test(n)))return!0;if(e)for(let t of e)try{if(new RegExp(t,"i").test(n))return!0}catch{}return!1}function qk(n,e){let t=n.function.name,r=n.meta,s=[];return e.blockedToolNames?.includes(t)?(s.push("policy_blocked"),{level:5,reasons:s}):r?.isReadOnly?(s.push("always_allowed"),{level:1,reasons:s}):r?.requiresApproval?(s.push("approval_required"),{level:4,reasons:s}):r?.isDangerous||Hk(t,e.dangerousPatterns)?(s.push("dangerous_tool"),{level:3,reasons:s}):{level:2,reasons:s}}function Wk(n){switch(n){case 1:return"eligible";case 2:return"eligible";case 3:return"dangerous-notify";case 4:return"approval-required";case 5:return"blocked-by-policy"}}function Gk(n,e={}){let t=new Map,r=[],s=[],o=[];for(let i of n){let a=i.function.name,{level:c,reasons:l}=qk(i,e),d=Wk(c),u={toolName:a,status:d,permissionLevel:c,approvalRequired:c===4,reasonCodes:l};t.set(a,u),c===5?s.push(u):(r.push(i),c===4&&o.push(u))}return{eligibleTools:r,blockedTools:s,approvalRequiredTools:o,eligibilityByName:t}}var Bk,Bd=X(()=>{"use strict";Bk=[/^(?:bash|shell|exec|terminal|run_command)$/i,/^(?:write_file|delete_file|move_file|create_directory)$/i,/^(?:git_push|git_reset|git_force)$/i]});import{accumulateToolCalls as zk}from"@xiaozhiclaw/provider-core";function Yk(n){let e=n.split(".").pop()?.toLowerCase()??"";return["png","jpg","jpeg","gif","webp","svg","bmp","ico"].includes(e)?"image":["md","txt","pdf","doc","docx","rtf","html"].includes(e)?"document":["mermaid","mmd","dot","puml","plantuml"].includes(e)?"diagram":["csv","tsv","xlsx","xls"].includes(e)?"table":["ts","tsx","js","jsx","py","rs","go","java","c","cpp","h","cs","rb","sh","sql","json","yaml","yml","toml","xml","css","scss","vue","svelte"].includes(e)?"code":"file"}function Jk(n){let e=n.split(".").pop()?.toLowerCase()??"";return{ts:"typescript",tsx:"typescriptreact",js:"javascript",jsx:"javascriptreact",py:"python",rs:"rust",go:"go",java:"java",c:"c",cpp:"cpp",h:"c",cs:"csharp",rb:"ruby",sh:"shellscript",sql:"sql",json:"json",yaml:"yaml",yml:"yaml",toml:"toml",xml:"xml",html:"html",css:"css",scss:"scss",vue:"vue",svelte:"svelte",md:"markdown"}[e]}function eS(n){if(!Zk.has(n.toolName))return!1;let e=typeof n.message?.content=="string"?n.message.content.trim():"";return e.length>0&&e.length<200&&Qk.test(e)}function Hd(n,e){for(let t=n.length-1;t>=0;t--){let r=n[t];if(!r||r.role!=="tool")continue;let s=typeof r.content=="string"?r.content:"";if(s.startsWith("Error: "))return s.slice(7).trim()}}function tS(n){return typeof n=="number"&&Number.isFinite(n)&&n>=1?Math.min(Math.round(n),100):Go}function qd(n){let e=n.message.toLowerCase();return n.status===413||e.includes("prompt_too_long")||e.includes("context_length_exceeded")||e.includes("maximum context length")}function nS(n){return n==="length"||n==="max_tokens"}function Wd(n){let e=n.message.toLowerCase();return(e.includes("image")||e.includes("media")||e.includes("file too large")||e.includes("payload too large"))&&(n.status===413||e.includes("too large")||e.includes("size"))}function rS(n){let e=n.headers;if(!e)return null;let t=e["retry-after"]??e["Retry-After"];if(!t)return null;let r=parseInt(t,10);return!isNaN(r)&&r>0?r*1e3:null}function sS(n){if(n.status!==400)return null;let e=n.message.match(/input length and `max_tokens` exceed context limit: (\d+) \+ (\d+) > (\d+)/);if(!e?.[1]||!e?.[3])return null;let t=parseInt(e[1],10),r=parseInt(e[3],10);if(isNaN(t)||isNaN(r))return null;let s=r-t-1e3;return s>=3e3?s:null}function oS(n){return n.filter(e=>e.role!=="assistant"?!0:!(typeof e.content=="string"&&e.content.trim()===""))}async function*Gd(n,e,t,r){let{turnId:s,sessionId:o,messages:i,tools:a,model:c,apiKey:l,temperature:d=0,hooks:u,signal:p}=n,m={sessionId:o,turnId:s},h=n.maxTurns??0,f=n.querySource,{resolveToolEligibility:y}=await Promise.resolve().then(()=>(Bd(),Fd)),b=y(a,n.toolEligibilityContext),k=b.eligibleTools;for(let j of b.blockedTools)yield{type:"tool_blocked",turnId:s,callId:"",name:j.toolName,reason:"blocked-by-policy"};if(!k.length){yield*iS(s,c,i,l,d,p,e,r);return}let A=tS(n.maxRounds),_={contextWindowTokens:n.contextWindowTokens??zo,responseBufferTokens:Xo,maxOutputTokens:n.maxOutputTokens??Yo,abortSignal:p,reactiveCompactEnabled:!0,outputEscalationEnabled:!0},I=new Set,N=0,L=k,F,T={messages:[...i],maxOutputTokensRecoveryCount:0,hasAttemptedReactiveCompact:!1,maxOutputTokensOverride:void 0,turnCount:1,transition:void 0,guardState:Gi(_),reactiveCompactState:Yi(),toolLoopState:es({maxRounds:A,replayMessages:[...i]}).state,consecutiveFailedRounds:0,finalText:"",totalUsage:{inputTokens:0,outputTokens:0},collapseStore:Ho(),currentModel:c,consecutive529Errors:0,consecutiveApiRetries:0,stopHookActive:void 0,lastResponseId:void 0,snipRemovedIds:new Set,contentReplacementState:ud(),budgetContinuationCount:0,lastBudgetDeltaTokens:0,lastBudgetGlobalTokens:0,identicalCallCounts:new Map,toolFailureCounts:new Map,fileReadCounts:new Map},ce=Math.max(h*5,200),le=0;for(;;){if(le++,le>ce){r.info(`hard iteration cap reached (${ce}), forcing completion`);let P=T.finalText||sr(T.messages,r);yield{type:"end",turnId:s,content:P,usage:T.totalUsage,model:T.currentModel};return}let{messages:j,maxOutputTokensRecoveryCount:ve,hasAttemptedReactiveCompact:oe,maxOutputTokensOverride:$e,turnCount:te,guardState:J,reactiveCompactState:R,collapseStore:B}=T,{toolLoopState:U}=T;if(F){try{let P=await F;P&&(yield{type:"tool_use_summary",turnId:s,summary:P})}catch{}F=void 0}if(n.refreshTools&&te>1){let P=n.refreshTools();P!==L&&(L=P,r.debug(`tools refreshed: ${P.length} tools`))}if(Xi(J,_)){r.info(`turn aborted by guard at turn ${te}`),yield{type:"error",turnId:s,error:"Turn aborted",code:"ABORTED",usage:T.totalUsage};return}let Ae=Ki(J,_);if(Ae.level==="blocking"){Ae.reason==="prompt_too_long"&&An(R)&&(R.attemptedThisTurn=!0,J.hasAttemptedReactiveCompact=!0,r.info(`token budget blocking (${Ae.reason}), reactive compact needed`),yield{type:"recovery",turnId:s,action:"reactive_compact",detail:"token budget pre-check"}),r.info(`token budget blocking (${Ae.reason}), ending tool loop`);break}Ae.level==="warning"&&r.info(`token budget warning: ${Ae.usagePercent}% used, ${Ae.remainingTokens} remaining`);let fe;{let P=await yd(j,T.contentReplacementState,o);fe=P.messages,P.newlyReplacedCount>0&&(r.info(`tool-result-budget: persisted ${P.newlyReplacedCount} oversized tool results`),yield{type:"recovery",turnId:s,action:"tool_result_budget",detail:`${P.newlyReplacedCount} persisted`})}{let P=Fo(fe,T.snipRemovedIds);fe=P.messages,P.removedCount>0&&(r.info(`snip: removed ${P.removedCount} messages, freed ~${P.tokensFreed} tokens`),yield{type:"recovery",turnId:s,action:"snip",detail:`${P.removedCount} messages`})}{let C=new Vt().compress(fe,0);C.droppedCount>0&&(fe=C.messages,r.info(`microcompact: cleared ${C.droppedCount} old tool results`))}if(fe=qo(fe,B).messages,J.promptTokens>0){let P=_.contextWindowTokens*.75,C=Od().getActive(),O;C?O=await C.compressAsync(fe,P,{model:T.currentModel,sessionId:o}):O=Ld(fe,{budget:P,model:T.currentModel}),O.droppedCount>0&&(fe=O.messages,r.info(`autocompact: ${O.strategy}, dropped ${O.droppedCount}`),yield{type:"recovery",turnId:s,action:"autocompact",detail:`${O.strategy}: ${O.droppedCount} dropped`},T.hasAttemptedReactiveCompact=!1,u?.invoke("context.after_compact",{...m,removedCount:O.droppedCount}).catch(()=>{}))}fe=oS(fe);let Mt=Mi({tools:L,toolChoice:n.toolChoice??"auto"}),g=es({maxRounds:A,replayMessages:fe,lastStopReason:U.lastStopReason,options:{stopReason:U.lastStopReason}}),S=Mt.extraSystemPrompt?[{role:"system",content:Mt.extraSystemPrompt},...g.state.replayMessages]:g.state.replayMessages;U=g.state,g.recoveryActions.length>0&&r.debug(`tool loop recovery: ${g.recoveryActions.map(P=>P.detail??P.kind).join("; ")}`),r.debug(`turn ${te}, messages: ${S.length}`),u?.invoke("turn.before_inference",{...m,model:T.currentModel}).catch(()=>{});let x=!1,E=[],w=new Map,$="stop",D,M=null,W=!1,ie=[],Z=[];try{for await(let P of e.stream({model:T.currentModel,messages:S,tools:Mt.tools,toolChoice:Mt.normalizedToolChoice??"auto",temperature:d,maxTokens:($e??J.currentMaxOutputTokens)||void 0,streamRequired:n.streamRequired,previousResponseId:T.lastResponseId,reasoning:n.reasoning,promptCacheKey:n.promptCacheKey,promptCacheRetention:n.promptCacheRetention,serviceTier:n.serviceTier,openaiBuiltinTools:n.openaiBuiltinTools,maxToolCalls:n.maxToolCalls,parallelToolCalls:n.parallelToolCalls,textVerbosity:n.textVerbosity},l,p))switch(P.type){case"delta":E.push(P.text),x||(yield{type:"delta",turnId:s,text:P.text});break;case"tool_call_delta":x=!0,zk(w,P);break;case"reasoning_delta":ie.push(P.text);break;case"reasoning_block_complete":P.signature&&Z.push({thinking:ie.join(""),signature:P.signature}),ie.length=0;break;case"usage":D={inputTokens:P.promptTokens,outputTokens:P.completionTokens,reasoningTokens:P.reasoningTokens,cacheRead:P.cacheReadTokens,cacheWrite:P.cacheCreationTokens};break;case"response_id":T.lastResponseId=P.id;break;case"annotations":yield{type:"annotations",turnId:s,annotations:P.annotations};break;case"builtin_tool_status":yield{type:"heartbeat",turnId:s,message:`${P.toolType}: ${P.event}`};break;case"done":$=P.finishReason;break}if(x||u?.invoke("turn.after_inference",{...m,model:T.currentModel}).catch(()=>{}),n.postSamplingHooks&&n.postSamplingHooks.length>0){let P=T.currentModel;for(let C of n.postSamplingHooks)try{C({messages:[...fe],model:P,sessionId:o})}catch{}}}catch(P){if(P instanceof Zn&&n.fallbackModel){r.info(`model fallback triggered: ${P.originalModel} \u2192 ${P.fallbackModel}`),yield{type:"recovery",turnId:s,action:"model_fallback",detail:`${P.originalModel} \u2192 ${P.fallbackModel}`},T={...T,currentModel:P.fallbackModel,consecutive529Errors:0,consecutiveApiRetries:0,transition:void 0};continue}let C=P instanceof Error?P.message:String(P),O=typeof P?.status=="number"?P.status:void 0;if(!O&&C&&(C.includes("ECONNRESET")||C.includes("EPIPE"))){let re=(T.consecutiveApiRetries??0)+1;if(re>Rn){r.info(`stale connection retry limit reached (${Rn}), aborting`),yield{type:"error",turnId:s,error:C,code:"RETRIES_EXHAUSTED",usage:T.totalUsage};return}r.info(`stale connection (${C.includes("ECONNRESET")?"ECONNRESET":"EPIPE"}): retrying`),yield{type:"recovery",turnId:s,action:"stale_connection_retry",detail:C.slice(0,80)},T={...T,consecutiveApiRetries:re,transition:void 0};continue}let H=sS({status:O,message:C});if(H!==null){r.info(`max_tokens overflow: adjusting to ${H}`),J.currentMaxOutputTokens=H,T={...T,maxOutputTokensOverride:H,transition:void 0};continue}if(Fi(O)){T.consecutive529Errors++;let re=2,we=n.fallbackModel&&T.currentModel!==n.fallbackModel;if(T.consecutive529Errors>re&&!we&&!ns()){r.info(`transient ${O} \xD7 ${T.consecutive529Errors}: hard limit reached, aborting`),yield{type:"error",turnId:s,error:`API unavailable after ${T.consecutive529Errors} consecutive ${O} errors`,code:"API_ERROR",usage:T.totalUsage};return}if(T.consecutive529Errors>=si&&n.fallbackModel&&T.currentModel!==n.fallbackModel){r.info(`529 \xD7 ${T.consecutive529Errors}: triggering fallback to ${n.fallbackModel}`),yield{type:"recovery",turnId:s,action:"model_fallback",detail:`529 \xD7 ${T.consecutive529Errors}`},T={...T,currentModel:n.fallbackModel,consecutive529Errors:0,transition:void 0};continue}if(ns()){let Q=ts(T.consecutive529Errors);r.info(`persistent retry: waiting ${Q}ms (attempt ${T.consecutive529Errors})`);let he=Q;for(;he>0;){if(p?.aborted){yield{type:"error",turnId:s,error:"Aborted during retry wait",code:"ABORTED",usage:T.totalUsage};return}yield{type:"heartbeat",turnId:s,message:`Retrying in ${Math.ceil(he/1e3)}s (${O})`};let ot=Math.min(he,ri);await new Promise(Co=>setTimeout(Co,ot)),he-=ot}T={...T,transition:void 0};continue}if(Ui(f)){let he=rS({status:O,message:C})??ts(T.consecutive529Errors);r.info(`transient ${O}: retry in ${he}ms`),yield{type:"recovery",turnId:s,action:"retry",detail:`${O} retry in ${he}ms`},await new Promise(ot=>setTimeout(ot,he)),T={...T,transition:void 0};continue}r.info(`background source ${f}: not retrying ${O}`)}M={status:O,message:C}}if(M&&u?.invoke("turn.after_inference",{...m,model:T.currentModel,response:{error:M.message}}).catch(()=>{}),M)if(qd(M))W=!0,r.info(`withheld prompt_too_long error (status=${M.status})`);else if(Wd(M))W=!0,r.info(`withheld media_size error (status=${M.status})`);else{let P=Vi({status:M.status??500,message:M.message},J,_);if(P.action==="reactive_compact"&&An(R)&&(R.attemptedThisTurn=!0,J.hasAttemptedReactiveCompact=!0,yield{type:"recovery",turnId:s,action:"reactive_compact",detail:`API ${M.status??500}: ${M.message}`}),P.action==="retry"){let O=(T.consecutiveApiRetries??0)+1;if(O>Rn){r.info(`API retry limit reached (${Rn}), aborting`);let H=Sn(M.status,M.message);yield{type:"error",turnId:s,error:M.message,code:H,usage:T.totalUsage};return}yield{type:"recovery",turnId:s,action:"retry",detail:P.reason},T={...T,consecutiveApiRetries:O,transition:void 0};continue}let C=Sn(M.status,M.message);u?.invoke("stop.failure",{sessionId:o,reason:C,error:M.message}).catch(()=>{}),yield{type:"error",turnId:s,error:M.message,code:C,usage:T.totalUsage};return}D&&(T.totalUsage.inputTokens+=D.inputTokens,T.totalUsage.outputTokens+=D.outputTokens,D.reasoningTokens&&(T.totalUsage.reasoningTokens=(T.totalUsage.reasoningTokens??0)+D.reasoningTokens),D.cacheRead&&(T.totalUsage.cacheRead=(T.totalUsage.cacheRead??0)+D.cacheRead),D.cacheWrite&&(T.totalUsage.cacheWrite=(T.totalUsage.cacheWrite??0)+D.cacheWrite)),D?.inputTokens&&(J.promptTokens=D.inputTokens);let ne=E.join("");ne&&(T.finalText=ne);let pe=[...w.values()].map(P=>({id:P.id||`tc_${s}_${te}_${Math.random().toString(36).slice(2,8)}`,type:"function",function:{name:P.name,arguments:P.arguments}}));if(pe.length===0&&!x){if(W&&M&&qd(M)){if(T.transition?.reason!=="collapse_drain_retry"){let O=Wo(fe,B);if(O.committed>0){r.info(`collapse drain: committed ${O.committed} stages`),yield{type:"recovery",turnId:s,action:"collapse_drain",detail:`${O.committed} stages committed`},T={...T,messages:O.messages,transition:{reason:"collapse_drain_retry",committed:O.committed}};continue}}if(An(R)){R.attemptedThisTurn=!0,J.hasAttemptedReactiveCompact=!0,r.info("withheld 413: reactive compact attempt"),yield{type:"recovery",turnId:s,action:"reactive_compact",detail:"withheld prompt_too_long"},T={...T,hasAttemptedReactiveCompact:!0,transition:{reason:"reactive_compact_retry"}};continue}r.info("withheld 413: recovery exhausted, surfacing error"),u?.invoke("stop.failure",{sessionId:o,reason:"prompt_too_long",error:M.message}).catch(()=>{}),yield{type:"error",turnId:s,error:M.message,code:"PROMPT_TOO_LONG",usage:T.totalUsage};return}if(W&&M&&Wd(M)){if(An(R)){R.attemptedThisTurn=!0,J.hasAttemptedReactiveCompact=!0,r.info("withheld media error: reactive compact strip-retry"),yield{type:"recovery",turnId:s,action:"reactive_compact",detail:"media error strip-retry"},T={...T,hasAttemptedReactiveCompact:!0,transition:{reason:"reactive_compact_retry"}};continue}r.info("withheld media error: recovery exhausted"),u?.invoke("stop.failure",{sessionId:o,reason:"media_error",error:M.message}).catch(()=>{}),yield{type:"error",turnId:s,error:M.message,code:"IMAGE_ERROR",usage:T.totalUsage};return}if(nS($)){J.consecutiveTruncations+=1;let O=n.modelMaxOutputTokens??Jo,H=zi(J,_,O);if(H.shouldEscalate&&$e===void 0){J.currentMaxOutputTokens=H.newMax,r.info(`max_output_tokens escalate: ${H.newMax} tokens`),yield{type:"recovery",turnId:s,action:"output_escalation",detail:`${H.newMax} tokens`},T={...T,maxOutputTokensOverride:Zo,transition:{reason:"max_output_tokens_escalate"}};continue}if(ve<Qo){let re={role:"user",content:"Output token limit hit. Resume directly \u2014 no apology, no recap of what you were doing. Pick up mid-thought if that is where the cut happened. Break remaining work into smaller pieces."};r.info(`max_output_tokens recovery #${ve+1}`),yield{type:"recovery",turnId:s,action:"max_output_tokens_recovery",detail:`attempt ${ve+1}`},T={...T,messages:[...fe,re],maxOutputTokensRecoveryCount:ve+1,maxOutputTokensOverride:void 0,transition:{reason:"max_output_tokens_recovery",attempt:ve+1}};continue}r.info("max_output_tokens recovery exhausted, completing with partial content")}else J.consecutiveTruncations=0;if(U=Zr(U,{replayMessages:j,lastStopReason:"completed"}),u){let O=await u.invoke("stop",{sessionId:o,reason:"completed"});if(O.action==="prevent"){r.info(`stop hook prevented continuation: ${O.reason??"no reason"}`),yield{type:"end",turnId:s,content:T.finalText,usage:T.totalUsage,model:T.currentModel};return}if(O.action==="abort"){let H=O.reason??"Stop hook requested continuation";r.info(`stop hook blocking: ${H}`);let re={role:"user",content:H},we={role:"assistant",content:T.finalText,...Z.length>0&&{thinkingBlocks:[...Z]}};T={...T,messages:[...j,we,re],stopHookActive:!0,transition:{reason:"stop_hook_blocking"}};continue}}if(n.tokenBudget&&n.tokenBudget>0&&T.budgetContinuationCount<5){let O=T.totalUsage.inputTokens+T.totalUsage.outputTokens+(T.totalUsage.reasoningTokens??0),H=O/n.tokenBudget*100,re=O-T.lastBudgetGlobalTokens,we=T.budgetContinuationCount>=ei&&re<Xr&&T.lastBudgetDeltaTokens<Xr;if(we&&r.info(`token budget early stop: diminishing returns at ${Math.round(H)}% (delta=${re})`),!we&&H<90){let Q=T.budgetContinuationCount+1,he={role:"user",content:jd(H,O,n.tokenBudget)};r.info(`token budget continuation #${Q}: ${Math.round(H)}% used`),yield{type:"recovery",turnId:s,action:"budget_continuation",detail:`${Math.round(H)}% used (#${Q})`};let ot={role:"assistant",content:T.finalText,...Z.length>0&&{thinkingBlocks:[...Z]}};T={...T,messages:[...j,ot,he],budgetContinuationCount:Q,lastBudgetDeltaTokens:re,lastBudgetGlobalTokens:O,transition:{reason:"token_budget_continuation"}};continue}}if(!T.stopHookActive){let O=i.find(Q=>Q.role==="user"),H=typeof O?.content=="string"?O.content:"",re=/创建文件|生成文件|写入|写一个|建一个|新建|重写|改写|create\s+(a\s+)?file|write\s+(a\s+)?file|make\s+(a\s+)?file|修改|改成|把.*改|文件名叫/i.test(H),we=I.has("write")||I.has("edit");if(re&&!we){if(r.info("AP1 action-verification: user requested file action but no write/edit tool was called, injecting nudge"),N>0){let ot=[...j].reverse().find(Co=>Co.role==="tool");ot&&typeof ot.content=="string"&&(ot.content+=`
|
|
26
26
|
|
|
27
|
-
\u26A0\uFE0F NOTE: You used shell commands but did not call the write or edit tool to create/modify the file. Shell commands may fail silently or produce incorrect results on this platform. Please use the 'write' tool directly to create the requested file with the correct content.`)}let Q={role:"user",content:N===0?"You described what to do but did not actually call any tool to write or edit a file. Please use the write or edit tool now to perform the requested action. Do not just describe the changes \u2014 actually make them.":"You used shell commands but did not call the write or edit tool to create/modify the file. Shell commands may fail on this platform. Please use the write tool directly to create the requested file with the correct content."},he={role:"assistant",content:T.finalText,...Z.length>0&&{thinkingBlocks:[...Z]}};T={...T,messages:[...j,he,Q],stopHookActive:!0,transition:{reason:"stop_hook_blocking"}};continue}}if(!T.stopHookActive&&N>=3&&I.has("write")){let O=0;for(let H of j){let re=H,we=re.is_error===!0||typeof re.content=="string"&&re.content.startsWith("Error:");re.role==="tool"&&typeof re.content=="string"&&!we&&O++}if(O>=3){r.info("AP3 verification nudge: 3+ files created, injecting completeness check");let H={role:"user",content:"You created multiple files. Before completing, verify: (1) All imports between your files resolve to real exports. (2) No TODO, placeholder, or 'not implemented' stubs remain. (3) Functions that are imported are actually called, not just declared. If everything is correct, confirm completion. If not, fix the issues now."},re={role:"assistant",content:T.finalText,...Z.length>0&&{thinkingBlocks:[...Z]}};T={...T,messages:[...j,re,H],stopHookActive:!0,transition:{reason:"stop_hook_blocking"}};continue}}if(N>0){let O={ok:!0,toolCallCount:N,distinctToolCount:I.size,multiStep:N>=2,hasSubAgent:!1,feedback:null,existingSkillName:null},H=Qr(O,{tools:[...I],projectRoot:n.projectRoot});H&&(yield{type:"skill_instruction",turnId:s,instruction:H})}let C=T.finalText||sr(j,r);yield{type:"end",turnId:s,content:C,usage:T.totalUsage,model:T.currentModel};return}let He=Z.length===0&&ie.length>0?ie.join(""):void 0;j.push(No(pe,T.finalText||void 0,Z.length>0?Z:void 0,He)),U=ji(U,{replayMessages:j,pendingToolCallIds:pe.map(P=>P.id),completedToolCallIds:U.completedToolCallIds,lastStopReason:"tool_calls"});let Ce=T.identicalCallCounts,Gt=[],ge=[],Nt=!1;for(let P of pe){let C=`${P.function.name}::${P.function.arguments}`,O=Ce.get(C)??0;Ce.set(C,O+1),O+1>Vo?(ge.push(P),Nt||(Nt=!0,r.info(`AP4 blocked: ${P.function.name} repeated ${O+1}x`))):Gt.push(P)}let St=[];for(let P of ge){let C=Ce.get(`${P.function.name}::${P.function.arguments}`),O=
|
|
27
|
+
\u26A0\uFE0F NOTE: You used shell commands but did not call the write or edit tool to create/modify the file. Shell commands may fail silently or produce incorrect results on this platform. Please use the 'write' tool directly to create the requested file with the correct content.`)}let Q={role:"user",content:N===0?"You described what to do but did not actually call any tool to write or edit a file. Please use the write or edit tool now to perform the requested action. Do not just describe the changes \u2014 actually make them.":"You used shell commands but did not call the write or edit tool to create/modify the file. Shell commands may fail on this platform. Please use the write tool directly to create the requested file with the correct content."},he={role:"assistant",content:T.finalText,...Z.length>0&&{thinkingBlocks:[...Z]}};T={...T,messages:[...j,he,Q],stopHookActive:!0,transition:{reason:"stop_hook_blocking"}};continue}}if(!T.stopHookActive&&N>=3&&I.has("write")){let O=0;for(let H of j){let re=H,we=re.is_error===!0||typeof re.content=="string"&&re.content.startsWith("Error:");re.role==="tool"&&typeof re.content=="string"&&!we&&O++}if(O>=3){r.info("AP3 verification nudge: 3+ files created, injecting completeness check");let H={role:"user",content:"You created multiple files. Before completing, verify: (1) All imports between your files resolve to real exports. (2) No TODO, placeholder, or 'not implemented' stubs remain. (3) Functions that are imported are actually called, not just declared. If everything is correct, confirm completion. If not, fix the issues now."},re={role:"assistant",content:T.finalText,...Z.length>0&&{thinkingBlocks:[...Z]}};T={...T,messages:[...j,re,H],stopHookActive:!0,transition:{reason:"stop_hook_blocking"}};continue}}if(N>0){let O={ok:!0,toolCallCount:N,distinctToolCount:I.size,multiStep:N>=2,hasSubAgent:!1,feedback:null,existingSkillName:null},H=Qr(O,{tools:[...I],projectRoot:n.projectRoot});H&&(yield{type:"skill_instruction",turnId:s,instruction:H})}let C=T.finalText||sr(j,r);yield{type:"end",turnId:s,content:C,usage:T.totalUsage,model:T.currentModel};return}let He=Z.length===0&&ie.length>0?ie.join(""):void 0;j.push(No(pe,T.finalText||void 0,Z.length>0?Z:void 0,He)),U=ji(U,{replayMessages:j,pendingToolCallIds:pe.map(P=>P.id),completedToolCallIds:U.completedToolCallIds,lastStopReason:"tool_calls"});let Ce=T.identicalCallCounts,Gt=[],ge=[],Nt=!1;for(let P of pe){let C=`${P.function.name}::${P.function.arguments}`,O=Ce.get(C)??0;Ce.set(C,O+1),O+1>Vo?(ge.push(P),Nt||(Nt=!0,r.info(`AP4 blocked: ${P.function.name} repeated ${O+1}x`))):Gt.push(P)}let St=[];for(let P of ge){let C=Ce.get(`${P.function.name}::${P.function.arguments}`),O=Hd(j,P.function.name),H=O?`This exact tool call has been attempted ${C} times. Last error: ${O}. Do not retry. Report this error to the user.`:`This exact tool call has been attempted ${C} times and keeps failing. Do not retry it. Report the issue to the user or try a completely different approach.`,re=Kt(P.id,{ok:!1,error:H});j.push(re),St.push(P.id),I.add(P.function.name),N++,yield{type:"tool_result",turnId:s,callId:P.id,name:P.function.name,ok:!1,error:H}}if(ge.length>0){let P=Hd(j,ge[0].function.name),C={role:"user",content:"Tool calls were blocked because you repeated them with identical arguments too many times. "+(P?`The error was: "${P}". Tell the user about this error. `:"The operation is not working. ")+"Stop retrying and report the result to the user."};j.push(C)}let Ge=[],_o=[];for(let P of Gt)(T.toolFailureCounts.get(P.function.name)??0)>=zr?_o.push(P):Ge.push(P);if(_o.length>0){for(let C of _o){let O=T.toolFailureCounts.get(C.function.name),H=`Tool "${C.function.name}" has failed ${O} times this turn with different arguments. The target likely does not exist. Stop trying variations and report the issue to the user.`,re=Kt(C.id,{ok:!1,error:H});j.push(re),St.push(C.id),I.add(C.function.name),N++,yield{type:"tool_result",turnId:s,callId:C.id,name:C.function.name,ok:!1,error:H},r.info(`AP4-variant blocked: ${C.function.name} failed ${O}x with different args`)}let P={role:"user",content:"Tool calls were blocked because the tool has failed too many times with different arguments. The resource you are looking for does not exist. Stop trying variations and tell the user what happened."};j.push(P)}for(let P of Ge){let C=P.function.arguments,O=L.find(H=>H.function.name===P.function.name);if(O?.backfillObservableInput)try{let H=JSON.parse(P.function.arguments),re={...H};O.backfillObservableInput(re),Object.keys(re).some(Q=>!(Q in H))&&(C=JSON.stringify(re))}catch{}yield{type:"tool_call",turnId:s,callId:P.id,name:P.function.name,arguments:C}}let Pb=new Map(T.toolFailureCounts);try{let P=new ss({toolInvoker:t,hooks:u,sessionId:o,turnId:s,log:r,signal:p,maxConcurrentTools:n?.maxConcurrentTools});for(let C of Ge)P.addTool(C);for await(let C of P.getRemainingResults()){C.blocked&&(yield{type:"tool_blocked",turnId:s,callId:C.callId,name:C.toolName,reason:C.blockReason??"blocked"}),j.push(C.message),St.push(C.callId),I.add(C.toolName),N++;let O=C.ok&&eS(C);if(!C.ok||O){let Q=(T.toolFailureCounts.get(C.toolName)??0)+1;T.toolFailureCounts.set(C.toolName,Q)}if(C.ok&&C.toolName==="read"){let we=Ge.find(Q=>Q.id===C.callId);if(we)try{let Q=JSON.parse(we.function.arguments),he=Q.file_path??Q.path??Q.filePath??"";if(he){let ot=T.fileReadCounts.get(he)??0;T.fileReadCounts.set(he,ot+1)}}catch{}}let H=typeof C.message?.content=="string"?C.message.content:"",re=C.ok&&H?H.slice(0,2e3):void 0;if(yield{type:"tool_result",turnId:s,callId:C.callId,name:C.toolName,ok:C.ok,error:C.error,outputPreview:re},C.ok){let we=pe.find(Q=>Q.id===C.callId);if(we){if(C.toolName==="plan_mode")try{let Q=JSON.parse(we.function.arguments);Q.action==="exit"&&typeof Q.plan=="string"&&Q.plan.length>0&&(yield{type:"plan_update",turnId:s,slug:"approved-plan",content:Q.plan})}catch{}if(Xk.has(C.toolName))try{let Q=JSON.parse(we.function.arguments),he=typeof Q.file_path=="string"?Q.file_path:typeof Q.filePath=="string"?Q.filePath:typeof Q.path=="string"?Q.path:void 0;he&&(yield{type:"artifact",turnId:s,artifactId:`artifact-${C.callId}`,artifactType:Yk(he),title:he.split(/[\\/]/).pop()||he,filePath:he,language:Jk(he)})}catch{}}}}}catch(P){let C=P instanceof Error?P.message:String(P);yield{type:"error",turnId:s,error:C,code:"TOOL_EXECUTION_ERROR",usage:T.totalUsage};return}for(let[P,C]of T.toolFailureCounts)C>=zr&&(Pb.get(P)??0)<zr&&j.push({role:"user",content:`Tool "${P}" has now failed/returned empty results ${C} times with different arguments. The target clearly does not exist. Do NOT call "${P}" again. Report the result to the user immediately.`});if(U=Zr(U,{replayMessages:j,completedToolCallIds:[...U.completedToolCallIds,...St],lastStopReason:"tool_calls"}),n.generateToolUseSummary&&pe.length>0){let P=pe.map(C=>({name:C.function.name,arguments:C.function.arguments}));F=n.generateToolUseSummary(P).catch(()=>null)}let Ib=pe.length>0&&pe.every(P=>{let C=j.find(H=>H?.role==="tool"&&H?.tool_call_id===P.id);if(!C)return!0;let O=C.content;return typeof O=="string"&&O.startsWith("Error: ")}),Kn=T.consecutiveFailedRounds;if(Ib){if(Kn+=1,Kn>=Ko){let P=T.finalText||sr(j,r);r.info(`early exit: ${Kn} consecutive failed rounds, returning ${T.finalText?"partial":"fallback"} response`),yield{type:"end",turnId:s,content:P,usage:T.totalUsage,model:T.currentModel};return}}else Kn=0;let _b=3,wl=[...T.fileReadCounts.entries()].filter(([,P])=>P>=_b);if(wl.length>0){let P=wl.map(([O])=>O).join(", ");r.info(`AP5: file read cycle detected on ${P}, injecting nudge`);let C={role:"user",content:`You are reading the same files repeatedly (${P}). This indicates a circular dependency or cycle. Stop reading files, summarize your findings so far, and explain the circular structure to the user.`};j.push(C),T.fileReadCounts.clear()}let Eo=te+1;if(h>0&&Eo>h){if(r.info(`max turns reached (${h}), completing`),u){let C=await u.invoke("stop",{sessionId:o,reason:"max_turns"});if(C.action==="abort"){let O=C.reason??"Stop hook requested continuation after max_turns",H={role:"assistant",content:T.finalText,...Z.length>0&&{thinkingBlocks:[...Z]}};T={...T,messages:[...j,H,{role:"user",content:O}],stopHookActive:!0,transition:{reason:"stop_hook_blocking"}};continue}}let P=T.finalText||sr(j,r);yield{type:"end",turnId:s,content:P,usage:T.totalUsage,model:T.currentModel};return}if(Eo>A){if(r.info(`tool loop budget exhausted (${A} rounds), returning`),N>0){let C={ok:!0,toolCallCount:N,distinctToolCount:I.size,multiStep:N>=2,hasSubAgent:!1,feedback:null,existingSkillName:null},O=Qr(C,{tools:[...I],projectRoot:n.projectRoot});O&&(yield{type:"skill_instruction",turnId:s,instruction:O})}let P=T.finalText||sr(j,r);yield{type:"end",turnId:s,content:P,usage:T.totalUsage,model:T.currentModel};return}T={messages:j,maxOutputTokensRecoveryCount:0,hasAttemptedReactiveCompact:!1,maxOutputTokensOverride:void 0,turnCount:Eo,transition:{reason:"next_turn"},guardState:J,reactiveCompactState:R,toolLoopState:U,consecutiveFailedRounds:Kn,finalText:T.finalText,totalUsage:T.totalUsage,collapseStore:B,currentModel:T.currentModel,consecutive529Errors:0,consecutiveApiRetries:0,stopHookActive:T.stopHookActive,lastResponseId:T.lastResponseId,snipRemovedIds:T.snipRemovedIds,contentReplacementState:T.contentReplacementState,budgetContinuationCount:0,lastBudgetDeltaTokens:0,lastBudgetGlobalTokens:0,identicalCallCounts:Ce,toolFailureCounts:T.toolFailureCounts,fileReadCounts:T.fileReadCounts}}}function sr(n,e){let t=[];for(let r=n.length-1;r>=0;r--){let s=n[r];if(s.role==="tool"&&typeof s.content=="string")t.unshift(s.content.slice(0,500));else if(s.role==="assistant"){if(typeof s.content=="string"&&s.content.trim())return e.info("synthesizeFallbackContent: found assistant text, using it"),s.content;break}else break}return t.length>0?(e.info(`synthesizeFallbackContent: synthesized from ${t.length} tool result(s)`),t.join(`
|
|
28
28
|
|
|
29
|
-
`)):""}async function*iS(n,e,t,r,s,o,i,a){let c=[],l;a.debug(`single LLM round, messages: ${t.length}`);for await(let d of i.stream({model:e,messages:t,temperature:s},r,o))switch(d.type){case"delta":c.push(d.text),yield{type:"delta",turnId:n,text:d.text};break;case"usage":l={inputTokens:d.promptTokens,outputTokens:d.completionTokens,reasoningTokens:d.reasoningTokens,cacheRead:d.cacheReadTokens,cacheWrite:d.cacheCreationTokens};break;case"done":break}yield{type:"end",turnId:n,content:c.join(""),usage:l??{inputTokens:0,outputTokens:0},model:e}}var Xk,Qk,Zk,
|
|
30
|
-
`)}function uS(n){let e=n.filter(s=>s.source==="l1-project-md").flatMap(s=>
|
|
31
|
-
${I}`})}}this.hooks.invoke("memory.after_recall",{sessionId:e.sessionId,turnId:r,blockCount:y?.context?.recalledMemories?.length??0}).catch(()=>{})}catch{}}let u=a?.model??"",p=Math.min(a?.maxRounds??this.maxRounds,100);try{let m=async y=>{let b=Y().resolveModelForPurpose("smallModel");if(!b)return null;try{let k=y.map(I=>`${I.name}(${I.arguments.slice(0,200)})`).join(", "),A=this.transport.stream({model:b,messages:[{role:"system",content:"Summarize the tool usage in ~30 chars, git-commit-subject style. Reply with ONLY the summary, nothing else."},{role:"user",content:k}],tools:[],maxTokens:60},a?.apiKey??this.apiKey),_="";for await(let I of A)I.type==="delta"&&(_+=I.text);return _.trim()||null}catch{return null}},h={turnId:r,sessionId:e.sessionId,messages:d,tools:o,model:u,apiKey:a?.apiKey??this.apiKey,temperature:a?.temperature,maxRounds:p,contextWindowTokens:a?.contextWindowTokens,maxOutputTokens:a?.maxOutputTokens,modelMaxOutputTokens:a?.modelMaxOutputTokens,toolChoice:a?.toolChoice,parentDepth:a?.parentDepth,hooks:this.hooks,fallbackModel:a?.fallbackModel,maxTurns:a?.maxTurns,tokenBudget:a?.tokenBudget,maxConcurrentTools:a?.maxConcurrentTools,streamRequired:a?.streamRequired,reasoning:a?.reasoning,promptCacheKey:a?.promptCacheKey,promptCacheRetention:a?.promptCacheRetention,serviceTier:a?.serviceTier,openaiBuiltinTools:a?.openaiBuiltinTools,maxToolCalls:a?.maxToolCalls,parallelToolCalls:a?.parallelToolCalls,textVerbosity:a?.textVerbosity,projectRoot:this.projectRoot,generateToolUseSummary:m,signal:t},f;for await(let y of
|
|
29
|
+
`)):""}async function*iS(n,e,t,r,s,o,i,a){let c=[],l;a.debug(`single LLM round, messages: ${t.length}`);for await(let d of i.stream({model:e,messages:t,temperature:s},r,o))switch(d.type){case"delta":c.push(d.text),yield{type:"delta",turnId:n,text:d.text};break;case"usage":l={inputTokens:d.promptTokens,outputTokens:d.completionTokens,reasoningTokens:d.reasoningTokens,cacheRead:d.cacheReadTokens,cacheWrite:d.cacheCreationTokens};break;case"done":break}yield{type:"end",turnId:n,content:c.join(""),usage:l??{inputTokens:0,outputTokens:0},model:e}}var Xk,Qk,Zk,Kd=X(()=>{"use strict";er();bd();ra();Ud();Ji();je();Xk=new Set(["write","edit","patch","apply_patch"]);Qk=/^no (matches|files|results) found\.?$|^file not found|^not found|^0 results|^\(exit code \d+, no output\)$/i,Zk=new Set(["search","grep","glob","find","list","read","exec"])});function Vd(n){if(!n||n.length<5)return{scenario:"general",preferred:[],deprioritized:[],confidence:0};let e=[];for(let[s,o]of Object.entries(aS)){if(s==="general")continue;let i=o.filter(a=>a.test(n)).length;if(i>0){let a=Math.min(1,i/2);e.push({scenario:s,score:a})}}if(e.length===0)return{scenario:"general",preferred:[],deprioritized:[],confidence:0};e.sort((s,o)=>o.score-s.score);let t=e[0];if(t.score<.5)return{scenario:"general",preferred:[],deprioritized:[],confidence:t.score};let r=cS[t.scenario];return{scenario:t.scenario,preferred:r.preferred,deprioritized:r.deprioritized,confidence:t.score}}function sa(n,e,t){return!e||t.scenario==="general"?n:t.preferred.includes(e)?Math.min(1,n*1.2):t.deprioritized.includes(e)?n*.7:n}function zd(n){let e=n.replace(/\.md$/,"").toLowerCase();for(let[t,r]of Object.entries(lS))if(e.startsWith(t+"-")||e.startsWith(t+"_")||e===t)return r;return null}var aS,cS,lS,oa=X(()=>{"use strict";aS={coding:[/(?:bug|error|fix|debug|报错|修复|编译|compile|build|lint)/i,/(?:implement|refactor|重构|实现|代码|code|function|method|class)/i,/(?:test|测试|vitest|jest|断言|assert)/i,/(?:type(?:script)?|接口|interface|generic|泛型)/i,/(?:import|export|module|依赖|package|npm|pnpm)/i,/(?:git|commit|branch|merge|rebase|PR|MR)/i],config:[/(?:deploy|部署|运维|docker|container|kubernetes|k8s)/i,/(?:port|端口|config|配置|env|环境变量|.env)/i,/(?:server|service|daemon|进程|systemd|nginx|redis)/i,/(?:版本|version|upgrade|migrate|迁移)/i,/(?:domain|域名|ssl|cert|证书|DNS)/i],conversation:[/(?:你好|hi|hello|hey|请问|问一下)/i,/(?:我(?:喜欢|偏好|习惯|想)|prefer|I (?:like|want|need))/i,/(?:帮我|help me|能不能|可以吗|would you)/i,/(?:style|风格|format|格式|命名|naming)/i],learning:[/(?:best practice|最佳实践|pattern|模式|惯例|convention)/i,/(?:怎么做|how to|how do|what's the|推荐|recommend)/i,/(?:为什么|why|原因|reason|explain|解释)/i,/(?:lesson|经验|教训|gotcha|pitfall|坑)/i],decision:[/(?:should|应该|选择|choose|decision|决定|trade-?off|权衡)/i,/(?:vs|versus|对比|compare|区别|difference)/i,/(?:architecture|架构|方案|approach|strategy)/i,/(?:pros|cons|优缺点|利弊|好处|坏处)/i],general:[]},cS={coding:{preferred:["lesson","pattern","fact"],deprioritized:["preference"]},config:{preferred:["fact","decision","lesson"],deprioritized:["preference","skill-learning"]},conversation:{preferred:["preference","fact"],deprioritized:["pattern","skill-learning"]},learning:{preferred:["lesson","pattern","skill-learning"],deprioritized:["preference"]},decision:{preferred:["decision","fact","lesson"],deprioritized:["skill-learning","preference"]},general:{preferred:[],deprioritized:[]}};lS={lesson:"lesson",debug:"lesson",gotcha:"lesson",fix:"lesson",preference:"preference",style:"preference",pattern:"pattern",convention:"pattern",practice:"pattern",fact:"fact",config:"fact",architecture:"fact",env:"fact",deploy:"fact",decision:"decision",choice:"decision",skill:"skill-learning",workflow:"skill-learning"}});function Jd(n){let e=uS(n),t=["[Recalled memories]","- L1 project MD is project-scoped working memory.","- L2 long-term memory is cross-project canonical memory.","- If L1 and L2 conflict on the same entity/fact, do not silently merge or choose. Surface the conflict and ask the user to confirm. For current-project operational tasks, use L1 only as a project-scoped clue until confirmed into L2."];if(e.length>0){t.push("[Memory conflict detected]");for(let r of e)t.push(`- entity: ${r.entity}; fact: ${r.predicate}; L1 project MD says: ${Yd(r.l1Amount)}; L2 long-term says: ${Yd(r.l2Amount)}; action: ask the user which value is current before using it.`)}for(let r of n){let s=gS(r);t.push(`- [${s}] ${r.text}`)}return t.join(`
|
|
30
|
+
`)}function uS(n){let e=n.filter(s=>s.source==="l1-project-md").flatMap(s=>Xd(s.text)),t=n.filter(s=>s.source==="l2-long-term").flatMap(s=>Xd(s.text)),r=[];for(let s of e)for(let o of t)s.entity===o.entity&&s.predicate===o.predicate&&s.amount!==o.amount&&r.push({entity:s.entity,predicate:s.predicate,l1Amount:s.amount,l2Amount:o.amount,l1Text:s.text,l2Text:o.text});return fS(r)}function Xd(n){let e=[];for(let t of n.split(/\r?\n/)){let r=t.trim();if(r)for(let s of dS){if(s==="\u91D1\u989D"&&/(接单金额|合同金额)/u.test(r))continue;let o=new RegExp(`${hS(s)}[^0-9.\u4E07kK,]{0,12}([0-9][0-9.,]*\\s*(?:\u4E07|k|K)?)`,"gi");for(let i of r.matchAll(o)){let a=mS(i[1]);a!==null&&e.push({entity:pS(r,s),predicate:s,amount:a,text:r})}}}return e}function pS(n,e){if(/Galaxy\s+Tech/i.test(n))return"Galaxy Tech";if(n.includes("\u7528\u6237"))return"\u7528\u6237";let t=n.toLowerCase().indexOf(e.toLowerCase()),s=(t>=0?n.slice(0,t):"").replace(/[#*`:\-,。;;,.]/g," ").trim().split(/\s+/).filter(Boolean);return s[s.length-1]??"unknown"}function mS(n){let e=n.replace(/,/g,"").replace(/\s+/g,"").trim(),t=e.endsWith("\u4E07")?1e4:/k$/i.test(e)?1e3:1,r=Number(e.replace(/[万kK]$/u,""));return Number.isFinite(r)?r*t:null}function gS(n){if(n.label)return n.label;switch(n.source){case"l1-project-md":return"L1 project MD";case"l2-long-term":return"L2 long-term";case"skill":return"Skill";case"system":return"System";default:return"Memory"}}function Yd(n){return Number.isInteger(n)?String(n):String(Number(n.toFixed(4)))}function fS(n){let e=new Set;return n.filter(t=>{let r=`${t.entity}\0${t.predicate}\0${t.l1Amount}\0${t.l2Amount}`;return e.has(r)?!1:(e.add(r),!0)})}function hS(n){return n.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}var dS,Qd=X(()=>{"use strict";dS=["\u63A5\u5355\u91D1\u989D","\u5408\u540C\u91D1\u989D","\u62A5\u4EF7","\u9884\u7B97","\u91D1\u989D","price","amount","contract amount"]});var eu={};en(eu,{Agent:()=>or});var or,ia=X(()=>{"use strict";er();Kd();je();oa();dt();Qd();or=class{transport;apiKey;toolInvoker;log;hooks;maxRounds;projectRoot;constructor(e){this.transport=e.llmTransport,this.apiKey=e.apiKey,this.toolInvoker=e.toolInvoker,this.log=e.log,this.hooks=e.hooks,this.projectRoot=e.projectRoot,this.maxRounds=Math.min(e.maxRounds??25,100)}async*run(e,t){let{turnId:r,messages:s,tools:o,systemPrompt:i,config:a}=e,c={sessionId:e.sessionId,turnId:r};yield{type:"start",turnId:r},this.hooks?.invoke("turn.submitted",{...c,prompt:s[s.length-1]?.content??void 0}).catch(()=>{});let l=Li(s),d=[];if(i&&d.push({role:"system",content:i}),d.push(...l),this.hooks){let m=l.filter(f=>f.role==="user").pop(),h=typeof m?.content=="string"?m.content.slice(0,500):void 0;if(h)try{let f=Vd(h),y=await this.hooks.invoke("memory.before_recall",{sessionId:e.sessionId,turnId:r,query:h,preferredCategories:f.preferred.length>0?f.preferred:void 0,deprioritizedCategories:f.deprioritized.length>0?f.deprioritized:void 0}),b=y?.context?.recalledMemories;if(b&&b.length>0){let A=0,_=[];for(let I of b){let N=(I.text?.length??0)*2;if(A+N>8192)break;_.push(I),A+=N}if(_.length>0){let I=Jd(_);d.splice(i?1:0,0,{role:"system",content:`[Recalled memories \u2014 context priority: project-specific facts override general user preferences when they conflict]
|
|
31
|
+
${I}`})}}this.hooks.invoke("memory.after_recall",{sessionId:e.sessionId,turnId:r,blockCount:y?.context?.recalledMemories?.length??0}).catch(()=>{})}catch{}}let u=a?.model??"",p=Math.min(a?.maxRounds??this.maxRounds,100);try{let m=async y=>{let b=Y().resolveModelForPurpose("smallModel");if(!b)return null;try{let k=y.map(I=>`${I.name}(${I.arguments.slice(0,200)})`).join(", "),A=this.transport.stream({model:b,messages:[{role:"system",content:"Summarize the tool usage in ~30 chars, git-commit-subject style. Reply with ONLY the summary, nothing else."},{role:"user",content:k}],tools:[],maxTokens:60},a?.apiKey??this.apiKey),_="";for await(let I of A)I.type==="delta"&&(_+=I.text);return _.trim()||null}catch{return null}},h={turnId:r,sessionId:e.sessionId,messages:d,tools:o,model:u,apiKey:a?.apiKey??this.apiKey,temperature:a?.temperature,maxRounds:p,contextWindowTokens:a?.contextWindowTokens,maxOutputTokens:a?.maxOutputTokens,modelMaxOutputTokens:a?.modelMaxOutputTokens,toolChoice:a?.toolChoice,parentDepth:a?.parentDepth,hooks:this.hooks,fallbackModel:a?.fallbackModel,maxTurns:a?.maxTurns,tokenBudget:a?.tokenBudget,maxConcurrentTools:a?.maxConcurrentTools,streamRequired:a?.streamRequired,reasoning:a?.reasoning,promptCacheKey:a?.promptCacheKey,promptCacheRetention:a?.promptCacheRetention,serviceTier:a?.serviceTier,openaiBuiltinTools:a?.openaiBuiltinTools,maxToolCalls:a?.maxToolCalls,parallelToolCalls:a?.parallelToolCalls,textVerbosity:a?.textVerbosity,projectRoot:this.projectRoot,generateToolUseSummary:m,signal:t},f;for await(let y of Gd(h,this.transport,this.toolInvoker,this.log))f=y,yield y;f?.type==="end"?this.hooks?.invoke("turn.completed",{...c}).catch(()=>{}):f?.type==="error"&&this.hooks?.invoke("turn.failed",{...c,code:f.code,error:f.error}).catch(()=>{})}catch(m){if(t?.aborted)this.hooks?.invoke("turn.failed",{...c,code:"ABORTED",error:"Turn aborted"}).catch(()=>{}),yield{type:"error",turnId:r,error:"Turn aborted",code:"ABORTED"};else{let h=m instanceof Error?m.message:String(m),f=typeof m?.status=="number"?m.status:void 0,y=Sn(f,h);this.log.error(`turn ${r} error [${y}, retryable=${Oo(y)}]: ${h}`),this.hooks?.invoke("turn.failed",{...c,code:y,error:h}).catch(()=>{}),yield{type:"error",turnId:r,error:h,code:y}}}}}});import{createHash as ml}from"node:crypto";import Ur from"node:fs";import rb from"node:path";function C_(n){return pl.find(e=>e.id===n)}function M_(n,e,t){let r=C_(t);if(r)return r;let s=pl.filter(a=>a.rarity===e);if(s.length===0)return pl[0];let i=ml("sha256").update(`breed-${n}`).digest()[0]%s.length;return s[i]}function N_(n){let t=ml("sha256").update(n).digest()[0]%100,r=0;for(let s=0;s<sb.length;s++)if(r+=sb[s],t<r)return E_[s];return"common"}function D_(n){let e=ml("sha256").update(`stats-${n}`).digest();return{grip:e[0]%10+1,patience:e[1]%10+1,curiosity:e[2]%10+1,appetite:e[3]%10+1,humor:e[4]%10+1}}var E_,sb,pl,Zt,ob=X(()=>{"use strict";E_=["common","uncommon","rare","epic","legendary"],sb=[50,25,15,8,2],pl=[{id:"default",name:"\u84DD\u8272\u4F19\u4F34",colors:{primary:"#5A7EFF",secondary:"#1E3A8A"},rarity:"default"},{id:"golden",name:"\u9EC4\u91D1\u4F19\u4F34",colors:{primary:"#F59E0B",secondary:"#92400E"},rarity:"legendary"},{id:"crystal",name:"\u6C34\u6676\u4F19\u4F34",colors:{primary:"#7DD3FC",secondary:"#0C4A6E"},rarity:"rare"},{id:"obsidian",name:"\u9ED1\u66DC\u4F19\u4F34",colors:{primary:"#7C3AED",secondary:"#1E1B4B"},rarity:"epic"},{id:"ghost",name:"\u96FE\u5F71\u4F19\u4F34",colors:{primary:"#94A3B8",secondary:"#475569"},rarity:"uncommon"},{id:"rainbow",name:"\u5F69\u8679\u4F19\u4F34",colors:{primary:"#EC4899",secondary:"#7C3AED"},rarity:"rare"}];Zt=class{constructor(e){this.workspaceDir=e;this.storagePath=rb.join(e,".qlogicagent","pet","soul.json")}workspaceDir;soul=null;storagePath;load(){if(this.soul)return this.soul;if(!Ur.existsSync(this.storagePath))return null;try{let e=JSON.parse(Ur.readFileSync(this.storagePath,"utf-8"));return this.soul=e,this.soul}catch{return null}}async hatch(e,t,r){let s=`${e}-xiaozhi-claw`,o=N_(s),i=D_(s),a=M_(s,o,r),c="\u963F\u84DD",l="\u5B89\u9759\u3001\u597D\u5947\uFF0C\u4F1A\u5728\u4F60\u4E13\u6CE8\u65F6\u966A\u5728\u65C1\u8FB9\u3002",d="\u6211\u5728\u8FD9\u91CC\u3002";if(t){let u=await t(o,i);c=u.name,l=u.personality,d=u.catchphrase}return this.soul={name:c,species:a.name,personality:l,catchphrase:d,stats:i,rarity:o,breed:a.id,breedColors:a.colors,level:1,experience:0,hatchedAt:new Date().toISOString()},this.persist(),this.soul}addExperience(e){if(!this.soul)return{leveledUp:!1,level:0,experience:0};this.soul.experience+=e;let t=this.soul.level*100,r=!1;for(;this.soul.experience>=t;)this.soul.experience-=t,this.soul.level+=1,r=!0;return this.persist(),{leveledUp:r,level:this.soul.level,experience:this.soul.experience}}getSoul(){return this.soul}updateSoul(e){this.soul=e,this.persist()}persist(){let e=rb.dirname(this.storagePath);Ur.existsSync(e)||Ur.mkdirSync(e,{recursive:!0}),Ur.writeFileSync(this.storagePath,JSON.stringify(this.soul,null,2),"utf-8")}}});function ko(n){let e=L_[n];if(!e||Math.random()>e.probability)return null;let t=O_[e.pool];return{text:t[Math.floor(Math.random()*t.length)],style:e.style}}async function So(n,e){let t=Fr.length>0?`
|
|
32
32
|
\u907F\u514D\u548C\u8FD9\u4E9B\u7C7B\u4F3C: ${Fr.join("\u3001")}`:"",r=`\u4F60\u662F\u4E00\u53EA\u53EB\u300C${n.soul.name}\u300D\u7684${n.soul.species}\u684C\u9762\u5BA0\u7269\u3002
|
|
33
33
|
\u6027\u683C: ${n.soul.personality}
|
|
34
34
|
\u53E3\u5934\u7985\u98CE\u683C: "${n.soul.catchphrase}"
|
|
35
35
|
|
|
36
36
|
\u521A\u624D\u53D1\u751F\u4E86: ${n.turnSummary}
|
|
37
37
|
|
|
38
|
-
\u7528\u4E00\u53E5\u8BDD(\u226420\u5B57)\u4EE5\u4F60\u7684\u6027\u683C\u505A\u51FA\u7B80\u77ED\u53CD\u5E94\u3002\u53EA\u8F93\u51FA\u53CD\u5E94\u6587\u672C\uFF0C\u4E0D\u8981\u5176\u4ED6\u5185\u5BB9\u3002${t}`;try{let s=await e(r,50);if(!s||s.length>50)return null;Fr.push(s),Fr.length>$_&&Fr.shift();let o=/[!!✨🎉]|搞定|完美|太棒/.test(s)?"excited":/[.。…]|嗯|想|看看/.test(s)?"thinking":/[zZ]|困|睡|累/.test(s)?"sleepy":"normal";return{text:s,style:o}}catch{return null}}var O_,L_,Fr,$_,
|
|
38
|
+
\u7528\u4E00\u53E5\u8BDD(\u226420\u5B57)\u4EE5\u4F60\u7684\u6027\u683C\u505A\u51FA\u7B80\u77ED\u53CD\u5E94\u3002\u53EA\u8F93\u51FA\u53CD\u5E94\u6587\u672C\uFF0C\u4E0D\u8981\u5176\u4ED6\u5185\u5BB9\u3002${t}`;try{let s=await e(r,50);if(!s||s.length>50)return null;Fr.push(s),Fr.length>$_&&Fr.shift();let o=/[!!✨🎉]|搞定|完美|太棒/.test(s)?"excited":/[.。…]|嗯|想|看看/.test(s)?"thinking":/[zZ]|困|睡|累/.test(s)?"sleepy":"normal";return{text:s,style:o}}catch{return null}}var O_,L_,Fr,$_,ib=X(()=>{"use strict";O_={greeting:["\u65B0\u7684\u4E00\u5929\uFF0C\u65B0\u7684\u5192\u9669\uFF01","\u563F\u563F~\u53C8\u89C1\u9762\u4E86","\u51C6\u5907\u597D\u4E86\u5417\uFF1F","\u65B0\u5192\u9669\u5F00\u59CB\u5566\uFF01"],completion:["\u641E\u5B9A\uFF01","\u8FD8\u633A\u987A\u5229\u7684\u561B~","\u4E0B\u4E00\u4E2A\uFF01","\u8FD9\u6CE2\u64CD\u4F5C\u4E0D\u9519","\u5B8C\u7F8E~"],error:["\u5443...\u51FA\u4E86\u70B9\u95EE\u9898","\u522B\u614C\u522B\u614C","\u8BA9\u6211\u770B\u770B\u600E\u4E48\u56DE\u4E8B","\u7CDF\u7CD5...\u518D\u8BD5\u8BD5\uFF1F"],curiosity:["\u8FD9\u4E2A\u5DE5\u5177\u6709\u610F\u601D","\u55EF\u55EF\uFF0C\u5728\u5E72\u6D3B\u4E86","\u597D\u591A\u4E8B\u60C5\u8981\u505A\u5440"],bored:["...","\u6709\u4EBA\u5417\uFF1F","\u8981\u4E0D\u8981\u804A\u804A\uFF1F","*\u5410\u6CE1\u6CE1*"],memory:["\u8BA9\u6211\u6574\u7406\u4E0B\u8BB0\u5FC6...","\u55EF\u55EF\uFF0C\u8FD9\u4E9B\u503C\u5F97\u8BB0\u4F4F","\u8BB0\u4F4F\u4E86~"],tool_success:["\u4E0D\u9519\u4E0D\u9519~","\u53C8\u641E\u5B9A\u4E00\u4E2A","\u987A\u5229\uFF01"]},L_={"turn.error":{probability:1,pool:"error",style:"normal"},"session.created":{probability:1,pool:"greeting",style:"excited"},"turn.end":{probability:.3,pool:"completion",style:"excited"},"turn.tool_call":{probability:.1,pool:"curiosity",style:"thinking"},"turn.tool_result.success":{probability:.15,pool:"tool_success",style:"excited"},"memory.updated":{probability:.5,pool:"memory",style:"thinking"},"idle.long":{probability:.05,pool:"bored",style:"sleepy"}};Fr=[],$_=5});var cb={};en(cb,{PetGrowthEngine:()=>Ee});var gl,ab,Ee,To=X(()=>{"use strict";gl=[{id:"bubble_speak",name:"\u6CE1\u6CE1\u8BED",description:"\u6CE1\u6CE1\u53EF\u4EE5\u663E\u793A\u66F4\u591A\u5B57\u6570",unlockedAtLevel:2},{id:"eye_tracking",name:"\u7075\u52A8\u89C6\u7EBF",description:"\u773C\u7403\u8FFD\u8E2A\u66F4\u7075\u654F",unlockedAtLevel:3},{id:"micro_reaction",name:"\u5FAE\u8868\u60C5",description:"\u89E3\u9501 antenna-twitch \u548C eye-sparkle",unlockedAtLevel:5},{id:"memory_sense",name:"\u8BB0\u5FC6\u611F\u77E5",description:"\u8BB0\u5FC6\u4FDD\u5B58\u65F6\u81EA\u52A8\u5207\u6362 sweeping \u72B6\u6001",unlockedAtLevel:7},{id:"mood_forecast",name:"\u5FC3\u60C5\u9884\u62A5",description:"\u6CE1\u6CE1\u4E2D\u5076\u5C14\u51FA\u73B0\u5929\u6C14\u98CE\u683C\u7684\u5FC3\u60C5\u8BED",unlockedAtLevel:10},{id:"deep_sleep",name:"\u6DF1\u5EA6\u7761\u7720",description:"\u7761\u7720\u65F6\u5192\u51FA zzZ \u6CE1\u6CE1",unlockedAtLevel:12},{id:"tool_intuition",name:"\u5DE5\u5177\u76F4\u89C9",description:"\u5DE5\u5177\u8C03\u7528\u65F6\u5076\u5C14\u9884\u6D4B\u7ED3\u679C",unlockedAtLevel:15},{id:"personality_evolve",name:"\u6027\u683C\u8FDB\u5316",description:"\u53E3\u5934\u7985\u968F\u4F7F\u7528\u98CE\u683C\u5FAE\u53D8",unlockedAtLevel:20}],ab=["\u7B2C\u4E00\u6B21\u8131\u58F3\uFF01\u5C0F\u867E\u58F3\u53D8\u5F97\u66F4\u6709\u5149\u6CFD\u4E86","\u58F3\u9762\u5F00\u59CB\u51FA\u73B0\u7EC6\u5FAE\u7684\u5F69\u8679\u7EB9\u7406","\u94B3\u5B50\u53D8\u5F97\u66F4\u52A0\u6709\u529B\uFF0C\u80FD\u5939\u8D77\u66F4\u591A\u4E1C\u897F\u4E86","\u89E6\u89D2\u7075\u654F\u5EA6\u63D0\u5347\uFF0C\u611F\u77E5\u8303\u56F4\u6269\u5927","\u5168\u8EAB\u6563\u53D1\u5FAE\u5149\uFF0C\u50CF\u662F\u5185\u5728\u529B\u91CF\u5728\u89C9\u9192","\u8FDB\u5165\u7A00\u6709\u4F53\u8272\u53D8\u5F02\u9636\u6BB5..."],Ee=class n{static xpForLevel(e){return e*100}static processXpGain(e,t){let r=[],s={},o=e.level,i=e.experience+t;for(;i>=n.xpForLevel(o);){if(i-=n.xpForLevel(o),o++,r.push({type:"level_up",level:o}),o%5===0){let c=Math.floor(o/5),l=n.getMoltResult(c,e.stats);r.push({type:"molt",level:o,moltStage:c});for(let[d,u]of Object.entries(l.statBoost)){let p=d;s[p]=(s[p]??0)+(u??0)}}let a=gl.find(c=>c.unlockedAtLevel===o);a&&r.push({type:"ability_unlock",level:o,ability:a})}return{newLevel:o,newXp:i,events:r,statBoosts:s}}static getMoltResult(e,t){let r=ab[Math.min(e-1,ab.length-1)]??"\u7EE7\u7EED\u6210\u957F\u4E2D...",s=["grip","patience","curiosity","appetite","humor"],i={[s[(e-1)%s.length]]:1};return{stage:e,description:r,statBoost:i}}static getUnlockedAbilities(e){return gl.filter(t=>t.unlockedAtLevel<=e)}static getNextAbility(e){return gl.find(t=>t.unlockedAtLevel>e)??null}static xpForEvent(e){switch(e){case"turn.end":return 10;case"turn.error":return 2;case"session.created":return 5;case"interact.pat":return 3;case"interact.feed":return 5;case"interact.poke":return 1;case"tool.success":return 2;default:return 1}}}});import{createHash as j_}from"node:crypto";import lb from"node:fs";async function pb(n){let e=lb.statSync(n);if(e.size>db)throw new Error(`Pet file exceeds ${db/1024}KB limit (got ${Math.round(e.size/1024)}KB)`);let t=lb.readFileSync(n),r=j_("sha256").update(t).digest("hex"),s=await F_(t),o=s.get("manifest.json");if(!o)throw new Error("Pet file missing manifest.json");let i;try{i=JSON.parse(o.toString("utf-8"))}catch{throw new Error("Pet file manifest.json is not valid JSON")}Br(i);let a={};for(let[d,u]of Object.entries(i.states)){let p=s.get(u.file);if(!p)throw new Error(`Missing SVG file for state "${d}": ${u.file}`);if(p.length>ub)throw new Error(`SVG for state "${d}" exceeds ${ub/1024}KB limit`);a[d]=Wt(p.toString("utf-8"))}let c,l=s.get("thumbnail.png");return l&&(c=`data:image/png;base64,${l.toString("base64")}`),{manifest:i,svgs:a,thumbnail:c,hash:r}}function Br(n){if(!n||typeof n!="object")throw new Error("Manifest must be an object");let e=n;if(e.version!==1)throw new Error(`Unsupported manifest version: ${e.version}`);for(let s of["name","author","created"])if(typeof e[s]!="string"||e[s].length===0)throw new Error(`Manifest missing or invalid field: ${s}`);if(e.name.length>30)throw new Error("Manifest name exceeds 30 characters");if(!e.dimensions||typeof e.dimensions!="object")throw new Error("Manifest missing dimensions");let t=e.dimensions;if(typeof t.width!="number"||typeof t.height!="number")throw new Error("Manifest dimensions must be numbers");if(t.width>400||t.height>400||t.width<50||t.height<50)throw new Error("Manifest dimensions must be 50-400px");if(!e.states||typeof e.states!="object")throw new Error("Manifest missing states");let r=e.states;for(let s of U_)if(!(s in r))throw new Error(`Manifest missing required state: ${s}`);for(let[s,o]of Object.entries(r)){if(!o||typeof o!="object")throw new Error(`Invalid state config for "${s}"`);let i=o;if(typeof i.file!="string")throw new Error(`State "${s}" missing file path`);if(typeof i.loop!="boolean")throw new Error(`State "${s}" missing loop flag`);if(i.file.includes("..")||i.file.startsWith("/"))throw new Error(`State "${s}" file path contains path traversal`)}}function Wt(n){let e=n.replace(/<\?xml[^?]*\?>/gi,"").replace(/<!DOCTYPE[^>]*>/gi,"");return e=e.replace(/<script[\s\S]*?<\/script>/gi,""),e=e.replace(/<script[^>]*\/>/gi,""),e=e.replace(/<foreignObject[\s\S]*?<\/foreignObject>/gi,""),e=e.replace(/<foreignObject[^>]*\/>/gi,""),e=e.replace(/\s+on\w+\s*=\s*"[^"]*"/gi,""),e=e.replace(/\s+on\w+\s*=\s*'[^']*'/gi,""),e=e.replace(/href\s*=\s*"javascript:[^"]*"/gi,'href=""'),e=e.replace(/href\s*=\s*'javascript:[^']*'/gi,"href=''"),e=e.replace(/xlink:href\s*=\s*"javascript:[^"]*"/gi,'xlink:href=""'),e=e.replace(/(href|src)\s*=\s*"(https?:\/\/[^"]*)"/gi,'$1=""'),e=e.replace(/(href|src)\s*=\s*'(https?:\/\/[^']*)'/gi,"$1=''"),e=e.replace(/<use[^>]*href\s*=\s*"https?:\/\/[^"]*"[^>]*\/?>/gi,""),e=e.replace(/@import\s+url\([^)]*https?:\/\/[^)]*\)[^;]*;/gi,""),e=e.replace(/url\(\s*['"]?https?:\/\/[^)]*\)/gi,"url()"),e.trim()}async function F_(n){let e=new Map,t=0;for(;t<n.length-4&&n.readUInt32LE(t)===67324752;){let s=n.readUInt16LE(t+8),o=n.readUInt32LE(t+18),i=n.readUInt32LE(t+22),a=n.readUInt16LE(t+26),c=n.readUInt16LE(t+28),l=t+30,d=n.subarray(l,l+a).toString("utf-8"),u=l+a+c;if(s===0)e.set(d,n.subarray(u,u+i));else if(s===8){let{inflateRawSync:p}=await import("node:zlib");try{let m=p(n.subarray(u,u+o));e.set(d,m)}catch{}}t=u+o}return e}var db,ub,U_,fl=X(()=>{"use strict";db=500*1024,ub=20*1024,U_=["idle"]});var mb={};en(mb,{STATE_ANIMATION_MAP:()=>Hr,buildSkeletonPrompt:()=>hl,extractColors:()=>qn,parseSkeleton:()=>Bn,renderState:()=>Hn,validateSkeleton:()=>Wn});function hl(n){return`\u4F60\u662F SVG \u89D2\u8272\u8BBE\u8BA1\u5E08\u3002\u57FA\u4E8E\u4EE5\u4E0B\u89D2\u8272\u63CF\u8FF0\uFF0C\u751F\u6210\u4E00\u4E2A 200x200 \u7684 SVG **\u57FA\u7840\u9AA8\u67B6**\u3002
|
|
39
39
|
|
|
40
40
|
\u89D2\u8272\uFF1A${n}
|
|
41
41
|
|
|
@@ -79,7 +79,7 @@ ${l}`);return d&&(u=u.replace(/<\/svg>/,`${d}
|
|
|
79
79
|
@keyframes right-arm-anim { 0%,100% { transform: rotate(-20deg); } }`,covering:`@keyframes left-arm-anim { 0%,100% { transform: rotate(-40deg) translateX(5px); } }
|
|
80
80
|
@keyframes right-arm-anim { 0%,100% { transform: rotate(40deg) translateX(-5px); } }`,hold:`@keyframes left-arm-anim { 0%,100% { transform: rotate(-10deg); } 50% { transform: rotate(-15deg); } }
|
|
81
81
|
@keyframes right-arm-anim { 0%,100% { transform: rotate(10deg); } 50% { transform: rotate(15deg); } }`,eat:`@keyframes left-arm-anim { 0%,100% { transform: rotate(-30deg); } }
|
|
82
|
-
@keyframes right-arm-anim { 0%,100% { transform: rotate(30deg) translateY(-5px); } 50% { transform: rotate(25deg) translateY(0); } }`},W_={zzz:'<g class="effect-zzz" opacity="0.7"><text x="150" y="40" font-size="18" fill="#6B7280" font-family="sans-serif"><animate attributeName="opacity" values="0;1;0" dur="2s" repeatCount="indefinite"/>Z</text><text x="165" y="25" font-size="14" fill="#9CA3AF" font-family="sans-serif"><animate attributeName="opacity" values="0;1;0" dur="2.5s" repeatCount="indefinite"/>z</text><text x="175" y="15" font-size="10" fill="#D1D5DB" font-family="sans-serif"><animate attributeName="opacity" values="0;1;0" dur="3s" repeatCount="indefinite"/>z</text></g>',sparkle:'<g class="effect-sparkle"><circle cx="40" cy="30" r="2" fill="#FFD700"><animate attributeName="opacity" values="0;1;0" dur="1.5s" repeatCount="indefinite"/></circle><circle cx="160" cy="25" r="1.5" fill="#FFD700"><animate attributeName="opacity" values="0;1;0" dur="2s" begin="0.3s" repeatCount="indefinite"/></circle><circle cx="100" cy="15" r="2" fill="#FFA500"><animate attributeName="opacity" values="0;1;0" dur="1.8s" begin="0.6s" repeatCount="indefinite"/></circle></g>',sweat:'<g class="effect-sweat"><ellipse cx="155" cy="55" rx="3" ry="5" fill="#87CEEB" opacity="0.8"><animate attributeName="cy" values="55;65;55" dur="1.5s" repeatCount="indefinite"/><animate attributeName="opacity" values="0.8;0;0.8" dur="1.5s" repeatCount="indefinite"/></ellipse></g>',question:'<g class="effect-question"><text x="100" y="25" font-size="24" fill="#6B7280" text-anchor="middle" font-family="sans-serif"><animate attributeName="opacity" values="0;1;1;0" dur="3s" repeatCount="indefinite"/>?</text></g>',ellipsis:'<g class="effect-ellipsis"><circle cx="85" cy="30" r="3" fill="#6B7280"><animate attributeName="opacity" values="0;1" dur="0.8s" fill="freeze"/></circle><circle cx="100" cy="30" r="3" fill="#6B7280"><animate attributeName="opacity" values="0;1" dur="0.8s" begin="0.3s" fill="freeze"/></circle><circle cx="115" cy="30" r="3" fill="#6B7280"><animate attributeName="opacity" values="0;1" dur="0.8s" begin="0.6s" fill="freeze"/></circle></g>',heart:'<g class="effect-heart"><text x="155" y="35" font-size="16"><animate attributeName="opacity" values="0;1;0" dur="2s" repeatCount="indefinite"/>\u2665</text></g>',exclaim:'<g class="effect-exclaim"><text x="100" y="20" font-size="22" fill="#EF4444" text-anchor="middle" font-family="sans-serif"><animate attributeName="transform" type="scale" values="1;1.2;1" dur="0.5s" repeatCount="3"/>!</text></g>',music:'<g class="effect-music"><text x="45" y="35" font-size="14" fill="#8B5CF6"><animate attributeName="opacity" values="0;1;0" dur="2.5s" repeatCount="indefinite"/><animate attributeName="y" values="35;25" dur="2.5s" repeatCount="indefinite"/>\u266A</text><text x="155" y="40" font-size="12" fill="#A78BFA"><animate attributeName="opacity" values="0;1;0" dur="3s" begin="0.5s" repeatCount="indefinite"/><animate attributeName="y" values="40;28" dur="3s" begin="0.5s" repeatCount="indefinite"/>\u266B</text></g>'}});var
|
|
82
|
+
@keyframes right-arm-anim { 0%,100% { transform: rotate(30deg) translateY(-5px); } 50% { transform: rotate(25deg) translateY(0); } }`},W_={zzz:'<g class="effect-zzz" opacity="0.7"><text x="150" y="40" font-size="18" fill="#6B7280" font-family="sans-serif"><animate attributeName="opacity" values="0;1;0" dur="2s" repeatCount="indefinite"/>Z</text><text x="165" y="25" font-size="14" fill="#9CA3AF" font-family="sans-serif"><animate attributeName="opacity" values="0;1;0" dur="2.5s" repeatCount="indefinite"/>z</text><text x="175" y="15" font-size="10" fill="#D1D5DB" font-family="sans-serif"><animate attributeName="opacity" values="0;1;0" dur="3s" repeatCount="indefinite"/>z</text></g>',sparkle:'<g class="effect-sparkle"><circle cx="40" cy="30" r="2" fill="#FFD700"><animate attributeName="opacity" values="0;1;0" dur="1.5s" repeatCount="indefinite"/></circle><circle cx="160" cy="25" r="1.5" fill="#FFD700"><animate attributeName="opacity" values="0;1;0" dur="2s" begin="0.3s" repeatCount="indefinite"/></circle><circle cx="100" cy="15" r="2" fill="#FFA500"><animate attributeName="opacity" values="0;1;0" dur="1.8s" begin="0.6s" repeatCount="indefinite"/></circle></g>',sweat:'<g class="effect-sweat"><ellipse cx="155" cy="55" rx="3" ry="5" fill="#87CEEB" opacity="0.8"><animate attributeName="cy" values="55;65;55" dur="1.5s" repeatCount="indefinite"/><animate attributeName="opacity" values="0.8;0;0.8" dur="1.5s" repeatCount="indefinite"/></ellipse></g>',question:'<g class="effect-question"><text x="100" y="25" font-size="24" fill="#6B7280" text-anchor="middle" font-family="sans-serif"><animate attributeName="opacity" values="0;1;1;0" dur="3s" repeatCount="indefinite"/>?</text></g>',ellipsis:'<g class="effect-ellipsis"><circle cx="85" cy="30" r="3" fill="#6B7280"><animate attributeName="opacity" values="0;1" dur="0.8s" fill="freeze"/></circle><circle cx="100" cy="30" r="3" fill="#6B7280"><animate attributeName="opacity" values="0;1" dur="0.8s" begin="0.3s" fill="freeze"/></circle><circle cx="115" cy="30" r="3" fill="#6B7280"><animate attributeName="opacity" values="0;1" dur="0.8s" begin="0.6s" fill="freeze"/></circle></g>',heart:'<g class="effect-heart"><text x="155" y="35" font-size="16"><animate attributeName="opacity" values="0;1;0" dur="2s" repeatCount="indefinite"/>\u2665</text></g>',exclaim:'<g class="effect-exclaim"><text x="100" y="20" font-size="22" fill="#EF4444" text-anchor="middle" font-family="sans-serif"><animate attributeName="transform" type="scale" values="1;1.2;1" dur="0.5s" repeatCount="3"/>!</text></g>',music:'<g class="effect-music"><text x="45" y="35" font-size="14" fill="#8B5CF6"><animate attributeName="opacity" values="0;1;0" dur="2.5s" repeatCount="indefinite"/><animate attributeName="y" values="35;25" dur="2.5s" repeatCount="indefinite"/>\u266A</text><text x="155" y="40" font-size="12" fill="#A78BFA"><animate attributeName="opacity" values="0;1;0" dur="3s" begin="0.5s" repeatCount="indefinite"/><animate attributeName="y" values="40;28" dur="3s" begin="0.5s" repeatCount="indefinite"/>\u266B</text></g>'}});var fb={};en(fb,{DEFAULT_MAX_RETRIES:()=>Gn,DEFAULT_THRESHOLD:()=>yl,buildConsistencyPrompt:()=>bl,buildRetryPrompt:()=>Gr,evaluateConsistency:()=>Wr,evaluateConsistencyWithVision:()=>kl,parseConsistencyResponse:()=>vl,structuralConsistencyScore:()=>qr});function qr(n,e){let t=10,r=["pet-body","pet-left-eye","pet-right-eye"];for(let p of r)e.includes(`id="${p}"`)||(t-=3);e.includes('class="pupil"')||(t-=2);let s=gb(n),o=gb(e),i=G_(s,o);i<.5&&(t-=2),i<.3&&(t-=1);let a=n.match(/viewBox="([^"]+)"/),c=e.match(/viewBox="([^"]+)"/);a&&c&&a[1]!==c[1]&&(t-=1);let l=(n.match(/<[a-z]/gi)??[]).length,d=(e.match(/<[a-z]/gi)??[]).length;return Math.min(l,d)/Math.max(l,d)<.4&&(t-=2),Math.max(0,Math.min(10,t))}function bl(n,e){return`\u4F60\u662F\u4E00\u4E2A\u89D2\u8272\u4E00\u81F4\u6027\u8BC4\u4F30\u4E13\u5BB6\u3002\u6211\u7ED9\u4F60\u4E24\u5F20\u56FE\u7247\uFF1A
|
|
83
83
|
1. \u7B2C\u4E00\u5F20\u662F\u89D2\u8272\u7684**\u57FA\u7840\u53C2\u8003\u5F62\u8C61**
|
|
84
84
|
2. \u7B2C\u4E8C\u5F20\u662F\u8BE5\u89D2\u8272\u5728\u300C${e}\u300D\u72B6\u6001\u4E0B\u7684\u53D8\u4F53
|
|
85
85
|
|
|
@@ -107,16 +107,16 @@ ${l}`);return d&&(u=u.replace(/<\/svg>/,`${d}
|
|
|
107
107
|
4. \u4FDD\u7559\u6240\u6709\u5FC5\u9700\u7684 id \u548C class \u5C5E\u6027
|
|
108
108
|
|
|
109
109
|
\u89D2\u8272\uFF1A${n}
|
|
110
|
-
\u72B6\u6001\uFF1A${e}`}function
|
|
110
|
+
\u72B6\u6001\uFF1A${e}`}function gb(n){let e=new Set,t=/#[0-9a-fA-F]{6}/g,r;for(;(r=t.exec(n))!==null;)e.add(r[0].toUpperCase());return e}function G_(n,e){if(n.size===0||e.size===0)return 0;let t=0;for(let r of n)e.has(r)&&t++;return t/Math.max(n.size,e.size)}var yl,Gn,Ao=X(()=>{"use strict";yl=6,Gn=2});var Sl={};en(Sl,{DEFAULT_MAX_RETRIES:()=>Gn,DEFAULT_THRESHOLD:()=>yl,PetGrowthEngine:()=>Ee,PetSoulService:()=>Zt,STATE_ANIMATION_MAP:()=>Hr,buildConsistencyPrompt:()=>bl,buildRetryPrompt:()=>Gr,buildSkeletonPrompt:()=>hl,evaluateConsistency:()=>Wr,evaluateConsistencyWithVision:()=>kl,extractColors:()=>qn,generateLLMReaction:()=>So,loadPetFile:()=>pb,maybeGenerateReaction:()=>ko,parseConsistencyResponse:()=>vl,parseSkeleton:()=>Bn,renderState:()=>Hn,sanitizeSvg:()=>Wt,structuralConsistencyScore:()=>qr,validatePetManifest:()=>Br,validateSkeleton:()=>Wn});var wo=X(()=>{"use strict";ob();ib();To();fl();Ro();Ao()});import{randomUUID as kt}from"node:crypto";import{createRequire as K_}from"node:module";import*as Po from"node:vm";import{createInterface as Cb}from"node:readline";var kn=class{messageHandler=null;closeHandler=null;verbose;constructor(e){this.verbose=e?.verbose??!1}onMessage(e){this.messageHandler=e}onClose(e){this.closeHandler=e}send(e){process.stdout.write(`${JSON.stringify(e)}
|
|
111
111
|
`)}start(){process.stdin.on("data",t=>{process.stderr.write(`[transport] raw stdin data (${t.length} bytes): ${t.toString().slice(0,300)}
|
|
112
|
-
`)});let e=
|
|
112
|
+
`)});let e=Cb({input:process.stdin,crlfDelay:Number.POSITIVE_INFINITY});e.on("line",t=>{let r=t.trim();if(r){process.stderr.write(`[transport] line: ${r.slice(0,300)}
|
|
113
113
|
`);try{let s=JSON.parse(r);this.messageHandler?.(s)}catch{this.log(`invalid JSON on stdin: ${r.slice(0,200)}`)}}}),e.on("close",()=>{this.closeHandler?.()})}close(){}log(e){this.verbose&&process.stderr.write(`[transport] ${e}
|
|
114
|
-
`)}};ia();import{ProviderRegistry as X_,createLLMClient as
|
|
115
|
-
`),l=null;for(let u=0;u<Math.min(c.length,at.HEADER_LINES);u++){let p=c[u].trim();if(!(!p||p.startsWith("#")||p.startsWith("---"))){l=p.slice(0,150);break}}let d=AS(s);return{filename:s,filePath:o,mtimeMs:i.mtimeMs,sizeBytes:i.size,description:l,category:d}}))).filter(s=>s.status==="fulfilled").map(s=>s.value).sort((s,o)=>o.mtimeMs-s.mtimeMs).slice(0,at.MAX_SCAN_FILES)}function TS(n,e){let t=aa(n);if(t.length===0)return[];let r=Date.now(),s=at.RECENCY_DAYS*24*60*60*1e3;return e.map(i=>{let a=0,c=aa(i.filename.replace(/\.md$/,"").replace(/[-_]/g," ")),l=t.filter(d=>c.some(u=>u.includes(d)||d.includes(u))).length;if(a+=Math.min(.5,l/t.length*.5),i.description){let d=aa(i.description),u=t.filter(p=>d.some(m=>m.includes(p)||p.includes(m))).length;a+=Math.min(.3,u/t.length*.3)}return i.category&&wS(n).includes(i.category)&&(a+=.1),r-i.mtimeMs<s&&(a+=at.RECENCY_BOOST),{header:i,score:a}}).sort((i,a)=>a.score-i.score)}async function RS(n){let e=[],t=0;for(let{header:r,score:s}of n){if(t>=at.MAX_TOTAL_BYTES)break;try{let o=await
|
|
114
|
+
`)}};ia();import{ProviderRegistry as X_,createLLMClient as Sb}from"@xiaozhiclaw/provider-core";import{MediaClient as Y_}from"@xiaozhiclaw/provider-core";function tu(n){let e=new Map;return{register(t){let r=e.get(t.point)??[],s={handler:t.handler,priority:t.priority??100,label:t.label};return r.push(s),r.sort((o,i)=>o.priority-i.priority),e.set(t.point,r),()=>{let o=r.indexOf(s);o>=0&&r.splice(o,1)}},async invoke(t,r){let s=e.get(t);if(!s||s.length===0)return{action:"continue",context:r};let o=r;for(let i of s)try{let a=await i.handler(t,o);if(!a||a.action==="continue"){a?.context&&(o=a.context);continue}if(a.action==="abort"||a.action==="skip")return n.info({hook:t,label:i.label,action:a.action,reason:a.reason},"hook intercepted"),a}catch(a){n.warn({hook:t,label:i.label,err:a.message},"hook handler failed (non-blocking)")}return{action:"continue",context:o}}}}import{readFile as nu,readdir as bS,stat as vS}from"node:fs/promises";import{existsSync as ru}from"node:fs";import{join as kS}from"node:path";var at={MAX_SCAN_FILES:100,MAX_SELECTED:5,MAX_FILE_BYTES:4096,MAX_TOTAL_BYTES:20*1024,MIN_SCORE:.2,HEADER_LINES:10,RECENCY_DAYS:7,RECENCY_BOOST:.15};async function su(n,e,t=new Set){if(!n.trim()||!ru(e))return[];let r=n.trim().split(/\s+/);if(r.length<2&&r[0].length<4)return[];let s=await SS(e);if(s.length===0)return[];let o=s.filter(c=>!t.has(c.filePath));if(o.length===0)return[];let a=TS(n,o).filter(c=>c.score>=at.MIN_SCORE).slice(0,at.MAX_SELECTED);return a.length===0?[]:RS(a)}async function SS(n){if(!ru(n))return[];let e;try{e=await bS(n)}catch{return[]}let t=e.filter(s=>s.endsWith(".md")&&s!=="INDEX.md");return(await Promise.allSettled(t.map(async s=>{let o=kS(n,s),i=await vS(o),c=(await nu(o,"utf-8")).split(`
|
|
115
|
+
`),l=null;for(let u=0;u<Math.min(c.length,at.HEADER_LINES);u++){let p=c[u].trim();if(!(!p||p.startsWith("#")||p.startsWith("---"))){l=p.slice(0,150);break}}let d=AS(s);return{filename:s,filePath:o,mtimeMs:i.mtimeMs,sizeBytes:i.size,description:l,category:d}}))).filter(s=>s.status==="fulfilled").map(s=>s.value).sort((s,o)=>o.mtimeMs-s.mtimeMs).slice(0,at.MAX_SCAN_FILES)}function TS(n,e){let t=aa(n);if(t.length===0)return[];let r=Date.now(),s=at.RECENCY_DAYS*24*60*60*1e3;return e.map(i=>{let a=0,c=aa(i.filename.replace(/\.md$/,"").replace(/[-_]/g," ")),l=t.filter(d=>c.some(u=>u.includes(d)||d.includes(u))).length;if(a+=Math.min(.5,l/t.length*.5),i.description){let d=aa(i.description),u=t.filter(p=>d.some(m=>m.includes(p)||p.includes(m))).length;a+=Math.min(.3,u/t.length*.3)}return i.category&&wS(n).includes(i.category)&&(a+=.1),r-i.mtimeMs<s&&(a+=at.RECENCY_BOOST),{header:i,score:a}}).sort((i,a)=>a.score-i.score)}async function RS(n){let e=[],t=0;for(let{header:r,score:s}of n){if(t>=at.MAX_TOTAL_BYTES)break;try{let o=await nu(r.filePath,"utf-8"),i=!1;o.length>at.MAX_FILE_BYTES&&(o=o.slice(0,at.MAX_FILE_BYTES)+`
|
|
116
116
|
|
|
117
117
|
> [Truncated at ${at.MAX_FILE_BYTES} bytes. Use memory tool read_file for full content: ${r.filename}]`,i=!0);let a=Buffer.byteLength(o,"utf-8");if(t+a>at.MAX_TOTAL_BYTES){let c=at.MAX_TOTAL_BYTES-t;o=o.slice(0,c)+`
|
|
118
118
|
|
|
119
|
-
> [Truncated to fit session budget. Use memory tool read_file for full content: ${r.filename}]`,i=!0}t+=Buffer.byteLength(o,"utf-8"),e.push({filename:r.filename,filePath:r.filePath,mtimeMs:r.mtimeMs,score:s,content:o,truncated:i})}catch{}}return e}function aa(n){return n.toLowerCase().replace(/[^\w\u4e00-\u9fff]+/g," ").split(/\s+/).filter(e=>e.length>1)}function AS(n){let e=n.replace(/\.md$/,""),t=["lesson","project","pattern","preference","fact","decision","task","reference"];for(let r of t)if(e.startsWith(r+"-")||e.startsWith(r+"_"))return r;return null}function wS(n){let e=[],t=n.toLowerCase();return/(?:bug|error|fix|debug|issue|问题|报错|修复)/.test(t)&&e.push("lesson"),/(?:architecture|设计|架构|决定|decision)/.test(t)&&e.push("decision"),/(?:pattern|convention|惯例|标准|practice)/.test(t)&&e.push("pattern"),/(?:prefer|style|偏好|风格|习惯)/.test(t)&&e.push("preference"),/(?:deploy|port|config|version|部署|配置|环境)/.test(t)&&e.push("fact"),/(?:project|repo|codebase|项目|仓库)/.test(t)&&e.push("project"),/(?:task|todo|plan|任务|计划)/.test(t)&&e.push("task"),/(?:api|doc|guide|reference|文档|手册)/.test(t)&&e.push("reference"),e}function
|
|
119
|
+
> [Truncated to fit session budget. Use memory tool read_file for full content: ${r.filename}]`,i=!0}t+=Buffer.byteLength(o,"utf-8"),e.push({filename:r.filename,filePath:r.filePath,mtimeMs:r.mtimeMs,score:s,content:o,truncated:i})}catch{}}return e}function aa(n){return n.toLowerCase().replace(/[^\w\u4e00-\u9fff]+/g," ").split(/\s+/).filter(e=>e.length>1)}function AS(n){let e=n.replace(/\.md$/,""),t=["lesson","project","pattern","preference","fact","decision","task","reference"];for(let r of t)if(e.startsWith(r+"-")||e.startsWith(r+"_"))return r;return null}function wS(n){let e=[],t=n.toLowerCase();return/(?:bug|error|fix|debug|issue|问题|报错|修复)/.test(t)&&e.push("lesson"),/(?:architecture|设计|架构|决定|decision)/.test(t)&&e.push("decision"),/(?:pattern|convention|惯例|标准|practice)/.test(t)&&e.push("pattern"),/(?:prefer|style|偏好|风格|习惯)/.test(t)&&e.push("preference"),/(?:deploy|port|config|version|部署|配置|环境)/.test(t)&&e.push("fact"),/(?:project|repo|codebase|项目|仓库)/.test(t)&&e.push("project"),/(?:task|todo|plan|任务|计划)/.test(t)&&e.push("task"),/(?:api|doc|guide|reference|文档|手册)/.test(t)&&e.push("reference"),e}function ou(n){if(n.length===0)return"";let e=Date.now();return n.map(r=>{let s=Math.floor((e-r.mtimeMs)/864e5);return`## Memory (saved ${s===0?"today":s===1?"yesterday":`${s} days ago`}): ${r.filename}
|
|
120
120
|
|
|
121
121
|
${r.content}`}).join(`
|
|
122
122
|
|
|
@@ -140,8 +140,8 @@ Assistant response:
|
|
|
140
140
|
Today's date: {today}
|
|
141
141
|
|
|
142
142
|
Respond ONLY with a JSON array (or empty array [] if nothing worth extracting):
|
|
143
|
-
[{"text": "...", "category": "personal_fact|preference|event|lesson", "importance": 0.5-0.9, "eventDate": "YYYY-MM-DD or null"}]`;async function IS(n,e,t){let r=PS.replace("{user_message}",n.userMessage.slice(0,1e3)).replace("{assistant_message}",n.assistantMessage.slice(0,500)).replace("{today}",t);try{let s=await e(r);if(!s)return[];let o=s.replace(/^```(?:json)?\n?/,"").replace(/\n?```$/,"").trim(),i=JSON.parse(o);return Array.isArray(i)?i.filter(a=>a.text&&typeof a.text=="string"&&a.text.length>=5&&a.text.length<=500&&a.category).map(a=>({text:a.text.trim(),category:_S(a.category),importance:Math.min(.9,Math.max(.3,Number(a.importance)||.5)),eventDate:typeof a.eventDate=="string"?a.eventDate:void 0})).slice(0,3):[]}catch{return[]}}function _S(n){return new Set(["personal_fact","preference","event","lesson","pattern","decision"]).has(n)?n:"personal_fact"}async function ou(n,e){if(!ca(n.userMessage))return 0;if(e.log.debug(`implicit-extract: signal detected in user message (${n.userMessage.slice(0,50)}...)`),!e.llmExtract)return e.log.debug("implicit-extract: no LLM extractor configured, skipping Layer 2"),0;let t=new Date().toISOString().slice(0,10),r=await IS(n,e.llmExtract,t);if(r.length===0)return e.log.debug("implicit-extract: LLM returned no facts"),0;let s=0;for(let o of r)try{if(((await e.localProvider.proposeExtracted([{text:o.text,category:o.category,importance:o.importance}],e.userId,{source:"implicit-extract"})).proposalsAdded??0)>0){if(s++,e.log.debug(`implicit-extract: proposed "${o.text.slice(0,60)}..." [${o.category}]`),o.category==="event")try{let a=await e.localProvider.findRelatedEvents(o.text,e.userId);for(let c of a)e.localProvider.feedback([c.id],"useful").catch(()=>{});a.length>0&&e.log.debug(`implicit-extract: linked to ${a.length} related events`)}catch{}}else e.log.debug(`implicit-extract: dedup skipped "${o.text.slice(0,40)}..."`)}catch{}return s}je();var xn={MAX_SESSION_BYTES:xi,LIMIT_PER_RECALL:Pi,MAX_SURFACED_ENTRIES:Ii};function Lt(){return{surfacedPaths:new Set,sessionBytes:0}}function au(n,e,t){let r=[],s=t??Lt(),o,i=[];return r.push(n.register({point:"memory.before_recall",priority:50,label:"qmemory-prefetch",handler:async(a,c)=>{if(!e.memoryProvider||!c.query)return{action:"continue",context:c};if(s.sessionBytes>=xn.MAX_SESSION_BYTES)return e.log.debug("memory.before_recall: session byte budget exhausted, skipping"),{action:"continue",context:c};try{let l=await e.memoryProvider.search(c.query,e.userId,{limit:xn.LIMIT_PER_RECALL}),d=l.filter(m=>{let h=m,f=h.path??h.id??"";if(!f)return!0;if(s.surfacedPaths.has(f))return!1;let y=(h.content?.length??0)*2;if(s.sessionBytes+y>xn.MAX_SESSION_BYTES)return!1;if(s.surfacedPaths.add(f),s.sessionBytes+=y,s.surfacedPaths.size>xn.MAX_SURFACED_ENTRIES){let b=s.surfacedPaths.values().next().value;b!==void 0&&s.surfacedPaths.delete(b)}return!0});o=c.turnId,i=d,e.log.debug(`memory.before_recall: prefetched ${l.length} \u922B?${d.length} after dedup (${s.sessionBytes} bytes used)`);let u=d.map(m=>{let h=m;return{text:h.text??h.content??"",score:h.score,category:h.metadata?.category??null,source:"l2-long-term",label:"L2 long-term"}}).filter(m=>m.text);if(c.preferredCategories?.length||c.deprioritizedCategories?.length){let m={scenario:"general",preferred:c.preferredCategories??[],deprioritized:c.deprioritizedCategories??[],confidence:1};u=u.map(h=>({...h,score:sa(h.score??.5,h.category,m)})).sort((h,f)=>(f.score??0)-(h.score??0))}let p=.15;return u=u.filter(m=>(m.score??0)>=p),{action:"continue",context:{...c,recalledMemories:[...c.recalledMemories??[],...u]}}}catch(l){e.log.warn(`memory.before_recall: qmemory prefetch failed: ${l instanceof Error?l.message:String(l)}`),i=[]}return{action:"continue",context:c}}})),r.push(n.register({point:"memory.after_recall",priority:50,label:"qmemory-recall-log",handler:(a,c)=>{let l=o===c.turnId?i.length:0;return e.log.debug(`memory.after_recall: ${c.blockCount??0} blocks assembled, ${l} qmemory results (session: ${s.sessionBytes} bytes)`),{action:"continue",context:c}}})),e.localMemoryProvider&&(r.push(n.register({point:"turn.completed",priority:90,label:"memory-auto-extract",handler:async(a,c)=>{let l=e.getLastUserMessage?.();if(!l)return{action:"continue",context:c};let d=iu(l);if(d.length===0)return{action:"continue",context:c};for(let u of d)try{await e.localMemoryProvider.addText(u.text,e.userId,{source:"auto-extract",category:u.category,importance:.6}),e.log.debug(`memory-auto-extract: stored "${u.text.slice(0,50)}..." (${u.category})`)}catch{}return{action:"continue",context:c}}})),r.push(n.register({point:"turn.completed",priority:95,label:"memory-implicit-extract",handler:async(a,c)=>{let l=e.getLastUserMessage?.();if(!l)return{action:"continue",context:c};if(iu(l).length>0)return{action:"continue",context:c};if(!ca(l))return{action:"continue",context:c};let u=e.getLastAssistantMessage?.();return!u||!e.llmExtract?{action:"continue",context:c}:(ou({userMessage:l,assistantMessage:u},{localProvider:e.localMemoryProvider,userId:e.userId,log:e.log,llmExtract:e.llmExtract}).catch(()=>{}),{action:"continue",context:c})}}))),()=>{for(let a of r)a();i=[]}}function cu(n,e,t){let r=t??Lt();return n.register({point:"memory.before_recall",priority:40,label:"memdir-cross-file-recall",handler:async(o,i)=>{let a=e.getMemdir();if(!a||!i.query)return{action:"continue",context:i};if(r.sessionBytes>=xn.MAX_SESSION_BYTES)return e.log.debug("memdir-recall: session byte budget exhausted, skipping"),{action:"continue",context:i};try{let c=a.getRootPath(),l=await ru(i.query,c,r.surfacedPaths);if(l.length===0)return{action:"continue",context:i};if(i.preferredCategories?.length||i.deprioritizedCategories?.length){let h={scenario:"general",preferred:i.preferredCategories??[],deprioritized:i.deprioritizedCategories??[],confidence:1};l=l.map(f=>({...f,score:sa(f.score,Vd(f.filename),h)})).sort((f,y)=>y.score-f.score)}let d=l.filter(h=>{let f=Buffer.byteLength(h.content,"utf-8");return r.sessionBytes+f>xn.MAX_SESSION_BYTES?!1:(r.surfacedPaths.add(h.filePath),r.sessionBytes+=f,!0)});if(d.length===0)return{action:"continue",context:i};e.log.debug(`memdir-recall: found ${l.length} \u922B?accepted ${d.length} files (${r.sessionBytes} bytes used)`);let u=su(d),p=i.recalledMemories??[];return{action:"continue",context:{...i,recalledMemories:[...[{text:u,score:.9,category:"project",source:"l1-project-md",label:"L1 project MD"}],...p]}}}catch(c){e.log.warn(`memdir-recall: cross-file recall failed: ${c instanceof Error?c.message:String(c)}`)}return{action:"continue",context:i}}})}var ES=[{pattern:/(?:请|帮我)?记住[::]\s*(.+)/i,category:"personal_fact",extractor:n=>n[1]?.trim()||null},{pattern:/(?:请|帮我)?记住(.{10,120})/i,category:"personal_fact",extractor:n=>n[1]?.trim()||null},{pattern:/我的偏好[是为::]\s*(.+)/i,category:"preference",extractor:n=>n[1]?.trim()||null},{pattern:/我(?:喜欢|偏好|习惯)(.{5,100})/i,category:"preference",extractor:n=>`\u7528\u6237\u504F\u597D: ${n[1]?.trim()}`},{pattern:/以后(?:都|请|要)(.{5,100})/i,category:"preference",extractor:n=>`\u7528\u6237\u8981\u6C42: ${n[1]?.trim()}`},{pattern:/remember(?:\s+that)?[::]\s*(.+)/i,category:"personal_fact",extractor:n=>n[1]?.trim()||null},{pattern:/(?:note|memo)[::]\s*(.+)/i,category:"lesson",extractor:n=>n[1]?.trim()||null},{pattern:/my preference is[::]?\s*(.+)/i,category:"preference",extractor:n=>n[1]?.trim()||null},{pattern:/i (?:always|prefer|like to|want you to)\s+(.{10,120})/i,category:"preference",extractor:n=>`User preference: ${n[1]?.trim()}`}];function iu(n){let e=[],t=n.slice(0,500);for(let{pattern:r,category:s,extractor:o}of ES){let i=t.match(r);if(i){let a=o(i,t);if(a&&a.length>=5&&a.length<=300){e.push({text:a,category:s});break}}}return e}ae();import*as us from"node:fs";import*as ir from"node:path";ae();import{existsSync as lu,mkdirSync as CS,readFileSync as MS,writeFileSync as NS}from"node:fs";import{join as DS}from"node:path";import{randomUUID as du}from"node:crypto";function uu(){return DS(q(),"projects.json")}function Ke(){let n=uu();if(!lu(n))return{activeProjectId:null,projects:[]};try{let e=MS(n,"utf-8");return JSON.parse(e)}catch{return{activeProjectId:null,projects:[]}}}function Rt(n){let e=uu(),t=q();lu(t)||CS(t,{recursive:!0}),NS(e,JSON.stringify(n,null,2),"utf-8")}function as(n){let e=Ke(),t=new Date().toISOString(),r={id:du(),name:n.name,workspaceDir:n.workspaceDir,type:n.type??"personal",status:"active",groupId:n.groupId,createdAt:t,updatedAt:t};return e.projects.push(r),n.skipAutoSwitch||(e.activeProjectId=r.id),Rt(e),r}function me(){return Ke().projects.filter(e=>e.status==="active")}function Oe(){let n=Ke();if(!n.activeProjectId)return null;let e=n.projects.find(t=>t.id===n.activeProjectId)??null;return e&&e.status!=="active"?null:e}function ct(n){return Ke().projects.find(t=>t.id===n)??null}function pu(n,e){let t=Ke(),r=t.projects.find(s=>s.id===n);return r?("planStatus"in e&&(r.planStatus=e.planStatus),"planAgents"in e&&(r.planAgents=e.planAgents),"planWinnerId"in e&&(r.planWinnerId=e.planWinnerId),"leaderSessionId"in e&&(r.leaderSessionId=e.leaderSessionId),r.updatedAt=new Date().toISOString(),Rt(t),!0):!1}function ut(n){let e=Ke(),t=e.projects.find(r=>r.id===n&&r.status==="active");return t?(e.activeProjectId=t.id,Rt(e),t):null}function la(n){let e=Ke(),t=e.projects.findIndex(o=>o.id===n);if(t===-1)return{deleted:!1};if(e.projects[t].type==="default")return{deleted:!1};e.projects.splice(t,1);let s;if(e.activeProjectId===n){let o=e.projects.find(i=>i.type==="default"&&i.status==="active");if(o)e.activeProjectId=o.id,s=o;else{let i=e.projects.find(a=>a.status==="active"&&a.id!==n);e.activeProjectId=i?.id??null,s=i}}return Rt(e),{deleted:!0,switchedTo:s}}function mu(n){let e=Ke(),t=e.projects.find(o=>o.type==="default"&&o.status==="active");if(t)return t;let r=new Date().toISOString(),s={id:du(),name:"\u9ED8\u8BA4\u9879\u76EE",workspaceDir:n,type:"default",status:"active",createdAt:r,updatedAt:r};return e.projects.push(s),e.activeProjectId||(e.activeProjectId=s.id),Rt(e),s}function gu(n,e){let t=Ke(),r=t.projects.find(o=>o.id===n&&o.status==="active");return!r||r.type==="default"||t.projects.find(o=>o.name===e&&o.status==="active"&&o.id!==n)?null:(r.name=e,r.updatedAt=new Date().toISOString(),Rt(t),r)}function fu(n,e){let t=Ke(),r=t.projects.find(s=>s.id===n);return r?(r.workspaceDir=e,r.updatedAt=new Date().toISOString(),Rt(t),!0):!1}function hu(n){let e=Ke(),t=e.projects.find(s=>s.id===n&&s.status==="active");if(!t)return{archived:!1};if(t.type==="default")return{archived:!1};t.status="archived",t.updatedAt=new Date().toISOString();let r;if(e.activeProjectId===n){let s=e.projects.find(o=>o.type==="default"&&o.status==="active");if(s)e.activeProjectId=s.id,r=s;else{let o=e.projects.find(i=>i.status==="active"&&i.id!==n);e.activeProjectId=o?.id??null,r=o}}return Rt(e),{archived:!0,switchedTo:r}}function yu(n){let e=Ke(),t=e.projects.find(r=>r.id===n&&r.status==="archived");return t?(t.status="active",t.updatedAt=new Date().toISOString(),Rt(e),t):null}function cs(n){return Ke().projects.find(t=>t.groupId===n&&t.status==="active")??null}function bu(n){let e=Ke(),t=e.projects.find(s=>s.groupId===n&&s.status==="active");if(!t)return{archived:!1};t.status="archived",t.updatedAt=new Date().toISOString();let r;if(e.activeProjectId===t.id){let s=e.projects.find(o=>o.type==="default"&&o.status==="active");if(s)e.activeProjectId=s.id,r=s;else{let o=e.projects.find(i=>i.status==="active"&&i.id!==t.id);e.activeProjectId=o?.id??null,r=o}}return Rt(e),{archived:!0,projectId:t.id,switchedTo:r}}je();var ds={MAX_RECALLED_SKILLS:li,MAX_SKILL_CONTENT_CHARS:di,CACHE_TTL_MS:ui};function OS(n){let e=[/之前.{0,8}(?:做过|写过|实现过|处理过|用过|搞过|弄过)/,/以前.{0,8}(?:做过|写过|实现过|处理过|用过)/,/(?:上次|上回|之前|以前).{0,12}(?:不是|是不是|已经).{0,8}(?:做|写|实现|处理)/,/(?:参考|参照|照着|按照).{0,6}(?:项目|工程|仓库)/,/(?:那个|那边|另一个).{0,6}(?:项目|工程).{0,6}(?:里|中|的)/,/(?:跟|和|像).{0,6}(?:项目|工程).{0,6}(?:一样|类似|差不多)/,/(?:复用|重用|搬过来|拿过来|移过来|copy过来)/],t=[/(?:有没有|有无|是否有).{0,6}(?:技能|skill|模板|template|现成的)/,/(?:能不能|可以).{0,6}(?:自动|像之前|快速).{0,6}(?:生成|创建|写|做)/,/(?:跟|和|类似|像).{0,4}(?:上次|之前|其他|那个).{0,4}(?:一样|类似)/,/(?:批量|自动化|一键).{0,6}(?:生成|创建|部署|处理)/,/(?:同样的|相同的|一样的).{0,4}(?:方式|方法|流程|步骤)/],r=[/(?:before|previously|earlier|last time).{0,20}(?:did|done|made|built|implemented|wrote)/i,/(?:didn't|did) you.{0,15}(?:already|before|earlier)/i,/(?:same|similar).{0,10}(?:as|to|like).{0,10}(?:project|repo)/i,/(?:reuse|re-use|copy from|bring over|port from).{0,15}(?:project|repo)/i,/(?:remember|recall).{0,10}(?:doing|making|building|writing)/i,/(?:other|another|different)\s+project/i],s=[/(?:is there|do you have|any).{0,10}(?:skill|template|automation|workflow)/i,/(?:like|similar to|same as).{0,15}(?:last time|before|the other)/i,/(?:automate|batch|bulk).{0,10}(?:create|generate|process|build)/i,/(?:can you|could you).{0,10}(?:do the same|repeat|replicate)/i];if(![...e,...t,...r,...s].some(c=>c.test(n)))return null;let a=LS(n);return a.length>0?a:null}function LS(n){let t=n.replace(/之前|以前|上次|上回|不是|是不是|已经|做过|写过|实现过|处理过|用过|搞过|弄过/g," ").replace(/参考|参照|照着|按照|项目|工程|仓库|那个|那边|另一个|里|中|的|跟|和|像|一样|类似|差不多/g," ").replace(/复用|重用|搬过来|拿过来|移过来/g," ").replace(/\b(the|a|an|is|was|were|did|didn't|do|you|i|we|it|this|that|before|previously|earlier|last|time|already|same|similar|as|to|like|from|project|repo|remember|recall|doing|making|building|writing|other|another|different)\b/gi," ").trim().split(/[\s,;.!?,。!?、;:""''()\[\]{}]+/).filter(r=>r.length>=2).map(r=>r.toLowerCase());return[...new Set(t)].slice(0,8)}var ls=null,da=0;function $S(n){let e=Date.now();if(ls&&e-da<ds.CACHE_TTL_MS)return ls;let t=[],r=me().map(o=>o.workspaceDir).filter(Boolean),s=Id(r,n);for(let o of s){let i=ir.join(o,".qlogicagent","skills");try{let a=us.readdirSync(i,{withFileTypes:!0});for(let c of a){if(!c.isDirectory())continue;let l=ir.join(i,c.name,"SKILL.md");try{let d=us.readFileSync(l,"utf8"),u=d.split(`
|
|
144
|
-
`).slice(0,5).join(" ").toLowerCase();t.push({name:c.name,projectDir:o,projectName:ir.basename(o),content:d,searchText:`${c.name.toLowerCase()} ${u}`})}catch{}}}catch{}}return ls=t,da=e,t}function jS(n,e){if(n.length===0)return[];let t=$S(e);return t.length===0?[]:t.map(s=>{let o=0;for(let i of n)s.searchText.includes(i)&&(o+=2),s.name.includes(i)&&(o+=3);return{skill:s,score:o}}).filter(s=>s.score>0).sort((s,o)=>o.score-s.score).slice(0,ds.MAX_RECALLED_SKILLS).map(s=>s.skill)}function
|
|
143
|
+
[{"text": "...", "category": "personal_fact|preference|event|lesson", "importance": 0.5-0.9, "eventDate": "YYYY-MM-DD or null"}]`;async function IS(n,e,t){let r=PS.replace("{user_message}",n.userMessage.slice(0,1e3)).replace("{assistant_message}",n.assistantMessage.slice(0,500)).replace("{today}",t);try{let s=await e(r);if(!s)return[];let o=s.replace(/^```(?:json)?\n?/,"").replace(/\n?```$/,"").trim(),i=JSON.parse(o);return Array.isArray(i)?i.filter(a=>a.text&&typeof a.text=="string"&&a.text.length>=5&&a.text.length<=500&&a.category).map(a=>({text:a.text.trim(),category:_S(a.category),importance:Math.min(.9,Math.max(.3,Number(a.importance)||.5)),eventDate:typeof a.eventDate=="string"?a.eventDate:void 0})).slice(0,3):[]}catch{return[]}}function _S(n){return new Set(["personal_fact","preference","event","lesson","pattern","decision"]).has(n)?n:"personal_fact"}async function iu(n,e){if(!ca(n.userMessage))return 0;if(e.log.debug(`implicit-extract: signal detected in user message (${n.userMessage.slice(0,50)}...)`),!e.llmExtract)return e.log.debug("implicit-extract: no LLM extractor configured, skipping Layer 2"),0;let t=new Date().toISOString().slice(0,10),r=await IS(n,e.llmExtract,t);if(r.length===0)return e.log.debug("implicit-extract: LLM returned no facts"),0;let s=0;for(let o of r)try{if(((await e.localProvider.proposeExtracted([{text:o.text,category:o.category,importance:o.importance}],e.userId,{source:"implicit-extract"})).proposalsAdded??0)>0){if(s++,e.log.debug(`implicit-extract: proposed "${o.text.slice(0,60)}..." [${o.category}]`),o.category==="event")try{let a=await e.localProvider.findRelatedEvents(o.text,e.userId);for(let c of a)e.localProvider.feedback([c.id],"useful").catch(()=>{});a.length>0&&e.log.debug(`implicit-extract: linked to ${a.length} related events`)}catch{}}else e.log.debug(`implicit-extract: dedup skipped "${o.text.slice(0,40)}..."`)}catch{}return s}je();var xn={MAX_SESSION_BYTES:xi,LIMIT_PER_RECALL:Pi,MAX_SURFACED_ENTRIES:Ii};function Lt(){return{surfacedPaths:new Set,sessionBytes:0}}function cu(n,e,t){let r=[],s=t??Lt(),o,i=[];return r.push(n.register({point:"memory.before_recall",priority:50,label:"qmemory-prefetch",handler:async(a,c)=>{if(!e.memoryProvider||!c.query)return{action:"continue",context:c};if(s.sessionBytes>=xn.MAX_SESSION_BYTES)return e.log.debug("memory.before_recall: session byte budget exhausted, skipping"),{action:"continue",context:c};try{let l=await e.memoryProvider.search(c.query,e.userId,{limit:xn.LIMIT_PER_RECALL}),d=l.filter(m=>{let h=m,f=h.path??h.id??"";if(!f)return!0;if(s.surfacedPaths.has(f))return!1;let y=(h.content?.length??0)*2;if(s.sessionBytes+y>xn.MAX_SESSION_BYTES)return!1;if(s.surfacedPaths.add(f),s.sessionBytes+=y,s.surfacedPaths.size>xn.MAX_SURFACED_ENTRIES){let b=s.surfacedPaths.values().next().value;b!==void 0&&s.surfacedPaths.delete(b)}return!0});o=c.turnId,i=d,e.log.debug(`memory.before_recall: prefetched ${l.length} \u922B?${d.length} after dedup (${s.sessionBytes} bytes used)`);let u=d.map(m=>{let h=m;return{text:h.text??h.content??"",score:h.score,category:h.metadata?.category??null,source:"l2-long-term",label:"L2 long-term"}}).filter(m=>m.text);if(c.preferredCategories?.length||c.deprioritizedCategories?.length){let m={scenario:"general",preferred:c.preferredCategories??[],deprioritized:c.deprioritizedCategories??[],confidence:1};u=u.map(h=>({...h,score:sa(h.score??.5,h.category,m)})).sort((h,f)=>(f.score??0)-(h.score??0))}let p=.15;return u=u.filter(m=>(m.score??0)>=p),{action:"continue",context:{...c,recalledMemories:[...c.recalledMemories??[],...u]}}}catch(l){e.log.warn(`memory.before_recall: qmemory prefetch failed: ${l instanceof Error?l.message:String(l)}`),i=[]}return{action:"continue",context:c}}})),r.push(n.register({point:"memory.after_recall",priority:50,label:"qmemory-recall-log",handler:(a,c)=>{let l=o===c.turnId?i.length:0;return e.log.debug(`memory.after_recall: ${c.blockCount??0} blocks assembled, ${l} qmemory results (session: ${s.sessionBytes} bytes)`),{action:"continue",context:c}}})),e.localMemoryProvider&&(r.push(n.register({point:"turn.completed",priority:90,label:"memory-auto-extract",handler:async(a,c)=>{let l=e.getLastUserMessage?.();if(!l)return{action:"continue",context:c};let d=au(l);if(d.length===0)return{action:"continue",context:c};for(let u of d)try{await e.localMemoryProvider.addText(u.text,e.userId,{source:"auto-extract",category:u.category,importance:.6}),e.log.debug(`memory-auto-extract: stored "${u.text.slice(0,50)}..." (${u.category})`)}catch{}return{action:"continue",context:c}}})),r.push(n.register({point:"turn.completed",priority:95,label:"memory-implicit-extract",handler:async(a,c)=>{let l=e.getLastUserMessage?.();if(!l)return{action:"continue",context:c};if(au(l).length>0)return{action:"continue",context:c};if(!ca(l))return{action:"continue",context:c};let u=e.getLastAssistantMessage?.();return!u||!e.llmExtract?{action:"continue",context:c}:(iu({userMessage:l,assistantMessage:u},{localProvider:e.localMemoryProvider,userId:e.userId,log:e.log,llmExtract:e.llmExtract}).catch(()=>{}),{action:"continue",context:c})}}))),()=>{for(let a of r)a();i=[]}}function lu(n,e,t){let r=t??Lt();return n.register({point:"memory.before_recall",priority:40,label:"memdir-cross-file-recall",handler:async(o,i)=>{let a=e.getMemdir();if(!a||!i.query)return{action:"continue",context:i};if(r.sessionBytes>=xn.MAX_SESSION_BYTES)return e.log.debug("memdir-recall: session byte budget exhausted, skipping"),{action:"continue",context:i};try{let c=a.getRootPath(),l=await su(i.query,c,r.surfacedPaths);if(l.length===0)return{action:"continue",context:i};if(i.preferredCategories?.length||i.deprioritizedCategories?.length){let h={scenario:"general",preferred:i.preferredCategories??[],deprioritized:i.deprioritizedCategories??[],confidence:1};l=l.map(f=>({...f,score:sa(f.score,zd(f.filename),h)})).sort((f,y)=>y.score-f.score)}let d=l.filter(h=>{let f=Buffer.byteLength(h.content,"utf-8");return r.sessionBytes+f>xn.MAX_SESSION_BYTES?!1:(r.surfacedPaths.add(h.filePath),r.sessionBytes+=f,!0)});if(d.length===0)return{action:"continue",context:i};e.log.debug(`memdir-recall: found ${l.length} \u922B?accepted ${d.length} files (${r.sessionBytes} bytes used)`);let u=ou(d),p=i.recalledMemories??[];return{action:"continue",context:{...i,recalledMemories:[...[{text:u,score:.9,category:"project",source:"l1-project-md",label:"L1 project MD"}],...p]}}}catch(c){e.log.warn(`memdir-recall: cross-file recall failed: ${c instanceof Error?c.message:String(c)}`)}return{action:"continue",context:i}}})}var ES=[{pattern:/(?:请|帮我)?记住[::]\s*(.+)/i,category:"personal_fact",extractor:n=>n[1]?.trim()||null},{pattern:/(?:请|帮我)?记住(.{10,120})/i,category:"personal_fact",extractor:n=>n[1]?.trim()||null},{pattern:/我的偏好[是为::]\s*(.+)/i,category:"preference",extractor:n=>n[1]?.trim()||null},{pattern:/我(?:喜欢|偏好|习惯)(.{5,100})/i,category:"preference",extractor:n=>`\u7528\u6237\u504F\u597D: ${n[1]?.trim()}`},{pattern:/以后(?:都|请|要)(.{5,100})/i,category:"preference",extractor:n=>`\u7528\u6237\u8981\u6C42: ${n[1]?.trim()}`},{pattern:/remember(?:\s+that)?[::]\s*(.+)/i,category:"personal_fact",extractor:n=>n[1]?.trim()||null},{pattern:/(?:note|memo)[::]\s*(.+)/i,category:"lesson",extractor:n=>n[1]?.trim()||null},{pattern:/my preference is[::]?\s*(.+)/i,category:"preference",extractor:n=>n[1]?.trim()||null},{pattern:/i (?:always|prefer|like to|want you to)\s+(.{10,120})/i,category:"preference",extractor:n=>`User preference: ${n[1]?.trim()}`}];function au(n){let e=[],t=n.slice(0,500);for(let{pattern:r,category:s,extractor:o}of ES){let i=t.match(r);if(i){let a=o(i,t);if(a&&a.length>=5&&a.length<=300){e.push({text:a,category:s});break}}}return e}ae();import*as us from"node:fs";import*as ir from"node:path";ae();import{existsSync as du,mkdirSync as CS,readFileSync as MS,writeFileSync as NS}from"node:fs";import{join as DS}from"node:path";import{randomUUID as uu}from"node:crypto";function pu(){return DS(q(),"projects.json")}function Ke(){let n=pu();if(!du(n))return{activeProjectId:null,projects:[]};try{let e=MS(n,"utf-8");return JSON.parse(e)}catch{return{activeProjectId:null,projects:[]}}}function Rt(n){let e=pu(),t=q();du(t)||CS(t,{recursive:!0}),NS(e,JSON.stringify(n,null,2),"utf-8")}function as(n){let e=Ke(),t=new Date().toISOString(),r={id:uu(),name:n.name,workspaceDir:n.workspaceDir,type:n.type??"personal",status:"active",groupId:n.groupId,createdAt:t,updatedAt:t};return e.projects.push(r),n.skipAutoSwitch||(e.activeProjectId=r.id),Rt(e),r}function me(){return Ke().projects.filter(e=>e.status==="active")}function Oe(){let n=Ke();if(!n.activeProjectId)return null;let e=n.projects.find(t=>t.id===n.activeProjectId)??null;return e&&e.status!=="active"?null:e}function ct(n){return Ke().projects.find(t=>t.id===n)??null}function mu(n,e){let t=Ke(),r=t.projects.find(s=>s.id===n);return r?("planStatus"in e&&(r.planStatus=e.planStatus),"planAgents"in e&&(r.planAgents=e.planAgents),"planWinnerId"in e&&(r.planWinnerId=e.planWinnerId),"leaderSessionId"in e&&(r.leaderSessionId=e.leaderSessionId),r.updatedAt=new Date().toISOString(),Rt(t),!0):!1}function ut(n){let e=Ke(),t=e.projects.find(r=>r.id===n&&r.status==="active");return t?(e.activeProjectId=t.id,Rt(e),t):null}function la(n){let e=Ke(),t=e.projects.findIndex(o=>o.id===n);if(t===-1)return{deleted:!1};if(e.projects[t].type==="default")return{deleted:!1};e.projects.splice(t,1);let s;if(e.activeProjectId===n){let o=e.projects.find(i=>i.type==="default"&&i.status==="active");if(o)e.activeProjectId=o.id,s=o;else{let i=e.projects.find(a=>a.status==="active"&&a.id!==n);e.activeProjectId=i?.id??null,s=i}}return Rt(e),{deleted:!0,switchedTo:s}}function gu(n){let e=Ke(),t=e.projects.find(o=>o.type==="default"&&o.status==="active");if(t)return t;let r=new Date().toISOString(),s={id:uu(),name:"\u9ED8\u8BA4\u9879\u76EE",workspaceDir:n,type:"default",status:"active",createdAt:r,updatedAt:r};return e.projects.push(s),e.activeProjectId||(e.activeProjectId=s.id),Rt(e),s}function fu(n,e){let t=Ke(),r=t.projects.find(o=>o.id===n&&o.status==="active");return!r||r.type==="default"||t.projects.find(o=>o.name===e&&o.status==="active"&&o.id!==n)?null:(r.name=e,r.updatedAt=new Date().toISOString(),Rt(t),r)}function hu(n,e){let t=Ke(),r=t.projects.find(s=>s.id===n);return r?(r.workspaceDir=e,r.updatedAt=new Date().toISOString(),Rt(t),!0):!1}function yu(n){let e=Ke(),t=e.projects.find(s=>s.id===n&&s.status==="active");if(!t)return{archived:!1};if(t.type==="default")return{archived:!1};t.status="archived",t.updatedAt=new Date().toISOString();let r;if(e.activeProjectId===n){let s=e.projects.find(o=>o.type==="default"&&o.status==="active");if(s)e.activeProjectId=s.id,r=s;else{let o=e.projects.find(i=>i.status==="active"&&i.id!==n);e.activeProjectId=o?.id??null,r=o}}return Rt(e),{archived:!0,switchedTo:r}}function bu(n){let e=Ke(),t=e.projects.find(r=>r.id===n&&r.status==="archived");return t?(t.status="active",t.updatedAt=new Date().toISOString(),Rt(e),t):null}function cs(n){return Ke().projects.find(t=>t.groupId===n&&t.status==="active")??null}function vu(n){let e=Ke(),t=e.projects.find(s=>s.groupId===n&&s.status==="active");if(!t)return{archived:!1};t.status="archived",t.updatedAt=new Date().toISOString();let r;if(e.activeProjectId===t.id){let s=e.projects.find(o=>o.type==="default"&&o.status==="active");if(s)e.activeProjectId=s.id,r=s;else{let o=e.projects.find(i=>i.status==="active"&&i.id!==t.id);e.activeProjectId=o?.id??null,r=o}}return Rt(e),{archived:!0,projectId:t.id,switchedTo:r}}je();var ds={MAX_RECALLED_SKILLS:li,MAX_SKILL_CONTENT_CHARS:di,CACHE_TTL_MS:ui};function OS(n){let e=[/之前.{0,8}(?:做过|写过|实现过|处理过|用过|搞过|弄过)/,/以前.{0,8}(?:做过|写过|实现过|处理过|用过)/,/(?:上次|上回|之前|以前).{0,12}(?:不是|是不是|已经).{0,8}(?:做|写|实现|处理)/,/(?:参考|参照|照着|按照).{0,6}(?:项目|工程|仓库)/,/(?:那个|那边|另一个).{0,6}(?:项目|工程).{0,6}(?:里|中|的)/,/(?:跟|和|像).{0,6}(?:项目|工程).{0,6}(?:一样|类似|差不多)/,/(?:复用|重用|搬过来|拿过来|移过来|copy过来)/],t=[/(?:有没有|有无|是否有).{0,6}(?:技能|skill|模板|template|现成的)/,/(?:能不能|可以).{0,6}(?:自动|像之前|快速).{0,6}(?:生成|创建|写|做)/,/(?:跟|和|类似|像).{0,4}(?:上次|之前|其他|那个).{0,4}(?:一样|类似)/,/(?:批量|自动化|一键).{0,6}(?:生成|创建|部署|处理)/,/(?:同样的|相同的|一样的).{0,4}(?:方式|方法|流程|步骤)/],r=[/(?:before|previously|earlier|last time).{0,20}(?:did|done|made|built|implemented|wrote)/i,/(?:didn't|did) you.{0,15}(?:already|before|earlier)/i,/(?:same|similar).{0,10}(?:as|to|like).{0,10}(?:project|repo)/i,/(?:reuse|re-use|copy from|bring over|port from).{0,15}(?:project|repo)/i,/(?:remember|recall).{0,10}(?:doing|making|building|writing)/i,/(?:other|another|different)\s+project/i],s=[/(?:is there|do you have|any).{0,10}(?:skill|template|automation|workflow)/i,/(?:like|similar to|same as).{0,15}(?:last time|before|the other)/i,/(?:automate|batch|bulk).{0,10}(?:create|generate|process|build)/i,/(?:can you|could you).{0,10}(?:do the same|repeat|replicate)/i];if(![...e,...t,...r,...s].some(c=>c.test(n)))return null;let a=LS(n);return a.length>0?a:null}function LS(n){let t=n.replace(/之前|以前|上次|上回|不是|是不是|已经|做过|写过|实现过|处理过|用过|搞过|弄过/g," ").replace(/参考|参照|照着|按照|项目|工程|仓库|那个|那边|另一个|里|中|的|跟|和|像|一样|类似|差不多/g," ").replace(/复用|重用|搬过来|拿过来|移过来/g," ").replace(/\b(the|a|an|is|was|were|did|didn't|do|you|i|we|it|this|that|before|previously|earlier|last|time|already|same|similar|as|to|like|from|project|repo|remember|recall|doing|making|building|writing|other|another|different)\b/gi," ").trim().split(/[\s,;.!?,。!?、;:""''()\[\]{}]+/).filter(r=>r.length>=2).map(r=>r.toLowerCase());return[...new Set(t)].slice(0,8)}var ls=null,da=0;function $S(n){let e=Date.now();if(ls&&e-da<ds.CACHE_TTL_MS)return ls;let t=[],r=me().map(o=>o.workspaceDir).filter(Boolean),s=Id(r,n);for(let o of s){let i=ir.join(o,".qlogicagent","skills");try{let a=us.readdirSync(i,{withFileTypes:!0});for(let c of a){if(!c.isDirectory())continue;let l=ir.join(i,c.name,"SKILL.md");try{let d=us.readFileSync(l,"utf8"),u=d.split(`
|
|
144
|
+
`).slice(0,5).join(" ").toLowerCase();t.push({name:c.name,projectDir:o,projectName:ir.basename(o),content:d,searchText:`${c.name.toLowerCase()} ${u}`})}catch{}}}catch{}}return ls=t,da=e,t}function jS(n,e){if(n.length===0)return[];let t=$S(e);return t.length===0?[]:t.map(s=>{let o=0;for(let i of n)s.searchText.includes(i)&&(o+=2),s.name.includes(i)&&(o+=3);return{skill:s,score:o}}).filter(s=>s.score>0).sort((s,o)=>o.score-s.score).slice(0,ds.MAX_RECALLED_SKILLS).map(s=>s.skill)}function ku(n,e){return n.register({point:"memory.before_recall",priority:60,label:"cross-project-skill-recall",handler:(r,s)=>{let o=s.query;if(!o)return{action:"continue",context:s};let i=OS(o);if(!i)return{action:"continue",context:s};e.log.debug(`skill-recall: retrospective trigger detected, keywords: [${i.join(", ")}]`);let a=jS(i,e.currentCwd);if(a.length===0)return e.log.debug("skill-recall: no cross-project skill matches found"),{action:"continue",context:s};e.log.debug(`skill-recall: found ${a.length} cross-project skill(s): ${a.map(d=>`${d.name}@${d.projectName}`).join(", ")}`);let c=s.recalledMemories??[],l=a.map(d=>{let u=d.content.length>ds.MAX_SKILL_CONTENT_CHARS?d.content.slice(0,ds.MAX_SKILL_CONTENT_CHARS)+`
|
|
145
145
|
...(truncated)`:d.content;return{text:[`[Cross-project skill available] Skill "${d.name}" learned in project "${d.projectName}" (${d.projectDir}):`,u,`\u2192 To use this skill in current project: use skill tool with action "create" name "${d.name}" and copy the content above`,`\u2192 After creating locally, promote to global: skill tool with action "promote" name "${d.name}"`,"\u2192 Or just follow the instructions above directly without saving"].join(`
|
|
146
146
|
`),source:"skill",label:"Skill",score:.85}});return{action:"continue",context:{...s,recalledMemories:[...c,...l]}}}})}function pt(){ls=null,da=0}import{isDebugTransportEnabled as J_,createDebugTransport as Q_}from"@xiaozhiclaw/provider-core";import{createRequire as QS}from"node:module";ae();import*as ms from"node:fs";import*as pa from"node:path";import{randomUUID as ar}from"node:crypto";var US=`
|
|
147
147
|
CREATE TABLE IF NOT EXISTS memories (
|
|
@@ -288,7 +288,7 @@ END;
|
|
|
288
288
|
SELECT id, text, category, importance, tags, created_at, access_count, embedding
|
|
289
289
|
FROM memories
|
|
290
290
|
WHERE user_id = ? AND is_archived = 0 AND embedding IS NOT NULL
|
|
291
|
-
`).all(t),i=[],a=
|
|
291
|
+
`).all(t),i=[],a=Tu(e);for(let c of o){let l=new Float32Array(c.embedding.buffer,c.embedding.byteOffset,c.embedding.byteLength/4),d=Tu(l),u=HS(a,d);u>=s&&i.push({id:c.id,text:c.text,score:u*.7+c.importance*.3,category:c.category,importance:c.importance,metadata:{tags:JSON.parse(c.tags||"[]"),createdAt:c.created_at,accessCount:c.access_count,cosineSimilarity:u}})}return i.sort((c,l)=>l.score-c.score),i.slice(0,r)}searchHybrid(e,t,r,s=10){let o=this.searchFts(e,r,s*2);if(!t)return o.slice(0,s);let i=this.searchVector(t,r,s*2),a=new Map;for(let c of o)a.set(c.id,c);for(let c of i){let l=a.get(c.id);(!l||c.score>l.score)&&a.set(c.id,c)}return Array.from(a.values()).sort((c,l)=>l.score-c.score).slice(0,s)}listByUser(e,t=1,r=50,s=!0){let o=(t-1)*r,i=s?"AND is_archived = 0":"";return this.db.prepare(`
|
|
292
292
|
SELECT * FROM memories
|
|
293
293
|
WHERE user_id = ? ${i}
|
|
294
294
|
ORDER BY created_at DESC
|
|
@@ -460,12 +460,12 @@ END;
|
|
|
460
460
|
SELECT * FROM memory_claims
|
|
461
461
|
WHERE user_id = ?
|
|
462
462
|
ORDER BY updated_at DESC
|
|
463
|
-
`).all(e)).map(
|
|
463
|
+
`).all(e)).map(Su)}findClaimsByFact(e,t,r,s=""){return this.db.prepare(`
|
|
464
464
|
SELECT * FROM memory_claims
|
|
465
465
|
WHERE user_id = ? AND entity = ? AND predicate = ? AND valid_time = ?
|
|
466
466
|
AND status IN ('active', 'pending_confirmation', 'conflicted')
|
|
467
467
|
ORDER BY updated_at DESC
|
|
468
|
-
`).all(e,t,r,s).map(
|
|
468
|
+
`).all(e,t,r,s).map(Su)}mergeClaimEvidence(e,t,r,s){let o=this.db.prepare("SELECT evidence_ids FROM memory_claims WHERE id = ?").get(e);if(!o)return!1;let i=Ru(o.evidence_ids),a=Array.from(new Set([...i,...t]));return this.db.prepare(`
|
|
469
469
|
UPDATE memory_claims
|
|
470
470
|
SET evidence_ids = ?, confidence = MAX(confidence, ?), importance = MAX(importance, ?), updated_at = ?
|
|
471
471
|
WHERE id = ?
|
|
@@ -478,41 +478,41 @@ END;
|
|
|
478
478
|
SELECT * FROM memory_conflicts
|
|
479
479
|
WHERE user_id = ?
|
|
480
480
|
ORDER BY updated_at DESC
|
|
481
|
-
`).all(e).map(FS)}close(){this.db.close()}};function ua(n){return{id:n.id,text:n.text,userId:n.user_id,category:n.category,importance:n.importance,confidence:n.confidence??1,source:n.source,sessionId:n.session_id,eventDate:n.event_date,tags:JSON.parse(n.tags||"[]"),embedding:n.embedding?new Float32Array(n.embedding.buffer,n.embedding.byteOffset,n.embedding.byteLength/4):null,createdAt:n.created_at,updatedAt:n.updated_at,accessCount:n.access_count,lastAccessedAt:n.last_accessed_at,isArchived:!!n.is_archived}}function ku(n){return{id:n.id,memoryId:n.memory_id??"",userId:n.user_id,entity:n.entity??"",predicate:n.predicate??"",value:BS(n.value_json),text:n.text,category:n.category,importance:n.importance,confidence:n.confidence,source:n.source,sourcePriority:n.source_priority,status:n.status,validTime:n.valid_time??"",evidenceIds:Tu(n.evidence_ids),supersedesClaimId:n.supersedes_claim_id??"",conflictGroupId:n.conflict_group_id??"",createdAt:n.created_at,updatedAt:n.updated_at}}function FS(n){return{id:n.id,userId:n.user_id,claimAId:n.claim_a_id,claimBId:n.claim_b_id,reason:n.reason,status:n.status,createdAt:n.created_at,updatedAt:n.updated_at}}function BS(n){if(!n)return{};try{let e=JSON.parse(n);return e&&typeof e=="object"&&!Array.isArray(e)?e:{}}catch{return{}}}function Tu(n){if(!n)return[];try{let e=JSON.parse(n);return Array.isArray(e)?e.filter(t=>typeof t=="string"):[]}catch{return[]}}function Su(n){let e=0;for(let r=0;r<n.length;r++)e+=n[r]*n[r];if(e=Math.sqrt(e),e===0)return n;let t=new Float32Array(n.length);for(let r=0;r<n.length;r++)t[r]=n[r]/e;return t}function HS(n,e){let t=0,r=Math.min(n.length,e.length);for(let s=0;s<r;s++)t+=n[s]*e[s];return t}function Ru(){let n=pa.join(q(),"memory");return ms.existsSync(n)||ms.mkdirSync(n,{recursive:!0}),pa.join(n,"memories.db")}var ma=class{dimensions=0;model="none";async embed(e){return new Float32Array(0)}async embedBatch(e){return e.map(()=>new Float32Array(0))}},ga=class{dimensions;model;baseUrl;apiKey;timeoutMs;format;constructor(e){this.baseUrl=e.baseUrl.replace(/\/$/,""),this.apiKey=e.apiKey,this.model=e.model,this.dimensions=e.dimensions??1536,this.timeoutMs=e.timeoutMs??1e4,this.format=e.format??"openai"}async embed(e){return(await this.embedBatch([e]))[0]}async embedBatch(e){if(e.length===0)return[];let t=new AbortController,r=setTimeout(()=>t.abort(),this.timeoutMs);try{let{url:s,body:o}=this.buildRequest(e),i=await fetch(s,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.apiKey}`},body:JSON.stringify(o),signal:t.signal});if(!i.ok){let c=await i.text().catch(()=>"");throw new Error(`Embedding API error [${this.format}]: ${i.status} ${i.statusText}${c?` \u2014 ${c.slice(0,200)}`:""}`)}let a=await i.json();return this.parseResponse(a,e.length)}finally{clearTimeout(r)}}buildRequest(e){switch(this.format){case"minimax":return{url:`${this.baseUrl}/v1/embeddings`,body:{model:this.model,texts:e,type:"db"}};case"volcengine":return{url:`${this.baseUrl}/v1/embeddings/multimodal`,body:{model:this.model,input:e.map(t=>({type:"text",text:t})),dimensions:this.dimensions}};default:return{url:`${this.baseUrl}/v1/embeddings`,body:{model:this.model,input:e,dimensions:this.dimensions}}}}parseResponse(e,t){switch(this.format){case"minimax":{let r=e.vectors;if(!r||r.length===0)throw new Error("MiniMax embedding returned empty vectors");return r.map(s=>new Float32Array(s))}case"volcengine":{let r=e.data;if(Array.isArray(r))return r.map(s=>new Float32Array(s.embedding));if(r?.embedding)return[new Float32Array(r.embedding)];throw new Error("Volcengine embedding returned unexpected structure")}default:{let r=e.data;if(!r||r.length===0)throw new Error("OpenAI embedding returned empty data");return r.sort((o,i)=>o.index-i.index).map(o=>new Float32Array(o.embedding))}}}};function Au(n){return n?.api?new ga(n.api):new ma}var qS={qwen:{format:"openai",baseUrl:"https://dashscope.aliyuncs.com/compatible-mode",defaultModel:"text-embedding-v3",defaultDimensions:1024},zhipu:{format:"openai",baseUrl:"https://open.bigmodel.cn/api/paas",defaultModel:"embedding-3",defaultDimensions:2048},minimax:{format:"minimax",baseUrl:"https://api.minimax.chat",defaultModel:"embo-01",defaultDimensions:1024},volcengine:{format:"volcengine",baseUrl:"https://ark.cn-beijing.volces.com/api",defaultModel:"doubao-embedding-vision-251215",defaultDimensions:1024},openai:{format:"openai",baseUrl:"https://api.openai.com",defaultModel:"text-embedding-3-small",defaultDimensions:1536},google:{format:"openai",baseUrl:"https://generativelanguage.googleapis.com",defaultModel:"text-embedding-004",defaultDimensions:768},deepseek:{format:"openai",baseUrl:"https://api.deepseek.com",defaultModel:"text-embedding-v1",defaultDimensions:1024}};function wu(n,e,t){let r=qS[n.toLowerCase()];return r?{baseUrl:t?.baseUrl||r.baseUrl,apiKey:e,model:t?.model||r.defaultModel,dimensions:t?.dimensions||r.defaultDimensions,format:r.format}:null}var WS={observationsAdded:0,proposalsAdded:0,claimsAdded:0,conflictsAdded:0,memoriesAdded:0,observationIds:[],proposalIds:[],claimIds:[],conflictIds:[]},hs=class{constructor(e,t){this.store=e;this.embed=t}store;embed;async observe(e,t,r){let s=fs(r?.source),o=cr(s),i=ha();for(let a of e){let c=a.text?.trim();if(!c)continue;let l=this.store.insertObservation({userId:t,text:c,source:s,sourcePriority:o,sessionId:r?.sessionId??"",evidenceType:"text",payload:{category:a.category,importance:a.importance,tags:a.tags??[]}});i.observationsAdded++,i.observationIds.push(l)}return i}async proposeExtracted(e,t,r){let s=fs(r?.source),o=cr(s),i=ha();for(let a of e){let c=a.text?.trim();if(!c)continue;let l=this.store.insertObservation({userId:t,text:c,source:s,sourcePriority:o,sessionId:r?.sessionId??"",evidenceType:"text",payload:{category:a.category,importance:a.importance,eventDate:a.event_date,tags:a.tags??[]}});i.observationsAdded++,i.observationIds.push(l);let d=xu(c,a,s),u=this.store.insertProposal({userId:t,observationIds:[l],text:c,category:a.category??"general",importance:jt(a.importance??.5,.1,1),confidence:d.confidence,source:s,sourcePriority:o,entity:d.entity,predicate:d.predicate,value:d.value,validTime:d.validTime,tags:a.tags??[],status:"pending"});i.proposalsAdded++,i.proposalIds.push(u)}return i}async commitExtracted(e,t,r){let s=fs(r?.source),o=cr(s),i=ha();for(let a of e){let c=a.text?.trim();if(!c)continue;let l=this.store.insertObservation({userId:t,text:c,source:s,sourcePriority:o,sessionId:r?.sessionId??"",evidenceType:"text",payload:{category:a.category,importance:a.importance,eventDate:a.event_date,tags:a.tags??[]}});i.observationsAdded++,i.observationIds.push(l);let d=xu(c,a,s),u=this.store.insertProposal({userId:t,observationIds:[l],text:c,category:a.category??"general",importance:jt(a.importance??.5,.1,1),confidence:d.confidence,source:s,sourcePriority:o,entity:d.entity,predicate:d.predicate,value:d.value,validTime:d.validTime,tags:a.tags??[],status:"pending"});i.proposalsAdded++,i.proposalIds.push(u);let p=this.store.findClaimsByFact(t,d.entity,d.predicate,d.validTime),m=p.find(k=>XS(k.value,d.value));if(m){this.store.mergeClaimEvidence(m.id,[l],Math.max(m.confidence,d.confidence),jt(a.importance??m.importance,.1,1)),this.store.updateProposalStatus(u,"merged",[m.id]),i.claimIds.push(m.id);continue}let h=p.find(k=>k.status==="active"||k.status==="pending_confirmation");if(h){let k=this.store.insertClaim({userId:t,entity:d.entity,predicate:d.predicate,value:d.value,text:c,category:a.category??"general",importance:jt(a.importance??.5,.1,1),confidence:d.confidence,source:s,sourcePriority:o,status:"conflicted",validTime:d.validTime,evidenceIds:[l]}),A=this.store.insertConflict({userId:t,claimAId:h.id,claimBId:k,reason:`same entity + same predicate + different value: ${d.entity}.${d.predicate}`});this.store.updateProposalStatus(u,"conflicted",[h.id,k]),i.claimsAdded++,i.conflictsAdded++,i.claimIds.push(k),i.conflictIds.push(A);continue}let f=GS(s,d.confidence),y=f==="active"?this.store.insert({text:c,userId:t,category:a.category??"general",importance:jt(a.importance??.5,.1,1),confidence:d.confidence,source:s,sessionId:r?.sessionId??"",eventDate:a.event_date??"",tags:a.tags??[],embedding:await this.embed(c)}):"",b=this.store.insertClaim({userId:t,memoryId:y,entity:d.entity,predicate:d.predicate,value:d.value,text:c,category:a.category??"general",importance:jt(a.importance??.5,.1,1),confidence:d.confidence,source:s,sourcePriority:o,status:f,validTime:d.validTime,evidenceIds:[l]});this.store.updateProposalStatus(u,f==="active"?"accepted":"pending",[b]),i.claimsAdded++,i.memoriesAdded+=y?1:0,i.claimIds.push(b)}return i}};function cr(n){let e=fs(n);return e==="manual"||e==="user_edit"?100:e==="explicit"||e==="agent-remember"||e==="agent"?90:e==="document"||e==="image"||e==="video"?70:e==="auto"||e==="turn"?45:e==="dream"||e==="dream-consolidation"||e==="profile-extraction"?20:40}function GS(n,e){return cr(n)>=45&&e>=.55?"active":"pending_confirmation"}function xu(n,e,t){let r=JS(n),s=(e.tags??[]).join(" "),o=KS(n,s),i=VS(n);if(i)return{entity:o,predicate:"contract_amount",value:i,validTime:Iu(e.event_date),confidence:fa(t,.92)};let a=zS(n);if(a)return{entity:o,predicate:"progress_update_schedule",value:a,validTime:"",confidence:fa(t,.86)};let c=YS(e.category??"general");return{entity:o,predicate:c,value:{text:r},validTime:Iu(e.event_date),confidence:fa(t,.7)}}function fa(n,e){let t=cr(n);return t>=90?jt(e+.04,.1,.99):t<=20?jt(e-.18,.1,.95):jt(e,.1,.98)}function KS(n,e){let t=`${n} ${e}`;if(/Galaxy\s*Tech|Galaxy/i.test(t))return"Galaxy Tech";let r=t.match(/\b[A-Z][A-Za-z0-9]*(?:\s+[A-Z][A-Za-z0-9]*){0,3}\b/);if(r?.[0])return r[0].trim();let s=t.match(/([\u4e00-\u9fa5A-Za-z0-9]{2,18})(?:公司|客户|合同|项目)/);return s?.[1]?s[1]:"user"}function VS(n){if(!/(合同|contract)/i.test(n))return null;let e=n.match(/(\d+(?:\.\d+)?)\s*k\b/i);if(e)return{amount:Math.round(Number(e[1])*1e3),currency:gs(n)};let t=n.match(/(\d+(?:\.\d+)?)\s*万/);if(t)return{amount:Math.round(Number(t[1])*1e4),currency:gs(n)};let r=n.match(/(?:金额|amount)[^\d]*(\d{5,})/i);return r?{amount:Number(r[1]),currency:gs(n)}:/一十八万/.test(n)?{amount:18e4,currency:gs(n)}:null}function zS(n){if(!/(提醒|进展|更新|progress|schedule|每周)/i.test(n))return null;let e=/周一|星期一|Monday/i.test(n)?"monday":/周二|星期二|Tuesday/i.test(n)?"tuesday":/周三|星期三|Wednesday/i.test(n)?"wednesday":/周四|星期四|Thursday/i.test(n)?"thursday":/周五|星期五|Friday/i.test(n)?"friday":/周六|星期六|Saturday/i.test(n)?"saturday":/周日|周天|星期日|星期天|Sunday/i.test(n)?"sunday":"";if(!e)return null;let t=n.match(/(?:上午|早上)?\s*(\d{1,2})\s*点/);return{cadence:"weekly",weekday:e,hour:t?Number(t[1]):null}}function XS(n,e){return Pu(n)===Pu(e)}function Pu(n){let e=Object.keys(n).sort();return JSON.stringify(e.reduce((t,r)=>(t[r]=n[r],t),{}))}function gs(n){return/[¥¥]|人民币|CNY/i.test(n)?"CNY":/\$|USD/i.test(n)?"USD":"unknown"}function YS(n){return n.trim().toLowerCase().replace(/[^a-z0-9_\-\u4e00-\u9fa5]+/g,"_")||"general"}function Iu(n){if(!n)return"";let e=new Date(n);return Number.isNaN(e.getTime())?"":`${e.getUTCFullYear()}-${String(e.getUTCMonth()+1).padStart(2,"0")}`}function JS(n){return n.trim().replace(/\s+/g," ").toLowerCase()}function fs(n){return n?.trim()||"agent"}function jt(n,e,t){return Number.isFinite(n)?Math.max(e,Math.min(t,n)):e}function ha(){return{...WS,observationIds:[],proposalIds:[],claimIds:[],conflictIds:[]}}var _u="qmemory-local",ba=class{providerId=_u;store;embedding;consolidator;userIdPrefix;dbPath;constructor(e){if(this.dbPath=Ru(),this.userIdPrefix=e.userIdPrefix??"",this.embedding=Au(e.embedding),!e.createDatabase)throw new Error("LocalMemoryProvider requires a createDatabase factory. Install better-sqlite3 and pass: (path) => new Database(path)");let t=e.createDatabase(this.dbPath);this.store=new ps(t),this.consolidator=new hs(this.store,r=>this.buildEmbedding(r))}resolveUserId(e){return this.userIdPrefix?`${this.userIdPrefix}:${e}`:e}async buildEmbedding(e){if(this.embedding.dimensions!==0)try{let t=await this.embedding.embed(e);return t.length?t:void 0}catch{return}}async search(e,t,r){let s=this.resolveUserId(t),o=r?.limit??10,i=r?.minScore??.1,a=null;if(this.embedding.dimensions>0)try{a=await this.embedding.embed(e)}catch{}let c=Math.min(o*3,50),l=this.store.searchHybrid(e,a,s,c),d=this.rerank(l.map(u=>({id:u.id,text:u.text,score:u.score,category:u.category,metadata:{...u.metadata,createdAt:u.metadata?.createdAt,accessCount:u.metadata?.accessCount}})),{preferredCategories:r?.preferredCategories});for(let u of d.slice(0,3))this.store.recordAccess(u.id);return d.filter(u=>u.score>=i).slice(0,o).map(u=>({blockId:u.id,text:u.text,score:u.score,source:_u,metadata:u.metadata}))}async ingest(e,t,r){let s=this.resolveUserId(t),o=e.filter(i=>i.content?.trim()&&i.content.trim().length>=10).map(i=>({text:i.content,category:"conversation",importance:.4}));await this.consolidator.observe(o,s,{source:r?.source??"turn",sessionId:r?.sessionId??""})}async addText(e,t,r){return this.ingestExtracted([{text:e,category:r?.category??"fact",importance:r?.importance??.6}],t,{...r,source:r?.source??"agent",sessionId:r?.sessionId??""})}async remove(e){return this.store.updateClaimsByMemoryId(e,"archived"),this.store.delete(e)}async update(e,t){let r=this.store.getById(e);if(!r)return!1;let s=t.text?.trim(),o=s&&s!==r.text?await this.buildEmbedding(s):void 0,i=this.store.update(e,{...t,text:s||void 0,embedding:o});return i&&this.store.updateClaimsByMemoryId(e,"superseded"),i}async ingestExtracted(e,t,r){if(e.length===0)return ya();let s=this.resolveUserId(t);return this.consolidator.commitExtracted(e,s,{source:r?.source??"agent",sessionId:r?.sessionId??""})}async observeExtracted(e,t,r){return e.length===0?ya():this.consolidator.observe(e,this.resolveUserId(t),{source:r?.source??"agent",sessionId:r?.sessionId??""})}async proposeExtracted(e,t,r){return e.length===0?ya():this.consolidator.proposeExtracted(e,this.resolveUserId(t),{source:r?.source??"agent",sessionId:r?.sessionId??""})}listClaims(e){return this.store.listClaims(this.resolveUserId(e))}listConflicts(e){return this.store.listConflicts(this.resolveUserId(e))}async triggerDecay(e,t=90){let r=this.resolveUserId(e),s=this.store.runFullDecay(r),o=this.store.enforceCapacityLimit(r,1e4);return s.total+o>10&&(this.store.exportAndPurgeArchived(r,200),this.store.vacuum()),{decayed:s.total+o}}async feedback(e,t){let r=0;for(let s of e)this.store.applyFeedback(s,t)&&r++;return{affected:r}}getProfile(e,t){return this.store.getProfile(this.resolveUserId(e),t)}setProfile(e,t,r){this.store.setProfile(this.resolveUserId(e),t,r)}getAllProfiles(e){return this.store.getAllProfiles(this.resolveUserId(e))}deleteProfile(e,t){return this.store.deleteProfile(this.resolveUserId(e),t)}getTemporalSlice(e,t,r,s){return this.store.getTemporalSlice(this.resolveUserId(e),t,r,s)}getActivitySummary(e,t=7){return this.store.getActivitySummary(this.resolveUserId(e),t)}list(e,t){return this.store.listByUser(this.resolveUserId(e),t?.page??1,t?.pageSize??500,t?.activeOnly??!0)}getAtlas(e,t){return this.store.getAtlas(this.resolveUserId(e),t)}findByEventDate(e,t,r=1){return this.store.findByEventDate(this.resolveUserId(e),t,r)}async findRelatedEvents(e,t,r){let s=this.resolveUserId(t),o=r?.minSimilarity??.55,i=r?.maxSimilarity??.82,a=r?.maxDaysBack??14,c=r?.limit??5;if(this.embedding.dimensions===0)return[];let l;try{l=await this.embedding.embed(e)}catch{return[]}let d=this.store.searchVector(l,s,c*3,o),u=Date.now()-a*864e5;return d.filter(p=>{let m=p.metadata?.cosineSimilarity??p.score,h=p.metadata?.createdAt??0;return m>=o&&m<i&&h>=u}).slice(0,c).map(p=>({id:p.id,text:p.text,score:p.metadata?.cosineSimilarity??p.score,date:new Date(p.metadata?.createdAt??Date.now()).toISOString().slice(0,10)}))}synthesizeTimeline(e,t,r){let s=this.getTemporalSlice(e,t,r);if(s.length===0)return"No memories in this time range.";let o=[];for(let i of s){o.push(`## ${i.date}`);for(let a of i.memories){let c=a.importance>=.7?"*":"-";o.push(`${c} [${a.category}] ${a.text}`)}}return o.join(`
|
|
482
|
-
`)}rerank(e,t){let r=(t?.recencyBoostDays??7)*864e5,s=Date.now(),o=new Set(t?.preferredCategories??[]);return e.map(i=>{let a=i.score,c=i.metadata?.createdAt??0;if(c>0){let d=s-c;d<r&&(a+=.1*(1-d/r))}let l=i.metadata?.accessCount??0;return l>0&&(a+=Math.min(.05,l*.01)),o.size>0&&i.category&&o.has(i.category)&&(a+=.08),{...i,score:Math.min(1,a)}}).sort((i,a)=>a.score-i.score)}async health(){return{status:"healthy",memoryCount:0,dbPath:this.dbPath}}count(e){return this.store.count(this.resolveUserId(e))}async resetUser(e){return this.store.resetUser(this.resolveUserId(e))}close(){this.store.close()}};function
|
|
483
|
-
`;return await de.promises.appendFile(Ve.join(s,
|
|
484
|
-
`))if(u.trim())try{let p=JSON.parse(u);o.push({role:p.role,content:p.content??null})}catch{i++}i>0&&console.warn(`[session-persistence] ${i} corrupt line(s) skipped in ${r}`)}catch{return null}if(o.length===0&&i>0)return console.error(`[session-persistence] Transcript fully corrupt for session ${n}`),null;let a=new Date().toISOString(),c={sessionId:n,projectId:"",createdAt:a,lastActiveAt:a,turnCount:0,messageCount:o.length};try{let d=await de.promises.readFile(s,"utf8");c=JSON.parse(d)}catch{}let l=o.filter(d=>d.role!=="system");return{metadata:c,messages:l}}async function At(n=gi,e){let t=Ot(e),r;try{r=await de.promises.readdir(t)}catch{return[]}let s=[];for(let o of r){let i=Ve.join(t,o,Ut);try{let a=await de.promises.readFile(i,"utf8"),c=JSON.parse(a);s.push({sessionId:c.sessionId,title:c.title,lastActiveAt:c.lastActiveAt,messageCount:c.messageCount,model:c.model,pinnedAt:c.pinnedAt,archivedAt:c.archivedAt,sealedAt:c.sealedAt,projectId:c.projectId,type:c.type,createdAt:c.createdAt,groupKey:c.groupKey,previousSessionId:c.previousSessionId})}catch{}}return s.sort((o,i)=>o.lastActiveAt>i.lastActiveAt?-1:o.lastActiveAt<i.lastActiveAt?1:0),s.slice(0,n)}async function Ra(n,e){let t=Pn(n,e);await de.promises.rm(t,{recursive:!0,force:!0})}function rT(n){return n.turnCount<fi?!1:n.taskSummaryGeneratedAt?n.turnCount-(n.taskSummaryGeneratedAt??0)>=hi:!0}var sT="Based on the user's message below, generate a very short session title (2-8 Chinese characters or 3-6 English words). The title should capture the main topic or intent. Reply with ONLY the title text, no quotes, no punctuation.";async function
|
|
485
|
-
`),a=r.transport.stream({model:r.model,messages:[{role:"system",content:"Generate a concise task summary (~100 words) of what the user is working on in this session. Focus on the goal, key decisions, and current progress. Reply with ONLY the summary."},{role:"user",content:i}],tools:[],maxTokens:200},r.apiKey),c="";for await(let u of a)u.type==="delta"&&(c+=u.text);if(c=c.trim(),!c)return null;let l=Pn(n,s),d=Ve.join(l,Ut);try{let u=await de.promises.readFile(d,"utf8"),p=JSON.parse(u);p.taskSummary=c,p.taskSummaryGeneratedAt=e.turnCount;let m=d+".tmp";await de.promises.writeFile(m,JSON.stringify(p,null,2),"utf8"),await de.promises.rename(m,d)}catch{}return c}catch{return null}}ra();import{randomUUID as NM}from"node:crypto";var oT=3e4;var bs=class{tasks=new Map;listeners=new Set;hooks=null;sessionId="";setHooks(e,t){this.hooks=e,this.sessionId=t}onTaskChange(e){return this.listeners.add(e),()=>this.listeners.delete(e)}notify(e,t){for(let r of this.listeners)try{r(e,t)}catch{}}registerTask(e){this.tasks.set(e.taskId,e),this.notify(e.taskId,e),this.hooks?.invoke("task.created",{sessionId:this.sessionId,taskId:e.taskId,taskType:e.type,label:e.label}).catch(()=>{})}updateTask(e,t){let r=this.tasks.get(e);if(!r)return;let s=t(r);s!==r&&(this.tasks.set(e,s),this.notify(e,s),!ys(r.lifecycle)&&ys(s.lifecycle)&&this.hooks?.invoke("task.completed",{sessionId:this.sessionId,taskId:s.taskId,taskType:s.type,label:s.label}).catch(()=>{}))}getTask(e){return this.tasks.get(e)}getRunningTasks(){return[...this.tasks.values()].filter(e=>e.lifecycle==="running")}getAllTasks(){return[...this.tasks.values()]}evictTask(e){let t=this.tasks.get(e);t&&ys(t.lifecycle)&&(this.tasks.delete(e),this.notify(e,null))}evictStaleTasks(e=oT){let t=Date.now();for(let[r,s]of this.tasks)ys(s.lifecycle)&&s.endedAt&&t-s.endedAt>e&&(this.tasks.delete(r),this.notify(r,null))}};function ys(n){return n==="completed"||n==="failed"||n==="cancelled"||n==="timeout"}ae();import{watch as iT}from"node:fs";import{stat as aT}from"node:fs/promises";import{join as
|
|
481
|
+
`).all(e).map(FS)}close(){this.db.close()}};function ua(n){return{id:n.id,text:n.text,userId:n.user_id,category:n.category,importance:n.importance,confidence:n.confidence??1,source:n.source,sessionId:n.session_id,eventDate:n.event_date,tags:JSON.parse(n.tags||"[]"),embedding:n.embedding?new Float32Array(n.embedding.buffer,n.embedding.byteOffset,n.embedding.byteLength/4):null,createdAt:n.created_at,updatedAt:n.updated_at,accessCount:n.access_count,lastAccessedAt:n.last_accessed_at,isArchived:!!n.is_archived}}function Su(n){return{id:n.id,memoryId:n.memory_id??"",userId:n.user_id,entity:n.entity??"",predicate:n.predicate??"",value:BS(n.value_json),text:n.text,category:n.category,importance:n.importance,confidence:n.confidence,source:n.source,sourcePriority:n.source_priority,status:n.status,validTime:n.valid_time??"",evidenceIds:Ru(n.evidence_ids),supersedesClaimId:n.supersedes_claim_id??"",conflictGroupId:n.conflict_group_id??"",createdAt:n.created_at,updatedAt:n.updated_at}}function FS(n){return{id:n.id,userId:n.user_id,claimAId:n.claim_a_id,claimBId:n.claim_b_id,reason:n.reason,status:n.status,createdAt:n.created_at,updatedAt:n.updated_at}}function BS(n){if(!n)return{};try{let e=JSON.parse(n);return e&&typeof e=="object"&&!Array.isArray(e)?e:{}}catch{return{}}}function Ru(n){if(!n)return[];try{let e=JSON.parse(n);return Array.isArray(e)?e.filter(t=>typeof t=="string"):[]}catch{return[]}}function Tu(n){let e=0;for(let r=0;r<n.length;r++)e+=n[r]*n[r];if(e=Math.sqrt(e),e===0)return n;let t=new Float32Array(n.length);for(let r=0;r<n.length;r++)t[r]=n[r]/e;return t}function HS(n,e){let t=0,r=Math.min(n.length,e.length);for(let s=0;s<r;s++)t+=n[s]*e[s];return t}function Au(){let n=pa.join(q(),"memory");return ms.existsSync(n)||ms.mkdirSync(n,{recursive:!0}),pa.join(n,"memories.db")}var ma=class{dimensions=0;model="none";async embed(e){return new Float32Array(0)}async embedBatch(e){return e.map(()=>new Float32Array(0))}},ga=class{dimensions;model;baseUrl;apiKey;timeoutMs;format;constructor(e){this.baseUrl=e.baseUrl.replace(/\/$/,""),this.apiKey=e.apiKey,this.model=e.model,this.dimensions=e.dimensions??1536,this.timeoutMs=e.timeoutMs??1e4,this.format=e.format??"openai"}async embed(e){return(await this.embedBatch([e]))[0]}async embedBatch(e){if(e.length===0)return[];let t=new AbortController,r=setTimeout(()=>t.abort(),this.timeoutMs);try{let{url:s,body:o}=this.buildRequest(e),i=await fetch(s,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.apiKey}`},body:JSON.stringify(o),signal:t.signal});if(!i.ok){let c=await i.text().catch(()=>"");throw new Error(`Embedding API error [${this.format}]: ${i.status} ${i.statusText}${c?` \u2014 ${c.slice(0,200)}`:""}`)}let a=await i.json();return this.parseResponse(a,e.length)}finally{clearTimeout(r)}}buildRequest(e){switch(this.format){case"minimax":return{url:`${this.baseUrl}/v1/embeddings`,body:{model:this.model,texts:e,type:"db"}};case"volcengine":return{url:`${this.baseUrl}/v1/embeddings/multimodal`,body:{model:this.model,input:e.map(t=>({type:"text",text:t})),dimensions:this.dimensions}};default:return{url:`${this.baseUrl}/v1/embeddings`,body:{model:this.model,input:e,dimensions:this.dimensions}}}}parseResponse(e,t){switch(this.format){case"minimax":{let r=e.vectors;if(!r||r.length===0)throw new Error("MiniMax embedding returned empty vectors");return r.map(s=>new Float32Array(s))}case"volcengine":{let r=e.data;if(Array.isArray(r))return r.map(s=>new Float32Array(s.embedding));if(r?.embedding)return[new Float32Array(r.embedding)];throw new Error("Volcengine embedding returned unexpected structure")}default:{let r=e.data;if(!r||r.length===0)throw new Error("OpenAI embedding returned empty data");return r.sort((o,i)=>o.index-i.index).map(o=>new Float32Array(o.embedding))}}}};function wu(n){return n?.api?new ga(n.api):new ma}var qS={qwen:{format:"openai",baseUrl:"https://dashscope.aliyuncs.com/compatible-mode",defaultModel:"text-embedding-v3",defaultDimensions:1024},zhipu:{format:"openai",baseUrl:"https://open.bigmodel.cn/api/paas",defaultModel:"embedding-3",defaultDimensions:2048},minimax:{format:"minimax",baseUrl:"https://api.minimax.chat",defaultModel:"embo-01",defaultDimensions:1024},volcengine:{format:"volcengine",baseUrl:"https://ark.cn-beijing.volces.com/api",defaultModel:"doubao-embedding-vision-251215",defaultDimensions:1024},openai:{format:"openai",baseUrl:"https://api.openai.com",defaultModel:"text-embedding-3-small",defaultDimensions:1536},google:{format:"openai",baseUrl:"https://generativelanguage.googleapis.com",defaultModel:"text-embedding-004",defaultDimensions:768},deepseek:{format:"openai",baseUrl:"https://api.deepseek.com",defaultModel:"text-embedding-v1",defaultDimensions:1024}};function xu(n,e,t){let r=qS[n.toLowerCase()];return r?{baseUrl:t?.baseUrl||r.baseUrl,apiKey:e,model:t?.model||r.defaultModel,dimensions:t?.dimensions||r.defaultDimensions,format:r.format}:null}var WS={observationsAdded:0,proposalsAdded:0,claimsAdded:0,conflictsAdded:0,memoriesAdded:0,observationIds:[],proposalIds:[],claimIds:[],conflictIds:[]},hs=class{constructor(e,t){this.store=e;this.embed=t}store;embed;async observe(e,t,r){let s=fs(r?.source),o=cr(s),i=ha();for(let a of e){let c=a.text?.trim();if(!c)continue;let l=this.store.insertObservation({userId:t,text:c,source:s,sourcePriority:o,sessionId:r?.sessionId??"",evidenceType:"text",payload:{category:a.category,importance:a.importance,tags:a.tags??[]}});i.observationsAdded++,i.observationIds.push(l)}return i}async proposeExtracted(e,t,r){let s=fs(r?.source),o=cr(s),i=ha();for(let a of e){let c=a.text?.trim();if(!c)continue;let l=this.store.insertObservation({userId:t,text:c,source:s,sourcePriority:o,sessionId:r?.sessionId??"",evidenceType:"text",payload:{category:a.category,importance:a.importance,eventDate:a.event_date,tags:a.tags??[]}});i.observationsAdded++,i.observationIds.push(l);let d=Pu(c,a,s),u=this.store.insertProposal({userId:t,observationIds:[l],text:c,category:a.category??"general",importance:jt(a.importance??.5,.1,1),confidence:d.confidence,source:s,sourcePriority:o,entity:d.entity,predicate:d.predicate,value:d.value,validTime:d.validTime,tags:a.tags??[],status:"pending"});i.proposalsAdded++,i.proposalIds.push(u)}return i}async commitExtracted(e,t,r){let s=fs(r?.source),o=cr(s),i=ha();for(let a of e){let c=a.text?.trim();if(!c)continue;let l=this.store.insertObservation({userId:t,text:c,source:s,sourcePriority:o,sessionId:r?.sessionId??"",evidenceType:"text",payload:{category:a.category,importance:a.importance,eventDate:a.event_date,tags:a.tags??[]}});i.observationsAdded++,i.observationIds.push(l);let d=Pu(c,a,s),u=this.store.insertProposal({userId:t,observationIds:[l],text:c,category:a.category??"general",importance:jt(a.importance??.5,.1,1),confidence:d.confidence,source:s,sourcePriority:o,entity:d.entity,predicate:d.predicate,value:d.value,validTime:d.validTime,tags:a.tags??[],status:"pending"});i.proposalsAdded++,i.proposalIds.push(u);let p=this.store.findClaimsByFact(t,d.entity,d.predicate,d.validTime),m=p.find(k=>XS(k.value,d.value));if(m){this.store.mergeClaimEvidence(m.id,[l],Math.max(m.confidence,d.confidence),jt(a.importance??m.importance,.1,1)),this.store.updateProposalStatus(u,"merged",[m.id]),i.claimIds.push(m.id);continue}let h=p.find(k=>k.status==="active"||k.status==="pending_confirmation");if(h){let k=this.store.insertClaim({userId:t,entity:d.entity,predicate:d.predicate,value:d.value,text:c,category:a.category??"general",importance:jt(a.importance??.5,.1,1),confidence:d.confidence,source:s,sourcePriority:o,status:"conflicted",validTime:d.validTime,evidenceIds:[l]}),A=this.store.insertConflict({userId:t,claimAId:h.id,claimBId:k,reason:`same entity + same predicate + different value: ${d.entity}.${d.predicate}`});this.store.updateProposalStatus(u,"conflicted",[h.id,k]),i.claimsAdded++,i.conflictsAdded++,i.claimIds.push(k),i.conflictIds.push(A);continue}let f=GS(s,d.confidence),y=f==="active"?this.store.insert({text:c,userId:t,category:a.category??"general",importance:jt(a.importance??.5,.1,1),confidence:d.confidence,source:s,sessionId:r?.sessionId??"",eventDate:a.event_date??"",tags:a.tags??[],embedding:await this.embed(c)}):"",b=this.store.insertClaim({userId:t,memoryId:y,entity:d.entity,predicate:d.predicate,value:d.value,text:c,category:a.category??"general",importance:jt(a.importance??.5,.1,1),confidence:d.confidence,source:s,sourcePriority:o,status:f,validTime:d.validTime,evidenceIds:[l]});this.store.updateProposalStatus(u,f==="active"?"accepted":"pending",[b]),i.claimsAdded++,i.memoriesAdded+=y?1:0,i.claimIds.push(b)}return i}};function cr(n){let e=fs(n);return e==="manual"||e==="user_edit"?100:e==="explicit"||e==="agent-remember"||e==="agent"?90:e==="document"||e==="image"||e==="video"?70:e==="auto"||e==="turn"?45:e==="dream"||e==="dream-consolidation"||e==="profile-extraction"?20:40}function GS(n,e){return cr(n)>=45&&e>=.55?"active":"pending_confirmation"}function Pu(n,e,t){let r=JS(n),s=(e.tags??[]).join(" "),o=KS(n,s),i=VS(n);if(i)return{entity:o,predicate:"contract_amount",value:i,validTime:_u(e.event_date),confidence:fa(t,.92)};let a=zS(n);if(a)return{entity:o,predicate:"progress_update_schedule",value:a,validTime:"",confidence:fa(t,.86)};let c=YS(e.category??"general");return{entity:o,predicate:c,value:{text:r},validTime:_u(e.event_date),confidence:fa(t,.7)}}function fa(n,e){let t=cr(n);return t>=90?jt(e+.04,.1,.99):t<=20?jt(e-.18,.1,.95):jt(e,.1,.98)}function KS(n,e){let t=`${n} ${e}`;if(/Galaxy\s*Tech|Galaxy/i.test(t))return"Galaxy Tech";let r=t.match(/\b[A-Z][A-Za-z0-9]*(?:\s+[A-Z][A-Za-z0-9]*){0,3}\b/);if(r?.[0])return r[0].trim();let s=t.match(/([\u4e00-\u9fa5A-Za-z0-9]{2,18})(?:公司|客户|合同|项目)/);return s?.[1]?s[1]:"user"}function VS(n){if(!/(合同|contract)/i.test(n))return null;let e=n.match(/(\d+(?:\.\d+)?)\s*k\b/i);if(e)return{amount:Math.round(Number(e[1])*1e3),currency:gs(n)};let t=n.match(/(\d+(?:\.\d+)?)\s*万/);if(t)return{amount:Math.round(Number(t[1])*1e4),currency:gs(n)};let r=n.match(/(?:金额|amount)[^\d]*(\d{5,})/i);return r?{amount:Number(r[1]),currency:gs(n)}:/一十八万/.test(n)?{amount:18e4,currency:gs(n)}:null}function zS(n){if(!/(提醒|进展|更新|progress|schedule|每周)/i.test(n))return null;let e=/周一|星期一|Monday/i.test(n)?"monday":/周二|星期二|Tuesday/i.test(n)?"tuesday":/周三|星期三|Wednesday/i.test(n)?"wednesday":/周四|星期四|Thursday/i.test(n)?"thursday":/周五|星期五|Friday/i.test(n)?"friday":/周六|星期六|Saturday/i.test(n)?"saturday":/周日|周天|星期日|星期天|Sunday/i.test(n)?"sunday":"";if(!e)return null;let t=n.match(/(?:上午|早上)?\s*(\d{1,2})\s*点/);return{cadence:"weekly",weekday:e,hour:t?Number(t[1]):null}}function XS(n,e){return Iu(n)===Iu(e)}function Iu(n){let e=Object.keys(n).sort();return JSON.stringify(e.reduce((t,r)=>(t[r]=n[r],t),{}))}function gs(n){return/[¥¥]|人民币|CNY/i.test(n)?"CNY":/\$|USD/i.test(n)?"USD":"unknown"}function YS(n){return n.trim().toLowerCase().replace(/[^a-z0-9_\-\u4e00-\u9fa5]+/g,"_")||"general"}function _u(n){if(!n)return"";let e=new Date(n);return Number.isNaN(e.getTime())?"":`${e.getUTCFullYear()}-${String(e.getUTCMonth()+1).padStart(2,"0")}`}function JS(n){return n.trim().replace(/\s+/g," ").toLowerCase()}function fs(n){return n?.trim()||"agent"}function jt(n,e,t){return Number.isFinite(n)?Math.max(e,Math.min(t,n)):e}function ha(){return{...WS,observationIds:[],proposalIds:[],claimIds:[],conflictIds:[]}}var Eu="qmemory-local",ba=class{providerId=Eu;store;embedding;consolidator;userIdPrefix;dbPath;constructor(e){if(this.dbPath=Au(),this.userIdPrefix=e.userIdPrefix??"",this.embedding=wu(e.embedding),!e.createDatabase)throw new Error("LocalMemoryProvider requires a createDatabase factory. Install better-sqlite3 and pass: (path) => new Database(path)");let t=e.createDatabase(this.dbPath);this.store=new ps(t),this.consolidator=new hs(this.store,r=>this.buildEmbedding(r))}resolveUserId(e){return this.userIdPrefix?`${this.userIdPrefix}:${e}`:e}async buildEmbedding(e){if(this.embedding.dimensions!==0)try{let t=await this.embedding.embed(e);return t.length?t:void 0}catch{return}}async search(e,t,r){let s=this.resolveUserId(t),o=r?.limit??10,i=r?.minScore??.1,a=null;if(this.embedding.dimensions>0)try{a=await this.embedding.embed(e)}catch{}let c=Math.min(o*3,50),l=this.store.searchHybrid(e,a,s,c),d=this.rerank(l.map(u=>({id:u.id,text:u.text,score:u.score,category:u.category,metadata:{...u.metadata,createdAt:u.metadata?.createdAt,accessCount:u.metadata?.accessCount}})),{preferredCategories:r?.preferredCategories});for(let u of d.slice(0,3))this.store.recordAccess(u.id);return d.filter(u=>u.score>=i).slice(0,o).map(u=>({blockId:u.id,text:u.text,score:u.score,source:Eu,metadata:u.metadata}))}async ingest(e,t,r){let s=this.resolveUserId(t),o=e.filter(i=>i.content?.trim()&&i.content.trim().length>=10).map(i=>({text:i.content,category:"conversation",importance:.4}));await this.consolidator.observe(o,s,{source:r?.source??"turn",sessionId:r?.sessionId??""})}async addText(e,t,r){return this.ingestExtracted([{text:e,category:r?.category??"fact",importance:r?.importance??.6}],t,{...r,source:r?.source??"agent",sessionId:r?.sessionId??""})}async remove(e){return this.store.updateClaimsByMemoryId(e,"archived"),this.store.delete(e)}async update(e,t){let r=this.store.getById(e);if(!r)return!1;let s=t.text?.trim(),o=s&&s!==r.text?await this.buildEmbedding(s):void 0,i=this.store.update(e,{...t,text:s||void 0,embedding:o});return i&&this.store.updateClaimsByMemoryId(e,"superseded"),i}async ingestExtracted(e,t,r){if(e.length===0)return ya();let s=this.resolveUserId(t);return this.consolidator.commitExtracted(e,s,{source:r?.source??"agent",sessionId:r?.sessionId??""})}async observeExtracted(e,t,r){return e.length===0?ya():this.consolidator.observe(e,this.resolveUserId(t),{source:r?.source??"agent",sessionId:r?.sessionId??""})}async proposeExtracted(e,t,r){return e.length===0?ya():this.consolidator.proposeExtracted(e,this.resolveUserId(t),{source:r?.source??"agent",sessionId:r?.sessionId??""})}listClaims(e){return this.store.listClaims(this.resolveUserId(e))}listConflicts(e){return this.store.listConflicts(this.resolveUserId(e))}async triggerDecay(e,t=90){let r=this.resolveUserId(e),s=this.store.runFullDecay(r),o=this.store.enforceCapacityLimit(r,1e4);return s.total+o>10&&(this.store.exportAndPurgeArchived(r,200),this.store.vacuum()),{decayed:s.total+o}}async feedback(e,t){let r=0;for(let s of e)this.store.applyFeedback(s,t)&&r++;return{affected:r}}getProfile(e,t){return this.store.getProfile(this.resolveUserId(e),t)}setProfile(e,t,r){this.store.setProfile(this.resolveUserId(e),t,r)}getAllProfiles(e){return this.store.getAllProfiles(this.resolveUserId(e))}deleteProfile(e,t){return this.store.deleteProfile(this.resolveUserId(e),t)}getTemporalSlice(e,t,r,s){return this.store.getTemporalSlice(this.resolveUserId(e),t,r,s)}getActivitySummary(e,t=7){return this.store.getActivitySummary(this.resolveUserId(e),t)}list(e,t){return this.store.listByUser(this.resolveUserId(e),t?.page??1,t?.pageSize??500,t?.activeOnly??!0)}getAtlas(e,t){return this.store.getAtlas(this.resolveUserId(e),t)}findByEventDate(e,t,r=1){return this.store.findByEventDate(this.resolveUserId(e),t,r)}async findRelatedEvents(e,t,r){let s=this.resolveUserId(t),o=r?.minSimilarity??.55,i=r?.maxSimilarity??.82,a=r?.maxDaysBack??14,c=r?.limit??5;if(this.embedding.dimensions===0)return[];let l;try{l=await this.embedding.embed(e)}catch{return[]}let d=this.store.searchVector(l,s,c*3,o),u=Date.now()-a*864e5;return d.filter(p=>{let m=p.metadata?.cosineSimilarity??p.score,h=p.metadata?.createdAt??0;return m>=o&&m<i&&h>=u}).slice(0,c).map(p=>({id:p.id,text:p.text,score:p.metadata?.cosineSimilarity??p.score,date:new Date(p.metadata?.createdAt??Date.now()).toISOString().slice(0,10)}))}synthesizeTimeline(e,t,r){let s=this.getTemporalSlice(e,t,r);if(s.length===0)return"No memories in this time range.";let o=[];for(let i of s){o.push(`## ${i.date}`);for(let a of i.memories){let c=a.importance>=.7?"*":"-";o.push(`${c} [${a.category}] ${a.text}`)}}return o.join(`
|
|
482
|
+
`)}rerank(e,t){let r=(t?.recencyBoostDays??7)*864e5,s=Date.now(),o=new Set(t?.preferredCategories??[]);return e.map(i=>{let a=i.score,c=i.metadata?.createdAt??0;if(c>0){let d=s-c;d<r&&(a+=.1*(1-d/r))}let l=i.metadata?.accessCount??0;return l>0&&(a+=Math.min(.05,l*.01)),o.size>0&&i.category&&o.has(i.category)&&(a+=.08),{...i,score:Math.min(1,a)}}).sort((i,a)=>a.score-i.score)}async health(){return{status:"healthy",memoryCount:0,dbPath:this.dbPath}}count(e){return this.store.count(this.resolveUserId(e))}async resetUser(e){return this.store.resetUser(this.resolveUserId(e))}close(){this.store.close()}};function Cu(n){return new ba(n)}function ya(){return{observationsAdded:0,proposalsAdded:0,claimsAdded:0,conflictsAdded:0,memoriesAdded:0,observationIds:[],proposalIds:[],claimIds:[],conflictIds:[]}}dt();function va(n){try{let e=ZS();if(e){let t={projectRoot:n.projectRoot,userIdPrefix:n.userIdPrefix,embedding:n.embedding,createDatabase:e};return{provider:Cu(t),mode:"local"}}}catch(e){return{provider:null,mode:"none",error:`Local provider failed: ${e.message}`}}return{provider:null,mode:"none",error:"better-sqlite3 not available"}}function ZS(){try{let e=QS(import.meta.url)("better-sqlite3"),t=e.default??e;if(typeof t!="function")return null;let r=t;return s=>new r(s)}catch{return null}}function ka(n){let e=process.env.QMEMORY_USER_PREFIX||void 0,r=Y().getActiveModel("embedding");if(r){let o=tT({provider:r.provider,apiKey:r.apiKey,model:r.model||"text-embedding-3-small",baseUrl:r.baseUrl}),i={projectRoot:n,userIdPrefix:e,embedding:{api:o}};return r.keyHandle.release({success:!0}),i}let s=eT();return{projectRoot:n,userIdPrefix:e,embedding:s?{api:s}:void 0}}function eT(){let n=Mu(process.env.QLOGIC_LLMROUTER_BASE_URL);if(!n)return;let e=process.env.QLOGIC_LLMROUTER_ACCESS_TOKEN?.trim();if(!e)return;let t=parseInt(process.env.QLOGIC_LLMROUTER_EMBEDDING_DIMENSIONS||process.env.QMEMORY_EMBEDDING_DIMENSIONS||"1024",10);return{baseUrl:n,apiKey:e,model:process.env.QLOGIC_LLMROUTER_EMBEDDING_MODEL||"BAAI/bge-m3",dimensions:Number.isFinite(t)?t:1024,format:"openai",timeoutMs:Nu()}}function tT(n){return{...xu(n.provider,n.apiKey,{model:n.model,baseUrl:n.baseUrl})??{baseUrl:Mu(n.baseUrl)||"",apiKey:n.apiKey,model:n.model,format:"openai"},timeoutMs:Nu()}}function Mu(n){return n?.trim().replace(/\/+$/,"")??""}function Nu(){let n=parseInt(process.env.QMEMORY_EMBEDDING_TIMEOUT_MS||"1500",10);return Number.isFinite(n)&&n>0?n:1500}var zt=class{sessionId;_trustAccepted=!1;_modelUsage=new Map;_totalInputTokens=0;_totalOutputTokens=0;_turnCount=0;_toolCallCount=0;_listeners=new Set;constructor(e){this.sessionId=e}get trustAccepted(){return this._trustAccepted}setTrustAccepted(e){this._trustAccepted=e,this.notifyListeners()}get totalInputTokens(){return this._totalInputTokens}get totalOutputTokens(){return this._totalOutputTokens}get turnCount(){return this._turnCount}get toolCallCount(){return this._toolCallCount}getModelUsage(e){return this._modelUsage.get(e)}getAllModelUsage(){let e={};for(let[t,r]of this._modelUsage)e[t]={...r};return e}addUsage(e,t){this._totalInputTokens+=e.inputTokens,this._totalOutputTokens+=e.outputTokens;let r=this._modelUsage.get(t);r?(r.inputTokens+=e.inputTokens,r.outputTokens+=e.outputTokens,r.cacheRead+=e.cacheRead??0,r.cacheCreation+=e.cacheWrite??0):this._modelUsage.set(t,{inputTokens:e.inputTokens,outputTokens:e.outputTokens,cacheRead:e.cacheRead??0,cacheCreation:e.cacheWrite??0,mediaCalls:0,mediaDurationSeconds:0,mediaCharacters:0}),this.notifyListeners()}addMediaUsage(e,t,r){let s=this._modelUsage.get(e),o=s??{inputTokens:0,outputTokens:0,cacheRead:0,cacheCreation:0,mediaCalls:0,mediaDurationSeconds:0,mediaCharacters:0};switch(s||this._modelUsage.set(e,o),o.mediaCalls+=1,t){case"per_second":o.mediaDurationSeconds+=r;break;case"per_character":o.mediaCharacters+=r;break;case"per_token":o.outputTokens+=r;break}this.notifyListeners()}recordToolCall(){this._toolCallCount++}recordTurnCompleted(){this._turnCount++}createSnapshot(){return{sessionId:this.sessionId,modelUsage:this.getAllModelUsage(),totalInputTokens:this._totalInputTokens,totalOutputTokens:this._totalOutputTokens,turnCount:this._turnCount,lastSavedAt:Date.now()}}restoreFromSnapshot(e){if(e.sessionId!==this.sessionId)return!1;this._totalInputTokens=e.totalInputTokens,this._totalOutputTokens=e.totalOutputTokens,this._turnCount=e.turnCount,this._modelUsage.clear();for(let[t,r]of Object.entries(e.modelUsage))this._modelUsage.set(t,{...r});return this.notifyListeners(),!0}onStateChange(e){return this._listeners.add(e),()=>{this._listeners.delete(e)}}notifyListeners(){for(let e of this._listeners)try{e()}catch{}}};ae();je();import*as de from"node:fs";import*as Ve from"node:path";var Du="transcript.jsonl",Ut="metadata.json";function nT(n){return Ot(n)}function Pn(n,e){let t=n.replace(/[^a-zA-Z0-9_-]/g,"_");return Ve.join(nT(e),t)}function Ou(n,e){let t=n.replace(/[^a-zA-Z0-9_-]/g,"_"),r=Ve.join(Ot(e),t),s=Ve.join(r,Ut);if(de.existsSync(s))return r}function cn(n,e){let t=Ou(n,e);if(!t)return null;try{let r=de.readFileSync(Ve.join(t,Ut),"utf8");return JSON.parse(r)}catch{return null}}async function Sa(n,e,t,r){let s=Pn(n,t);try{await de.promises.mkdir(s,{recursive:!0});let o={role:e.role,content:e.content,ts:Date.now()};r&&(o.turnId=r);let i=JSON.stringify(o)+`
|
|
483
|
+
`;return await de.promises.appendFile(Ve.join(s,Du),i,"utf8"),!0}catch(o){return console.error(`[session-persistence] appendMessage failed for ${n}: ${o.message}`),!1}}async function Lu(n,e,t,r){let s=Pn(n,r);await de.promises.mkdir(s,{recursive:!0});let o={};try{let l=await de.promises.readFile(Ve.join(s,Ut),"utf8");o=JSON.parse(l)}catch{}let i=new Date().toISOString(),a={sessionId:n,projectId:t.projectId??o.projectId??"",createdAt:t.createdAt??o.createdAt??i,lastActiveAt:i,model:t.model??o.model,cwd:t.cwd??o.cwd,turnCount:e.turnCount,messageCount:t.messageCount??o.messageCount??0,title:t.title??o.title,pinnedAt:t.pinnedAt!==void 0?t.pinnedAt:o.pinnedAt,archivedAt:t.archivedAt!==void 0?t.archivedAt:o.archivedAt,type:t.type??o.type,ownerId:t.ownerId??o.ownerId,groupKey:t.groupKey??o.groupKey,groupName:t.groupName??o.groupName,groupPlatform:t.groupPlatform??o.groupPlatform,sealedAt:t.sealedAt??o.sealedAt,previousSessionId:t.previousSessionId??o.previousSessionId,carryoverSummary:t.carryoverSummary??o.carryoverSummary,totalInputTokens:e.totalInputTokens,totalOutputTokens:e.totalOutputTokens},c=Ve.join(s,Ut+".tmp");await de.promises.writeFile(c,JSON.stringify(a,null,2),"utf8"),await de.promises.rename(c,Ve.join(s,Ut))}async function et(n,e,t){let s=Ou(n,t)??Pn(n,t),o=Ve.join(s,Ut),i=new Date().toISOString(),a;try{let d=await de.promises.readFile(o,"utf8");a=JSON.parse(d)}catch{await de.promises.mkdir(s,{recursive:!0}),a={sessionId:n,projectId:e.projectId??"",createdAt:i,lastActiveAt:i,turnCount:0,messageCount:0,...e};let d=o+".tmp";return await de.promises.writeFile(d,JSON.stringify(a,null,2),"utf8"),await de.promises.rename(d,o),a}let c={...a};e.title!==void 0&&(c.title=e.title??void 0),e.pinnedAt!==void 0&&(c.pinnedAt=e.pinnedAt??void 0),e.archivedAt!==void 0&&(c.archivedAt=e.archivedAt??void 0),e.sealedAt!==void 0&&(c.sealedAt=e.sealedAt??void 0),e.previousSessionId!==void 0&&(c.previousSessionId=e.previousSessionId??void 0),e.carryoverSummary!==void 0&&(c.carryoverSummary=e.carryoverSummary??void 0),e.projectId!==void 0&&(c.projectId=e.projectId??c.projectId),e.type!==void 0&&(c.type=e.type??void 0),e.ownerId!==void 0&&(c.ownerId=e.ownerId??void 0),e.groupKey!==void 0&&(c.groupKey=e.groupKey??void 0),e.groupName!==void 0&&(c.groupName=e.groupName??void 0),e.groupPlatform!==void 0&&(c.groupPlatform=e.groupPlatform??void 0),c.lastActiveAt=i;let l=o+".tmp";return await de.promises.writeFile(l,JSON.stringify(c,null,2),"utf8"),await de.promises.rename(l,o),c}async function Ta(n,e){try{await de.promises.access(e,de.constants.R_OK)}catch{return console.error(`[session-persistence] loadSessionForResume: projectRoot not accessible: ${e}`),null}let t=Pn(n,e),r=Ve.join(t,Du),s=Ve.join(t,Ut),o=[],i=0;try{let d=await de.promises.readFile(r,"utf8");for(let u of d.split(`
|
|
484
|
+
`))if(u.trim())try{let p=JSON.parse(u);o.push({role:p.role,content:p.content??null})}catch{i++}i>0&&console.warn(`[session-persistence] ${i} corrupt line(s) skipped in ${r}`)}catch{return null}if(o.length===0&&i>0)return console.error(`[session-persistence] Transcript fully corrupt for session ${n}`),null;let a=new Date().toISOString(),c={sessionId:n,projectId:"",createdAt:a,lastActiveAt:a,turnCount:0,messageCount:o.length};try{let d=await de.promises.readFile(s,"utf8");c=JSON.parse(d)}catch{}let l=o.filter(d=>d.role!=="system");return{metadata:c,messages:l}}async function At(n=gi,e){let t=Ot(e),r;try{r=await de.promises.readdir(t)}catch{return[]}let s=[];for(let o of r){let i=Ve.join(t,o,Ut);try{let a=await de.promises.readFile(i,"utf8"),c=JSON.parse(a);s.push({sessionId:c.sessionId,title:c.title,lastActiveAt:c.lastActiveAt,messageCount:c.messageCount,model:c.model,pinnedAt:c.pinnedAt,archivedAt:c.archivedAt,sealedAt:c.sealedAt,projectId:c.projectId,type:c.type,createdAt:c.createdAt,groupKey:c.groupKey,previousSessionId:c.previousSessionId})}catch{}}return s.sort((o,i)=>o.lastActiveAt>i.lastActiveAt?-1:o.lastActiveAt<i.lastActiveAt?1:0),s.slice(0,n)}async function Ra(n,e){let t=Pn(n,e);await de.promises.rm(t,{recursive:!0,force:!0})}function rT(n){return n.turnCount<fi?!1:n.taskSummaryGeneratedAt?n.turnCount-(n.taskSummaryGeneratedAt??0)>=hi:!0}var sT="Based on the user's message below, generate a very short session title (2-8 Chinese characters or 3-6 English words). The title should capture the main topic or intent. Reply with ONLY the title text, no quotes, no punctuation.";async function $u(n,e){if(!n.trim())return null;try{let t=e.transport.stream({model:e.model,messages:[{role:"system",content:sT},{role:"user",content:n.slice(0,500)}],tools:[],maxTokens:30},e.apiKey),r="";for await(let s of t)s.type==="delta"&&(r+=s.text);return r=r.trim().replace(/^["'""'']+|["'""'']+$/g,""),r||null}catch{return null}}async function ju(n,e,t,r,s){if(!rT(e))return null;try{let i=t.slice(-20).map(u=>`[${u.role}]: ${typeof u.content=="string"?u.content.slice(0,500):JSON.stringify(u.content).slice(0,500)}`).join(`
|
|
485
|
+
`),a=r.transport.stream({model:r.model,messages:[{role:"system",content:"Generate a concise task summary (~100 words) of what the user is working on in this session. Focus on the goal, key decisions, and current progress. Reply with ONLY the summary."},{role:"user",content:i}],tools:[],maxTokens:200},r.apiKey),c="";for await(let u of a)u.type==="delta"&&(c+=u.text);if(c=c.trim(),!c)return null;let l=Pn(n,s),d=Ve.join(l,Ut);try{let u=await de.promises.readFile(d,"utf8"),p=JSON.parse(u);p.taskSummary=c,p.taskSummaryGeneratedAt=e.turnCount;let m=d+".tmp";await de.promises.writeFile(m,JSON.stringify(p,null,2),"utf8"),await de.promises.rename(m,d)}catch{}return c}catch{return null}}ra();import{randomUUID as NM}from"node:crypto";var oT=3e4;var bs=class{tasks=new Map;listeners=new Set;hooks=null;sessionId="";setHooks(e,t){this.hooks=e,this.sessionId=t}onTaskChange(e){return this.listeners.add(e),()=>this.listeners.delete(e)}notify(e,t){for(let r of this.listeners)try{r(e,t)}catch{}}registerTask(e){this.tasks.set(e.taskId,e),this.notify(e.taskId,e),this.hooks?.invoke("task.created",{sessionId:this.sessionId,taskId:e.taskId,taskType:e.type,label:e.label}).catch(()=>{})}updateTask(e,t){let r=this.tasks.get(e);if(!r)return;let s=t(r);s!==r&&(this.tasks.set(e,s),this.notify(e,s),!ys(r.lifecycle)&&ys(s.lifecycle)&&this.hooks?.invoke("task.completed",{sessionId:this.sessionId,taskId:s.taskId,taskType:s.type,label:s.label}).catch(()=>{}))}getTask(e){return this.tasks.get(e)}getRunningTasks(){return[...this.tasks.values()].filter(e=>e.lifecycle==="running")}getAllTasks(){return[...this.tasks.values()]}evictTask(e){let t=this.tasks.get(e);t&&ys(t.lifecycle)&&(this.tasks.delete(e),this.notify(e,null))}evictStaleTasks(e=oT){let t=Date.now();for(let[r,s]of this.tasks)ys(s.lifecycle)&&s.endedAt&&t-s.endedAt>e&&(this.tasks.delete(r),this.notify(r,null))}};function ys(n){return n==="completed"||n==="failed"||n==="cancelled"||n==="timeout"}ae();import{watch as iT}from"node:fs";import{stat as aT}from"node:fs/promises";import{join as Uu,relative as cT,resolve as lT}from"node:path";var dT=[`${qe}/settings.json`,"INSTRUCTIONS.md",`${qe}/INSTRUCTIONS.md`,"INSTRUCTIONS.local.md",`${qe}/rules`],uT=["INSTRUCTIONS.md","INSTRUCTIONS.local.md",`${qe}/rules`],Aa=class{watchers=new Map;deps;debounceTimers=new Map;_cwd;constructor(e){this.deps=e,this._cwd=e.projectRoot}get cwd(){return this._cwd}async start(){for(let e of dT){let t=Uu(this.deps.projectRoot,e);this.watchPath(t,e)}this.deps.log?.(`file-watcher: watching ${this.watchers.size} paths`)}watchPath(e,t){if(!this.watchers.has(e))try{let r=iT(e,{persistent:!1,recursive:t.includes("/")?!1:void 0},(s,o)=>{let i=o?Uu(e,o):e;this.handleChange(i,s==="rename"?"created":"modified")});r.on("error",()=>{this.watchers.delete(e)}),this.watchers.set(e,r)}catch{}}handleChange(e,t){let r=this.debounceTimers.get(e);r&&clearTimeout(r),this.debounceTimers.set(e,setTimeout(async()=>{this.debounceTimers.delete(e);let s=t;try{await aT(e)}catch{s="deleted"}let o=cT(this.deps.projectRoot,e);this.deps.log?.(`file-watcher: ${s} ${o}`),this.deps.hooks.invoke("file.changed",{sessionId:this.deps.sessionId,filePath:e,changeType:s}).catch(()=>{}),uT.some(a=>o.includes(a)||e.includes(a))&&this.deps.onInstructionCacheReset?.()},300))}setCwd(e){let t=lT(e);if(t===this._cwd)return;let r=this._cwd;this._cwd=t,this.deps.hooks.invoke("cwd.changed",{sessionId:this.deps.sessionId,oldCwd:r,newCwd:t}).catch(()=>{}),this.deps.onInstructionCacheReset?.()}stop(){for(let[,e]of this.watchers)e.close();this.watchers.clear();for(let[,e]of this.debounceTimers)clearTimeout(e);this.debounceTimers.clear()}};async function Fu(n){let e=new Aa(n);return await e.start(),e}ae();je();import{readFile as pT,readdir as mT,stat as gT}from"node:fs/promises";import{dirname as vs,extname as fT,isAbsolute as hT,join as _n,parse as Hu,resolve as Bu}from"node:path";import{homedir as yT}from"node:os";var bT="INSTRUCTIONS.md",vT="INSTRUCTIONS.local.md",kT=[".instructions.md"],ST=new Set([".md",".txt",".text",".json",".yaml",".yml",".toml",".xml",".csv",".html",".htm",".css",".scss",".sass",".less",".js",".ts",".tsx",".jsx",".mjs",".cjs",".mts",".cts",".py",".pyi",".pyw",".rb",".erb",".rake",".go",".rs",".java",".kt",".kts",".scala",".c",".cpp",".cc",".cxx",".h",".hpp",".hxx",".cs",".swift",".sh",".bash",".zsh",".fish",".ps1",".bat",".cmd",".env",".ini",".cfg",".conf",".config",".properties",".sql",".graphql",".gql",".proto",".vue",".svelte",".astro",".php",".pl",".pm",".lua",".r",".R",".dart",".ex",".exs",".erl",".hrl",".clj",".cljs",".cljc",".edn",".hs",".lhs",".elm",".ml",".mli",".f",".f90",".f95",".for",".cmake",".make",".makefile",".gradle",".sbt",".rst",".adoc",".asciidoc",".org",".tex",".latex",".lock",".log",".diff",".patch"]);async function TT(n){try{return await pT(n,"utf-8")}catch{return null}}function RT(n){return n.includes("<!--")?n.replace(/^[ \t]*<!--[\s\S]*?-->[ \t]*$/gm,""):n}function AT(n){let e=n.match(/^---\r?\n([\s\S]*?)\r?\n---\r?\n?/);if(!e)return{content:n};let t=e[1],r=n.slice(e[0].length),s=t.match(/^paths:\s*(.+)$/m);if(!s)return{content:r};let o=[],i=s[1].trim();if(i.startsWith("["))try{o=JSON.parse(i)}catch{}else o=i.split(",").map(c=>c.trim()).filter(Boolean);let a=o.map(c=>c.endsWith("/**")?c.slice(0,-3):c).filter(c=>c.length>0&&c!=="**");return{content:r,globs:a.length>0?a:void 0}}function wT(n,e){let t=new Set,r=/(?:^|\s)@((?:[^\s\\]|\\ )+)/g,o=n.replace(/```[\s\S]*?```/g,"").replace(/`[^`]+`/g,""),i;for(;(i=r.exec(o))!==null;){let a=i[1];if(!a)continue;let c=a.indexOf("#");if(c!==-1&&(a=a.substring(0,c)),!a)continue;a=a.replace(/\\ /g," ");let l;if(a.startsWith("~/"))l=_n(yT(),a.slice(2));else if(hT(a))l=a;else if(a.startsWith("./"))l=Bu(vs(e),a);else if(/^[a-zA-Z0-9._-]/.test(a)&&!a.startsWith("@"))l=Bu(vs(e),a);else continue;t.add(l)}return[...t]}async function In(n,e,t,r=0,s){let o=n.toLowerCase();if(t.has(o)||r>=yi)return[];let i=fT(n).toLowerCase();if(i&&!ST.has(i))return[];t.add(o);let a=await TT(n);if(!a?.trim())return[];let{content:c,globs:l}=AT(a),d=RT(c);if(!d.trim())return[];let u=[],p={path:n,type:e,content:d.trim()};s&&(p.parent=s),l&&(p.globs=l),u.push(p);let m=wT(c,n);for(let h of m){let f=await In(h,e,t,r+1,n);u.push(...f)}return u}async function qu(n,e,t,r,s=new Set){if(s.has(n))return[];s.add(n);let o=[];try{let i=await mT(n,{withFileTypes:!0});for(let a of i){let c=_n(n,a.name);if(a.isDirectory())o.push(...await qu(c,e,t,r,s));else if(a.isFile()&&a.name.endsWith(".md")){let l=await In(c,e,t);o.push(...l.filter(d=>r?!!d.globs:!d.globs))}}}catch{}return o}async function xT(n){let e=n,t=Hu(e).root;for(;e!==t;){try{let r=_n(e,".git"),s=await gT(r);if(s.isDirectory()||s.isFile())return e}catch{}e=vs(e)}return null}async function PT(n,e){let t=[],r=new Set,o=await xT(n)??Hu(n).root,i=[],a=n;for(;i.push(a),!(a===o&&a!==n);){let c=vs(a);if(c===a)break;a=c}for(let c of i.reverse()){t.push(...await In(_n(c,bT),"Project",r));for(let l of kT)t.push(...await In(_n(c,l),"Project",r));t.push(...await In(tr(c),"Project",r)),t.push(...await qu(wn(c),"Project",r,!1)),t.push(...await In(_n(c,vT),"Local",r))}return e&&t.length>0&&e.invoke("instructions.loaded",{sessionId:"",source:n,fileCount:t.length}).catch(()=>{}),t}function Wu(n){if(n.length===0)return"";let e="Codebase and user instructions are shown below. Be sure to adhere to these instructions. IMPORTANT: These instructions OVERRIDE any default behavior and you MUST follow them exactly as written.",t=[];for(let r of n){if(!r.content)continue;let s=r.type==="Project"?" (project instructions, checked into the codebase)":r.type==="Local"?" (user's private project instructions, not checked in)":" (user's private global instructions for all projects)";t.push(`Contents of ${r.path}${s}:
|
|
486
486
|
|
|
487
487
|
${r.content.trim()}`)}return t.length>0?`${e}
|
|
488
488
|
|
|
489
489
|
${t.join(`
|
|
490
490
|
|
|
491
|
-
`)}`:""}var lr=null,wa=null;async function
|
|
492
|
-
`)}},required:["thought"]};function
|
|
493
|
-
`),parameters:_T,execute:async(n,e)=>({content:[{type:"text",text:"Thought recorded. Now proceed with the best action based on your reasoning."}],details:{type:"think"}})}}var ET="task",CT=["create","update","delete","list","get"];var MT={type:"object",properties:{action:{type:"string",enum:[...CT],description:"create \u2014 add a new task (auto-assigns id). update \u2014 modify a task by id (partial, supports dependency wiring). delete \u2014 remove a task by id (cascades block refs). list \u2014 read current task list with summary. get \u2014 get a single task by id."},id:{type:"number",description:"[update|delete|get] Task id to operate on."},title:{type:"string",description:"[create|update] Task title (3-7 words, imperative form)."},description:{type:"string",description:"[create|update] Detailed task description."},status:{type:"string",enum:["not-started","in-progress","completed"],description:"[create|update] Task status. create defaults to not-started."},owner:{type:"string",description:"[create|update] Owner agent/subagent identifier."},addBlocks:{type:"array",items:{type:"number"},description:"[update] Task IDs that this task should block (they depend on this task)."},addBlockedBy:{type:"array",items:{type:"number"},description:"[update] Task IDs that should block this task (this task depends on them)."}},required:["action"]};function dr(n){let e=new Set(n.filter(t=>t.status==="completed").map(t=>t.id));return{total:n.length,completed:n.filter(t=>t.status==="completed").length,inProgress:n.filter(t=>t.status==="in-progress").length,notStarted:n.filter(t=>t.status==="not-started").length,blocked:n.filter(t=>t.status!=="completed"&&t.blockedBy?.some(r=>!e.has(r))).length}}function
|
|
491
|
+
`)}`:""}var lr=null,wa=null;async function Gu(n,e){return lr&&wa===n||(lr=await PT(n,e),wa=n),lr}function Ku(){lr=null,wa=null}import*as G from"node:fs";import*as K from"node:path";import{execFile as ZA}from"node:child_process";var xa=new Set(["gateway","agents_list","session_status","sessions_send","sessions_list","sessions_history","sessions_spawn","cron","config","workflow"]),Vu=new Set([...xa,"agent"]);function Pa(n,e){let t=e?xa:Vu;return n.filter(r=>r.function.name.startsWith("mcp__")?!0:!t.has(r.function.name))}var Ft=new Map,Ia=new Set;function zu(n){Ft.clear(),Ia.clear();for(let e of n)Ft.set(e.name,e)}function Pe(n){Ft.set(n.name,n)}function _a(n){for(let e of n)Ft.set(e.name,e)}function ks(n){return Ft.delete(n)}function tt(n){return Ft.get(n)}function Xt(){return Array.from(Ft.keys())}function Xu(n){let e=Ft.get(n);return!e||e.isEnabled?.()===!1?!1:(Ia.add(n),!0)}function wt(n=!1){let e=[];for(let t of Ft.values())t.isEnabled?.()!==!1&&(!n&&t.shouldDefer&&!Ia.has(t.name)||e.push({type:"function",function:{name:t.name,description:t.description,parameters:t.parameters},meta:{parallelSafe:t.isConcurrencySafe??!1,isReadOnly:t.isReadOnly??!1,isDangerous:!(t.isReadOnly??!1)&&!(t.isConcurrencySafe??!1)}}));return e}var IT="think",_T={type:"object",properties:{thought:{type:"string",description:["Your internal reasoning about the current situation.","Use this to:","\u2022 Analyze what the user really wants (disambiguate vague requests)","\u2022 Plan multi-step approaches before executing","\u2022 Evaluate which tool(s) to use and why","\u2022 Consider edge cases or potential issues","\u2022 Reflect on conversation context and user preferences","This content is never shown to the user."].join(`
|
|
492
|
+
`)}},required:["thought"]};function Yu(){return{name:IT,label:"Think",shouldDefer:!0,description:["Use this tool to think and reason about the current situation BEFORE taking action.","Call this tool when you need to:","- Analyze an ambiguous or complex user request before deciding what to do","- Plan a multi-step approach (what tools to call and in what order)","- Identify which steps can run in parallel vs. which must be sequential","- Evaluate tradeoffs between different approaches","- Reflect on user preferences from conversation history","- Process new information that changes your understanding","","This tool has NO side effects \u2014 it simply records your reasoning process.","Your thought is NOT shown to the user; it only improves YOUR decision quality.","After thinking, proceed to take the appropriate action.","","When planning multi-step work, be explicit about parallelism:",'- Say "\u8FD9\u4E9B\u53EF\u4EE5\u5E76\u884C\u751F\u6210" or "these can run in parallel" for independent tasks.','- Say "\u5148\u2026\u7136\u540E\u2026" or "step 1 first, then step 2" for sequential dependencies.'].join(`
|
|
493
|
+
`),parameters:_T,execute:async(n,e)=>({content:[{type:"text",text:"Thought recorded. Now proceed with the best action based on your reasoning."}],details:{type:"think"}})}}var ET="task",CT=["create","update","delete","list","get"];var MT={type:"object",properties:{action:{type:"string",enum:[...CT],description:"create \u2014 add a new task (auto-assigns id). update \u2014 modify a task by id (partial, supports dependency wiring). delete \u2014 remove a task by id (cascades block refs). list \u2014 read current task list with summary. get \u2014 get a single task by id."},id:{type:"number",description:"[update|delete|get] Task id to operate on."},title:{type:"string",description:"[create|update] Task title (3-7 words, imperative form)."},description:{type:"string",description:"[create|update] Detailed task description."},status:{type:"string",enum:["not-started","in-progress","completed"],description:"[create|update] Task status. create defaults to not-started."},owner:{type:"string",description:"[create|update] Owner agent/subagent identifier."},addBlocks:{type:"array",items:{type:"number"},description:"[update] Task IDs that this task should block (they depend on this task)."},addBlockedBy:{type:"array",items:{type:"number"},description:"[update] Task IDs that should block this task (this task depends on them)."}},required:["action"]};function dr(n){let e=new Set(n.filter(t=>t.status==="completed").map(t=>t.id));return{total:n.length,completed:n.filter(t=>t.status==="completed").length,inProgress:n.filter(t=>t.status==="in-progress").length,notStarted:n.filter(t=>t.status==="not-started").length,blocked:n.filter(t=>t.status!=="completed"&&t.blockedBy?.some(r=>!e.has(r))).length}}function Ju(n,e){let t=[],r=0,s=n??{},o=s.verificationNudge!==!1;function i(){let f=t.reduce((y,b)=>Math.max(y,b.id),0);return r=Math.max(r,f)+1,r}function a(f){return{content:[{type:"text",text:`Error: ${f}`}],details:{type:"task",error:f}}}function c(f){let y=dr(t),b=new Set(t.filter(I=>I.status==="completed").map(I=>I.id)),k=t.map(I=>{let N=I.blockedBy?.filter(L=>!b.has(L));return{...I,...N?.length?{blockedBy:N}:{blockedBy:void 0}}}),A=[];if(A.push(`Task list updated. ${y.total} tasks: ${y.completed} completed, ${y.inProgress} in-progress, ${y.notStarted} not-started.`),y.blocked>0&&A.push(`${y.blocked} blocked.`),f?.created){let I=f.created;A.push(`Created task #${I.id}: "${I.title}"`)}if(f?.updated){let I=f.updated;A.push(`Updated task #${I.id}: "${I.title}"`)}if(f?.deleted!=null&&A.push(`Deleted task #${f.deleted}`),k.length>0){A.push("");for(let I of k){let N=I.status==="completed"?"\u2713":I.status==="in-progress"?"\u2192":"\u25CB",L=I.blockedBy?.length?` [blocked by #${I.blockedBy.join(", #")}]`:"",F=I.owner?` (${I.owner})`:"";A.push(` ${N} #${I.id}: ${I.title} (${I.status})${F}${L}`)}}let _=!1;if(o&&f?.updated&&f.updated.status==="completed"){let N=t.every(T=>T.status==="completed"),L=t.length,F=t.some(T=>/verif/i.test(T.title));N&&L>=3&&!F&&(_=!0,A.push(""),A.push("NOTE: You just closed out "+L+' tasks and none of them was a verification step. Before writing your final summary, spawn the verification agent (agent type="verify"). You cannot self-assign PARTIAL by listing caveats in your summary \u2014 only the verifier issues a verdict.'))}return{content:[{type:"text",text:A.join(`
|
|
494
494
|
`)}],details:{type:"task",...y,...f,taskList:k,agentId:s.agentId,..._&&{verificationNudgeNeeded:!0}}}}function l(f,y,b){let k=t.find(A=>A.id===f);if(k){if(y?.length){k.blocks=[...new Set([...k.blocks??[],...y])];for(let A of y){let _=t.find(I=>I.id===A);_&&(_.blockedBy=[...new Set([..._.blockedBy??[],f])])}}if(b?.length){k.blockedBy=[...new Set([...k.blockedBy??[],...b])];for(let A of b){let _=t.find(I=>I.id===A);_&&(_.blocks=[...new Set([..._.blocks??[],f])])}}}}function d(f){for(let y of t)y.blocks&&(y.blocks=y.blocks.filter(b=>b!==f)),y.blockedBy&&(y.blockedBy=y.blockedBy.filter(b=>b!==f))}function u(f){if(!f.title)return a("title is required for create action.");let y={id:i(),title:f.title,status:f.status??"not-started",...f.description!=null&&{description:f.description},...f.owner!=null&&{owner:f.owner}};return t.push(y),l(y.id,void 0,f.addBlockedBy),e?.onTaskCreated?.(y),c({created:{id:y.id,title:y.title}})}function p(f){if(f.id==null)return a("id is required for update action.");let y=t.find(b=>b.id===f.id);if(!y)return a(`Task #${f.id} not found.`);if(f.status==="in-progress"){let b=new Set(t.filter(A=>A.status==="completed").map(A=>A.id)),k=y.blockedBy?.filter(A=>!b.has(A));if(k?.length)return a(`Cannot set #${f.id} to in-progress: blocked by unresolved task(s) #${k.join(", #")}.`)}if(f.title!=null&&(y.title=f.title),f.description!=null&&(y.description=f.description),f.owner!=null&&(y.owner=f.owner),f.status!=null){let b=y.status;y.status=f.status,b!=="completed"&&f.status==="completed"&&e?.onTaskCompleted?.(y)}return l(y.id,f.addBlocks,f.addBlockedBy),c({updated:{id:y.id,title:y.title,status:y.status}})}function m(f){if(f.id==null)return a("id is required for delete action.");let y=t.findIndex(b=>b.id===f.id);return y===-1?a(`Task #${f.id} not found.`):(r=Math.max(r,f.id),t.splice(y,1),d(f.id),c({deleted:f.id}))}function h(f){if(f.id==null)return a("id is required for get action.");let y=t.find(_=>_.id===f.id);if(!y)return a(`Task #${f.id} not found.`);let b=new Set(t.filter(_=>_.status==="completed").map(_=>_.id)),k=y.blockedBy?.filter(_=>!b.has(_));return{content:[{type:"text",text:[`Task #${y.id}: ${y.title}`,`Status: ${y.status}`,y.description?`Description: ${y.description}`:"",y.owner?`Owner: ${y.owner}`:"",k?.length?`Blocked by: #${k.join(", #")}`:"",y.blocks?.length?`Blocks: #${y.blocks.join(", #")}`:""].filter(Boolean).join(`
|
|
495
|
-
`)}],details:{type:"task",action:"get",task:y}}}return{name:ET,label:"Task",description:"Manage a structured task list to track multi-step work progress. Actions: create (add task), update (modify by id), delete (remove by id), list (read all), get (single task). Supports dependency tracking (blocks/blockedBy) \u2014 tasks cannot start until blockers complete. Use frequently during complex work to plan steps, coordinate subagents, and show progress.",parameters:MT,searchHint:"manage session task checklist progress tracking dependencies planning",maxResultSizeChars:1e5,execute:async(f,y)=>{let b=y.action;switch(b){case"create":return u(y);case"update":return p(y);case"delete":return m(y);case"list":return c();case"get":return h(y);default:return a(`Unknown action: ${b}. Valid: create, update, delete, list, get.`)}}}}import{isAbsolute as rR,resolve as sR}from"node:path";var Ju=new Set(["find","grep","rg","ag","ack","locate","which","whereis"]),Qu=new Set(["cat","head","tail","less","more","wc","stat","file","strings","jq","awk","cut","sort","uniq","tr"]),Zu=new Set(["ls","tree","du"]);var ep=new Set(["mv","cp","rm","mkdir","rmdir","chmod","chown","chgrp","touch","ln","cd","export","unset","wait"]);function NT(n){let t=n.replace(/\\\n/g," ").trim().split(/[|;&]/).shift()?.trim()??"";if(!t)return null;let r=t.split(/\s+/),s=0;for(;s<r.length&&/^[A-Za-z_]\w*=/.test(r[s]);)s++;let o=/^(?:timeout|time|nice|nohup|stdbuf|command|builtin|exec)$/;for(;s<r.length;){let c=r[s];if(o.test(c)){for(s++;s<r.length&&/^[-+]/.test(r[s]);)s++;s<r.length&&/^\d+(?:\.\d+)?[smhd]?$/.test(r[s])&&s++;continue}break}if(s>=r.length)return null;let i=r[s],a=i.lastIndexOf("/");return a>=0?i.slice(a+1):i}function tp(n){return/(?:^|[;&|])\s*(?:cd|pushd|popd)\b/.test(n)}function Ea(n){let e=NT(n),t=e!==null&&Ju.has(e),r=e!==null&&Qu.has(e),s=e!==null&&Zu.has(e),o=e!==null&&ep.has(e),i=/(?:[^2]>|^>|\|>)/.test(n),a=tp(n),c=(t||r||s)&&!i&&!a;return{firstCommand:e,isSearch:t,isRead:r,isList:s,isSilent:o,isConcurrencySafe:c,isReadOnly:c}}var DT=n=>({isError:n!==0,message:n!==0?`Command failed with exit code ${n}`:void 0}),OT=new Map([["grep",n=>({isError:n>=2,message:n===1?"No matches found":void 0})],["rg",n=>({isError:n>=2,message:n===1?"No matches found":void 0})],["egrep",n=>({isError:n>=2,message:n===1?"No matches found":void 0})],["fgrep",n=>({isError:n>=2,message:n===1?"No matches found":void 0})],["ag",n=>({isError:n>=2,message:n===1?"No matches found":void 0})],["find",n=>({isError:n>=2,message:n===1?"Some directories were inaccessible":void 0})],["diff",n=>({isError:n>=2,message:n===1?"Files differ":void 0})],["test",n=>({isError:n>=2,message:n===1?"Condition is false":void 0})],["[",n=>({isError:n>=2,message:n===1?"Condition is false":void 0})],["cmp",n=>({isError:n>=2,message:n===1?"Files differ":void 0})]]);function LT(n){let e=n.trim(),t=e.split(/\s*\|\s*/);return(t[t.length-1]??e).trim().split(/\s+/)[0]??""}function Ca(n,e,t,r){let s=LT(n);return(OT.get(s)??DT)(e,t,r)}function Ma(n){return/(?:^|[;&|])\s*sleep\s+\d/i.test(n)?"sleep command blocks execution \u2014 use run_in_background: true":/\bwhile\s+(?:true|:|\[\s*1\s*\])\b/.test(n)?"infinite loop \u2014 use run_in_background: true or monitor tool":null}import{spawn as XT}from"node:child_process";import{constants as Rs,readFileSync as YT,unlinkSync as JT}from"node:fs";import{mkdir as QT,open as ZT,realpath as op}from"node:fs/promises";import{isAbsolute as eR,resolve as tR}from"node:path";function ln(){if(process.platform!=="win32")return!1;let n=process.env.QLOGICAGENT_USE_POWERSHELL;return n==="1"||n==="true"}function Na(){return ln()?"powershell":"bash"}function Da(){return Math.floor(Math.random()*65536).toString(16).padStart(4,"0")}import{mkdir as $T,readFile as jT,writeFile as UT,unlink as FT}from"node:fs/promises";import{join as np}from"node:path";import{tmpdir as BT}from"node:os";var HT=8*1024*1024,qT=5*1024*1024*1024;var Oa;function ur(){if(!Oa){let n=Math.random().toString(36).slice(2,10);Oa=np(BT(),"qla-tasks",n)}return Oa}function rp(n){return np(ur(),`${n}.output`)}function Bt(n="local_bash"){return`${n}-${Date.now()}-${Math.random().toString(36).slice(2,8)}`}var Yt=class{taskId;path;stdoutToFile;#e="";#n="";#s=0;#o=0;#t;#i;#r=0;#a=!1;constructor(e,t,r=!1,s=HT){this.taskId=e,this.path=rp(e),this.stdoutToFile=r,this.#t=s,this.#i=t}writeStdout(e){this.#e+=e,this.#o+=e.length,this.#s+=WT(e),this.#d()}writeStderr(e){this.#n+=e}async getStdout(){if(this.stdoutToFile)try{let e=await jT(this.path,"utf-8");return this.#r=Buffer.byteLength(e),e}catch{return""}return this.#e}getStderr(){return this.#n}get outputFileSize(){return this.#r}get outputFileRedundant(){return this.#r<=this.#t}#d(){this.#e.length>this.#t&&this.spillToDisk()}spillToDisk(){this.#e.length!==0&&$T(ur(),{recursive:!0}).then(()=>UT(this.path,this.#e).catch(()=>{}))}async deleteOutputFile(){try{await FT(this.path)}catch{}}clear(){this.#a||(this.#a=!0,this.#e="",this.#n="",this.#i=null,this.deleteOutputFile())}};function WT(n){let e=0;for(let t=0;t<n.length;t++)n.charCodeAt(t)===10&&e++;return e}var La=137,sp=143,GT=5e3,$a=5*1024*1024*1024,Ss=class{#e;#n;#s;#o=!1;constructor(e,t,r){this.#e=e,this.#n=t,this.#s=r,e.setEncoding("utf-8"),e.on("data",this.#t)}#t=e=>{let t=typeof e=="string"?e:e.toString();this.#s?this.#n.writeStderr(t):this.#n.writeStdout(t)};cleanup(){this.#o||(this.#o=!0,this.#e.removeListener("data",this.#t),this.#e=null,this.#n=null)}},ja=class n{#e="running";#n;#s;#o;#t;#i=null;#r=null;#a=!1;#d;#c;#u;#g;#b;#p=null;#m=null;#l=null;taskOutput;result;onTimeout;constructor(e,t,r,s,o=!1,i=$a){this.#t=e,this.#c=t,this.#g=r,this.#b=o,this.#d=i,this.taskOutput=s,this.#o=e.stderr?new Ss(e.stderr,s,!0):null,this.#s=e.stdout?new Ss(e.stdout,s,!1):null,o&&(this.onTimeout=a=>{this.#u=a}),this.result=this.#w()}get status(){return this.#e}static#k(e){e.#b&&e.#u?e.#u(e.background.bind(e)):e.#y(sp)}#S(){this.#c.reason!=="interrupt"&&this.kill()}#T(e,t){let r=e??(t==="SIGTERM"?144:1);this.#f(r)}#R(){this.#f(1)}#f(e){this.#m&&(this.#m(e),this.#m=null)}#h(){this.#v(),this.#i&&(clearTimeout(this.#i),this.#i=null),this.#l&&(this.#c.removeEventListener("abort",this.#l),this.#l=null)}#v(){this.#r&&(clearInterval(this.#r),this.#r=null)}#A(){this.#r=setInterval(()=>{import("node:fs/promises").then(({stat:e})=>e(this.taskOutput.path).then(t=>{t.size>this.#d&&this.#e==="backgrounded"&&this.#r!==null&&(this.#a=!0,this.#v(),this.#y(La))},()=>{}))},GT),this.#r.unref?.()}#w(){this.#l=this.#S.bind(this),this.#c.addEventListener("abort",this.#l,{once:!0}),this.#t.once("exit",this.#T.bind(this)),this.#t.once("error",this.#R.bind(this)),this.#i=setTimeout(n.#k,this.#g,this);let e=new Promise(t=>{this.#m=t});return new Promise(t=>{this.#p=t,e.then(this.#x.bind(this))})}async#x(e){this.#h(),(this.#e==="running"||this.#e==="backgrounded")&&(this.#e="completed");let t=await this.taskOutput.getStdout(),r={code:e,stdout:t,stderr:this.taskOutput.getStderr(),interrupted:e===La,backgroundTaskId:this.#n};this.taskOutput.stdoutToFile&&!this.#n&&(this.taskOutput.outputFileRedundant?this.taskOutput.deleteOutputFile():(r.outputFilePath=this.taskOutput.path,r.outputFileSize=this.taskOutput.outputFileSize)),this.#a?r.stderr=`Background command killed: output file exceeded ${$a} bytes. ${r.stderr}`:e===sp&&(r.stderr=`Command timed out after ${this.#g}ms. ${r.stderr}`),this.#p&&(this.#p(r),this.#p=null)}#y(e){this.#e="killed";let t=this.#t.pid;if(t)try{if(process.platform==="win32")import("node:child_process").then(({execSync:r})=>{try{r(`taskkill /PID ${t} /T /F`,{stdio:"ignore"})}catch{}});else try{process.kill(-t,"SIGKILL")}catch{try{process.kill(t,"SIGKILL")}catch{}}}catch{try{this.#t.kill("SIGKILL")}catch{}}this.#f(e??La)}kill(){this.#y()}background(e){return this.#e==="running"?(this.#n=e,this.#e="backgrounded",this.#h(),this.taskOutput.stdoutToFile?this.#A():this.taskOutput.spillToDisk(),!0):!1}cleanup(){this.#s?.cleanup(),this.#o?.cleanup(),this.taskOutput.clear(),this.#h(),this.#t=null,this.#c=null,this.#u=void 0}};function Ua(n,e,t,r,s=!1,o=$a){return new ja(n,e,t,r,s,o)}function Ts(n,e){let t=new Yt(Bt("local_bash"),null);return{status:"killed",result:Promise.resolve({code:e?.code??145,stdout:"",stderr:e?.stderr??"Command aborted before execution",interrupted:!0,backgroundTaskId:n}),taskOutput:t,background:()=>!1,kill:()=>{},cleanup:()=>{}}}function Fa(n){let e=new Yt(Bt("local_bash"),null);return{status:"completed",result:Promise.resolve({code:1,stdout:"",stderr:n,interrupted:!1,preSpawnError:n}),taskOutput:e,background:()=>!1,kill:()=>{},cleanup:()=>{}}}var KT=new Set(["API_KEY","ANTHROPIC_API_KEY","OPENAI_API_KEY","DEEPSEEK_API_KEY","DOUBAO_API_KEY","MINIMAX_API_KEY","GLM_API_KEY","KIMI_API_KEY","QWEN_API_KEY","MOONSHOT_API_KEY","ZHIPU_API_KEY","BAICHUAN_API_KEY","VOLCENGINE_API_KEY","AWS_SECRET_ACCESS_KEY","AWS_SESSION_TOKEN","GOOGLE_APPLICATION_CREDENTIALS","AZURE_CLIENT_SECRET","AZURE_CLIENT_ID","AZURE_TENANT_ID","ACTIONS_ID_TOKEN_REQUEST_TOKEN","ACTIONS_RUNTIME_TOKEN","GITHUB_TOKEN","GH_TOKEN","GITLAB_TOKEN","CI_JOB_TOKEN","DATABASE_URL","REDIS_URL","REDIS_PASSWORD"]),VT=["_SECRET","_TOKEN","_PASSWORD","_CREDENTIAL","_API_KEY","SECRET_","TOKEN_","PASSWORD_","CREDENTIAL_","_AUTH_","PRIVATE_KEY"];function Ba(){let n={...process.env};for(let e of Object.keys(n))zT(e)&&delete n[e];return n}function zT(n){if(KT.has(n))return!0;let e=n.toUpperCase();for(let t of VT)if(e.includes(t))return!0;return!1}var nR=1800*1e3,As=process.cwd(),ip=process.cwd();function ws(){return As}function Ha(n,e){As=eR(n)?n:tR(e||As,n)}function ap(){return ip}function xs(n){As=n,ip=n}var qa=null;function pr(n){qa={provider:n}}function cp(){if(!qa)throw new Error("Shell provider not configured. Call setShellProvider() at startup.");return qa.provider}async function Ps(n,e,t,r){let{timeout:s,onProgress:o,preventCwdChanges:i,shouldAutoBackground:a,onStdout:c,cwd:l}=r??{},d=s||nR,u=t??Na(),p=cp(),m=Da(),{commandString:h,cwdFilePath:f}=await p.buildExecCommand(n,{id:m,useSandbox:!1}),y=h,b=l??ws();try{await op(b)}catch{let T=ap();try{await op(T),Ha(T),b=T}catch{return Fa(`Working directory "${b}" no longer exists.`)}}if(e.aborted)return Ts();let k=p.shellPath,A=p.getSpawnArgs(y),_=await p.getEnvironmentOverrides(n),I=!!c,N=Bt("local_bash"),L=new Yt(N,o??null,!I);await QT(ur(),{recursive:!0});let F;if(!I){let T=Rs.O_NOFOLLOW??0;F=await ZT(L.path,process.platform==="win32"?"w":Rs.O_WRONLY|Rs.O_CREAT|Rs.O_APPEND|T)}try{let T=XT(k,A,{env:{...Ba(),GIT_EDITOR:"true",QLOGICAGENT:"1",..._},cwd:b,stdio:I?["pipe","pipe","pipe"]:["pipe",F?.fd,F?.fd],detached:p.detached,windowsHide:!0}),ce=Ua(T,e,d,L,a);if(F!==void 0)try{await F.close()}catch{}return T.stdout&&c&&T.stdout.on("data",le=>{c(typeof le=="string"?le:le.toString())}),f&&ce.result.then(le=>{if(le&&!i&&!le.backgroundTaskId){try{let j=YT(f,{encoding:"utf8"}).trim();j&&j.normalize("NFC")!==b&&Ha(j,b)}catch{}try{JT(f)}catch{}}}),ce}catch(T){if(F!==void 0)try{await F.close()}catch{}return L.clear(),Ts(void 0,{code:126,stderr:T instanceof Error?T.message:String(T)})}}var oR="exec",iR={type:"object",properties:{command:{type:"string",description:ln()?"Shell command to execute in PowerShell.":"Shell command to execute in bash. Use Unix-style commands (ls, cat, mkdir -p, etc.)."},description:{type:"string",description:'Clear, concise description of what this command does (e.g. "Install dependencies", "Run unit tests"). Used for UI display and permission logging. For simple commands keep it 5-10 words; for complex piped/flagged commands add enough context to clarify intent.'},workdir:{type:"string",description:"Working directory for the command."},timeout:{type:"number",description:"Timeout in milliseconds (default: 120000). Only applies to foreground commands. Max allowed: 600000 (10 min)."},background:{type:"boolean",description:"If true, start the command in the background and return immediately with a task ID. Use getOutput to check on it later. Good for dev servers, watchers, long builds. Default: false."}},required:["command"]},aR=12e4,cR=6e5,Is=3e4;function Wa(n,e){if(n.length<=e)return n;let t=Math.floor(e/2)-50;return`${n.slice(0,t)}
|
|
495
|
+
`)}],details:{type:"task",action:"get",task:y}}}return{name:ET,label:"Task",description:"Manage a structured task list to track multi-step work progress. Actions: create (add task), update (modify by id), delete (remove by id), list (read all), get (single task). Supports dependency tracking (blocks/blockedBy) \u2014 tasks cannot start until blockers complete. Use frequently during complex work to plan steps, coordinate subagents, and show progress.",parameters:MT,searchHint:"manage session task checklist progress tracking dependencies planning",maxResultSizeChars:1e5,execute:async(f,y)=>{let b=y.action;switch(b){case"create":return u(y);case"update":return p(y);case"delete":return m(y);case"list":return c();case"get":return h(y);default:return a(`Unknown action: ${b}. Valid: create, update, delete, list, get.`)}}}}import{isAbsolute as rR,resolve as sR}from"node:path";var Qu=new Set(["find","grep","rg","ag","ack","locate","which","whereis"]),Zu=new Set(["cat","head","tail","less","more","wc","stat","file","strings","jq","awk","cut","sort","uniq","tr"]),ep=new Set(["ls","tree","du"]);var tp=new Set(["mv","cp","rm","mkdir","rmdir","chmod","chown","chgrp","touch","ln","cd","export","unset","wait"]);function NT(n){let t=n.replace(/\\\n/g," ").trim().split(/[|;&]/).shift()?.trim()??"";if(!t)return null;let r=t.split(/\s+/),s=0;for(;s<r.length&&/^[A-Za-z_]\w*=/.test(r[s]);)s++;let o=/^(?:timeout|time|nice|nohup|stdbuf|command|builtin|exec)$/;for(;s<r.length;){let c=r[s];if(o.test(c)){for(s++;s<r.length&&/^[-+]/.test(r[s]);)s++;s<r.length&&/^\d+(?:\.\d+)?[smhd]?$/.test(r[s])&&s++;continue}break}if(s>=r.length)return null;let i=r[s],a=i.lastIndexOf("/");return a>=0?i.slice(a+1):i}function np(n){return/(?:^|[;&|])\s*(?:cd|pushd|popd)\b/.test(n)}function Ea(n){let e=NT(n),t=e!==null&&Qu.has(e),r=e!==null&&Zu.has(e),s=e!==null&&ep.has(e),o=e!==null&&tp.has(e),i=/(?:[^2]>|^>|\|>)/.test(n),a=np(n),c=(t||r||s)&&!i&&!a;return{firstCommand:e,isSearch:t,isRead:r,isList:s,isSilent:o,isConcurrencySafe:c,isReadOnly:c}}var DT=n=>({isError:n!==0,message:n!==0?`Command failed with exit code ${n}`:void 0}),OT=new Map([["grep",n=>({isError:n>=2,message:n===1?"No matches found":void 0})],["rg",n=>({isError:n>=2,message:n===1?"No matches found":void 0})],["egrep",n=>({isError:n>=2,message:n===1?"No matches found":void 0})],["fgrep",n=>({isError:n>=2,message:n===1?"No matches found":void 0})],["ag",n=>({isError:n>=2,message:n===1?"No matches found":void 0})],["find",n=>({isError:n>=2,message:n===1?"Some directories were inaccessible":void 0})],["diff",n=>({isError:n>=2,message:n===1?"Files differ":void 0})],["test",n=>({isError:n>=2,message:n===1?"Condition is false":void 0})],["[",n=>({isError:n>=2,message:n===1?"Condition is false":void 0})],["cmp",n=>({isError:n>=2,message:n===1?"Files differ":void 0})]]);function LT(n){let e=n.trim(),t=e.split(/\s*\|\s*/);return(t[t.length-1]??e).trim().split(/\s+/)[0]??""}function Ca(n,e,t,r){let s=LT(n);return(OT.get(s)??DT)(e,t,r)}function Ma(n){return/(?:^|[;&|])\s*sleep\s+\d/i.test(n)?"sleep command blocks execution \u2014 use run_in_background: true":/\bwhile\s+(?:true|:|\[\s*1\s*\])\b/.test(n)?"infinite loop \u2014 use run_in_background: true or monitor tool":null}import{spawn as XT}from"node:child_process";import{constants as Rs,readFileSync as YT,unlinkSync as JT}from"node:fs";import{mkdir as QT,open as ZT,realpath as ip}from"node:fs/promises";import{isAbsolute as eR,resolve as tR}from"node:path";function ln(){if(process.platform!=="win32")return!1;let n=process.env.QLOGICAGENT_USE_POWERSHELL;return n==="1"||n==="true"}function Na(){return ln()?"powershell":"bash"}function Da(){return Math.floor(Math.random()*65536).toString(16).padStart(4,"0")}import{mkdir as $T,readFile as jT,writeFile as UT,unlink as FT}from"node:fs/promises";import{join as rp}from"node:path";import{tmpdir as BT}from"node:os";var HT=8*1024*1024,qT=5*1024*1024*1024;var Oa;function ur(){if(!Oa){let n=Math.random().toString(36).slice(2,10);Oa=rp(BT(),"qla-tasks",n)}return Oa}function sp(n){return rp(ur(),`${n}.output`)}function Bt(n="local_bash"){return`${n}-${Date.now()}-${Math.random().toString(36).slice(2,8)}`}var Yt=class{taskId;path;stdoutToFile;#e="";#n="";#s=0;#o=0;#t;#i;#r=0;#a=!1;constructor(e,t,r=!1,s=HT){this.taskId=e,this.path=sp(e),this.stdoutToFile=r,this.#t=s,this.#i=t}writeStdout(e){this.#e+=e,this.#o+=e.length,this.#s+=WT(e),this.#d()}writeStderr(e){this.#n+=e}async getStdout(){if(this.stdoutToFile)try{let e=await jT(this.path,"utf-8");return this.#r=Buffer.byteLength(e),e}catch{return""}return this.#e}getStderr(){return this.#n}get outputFileSize(){return this.#r}get outputFileRedundant(){return this.#r<=this.#t}#d(){this.#e.length>this.#t&&this.spillToDisk()}spillToDisk(){this.#e.length!==0&&$T(ur(),{recursive:!0}).then(()=>UT(this.path,this.#e).catch(()=>{}))}async deleteOutputFile(){try{await FT(this.path)}catch{}}clear(){this.#a||(this.#a=!0,this.#e="",this.#n="",this.#i=null,this.deleteOutputFile())}};function WT(n){let e=0;for(let t=0;t<n.length;t++)n.charCodeAt(t)===10&&e++;return e}var La=137,op=143,GT=5e3,$a=5*1024*1024*1024,Ss=class{#e;#n;#s;#o=!1;constructor(e,t,r){this.#e=e,this.#n=t,this.#s=r,e.setEncoding("utf-8"),e.on("data",this.#t)}#t=e=>{let t=typeof e=="string"?e:e.toString();this.#s?this.#n.writeStderr(t):this.#n.writeStdout(t)};cleanup(){this.#o||(this.#o=!0,this.#e.removeListener("data",this.#t),this.#e=null,this.#n=null)}},ja=class n{#e="running";#n;#s;#o;#t;#i=null;#r=null;#a=!1;#d;#c;#u;#g;#b;#p=null;#m=null;#l=null;taskOutput;result;onTimeout;constructor(e,t,r,s,o=!1,i=$a){this.#t=e,this.#c=t,this.#g=r,this.#b=o,this.#d=i,this.taskOutput=s,this.#o=e.stderr?new Ss(e.stderr,s,!0):null,this.#s=e.stdout?new Ss(e.stdout,s,!1):null,o&&(this.onTimeout=a=>{this.#u=a}),this.result=this.#w()}get status(){return this.#e}static#k(e){e.#b&&e.#u?e.#u(e.background.bind(e)):e.#y(op)}#S(){this.#c.reason!=="interrupt"&&this.kill()}#T(e,t){let r=e??(t==="SIGTERM"?144:1);this.#f(r)}#R(){this.#f(1)}#f(e){this.#m&&(this.#m(e),this.#m=null)}#h(){this.#v(),this.#i&&(clearTimeout(this.#i),this.#i=null),this.#l&&(this.#c.removeEventListener("abort",this.#l),this.#l=null)}#v(){this.#r&&(clearInterval(this.#r),this.#r=null)}#A(){this.#r=setInterval(()=>{import("node:fs/promises").then(({stat:e})=>e(this.taskOutput.path).then(t=>{t.size>this.#d&&this.#e==="backgrounded"&&this.#r!==null&&(this.#a=!0,this.#v(),this.#y(La))},()=>{}))},GT),this.#r.unref?.()}#w(){this.#l=this.#S.bind(this),this.#c.addEventListener("abort",this.#l,{once:!0}),this.#t.once("exit",this.#T.bind(this)),this.#t.once("error",this.#R.bind(this)),this.#i=setTimeout(n.#k,this.#g,this);let e=new Promise(t=>{this.#m=t});return new Promise(t=>{this.#p=t,e.then(this.#x.bind(this))})}async#x(e){this.#h(),(this.#e==="running"||this.#e==="backgrounded")&&(this.#e="completed");let t=await this.taskOutput.getStdout(),r={code:e,stdout:t,stderr:this.taskOutput.getStderr(),interrupted:e===La,backgroundTaskId:this.#n};this.taskOutput.stdoutToFile&&!this.#n&&(this.taskOutput.outputFileRedundant?this.taskOutput.deleteOutputFile():(r.outputFilePath=this.taskOutput.path,r.outputFileSize=this.taskOutput.outputFileSize)),this.#a?r.stderr=`Background command killed: output file exceeded ${$a} bytes. ${r.stderr}`:e===op&&(r.stderr=`Command timed out after ${this.#g}ms. ${r.stderr}`),this.#p&&(this.#p(r),this.#p=null)}#y(e){this.#e="killed";let t=this.#t.pid;if(t)try{if(process.platform==="win32")import("node:child_process").then(({execSync:r})=>{try{r(`taskkill /PID ${t} /T /F`,{stdio:"ignore"})}catch{}});else try{process.kill(-t,"SIGKILL")}catch{try{process.kill(t,"SIGKILL")}catch{}}}catch{try{this.#t.kill("SIGKILL")}catch{}}this.#f(e??La)}kill(){this.#y()}background(e){return this.#e==="running"?(this.#n=e,this.#e="backgrounded",this.#h(),this.taskOutput.stdoutToFile?this.#A():this.taskOutput.spillToDisk(),!0):!1}cleanup(){this.#s?.cleanup(),this.#o?.cleanup(),this.taskOutput.clear(),this.#h(),this.#t=null,this.#c=null,this.#u=void 0}};function Ua(n,e,t,r,s=!1,o=$a){return new ja(n,e,t,r,s,o)}function Ts(n,e){let t=new Yt(Bt("local_bash"),null);return{status:"killed",result:Promise.resolve({code:e?.code??145,stdout:"",stderr:e?.stderr??"Command aborted before execution",interrupted:!0,backgroundTaskId:n}),taskOutput:t,background:()=>!1,kill:()=>{},cleanup:()=>{}}}function Fa(n){let e=new Yt(Bt("local_bash"),null);return{status:"completed",result:Promise.resolve({code:1,stdout:"",stderr:n,interrupted:!1,preSpawnError:n}),taskOutput:e,background:()=>!1,kill:()=>{},cleanup:()=>{}}}var KT=new Set(["API_KEY","ANTHROPIC_API_KEY","OPENAI_API_KEY","DEEPSEEK_API_KEY","DOUBAO_API_KEY","MINIMAX_API_KEY","GLM_API_KEY","KIMI_API_KEY","QWEN_API_KEY","MOONSHOT_API_KEY","ZHIPU_API_KEY","BAICHUAN_API_KEY","VOLCENGINE_API_KEY","AWS_SECRET_ACCESS_KEY","AWS_SESSION_TOKEN","GOOGLE_APPLICATION_CREDENTIALS","AZURE_CLIENT_SECRET","AZURE_CLIENT_ID","AZURE_TENANT_ID","ACTIONS_ID_TOKEN_REQUEST_TOKEN","ACTIONS_RUNTIME_TOKEN","GITHUB_TOKEN","GH_TOKEN","GITLAB_TOKEN","CI_JOB_TOKEN","DATABASE_URL","REDIS_URL","REDIS_PASSWORD"]),VT=["_SECRET","_TOKEN","_PASSWORD","_CREDENTIAL","_API_KEY","SECRET_","TOKEN_","PASSWORD_","CREDENTIAL_","_AUTH_","PRIVATE_KEY"];function Ba(){let n={...process.env};for(let e of Object.keys(n))zT(e)&&delete n[e];return n}function zT(n){if(KT.has(n))return!0;let e=n.toUpperCase();for(let t of VT)if(e.includes(t))return!0;return!1}var nR=1800*1e3,As=process.cwd(),ap=process.cwd();function ws(){return As}function Ha(n,e){As=eR(n)?n:tR(e||As,n)}function cp(){return ap}function xs(n){As=n,ap=n}var qa=null;function pr(n){qa={provider:n}}function lp(){if(!qa)throw new Error("Shell provider not configured. Call setShellProvider() at startup.");return qa.provider}async function Ps(n,e,t,r){let{timeout:s,onProgress:o,preventCwdChanges:i,shouldAutoBackground:a,onStdout:c,cwd:l}=r??{},d=s||nR,u=t??Na(),p=lp(),m=Da(),{commandString:h,cwdFilePath:f}=await p.buildExecCommand(n,{id:m,useSandbox:!1}),y=h,b=l??ws();try{await ip(b)}catch{let T=cp();try{await ip(T),Ha(T),b=T}catch{return Fa(`Working directory "${b}" no longer exists.`)}}if(e.aborted)return Ts();let k=p.shellPath,A=p.getSpawnArgs(y),_=await p.getEnvironmentOverrides(n),I=!!c,N=Bt("local_bash"),L=new Yt(N,o??null,!I);await QT(ur(),{recursive:!0});let F;if(!I){let T=Rs.O_NOFOLLOW??0;F=await ZT(L.path,process.platform==="win32"?"w":Rs.O_WRONLY|Rs.O_CREAT|Rs.O_APPEND|T)}try{let T=XT(k,A,{env:{...Ba(),GIT_EDITOR:"true",QLOGICAGENT:"1",..._},cwd:b,stdio:I?["pipe","pipe","pipe"]:["pipe",F?.fd,F?.fd],detached:p.detached,windowsHide:!0}),ce=Ua(T,e,d,L,a);if(F!==void 0)try{await F.close()}catch{}return T.stdout&&c&&T.stdout.on("data",le=>{c(typeof le=="string"?le:le.toString())}),f&&ce.result.then(le=>{if(le&&!i&&!le.backgroundTaskId){try{let j=YT(f,{encoding:"utf8"}).trim();j&&j.normalize("NFC")!==b&&Ha(j,b)}catch{}try{JT(f)}catch{}}}),ce}catch(T){if(F!==void 0)try{await F.close()}catch{}return L.clear(),Ts(void 0,{code:126,stderr:T instanceof Error?T.message:String(T)})}}var oR="exec",iR={type:"object",properties:{command:{type:"string",description:ln()?"Shell command to execute in PowerShell.":"Shell command to execute in bash. Use Unix-style commands (ls, cat, mkdir -p, etc.)."},description:{type:"string",description:'Clear, concise description of what this command does (e.g. "Install dependencies", "Run unit tests"). Used for UI display and permission logging. For simple commands keep it 5-10 words; for complex piped/flagged commands add enough context to clarify intent.'},workdir:{type:"string",description:"Working directory for the command."},timeout:{type:"number",description:"Timeout in milliseconds (default: 120000). Only applies to foreground commands. Max allowed: 600000 (10 min)."},background:{type:"boolean",description:"If true, start the command in the background and return immediately with a task ID. Use getOutput to check on it later. Good for dev servers, watchers, long builds. Default: false."}},required:["command"]},aR=12e4,cR=6e5,Is=3e4;function Wa(n,e){if(n.length<=e)return n;let t=Math.floor(e/2)-50;return`${n.slice(0,t)}
|
|
496
496
|
|
|
497
497
|
... [truncated ${n.length-e} chars] ...
|
|
498
498
|
|
|
499
|
-
${n.slice(-t)}`}function lR(n){return n==null||n<=0?aR:Math.min(n,cR)}async function*dR(n){let{command:e,abortController:t,timeout:r,shouldAutoBackground:s,cwd:o}=n,i="",a=0,c=0,l=Date.now(),d=null;function u(){return new Promise(h=>{d=()=>h(null)})}let p=await Ps(e,t.signal,void 0,{timeout:r,onProgress(h,f,y,b,k){i=f,a=y,c=b,d&&(d(),d=null)},shouldAutoBackground:s,cwd:o});for(p.onTimeout&&s&&p.onTimeout(h=>{let f=Bt("bg");h(f)});p.status==="running"&&await Promise.race([u(),p.result])===null;)yield{type:"exec_progress",output:i.slice(-4096),fullOutput:i,elapsedTimeSeconds:(Date.now()-l)/1e3,totalLines:a,totalBytes:c};let m=await p.result;return p.cleanup(),m}function
|
|
499
|
+
${n.slice(-t)}`}function lR(n){return n==null||n<=0?aR:Math.min(n,cR)}async function*dR(n){let{command:e,abortController:t,timeout:r,shouldAutoBackground:s,cwd:o}=n,i="",a=0,c=0,l=Date.now(),d=null;function u(){return new Promise(h=>{d=()=>h(null)})}let p=await Ps(e,t.signal,void 0,{timeout:r,onProgress(h,f,y,b,k){i=f,a=y,c=b,d&&(d(),d=null)},shouldAutoBackground:s,cwd:o});for(p.onTimeout&&s&&p.onTimeout(h=>{let f=Bt("bg");h(f)});p.status==="running"&&await Promise.race([u(),p.result])===null;)yield{type:"exec_progress",output:i.slice(-4096),fullOutput:i,elapsedTimeSeconds:(Date.now()-l)/1e3,totalLines:a,totalBytes:c};let m=await p.result;return p.cleanup(),m}function dp(n={}){return{name:oR,label:"Execute Command",description:"Execute a shell command. Supports foreground (blocking, returns output) and background (non-blocking, returns task ID) modes. "+(ln()?"Uses PowerShell. ":"Uses bash. ")+`Commands are classified for safety: search/read commands may run in parallel; silent commands (mv, cp, rm) show 'Done' instead of empty output. Output is truncated and persisted if too long.
|
|
500
500
|
IMPORTANT: Do NOT use this tool for file operations when dedicated tools exist. Use the 'write' tool instead of echo/cat/heredoc for creating files. Use the 'edit' tool instead of sed/awk for modifying files. Use the 'read' tool instead of cat/head/tail for reading files. Reserve this tool exclusively for system commands, builds, tests, and terminal operations that require shell execution.`,searchHint:"execute shell commands",parameters:iR,maxResultSizeChars:Is,execute:async(e,t)=>{let r=Ea(t.command);if(!t.background){let m=Ma(t.command);if(m)return{content:[{type:"text",text:`Command blocked: ${m}`}],details:{type:"exec",error:"blocked_sleep_pattern",classification:r}}}if(n.validateCommand){let m=await n.validateCommand(t.command);if(m)return{content:[{type:"text",text:`Command blocked: ${m}`}],details:{type:"exec",error:"blocked_by_guard",reason:m,classification:r}}}let s=new AbortController,o=lR(t.timeout),i=t.workdir?rR(t.workdir)?t.workdir:sR(ws(),t.workdir):void 0;if(t.background){let m=await Ps(t.command,s.signal,void 0,{shouldAutoBackground:!1,cwd:i}),h=Bt("bg");if(m.background(h))return{content:[{type:"text",text:`Background task started (id: ${h}).
|
|
501
501
|
Use getOutput to check on it later.`}],details:{type:"exec_background",backgroundTaskId:h,description:t.description,classification:r}}}let a=dR({command:t.command,abortController:s,timeout:o,shouldAutoBackground:!0,cwd:i}),c;do c=await a.next(),!c.done&&n.onProgress&&n.onProgress(c.value);while(!c.done);let l=c.value,d=[];if(l.backgroundTaskId)return{content:[{type:"text",text:`Command auto-backgrounded (task: ${l.backgroundTaskId}).`}],details:{type:"exec_background",backgroundTaskId:l.backgroundTaskId,assistantAutoBackgrounded:l.assistantAutoBackgrounded,classification:r}};l.outputFilePath?(d.push(Wa(l.stdout,Is)),d.push(`[full output: ${l.outputFilePath} (${l.outputFileSize} bytes)]`)):l.stdout&&d.push(Wa(l.stdout,Is)),l.stderr&&d.push(`[stderr]
|
|
502
502
|
${Wa(l.stderr,Math.floor(Is/4))}`),l.interrupted&&d.push(`[interrupted \u2014 exit code ${l.code}]`);let u=l.code!==0?Ca(t.command,l.code,l.stdout,l.stderr):void 0;u&&!u.isError&&u.message&&d.push(`[exit ${l.code}: ${u.message}]`);let p;return l.code!==0&&n.interpretExitCode&&(!u||u.isError)&&(p=n.interpretExitCode(l.code,l.stderr),p&&d.push(`[exit ${l.code}: ${p}]`)),d.length===0&&d.push(r.isSilent&&l.code===0?"Done":`(exit code ${l.code}, no output)`),{content:[{type:"text",text:d.join(`
|
|
503
|
-
`)}],details:{type:"exec",exitCode:l.code,interrupted:l.interrupted,description:t.description,returnCodeInterpretation:p??u?.message,noOutputExpected:r.isSilent,outputFilePath:l.outputFilePath,semanticNonError:u?!u.isError:void 0,classification:r}}}}}import{tmpdir as uR}from"node:os";import{join as pR,posix as Ga}from"node:path";function mR(n){return n.replace(/(\d?)>nul\b/gi,(e,t)=>`${t||""}>/dev/null`)}function gR(n){return!(/(?:^|[;&|])\s*<\s/.test(n)||/<<[-]?\s*['"]?[A-Za-z_]/.test(n))}function fR(n,e){return`$'${n.replace(/\\/g,"\\\\").replace(/'/g,"\\'").replace(/\n/g,"\\n")}'${e?" < /dev/null":""}`}function
|
|
504
|
-
; `),i=e+o;return{commandString:t.useSandbox?[`'${n.replace(/'/g,"'\\''")}'`,"-NoProfile","-NonInteractive","-EncodedCommand",
|
|
503
|
+
`)}],details:{type:"exec",exitCode:l.code,interrupted:l.interrupted,description:t.description,returnCodeInterpretation:p??u?.message,noOutputExpected:r.isSilent,outputFilePath:l.outputFilePath,semanticNonError:u?!u.isError:void 0,classification:r}}}}}import{tmpdir as uR}from"node:os";import{join as pR,posix as Ga}from"node:path";function mR(n){return n.replace(/(\d?)>nul\b/gi,(e,t)=>`${t||""}>/dev/null`)}function gR(n){return!(/(?:^|[;&|])\s*<\s/.test(n)||/<<[-]?\s*['"]?[A-Za-z_]/.test(n))}function fR(n,e){return`$'${n.replace(/\\/g,"\\\\").replace(/'/g,"\\'").replace(/\n/g,"\\n")}'${e?" < /dev/null":""}`}function up(n){return process.platform!=="win32"?n:n.replace(/^([A-Za-z]):/,(e,t)=>`/${t.toLowerCase()}`).replace(/\\/g,"/")}function _s(n,e){let t=e?.snapshotFilePath;return{type:"bash",shellPath:n,detached:!0,async buildExecCommand(r,s){let o=process.platform==="win32",i=uR(),a=o?up(i):i,c=s.useSandbox&&s.sandboxTmpDir?Ga.join(s.sandboxTmpDir,`cwd-${s.id}`):Ga.join(a,`qla-${s.id}-cwd`),l=s.useSandbox&&s.sandboxTmpDir?Ga.join(s.sandboxTmpDir,`cwd-${s.id}`):pR(i,`qla-${s.id}-cwd`),d=mR(r),u=gR(d),p=fR(d,u),m=[];if(t){let f=o?up(t):t;m.push(`source '${f}' 2>/dev/null || true`)}return e?.sessionEnvScript&&m.push(e.sessionEnvScript),m.push(`eval ${p}`),m.push(`pwd -P >| '${c}'`),{commandString:m.join(" && "),cwdFilePath:l}},getSpawnArgs(r){return["-c",...!!t?[]:["-l"],r]},async getEnvironmentOverrides(r){return{GIT_EDITOR:"true",QLOGICAGENT:"1"}}}}import{tmpdir as hR}from"node:os";import{join as yR,posix as bR}from"node:path";function pp(n){return Buffer.from(n,"utf16le").toString("base64")}function vR(n){return["-NoProfile","-NonInteractive","-Command",n]}function Ka(n){return{type:"powershell",shellPath:n,detached:!1,async buildExecCommand(e,t){let r=t.useSandbox&&t.sandboxTmpDir?bR.join(t.sandboxTmpDir,`qla-pwd-ps-${t.id}`):yR(hR(),`qla-pwd-ps-${t.id}`),o=["","$_ec = if ($null -ne $LASTEXITCODE) { $LASTEXITCODE } elseif ($?) { 0 } else { 1 }",`(Get-Location).Path | Out-File -FilePath '${r.replace(/'/g,"''")}' -Encoding utf8 -NoNewline`,"exit $_ec"].join(`
|
|
504
|
+
; `),i=e+o;return{commandString:t.useSandbox?[`'${n.replace(/'/g,"'\\''")}'`,"-NoProfile","-NonInteractive","-EncodedCommand",pp(i)].join(" "):i,cwdFilePath:r}},getSpawnArgs(e){return vR(e)},async getEnvironmentOverrides(e){return{QLOGICAGENT:"1"}}}}var kR=[{pattern:/\bgit\s+reset\s+--hard\b/,warning:"Note: may discard uncommitted changes"},{pattern:/\bgit\s+push\b[^;&|\n]*[ \t](--force|--force-with-lease|-f)\b/,warning:"Note: may overwrite remote history"},{pattern:/\bgit\s+clean\b(?![^;&|\n]*(?:-[a-zA-Z]*n|--dry-run))[^;&|\n]*-[a-zA-Z]*f/,warning:"Note: may permanently delete untracked files"},{pattern:/\bgit\s+checkout\s+(--\s+)?\.[ \t]*($|[;&|\n])/,warning:"Note: may discard all working tree changes"},{pattern:/\bgit\s+restore\s+(--\s+)?\.[ \t]*($|[;&|\n])/,warning:"Note: may discard all working tree changes"},{pattern:/\bgit\s+stash[ \t]+(drop|clear)\b/,warning:"Note: may permanently remove stashed changes"},{pattern:/\bgit\s+branch\s+(-D[ \t]|--delete\s+--force|--force\s+--delete)\b/,warning:"Note: may force-delete a branch"},{pattern:/\bgit\s+(commit|push|merge)\b[^;&|\n]*--no-verify\b/,warning:"Note: may skip safety hooks"},{pattern:/\bgit\s+commit\b[^;&|\n]*--amend\b/,warning:"Note: may rewrite the last commit"},{pattern:/(^|[;&|\n]\s*)rm\s+-[a-zA-Z]*[rR][a-zA-Z]*f|(^|[;&|\n]\s*)rm\s+-[a-zA-Z]*f[a-zA-Z]*[rR]/,warning:"Note: may recursively force-remove files"},{pattern:/(^|[;&|\n]\s*)rm\s+-[a-zA-Z]*[rR]/,warning:"Note: may recursively remove files"},{pattern:/(^|[;&|\n]\s*)rm\s+-[a-zA-Z]*f/,warning:"Note: may force-remove files"},{pattern:/\b(DROP|TRUNCATE)\s+(TABLE|DATABASE|SCHEMA)\b/i,warning:"Note: may drop or truncate database objects"},{pattern:/\bDELETE\s+FROM\s+\w+[ \t]*(;|"|'|\n|$)/i,warning:"Note: may delete all rows from a database table"},{pattern:/\bkubectl\s+delete\b/,warning:"Note: may delete Kubernetes resources"},{pattern:/\bterraform\s+destroy\b/,warning:"Note: may destroy Terraform infrastructure"}],SR=[{pattern:/(?:^|[|;&\n({])\s*(Remove-Item|rm|del|rd|rmdir|ri)\b[^|;&\n}]*-Recurse\b[^|;&\n}]*-Force\b/i,warning:"Note: may recursively force-remove files"},{pattern:/(?:^|[|;&\n({])\s*(Remove-Item|rm|del|rd|rmdir|ri)\b[^|;&\n}]*-Force\b[^|;&\n}]*-Recurse\b/i,warning:"Note: may recursively force-remove files"},{pattern:/(?:^|[|;&\n({])\s*(Remove-Item|rm|del|rd|rmdir|ri)\b[^|;&\n}]*-Recurse\b/i,warning:"Note: may recursively remove files"},{pattern:/(?:^|[|;&\n({])\s*(Remove-Item|rm|del|rd|rmdir|ri)\b[^|;&\n}]*-Force\b/i,warning:"Note: may force-remove files"},{pattern:/\bClear-Content\b[^|;&\n]*\*/i,warning:"Note: may clear content of multiple files"},{pattern:/\bFormat-Volume\b/i,warning:"Note: may format a disk volume"},{pattern:/\bClear-Disk\b/i,warning:"Note: may clear a disk"},{pattern:/\bgit\s+reset\s+--hard\b/i,warning:"Note: may discard uncommitted changes"},{pattern:/\bgit\s+push\b[^|;&\n]*\s+(--force|--force-with-lease|-f)\b/i,warning:"Note: may overwrite remote history"},{pattern:/\bgit\s+clean\b(?![^|;&\n]*(?:-[a-zA-Z]*n|--dry-run))[^|;&\n]*-[a-zA-Z]*f/i,warning:"Note: may permanently delete untracked files"},{pattern:/\bgit\s+stash\s+(drop|clear)\b/i,warning:"Note: may permanently remove stashed changes"},{pattern:/\b(DROP|TRUNCATE)\s+(TABLE|DATABASE|SCHEMA)\b/i,warning:"Note: may drop or truncate database objects"},{pattern:/\bStop-Computer\b/i,warning:"Note: will shut down the computer"},{pattern:/\bRestart-Computer\b/i,warning:"Note: will restart the computer"},{pattern:/\bClear-RecycleBin\b/i,warning:"Note: permanently deletes recycled files"}];function Va(n){for(let{pattern:e,warning:t}of kR)if(e.test(n))return t;return null}function za(n){for(let{pattern:e,warning:t}of SR)if(e.test(n))return t;return null}var TR="read",RR={type:"object",properties:{path:{type:"string",description:"Absolute path to the file to read."},offset:{type:"number",description:"Line number to start reading from (1-indexed). Default: 1."},limit:{type:"number",description:"Maximum number of lines to read. Default/max: 2000."}},required:["path"]};function mp(n){return{name:TR,label:"Read File",description:"Read the contents of a file. Supports text files and images (jpg, png, gif, webp). For text files, output is truncated to 2000 lines or 50KB. Binary files are rejected with a hint. Use offset/limit for pagination of large files.",parameters:RR,isReadOnly:!0,execute:async(r,s)=>{let o=n.resolvePath(s.path);if(n.validatePath){let f=n.validatePath(o);if(f)return{content:[{type:"text",text:`Access denied: ${f}`}],details:{type:"read",path:o,error:"access_denied"}}}let i=await n.readFile(o);if(i.type==="image")return{content:[{type:"text",text:`[Image: ${o}] (${i.mimeType})`}],details:{type:"read",path:o,isImage:!0},imageUrls:[i.localPath]};if(i.type==="binary")return{content:[{type:"text",text:`Cannot read binary file (${i.mimeType}). Use a specific tool for this file type (e.g. pdf tool for PDFs).`}],details:{type:"read",path:o,error:"binary_file",mimeType:i.mimeType}};let a=i.text.split(`
|
|
505
505
|
`),c=Math.max(0,(s.offset??1)-1),l=Math.min(s.limit??2e3,2e3),d=a.slice(c,c+l),u=d.join(`
|
|
506
506
|
`);u.length>5e4&&(u=u.slice(0,5e4)+`
|
|
507
|
-
... (truncated)`);let p=a.length,m=c+d.length,h=m<p;return{content:[{type:"text",text:u}],details:{type:"read",path:o,totalLines:p,startLine:c+1,endLine:m,hasMore:h}}}}}var AR="write",wR={type:"object",properties:{path:{type:"string",description:"Absolute path to the file to write."},content:{type:"string",description:"Content to write to the file."}},required:["path","content"]},
|
|
508
|
-
`).length;return{content:[{type:"text",text:`Wrote ${s} lines to ${r}`}],details:{type:"write",path:r,lineCount:s}}}}}var xR="edit",PR={type:"object",properties:{path:{type:"string",description:"Path to the file to edit (relative or absolute)."},oldText:{type:"string",description:"Exact text to find and replace (must match exactly, including whitespace)."},newText:{type:"string",description:"New text to replace the old text with."}},required:["path","oldText","newText"]};function
|
|
509
|
-
`).length;return{content:[{type:"text",text:`Edited ${r} (line ${l})`}],details:{type:"edit",path:r,success:!0,firstChangedLine:l}}}}}var IR="search",_R={type:"object",properties:{mode:{type:"string",enum:["filename","content","both"],description:'Search mode: "filename" to find files by name pattern (glob), "content" to search within file contents (regex), "both" to match both filename patterns and content simultaneously.'},pattern:{type:"string",description:"The pattern to search for. In filename mode this is a glob pattern (e.g. **/*.ts). In content mode this is a regular expression. In both mode this is treated as a regex for content, and fileGlob filters the filename set."},path:{type:"string",description:"Directory to search in. Defaults to workdir/cwd if omitted."},fileGlob:{type:"string",description:'Glob pattern to filter files (e.g. "*.ts", "*.{js,tsx}"). In content/both modes, only files matching this glob are searched.'},contextLines:{type:"number",description:"Number of context lines to show before and after each match (content/both modes only). Default: 0."},caseInsensitive:{type:"boolean",description:"Case insensitive search (content/both modes). Default: false."},headLimit:{type:"number",description:"Maximum number of result entries to return. Default 100 for filename, 250 for content. Pass 0 for unlimited (use sparingly)."},offset:{type:"number",description:"Skip first N results before applying headLimit. Default: 0."}},required:["mode","pattern"]},
|
|
507
|
+
... (truncated)`);let p=a.length,m=c+d.length,h=m<p;return{content:[{type:"text",text:u}],details:{type:"read",path:o,totalLines:p,startLine:c+1,endLine:m,hasMore:h}}}}}var AR="write",wR={type:"object",properties:{path:{type:"string",description:"Absolute path to the file to write."},content:{type:"string",description:"Content to write to the file."}},required:["path","content"]},gp=5e5;function fp(n){return{name:AR,label:"Write File",description:"Write content to a file. Creates the file if it doesn't exist, overwrites if it does. Automatically creates parent directories. Prefer edit/patch for modifying existing files (safer than full overwrite). ALWAYS use this tool to create new files \u2014 never use shell commands (echo, cat, heredoc) for file creation.",parameters:wR,execute:async(e,t)=>{let r=n.resolvePath(t.path);if(n.validatePath){let o=n.validatePath(r);if(o)return{content:[{type:"text",text:`Access denied: ${o}`}],details:{type:"write",path:r,error:"access_denied"}}}if(t.content.length>gp)return{content:[{type:"text",text:`Content too large (${t.content.length} chars, max ${gp}). Split into multiple writes or use a different approach.`}],details:{type:"write",path:r,error:"content_too_large"}};if(n.checkReadBeforeWrite){let o=n.checkReadBeforeWrite(r);if(o)return{content:[{type:"text",text:o}],details:{type:"write",path:r,error:"not_read_first"}}}if(n.checkConcurrentModification){let o=n.checkConcurrentModification(r);if(o)return{content:[{type:"text",text:`Concurrent modification detected: ${o}. Re-read the file first.`}],details:{type:"write",path:r,error:"concurrent_modification"}}}await n.writeFile(r,t.content);let s=t.content.split(`
|
|
508
|
+
`).length;return{content:[{type:"text",text:`Wrote ${s} lines to ${r}`}],details:{type:"write",path:r,lineCount:s}}}}}var xR="edit",PR={type:"object",properties:{path:{type:"string",description:"Path to the file to edit (relative or absolute)."},oldText:{type:"string",description:"Exact text to find and replace (must match exactly, including whitespace)."},newText:{type:"string",description:"New text to replace the old text with."}},required:["path","oldText","newText"]};function hp(n){return{name:xR,label:"Edit File",description:"Edit a file by replacing exact text. The oldText must match exactly (including whitespace). Use this for precise, surgical edits. For multiple edits, call this tool multiple times. ALWAYS use this tool to modify existing files \u2014 never use sed/awk/shell commands for text replacement.",parameters:PR,execute:async(e,t)=>{let r=n.resolvePath(t.path);if(n.checkConcurrentModification){let d=n.checkConcurrentModification(r);if(d)return{content:[{type:"text",text:`Concurrent modification detected: ${d}. Re-read the file first.`}],details:{type:"edit",path:r,success:!1,reason:"concurrent_modification"}}}let s=await n.readFile(r),o=s.indexOf(t.oldText);if(o===-1)return{content:[{type:"text",text:`Error: oldText not found in ${r}. Ensure it matches exactly.`}],details:{type:"edit",path:r,success:!1,reason:"not_found"}};if(s.indexOf(t.oldText,o+1)!==-1)return{content:[{type:"text",text:`Error: oldText matches multiple locations in ${r}. Include more context to make the match unique.`}],details:{type:"edit",path:r,success:!1,reason:"ambiguous"}};let a=s.slice(0,o)+t.newText+s.slice(o+t.oldText.length);await n.writeFile(r,a);let l=s.slice(0,o).split(`
|
|
509
|
+
`).length;return{content:[{type:"text",text:`Edited ${r} (line ${l})`}],details:{type:"edit",path:r,success:!0,firstChangedLine:l}}}}}var IR="search",_R={type:"object",properties:{mode:{type:"string",enum:["filename","content","both"],description:'Search mode: "filename" to find files by name pattern (glob), "content" to search within file contents (regex), "both" to match both filename patterns and content simultaneously.'},pattern:{type:"string",description:"The pattern to search for. In filename mode this is a glob pattern (e.g. **/*.ts). In content mode this is a regular expression. In both mode this is treated as a regex for content, and fileGlob filters the filename set."},path:{type:"string",description:"Directory to search in. Defaults to workdir/cwd if omitted."},fileGlob:{type:"string",description:'Glob pattern to filter files (e.g. "*.ts", "*.{js,tsx}"). In content/both modes, only files matching this glob are searched.'},contextLines:{type:"number",description:"Number of context lines to show before and after each match (content/both modes only). Default: 0."},caseInsensitive:{type:"boolean",description:"Case insensitive search (content/both modes). Default: false."},headLimit:{type:"number",description:"Maximum number of result entries to return. Default 100 for filename, 250 for content. Pass 0 for unlimited (use sparingly)."},offset:{type:"number",description:"Skip first N results before applying headLimit. Default: 0."}},required:["mode","pattern"]},yp=100,bp=250,Xa=1e5;function vp(n){return{name:IR,label:"Search",description:"Search for files by name, search within file contents by regex, or both. In filename mode, pattern is a glob. In content mode, pattern is a regex. Results are paginated via headLimit + offset.",parameters:_R,isReadOnly:!0,execute:async(e,t)=>{let r=t.path?n.resolvePath?n.resolvePath(t.path):t.path:"",s=t.mode;return s==="filename"?ER(n,t,r):s==="content"?CR(n,t,r):MR(n,t,r)}}}async function ER(n,e,t){let r=e.headLimit??yp,{files:s,truncated:o}=await n.glob(e.pattern,{cwd:t,limit:r===0?1e4:r}),i=e.offset??0,a=i>0?s.slice(i):s,c=r===0?a.length:r,l=a.slice(0,c),d=o||a.length>c;if(l.length===0)return{content:[{type:"text",text:"No files found matching pattern."}],details:{mode:"filename",totalMatches:0,truncated:!1}};let u=l.join(`
|
|
510
510
|
`);return d&&(u+=`
|
|
511
511
|
|
|
512
|
-
(Results truncated. ${l.length} shown. Use a more specific pattern or increase headLimit.)`),u=Ya(u,Xa),{content:[{type:"text",text:u}],details:{mode:"filename",totalMatches:l.length,truncated:d}}}async function CR(n,e,t){let r=e.headLimit??
|
|
512
|
+
(Results truncated. ${l.length} shown. Use a more specific pattern or increase headLimit.)`),u=Ya(u,Xa),{content:[{type:"text",text:u}],details:{mode:"filename",totalMatches:l.length,truncated:d}}}async function CR(n,e,t){let r=e.headLimit??bp,{matches:s,truncated:o}=await n.grep(e.pattern,{cwd:t,fileGlob:e.fileGlob,caseInsensitive:e.caseInsensitive,contextLines:e.contextLines,headLimit:r===0?void 0:r,offset:e.offset});if(s.length===0)return{content:[{type:"text",text:"No matches found."}],details:{mode:"content",totalMatches:0,truncated:!1}};let i=[];for(let c of s){if(c.contextBefore&&c.contextBefore.length>0)for(let l of c.contextBefore)i.push(` ${l}`);if(i.push(`${c.path}:${c.line}: ${c.text}`),c.contextAfter&&c.contextAfter.length>0)for(let l of c.contextAfter)i.push(` ${l}`);e.contextLines&&e.contextLines>0&&i.push("--")}let a=i.join(`
|
|
513
513
|
`);return o&&(a+=`
|
|
514
514
|
|
|
515
|
-
(Results truncated at ${s.length} matches. Use offset/headLimit for pagination.)`),a=Ya(a,Xa),{content:[{type:"text",text:a}],details:{mode:"content",totalMatches:s.length,truncated:o}}}async function MR(n,e,t){let[r,s]=await Promise.all([e.fileGlob?n.glob(e.fileGlob,{cwd:t,limit:
|
|
515
|
+
(Results truncated at ${s.length} matches. Use offset/headLimit for pagination.)`),a=Ya(a,Xa),{content:[{type:"text",text:a}],details:{mode:"content",totalMatches:s.length,truncated:o}}}async function MR(n,e,t){let[r,s]=await Promise.all([e.fileGlob?n.glob(e.fileGlob,{cwd:t,limit:yp}):Promise.resolve({files:[],truncated:!1}),n.grep(e.pattern,{cwd:t,fileGlob:e.fileGlob,caseInsensitive:e.caseInsensitive,contextLines:e.contextLines,headLimit:e.headLimit??bp,offset:e.offset})]),o=new Set(s.matches.map(d=>d.path)),i=r.files.filter(d=>!o.has(d)),a=[];if(i.length>0&&a.push(`## Files matching glob (${i.length}):
|
|
516
516
|
${i.join(`
|
|
517
517
|
`)}`),s.matches.length>0){let d=[];for(let u of s.matches)d.push(`${u.path}:${u.line}: ${u.text}`);a.push(`## Content matches (${s.matches.length}):
|
|
518
518
|
${d.join(`
|
|
@@ -527,15 +527,15 @@ ${d.join(`
|
|
|
527
527
|
${n.slice(-t)}`}var NR="apply_patch",DR={type:"object",properties:{input:{type:"string",description:"Patch content using the *** Begin Patch / *** End Patch format."}},required:["input"]};function OR(n){let e=n.split(`
|
|
528
528
|
`),t=[],r=null,s=null,o=!1;for(let i of e){if(i.startsWith("*** Begin Patch")){o=!0;continue}if(i.startsWith("*** End Patch"))break;if(o){if(i.startsWith("*** Add File: "))r&&t.push(r),r={type:"add",path:i.slice(14).trim(),hunks:[]},s={contextBefore:[],removals:[],additions:[],contextAfter:[]},r.hunks.push(s);else if(i.startsWith("*** Update File: "))r&&t.push(r),r={type:"update",path:i.slice(17).trim(),hunks:[]},s=null;else if(i.startsWith("*** Delete File: "))r&&t.push(r),r={type:"delete",path:i.slice(17).trim(),hunks:[]},s=null;else if(i.startsWith("*** Move to: ")&&r)r.moveTo=i.slice(13).trim();else if(i.startsWith("@@ ")&&r)s={contextBefore:[],removals:[],additions:[],contextAfter:[]},r.hunks.push(s);else if(s)if(i.startsWith("+"))s.additions.push(i.slice(1));else if(i.startsWith("-"))s.removals.push(i.slice(1));else{let a=i.startsWith(" ")?i.slice(1):i;s.additions.length===0&&s.removals.length===0?s.contextBefore.push(a):s.contextAfter.push(a)}}}return r&&t.push(r),t}function LR(n,e){let r=[...n.split(`
|
|
529
529
|
`)];for(let s of e){let o=-1;if(s.contextBefore.length>0)for(let i=0;i<=r.length-s.contextBefore.length;i++){let a=!0;for(let c=0;c<s.contextBefore.length;c++)if(r[i+c]!==s.contextBefore[c]){a=!1;break}if(a){o=i+s.contextBefore.length;break}}else o=0;o!==-1&&(s.removals.length>0?r.splice(o,s.removals.length,...s.additions):r.splice(o,0,...s.additions))}return r.join(`
|
|
530
|
-
`)}function
|
|
530
|
+
`)}function kp(n){return{name:NR,label:"Apply Patch",description:"Apply a patch to one or more files using the *** Begin Patch / *** End Patch format. Supports Add File, Update File, Delete File, and Move To operations.",parameters:DR,execute:async(e,t)=>{let r=OR(t.input);if(r.length===0)return{content:[{type:"text",text:"Error: No valid patch operations found. Ensure *** Begin Patch / *** End Patch markers are present."}]};let s={added:[],modified:[],deleted:[]},o=[];for(let a of r){let c=n.resolvePath(a.path);try{switch(a.type){case"add":{let l=a.hunks.flatMap(d=>[...d.additions]).join(`
|
|
531
531
|
`);await n.writeFile(c,l),s.added.push(a.path);break}case"update":{let l=await n.readFile(c),d=LR(l,a.hunks);if(a.moveTo){let u=n.resolvePath(a.moveTo);await n.writeFile(u,d),await n.deleteFile(c),s.modified.push(`${a.path} \u2192 ${a.moveTo}`)}else await n.writeFile(c,d),s.modified.push(a.path);break}case"delete":{await n.deleteFile(c),s.deleted.push(a.path);break}}}catch(l){o.push(`${a.type} ${a.path}: ${l instanceof Error?l.message:String(l)}`)}}let i=[];return s.added.length&&i.push(`Added: ${s.added.join(", ")}`),s.modified.length&&i.push(`Modified: ${s.modified.join(", ")}`),s.deleted.length&&i.push(`Deleted: ${s.deleted.join(", ")}`),o.length&&i.push(`Errors: ${o.join("; ")}`),{content:[{type:"text",text:i.join(`
|
|
532
532
|
`)||"No changes applied."}],details:{type:"apply_patch",summary:s,errors:o}}}}}var $R="patch",jR={type:"object",properties:{input:{type:"string",description:`Patch content. Supports two formats:
|
|
533
533
|
1) V4A unified diff (*** Begin Patch / *** End Patch markers)
|
|
534
534
|
2) Simple find-replace: first line is file path, then <<<< SEARCH / ==== / >>>> REPLACE blocks.
|
|
535
535
|
Fuzzy matching automatically handles whitespace/indent/unicode drift in the search text.`},replaceAll:{type:"boolean",description:"Replace all occurrences instead of first only (default: false)."}},required:["input"]};function UR(n){return n.replace(/\\n/g,`
|
|
536
|
-
`).replace(/\\t/g," ").replace(/\\'/g,"'").replace(/\\"/g,'"')}function
|
|
536
|
+
`).replace(/\\t/g," ").replace(/\\'/g,"'").replace(/\\"/g,'"')}function Sp(n){return n.replace(/[\u201c\u201d\u201e\u201f]/g,'"').replace(/[\u2018\u2019\u201a\u201b]/g,"'").replace(/\u2014/g,"--").replace(/\u2013/g,"-").replace(/\u2026/g,"...").replace(/\u00a0/g," ")}function Tp(n,e){if(n===e||Math.max(n.length,e.length)===0)return 1;let r=0,s=n.length,o=e.length,i=Math.max(s,o);for(let a=0;a<Math.min(s,o);a++)n[a]!==e[a]&&r++;return r+=Math.abs(s-o),1-r/i}function Ip(n,e,t){let r=[],s=n.indexOf(e);if(s!==-1){if(t){let f=0;for(;(s=n.indexOf(e,f))!==-1;)r.push({start:s,end:s+e.length,strategy:"exact"}),f=s+e.length}else r.push({start:s,end:s+e.length,strategy:"exact"});return r}let o=e.split(`
|
|
537
537
|
`).map(f=>f.trim()),i=n.split(`
|
|
538
|
-
`),a=
|
|
538
|
+
`),a=Rp(i,o,(f,y)=>f.trim()===y);if(a)return[{...Ap(n,i,a),strategy:"line_trimmed"}];let c=e.replace(/[ \t]+/g," "),l=n.replace(/[ \t]+/g," ");if(s=l.indexOf(c),s!==-1){let f=wp(n,l,s,c.length);if(f)return[{...f,strategy:"whitespace_normalized"}]}let d=Rp(i,o,(f,y)=>f.trimStart()===y.trimStart());if(d)return[{...Ap(n,i,d),strategy:"indentation_flexible"}];let u=UR(e);if(u!==e&&(s=n.indexOf(u),s!==-1))return[{start:s,end:s+u.length,strategy:"escape_normalized"}];let p=e.split(`
|
|
539
539
|
`);if(p.length>=3){let f=p.slice(1,-1).join(`
|
|
540
540
|
`),y=p[0].trim(),b=p[p.length-1].trim();for(let k=0;k<i.length;k++)if(i[k].trim()===y){let A=i.slice(0,k+1).join(`
|
|
541
541
|
`).length+1,_=n.indexOf(f,A);if(_!==-1){let I=_+f.length,N=n.indexOf(`
|
|
@@ -543,25 +543,25 @@ Fuzzy matching automatically handles whitespace/indent/unicode drift in the sear
|
|
|
543
543
|
`,I+1)===-1?void 0:n.indexOf(`
|
|
544
544
|
`,I+1)).trim()===b){let F=i.slice(0,k).join(`
|
|
545
545
|
`).length+(k>0?1:0),T=k,ce=p.length;if(k+ce<=i.length){T=k+ce;let le=i.slice(0,T).join(`
|
|
546
|
-
`).length;return[{start:F,end:le,strategy:"trimmed_boundary"}]}}}}}let m=
|
|
546
|
+
`).length;return[{start:F,end:le,strategy:"trimmed_boundary"}]}}}}}let m=Sp(e),h=Sp(n);if((m!==e||h!==n)&&(s=h.indexOf(m),s!==-1)){let f=wp(n,h,s,m.length);if(f)return[{...f,strategy:"unicode_normalized"}]}if(p.length>=3){let f=p[0],y=p[p.length-1];for(let b=0;b<i.length;b++)if(i[b]===f){for(let k=b+p.length-1;k<Math.min(b+p.length+2,i.length);k++)if(i[k]===y){let A=k-b+1,_=i.slice(b+1,k),I=p.slice(1,-1),N=I.filter(F=>_.some(T=>Tp(T,F)>=.7)).length;if((I.length>0?N/I.length:1)>=.5&&A<=p.length+2){let F=i.slice(0,b).join(`
|
|
547
547
|
`).length+(b>0?1:0),T=i.slice(0,k+1).join(`
|
|
548
|
-
`).length;return[{start:F,end:T,strategy:"block_anchor"}]}}}}if(p.length>=2)for(let f=0;f<=i.length-p.length;f++){let y=i.slice(f,f+p.length);if(p.map((A,_)=>
|
|
548
|
+
`).length;return[{start:F,end:T,strategy:"block_anchor"}]}}}}if(p.length>=2)for(let f=0;f<=i.length-p.length;f++){let y=i.slice(f,f+p.length);if(p.map((A,_)=>Tp(A,y[_])).filter(A=>A>=.8).length/p.length>=.5){let A=i.slice(0,f).join(`
|
|
549
549
|
`).length+(f>0?1:0),_=i.slice(0,f+p.length).join(`
|
|
550
|
-
`).length;return[{start:A,end:_,strategy:"context_aware"}]}}return[]}function
|
|
550
|
+
`).length;return[{start:A,end:_,strategy:"context_aware"}]}}return[]}function Rp(n,e,t){for(let r=0;r<=n.length-e.length;r++){let s=!0;for(let o=0;o<e.length;o++)if(!t(n[r+o],e[o])){s=!1;break}if(s)return{startIdx:r,endIdx:r+e.length}}return null}function Ap(n,e,t){let r=e.slice(0,t.startIdx).join(`
|
|
551
551
|
`).length+(t.startIdx>0?1:0),s=e.slice(0,t.endIdx).join(`
|
|
552
|
-
`).length;return{start:r,end:s}}function
|
|
552
|
+
`).length;return{start:r,end:s}}function wp(n,e,t,r){let s=0,o=0,i=-1,a=-1;for(;s<=n.length&&o<=e.length;){if(o===t&&i===-1&&(i=s),o===t+r){a=s;break}if(o>=e.length||s>=n.length)break;for(o++,s++;s<n.length&&o<e.length&&n[s]!==e[o];)s++}return i!==-1&&a===-1&&(a=n.length),i===-1?null:{start:i,end:a}}function xp(n){let e=n.split(`
|
|
553
553
|
`),t=[],r=null,s=null,o=!1;for(let i of e){if(i.startsWith("*** Begin Patch")){o=!0;continue}if(i.startsWith("*** End Patch"))break;if(o)if(i.startsWith("*** Add File: "))r&&t.push(r),r={type:"add",path:i.slice(14).trim(),hunks:[]},s={lines:[]},r.hunks.push(s);else if(i.startsWith("*** Update File: "))r&&t.push(r),r={type:"update",path:i.slice(17).trim(),hunks:[]},s=null;else if(i.startsWith("*** Delete File: "))r&&t.push(r),r={type:"delete",path:i.slice(17).trim(),hunks:[]},s=null;else if(i.startsWith("*** Move File: ")){r&&t.push(r);let a=i.slice(15).trim().split(" -> ");r={type:"move",path:a[0].trim(),newPath:a[1]?.trim(),hunks:[]},s=null}else i.startsWith("@@ ")&&r?(s={contextHint:i.slice(3).replace(/ @@$/,"").trim()||void 0,lines:[]},r.hunks.push(s)):s&&(i.startsWith("+")?s.lines.push({prefix:"+",content:i.slice(1)}):i.startsWith("-")?s.lines.push({prefix:"-",content:i.slice(1)}):s.lines.push({prefix:" ",content:i.startsWith(" ")?i.slice(1):i}))}return r&&t.push(r),t}function FR(n){let e=[],t=n.split(/^(<<<< SEARCH)$/m);if(t.length<2)return[];let r=t[0].trim().split(`
|
|
554
554
|
`).pop()?.trim();if(!r)return[];for(let s=1;s<t.length;s+=2){let o=t[s+1]||"",i=o.indexOf(`
|
|
555
555
|
====
|
|
556
556
|
`);if(i===-1)continue;let a=o.slice(0,i).replace(/^\n/,""),c=o.slice(i+6),l=c.indexOf(`
|
|
557
|
-
>>>> REPLACE`),d=l===-1?c:c.slice(0,l);e.push({path:r,search:a,replace:d})}return e}function
|
|
557
|
+
>>>> REPLACE`),d=l===-1?c:c.slice(0,l);e.push({path:r,search:a,replace:d})}return e}function Pp(n,e,t){let r=e.lines.filter(h=>h.prefix===" ").map(h=>h.content),s=e.lines.filter(h=>h.prefix==="-").map(h=>h.content),o=e.lines.filter(h=>h.prefix==="+").map(h=>h.content),i=[],a="context";for(let h of e.lines)(h.prefix===" "||h.prefix==="-")&&i.push(h.content);let c=i.join(`
|
|
558
558
|
`);if(!c)return{content:n+`
|
|
559
559
|
`+o.join(`
|
|
560
|
-
`),strategy:"exact"};let l=
|
|
561
|
-
`),p=l[0];return{content:n.slice(0,p.start)+u+n.slice(p.end),strategy:p.strategy}}function Ja(n){return{name:$R,label:"Patch",description:"Apply edits to files using fuzzy matching. Supports V4A unified diff format (*** Begin Patch / *** End Patch) for multi-file operations, and simple search/replace blocks. The fuzzy matcher handles whitespace, indentation, unicode, and escape drift \u2014 LLM output with minor formatting differences will still match correctly.",parameters:jR,execute:async(e,t)=>{let r=t.replaceAll??!1,s={filesModified:[],filesAdded:[],filesDeleted:[],strategies:{},errors:[]},o=t.input.includes("*** Begin Patch"),i=t.input.includes("<<<< SEARCH");if(o){let l=
|
|
562
|
-
`);await n.writeFile(u,p),s.filesAdded.push(d.path),s.strategies[d.path]="exact";break}case"delete":{await n.deleteFile(u),s.filesDeleted.push(d.path);break}case"move":{let p=await n.readFile(u);if(d.newPath){let m=n.resolvePath(d.newPath),h=p;for(let f of d.hunks){let y=
|
|
560
|
+
`),strategy:"exact"};let l=Ip(n,c,t);if(l.length===0)return null;let d=[];for(let h of e.lines)(h.prefix===" "||h.prefix==="+")&&d.push(h.content);let u=d.join(`
|
|
561
|
+
`),p=l[0];return{content:n.slice(0,p.start)+u+n.slice(p.end),strategy:p.strategy}}function Ja(n){return{name:$R,label:"Patch",description:"Apply edits to files using fuzzy matching. Supports V4A unified diff format (*** Begin Patch / *** End Patch) for multi-file operations, and simple search/replace blocks. The fuzzy matcher handles whitespace, indentation, unicode, and escape drift \u2014 LLM output with minor formatting differences will still match correctly.",parameters:jR,execute:async(e,t)=>{let r=t.replaceAll??!1,s={filesModified:[],filesAdded:[],filesDeleted:[],strategies:{},errors:[]},o=t.input.includes("*** Begin Patch"),i=t.input.includes("<<<< SEARCH");if(o){let l=xp(t.input);if(l.length===0)return{content:[{type:"text",text:"Error: No valid V4A operations found. Ensure *** Begin Patch / *** End Patch markers are present."}],details:{type:"patch",error:"parse_failed"}};for(let d of l){let u=n.resolvePath(d.path);try{switch(d.type){case"add":{let p=d.hunks.flatMap(m=>m.lines.filter(h=>h.prefix==="+").map(h=>h.content)).join(`
|
|
562
|
+
`);await n.writeFile(u,p),s.filesAdded.push(d.path),s.strategies[d.path]="exact";break}case"delete":{await n.deleteFile(u),s.filesDeleted.push(d.path);break}case"move":{let p=await n.readFile(u);if(d.newPath){let m=n.resolvePath(d.newPath),h=p;for(let f of d.hunks){let y=Pp(h,f,r);y&&(h=y.content,s.strategies[d.path]=y.strategy)}await n.writeFile(m,h),await n.deleteFile(u),s.filesModified.push(`${d.path} \u2192 ${d.newPath}`)}break}case"update":{let p=await n.readFile(u),m="exact",h=!0;for(let f of d.hunks){let y=Pp(p,f,r);if(y)p=y.content,m=y.strategy;else{h=!1;let b=f.lines.filter(k=>k.prefix===" "||k.prefix==="-").map(k=>k.content).slice(0,5).join(`
|
|
563
563
|
`);s.errors.push(`${d.path}: hunk not matched. Search begins with:
|
|
564
|
-
${b}`)}}(h||p!==await n.readFile(u))&&(await n.writeFile(u,p),s.filesModified.push(d.path),s.strategies[d.path]=m);break}}}catch(p){s.errors.push(`${d.type} ${d.path}: ${p instanceof Error?p.message:String(p)}`)}}}else if(i){let l=FR(t.input);if(l.length===0)return{content:[{type:"text",text:"Error: Invalid search/replace format. Use <<<< SEARCH / ==== / >>>> REPLACE blocks."}],details:{type:"patch",error:"parse_failed"}};for(let d of l){let u=n.resolvePath(d.path);try{let p=await n.readFile(u),m=
|
|
564
|
+
${b}`)}}(h||p!==await n.readFile(u))&&(await n.writeFile(u,p),s.filesModified.push(d.path),s.strategies[d.path]=m);break}}}catch(p){s.errors.push(`${d.type} ${d.path}: ${p instanceof Error?p.message:String(p)}`)}}}else if(i){let l=FR(t.input);if(l.length===0)return{content:[{type:"text",text:"Error: Invalid search/replace format. Use <<<< SEARCH / ==== / >>>> REPLACE blocks."}],details:{type:"patch",error:"parse_failed"}};for(let d of l){let u=n.resolvePath(d.path);try{let p=await n.readFile(u),m=Ip(p,d.search,r);if(m.length===0){s.errors.push(`${d.path}: search text not matched (tried all 9 strategies)`);continue}let h=[...m].sort((f,y)=>y.start-f.start);for(let f of h)p=p.slice(0,f.start)+d.replace+p.slice(f.end);await n.writeFile(u,p),s.filesModified.push(d.path),s.strategies[d.path]=m[0].strategy}catch(p){s.errors.push(`${d.path}: ${p instanceof Error?p.message:String(p)}`)}}}else return xp(`*** Begin Patch
|
|
565
565
|
`+t.input+`
|
|
566
566
|
*** End Patch`).length>0?Ja(n).execute(e,{input:`*** Begin Patch
|
|
567
567
|
`+t.input+`
|
|
@@ -569,29 +569,29 @@ ${b}`)}}(h||p!==await n.readFile(u))&&(await n.writeFile(u,p),s.filesModified.pu
|
|
|
569
569
|
Errors:
|
|
570
570
|
${s.errors.join(`
|
|
571
571
|
`)}`);let c=s.errors.length===0;return{content:[{type:"text",text:a.join(`
|
|
572
|
-
`)||"No changes applied."}],details:{type:"patch",...s,success:c}}}}}var BR="web_fetch",HR={type:"object",properties:{url:{type:"string",description:"HTTP or HTTPS URL to fetch."},extractMode:{type:"string",enum:["markdown","text","json"],description:'Extraction mode: "markdown" (default), "text", or "json" (LLM-driven structured extraction).'},maxChars:{type:"number",description:"Maximum characters to return (truncates when exceeded).",minimum:100},query:{type:"string",description:"Original search query. When provided, returns the most query-relevant sections."},extract:{type:"boolean",description:"When true, returns structured extraction (title, summary, key facts, entities, topics, sentiment)."},summarize:{type:"boolean",description:"When true, returns a concise summary (< 500 chars) of the page content. Useful for long pages to reduce context usage while preserving key information."}},required:["url"]},qR=5e4;function
|
|
572
|
+
`)||"No changes applied."}],details:{type:"patch",...s,success:c}}}}}var BR="web_fetch",HR={type:"object",properties:{url:{type:"string",description:"HTTP or HTTPS URL to fetch."},extractMode:{type:"string",enum:["markdown","text","json"],description:'Extraction mode: "markdown" (default), "text", or "json" (LLM-driven structured extraction).'},maxChars:{type:"number",description:"Maximum characters to return (truncates when exceeded).",minimum:100},query:{type:"string",description:"Original search query. When provided, returns the most query-relevant sections."},extract:{type:"boolean",description:"When true, returns structured extraction (title, summary, key facts, entities, topics, sentiment)."},summarize:{type:"boolean",description:"When true, returns a concise summary (< 500 chars) of the page content. Useful for long pages to reduce context usage while preserving key information."}},required:["url"]},qR=5e4;function _p(n){return{name:BR,label:"Web Fetch",description:"Fetch content from a URL and extract it as markdown, text, or structured JSON. Supports query-based relevance filtering and structured extraction (title, summary, key facts, entities, topics, sentiment).",parameters:HR,isReadOnly:!0,execute:async(e,t)=>{let r=await n.fetchUrl({url:t.url,extractMode:t.extractMode,maxChars:t.maxChars??qR,query:t.query,extract:t.extract});if(t.summarize&&n.summarizeContent&&r.content.length>1e3){let o=await n.summarizeContent(r.content,t.query);return{content:[{type:"text",text:r.title?`# ${r.title}
|
|
573
573
|
|
|
574
574
|
${o}`:o}],details:{type:"web_fetch",url:t.url,summarized:!0,originalLength:r.content.length,summaryLength:o.length}}}let s=[];if(r.title&&s.push(`# ${r.title}
|
|
575
575
|
`),s.push(r.content),r.relevantExcerpts?.length){s.push(`
|
|
576
576
|
---
|
|
577
577
|
## Relevant Excerpts
|
|
578
578
|
`);for(let o of r.relevantExcerpts)s.push(`- ${o}`)}return{content:[{type:"text",text:s.join(`
|
|
579
|
-
`)}],details:{type:"web_fetch",url:t.url,extractMode:t.extractMode??"markdown",hasExtraction:!!r.extraction,extraction:r.extraction}}}}}var WR="web_search",GR={type:"object",properties:{query:{type:"string",description:"Search query string. Be specific and concise for best results."},allowedDomains:{type:"array",items:{type:"string"},description:"Only include results from these domains (e.g. ['docs.python.org', 'stackoverflow.com']). Cannot be used together with blockedDomains."},blockedDomains:{type:"array",items:{type:"string"},description:"Exclude results from these domains. Cannot be used together with allowedDomains."}},required:["query"]},KR=10;function
|
|
580
|
-
`)}],details:{type:"web_search",query:r.query,resultCount:r.results.length}}}}}var VR="instructions",zR={type:"object",properties:{action:{type:"string",enum:["list","read","write","edit","delete"],description:"Operation: list all files, read a file, write (create/overwrite), edit (partial replace), or delete a file."},project_id:{type:"string",description:'Project ID. Use "default" for the default project.'},filename:{type:"string",description:'Instruction file name ending in .md (e.g. "code-style.md"). Required for read/write/delete. Sub-paths like "testing/unit-test.md" are supported.'},content:{type:"string",description:"Markdown content for the instruction file. Required for write action."},old_text:{type:"string",description:"Required for edit action: the exact existing text to find and replace (must appear exactly once)."},new_text:{type:"string",description:"Required for edit action: the replacement text."}},required:["action","project_id"]};function
|
|
579
|
+
`)}],details:{type:"web_fetch",url:t.url,extractMode:t.extractMode??"markdown",hasExtraction:!!r.extraction,extraction:r.extraction}}}}}var WR="web_search",GR={type:"object",properties:{query:{type:"string",description:"Search query string. Be specific and concise for best results."},allowedDomains:{type:"array",items:{type:"string"},description:"Only include results from these domains (e.g. ['docs.python.org', 'stackoverflow.com']). Cannot be used together with blockedDomains."},blockedDomains:{type:"array",items:{type:"string"},description:"Exclude results from these domains. Cannot be used together with allowedDomains."}},required:["query"]},KR=10;function Ep(n){return{name:WR,label:"Web Search",description:"Search the web for current information. Returns top results with title, URL, and snippet. Use this when you need up-to-date information that may not be in your training data. You MUST include source URLs as markdown links when citing search results.",parameters:GR,isReadOnly:!0,execute:async(e,t)=>{if(t.allowedDomains?.length&&t.blockedDomains?.length)return{content:[{type:"text",text:"Error: allowedDomains and blockedDomains cannot both be specified."}],details:{type:"web_search",error:"mutual_exclusion"}};if(!t.query||t.query.trim().length<2)return{content:[{type:"text",text:"Error: query must be at least 2 characters."}],details:{type:"web_search",error:"invalid_query"}};let r=await n.search(t.query.trim(),{allowedDomains:t.allowedDomains,blockedDomains:t.blockedDomains,maxResults:KR});if(r.results.length===0)return{content:[{type:"text",text:`No results found for: "${t.query}"`}],details:{type:"web_search",query:t.query,resultCount:0}};let s=[`Web search results for: "${r.query}"`,"","REMINDER: You MUST include source URLs as markdown links when referencing these results.",""];for(let o=0;o<r.results.length;o++){let i=r.results[o];s.push(`${o+1}. [${i.title}](${i.url})`),s.push(` ${i.snippet}`),s.push("")}return{content:[{type:"text",text:s.join(`
|
|
580
|
+
`)}],details:{type:"web_search",query:r.query,resultCount:r.results.length}}}}}var VR="instructions",zR={type:"object",properties:{action:{type:"string",enum:["list","read","write","edit","delete"],description:"Operation: list all files, read a file, write (create/overwrite), edit (partial replace), or delete a file."},project_id:{type:"string",description:'Project ID. Use "default" for the default project.'},filename:{type:"string",description:'Instruction file name ending in .md (e.g. "code-style.md"). Required for read/write/delete. Sub-paths like "testing/unit-test.md" are supported.'},content:{type:"string",description:"Markdown content for the instruction file. Required for write action."},old_text:{type:"string",description:"Required for edit action: the exact existing text to find and replace (must appear exactly once)."},new_text:{type:"string",description:"Required for edit action: the replacement text."}},required:["action","project_id"]};function Cp(n){return{name:VR,label:"Instructions",description:"Manage project instruction files (.md) \u2014 list, read, write, edit, or delete. Instructions define agent behavior rules, coding standards, and project context.",parameters:zR,isReadOnly:!1,isConcurrencySafe:!0,searchHint:"instructions list read write edit delete rules coding standards behavior guidelines",execute:async(e,t)=>{switch(t.action){case"list":{let r=n.list(t.project_id);if(r.length===0)return{content:[{type:"text",text:"No instruction files found for this project."}],details:{projectId:t.project_id,count:0}};let s=r.map(o=>`- ${o.filename} (${o.size} bytes, updated ${o.updatedAt})`).join(`
|
|
581
581
|
`);return{content:[{type:"text",text:`Found ${r.length} instruction file(s):
|
|
582
582
|
${s}`}],details:{projectId:t.project_id,count:r.length,files:r}}}case"read":{if(!t.filename)return{content:[{type:"text",text:"filename is required for read action"}],details:{error:"missing_filename"}};let r=n.read(t.project_id,t.filename);return r?{content:[{type:"text",text:r.content}],details:{projectId:t.project_id,filename:r.filename,size:r.size}}:{content:[{type:"text",text:`Instruction file not found: ${t.filename}`}],details:{projectId:t.project_id,filename:t.filename,error:"not_found"}}}case"write":{if(!t.filename)return{content:[{type:"text",text:"filename is required for write action"}],details:{error:"missing_filename"}};if(t.content===void 0||t.content===null)return{content:[{type:"text",text:"content is required for write action"}],details:{error:"missing_content"}};if(!t.filename.endsWith(".md"))return{content:[{type:"text",text:"Filename must end with .md"}],details:{error:"invalid_filename"}};if(t.filename.includes(".."))return{content:[{type:"text",text:"Path traversal not allowed"}],details:{error:"path_traversal"}};let r=n.write(t.project_id,t.filename,t.content);return{content:[{type:"text",text:`Instruction file written: ${r.filename} (${r.size} bytes)`}],details:{projectId:t.project_id,filename:r.filename,size:r.size}}}case"edit":{if(!t.filename)return{content:[{type:"text",text:"filename is required for edit action"}],details:{error:"missing_filename"}};if(!t.old_text)return{content:[{type:"text",text:"old_text is required for edit action"}],details:{error:"missing_old_text"}};if(t.new_text===void 0||t.new_text===null)return{content:[{type:"text",text:"new_text is required for edit action"}],details:{error:"missing_new_text"}};if(t.filename.includes(".."))return{content:[{type:"text",text:"Path traversal not allowed"}],details:{error:"path_traversal"}};let r=n.read(t.project_id,t.filename);if(!r)return{content:[{type:"text",text:`Instruction file not found: ${t.filename}`}],details:{projectId:t.project_id,filename:t.filename,error:"not_found"}};let s=r.content.split(t.old_text).length-1;if(s===0)return{content:[{type:"text",text:"old_text not found in the file"}],details:{projectId:t.project_id,filename:t.filename,error:"old_text_not_found"}};if(s>1)return{content:[{type:"text",text:`old_text matches ${s} locations \u2014 must match exactly once. Add more surrounding context to make it unique.`}],details:{projectId:t.project_id,filename:t.filename,error:"ambiguous_match",occurrences:s}};let o=r.content.replace(t.old_text,t.new_text),i=n.write(t.project_id,t.filename,o);return{content:[{type:"text",text:`Instruction file edited: ${i.filename} (${i.size} bytes)`}],details:{projectId:t.project_id,filename:i.filename,size:i.size}}}case"delete":return t.filename?t.filename.includes("..")?{content:[{type:"text",text:"Path traversal not allowed"}],details:{error:"path_traversal"}}:n.remove(t.project_id,t.filename)?{content:[{type:"text",text:`Instruction file deleted: ${t.filename}`}],details:{projectId:t.project_id,filename:t.filename}}:{content:[{type:"text",text:`Instruction file not found: ${t.filename}`}],details:{projectId:t.project_id,filename:t.filename,error:"not_found"}}:{content:[{type:"text",text:"filename is required for delete action"}],details:{error:"missing_filename"}};default:return{content:[{type:"text",text:`Unknown action: ${t.action}. Use list, read, write, edit, or delete.`}],details:{error:"unknown_action"}}}}}}var XR="worktree",YR={type:"object",properties:{action:{type:"string",enum:["enter","exit","list"],description:`enter: Create and switch to an isolated git worktree branch.
|
|
583
583
|
exit: Leave worktree (keep or remove it).
|
|
584
|
-
list: Show all active worktrees.`},name:{type:"string",description:"Worktree/branch name (for enter). Must be kebab-case, max 64 characters. If omitted, auto-generated from task context."},exitAction:{type:"string",enum:["keep","remove"],description:"For exit: 'keep' retains the worktree for later use; 'remove' deletes it."},discardChanges:{type:"boolean",description:"Required true to confirm discarding uncommitted changes when exitAction='remove'. Safety mechanism to prevent data loss."}},required:["action"]},JR=/^[a-z0-9][a-z0-9-]{0,62}[a-z0-9]?$/;function
|
|
584
|
+
list: Show all active worktrees.`},name:{type:"string",description:"Worktree/branch name (for enter). Must be kebab-case, max 64 characters. If omitted, auto-generated from task context."},exitAction:{type:"string",enum:["keep","remove"],description:"For exit: 'keep' retains the worktree for later use; 'remove' deletes it."},discardChanges:{type:"boolean",description:"Required true to confirm discarding uncommitted changes when exitAction='remove'. Safety mechanism to prevent data loss."}},required:["action"]},JR=/^[a-z0-9][a-z0-9-]{0,62}[a-z0-9]?$/;function Mp(n){return{name:XR,label:"Git Worktree",description:"Create isolated git worktree branches for parallel development. Each worktree has its own working directory independent of the main branch. Use for: parallel features, safe experimentation, sub-agent isolation. Exit to keep or remove the worktree when done.",parameters:YR,execute:async(e,t)=>{switch(t.action){case"enter":{if(n.isInWorktree())return{content:[{type:"text",text:"Error: already in a worktree. Exit first before entering another."}],details:{type:"worktree",error:"already_in_worktree"}};if(t.name&&!JR.test(t.name))return{content:[{type:"text",text:"Error: name must be kebab-case (a-z, 0-9, hyphens), 2-64 characters."}],details:{type:"worktree",error:"invalid_name"}};let r=await n.enterWorktree(t.name);if(!r.success)return{content:[{type:"text",text:`Error: ${r.error||"failed to create worktree"}`}],details:{type:"worktree",error:r.error}};let s=r.worktree;return{content:[{type:"text",text:[`Entered worktree: ${s.name}`,` Branch: ${s.branch}`,` Path: ${s.path}`,"","Working in isolated branch. Changes here do not affect the main branch.","Use action='exit' when done (keep or remove)."].join(`
|
|
585
585
|
`)}],details:{type:"worktree",action:"enter",name:s.name,branch:s.branch,path:s.path}}}case"exit":{if(!n.isInWorktree())return{content:[{type:"text",text:"Error: not in a worktree."}],details:{type:"worktree",error:"not_in_worktree"}};let r=t.exitAction||"keep";if(r==="remove"){let i=n.currentWorktree?.();if(i&&(i.hasChanges||i.unpushedCommits>0)&&!t.discardChanges){let a=[];return i.hasChanges&&a.push("uncommitted changes"),i.unpushedCommits>0&&a.push(`${i.unpushedCommits} unpushed commit(s)`),{content:[{type:"text",text:`Error: worktree has ${a.join(" and ")}. Set discardChanges=true to confirm removal, or use exitAction='keep'.`}],details:{type:"worktree",error:"has_changes",hasChanges:i.hasChanges,unpushedCommits:i.unpushedCommits}}}}let s=await n.exitWorktree(r,t.discardChanges);return s.success?{content:[{type:"text",text:`Exited worktree. ${r==="keep"?"Worktree kept for later use.":"Worktree removed."}
|
|
586
586
|
Restored to: ${s.previousCwd||"main workspace"}`}],details:{type:"worktree",action:"exit",exitAction:r,previousCwd:s.previousCwd}}:{content:[{type:"text",text:`Error: ${s.error||"failed to exit worktree"}`}],details:{type:"worktree",error:s.error}}}case"list":{let r=await n.listWorktrees();if(!r.worktrees||r.worktrees.length===0)return{content:[{type:"text",text:"No worktrees (only the main working tree)."}],details:{type:"worktree",action:"list",count:0}};let s=[`Worktrees (${r.worktrees.length}):`,""];for(let o of r.worktrees){let i=o.isCurrent?" \u2190 current":"",a=o.hasChanges?" (has changes)":"";s.push(` ${o.name} [${o.branch}]${i}${a}`),s.push(` path: ${o.path}`)}return{content:[{type:"text",text:s.join(`
|
|
587
|
-
`)}],details:{type:"worktree",action:"list",count:r.worktrees.length}}}default:return{content:[{type:"text",text:`Error: unknown action "${t.action}".`}],details:{type:"worktree",error:"unknown_action"}}}}}}ae();import{execFile as QR}from"node:child_process";import{promisify as ZR}from"node:util";import{join as dn,resolve as
|
|
588
|
-
`).filter(Boolean).length}async function
|
|
589
|
-
`).find(L=>L.startsWith("worktree ")&&L.includes(l));if(h){let L=h.replace("worktree ","").trim(),F=process.cwd();return process.chdir(L),nt={originalCwd:F,worktreePath:L,worktreeName:c,worktreeBranch:d},e.info(`[worktree] resumed existing worktree: ${c} at ${L}`),{success:!0,worktree:{name:c,path:L,branch:d,isCurrent:!0,hasChanges:!1,unpushedCommits:0}}}let f=r&&r.length>0,y=["worktree","add"];f&&y.push("--no-checkout"),y.push("-B",d,p,"HEAD");let{code:b,stderr:k}=await Le(y,i);if(b!==0)return{success:!1,error:`git worktree add failed: ${k.trim()}`};let A=!1;f&&r&&(await rA(p,i,r),A=!0),await
|
|
587
|
+
`)}],details:{type:"worktree",action:"list",count:r.worktrees.length}}}default:return{content:[{type:"text",text:`Error: unknown action "${t.action}".`}],details:{type:"worktree",error:"unknown_action"}}}}}}ae();import{execFile as QR}from"node:child_process";import{promisify as ZR}from"node:util";import{join as dn,resolve as Np,basename as Qa}from"node:path";import{mkdir as Up,rm as Fp,symlink as eA,readdir as yN,stat as tA}from"node:fs/promises";var gr=ZR(QR),nA=/^[a-zA-Z0-9._-]+$/,Dp=64;function Bp(n){if(n.length>Dp)throw new Error(`Invalid worktree name: must be ${Dp} characters or fewer (got ${n.length})`);for(let e of n.split("/")){if(e==="."||e==="..")throw new Error(`Invalid worktree name "${n}": must not contain "." or ".." path segments`);if(!nA.test(e))throw new Error(`Invalid worktree name "${n}": segment must contain only letters, digits, dots, underscores, and dashes`)}}function Za(n){return n.replaceAll("/","+")}function Hp(n){return`worktree-${Za(n)}`}var nt=null;async function Le(n,e){try{let{stdout:t,stderr:r}=await gr("git",n,{cwd:e??process.cwd(),env:{...process.env,GIT_TERMINAL_PROMPT:"0",GIT_ASKPASS:""},timeout:3e4});return{stdout:t,stderr:r,code:0}}catch(t){let r=t;return{stdout:r.stdout??"",stderr:r.stderr??String(t),code:r.code??1}}}async function mr(n){let{stdout:e,code:t}=await Le(["rev-parse","--show-toplevel"],n);return t===0?e.trim():null}async function Op(n){let{stdout:e,code:t}=await Le(["status","--porcelain"],n);return t!==0?-1:e.trim().split(`
|
|
588
|
+
`).filter(Boolean).length}async function Lp(n,e){let{stdout:t,code:r}=await Le(["rev-list",`origin/${e}..${e}`,"--count"],n);return r!==0?0:parseInt(t.trim(),10)||0}async function qp(n,e,t,r){for(let s of t){if(s.includes("..")||s.startsWith("/")||s.startsWith("\\")){r?.warn(`[worktree] skipping symlink for "${s}": path traversal detected`);continue}let o=dn(n,s),i=dn(e,s);try{await eA(o,i,"dir"),r?.info(`[worktree] symlinked ${s} from main repo to worktree`)}catch(a){let c=a.code;c!=="ENOENT"&&c!=="EEXIST"&&r?.warn(`[worktree] failed to symlink ${s} (${c??"unknown"}): ${a}`)}}}async function rA(n,e,t){let{code:r,stderr:s}=await Le(["sparse-checkout","set","--cone","--",...t],n);if(r!==0)throw await Le(["worktree","remove","--force",n],e),new Error(`Failed to configure sparse-checkout: ${s}`);let{code:o,stderr:i}=await Le(["checkout","HEAD"],n);if(o!==0)throw await Le(["worktree","remove","--force",n],e),new Error(`Failed to checkout sparse worktree: ${i}`);return!0}async function sA(){try{return await gr("tmux",["-V"],{timeout:5e3}),!0}catch{return!1}}function oA(n,e){return`${Qa(n)}_${e}`.replace(/[/.]/g,"_")}async function iA(n,e){if(!await sA())return null;try{return await gr("tmux",["new-session","-d","-s",e,"-c",n],{timeout:1e4}),e}catch{return null}}async function $p(n){try{return await gr("tmux",["kill-session","-t",n],{timeout:5e3}),!0}catch{return!1}}async function jp(n,e,t,r){let s=Pd(e),o=dn(s,n);try{if(!(await tA(o)).isFile())return null}catch{return null}try{let{stdout:i,stderr:a}=await gr(o,[],{cwd:e,env:{...process.env,...t},timeout:3e4});return r?.info(`[worktree] hook ${n} succeeded: ${i.trim()}`),i.trim()||null}catch(i){return r?.warn(`[worktree] hook ${n} failed: ${i}`),null}}async function Wp(n,e,t){Bp(e);let r=Za(e),s=Hp(e),o=dn(n,".worktrees"),i=dn(o,r);await Up(o,{recursive:!0});let{code:a,stderr:c}=await Le(["worktree","add","-B",s,i,"HEAD"],n);return a!==0?(t?.warn(`[worktree] agent worktree creation failed: ${c}`),null):(await qp(n,i,["node_modules"],t),t?.info(`[worktree] agent worktree created: ${e} at ${i}`),{worktreePath:i,branch:s})}async function Gp(n,e,t,r){let{code:s}=await Le(["worktree","remove","--force",e],n);return s!==0&&(await Fp(e,{recursive:!0,force:!0}).catch(()=>{}),await Le(["worktree","prune"],n)),await Le(["branch","-D",t],n),r?.info(`[worktree] agent worktree removed: ${e}`),!0}function Kp(n){let{log:e,symlinkDirs:t=["node_modules"],sparsePaths:r}=n;return{async enterWorktree(s){try{let o=Date.now(),i=await mr();if(!i)return{success:!1,error:"Not in a git repository"};let a=await jp("worktree-create",i,{WORKTREE_NAME:s??""},e);if(a){let L=process.cwd();return process.chdir(a),nt={originalCwd:L,worktreePath:a,worktreeName:s??Qa(a),worktreeBranch:"",hookBased:!0,creationDurationMs:Date.now()-o},{success:!0,worktree:{name:nt.worktreeName,path:a,branch:"",isCurrent:!0,hasChanges:!1,unpushedCommits:0}}}let c=s??`agent-${Date.now().toString(36)}`;Bp(c);let l=Za(c),d=Hp(c),u=dn(i,".worktrees"),p=dn(u,l);await Up(u,{recursive:!0});let{stdout:m}=await Le(["worktree","list","--porcelain"],i),h=m.split(`
|
|
589
|
+
`).find(L=>L.startsWith("worktree ")&&L.includes(l));if(h){let L=h.replace("worktree ","").trim(),F=process.cwd();return process.chdir(L),nt={originalCwd:F,worktreePath:L,worktreeName:c,worktreeBranch:d},e.info(`[worktree] resumed existing worktree: ${c} at ${L}`),{success:!0,worktree:{name:c,path:L,branch:d,isCurrent:!0,hasChanges:!1,unpushedCommits:0}}}let f=r&&r.length>0,y=["worktree","add"];f&&y.push("--no-checkout"),y.push("-B",d,p,"HEAD");let{code:b,stderr:k}=await Le(y,i);if(b!==0)return{success:!1,error:`git worktree add failed: ${k.trim()}`};let A=!1;f&&r&&(await rA(p,i,r),A=!0),await qp(i,p,t,e);let _=process.cwd();process.chdir(p);let I=oA(i,d),N=await iA(p,I);return nt={originalCwd:_,worktreePath:p,worktreeName:c,worktreeBranch:d,tmuxSessionName:N??void 0,creationDurationMs:Date.now()-o,usedSparsePaths:A},e.info(`[worktree] entered: ${c} at ${p}`),{success:!0,worktree:{name:c,path:p,branch:d,isCurrent:!0,hasChanges:!1,unpushedCommits:0}}}catch(o){return{success:!1,error:o instanceof Error?o.message:String(o)}}},async exitWorktree(s,o){if(!nt)return{success:!1,error:"Not in a worktree"};try{let i=nt,a=await mr(i.originalCwd);if(!a)return{success:!1,error:"Original git root not found"};if(s==="remove"){let c=await Op(i.worktreePath),l=await Lp(i.worktreePath,i.worktreeBranch);if((c>0||l>0)&&!o)return{success:!1,error:`Worktree has ${c} uncommitted change(s) and ${l} unpushed commit(s). Set discardChanges=true to confirm.`};process.chdir(i.originalCwd),nt=null,i.tmuxSessionName&&await $p(i.tmuxSessionName),await jp("worktree-remove",a,{WORKTREE_PATH:i.worktreePath},e);let d=["worktree","remove"];o&&d.push("--force"),d.push(i.worktreePath);let{code:u,stderr:p}=await Le(d,a);u!==0&&(e.warn(`[worktree] git worktree remove failed: ${p.trim()}, cleaning up manually`),await Fp(i.worktreePath,{recursive:!0,force:!0}).catch(()=>{}),await Le(["worktree","prune"],a)),await Le(["branch","-D",i.worktreeBranch],a),e.info(`[worktree] removed: ${i.worktreeName}`)}else process.chdir(i.originalCwd),i.tmuxSessionName&&await $p(i.tmuxSessionName),nt=null,e.info(`[worktree] exited (kept): ${i.worktreeName}`);return{success:!0,previousCwd:i.originalCwd}}catch(i){return{success:!1,error:i instanceof Error?i.message:String(i)}}},async listWorktrees(){try{let{stdout:s,code:o}=await Le(["worktree","list","--porcelain"]);if(o!==0)return{success:!0,worktrees:[]};let i=[],a=process.cwd(),c=s.split(`
|
|
590
590
|
|
|
591
591
|
`).filter(Boolean);for(let l of c){let d=l.split(`
|
|
592
|
-
`),u="",p="";for(let y of d)y.startsWith("worktree ")&&(u=y.slice(9).trim()),y.startsWith("branch ")&&(p=y.slice(7).trim().replace("refs/heads/",""));if(!u)continue;let m=
|
|
592
|
+
`),u="",p="";for(let y of d)y.startsWith("worktree ")&&(u=y.slice(9).trim()),y.startsWith("branch ")&&(p=y.slice(7).trim().replace("refs/heads/",""));if(!u)continue;let m=Np(u)===Np(a),h=await Op(u),f=await Lp(u,p);i.push({name:p.startsWith("worktree-")?p.slice(9):Qa(u),path:u,branch:p,isCurrent:m,hasChanges:h>0,unpushedCommits:f})}return{success:!0,worktrees:i}}catch(s){return{success:!1,error:s instanceof Error?s.message:String(s)}}},isInWorktree(){return nt!==null},currentWorktree(){return nt?{name:nt.worktreeName,path:nt.worktreePath,branch:nt.worktreeBranch,isCurrent:!0,hasChanges:!1,unpushedCommits:0}:null}}}import{readFile as aA,writeFile as cA}from"node:fs/promises";import*as Vp from"node:path";var lA={type:"object",properties:{notebook_path:{type:"string",description:"Absolute path to the .ipynb notebook file."},cell_number:{type:"number",description:"1-based cell number to operate on. For 'insert', the new cell is inserted after this cell (use 0 to insert at the beginning)."},new_source:{type:"string",description:"New cell content. Required for 'replace' and 'insert' modes."},cell_type:{type:"string",enum:["code","markdown"],description:"Cell type for 'insert' mode. Default: 'code'."},edit_mode:{type:"string",enum:["replace","insert","delete"],description:"Edit operation: replace (default), insert (after cell_number), or delete."}},required:["notebook_path","cell_number"]};function zp(n){let e=n.split(`
|
|
593
593
|
`);return e.map((t,r)=>r<e.length-1?t+`
|
|
594
|
-
`:t)}function
|
|
594
|
+
`:t)}function Xp(n){return n.join("")}function dA(n,e){let t=Xp(n.source).trim(),r=t.length>80?t.slice(0,80)+"...":t;return`Cell ${e+1} [${n.cell_type}]: ${r}`}function uA(n,e){let t={cell_type:n,source:zp(e),metadata:{}};return n==="code"&&(t.execution_count=null,t.outputs=[]),t}function Yp(){return{name:"notebook_edit",label:"Notebook Edit",description:"Edit Jupyter notebook (.ipynb) files at the cell level. Supports replacing cell content, inserting new cells, and deleting cells. Operates on the notebook's JSON structure directly.",parameters:lA,shouldDefer:!0,isConcurrencySafe:!1,isReadOnly:!1,searchHint:"jupyter notebook ipynb cell edit insert delete",execute:async(n,e)=>{let{notebook_path:t,cell_number:r,edit_mode:s="replace"}=e,o=Vp.extname(t).toLowerCase();if(o!==".ipynb")return{content:[{type:"text",text:`Error: File must be a .ipynb notebook. Got: ${o}`}],details:{error:"invalid_extension"}};let i;try{i=await aA(t,"utf-8")}catch(m){return{content:[{type:"text",text:`Error reading notebook: ${m.message}`}],details:{error:"read_failed"}}}let a;try{a=JSON.parse(i)}catch{return{content:[{type:"text",text:"Error: File is not valid JSON (not a valid .ipynb)."}],details:{error:"parse_failed"}}}if(!Array.isArray(a.cells))return{content:[{type:"text",text:"Error: Notebook has no cells array."}],details:{error:"invalid_notebook"}};let c=a.cells.length,l=r-1;if(s==="insert"){if(r<0||r>c)return{content:[{type:"text",text:`Error: cell_number ${r} out of range. For insert, use 0-${c}.`}],details:{error:"out_of_range"}}}else if(l<0||l>=c)return{content:[{type:"text",text:`Error: cell_number ${r} out of range. Notebook has ${c} cell(s).`}],details:{error:"out_of_range"}};let d;switch(s){case"replace":{if(!e.new_source)return{content:[{type:"text",text:"Error: new_source is required for 'replace' mode."}],details:{error:"missing_source"}};let m=a.cells[l],h=Xp(m.source);m.source=zp(e.new_source),m.cell_type==="code"&&(m.execution_count=null,m.outputs=[]),d=`Replaced cell ${r} [${m.cell_type}].
|
|
595
595
|
Old: ${h.slice(0,120)}${h.length>120?"...":""}
|
|
596
596
|
New: ${e.new_source.slice(0,120)}${e.new_source.length>120?"...":""}`;break}case"insert":{if(!e.new_source)return{content:[{type:"text",text:"Error: new_source is required for 'insert' mode."}],details:{error:"missing_source"}};let m=e.cell_type??"code",h=uA(m,e.new_source);a.cells.splice(r,0,h),d=`Inserted new ${m} cell after position ${r}. Total cells: ${a.cells.length}.`;break}case"delete":{let m=a.cells.splice(l,1)[0];d=`Deleted cell ${r} [${m.cell_type}]. Remaining: ${a.cells.length} cells.`;break}default:return{content:[{type:"text",text:`Error: unknown edit_mode "${s}". Use replace, insert, or delete.`}],details:{error:"unknown_mode"}}}try{let m=JSON.stringify(a,null,1)+`
|
|
597
597
|
`;await cA(t,m,"utf-8")}catch(m){return{content:[{type:"text",text:`Error writing notebook: ${m.message}`}],details:{error:"write_failed"}}}let u=a.cells.slice(0,10).map((m,h)=>dA(m,h)).join(`
|
|
@@ -599,35 +599,35 @@ New: ${e.new_source.slice(0,120)}${e.new_source.length>120?"...":""}`;break}case
|
|
|
599
599
|
... and ${a.cells.length-10} more cells`:"";return{content:[{type:"text",text:`${d}
|
|
600
600
|
|
|
601
601
|
Current cells:
|
|
602
|
-
${u}${p}`}],details:{type:"notebook_edit",edit_mode:s,cell_number:r,total_cells:a.cells.length}}}}}ae();import{readFile as pA,readdir as mA}from"node:fs/promises";import*as
|
|
602
|
+
${u}${p}`}],details:{type:"notebook_edit",edit_mode:s,cell_number:r,total_cells:a.cells.length}}}}}ae();import{readFile as pA,readdir as mA}from"node:fs/promises";import*as Qp from"node:path";import{existsSync as gA}from"node:fs";var fA={type:"object",properties:{action:{type:"string",enum:["list","run","describe"],description:`list: Show available workflows.
|
|
603
603
|
run: Execute a workflow by name.
|
|
604
|
-
describe: Show workflow steps and variables.`},workflow:{type:"string",description:"Workflow name (required for 'run' and 'describe')."},variables:{type:"object",description:"Variable overrides (key-value pairs) for the workflow run.",additionalProperties:{type:"string"}}},required:["action"]};async function ec(n){let e=new Map,t=wd(n);await
|
|
604
|
+
describe: Show workflow steps and variables.`},workflow:{type:"string",description:"Workflow name (required for 'run' and 'describe')."},variables:{type:"object",description:"Variable overrides (key-value pairs) for the workflow run.",additionalProperties:{type:"string"}}},required:["action"]};async function ec(n){let e=new Map,t=wd(n);await Jp(t,e);let r=Rd();return await Jp(r,e),e}async function Jp(n,e){if(gA(n))try{let t=await mA(n,{withFileTypes:!0});for(let r of t)if(r.isFile()&&r.name.endsWith(".json")){let s=r.name.replace(/\.json$/,"");e.has(s)||e.set(s,Qp.join(n,r.name))}}catch{}}async function tc(n){let e=await pA(n,"utf-8");return JSON.parse(e)}function hA(n){let e=new Map(n.map(o=>[o.id,o])),t=new Set,r=[];function s(o,i){if(t.has(o))return;if(i.has(o))throw new Error(`Circular dependency detected at step: ${o}`);i.add(o);let a=e.get(o);if(!a)throw new Error(`Unknown step dependency: ${o}`);for(let c of a.dependsOn??[])s(c,i);i.delete(o),t.add(o),r.push(a)}for(let o of n)s(o.id,new Set);return r}function yA(n,e,t){let r={};for(let[s,o]of Object.entries(n))if(typeof o=="string"){let i=o;i=i.replace(/\$\{var\.(\w+)\}/g,(a,c)=>e[c]??`\${var.${c}}`),i=i.replace(/\$\{step\.(\w+)\.result\}/g,(a,c)=>t.get(c)?.output??""),r[s]=i}else r[s]=o;return r}function Zp(n){return{name:"workflow",label:"Workflow",description:"Execute predefined automation workflows. Workflows are step-based pipelines defined as JSON files in .qlogicagent/workflows/ or ~/.qlogicagent/workflows/. Steps run in dependency order, support variable interpolation, and can reference previous step outputs via ${step.<id>.result}.",parameters:fA,shouldDefer:!0,isConcurrencySafe:!1,isReadOnly:!1,searchHint:"workflow pipeline automation steps DAG",execute:async(e,t,r)=>{let s=n.getCwd();switch(t.action){case"list":{let o=await ec(s);if(o.size===0)return{content:[{type:"text",text:"No workflows found. Create .json files in .qlogicagent/workflows/ or ~/.qlogicagent/workflows/."}],details:{type:"workflow",action:"list",count:0}};let i=["Available workflows:"];for(let[a,c]of o)try{let l=await tc(c);i.push(` - ${a}: ${l.description??"(no description)"} (${l.steps.length} steps)`)}catch{i.push(` - ${a}: (failed to load)`)}return{content:[{type:"text",text:i.join(`
|
|
605
605
|
`)}],details:{type:"workflow",action:"list",count:o.size}}}case"describe":{if(!t.workflow)return{content:[{type:"text",text:"Error: 'workflow' parameter is required for 'describe'."}],details:{error:"missing_workflow"}};let i=(await ec(s)).get(t.workflow);if(!i)return{content:[{type:"text",text:`Error: Workflow "${t.workflow}" not found.`}],details:{error:"not_found"}};let a=await tc(i),c=[`Workflow: ${a.name}`,a.description?`Description: ${a.description}`:"","","Steps:"];for(let l of a.steps){let d=l.dependsOn?.length?` (after: ${l.dependsOn.join(", ")})`:"";c.push(` ${l.id}: ${l.label??l.tool}${d}`),c.push(` tool: ${l.tool}`),c.push(` args: ${JSON.stringify(l.args)}`)}if(a.variables&&Object.keys(a.variables).length>0){c.push("","Variables (defaults):");for(let[l,d]of Object.entries(a.variables))c.push(` ${l} = ${d}`)}return{content:[{type:"text",text:c.filter(Boolean).join(`
|
|
606
606
|
`)}],details:{type:"workflow",action:"describe",workflow:a.name}}}case"run":{if(!t.workflow)return{content:[{type:"text",text:"Error: 'workflow' parameter is required for 'run'."}],details:{error:"missing_workflow"}};let i=(await ec(s)).get(t.workflow);if(!i)return{content:[{type:"text",text:`Error: Workflow "${t.workflow}" not found.`}],details:{error:"not_found"}};let a=await tc(i),c={...a.variables,...t.variables},l;try{l=hA(a.steps)}catch(m){return{content:[{type:"text",text:`Error: ${m.message}`}],details:{error:"dag_error"}}}let d=new Map,u=[`Running workflow: ${a.name}`,""],p=!0;for(let m of l){if(r?.aborted){u.push(`\u26A1 Aborted at step: ${m.id}`),p=!1;break}let h=(m.dependsOn??[]).some(b=>!d.get(b)?.success),f=m.condition??"on_success";if(f==="on_success"&&h){u.push(`\u23ED Skipped ${m.id} (dependency failed)`),d.set(m.id,{stepId:m.id,success:!1,output:"",error:"dependency_failed"}),p=!1;continue}if(f==="on_failure"&&!h){u.push(`\u23ED Skipped ${m.id} (no failure to handle)`),d.set(m.id,{stepId:m.id,success:!0,output:""});continue}u.push(`\u25B6 ${m.id}: ${m.label??m.tool}`);let y=yA(m.args,c,d);try{let b=await n.invokeTool(m.tool,y,r),k=!b.error;if(d.set(m.id,{stepId:m.id,success:k,output:b.result,error:b.error}),k){let A=b.result.length>200?b.result.slice(0,200)+"...":b.result;u.push(` \u2705 ${A}`)}else u.push(` \u274C ${b.error}`),p=!1}catch(b){let k=b.message;d.set(m.id,{stepId:m.id,success:!1,output:"",error:k}),u.push(` \u274C ${k}`),p=!1}}return u.push("",p?"Workflow completed successfully.":"Workflow completed with errors."),{content:[{type:"text",text:u.join(`
|
|
607
|
-
`)}],details:{type:"workflow",action:"run",workflow:a.name,success:p,stepsExecuted:d.size,totalSteps:a.steps.length}}}default:return{content:[{type:"text",text:`Error: unknown action "${t.action}". Use list, run, or describe.`}],details:{error:"unknown_action"}}}}}}var bA="sleep",vA={type:"object",properties:{duration:{type:"number",description:"Duration to sleep in seconds (1\u20133600). Prefer short sleeps (10\u201360s) to stay responsive.",minimum:1,maximum:3600},reason:{type:"string",description:'Brief reason for sleeping. Examples: "waiting for build to finish", "nothing to do", "user asked to rest".'}},required:["duration"]};function
|
|
607
|
+
`)}],details:{type:"workflow",action:"run",workflow:a.name,success:p,stepsExecuted:d.size,totalSteps:a.steps.length}}}default:return{content:[{type:"text",text:`Error: unknown action "${t.action}". Use list, run, or describe.`}],details:{error:"unknown_action"}}}}}}var bA="sleep",vA={type:"object",properties:{duration:{type:"number",description:"Duration to sleep in seconds (1\u20133600). Prefer short sleeps (10\u201360s) to stay responsive.",minimum:1,maximum:3600},reason:{type:"string",description:'Brief reason for sleeping. Examples: "waiting for build to finish", "nothing to do", "user asked to rest".'}},required:["duration"]};function em(n){return{name:bA,label:"Sleep",shouldDefer:!0,isConcurrencySafe:!0,isReadOnly:!0,searchHint:"wait sleep rest idle tick proactive",description:["Wait for a specified duration. The user can interrupt the sleep at any time.","","Use this when:","\u2022 You have nothing useful to do right now","\u2022 You're waiting for an external process to complete","\u2022 The user tells you to sleep or rest","\u2022 You receive a <tick> check-in with no actionable work","","Prefer this over `exec(sleep ...)` \u2014 it doesn't hold a shell process.","You can call this concurrently with other tools \u2014 it won't interfere with them.","","Each wake-up costs an API call, but the prompt cache expires after 5 minutes of inactivity \u2014 balance accordingly."].join(`
|
|
608
608
|
`),parameters:vA,execute:async(e,t,r)=>{let s=Math.max(1,Math.min(3600,Math.round(t.duration))),o=s*1e3,i=new AbortController,a=()=>i.abort();r?.addEventListener("abort",a,{once:!0}),r?.aborted&&i.abort();try{let c=await n.sleep(o,i.signal),l=[];return c.interrupted?(l.push(`Sleep interrupted after ${c.sleptSeconds}s.`),c.interruptReason&&l.push(`Reason: ${c.interruptReason}`),l.push("Check for new messages or tasks.")):l.push(`Slept for ${c.sleptSeconds}s. Waking up.`),{content:[{type:"text",text:l.join(`
|
|
609
|
-
`)}],details:{...c,requestedSeconds:s}}}finally{r?.removeEventListener("abort",a)}}}}var kA="tool_search",SA={type:"object",properties:{query:{type:"string",description:'Search query for tools. Use "select:toolName" to directly activate a deferred tool, or provide keywords to search tool names/descriptions. Prefix a term with "+" to mark it as required (all +terms must match).'},maxResults:{type:"number",description:"Maximum number of results to return (default: 5)."}},required:["query"]},TA=5;function
|
|
610
|
-
`)}],details:{type:"tool_search",activated:a,notFound:c,mode:"select"}}}let o=await n.searchTools(r,{maxResults:s});return
|
|
611
|
-
`)}],details:{type:"tool_search",query:n.query,matchCount:n.matches.length,totalDeferred:n.totalDeferred,matches:n.matches.map(t=>t.name)}}}var nc="image_generate",RA={type:"object",properties:{prompt:{type:"string",description:"Image generation prompt. Enrich vague requests with style, lighting, composition, color, mood details."},purpose:{type:"string",description:"Intended use: 'social-media', 'short-video-cover', 'phone-wallpaper', 'avatar', 'poster', etc."},style:{type:"string",description:"Visual art style: 'photorealistic', 'anime', 'watercolor', 'oil-painting', '3d-render', etc."},size:{type:"string",description:"Dimensions: e.g. '1024x1792' (portrait), '1792x1024' (landscape), '1024x1024' (square). Default: '1024x1024'."},image_url:{type:"string",description:"Reference image URL for image-to-image generation (img2img). Character reference sheet or style transfer. MUST be a publicly accessible HTTP/HTTPS URL. Local file paths and data: URLs are NOT supported."},n:{type:"number",description:"Number of images to generate (1-4). Default: 1."},quality:{type:"string",description:"Image quality level: 'auto', 'high', 'low', 'hd'. Provider-specific."},seed:{type:"number",description:"Random seed for reproducible generation. Same seed + prompt = same result."}},required:["prompt"]};function nm(n){return{name:nc,label:"Image Generate",description:"Generate images from a text prompt. You MUST enrich vague prompts with details about style, lighting, composition, color, and mood before calling. Supports img2img via image_url reference. All generated images are saved locally and can be viewed immediately. IMPORTANT: If the user has not specified purpose or preferred style, use ask_user to clarify (e.g. purpose: social-media / wallpaper / poster; style: photorealistic / anime / watercolor) before calling this tool. Infer image size automatically from purpose (e.g. 1024x1792 for phone wallpaper, 1792x1024 for landscape poster, 1024x1024 for avatar/social). Do NOT expose size as a raw number to the user. ALL reference image URLs MUST be publicly accessible HTTP/HTTPS URLs. Use file_upload tool first if the user provides a local file. Local file paths and data: URIs are NOT supported by the generation API.",parameters:RA,execute:async(e,t)=>{let r=await n.generateImage({prompt:t.prompt,purpose:t.purpose,style:t.style,size:t.size,imageUrl:t.image_url,n:t.n,quality:t.quality,seed:t.seed}),s=r.mediaUrls.length;return{content:[{type:"text",text:`Generated ${s} image${s>1?"s":""}${r.model?` (model: ${r.model})`:""}`}],details:{type:"image_generate",model:r.model,size:r.size,durationMs:r.durationMs,mediaUrls:r.mediaUrls}}}}}var AA={type:"object",properties:{text:{type:"string",description:"Text to convert to speech."},channel:{type:"string",description:"Optional channel id to pick output format (e.g. telegram)."},voice:{type:"string",description:"Voice name for TTS. Available voices depend on the provider. Common options: alloy, ash, ballad, coral, echo, fable, nova, onyx, sage, shimmer."},speed:{type:"number",description:"Speech speed multiplier (0.25-4.0). Default is 1.0."}},required:["text"]};function rm(n){return{name:"tts",label:"TTS",description:"Convert text to speech (TTS) \u2014 read text aloud as spoken audio. Use for narration, voice messages, or any spoken-word output. DO NOT use for music, songs, or melodies \u2014 use music_generate instead.",parameters:AA,execute:async(e,t)=>{let r=await n.textToSpeech({text:t.text,channel:t.channel,voice:t.voice,speed:t.speed});return{content:[{type:"text",text:"\u5DF2\u6210\u529F\u751F\u6210\u8BED\u97F3\u3002"}],details:{type:"tts",audioPath:r.audioPath,provider:r.provider,voiceCompatible:r.voiceCompatible,mediaUrls:r.mediaUrls}}}}}var rc="video_generate",wA={type:"object",properties:{prompt:{type:"string",description:"Video generation prompt. MUST be in English. Include scene, movement, camera motion, lighting, style."},purpose:{type:"string",description:"Intended use: 'social-media', 'short-video', 'presentation', etc."},style:{type:"string",description:"Visual style: 'cinematic', 'anime', 'watercolor', etc."},image_url:{type:"string",description:"Reference image URL for image-to-video generation (first frame, style reference, or character reference). MUST be a publicly accessible HTTP/HTTPS URL. Local file paths and data: URLs are NOT supported. If the user provides a local file, use a file hosting service or the image_generate tool first."},reference_videos:{type:"array",items:{type:"string"},maxItems:3,description:"Reference video URLs for video-to-video or multimodal generation (Seedance 2.0). Max 3 videos, total duration \u226415s. Use for: (a) video-to-video: provide source video to restyle/transform with prompt guidance; (b) multimodal reference: combine with image_url and/or reference_audios for style/motion/audio-guided generation. Each URL MUST be publicly accessible HTTP/HTTPS. Use file_upload tool first if the user provides a local file."},reference_audios:{type:"array",items:{type:"string"},maxItems:3,description:"Reference audio URLs for audio-guided video generation (Seedance 2.0). Max 3 audio clips, total duration \u226415s. CANNOT be used alone \u2014 must be combined with at least one image_url or reference_video. Each URL MUST be publicly accessible HTTP/HTTPS. Use file_upload tool first if the user provides a local file."},generate_audio:{type:"boolean",description:"Generate synchronized audio track for the video (Seedance 2.0/1.5 pro). When true, the output video includes AI-generated sound effects matching the visual content."},aspect_ratio:{type:"string",description:"Video aspect ratio: '9:16' (vertical), '16:9' (horizontal), '1:1' (square). Default: '16:9'."},duration:{type:"number",minimum:3,maximum:15,description:"Video duration in seconds. Seedance 2.0: 4-15s per shot. Seedance 1.0/1.5: 3-10s. For longer videos (>15s), use multi-shot storyboard workflow (generate + extend/merge). Must be confirmed by user before generation."},resolution:{type:"string",description:"Output resolution: '480p', '720p', '1080p'. Default: '720p'."},fps:{type:"number",description:"Frame rate: 24 or 30 fps. Default: provider-specific."},seed:{type:"number",description:"Random seed for reproducible generation."},camera_fixed:{type:"boolean",description:"Lock camera position (Seedance 1.0/1.5 only, not supported for img2video)."},return_last_frame:{type:"boolean",description:"Return last frame URL for chaining continuous video segments."},draft:{type:"boolean",description:"Draft mode: low-cost preview (Seedance 1.5 pro only)."},service_tier:{type:"string",enum:["default","flex"],description:"'default' (online, fast) or 'flex' (offline, ~50% cost). Not all models support flex."},callback_url:{type:"string",description:"Webhook URL for async task completion notification."},safety_identifier:{type:"string",description:"End-user safety identifier for content moderation tracking."},execution_expires_after:{type:"number",description:"Task expiration in seconds (for offline/flex scheduling)."},video_tools:{type:"array",items:{type:"string"},description:"Video-level builtin tools, e.g. ['web_search'] (Seedance 2.0 online search)."}},required:["prompt"]};function sm(n){return{name:rc,label:"Video Generate",description:"Generate a short video clip from a text prompt, reference image, source video, or multimodal references. Prompt MUST be in English. Include scene, movement, camera motion, lighting details. Single-shot: 3\u201310s. For longer videos (>10s), use multi-shot storyboard workflow. MODES: (1) text-to-video: prompt only. (2) image-to-video: prompt + image_url. (3) video-to-video: prompt + reference_videos \u2014 restyle/transform an existing video with prompt guidance. (4) multimodal reference: prompt + any combination of image_url / reference_videos / reference_audios for style/motion/audio-guided generation. (5) generate_audio=true for synchronized sound effects. ALL image/video/audio URLs MUST be publicly accessible HTTP/HTTPS URLs. Local file paths and data: URIs are NOT supported by the generation API. If the user provides a local file, use the file_upload tool FIRST to get a public URL. IMPORTANT: If the user has not specified aspect ratio or duration, use ask_user to clarify (e.g. aspect: 16:9 for landscape / 9:16 for vertical / 1:1 for square; duration: 3-10s). Auto-set aspect_ratio based on stated purpose (e.g. 9:16 for short-video / Douyin, 16:9 for presentation).",parameters:wA,execute:async(e,t)=>{let r=await n.generateVideo({prompt:t.prompt,purpose:t.purpose,style:t.style,imageUrl:t.image_url,referenceVideos:t.reference_videos,referenceAudios:t.reference_audios,generateAudio:t.generate_audio,aspectRatio:t.aspect_ratio,duration:t.duration,resolution:t.resolution,fps:t.fps,seed:t.seed,cameraFixed:t.camera_fixed,returnLastFrame:t.return_last_frame,draft:t.draft,serviceTier:t.service_tier,callbackUrl:t.callback_url,safetyIdentifier:t.safety_identifier,executionExpiresAfterSeconds:t.execution_expires_after,videoTools:t.video_tools}),s=r.mediaUrls.length,o=[`Generated ${s} video${s>1?"s":""}`];return r.model&&o.push(`model: ${r.model}`),r.lastFrameUrl&&o.push(`last_frame: ${r.lastFrameUrl}`),r.taskId&&o.push(`task_id: ${r.taskId}`),{content:[{type:"text",text:o.length>1?`${o[0]} (${o.slice(1).join(", ")})`:o[0]}],details:{type:"video_generate",model:r.model,durationMs:r.durationMs,mediaUrls:r.mediaUrls,...r.taskId?{taskId:r.taskId}:{}}}}}}var sc="music_generate",xA={type:"object",properties:{prompt:{type:"string",description:"Music generation prompt. MUST be in English. Include genre, mood, tempo, instruments, and atmosphere details."},purpose:{type:"string",description:"Intended use: 'background-music', 'ringtone', 'short-video-bgm', 'full-song', 'notification-sound', etc."},style:{type:"string",description:"Musical style/genre: 'lo-fi', 'pop', 'rock', 'jazz', 'classical', 'electronic', 'ambient', etc."},lyrics:{type:"string",description:"Optional lyrics for vocal music. Structure with [verse], [chorus], [bridge] tags if desired."},duration:{type:"number",description:"Duration in seconds (5-300). Infer from purpose: ringtone 15-30s, BGM 30-60s, full song 120-180s."},is_instrumental:{type:"boolean",description:"Set true for pure instrumental music without vocals. Defaults to true when no lyrics are provided."},cover_audio_url:{type:"string",description:"URL of an existing audio track to use as base for cover/remix. When provided, generates a cover version. MUST be a publicly accessible HTTP/HTTPS URL. Use file_upload tool first if the user provides a local file."},audio_format:{type:"string",enum:["mp3","wav","flac"],description:"Output audio format. Defaults to mp3."}},required:["prompt"]};function om(n){return{name:sc,label:"Music Generate",description:"Generate music, songs, or melodies from text descriptions. Prompt MUST be in English. Supports lyrics for vocal songs. DO NOT use for spoken-word audio or TTS \u2014 use tts tool instead. IMPORTANT: If the user has not specified genre/style or duration, use ask_user to clarify (e.g. style: lo-fi / pop / rock / jazz; duration inferred from purpose: 30s for ringtone, 60-90s for BGM, 180-240s for full song). Auto-infer duration from purpose when possible.",parameters:xA,execute:async(e,t)=>{let r=t.lyrics;if(!r&&!t.is_instrumental&&n.generateLyrics)try{r=await n.generateLyrics(t.prompt)}catch{}let s=await n.generateMusic({prompt:t.prompt,purpose:t.purpose,style:t.style,lyrics:r,duration:t.duration,isInstrumental:t.is_instrumental,audioUrl:t.cover_audio_url,audioFormat:t.audio_format}),o=s.mediaUrls.length;return{content:[{type:"text",text:`Generated ${o} audio track${o>1?"s":""}${s.model?` (model: ${s.model})`:""}`}],details:{type:"music_generate",model:s.model,durationMs:s.durationMs,mediaUrls:s.mediaUrls}}}}}var PA="video_edit",IA={type:"object",properties:{prompt:{type:"string",description:"Edit instruction. Reference videos as \u89C6\u98911, \u89C6\u98912, \u89C6\u98913. Reference images as \u56FE\u72471, \u56FE\u72472. Operations: add/remove/modify elements, extend, track fill."},source_videos:{type:"array",items:{type:"string"},minItems:1,maxItems:3,description:"Video(s) to edit (1-3 URLs). Order: [0]=\u89C6\u98911, [1]=\u89C6\u98912, [2]=\u89C6\u98913. All URLs MUST be publicly accessible HTTP/HTTPS. Use file_upload tool first if the user provides a local file."},reference_images:{type:"array",items:{type:"string"},maxItems:9,description:"Optional reference images for element replacement (up to 9). All URLs MUST be publicly accessible HTTP/HTTPS. Use file_upload tool first if the user provides a local file."},duration:{type:"number",minimum:4,maximum:15,description:"Output duration in seconds (4-15s). Default: same as source."},aspect_ratio:{type:"string",description:"Output aspect ratio: 16:9, 9:16, 1:1, 4:3, 3:4, 21:9. Default: same as source."},resolution:{type:"string",description:"Output resolution: '480p' or '720p'. Default: '720p'."}},required:["prompt","source_videos"]};function im(n){return{name:PA,label:"Video Edit",description:"Edit existing videos: add/remove/modify elements, extend, or bridge clips. Requires source_videos (max 3). Max 9 reference images for element replacement. Max 720p. All video/image URLs MUST be publicly accessible HTTP/HTTPS. Use file_upload tool first if the user provides a local file. For generating NEW videos from scratch, use video_generate instead.",parameters:IA,execute:async(e,t)=>{if(!t.source_videos?.length)return{content:[{type:"text",text:"Error: source_videos is required."}]};let r=await n.editVideo({prompt:t.prompt,sourceVideos:t.source_videos,referenceImages:t.reference_images,duration:t.duration,aspectRatio:t.aspect_ratio,resolution:t.resolution});return{content:[{type:"text",text:`Video edited successfully${r.model?` (model: ${r.model})`:""}`}],details:{type:"video_edit",model:r.model,durationMs:r.durationMs,mediaUrls:r.mediaUrls}}}}}var _A="video_merge",EA={type:"object",properties:{clips:{type:"array",items:{type:"object",properties:{video:{type:"string",description:"Video URL or file path. MUST be publicly accessible HTTP/HTTPS URL. Use file_upload tool first if local file."},audio:{type:"string",description:"Narration audio file path (from TTS)."},trimStart:{type:"number",description:"Trim start in seconds (default 0)."},trimEnd:{type:"number",description:"Trim end in seconds (default: full)."}},required:["video"]},minItems:2,description:"Array of video clips to merge, in order."},transition:{type:"string",description:"Transition effect: 'crossfade' (default), 'fade', 'wipeleft', 'cut', 'dissolve', etc."},transitionDuration:{type:"number",description:"Transition duration in seconds (0.1-2.0, default 0.5)."},subtitles:{type:"string",description:"Path to SRT subtitle file to burn-in."},bgm:{type:"string",description:"Background music file path."},bgmVolume:{type:"number",description:"BGM volume (0.0-1.0, default 0.15)."},outputResolution:{type:"string",description:"Output resolution: '1920x1080', '1080x1920', etc. Default: auto."},outputFps:{type:"number",description:"Output FPS (default 30)."}},required:["clips"]};function am(n){return{name:_A,label:"Video Merge",description:"Merge multiple video clips into a single video with transitions, subtitles, and background music. Requires at least 2 clips. Supports crossfade, fade, wipe, dissolve, and cut transitions. All video/audio URLs MUST be publicly accessible HTTP/HTTPS. Use file_upload tool first if the user provides local files. Audio per clip is preserved; BGM is mixed at adjustable volume.",parameters:EA,execute:async(e,t)=>{if(!t.clips||t.clips.length<2)return{content:[{type:"text",text:"Error: at least 2 clips are required for merging."}]};let r=await n.mergeVideos({clips:t.clips,transition:t.transition,transitionDuration:t.transitionDuration,subtitles:t.subtitles,bgm:t.bgm,bgmVolume:t.bgmVolume,outputResolution:t.outputResolution,outputFps:t.outputFps});return{content:[{type:"text",text:`Merged ${r.clipCount} clips \u2192 ${r.durationSec.toFixed(1)}s video`+(t.transition?` (transition: ${t.transition})`:"")}],details:{type:"video_merge",localPath:r.localPath,servePath:r.servePath,durationSec:r.durationSec,clipCount:r.clipCount,mediaUrls:r.mediaUrls}}}}}var CA="video_upscale",MA={type:"object",properties:{video:{type:"string",description:"Video URL to upscale. MUST be publicly accessible HTTP/HTTPS URL. Use file_upload tool first if the user provides a local file."},targetResolution:{type:"string",description:"Target resolution: '1080p' (default, 1920x1080/1080x1920), '2k' (2560x1440/1440x2560)."},sharpness:{type:"string",description:"Sharpening intensity: 'light' (default), 'medium', 'strong'."}},required:["video"]};function cm(n){return{name:CA,label:"Video Upscale",description:"Upscale a video to higher resolution with optional sharpening. Auto-detects orientation (landscape/portrait). Uses Lanczos interpolation + unsharp mask. Supports 1080p and 2K targets. Video URL MUST be publicly accessible HTTP/HTTPS. Use file_upload tool first if the user provides a local file. Best used as post-processing after video_merge.",parameters:MA,execute:async(e,t)=>{let r=await n.upscaleVideo({video:t.video,targetResolution:t.targetResolution,sharpness:t.sharpness});return{content:[{type:"text",text:`Upscaled to ${r.resolution}${t.sharpness?` (sharpness: ${t.sharpness})`:""}`}],details:{type:"video_upscale",localPath:r.localPath,servePath:r.servePath,resolution:r.resolution,durationSec:r.durationSec,mediaUrls:r.mediaUrls}}}}}var NA="three_d_generate",DA={type:"object",properties:{prompt:{type:"string",description:"3D model generation prompt. Describe the object's shape, material, texture, color, and pose. For text-to-3D, provide a detailed description. For image-to-3D, also provide image_url."},image_url:{type:"string",description:"Reference image URL for image-to-3D generation. The image should show the object clearly from a single viewpoint with clean background for best results. MUST be a publicly accessible HTTP/HTTPS URL. Local file paths and data: URLs are NOT supported."},output_format:{type:"string",description:"3D model output format: 'glb' (default), 'obj', 'usd', 'usdz'."},seed:{type:"number",description:"Random seed for reproducible generation."}},required:["prompt"]};function lm(n){return{name:NA,label:"3D Generate",description:"Generate a 3D model from a text prompt or reference image. Supports text-to-3D and image-to-3D workflows. Output formats include GLB, OBJ, USD. The generated model can be viewed in any 3D viewer or imported into game engines. IMPORTANT: Describe the object in detail \u2014 shape, size, material, texture, color, and pose.",parameters:DA,execute:async(e,t)=>{let r=await n.generate3D({prompt:t.prompt,imageUrl:t.image_url,outputFormat:t.output_format,seed:t.seed}),s=r.mediaUrls.length,o=`Generated ${s} 3D model${s>1?"s":""}${r.model?` (model: ${r.model})`:""}`;return s===0&&r.metadata?.debugResponseKeys&&(o+=` [debug: response keys=${JSON.stringify(r.metadata.debugResponseKeys)}, content=${r.metadata.debugContentSample??"null"}]`),{content:[{type:"text",text:o}],details:{type:"three_d_generate",model:r.model,durationMs:r.durationMs,mediaUrls:r.mediaUrls,...r.metadata??{}}}}}}var OA={type:"object",properties:{audio_url:{type:"string",description:"URL of the audio file to transcribe. Supports mp3, wav, m4a, ogg, flac formats. MUST be a publicly accessible HTTP/HTTPS URL. Use file_upload tool first if the user provides a local file."},language:{type:"string",description:"Language hint for transcription: 'zh' (Chinese), 'en' (English), or auto-detect if omitted."}},required:["audio_url"]};function dm(n){return{name:"stt",label:"STT",description:"Transcribe audio to text (Speech-to-Text). Provide an audio file URL and receive the spoken content as text. Supports Chinese and English. Use for meeting transcription, voice message reading, subtitle generation, or any audio-to-text conversion.",parameters:OA,execute:async(e,t)=>{if(!t.audio_url)return{content:[{type:"text",text:"Error: audio_url parameter is required. Provide a publicly accessible HTTP/HTTPS URL to an audio file."}],details:{error:"audio_url parameter is required"}};let r=await n.speechToText({audioUrl:t.audio_url,language:t.language}),s=r.transcription.length>200?r.transcription.slice(0,200)+"\u2026":r.transcription;return{content:[{type:"text",text:r.transcription}],details:{type:"stt",model:r.model,durationMs:r.durationMs,transcriptionLength:r.transcription.length,preview:s}}}}}var LA="voice_clone",$A={type:"object",properties:{text:{type:"string",description:"Text to synthesize in the cloned voice."},sample_audio_url:{type:"string",description:"URL of an audio sample (5-30 seconds recommended) of the voice to clone. The sample should be clear speech with minimal background noise. MUST be a publicly accessible HTTP/HTTPS URL. Use file_upload tool first if the user provides a local file."},speed:{type:"number",description:"Speech speed multiplier (0.5-2.0). Default is 1.0."}},required:["text","sample_audio_url"]};function um(n){return{name:LA,label:"Voice Clone",description:"Clone a voice from an audio sample and synthesize new speech in that voice. Requires a clear audio sample (5-30s recommended) of the target voice. Use for personalized narration, character voices, or voice preservation. DO NOT use for impersonation or deception. For standard TTS with preset voices, use the tts tool instead.",parameters:$A,execute:async(e,t)=>{let r=await n.cloneVoice({text:t.text,sampleAudioUrl:t.sample_audio_url,speed:t.speed});return{content:[{type:"text",text:`Voice cloned and synthesized speech${r.model?` (model: ${r.model})`:""}`}],details:{type:"voice_clone",model:r.model,voiceId:r.voiceId,durationMs:r.durationMs,mediaUrls:r.mediaUrls}}}}}var jA="media_cancel",UA={type:"object",properties:{task_id:{type:"string",description:"The task ID of the media generation to cancel (returned in previous generation results)."},provider:{type:"string",description:"Provider name (e.g. 'doubao', 'zhipu'). If omitted, auto-detects from task context."}},required:["task_id"]};function pm(n){return{name:jA,label:"Media Cancel",description:"Cancel an in-progress media generation task (video, 3D, etc.). Provide the task_id from a previous generation result. Use this when a user wants to abort a long-running generation.",parameters:UA,execute:async(e,t)=>{if(!t.task_id)return{content:[{type:"text",text:"Error: task_id is required."}],details:{error:"task_id is required"}};let r=await n.cancelTask({taskId:t.task_id,provider:t.provider});return{content:[{type:"text",text:r.ok?`Task ${t.task_id} cancelled.`:`Cancel failed: ${r.message}`}],details:r.ok?void 0:{error:r.message}}}}}var FA="file_upload",BA={type:"object",properties:{file_path:{type:"string",description:"Absolute path to the local file to upload. Supported: images (jpg/png/webp/gif), audio (mp3/wav/m4a/ogg/flac), video (mp4/mov/avi). The file will be uploaded to the configured provider's Files API and a file ID or public URL will be returned."},purpose:{type:"string",description:"Upload purpose hint: 'media_reference' (for image/video/audio generation), 'user_data' (general). Default: 'media_reference'."}},required:["file_path"]};function mm(n){return{name:FA,label:"File Upload",description:"Upload a local file to the cloud provider's Files API. Returns a file ID (or public URL) that can be used as input for media generation tools (image_generate, video_generate, video_edit, etc.). Use this when the user provides a local file that needs to be referenced by URL in media tools. IMPORTANT: Only call this tool for files that actually need to be uploaded for media generation. Not all providers support file upload \u2014 tool availability depends on the configured provider.",parameters:BA,execute:async(e,t)=>{let r=await n.uploadFile({filePath:t.file_path,purpose:t.purpose}),s=[`Uploaded "${r.filename}" (${oc(r.bytes)}) via ${r.provider}`];return r.url&&s.push(`URL: ${r.url}`),s.push(`File ID: ${r.fileId}`),{content:[{type:"text",text:s.join(`
|
|
612
|
-
`)}],details:{type:"file_upload",fileId:r.fileId,url:r.url,filename:r.filename,bytes:r.bytes,provider:r.provider}}}}}var HA="file_query",qA={type:"object",properties:{file_id:{type:"string",description:"Query a specific file by ID. If omitted, lists recent uploaded files."},limit:{type:"number",description:"Max number of files to list when file_id is omitted. Default: 10, max: 100."}},required:[]};function
|
|
609
|
+
`)}],details:{...c,requestedSeconds:s}}}finally{r?.removeEventListener("abort",a)}}}}var kA="tool_search",SA={type:"object",properties:{query:{type:"string",description:'Search query for tools. Use "select:toolName" to directly activate a deferred tool, or provide keywords to search tool names/descriptions. Prefix a term with "+" to mark it as required (all +terms must match).'},maxResults:{type:"number",description:"Maximum number of results to return (default: 5)."}},required:["query"]},TA=5;function nm(n){return{name:kA,label:"Tool Search",description:'Search for available tools that are not currently loaded. Many tools are deferred to save context tokens. Use "select:toolName" to directly activate a tool, or provide keywords to find relevant tools. Activated tools become available in subsequent messages.',parameters:SA,execute:async(e,t)=>{if(!t.query||t.query.trim().length===0)return{content:[{type:"text",text:"Error: query is required."}],details:{type:"tool_search",error:"empty_query"}};let r=t.query.trim(),s=t.maxResults??TA;if(r.startsWith("select:")){let i=r.slice(7).split(",").map(d=>d.trim()).filter(Boolean),a=[],c=[];if(n.activateTool)for(let d of i)await n.activateTool(d)?a.push(d):c.push(d);else{let d=await n.searchTools(r,{maxResults:s});return tm(d)}let l=[];return a.length>0&&l.push(`Activated: ${a.join(", ")}. These tools are now available.`),c.length>0&&l.push(`Not found: ${c.join(", ")}.`),{content:[{type:"text",text:l.join(`
|
|
610
|
+
`)}],details:{type:"tool_search",activated:a,notFound:c,mode:"select"}}}let o=await n.searchTools(r,{maxResults:s});return tm(o)}}}function tm(n){if(n.matches.length===0)return{content:[{type:"text",text:`No tools found matching "${n.query}". Total deferred tools available: ${n.totalDeferred}.`}],details:{type:"tool_search",query:n.query,matchCount:0,totalDeferred:n.totalDeferred}};let e=[`Found ${n.matches.length} tool(s) matching "${n.query}" (${n.totalDeferred} total deferred):`,""];for(let t of n.matches)e.push(`- **${t.name}**: ${t.description}`);return e.push(""),e.push('Use "select:toolName" to activate a tool for use in subsequent messages.'),{content:[{type:"text",text:e.join(`
|
|
611
|
+
`)}],details:{type:"tool_search",query:n.query,matchCount:n.matches.length,totalDeferred:n.totalDeferred,matches:n.matches.map(t=>t.name)}}}var nc="image_generate",RA={type:"object",properties:{prompt:{type:"string",description:"Image generation prompt. Enrich vague requests with style, lighting, composition, color, mood details."},purpose:{type:"string",description:"Intended use: 'social-media', 'short-video-cover', 'phone-wallpaper', 'avatar', 'poster', etc."},style:{type:"string",description:"Visual art style: 'photorealistic', 'anime', 'watercolor', 'oil-painting', '3d-render', etc."},size:{type:"string",description:"Dimensions: e.g. '1024x1792' (portrait), '1792x1024' (landscape), '1024x1024' (square). Default: '1024x1024'."},image_url:{type:"string",description:"Reference image URL for image-to-image generation (img2img). Character reference sheet or style transfer. MUST be a publicly accessible HTTP/HTTPS URL. Local file paths and data: URLs are NOT supported."},n:{type:"number",description:"Number of images to generate (1-4). Default: 1."},quality:{type:"string",description:"Image quality level: 'auto', 'high', 'low', 'hd'. Provider-specific."},seed:{type:"number",description:"Random seed for reproducible generation. Same seed + prompt = same result."}},required:["prompt"]};function rm(n){return{name:nc,label:"Image Generate",description:"Generate images from a text prompt. You MUST enrich vague prompts with details about style, lighting, composition, color, and mood before calling. Supports img2img via image_url reference. All generated images are saved locally and can be viewed immediately. IMPORTANT: If the user has not specified purpose or preferred style, use ask_user to clarify (e.g. purpose: social-media / wallpaper / poster; style: photorealistic / anime / watercolor) before calling this tool. Infer image size automatically from purpose (e.g. 1024x1792 for phone wallpaper, 1792x1024 for landscape poster, 1024x1024 for avatar/social). Do NOT expose size as a raw number to the user. ALL reference image URLs MUST be publicly accessible HTTP/HTTPS URLs. Use file_upload tool first if the user provides a local file. Local file paths and data: URIs are NOT supported by the generation API.",parameters:RA,execute:async(e,t)=>{let r=await n.generateImage({prompt:t.prompt,purpose:t.purpose,style:t.style,size:t.size,imageUrl:t.image_url,n:t.n,quality:t.quality,seed:t.seed}),s=r.mediaUrls.length;return{content:[{type:"text",text:`Generated ${s} image${s>1?"s":""}${r.model?` (model: ${r.model})`:""}`}],details:{type:"image_generate",model:r.model,size:r.size,durationMs:r.durationMs,mediaUrls:r.mediaUrls}}}}}var AA={type:"object",properties:{text:{type:"string",description:"Text to convert to speech."},channel:{type:"string",description:"Optional channel id to pick output format (e.g. telegram)."},voice:{type:"string",description:"Voice name for TTS. Available voices depend on the provider. Common options: alloy, ash, ballad, coral, echo, fable, nova, onyx, sage, shimmer."},speed:{type:"number",description:"Speech speed multiplier (0.25-4.0). Default is 1.0."}},required:["text"]};function sm(n){return{name:"tts",label:"TTS",description:"Convert text to speech (TTS) \u2014 read text aloud as spoken audio. Use for narration, voice messages, or any spoken-word output. DO NOT use for music, songs, or melodies \u2014 use music_generate instead.",parameters:AA,execute:async(e,t)=>{let r=await n.textToSpeech({text:t.text,channel:t.channel,voice:t.voice,speed:t.speed});return{content:[{type:"text",text:"\u5DF2\u6210\u529F\u751F\u6210\u8BED\u97F3\u3002"}],details:{type:"tts",audioPath:r.audioPath,provider:r.provider,voiceCompatible:r.voiceCompatible,mediaUrls:r.mediaUrls}}}}}var rc="video_generate",wA={type:"object",properties:{prompt:{type:"string",description:"Video generation prompt. MUST be in English. Include scene, movement, camera motion, lighting, style."},purpose:{type:"string",description:"Intended use: 'social-media', 'short-video', 'presentation', etc."},style:{type:"string",description:"Visual style: 'cinematic', 'anime', 'watercolor', etc."},image_url:{type:"string",description:"Reference image URL for image-to-video generation (first frame, style reference, or character reference). MUST be a publicly accessible HTTP/HTTPS URL. Local file paths and data: URLs are NOT supported. If the user provides a local file, use a file hosting service or the image_generate tool first."},reference_videos:{type:"array",items:{type:"string"},maxItems:3,description:"Reference video URLs for video-to-video or multimodal generation (Seedance 2.0). Max 3 videos, total duration \u226415s. Use for: (a) video-to-video: provide source video to restyle/transform with prompt guidance; (b) multimodal reference: combine with image_url and/or reference_audios for style/motion/audio-guided generation. Each URL MUST be publicly accessible HTTP/HTTPS. Use file_upload tool first if the user provides a local file."},reference_audios:{type:"array",items:{type:"string"},maxItems:3,description:"Reference audio URLs for audio-guided video generation (Seedance 2.0). Max 3 audio clips, total duration \u226415s. CANNOT be used alone \u2014 must be combined with at least one image_url or reference_video. Each URL MUST be publicly accessible HTTP/HTTPS. Use file_upload tool first if the user provides a local file."},generate_audio:{type:"boolean",description:"Generate synchronized audio track for the video (Seedance 2.0/1.5 pro). When true, the output video includes AI-generated sound effects matching the visual content."},aspect_ratio:{type:"string",description:"Video aspect ratio: '9:16' (vertical), '16:9' (horizontal), '1:1' (square). Default: '16:9'."},duration:{type:"number",minimum:3,maximum:15,description:"Video duration in seconds. Seedance 2.0: 4-15s per shot. Seedance 1.0/1.5: 3-10s. For longer videos (>15s), use multi-shot storyboard workflow (generate + extend/merge). Must be confirmed by user before generation."},resolution:{type:"string",description:"Output resolution: '480p', '720p', '1080p'. Default: '720p'."},fps:{type:"number",description:"Frame rate: 24 or 30 fps. Default: provider-specific."},seed:{type:"number",description:"Random seed for reproducible generation."},camera_fixed:{type:"boolean",description:"Lock camera position (Seedance 1.0/1.5 only, not supported for img2video)."},return_last_frame:{type:"boolean",description:"Return last frame URL for chaining continuous video segments."},draft:{type:"boolean",description:"Draft mode: low-cost preview (Seedance 1.5 pro only)."},service_tier:{type:"string",enum:["default","flex"],description:"'default' (online, fast) or 'flex' (offline, ~50% cost). Not all models support flex."},callback_url:{type:"string",description:"Webhook URL for async task completion notification."},safety_identifier:{type:"string",description:"End-user safety identifier for content moderation tracking."},execution_expires_after:{type:"number",description:"Task expiration in seconds (for offline/flex scheduling)."},video_tools:{type:"array",items:{type:"string"},description:"Video-level builtin tools, e.g. ['web_search'] (Seedance 2.0 online search)."}},required:["prompt"]};function om(n){return{name:rc,label:"Video Generate",description:"Generate a short video clip from a text prompt, reference image, source video, or multimodal references. Prompt MUST be in English. Include scene, movement, camera motion, lighting details. Single-shot: 3\u201310s. For longer videos (>10s), use multi-shot storyboard workflow. MODES: (1) text-to-video: prompt only. (2) image-to-video: prompt + image_url. (3) video-to-video: prompt + reference_videos \u2014 restyle/transform an existing video with prompt guidance. (4) multimodal reference: prompt + any combination of image_url / reference_videos / reference_audios for style/motion/audio-guided generation. (5) generate_audio=true for synchronized sound effects. ALL image/video/audio URLs MUST be publicly accessible HTTP/HTTPS URLs. Local file paths and data: URIs are NOT supported by the generation API. If the user provides a local file, use the file_upload tool FIRST to get a public URL. IMPORTANT: If the user has not specified aspect ratio or duration, use ask_user to clarify (e.g. aspect: 16:9 for landscape / 9:16 for vertical / 1:1 for square; duration: 3-10s). Auto-set aspect_ratio based on stated purpose (e.g. 9:16 for short-video / Douyin, 16:9 for presentation).",parameters:wA,execute:async(e,t)=>{let r=await n.generateVideo({prompt:t.prompt,purpose:t.purpose,style:t.style,imageUrl:t.image_url,referenceVideos:t.reference_videos,referenceAudios:t.reference_audios,generateAudio:t.generate_audio,aspectRatio:t.aspect_ratio,duration:t.duration,resolution:t.resolution,fps:t.fps,seed:t.seed,cameraFixed:t.camera_fixed,returnLastFrame:t.return_last_frame,draft:t.draft,serviceTier:t.service_tier,callbackUrl:t.callback_url,safetyIdentifier:t.safety_identifier,executionExpiresAfterSeconds:t.execution_expires_after,videoTools:t.video_tools}),s=r.mediaUrls.length,o=[`Generated ${s} video${s>1?"s":""}`];return r.model&&o.push(`model: ${r.model}`),r.lastFrameUrl&&o.push(`last_frame: ${r.lastFrameUrl}`),r.taskId&&o.push(`task_id: ${r.taskId}`),{content:[{type:"text",text:o.length>1?`${o[0]} (${o.slice(1).join(", ")})`:o[0]}],details:{type:"video_generate",model:r.model,durationMs:r.durationMs,mediaUrls:r.mediaUrls,...r.taskId?{taskId:r.taskId}:{}}}}}}var sc="music_generate",xA={type:"object",properties:{prompt:{type:"string",description:"Music generation prompt. MUST be in English. Include genre, mood, tempo, instruments, and atmosphere details."},purpose:{type:"string",description:"Intended use: 'background-music', 'ringtone', 'short-video-bgm', 'full-song', 'notification-sound', etc."},style:{type:"string",description:"Musical style/genre: 'lo-fi', 'pop', 'rock', 'jazz', 'classical', 'electronic', 'ambient', etc."},lyrics:{type:"string",description:"Optional lyrics for vocal music. Structure with [verse], [chorus], [bridge] tags if desired."},duration:{type:"number",description:"Duration in seconds (5-300). Infer from purpose: ringtone 15-30s, BGM 30-60s, full song 120-180s."},is_instrumental:{type:"boolean",description:"Set true for pure instrumental music without vocals. Defaults to true when no lyrics are provided."},cover_audio_url:{type:"string",description:"URL of an existing audio track to use as base for cover/remix. When provided, generates a cover version. MUST be a publicly accessible HTTP/HTTPS URL. Use file_upload tool first if the user provides a local file."},audio_format:{type:"string",enum:["mp3","wav","flac"],description:"Output audio format. Defaults to mp3."}},required:["prompt"]};function im(n){return{name:sc,label:"Music Generate",description:"Generate music, songs, or melodies from text descriptions. Prompt MUST be in English. Supports lyrics for vocal songs. DO NOT use for spoken-word audio or TTS \u2014 use tts tool instead. IMPORTANT: If the user has not specified genre/style or duration, use ask_user to clarify (e.g. style: lo-fi / pop / rock / jazz; duration inferred from purpose: 30s for ringtone, 60-90s for BGM, 180-240s for full song). Auto-infer duration from purpose when possible.",parameters:xA,execute:async(e,t)=>{let r=t.lyrics;if(!r&&!t.is_instrumental&&n.generateLyrics)try{r=await n.generateLyrics(t.prompt)}catch{}let s=await n.generateMusic({prompt:t.prompt,purpose:t.purpose,style:t.style,lyrics:r,duration:t.duration,isInstrumental:t.is_instrumental,audioUrl:t.cover_audio_url,audioFormat:t.audio_format}),o=s.mediaUrls.length;return{content:[{type:"text",text:`Generated ${o} audio track${o>1?"s":""}${s.model?` (model: ${s.model})`:""}`}],details:{type:"music_generate",model:s.model,durationMs:s.durationMs,mediaUrls:s.mediaUrls}}}}}var PA="video_edit",IA={type:"object",properties:{prompt:{type:"string",description:"Edit instruction. Reference videos as \u89C6\u98911, \u89C6\u98912, \u89C6\u98913. Reference images as \u56FE\u72471, \u56FE\u72472. Operations: add/remove/modify elements, extend, track fill."},source_videos:{type:"array",items:{type:"string"},minItems:1,maxItems:3,description:"Video(s) to edit (1-3 URLs). Order: [0]=\u89C6\u98911, [1]=\u89C6\u98912, [2]=\u89C6\u98913. All URLs MUST be publicly accessible HTTP/HTTPS. Use file_upload tool first if the user provides a local file."},reference_images:{type:"array",items:{type:"string"},maxItems:9,description:"Optional reference images for element replacement (up to 9). All URLs MUST be publicly accessible HTTP/HTTPS. Use file_upload tool first if the user provides a local file."},duration:{type:"number",minimum:4,maximum:15,description:"Output duration in seconds (4-15s). Default: same as source."},aspect_ratio:{type:"string",description:"Output aspect ratio: 16:9, 9:16, 1:1, 4:3, 3:4, 21:9. Default: same as source."},resolution:{type:"string",description:"Output resolution: '480p' or '720p'. Default: '720p'."}},required:["prompt","source_videos"]};function am(n){return{name:PA,label:"Video Edit",description:"Edit existing videos: add/remove/modify elements, extend, or bridge clips. Requires source_videos (max 3). Max 9 reference images for element replacement. Max 720p. All video/image URLs MUST be publicly accessible HTTP/HTTPS. Use file_upload tool first if the user provides a local file. For generating NEW videos from scratch, use video_generate instead.",parameters:IA,execute:async(e,t)=>{if(!t.source_videos?.length)return{content:[{type:"text",text:"Error: source_videos is required."}]};let r=await n.editVideo({prompt:t.prompt,sourceVideos:t.source_videos,referenceImages:t.reference_images,duration:t.duration,aspectRatio:t.aspect_ratio,resolution:t.resolution});return{content:[{type:"text",text:`Video edited successfully${r.model?` (model: ${r.model})`:""}`}],details:{type:"video_edit",model:r.model,durationMs:r.durationMs,mediaUrls:r.mediaUrls}}}}}var _A="video_merge",EA={type:"object",properties:{clips:{type:"array",items:{type:"object",properties:{video:{type:"string",description:"Video URL or file path. MUST be publicly accessible HTTP/HTTPS URL. Use file_upload tool first if local file."},audio:{type:"string",description:"Narration audio file path (from TTS)."},trimStart:{type:"number",description:"Trim start in seconds (default 0)."},trimEnd:{type:"number",description:"Trim end in seconds (default: full)."}},required:["video"]},minItems:2,description:"Array of video clips to merge, in order."},transition:{type:"string",description:"Transition effect: 'crossfade' (default), 'fade', 'wipeleft', 'cut', 'dissolve', etc."},transitionDuration:{type:"number",description:"Transition duration in seconds (0.1-2.0, default 0.5)."},subtitles:{type:"string",description:"Path to SRT subtitle file to burn-in."},bgm:{type:"string",description:"Background music file path."},bgmVolume:{type:"number",description:"BGM volume (0.0-1.0, default 0.15)."},outputResolution:{type:"string",description:"Output resolution: '1920x1080', '1080x1920', etc. Default: auto."},outputFps:{type:"number",description:"Output FPS (default 30)."}},required:["clips"]};function cm(n){return{name:_A,label:"Video Merge",description:"Merge multiple video clips into a single video with transitions, subtitles, and background music. Requires at least 2 clips. Supports crossfade, fade, wipe, dissolve, and cut transitions. All video/audio URLs MUST be publicly accessible HTTP/HTTPS. Use file_upload tool first if the user provides local files. Audio per clip is preserved; BGM is mixed at adjustable volume.",parameters:EA,execute:async(e,t)=>{if(!t.clips||t.clips.length<2)return{content:[{type:"text",text:"Error: at least 2 clips are required for merging."}]};let r=await n.mergeVideos({clips:t.clips,transition:t.transition,transitionDuration:t.transitionDuration,subtitles:t.subtitles,bgm:t.bgm,bgmVolume:t.bgmVolume,outputResolution:t.outputResolution,outputFps:t.outputFps});return{content:[{type:"text",text:`Merged ${r.clipCount} clips \u2192 ${r.durationSec.toFixed(1)}s video`+(t.transition?` (transition: ${t.transition})`:"")}],details:{type:"video_merge",localPath:r.localPath,servePath:r.servePath,durationSec:r.durationSec,clipCount:r.clipCount,mediaUrls:r.mediaUrls}}}}}var CA="video_upscale",MA={type:"object",properties:{video:{type:"string",description:"Video URL to upscale. MUST be publicly accessible HTTP/HTTPS URL. Use file_upload tool first if the user provides a local file."},targetResolution:{type:"string",description:"Target resolution: '1080p' (default, 1920x1080/1080x1920), '2k' (2560x1440/1440x2560)."},sharpness:{type:"string",description:"Sharpening intensity: 'light' (default), 'medium', 'strong'."}},required:["video"]};function lm(n){return{name:CA,label:"Video Upscale",description:"Upscale a video to higher resolution with optional sharpening. Auto-detects orientation (landscape/portrait). Uses Lanczos interpolation + unsharp mask. Supports 1080p and 2K targets. Video URL MUST be publicly accessible HTTP/HTTPS. Use file_upload tool first if the user provides a local file. Best used as post-processing after video_merge.",parameters:MA,execute:async(e,t)=>{let r=await n.upscaleVideo({video:t.video,targetResolution:t.targetResolution,sharpness:t.sharpness});return{content:[{type:"text",text:`Upscaled to ${r.resolution}${t.sharpness?` (sharpness: ${t.sharpness})`:""}`}],details:{type:"video_upscale",localPath:r.localPath,servePath:r.servePath,resolution:r.resolution,durationSec:r.durationSec,mediaUrls:r.mediaUrls}}}}}var NA="three_d_generate",DA={type:"object",properties:{prompt:{type:"string",description:"3D model generation prompt. Describe the object's shape, material, texture, color, and pose. For text-to-3D, provide a detailed description. For image-to-3D, also provide image_url."},image_url:{type:"string",description:"Reference image URL for image-to-3D generation. The image should show the object clearly from a single viewpoint with clean background for best results. MUST be a publicly accessible HTTP/HTTPS URL. Local file paths and data: URLs are NOT supported."},output_format:{type:"string",description:"3D model output format: 'glb' (default), 'obj', 'usd', 'usdz'."},seed:{type:"number",description:"Random seed for reproducible generation."}},required:["prompt"]};function dm(n){return{name:NA,label:"3D Generate",description:"Generate a 3D model from a text prompt or reference image. Supports text-to-3D and image-to-3D workflows. Output formats include GLB, OBJ, USD. The generated model can be viewed in any 3D viewer or imported into game engines. IMPORTANT: Describe the object in detail \u2014 shape, size, material, texture, color, and pose.",parameters:DA,execute:async(e,t)=>{let r=await n.generate3D({prompt:t.prompt,imageUrl:t.image_url,outputFormat:t.output_format,seed:t.seed}),s=r.mediaUrls.length,o=`Generated ${s} 3D model${s>1?"s":""}${r.model?` (model: ${r.model})`:""}`;return s===0&&r.metadata?.debugResponseKeys&&(o+=` [debug: response keys=${JSON.stringify(r.metadata.debugResponseKeys)}, content=${r.metadata.debugContentSample??"null"}]`),{content:[{type:"text",text:o}],details:{type:"three_d_generate",model:r.model,durationMs:r.durationMs,mediaUrls:r.mediaUrls,...r.metadata??{}}}}}}var OA={type:"object",properties:{audio_url:{type:"string",description:"URL of the audio file to transcribe. Supports mp3, wav, m4a, ogg, flac formats. MUST be a publicly accessible HTTP/HTTPS URL. Use file_upload tool first if the user provides a local file."},language:{type:"string",description:"Language hint for transcription: 'zh' (Chinese), 'en' (English), or auto-detect if omitted."}},required:["audio_url"]};function um(n){return{name:"stt",label:"STT",description:"Transcribe audio to text (Speech-to-Text). Provide an audio file URL and receive the spoken content as text. Supports Chinese and English. Use for meeting transcription, voice message reading, subtitle generation, or any audio-to-text conversion.",parameters:OA,execute:async(e,t)=>{if(!t.audio_url)return{content:[{type:"text",text:"Error: audio_url parameter is required. Provide a publicly accessible HTTP/HTTPS URL to an audio file."}],details:{error:"audio_url parameter is required"}};let r=await n.speechToText({audioUrl:t.audio_url,language:t.language}),s=r.transcription.length>200?r.transcription.slice(0,200)+"\u2026":r.transcription;return{content:[{type:"text",text:r.transcription}],details:{type:"stt",model:r.model,durationMs:r.durationMs,transcriptionLength:r.transcription.length,preview:s}}}}}var LA="voice_clone",$A={type:"object",properties:{text:{type:"string",description:"Text to synthesize in the cloned voice."},sample_audio_url:{type:"string",description:"URL of an audio sample (5-30 seconds recommended) of the voice to clone. The sample should be clear speech with minimal background noise. MUST be a publicly accessible HTTP/HTTPS URL. Use file_upload tool first if the user provides a local file."},speed:{type:"number",description:"Speech speed multiplier (0.5-2.0). Default is 1.0."}},required:["text","sample_audio_url"]};function pm(n){return{name:LA,label:"Voice Clone",description:"Clone a voice from an audio sample and synthesize new speech in that voice. Requires a clear audio sample (5-30s recommended) of the target voice. Use for personalized narration, character voices, or voice preservation. DO NOT use for impersonation or deception. For standard TTS with preset voices, use the tts tool instead.",parameters:$A,execute:async(e,t)=>{let r=await n.cloneVoice({text:t.text,sampleAudioUrl:t.sample_audio_url,speed:t.speed});return{content:[{type:"text",text:`Voice cloned and synthesized speech${r.model?` (model: ${r.model})`:""}`}],details:{type:"voice_clone",model:r.model,voiceId:r.voiceId,durationMs:r.durationMs,mediaUrls:r.mediaUrls}}}}}var jA="media_cancel",UA={type:"object",properties:{task_id:{type:"string",description:"The task ID of the media generation to cancel (returned in previous generation results)."},provider:{type:"string",description:"Provider name (e.g. 'doubao', 'zhipu'). If omitted, auto-detects from task context."}},required:["task_id"]};function mm(n){return{name:jA,label:"Media Cancel",description:"Cancel an in-progress media generation task (video, 3D, etc.). Provide the task_id from a previous generation result. Use this when a user wants to abort a long-running generation.",parameters:UA,execute:async(e,t)=>{if(!t.task_id)return{content:[{type:"text",text:"Error: task_id is required."}],details:{error:"task_id is required"}};let r=await n.cancelTask({taskId:t.task_id,provider:t.provider});return{content:[{type:"text",text:r.ok?`Task ${t.task_id} cancelled.`:`Cancel failed: ${r.message}`}],details:r.ok?void 0:{error:r.message}}}}}var FA="file_upload",BA={type:"object",properties:{file_path:{type:"string",description:"Absolute path to the local file to upload. Supported: images (jpg/png/webp/gif), audio (mp3/wav/m4a/ogg/flac), video (mp4/mov/avi). The file will be uploaded to the configured provider's Files API and a file ID or public URL will be returned."},purpose:{type:"string",description:"Upload purpose hint: 'media_reference' (for image/video/audio generation), 'user_data' (general). Default: 'media_reference'."}},required:["file_path"]};function gm(n){return{name:FA,label:"File Upload",description:"Upload a local file to the cloud provider's Files API. Returns a file ID (or public URL) that can be used as input for media generation tools (image_generate, video_generate, video_edit, etc.). Use this when the user provides a local file that needs to be referenced by URL in media tools. IMPORTANT: Only call this tool for files that actually need to be uploaded for media generation. Not all providers support file upload \u2014 tool availability depends on the configured provider.",parameters:BA,execute:async(e,t)=>{let r=await n.uploadFile({filePath:t.file_path,purpose:t.purpose}),s=[`Uploaded "${r.filename}" (${oc(r.bytes)}) via ${r.provider}`];return r.url&&s.push(`URL: ${r.url}`),s.push(`File ID: ${r.fileId}`),{content:[{type:"text",text:s.join(`
|
|
612
|
+
`)}],details:{type:"file_upload",fileId:r.fileId,url:r.url,filename:r.filename,bytes:r.bytes,provider:r.provider}}}}}var HA="file_query",qA={type:"object",properties:{file_id:{type:"string",description:"Query a specific file by ID. If omitted, lists recent uploaded files."},limit:{type:"number",description:"Max number of files to list when file_id is omitted. Default: 10, max: 100."}},required:[]};function fm(n){return{name:HA,label:"File Query",description:"Query or list uploaded files from the provider's Files API. Use file_id to get info on a specific file, or omit to list recent uploads. Returns file ID, name, size, status, and URL (if available).",parameters:qA,execute:async(e,t)=>{if(t.file_id){let i=await n.queryFile({fileId:t.file_id}),a=[`File: ${i.filename}`,`ID: ${i.id}`,`Size: ${oc(i.bytes)}`,`Status: ${i.status}`];return i.url&&a.push(`URL: ${i.url}`),i.createdAt&&a.push(`Created: ${i.createdAt}`),{content:[{type:"text",text:a.join(`
|
|
613
613
|
`)}],details:{type:"file_query",fileId:i.id}}}let r=Math.min(Math.max(t.limit??10,1),100),s=await n.listFiles({limit:r});if(s.length===0)return{content:[{type:"text",text:"No uploaded files found."}],details:{type:"file_query",count:0}};let o=[`Found ${s.length} file(s):
|
|
614
614
|
`];for(let i of s)o.push(`- ${i.filename} | ID: ${i.id} | ${oc(i.bytes)} | ${i.status}${i.url?` | ${i.url}`:""}`);return{content:[{type:"text",text:o.join(`
|
|
615
|
-
`)}],details:{type:"file_query",count:s.length}}}}}var WA="file_delete",GA={type:"object",properties:{file_id:{type:"string",description:"ID of the uploaded file to delete."}},required:["file_id"]};function
|
|
616
|
-
`)}],details:{type:"ask_user",answers:s,questionCount:t.questions.length}}}}}var zA="project_switch",XA={type:"object",properties:{projectName:{type:"string",description:"The name of the project to switch to. Use the exact project name from the available project list."}},required:["projectName"]};function
|
|
617
|
-
`),parameters:XA,isReadOnly:!1,isConcurrencySafe:!1,shouldDefer:!0,searchHint:"switch project change workspace \u5207\u6362\u9879\u76EE",execute:async(e,t)=>{let r=n.listProjects();if(r.length===0)return{content:[{type:"text",text:"Error: No projects available."}]};let s=t.projectName.toLowerCase().trim(),o=r.find(a=>a.name.toLowerCase()===s);if(!o){let a=r.map(c=>`"${c.name}"`).join(", ");return{content:[{type:"text",text:`Error: No project with exact name "${t.projectName}". Available projects: ${a}. Please confirm the exact project name with the user before retrying.`}]}}let i=n.switchProject(o.id);return i?(n.onSwitched?.(i),{content:[{type:"text",text:`Switched to project "${i.name}" (workspace: ${i.workspaceDir}).`}]}):{content:[{type:"text",text:`Error: Failed to switch to project "${o.name}".`}]}}}}import{ZhipuToolAPI as ew}from"@xiaozhiclaw/provider-core/transports/zhipu-tool-api";import{MiniMaxMediaTransport as tw}from"@xiaozhiclaw/provider-core/transports/minimax-media";import{VolcengineMediaTransport as fr}from"@xiaozhiclaw/provider-core/transports/volcengine-media";import{GeminiFileAPI as nw}from"@xiaozhiclaw/provider-core/transports/gemini-file-api";function
|
|
615
|
+
`)}],details:{type:"file_query",count:s.length}}}}}var WA="file_delete",GA={type:"object",properties:{file_id:{type:"string",description:"ID of the uploaded file to delete."}},required:["file_id"]};function hm(n){return{name:WA,label:"File Delete",description:"Delete a previously uploaded file from the provider's Files API. Use the file ID returned by file_upload or file_query.",parameters:GA,execute:async(e,t)=>(await n.deleteFile({fileId:t.file_id}),{content:[{type:"text",text:`Deleted file ${t.file_id}`}],details:{type:"file_delete",fileId:t.file_id}})}}function oc(n){return n<1024?`${n} B`:n<1024*1024?`${(n/1024).toFixed(1)} KB`:`${(n/(1024*1024)).toFixed(1)} MB`}var KA="ask_user",VA={type:"object",properties:{questions:{type:"array",minItems:1,maxItems:4,description:"1-4 clarifying questions to ask the user.",items:{type:"object",properties:{question:{type:"string",description:"The question text. Should end with '?'."},header:{type:"string",description:"Short identifier/tag for this question (max 50 chars)."},options:{type:"array",description:"2-4 options for the user to choose from. Omit for free text.",items:{type:"object",properties:{label:{type:"string",description:"Display label (1-5 words)."},description:{type:"string",description:"Brief explanation of this option."}},required:["label"]}},multiSelect:{type:"boolean",description:"Allow selecting multiple options (default: false)."}},required:["question","header"]}}},required:["questions"]};function ym(n){return{name:KA,label:"Ask User",description:"Ask the user clarifying questions when you need more information to proceed. Supports free text questions and multiple-choice options. Use this when the user's intent is ambiguous or you need confirmation.",parameters:VA,execute:async(e,t)=>{if(!t.questions||t.questions.length===0)return{content:[{type:"text",text:"Error: at least one question is required."}],details:{type:"ask_user",error:"no_questions"}};if(t.questions.length>4)return{content:[{type:"text",text:"Error: maximum 4 questions allowed."}],details:{type:"ask_user",error:"too_many_questions"}};let r=t.questions.map(i=>i.question);if(new Set(r).size!==r.length)return{content:[{type:"text",text:"Error: all questions must have unique text."}],details:{type:"ask_user",error:"duplicate_questions"}};for(let i of t.questions){if(i.options&&(i.options.length<2||i.options.length>4))return{content:[{type:"text",text:`Error: question "${i.header}" must have 2-4 options (got ${i.options.length}).`}],details:{type:"ask_user",error:"invalid_option_count"}};if(i.options){let a=i.options.map(c=>c.label);if(new Set(a).size!==a.length)return{content:[{type:"text",text:`Error: question "${i.header}" has duplicate option labels.`}],details:{type:"ask_user",error:"duplicate_option_labels"}}}}let s=await n.askUser(t.questions);if(s===null)return{content:[{type:"text",text:"User declined to answer questions."}],details:{type:"ask_user",declined:!0}};let o=["User answered:"];for(let i of t.questions){let a=s[i.question]??"(no answer)";o.push(`- ${i.header}: ${a}`)}return{content:[{type:"text",text:o.join(`
|
|
616
|
+
`)}],details:{type:"ask_user",answers:s,questionCount:t.questions.length}}}}}var zA="project_switch",XA={type:"object",properties:{projectName:{type:"string",description:"The name of the project to switch to. Use the exact project name from the available project list."}},required:["projectName"]};function bm(n){return{name:zA,label:"Switch Project",description:["Switch the active project context. ONLY call this when the user EXPLICITLY asks to switch projects","(e.g. '\u5207\u6362\u5230XX\u9879\u76EE', 'switch to project X').","Do NOT call this if the user merely mentions a project name in conversation.","The projectName must be an EXACT match from the available project list.","If unsure which project the user means, ask them to clarify first."].join(`
|
|
617
|
+
`),parameters:XA,isReadOnly:!1,isConcurrencySafe:!1,shouldDefer:!0,searchHint:"switch project change workspace \u5207\u6362\u9879\u76EE",execute:async(e,t)=>{let r=n.listProjects();if(r.length===0)return{content:[{type:"text",text:"Error: No projects available."}]};let s=t.projectName.toLowerCase().trim(),o=r.find(a=>a.name.toLowerCase()===s);if(!o){let a=r.map(c=>`"${c.name}"`).join(", ");return{content:[{type:"text",text:`Error: No project with exact name "${t.projectName}". Available projects: ${a}. Please confirm the exact project name with the user before retrying.`}]}}let i=n.switchProject(o.id);return i?(n.onSwitched?.(i),{content:[{type:"text",text:`Switched to project "${i.name}" (workspace: ${i.workspaceDir}).`}]}):{content:[{type:"text",text:`Error: Failed to switch to project "${o.name}".`}]}}}}import{ZhipuToolAPI as ew}from"@xiaozhiclaw/provider-core/transports/zhipu-tool-api";import{MiniMaxMediaTransport as tw}from"@xiaozhiclaw/provider-core/transports/minimax-media";import{VolcengineMediaTransport as fr}from"@xiaozhiclaw/provider-core/transports/volcengine-media";import{GeminiFileAPI as nw}from"@xiaozhiclaw/provider-core/transports/gemini-file-api";function vm(n,e){return!n?.webSearch||!n.capabilities.includes("web_search")?e:async(t,r)=>{try{let o=await n.webSearch(t,{maxResults:r?.maxResults});if(r?.allowedDomains?.length){let i=new Set(r.allowedDomains.map(a=>a.toLowerCase()));o=o.filter(a=>{try{return i.has(new URL(a.url).hostname.toLowerCase())}catch{return!1}})}if(r?.blockedDomains?.length){let i=new Set(r.blockedDomains.map(a=>a.toLowerCase()));o=o.filter(a=>{try{return!i.has(new URL(a.url).hostname.toLowerCase())}catch{return!0}})}if(o.length>0)return{query:t,results:o.map(i=>({title:i.title,url:i.url,snippet:i.snippet}))}}catch{}return e(t,r)}}var YA=[{pattern:"Bash",behavior:"ask",reason:"Group security: shell commands require approval in group chat",source:"group-policy"},{pattern:"computer",behavior:"deny",reason:"Group security: computer control blocked in group chat",source:"group-policy"}],JA=[/\.env($|\.)/i,/\.(key|pem|p12|pfx|jks)$/i,/id_rsa/i,/id_ed25519/i,/\.ssh\//i,/secret/i,/credential/i,/token/i,/password/i,/\.aws\//i,/\.gnupg\//i];function km(){return[...YA]}function ic(n){return JA.some(e=>e.test(n))}var mc=!1;function gc(n){mc=n}var ke,Ue={},Am,lc,Jt={},wm;function fc(n){wm=n}var rw=new Set(["zhipu","zhipu-openai","zhipu-coding"]),sw="https://open.bigmodel.cn/api/paas/v4";function xm(n,e){if(!(!n||!e)&&rw.has(n))return new ew({baseUrl:sw,apiKey:e})}var Pm=null,ow;var dc;function Im(n){dc=n}function _m(n){Pm=n}function Em(n,e,t,r,s){ke=n,Ue=e??{},Am=t,lc=s,Jt=r??{},iw()}function hc(n){let e=Jt[n];if(!(!e||!ke))return ke.resolveModelById(e.provider,e.model,n)}function iw(){aw(),cw(),lw(),dw()}function aw(){let n=tt(rc);if(!n)return;let e=Jt.video;if(!e||!ke)return;let t=ke.resolveModelById(e.provider,e.model,"video");if(!t)return;let r=t.modelInfo.mediaCapabilities;if(!r)return;let s=r.maxDurationSeconds??10,o=s>=10?4:3,i=r.resolutions?.join("/")||"720P",a=t.modelInfo.name||t.modelInfo.id;n.description=`Generate a short video clip from a text prompt, reference image, source video, or multimodal references. Prompt MUST be in English. Include scene, movement, camera motion, lighting details. Current model: ${a}. Single-shot: ${o}\u2013${s}s. For longer videos (>${s}s), use multi-shot storyboard workflow. MODES: (1) text-to-video: prompt only. (2) image-to-video: prompt + image_url. (3) video-to-video: prompt + reference_videos \u2014 restyle/transform an existing video with prompt guidance. (4) multimodal reference: prompt + any combination of image_url / reference_videos / reference_audios for style/motion/audio-guided generation. (5) generate_audio=true for synchronized sound effects. ALL image/video/audio URLs MUST be publicly accessible HTTP/HTTPS URLs. Local file paths and data: URIs are NOT supported by the generation API. If the user provides a local file, use the file_upload tool FIRST to get a public URL. IMPORTANT: If the user has not specified aspect ratio or duration, use ask_user to clarify (e.g. aspect: 16:9 for landscape / 9:16 for vertical / 1:1 for square; duration: ${o}-${s}s). Auto-set aspect_ratio based on stated purpose (e.g. 9:16 for short-video / Douyin, 16:9 for presentation).`;let c=n.parameters?.properties,l=c?.duration;l&&(l.minimum=o,l.maximum=s,l.description=`Video duration in seconds (${o}\u2013${s}s for ${a}). For longer videos (>${s}s), use multi-shot storyboard workflow (generate + extend/merge). Must be confirmed by user before generation.`);let d=c?.resolution;d&&r.resolutions&&(d.description=`Output resolution: ${i}. Default: '720p'.`)}function cw(){let n=tt(nc);if(!n)return;let e=hc("image");if(!e)return;let t=e.modelInfo.mediaCapabilities,r=e.modelInfo.name||e.modelInfo.id,s=[];if(t?.sizes?.length&&s.push(`Sizes: ${t.sizes.join(", ")}`),t?.transparentBackground&&s.push("Supports transparent background"),n.description=`Generate images from a text prompt. You MUST enrich vague prompts with details about style, lighting, composition, color, and mood before calling. Supports img2img via image_url reference. All generated images are saved locally and can be viewed immediately. Current model: ${r}. ${s.join(". ")}${s.length?". ":""}IMPORTANT: If the user has not specified purpose or preferred style, use ask_user to clarify (e.g. purpose: social-media / wallpaper / poster; style: photorealistic / anime / watercolor). Infer image size automatically from purpose. ALL reference image URLs MUST be publicly accessible HTTP/HTTPS URLs. Use file_upload tool first if the user provides a local file.`,t?.sizes?.length){let i=n.parameters?.properties?.size;i&&(i.description=`Dimensions: ${t.sizes.join(", ")}. Default: '1024x1024'. Auto-infer from purpose.`)}}function lw(){let n=tt("tts");if(!n)return;let e=hc("tts");if(!e)return;let t=e.modelInfo.mediaCapabilities,r=e.modelInfo.name||e.modelInfo.id,s=[];if(t?.voices?.length&&s.push(`Voices: ${t.voices.join(", ")}`),t?.maxCharacters&&s.push(`Max: ${t.maxCharacters} characters per request`),t?.formats?.length&&s.push(`Formats: ${t.formats.join(", ")}`),n.description=`Convert text to speech (TTS) \u2014 read text aloud as spoken audio. Use for narration, voice messages, or any spoken-word output. DO NOT use for music, songs, or melodies \u2014 use music_generate instead. Current model: ${r}. ${s.join(". ")}${s.length?".":""}`,t?.voices?.length){let i=n.parameters?.properties?.voice;i&&(i.description=`Voice name. Available: ${t.voices.join(", ")}.`)}}function dw(){let n=tt(sc);if(!n)return;let e=hc("music");if(!e)return;let t=e.modelInfo.mediaCapabilities,r=e.modelInfo.name||e.modelInfo.id,s=[];if(t?.maxDurationSeconds&&s.push(`Max duration: ${t.maxDurationSeconds}s`),t?.formats?.length&&s.push(`Formats: ${t.formats.join(", ")}`),n.description=`Generate music, songs, or melodies from text descriptions. Prompt MUST be in English. Supports lyrics for vocal songs. DO NOT use for spoken-word audio or TTS \u2014 use tts tool instead. Current model: ${r}. ${s.join(". ")}${s.length?". ":""}IMPORTANT: If the user has not specified genre/style or duration, use ask_user to clarify (e.g. style: lo-fi / pop / rock / jazz; duration inferred from purpose).`,t?.maxDurationSeconds){let i=n.parameters?.properties?.duration;i&&(i.maximum=t.maxDurationSeconds,i.description=`Duration in seconds (5\u2013${t.maxDurationSeconds}s for ${r}). Infer from purpose: ringtone 15-30s, BGM 30-60s, full song 120-180s.`)}}async function xt(n){if(!ke)throw new Error(`No media provider configured for ${n.mediaType}`);let e=Jt[n.mediaType],t=e?.provider,r=e?.model||n.model;if(!t)throw new Error(`No provider configured for ${n.mediaType}. Please configure a provider in settings.`);let s={...n};lc&&!s.onProgress&&(s.onProgress=(c,l,d)=>{lc(d??"pending",n.mediaType,c,l,t)});let o=await Sm(t,r||n.model,s);if(o.ok)return o.result;let i=ke.listMediaModels(n.mediaType),a=[`${t}: ${o.error}`];for(let c of i){if(c.providerId===t||!Ue[c.providerId])continue;let d=await Sm(c.providerId,c.modelInfo.id,n);if(d.ok)return d.result;a.push(`${c.providerId}/${c.modelInfo.id}: ${d.error}`)}throw new Error(`All media providers failed for ${n.mediaType}:
|
|
618
618
|
`+a.map(c=>` - ${c}`).join(`
|
|
619
|
-
`))}async function
|
|
620
|
-
`))if(p.trim())try{let m=JSON.parse(p);m.type==="match"&&m.data&&c.push({path:m.data.path?.text??"",line:m.data.line_number??0,text:(m.data.lines?.text??"").trimEnd()})}catch{}let l=t.headLimit??250,d=t.offset??0,u=c.slice(d,d+l);r({matches:u,truncated:c.length>d+l})})})}async function kw(n,e,t){let r=new RegExp(n,t.caseInsensitive?"i":""),s=t.headLimit??250,o=t.offset??0,i=t.fileGlob?
|
|
621
|
-
`);for(let m=0;m<p.length;m++)if(r.test(p[m])&&(a.push({path:l,line:m+1,text:p[m].slice(0,500)}),a.length>=o+s+1))return c=!0,!1}catch{}return!0},1/0),{matches:a.slice(o,o+s),truncated:c}}var
|
|
622
|
-
`),error:f.details?.error}}catch(f){return{result:"",error:f.message}}},getCwd:()=>rt};e.push(Qp(c)),e.push(Zp({sleep:(u,p)=>new Promise(m=>{let h=Date.now(),f=setTimeout(()=>{m({sleptSeconds:Math.round((Date.now()-h)/1e3),interrupted:!1})},u),y=()=>{clearTimeout(f),m({sleptSeconds:Math.round((Date.now()-h)/1e3),interrupted:!0,interruptReason:"aborted"})};p.addEventListener("abort",y,{once:!0}),p.aborted&&(clearTimeout(f),y())})}));let l={listProjects:()=>me(),switchProject:u=>ut(u),onSwitched:u=>ow?.(u)};e.push(ym(l)),e.push(tm({searchTools:async(u,p)=>{let m=p?.maxResults??5,h=Xt(),f=u.toLowerCase().split(/\s+/).filter(Boolean),y=[],b=[];for(let N of f)N.startsWith("+")&&N.length>1?y.push(N.slice(1)):b.push(N);let k=[...y,...b],A=N=>N.replace(/([a-z])([A-Z])/g,"$1 $2").replace(/_/g," ").toLowerCase().split(/\s+/).filter(Boolean);return{matches:h.map(N=>{let L=tt(N),F=A(N),T=(L?.description??"").toLowerCase(),ce=(L?.searchHint??"").toLowerCase();if(y.length>0){let j=`${F.join(" ")} ${T} ${ce}`;if(!y.every(oe=>j.includes(oe)))return null}let le=0;for(let j of k){let ve=0;F.some(oe=>oe===j)?ve=10:F.some(oe=>oe.includes(j))?ve=5:N.toLowerCase().includes(j)&&(ve=3),ce&&new RegExp(`\\b${j}`,"i").test(ce)&&(ve+=4),new RegExp(`\\b${j}`,"i").test(T)&&(ve+=2),le+=ve}return{name:N,description:L?.description??"",searchHint:L?.searchHint,score:le}}).filter(N=>N!==null&&N.score>0).sort((N,L)=>L.score-N.score).slice(0,m),query:u,totalDeferred:h.length}},activateTool:async u=>zu(u)})),e.push({...nm({generateImage:async u=>{let p=await xt({mediaType:"image",model:"",prompt:u.prompt,purpose:u.purpose,style:u.style,size:u.size,imageUrl:u.imageUrl,n:u.n,quality:u.quality,seed:u.seed});return{mediaUrls:p.mediaUrls,model:p.model,size:p.size,durationMs:p.durationMs}}}),isEnabled:()=>Pt("image")}),e.push({...rm({textToSpeech:async u=>{let p=await xt({mediaType:"tts",model:"",prompt:"",text:u.text,channel:u.channel,voice:u.voice,speed:u.speed});return{audioPath:"",provider:p.model,mediaUrls:p.mediaUrls}}}),isEnabled:()=>Pt("tts")}),e.push({...sm({generateVideo:async u=>{let p=await xt({mediaType:"video",model:"",prompt:u.prompt,purpose:u.purpose,style:u.style,imageUrl:u.imageUrl,referenceVideos:u.referenceVideos,referenceAudios:u.referenceAudios,generateAudio:u.generateAudio,aspectRatio:u.aspectRatio,duration:u.duration,resolution:u.resolution,fps:u.fps,seed:u.seed,cameraFixed:u.cameraFixed,returnLastFrame:u.returnLastFrame,draft:u.draft,serviceTier:u.serviceTier,callbackUrl:u.callbackUrl,safetyIdentifier:u.safetyIdentifier,executionExpiresAfterSeconds:u.executionExpiresAfterSeconds,videoTools:u.videoTools});return{mediaUrls:p.mediaUrls,model:p.model,durationMs:p.durationMs,lastFrameUrl:p.lastFrameUrl,taskId:p.taskId}}}),isEnabled:()=>Pt("video")}),e.push({...om({generateMusic:async u=>{let p=await xt({mediaType:"music",model:"",prompt:u.prompt,purpose:u.purpose,style:u.style,lyrics:u.lyrics,duration:u.duration,isInstrumental:u.isInstrumental,audioUrl:u.audioUrl,audioFormat:u.audioFormat});return{mediaUrls:p.mediaUrls,model:p.model,durationMs:p.durationMs}},generateLyrics:async u=>{let p=Jt.music;if(!p||!ke)return"";let m=ke.getTransport(p.provider);if(!(m instanceof tw))return"";let h=Ue[p.provider];return h?m.generateLyrics(u,h):""}}),isEnabled:()=>Pt("music")}),e.push({...im({editVideo:async u=>{let p=await xt({mediaType:"video",model:"",prompt:u.prompt,operation:"edit",sourceVideos:u.sourceVideos,referenceImages:u.referenceImages,duration:u.duration,aspectRatio:u.aspectRatio,resolution:u.resolution});return{mediaUrls:p.mediaUrls,model:p.model,durationMs:p.durationMs}}}),shouldDefer:!0,isEnabled:()=>ac("video","edit")}),e.push({...am({mergeVideos:async u=>{let p=[`merge ${u.clips.length} clips`];u.transition&&p.push(`transition: ${u.transition}${u.transitionDuration?` (${u.transitionDuration}s)`:""}`),u.subtitles&&p.push(`burn-in subtitles: ${u.subtitles}`),u.bgm&&p.push(`background music: ${u.bgm}${u.bgmVolume!==void 0?` at volume ${u.bgmVolume}`:""}`);let m=await xt({mediaType:"video",model:"",prompt:p.join("; "),operation:"merge",sourceVideos:u.clips.map(h=>h.video),resolution:u.outputResolution,fps:u.outputFps});return{localPath:"",servePath:m.mediaUrls[0]??"",durationSec:(m.durationMs??0)/1e3,clipCount:u.clips.length,mediaUrls:m.mediaUrls}}}),shouldDefer:!0,isEnabled:()=>ac("video","merge")}),e.push({...cm({upscaleVideo:async u=>{let p=["upscale"];u.sharpness&&p.push(`sharpness: ${u.sharpness}`);let m=await xt({mediaType:"video",model:"",prompt:p.join(", "),operation:"upscale",sourceVideos:[u.video],resolution:u.targetResolution??"1080p"});return{localPath:"",servePath:m.mediaUrls[0]??"",resolution:u.targetResolution??"1080p",durationSec:(m.durationMs??0)/1e3,mediaUrls:m.mediaUrls}}}),shouldDefer:!0,isEnabled:()=>ac("video","upscale")}),e.push({...lm({generate3D:async u=>{let p=await xt({mediaType:"3d",model:"",prompt:u.prompt,imageUrl:u.imageUrl,outputFormat:u.outputFormat,seed:u.seed});return{mediaUrls:p.mediaUrls,model:p.model,durationMs:p.durationMs,metadata:p.metadata}}}),shouldDefer:!0,isEnabled:()=>Pt("3d")}),e.push({...dm({speechToText:async u=>{let p=await xt({mediaType:"stt",model:"",prompt:"",audioUrl:u.audioUrl,metadata:u.language?{language:u.language}:void 0});return{transcription:p.metadata?.transcription??"",model:p.model,durationMs:p.durationMs}}}),shouldDefer:!0,isEnabled:()=>Pt("stt")}),e.push({...um({cloneVoice:async u=>{let p=await xt({mediaType:"voice_clone",model:"",prompt:"",text:u.text,audioUrl:u.sampleAudioUrl,speed:u.speed});return{mediaUrls:p.mediaUrls,model:p.model,voiceId:p.metadata?.voiceId,durationMs:p.durationMs}}}),shouldDefer:!0,isEnabled:()=>Pt("voice_clone")}),e.push({...pm({cancelTask:async u=>{let p=u.provider??"doubao";if(!ke)return{ok:!1,message:"Media client not configured."};let m=ke.getTransport(p);if(!m)return{ok:!1,message:`No transport for provider: ${p}`};let h=Ue[p];if(!h)return{ok:!1,message:`No API key for provider: ${p}`};try{return"deleteVideoTask"in m&&typeof m.deleteVideoTask=="function"?(await m.deleteVideoTask(u.taskId,h),{ok:!0,message:"Task cancelled."}):{ok:!1,message:`Provider ${p} does not support task cancellation.`}}catch(f){return{ok:!1,message:f instanceof Error?f.message:String(f)}}}}),shouldDefer:!0,isEnabled:()=>Pt("video")||Pt("3d")});let d=Es();return e.push({...mm({uploadFile:async u=>{if(!d)throw new Error("No file upload provider available. Configure a media provider with Files API support (e.g. Volcengine, Google).");let p=Fe(u.filePath);if(!G.existsSync(p))throw new Error(`File not found: ${p}`);let m=G.statSync(p);if(m.size>100*1024*1024)throw new Error(`File too large (${(m.size/1024/1024).toFixed(1)} MB). Max: 100 MB.`);let h=await G.promises.readFile(p),f=K.basename(p);if(d.type==="gemini"){let I=Cs(),N=Ue.google,L=K.extname(p).toLowerCase(),F=pw[L]??"application/octet-stream",T=await I.uploadFile(Buffer.from(h),N,{mimeType:F,displayName:f});if(T.state==="PROCESSING"){let ce=await I.waitForProcessing(T.name,N);return{fileId:ce.name,url:ce.uri,filename:f,bytes:m.size,provider:"google"}}return{fileId:T.name,url:T.uri,filename:f,bytes:m.size,provider:"google"}}let y=new Blob([h]),b=ke.getTransport(d.id),k=Ue[d.id];if(!(b instanceof fr))throw new Error(`File upload only supported via Volcengine or Google provider. Current: ${d.id}`);let A=await b.uploadFile(y,k,{purpose:u.purpose??"media_reference",filename:f}),_;try{let I=await b.getFile(A.id,k);typeof I.url=="string"&&I.url&&(_=I.url)}catch{}return{fileId:A.id,url:_,filename:f,bytes:m.size,provider:d.id}}}),shouldDefer:!0,isEnabled:()=>!!Es()}),e.push({...gm({queryFile:async u=>{if(!d)throw new Error("No file API provider available.");if(d.type==="gemini"){let f=Cs(),y=Ue.google,b=await f.getFile(u.fileId,y);return{id:b.name,filename:b.displayName??"",bytes:Number(b.sizeBytes??0),status:b.state?.toLowerCase()??"unknown",createdAt:b.createTime,url:b.uri}}let p=ke.getTransport(d.id),m=Ue[d.id];if(!(p instanceof fr))throw new Error("File query only supported via Volcengine or Google provider.");let h=await p.getFile(u.fileId,m);return{id:String(h.id??u.fileId),filename:String(h.filename??""),bytes:Number(h.bytes??0),status:String(h.status??"unknown"),createdAt:h.created_at?String(h.created_at):void 0,url:h.url?String(h.url):void 0}},listFiles:async u=>{if(!d)throw new Error("No file API provider available.");if(d.type==="gemini"){let y=Cs(),b=Ue.google;return(await y.listFiles(b,{pageSize:u.limit??10})).files.map(A=>({id:A.name,filename:A.displayName??"",bytes:Number(A.sizeBytes??0),status:A.state?.toLowerCase()??"unknown",createdAt:A.createTime,url:A.uri}))}let p=ke.getTransport(d.id),m=Ue[d.id];if(!(p instanceof fr))throw new Error("File list only supported via Volcengine or Google provider.");return((await p.listFiles(m,{limit:u.limit??10})).data??[]).map(y=>({id:String(y.id??""),filename:String(y.filename??""),bytes:Number(y.bytes??0),status:String(y.status??"unknown"),createdAt:y.created_at?String(y.created_at):void 0,url:y.url?String(y.url):void 0}))}}),shouldDefer:!0,isEnabled:()=>!!Es()}),e.push({...fm({deleteFile:async u=>{if(!d)throw new Error("No file API provider available.");if(d.type==="gemini"){let h=Cs(),f=Ue.google;await h.deleteFile(u.fileId,f);return}let p=ke.getTransport(d.id),m=Ue[d.id];if(!(p instanceof fr))throw new Error("File delete only supported via Volcengine or Google provider.");await p.deleteFile(u.fileId,m)}}),shouldDefer:!0,isEnabled:()=>!!Es()}),Vu(e),n?.log?.info(`[tool-bootstrap] Registered ${e.length} local tools (${e.filter(u=>u.isEnabled?.()!==!1).length} enabled): ${Xt().join(", ")}`),e}import{spawn as Iw}from"node:child_process";import{createInterface as _w}from"node:readline";var Ms=class{process=null;readline=null;pending=new Map;nextId=1;connected=!1;toolsCache=[];serverName="";serverVersion="";supportsToolsListChanged=!1;onToolsChanged=null;stderrBuffer="";config;constructor(e){this.config=e}async connect(){if(this.connected)return;let e={...process.env,...this.config.env};this.process=Iw(this.config.command,this.config.args??[],{stdio:["pipe","pipe","pipe"],env:e,cwd:this.config.cwd,windowsHide:!0}),this.process.on("error",r=>{this.handleProcessError(r)}),this.process.on("exit",r=>{this.handleProcessExit(r)}),this.process.stderr?.on("data",r=>{this.stderrBuffer+=r.toString(),this.stderrBuffer.length>4096&&(this.stderrBuffer=this.stderrBuffer.slice(-4096))}),this.readline=_w({input:this.process.stdout,crlfDelay:Number.POSITIVE_INFINITY}),this.readline.on("line",r=>this.handleLine(r));let t=await this.sendRequest("initialize",{protocolVersion:"2024-11-05",capabilities:{},clientInfo:{name:"qlogicagent",version:"0.3.0"}},this.config.initTimeoutMs??3e4);this.serverName=t.serverInfo?.name??this.config.name,this.serverVersion=t.serverInfo?.version??"unknown",this.supportsToolsListChanged=t.capabilities?.tools?.listChanged??!1,this.sendNotification("notifications/initialized",{}),this.connected=!0,await this.refreshTools()}async disconnect(){if(this.connected){this.connected=!1;for(let[,e]of this.pending)e.reject(new Error("MCP client disconnecting"));if(this.pending.clear(),this.toolsCache=[],this.readline?.close(),this.readline=null,this.process){this.process.kill("SIGTERM");let e=setTimeout(()=>this.process?.kill("SIGKILL"),5e3);this.process.on("exit",()=>clearTimeout(e)),this.process=null}}}get isConnected(){return this.connected}get info(){return{name:this.serverName,version:this.serverVersion}}async refreshTools(){if(!this.connected)return[];try{let e=await this.sendRequest("tools/list",{});this.toolsCache=e.tools??[]}catch{this.toolsCache=[]}return this.toolsCache}getCachedTools(){return this.toolsCache}async callTool(e,t,r){if(!this.connected)throw new Error(`MCP server ${this.config.name} not connected`);return await this.sendRequest("tools/call",{name:e,arguments:t??{}},12e4,r)}async listResources(){if(!this.connected)return[];try{return(await this.sendRequest("resources/list",{})).resources??[]}catch{return[]}}async readResource(e){if(!this.connected)throw new Error(`MCP server ${this.config.name} not connected`);return(await this.sendRequest("resources/read",{uri:e})).contents??[]}toPortableTools(){let e=Ew(this.config.name);return this.toolsCache.map(t=>({name:`mcp__${e}__${t.name}`,label:`[${this.config.name}] ${t.name}`,description:t.description??`MCP tool from ${this.config.name}`,parameters:t.inputSchema??{type:"object",properties:{}},isConcurrencySafe:!0,isReadOnly:!1,searchHint:`mcp ${this.config.name} ${t.name}`,execute:async(r,s,o)=>this.executeAsTool(t.name,s,o)}))}setOnToolsChanged(e){this.onToolsChanged=e}async executeAsTool(e,t,r){try{let s=await this.callTool(e,t,r);return{content:[{type:"text",text:s.content.filter(a=>a.type==="text"&&a.text).map(a=>a.text).join(`
|
|
619
|
+
`))}async function Sm(n,e,t){let r=ke.getTransport(n);if(!r)return{ok:!1,error:"transport not available"};let s=Ue[n];if(!s)return{ok:!1,error:"no API key"};try{let o={...t,model:e},i=await r.generate(o,s);i.billingUnit||(t.mediaType==="tts"&&t.text?(i.billingUnit="per_character",i.billingQuantity=t.text.length):(t.mediaType==="video"||t.mediaType==="music")&&t.duration?(i.billingUnit="per_second",i.billingQuantity=t.duration):(i.billingUnit="per_call",i.billingQuantity=1));let a=i.model??o.model,c=i.billingUnit??"per_call",l=i.billingQuantity??1;return Am?.(a,c,l),{ok:!0,result:i}}catch(o){return{ok:!1,error:o instanceof Error?o.message:String(o)}}}function Pt(n){if(!ke)return!1;let e=Jt[n];if(!e)return!1;let t=ke.getTransport(e.provider),r=Ue[e.provider];return!!(t&&r)}function ac(n,e){if(!Pt(n))return!1;let t=Jt[n],r=ke.resolveModelById(t.provider,t.model,n);if(!r)return!1;let s=r.modelInfo.mediaCapabilities;return!s||!("operations"in s)||!s.operations?!0:s.operations.includes(e)}function Es(){if(!ke)return;for(let[,e]of Object.entries(Jt)){if(!e)continue;let t=ke.getTransport(e.provider),r=Ue[e.provider];if(t instanceof fr&&r)return{id:e.provider,type:"volcengine"}}if(Ue.google)return{id:"google",type:"gemini"}}var cc;function Cs(){return cc||(cc=new nw({baseUrl:"https://generativelanguage.googleapis.com/v1beta"})),cc}var rt=process.cwd(),uc=!1;function Cm(n){rt=n,uc=!0,xs(n)}function Fe(n){return K.isAbsolute(n)?K.normalize(n):K.resolve(rt,n)}function hr(n){let e=K.resolve(rt)+K.sep,t=K.resolve(n);return process.platform==="win32"?t.toLowerCase().startsWith(e.toLowerCase())||t.toLowerCase()===e.slice(0,-1).toLowerCase():t.startsWith(e)||t===e.slice(0,-1)}function Ht(n){return hr(n)?null:`Blocked: path "${n}" is outside the workspace boundary "${rt}"`}function Tm(n){let e=n.replace(/\\/g,"/");return e.includes("../")||e.includes("..")}var uw=new Set([".png",".jpg",".jpeg",".gif",".webp",".bmp",".svg",".ico"]),Mm=new Set([".exe",".dll",".so",".dylib",".zip",".tar",".gz",".7z",".rar",".wasm",".class"]),pc=new Set,pw={".pdf":"application/pdf",".txt":"text/plain",".html":"text/html",".htm":"text/html",".css":"text/css",".js":"text/javascript",".ts":"text/plain",".json":"application/json",".xml":"application/xml",".csv":"text/csv",".md":"text/markdown",".png":"image/png",".jpg":"image/jpeg",".jpeg":"image/jpeg",".gif":"image/gif",".webp":"image/webp",".bmp":"image/bmp",".svg":"image/svg+xml",".mp3":"audio/mpeg",".wav":"audio/wav",".ogg":"audio/ogg",".flac":"audio/flac",".m4a":"audio/mp4",".aac":"audio/aac",".mp4":"video/mp4",".webm":"video/webm",".avi":"video/x-msvideo",".mov":"video/quicktime",".doc":"application/msword",".docx":"application/vnd.openxmlformats-officedocument.wordprocessingml.document",".xls":"application/vnd.ms-excel",".xlsx":"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",".pptx":"application/vnd.openxmlformats-officedocument.presentationml.presentation"};function mw(){return{resolvePath:Fe,async readFile(n){let e=Fe(n),t=K.extname(e).toLowerCase();if(uc){let s=Ht(e);if(s)throw new Error(s)}else if(Tm(n)&&!hr(e))throw new Error(`Blocked: path traversal "${n}" escapes workspace "${rt}"`);if(e.startsWith("/dev/")||e.startsWith("/proc/")||e.startsWith("/sys/"))throw new Error(`Blocked: reading device/system path ${e}`);if(Mm.has(t))return{type:"binary",mimeType:"application/octet-stream"};if(uw.has(t))return{type:"image",localPath:e,mimeType:t===".png"?"image/png":t===".svg"?"image/svg+xml":t===".gif"?"image/gif":t===".webp"?"image/webp":"image/jpeg"};let r=await G.promises.readFile(e,"utf8");return pc.add(e),{type:"text",text:r}},validatePath(n){let e=Fe(n);if(uc){let t=Ht(e);if(t)return t}else if(Tm(n)&&!hr(e))return`Blocked: path traversal "${n}" escapes workspace "${rt}"`;return e.startsWith("/dev/")||e.startsWith("/proc/")||e.startsWith("/sys/")?`Blocked: reading device/system path ${e}`:mc&&ic(e)?"Blocked: reading sensitive file in group chat mode":null}}}function gw(){return{resolvePath:Fe,validatePath(n){let e=Fe(n),t=Ht(e);return t||(e.startsWith("/dev/")||e.startsWith("/proc/")||e.startsWith("/sys/")?`Blocked: writing to device/system path ${e}`:mc&&ic(e)?"Blocked: writing sensitive file in group chat mode":null)},checkReadBeforeWrite(n){try{G.accessSync(n,G.constants.F_OK)}catch{return null}return pc.has(n)?null:"File already exists but has not been read yet in this session. Read it first with the read tool before overwriting, to avoid unintended data loss. If you intend to completely replace the file, read it first to confirm."},async writeFile(n,e){let t=Fe(n),r=Ht(t);if(r)throw new Error(r);await G.promises.mkdir(K.dirname(t),{recursive:!0}),await G.promises.writeFile(t,e,"utf8"),pc.add(t)}}}function fw(){return{resolvePath:Fe,async readFile(n){let e=Fe(n),t=Ht(e);if(t)throw new Error(t);return G.promises.readFile(e,"utf8")},async writeFile(n,e){let t=Fe(n),r=Ht(t);if(r)throw new Error(r);await G.promises.mkdir(K.dirname(t),{recursive:!0}),await G.promises.writeFile(t,e,"utf8")}}}function hw(){return{resolvePath:Fe,async readFile(n){let e=Fe(n),t=Ht(e);if(t)throw new Error(t);return G.promises.readFile(e,"utf8")},async writeFile(n,e){let t=Fe(n),r=Ht(t);if(r)throw new Error(r);await G.promises.mkdir(K.dirname(t),{recursive:!0}),await G.promises.writeFile(t,e,"utf8")},async deleteFile(n){let e=Fe(n),t=Ht(e);if(t)throw new Error(t);await G.promises.unlink(e)},async fileExists(n){let e=Fe(n);try{return await G.promises.access(e),!0}catch{return!1}}}}function yw(){return{resolvePath:Fe,async glob(n,e){let t=e.cwd||rt,r=e.limit||1e3,s=[],o=!1,i=n.replace(/\\/g,"/").split("/"),a=i.some(d=>d==="**"),c=i[i.length-1]??"*",l=Nm(c);try{await yc(t,async d=>{if(s.length>=r)return o=!0,!1;let u=K.basename(d);return l.test(u)&&s.push(d),!0},a?1/0:1)}catch{}return{files:s,truncated:o}},async grep(n,e){let t=e.cwd||rt;try{return await vw(n,t,e)}catch{return await kw(n,t,e)}}}}function Nm(n){let e=n.replace(/[.+^$|()[\]\\]/g,"\\$&").replace(/\*/g,".*").replace(/\?/g,".");return e=e.replace(/\\\{([^}]+)\\\}/g,(t,r)=>"("+r.replace(/,/g,"|")+")"),new RegExp(`^${e}$`,"i")}var bw=new Set([".git",".svn",".hg","node_modules","__pycache__",".next","dist",".tox",".venv"]);async function yc(n,e,t,r=0,s=""){if(r>t)return;let o;try{o=await G.promises.readdir(n,{withFileTypes:!0})}catch{return}for(let i of o){let a=s?`${s}/${i.name}`:i.name;if(i.isDirectory()){if(bw.has(i.name))continue;await yc(K.join(n,i.name),e,t,r+1,a)}else if(i.isFile()&&!await e(a))return}}function vw(n,e,t){return new Promise((r,s)=>{let o=["--json","--no-heading","--max-columns","500"];t.caseInsensitive&&o.push("-i"),t.contextLines&&o.push("-C",String(t.contextLines)),t.fileGlob&&o.push("-g",t.fileGlob),o.push("--max-count",String(t.headLimit??250)),o.push(n),o.push("."),ZA("rg",o,{cwd:e,maxBuffer:10*1024*1024,timeout:3e4},(i,a)=>{if(i&&!("killed"in i&&i.killed)&&i.code!==1){s(i);return}let c=[];for(let p of a.split(`
|
|
620
|
+
`))if(p.trim())try{let m=JSON.parse(p);m.type==="match"&&m.data&&c.push({path:m.data.path?.text??"",line:m.data.line_number??0,text:(m.data.lines?.text??"").trimEnd()})}catch{}let l=t.headLimit??250,d=t.offset??0,u=c.slice(d,d+l);r({matches:u,truncated:c.length>d+l})})})}async function kw(n,e,t){let r=new RegExp(n,t.caseInsensitive?"i":""),s=t.headLimit??250,o=t.offset??0,i=t.fileGlob?Nm(t.fileGlob):null,a=[],c=!1;return await yc(e,async l=>{if(a.length>=o+s+1)return c=!0,!1;if(i&&!i.test(K.basename(l)))return!0;let d=K.extname(l).toLowerCase();if(Mm.has(d))return!0;try{let p=(await G.promises.readFile(K.join(e,l),"utf8")).split(`
|
|
621
|
+
`);for(let m=0;m<p.length;m++)if(r.test(p[m])&&(a.push({path:l,line:m+1,text:p[m].slice(0,500)}),a.length>=o+s+1))return c=!0,!1}catch{}return!0},1/0),{matches:a.slice(o,o+s),truncated:c}}var Rm=!1;function Sw(){if(!Rm)if(Rm=!0,ln()){let n=process.env.QLOGICAGENT_POWERSHELL_PATH??"powershell.exe";pr(Ka(n))}else if(process.platform==="win32"){let n=Tw();pr(_s(n))}else{let n=process.env.SHELL?.endsWith("bash")?process.env.SHELL:"/bin/bash";pr(_s(n))}}function Tw(){let n=process.env.QLOGICAGENT_BASH_PATH;if(n&&G.existsSync(n))return n;let e=["C:\\Program Files\\Git\\bin\\bash.exe","C:\\Program Files (x86)\\Git\\bin\\bash.exe"],t=process.env.ProgramFiles?K.join(process.env.ProgramFiles,"Git","bin","bash.exe"):null;t&&!e.includes(t)&&e.unshift(t);for(let r of e)if(G.existsSync(r))return r;return"bash"}function Rw(){return{async fetchUrl(n){let e=new AbortController,t=setTimeout(()=>e.abort(),3e4);try{let r=await fetch(n.url,{signal:e.signal,headers:{"User-Agent":"Mozilla/5.0 (compatible; QLogicAgent/1.0)",Accept:"text/html,application/xhtml+xml,text/plain,*/*"},redirect:"follow"});if(!r.ok)return{content:`HTTP ${r.status} ${r.statusText}`};let s=r.headers.get("content-type")??"",o=await r.text();return n.maxChars&&o.length>n.maxChars&&(o=o.slice(0,n.maxChars)),s.includes("html")&&n.extractMode!=="json"&&(o=Aw(o)),{content:o,title:ww(o)}}finally{clearTimeout(t)}}}}function Aw(n){return n.replace(/<script[\s\S]*?<\/script>/gi,"").replace(/<style[\s\S]*?<\/style>/gi,"").replace(/<[^>]+>/g," ").replace(/ /gi," ").replace(/&/gi,"&").replace(/</gi,"<").replace(/>/gi,">").replace(/"/gi,'"').replace(/'/gi,"'").replace(/\s{2,}/g," ").trim()}function ww(n){return n.match(/<title[^>]*>([^<]+)<\/title>/i)?.[1]?.trim()}function xw(){let n=async(e,t)=>{let{getModelRegistry:r}=await Promise.resolve().then(()=>(dt(),Cd)),s=r().getTunable("searxngBaseUrl")??process.env.SEARXNG_BASE_URL?.trim();if(!s)return{query:e,results:[],totalResults:0};let o=t?.maxResults??10,i=new URL("/search",s);i.searchParams.set("q",e),i.searchParams.set("format","json"),i.searchParams.set("pageno","1");let a=new AbortController,c=setTimeout(()=>a.abort(),15e3);try{let l=await fetch(i.toString(),{signal:a.signal,headers:{Accept:"application/json"}});if(!l.ok)return{query:e,results:[]};let d=await l.json(),u=(d.results??[]).slice(0,o).map(p=>({title:p.title??"",url:p.url??"",snippet:p.content??""}));if(t?.allowedDomains?.length){let p=new Set(t.allowedDomains.map(m=>m.toLowerCase()));return{query:e,results:u.filter(m=>{try{return p.has(new URL(m.url).hostname.toLowerCase())}catch{return!1}})}}if(t?.blockedDomains?.length){let p=new Set(t.blockedDomains.map(m=>m.toLowerCase()));return{query:e,results:u.filter(m=>{try{return!p.has(new URL(m.url).hostname.toLowerCase())}catch{return!0}})}}return{query:e,results:u,totalResults:d.number_of_results}}finally{clearTimeout(c)}};return{search:(e,t)=>vm(wm,n)(e,t)}}function Pw(){let n=K.join(process.env.HOME??process.env.USERPROFILE??".",".qlogicagent");function e(s){return K.join(n,"projects",s,".instructions")}function t(s,o){if(!o.endsWith(".md"))throw new Error("Filename must end with .md");if(o.includes(".."))throw new Error("Path traversal not allowed");let i=e(s),a=K.resolve(i,o);if(!a.startsWith(i+K.sep)&&a!==i)throw new Error("Path traversal not allowed");return a}function r(s,o){if(!G.existsSync(s))return[];let i=[];for(let a of G.readdirSync(s,{withFileTypes:!0})){let c=K.join(s,a.name);if(a.isDirectory())i.push(...r(c,o));else if(a.isFile()&&a.name.endsWith(".md")){let l=G.statSync(c);i.push({filename:K.relative(o,c).replace(/\\/g,"/"),path:c,size:l.size,updatedAt:l.mtime.toISOString(),content:G.readFileSync(c,"utf-8")})}}return i}return{list(s){let o=e(s);return r(o,o).map(i=>({filename:i.filename,path:i.path,size:i.size,updatedAt:i.updatedAt}))},read(s,o){try{let i=t(s,o);if(!G.existsSync(i))return null;let a=G.statSync(i),c=G.readFileSync(i,"utf-8");return{filename:o,path:i,size:a.size,updatedAt:a.mtime.toISOString(),content:c}}catch{return null}},write(s,o,i){let a=t(s,o);G.mkdirSync(K.dirname(a),{recursive:!0}),G.writeFileSync(a,i,"utf-8");let c=G.statSync(a);return{filename:o,path:a,size:c.size,updatedAt:c.mtime.toISOString(),content:i}},remove(s,o){try{let i=t(s,o);return G.existsSync(i)?(G.unlinkSync(i),!0):!1}catch{return!1}}}}function Dm(n){n?.workdir&&(rt=n.workdir),Sw(),xs(rt);let e=[];e.push(Yu()),e.push(Ju(void 0,{onTaskCreated:u=>dc?.onTaskCreated?.(u),onTaskCompleted:u=>dc?.onTaskCompleted?.(u)})),e.push(ym({askUser:async u=>Pm?.(u)??null})),e.push(dp({onProgress:n?.onExecProgress,validateCommand:async u=>{let p=/(?:>>?|[12]>)\s*(?:"([^"]+)"|'([^']+)'|(\S+))/g,m;for(;(m=p.exec(u))!==null;){let f=m[1]||m[2]||m[3];if(f){let y=K.isAbsolute(f)?K.normalize(f):K.resolve(rt,f);if(!hr(y))return`Blocked: output redirection to path outside workspace: ${f}`}}let h=[/(?:^|[\s;|&(])(?:"(\/[^"]+)"|'(\/[^']+)'|(\/(?!dev\/null\b)[^\s;|&><)]+))/g,/(?:^|[\s;|&(])(?:"([A-Za-z]:[\\\/][^"]+)"|'([A-Za-z]:[\\\/][^']+)'|([A-Za-z]:[\\\/][^\s;|&><)]+))/g,/(?:^|[\s;|&(])(?:"([^"]*\.\.[\\/][^"]+)"|'([^']*\.\.[\\/][^']+)'|([^\s;|&><)"']*\.\.[\\/][^\s;|&><)]+))/g];for(let f of h){let y;for(;(y=f.exec(u))!==null;){let b=y[1]||y[2]||y[3];if(!b||/^\/[a-zA-Z](?:[- ]|$)/.test(b)||/^\/[a-zA-Z]{1,3}$/.test(b))continue;let k;if(process.platform==="win32"&&/^\/[a-zA-Z]\//.test(b)){let A=b.replace(/^\/([a-zA-Z])\//,(_,I)=>`${I.toUpperCase()}:\\`).replace(/\//g,"\\");k=K.normalize(A)}else k=K.isAbsolute(b)?K.normalize(b):K.resolve(rt,b);if(!hr(k))return`Blocked: command references path outside workspace: ${b}`}}return null},interpretExitCode:(u,p)=>{if(u===127)return"command not found";if(u===126)return"permission denied";if(u===137)return"killed (SIGKILL / OOM)";if(u===143)return"terminated (SIGTERM)";if(u===130)return"interrupted (Ctrl+C)"}}));let t=mw(),r=gw(),s=fw(),o=hw();e.push(mp(t)),e.push(fp(r)),e.push(hp(s)),e.push(Ja(o)),e.push(kp(o)),e.push(vp(yw())),e.push(_p(Rw())),e.push(Ep(xw()));let i=Pw();e.push(Cp(i));let a=n?.log??{info:()=>{},warn:()=>{}};e.push(Mp(Kp({log:a}))),e.push(Yp());let c={invokeTool:async(u,p,m)=>{let h=tt(u);if(!h)return{result:"",error:`Unknown tool: ${u}`};try{let f=await h.execute(`wf_${Date.now()}`,p,m);return{result:f.content.map(b=>b.text??"").join(`
|
|
622
|
+
`),error:f.details?.error}}catch(f){return{result:"",error:f.message}}},getCwd:()=>rt};e.push(Zp(c)),e.push(em({sleep:(u,p)=>new Promise(m=>{let h=Date.now(),f=setTimeout(()=>{m({sleptSeconds:Math.round((Date.now()-h)/1e3),interrupted:!1})},u),y=()=>{clearTimeout(f),m({sleptSeconds:Math.round((Date.now()-h)/1e3),interrupted:!0,interruptReason:"aborted"})};p.addEventListener("abort",y,{once:!0}),p.aborted&&(clearTimeout(f),y())})}));let l={listProjects:()=>me(),switchProject:u=>ut(u),onSwitched:u=>ow?.(u)};e.push(bm(l)),e.push(nm({searchTools:async(u,p)=>{let m=p?.maxResults??5,h=Xt(),f=u.toLowerCase().split(/\s+/).filter(Boolean),y=[],b=[];for(let N of f)N.startsWith("+")&&N.length>1?y.push(N.slice(1)):b.push(N);let k=[...y,...b],A=N=>N.replace(/([a-z])([A-Z])/g,"$1 $2").replace(/_/g," ").toLowerCase().split(/\s+/).filter(Boolean);return{matches:h.map(N=>{let L=tt(N),F=A(N),T=(L?.description??"").toLowerCase(),ce=(L?.searchHint??"").toLowerCase();if(y.length>0){let j=`${F.join(" ")} ${T} ${ce}`;if(!y.every(oe=>j.includes(oe)))return null}let le=0;for(let j of k){let ve=0;F.some(oe=>oe===j)?ve=10:F.some(oe=>oe.includes(j))?ve=5:N.toLowerCase().includes(j)&&(ve=3),ce&&new RegExp(`\\b${j}`,"i").test(ce)&&(ve+=4),new RegExp(`\\b${j}`,"i").test(T)&&(ve+=2),le+=ve}return{name:N,description:L?.description??"",searchHint:L?.searchHint,score:le}}).filter(N=>N!==null&&N.score>0).sort((N,L)=>L.score-N.score).slice(0,m),query:u,totalDeferred:h.length}},activateTool:async u=>Xu(u)})),e.push({...rm({generateImage:async u=>{let p=await xt({mediaType:"image",model:"",prompt:u.prompt,purpose:u.purpose,style:u.style,size:u.size,imageUrl:u.imageUrl,n:u.n,quality:u.quality,seed:u.seed});return{mediaUrls:p.mediaUrls,model:p.model,size:p.size,durationMs:p.durationMs}}}),isEnabled:()=>Pt("image")}),e.push({...sm({textToSpeech:async u=>{let p=await xt({mediaType:"tts",model:"",prompt:"",text:u.text,channel:u.channel,voice:u.voice,speed:u.speed});return{audioPath:"",provider:p.model,mediaUrls:p.mediaUrls}}}),isEnabled:()=>Pt("tts")}),e.push({...om({generateVideo:async u=>{let p=await xt({mediaType:"video",model:"",prompt:u.prompt,purpose:u.purpose,style:u.style,imageUrl:u.imageUrl,referenceVideos:u.referenceVideos,referenceAudios:u.referenceAudios,generateAudio:u.generateAudio,aspectRatio:u.aspectRatio,duration:u.duration,resolution:u.resolution,fps:u.fps,seed:u.seed,cameraFixed:u.cameraFixed,returnLastFrame:u.returnLastFrame,draft:u.draft,serviceTier:u.serviceTier,callbackUrl:u.callbackUrl,safetyIdentifier:u.safetyIdentifier,executionExpiresAfterSeconds:u.executionExpiresAfterSeconds,videoTools:u.videoTools});return{mediaUrls:p.mediaUrls,model:p.model,durationMs:p.durationMs,lastFrameUrl:p.lastFrameUrl,taskId:p.taskId}}}),isEnabled:()=>Pt("video")}),e.push({...im({generateMusic:async u=>{let p=await xt({mediaType:"music",model:"",prompt:u.prompt,purpose:u.purpose,style:u.style,lyrics:u.lyrics,duration:u.duration,isInstrumental:u.isInstrumental,audioUrl:u.audioUrl,audioFormat:u.audioFormat});return{mediaUrls:p.mediaUrls,model:p.model,durationMs:p.durationMs}},generateLyrics:async u=>{let p=Jt.music;if(!p||!ke)return"";let m=ke.getTransport(p.provider);if(!(m instanceof tw))return"";let h=Ue[p.provider];return h?m.generateLyrics(u,h):""}}),isEnabled:()=>Pt("music")}),e.push({...am({editVideo:async u=>{let p=await xt({mediaType:"video",model:"",prompt:u.prompt,operation:"edit",sourceVideos:u.sourceVideos,referenceImages:u.referenceImages,duration:u.duration,aspectRatio:u.aspectRatio,resolution:u.resolution});return{mediaUrls:p.mediaUrls,model:p.model,durationMs:p.durationMs}}}),shouldDefer:!0,isEnabled:()=>ac("video","edit")}),e.push({...cm({mergeVideos:async u=>{let p=[`merge ${u.clips.length} clips`];u.transition&&p.push(`transition: ${u.transition}${u.transitionDuration?` (${u.transitionDuration}s)`:""}`),u.subtitles&&p.push(`burn-in subtitles: ${u.subtitles}`),u.bgm&&p.push(`background music: ${u.bgm}${u.bgmVolume!==void 0?` at volume ${u.bgmVolume}`:""}`);let m=await xt({mediaType:"video",model:"",prompt:p.join("; "),operation:"merge",sourceVideos:u.clips.map(h=>h.video),resolution:u.outputResolution,fps:u.outputFps});return{localPath:"",servePath:m.mediaUrls[0]??"",durationSec:(m.durationMs??0)/1e3,clipCount:u.clips.length,mediaUrls:m.mediaUrls}}}),shouldDefer:!0,isEnabled:()=>ac("video","merge")}),e.push({...lm({upscaleVideo:async u=>{let p=["upscale"];u.sharpness&&p.push(`sharpness: ${u.sharpness}`);let m=await xt({mediaType:"video",model:"",prompt:p.join(", "),operation:"upscale",sourceVideos:[u.video],resolution:u.targetResolution??"1080p"});return{localPath:"",servePath:m.mediaUrls[0]??"",resolution:u.targetResolution??"1080p",durationSec:(m.durationMs??0)/1e3,mediaUrls:m.mediaUrls}}}),shouldDefer:!0,isEnabled:()=>ac("video","upscale")}),e.push({...dm({generate3D:async u=>{let p=await xt({mediaType:"3d",model:"",prompt:u.prompt,imageUrl:u.imageUrl,outputFormat:u.outputFormat,seed:u.seed});return{mediaUrls:p.mediaUrls,model:p.model,durationMs:p.durationMs,metadata:p.metadata}}}),shouldDefer:!0,isEnabled:()=>Pt("3d")}),e.push({...um({speechToText:async u=>{let p=await xt({mediaType:"stt",model:"",prompt:"",audioUrl:u.audioUrl,metadata:u.language?{language:u.language}:void 0});return{transcription:p.metadata?.transcription??"",model:p.model,durationMs:p.durationMs}}}),shouldDefer:!0,isEnabled:()=>Pt("stt")}),e.push({...pm({cloneVoice:async u=>{let p=await xt({mediaType:"voice_clone",model:"",prompt:"",text:u.text,audioUrl:u.sampleAudioUrl,speed:u.speed});return{mediaUrls:p.mediaUrls,model:p.model,voiceId:p.metadata?.voiceId,durationMs:p.durationMs}}}),shouldDefer:!0,isEnabled:()=>Pt("voice_clone")}),e.push({...mm({cancelTask:async u=>{let p=u.provider??"doubao";if(!ke)return{ok:!1,message:"Media client not configured."};let m=ke.getTransport(p);if(!m)return{ok:!1,message:`No transport for provider: ${p}`};let h=Ue[p];if(!h)return{ok:!1,message:`No API key for provider: ${p}`};try{return"deleteVideoTask"in m&&typeof m.deleteVideoTask=="function"?(await m.deleteVideoTask(u.taskId,h),{ok:!0,message:"Task cancelled."}):{ok:!1,message:`Provider ${p} does not support task cancellation.`}}catch(f){return{ok:!1,message:f instanceof Error?f.message:String(f)}}}}),shouldDefer:!0,isEnabled:()=>Pt("video")||Pt("3d")});let d=Es();return e.push({...gm({uploadFile:async u=>{if(!d)throw new Error("No file upload provider available. Configure a media provider with Files API support (e.g. Volcengine, Google).");let p=Fe(u.filePath);if(!G.existsSync(p))throw new Error(`File not found: ${p}`);let m=G.statSync(p);if(m.size>100*1024*1024)throw new Error(`File too large (${(m.size/1024/1024).toFixed(1)} MB). Max: 100 MB.`);let h=await G.promises.readFile(p),f=K.basename(p);if(d.type==="gemini"){let I=Cs(),N=Ue.google,L=K.extname(p).toLowerCase(),F=pw[L]??"application/octet-stream",T=await I.uploadFile(Buffer.from(h),N,{mimeType:F,displayName:f});if(T.state==="PROCESSING"){let ce=await I.waitForProcessing(T.name,N);return{fileId:ce.name,url:ce.uri,filename:f,bytes:m.size,provider:"google"}}return{fileId:T.name,url:T.uri,filename:f,bytes:m.size,provider:"google"}}let y=new Blob([h]),b=ke.getTransport(d.id),k=Ue[d.id];if(!(b instanceof fr))throw new Error(`File upload only supported via Volcengine or Google provider. Current: ${d.id}`);let A=await b.uploadFile(y,k,{purpose:u.purpose??"media_reference",filename:f}),_;try{let I=await b.getFile(A.id,k);typeof I.url=="string"&&I.url&&(_=I.url)}catch{}return{fileId:A.id,url:_,filename:f,bytes:m.size,provider:d.id}}}),shouldDefer:!0,isEnabled:()=>!!Es()}),e.push({...fm({queryFile:async u=>{if(!d)throw new Error("No file API provider available.");if(d.type==="gemini"){let f=Cs(),y=Ue.google,b=await f.getFile(u.fileId,y);return{id:b.name,filename:b.displayName??"",bytes:Number(b.sizeBytes??0),status:b.state?.toLowerCase()??"unknown",createdAt:b.createTime,url:b.uri}}let p=ke.getTransport(d.id),m=Ue[d.id];if(!(p instanceof fr))throw new Error("File query only supported via Volcengine or Google provider.");let h=await p.getFile(u.fileId,m);return{id:String(h.id??u.fileId),filename:String(h.filename??""),bytes:Number(h.bytes??0),status:String(h.status??"unknown"),createdAt:h.created_at?String(h.created_at):void 0,url:h.url?String(h.url):void 0}},listFiles:async u=>{if(!d)throw new Error("No file API provider available.");if(d.type==="gemini"){let y=Cs(),b=Ue.google;return(await y.listFiles(b,{pageSize:u.limit??10})).files.map(A=>({id:A.name,filename:A.displayName??"",bytes:Number(A.sizeBytes??0),status:A.state?.toLowerCase()??"unknown",createdAt:A.createTime,url:A.uri}))}let p=ke.getTransport(d.id),m=Ue[d.id];if(!(p instanceof fr))throw new Error("File list only supported via Volcengine or Google provider.");return((await p.listFiles(m,{limit:u.limit??10})).data??[]).map(y=>({id:String(y.id??""),filename:String(y.filename??""),bytes:Number(y.bytes??0),status:String(y.status??"unknown"),createdAt:y.created_at?String(y.created_at):void 0,url:y.url?String(y.url):void 0}))}}),shouldDefer:!0,isEnabled:()=>!!Es()}),e.push({...hm({deleteFile:async u=>{if(!d)throw new Error("No file API provider available.");if(d.type==="gemini"){let h=Cs(),f=Ue.google;await h.deleteFile(u.fileId,f);return}let p=ke.getTransport(d.id),m=Ue[d.id];if(!(p instanceof fr))throw new Error("File delete only supported via Volcengine or Google provider.");await p.deleteFile(u.fileId,m)}}),shouldDefer:!0,isEnabled:()=>!!Es()}),zu(e),n?.log?.info(`[tool-bootstrap] Registered ${e.length} local tools (${e.filter(u=>u.isEnabled?.()!==!1).length} enabled): ${Xt().join(", ")}`),e}import{spawn as Iw}from"node:child_process";import{createInterface as _w}from"node:readline";var Ms=class{process=null;readline=null;pending=new Map;nextId=1;connected=!1;toolsCache=[];serverName="";serverVersion="";supportsToolsListChanged=!1;onToolsChanged=null;stderrBuffer="";config;constructor(e){this.config=e}async connect(){if(this.connected)return;let e={...process.env,...this.config.env};this.process=Iw(this.config.command,this.config.args??[],{stdio:["pipe","pipe","pipe"],env:e,cwd:this.config.cwd,windowsHide:!0}),this.process.on("error",r=>{this.handleProcessError(r)}),this.process.on("exit",r=>{this.handleProcessExit(r)}),this.process.stderr?.on("data",r=>{this.stderrBuffer+=r.toString(),this.stderrBuffer.length>4096&&(this.stderrBuffer=this.stderrBuffer.slice(-4096))}),this.readline=_w({input:this.process.stdout,crlfDelay:Number.POSITIVE_INFINITY}),this.readline.on("line",r=>this.handleLine(r));let t=await this.sendRequest("initialize",{protocolVersion:"2024-11-05",capabilities:{},clientInfo:{name:"qlogicagent",version:"0.3.0"}},this.config.initTimeoutMs??3e4);this.serverName=t.serverInfo?.name??this.config.name,this.serverVersion=t.serverInfo?.version??"unknown",this.supportsToolsListChanged=t.capabilities?.tools?.listChanged??!1,this.sendNotification("notifications/initialized",{}),this.connected=!0,await this.refreshTools()}async disconnect(){if(this.connected){this.connected=!1;for(let[,e]of this.pending)e.reject(new Error("MCP client disconnecting"));if(this.pending.clear(),this.toolsCache=[],this.readline?.close(),this.readline=null,this.process){this.process.kill("SIGTERM");let e=setTimeout(()=>this.process?.kill("SIGKILL"),5e3);this.process.on("exit",()=>clearTimeout(e)),this.process=null}}}get isConnected(){return this.connected}get info(){return{name:this.serverName,version:this.serverVersion}}async refreshTools(){if(!this.connected)return[];try{let e=await this.sendRequest("tools/list",{});this.toolsCache=e.tools??[]}catch{this.toolsCache=[]}return this.toolsCache}getCachedTools(){return this.toolsCache}async callTool(e,t,r){if(!this.connected)throw new Error(`MCP server ${this.config.name} not connected`);return await this.sendRequest("tools/call",{name:e,arguments:t??{}},12e4,r)}async listResources(){if(!this.connected)return[];try{return(await this.sendRequest("resources/list",{})).resources??[]}catch{return[]}}async readResource(e){if(!this.connected)throw new Error(`MCP server ${this.config.name} not connected`);return(await this.sendRequest("resources/read",{uri:e})).contents??[]}toPortableTools(){let e=Ew(this.config.name);return this.toolsCache.map(t=>({name:`mcp__${e}__${t.name}`,label:`[${this.config.name}] ${t.name}`,description:t.description??`MCP tool from ${this.config.name}`,parameters:t.inputSchema??{type:"object",properties:{}},isConcurrencySafe:!0,isReadOnly:!1,searchHint:`mcp ${this.config.name} ${t.name}`,execute:async(r,s,o)=>this.executeAsTool(t.name,s,o)}))}setOnToolsChanged(e){this.onToolsChanged=e}async executeAsTool(e,t,r){try{let s=await this.callTool(e,t,r);return{content:[{type:"text",text:s.content.filter(a=>a.type==="text"&&a.text).map(a=>a.text).join(`
|
|
623
623
|
`)||"(no text output)"}],...s.isError?{details:{error:"mcp_tool_error"}}:{}}}catch(s){let o=s instanceof Error?s.message:String(s);return{content:[{type:"text",text:`MCP tool error: ${o}`}],details:{error:o}}}}sendRequest(e,t,r=3e4,s){return new Promise((o,i)=>{if(s?.aborted){i(new Error("Aborted"));return}let a=this.nextId++,c={jsonrpc:"2.0",id:a,method:e,params:t},l=setTimeout(()=>{this.pending.delete(a),i(new Error(`MCP request ${e} timed out after ${r}ms`))},r),d=()=>{clearTimeout(l),this.pending.delete(a)};s?.addEventListener("abort",()=>{d(),i(new Error("Aborted"))},{once:!0}),this.pending.set(a,{resolve:u=>{d(),u.error?i(new Error(`MCP error ${u.error.code}: ${u.error.message}`)):o(u.result)},reject:u=>{d(),i(u)}}),this.writeLine(JSON.stringify(c))})}sendNotification(e,t){let r={jsonrpc:"2.0",method:e,params:t};this.writeLine(JSON.stringify(r))}writeLine(e){this.process?.stdin?.writable&&this.process.stdin.write(e+`
|
|
624
624
|
`)}handleLine(e){let t=e.trim();if(!t)return;let r;try{r=JSON.parse(t)}catch{return}if("id"in r&&("result"in r||"error"in r)){let s=r.id,o=this.pending.get(s);o&&o.resolve(r)}else"method"in r&&!("id"in r)&&this.handleNotification(r)}handleNotification(e){e.method==="notifications/tools/list_changed"&&this.refreshTools().then(()=>{this.onToolsChanged?.()}).catch(()=>{})}handleProcessError(e){this.connected=!1;for(let[,t]of this.pending)t.reject(new Error(`MCP process error: ${e.message}`));this.pending.clear()}handleProcessExit(e){this.connected=!1;for(let[,t]of this.pending)t.reject(new Error(`MCP process exited with code ${e}`));this.pending.clear()}};function Ew(n){return n.replace(/[^a-zA-Z0-9_]/g,"_").toLowerCase()}import{randomUUID as Cw}from"node:crypto";var Ns=class{connected=!1;toolsCache=[];serverName="";serverVersion="";sessionId=null;onToolsChanged=null;config;constructor(e){this.config=e}async connect(){if(this.connected)return;let e=await this.sendRequest("initialize",{protocolVersion:"2025-03-26",capabilities:{},clientInfo:{name:"qlogicagent",version:"0.3.0"}},this.config.initTimeoutMs??3e4);this.serverName=e.serverInfo?.name??this.config.name,this.serverVersion=e.serverInfo?.version??"unknown",await this.sendNotification("notifications/initialized",{}),this.connected=!0,await this.refreshTools()}async disconnect(){this.connected=!1,this.toolsCache=[],this.sessionId=null}async callTool(e,t,r){if(!this.connected)throw new Error(`MCP server ${this.config.name} not connected`);return await this.sendRequest("tools/call",{name:e,arguments:t??{}},this.config.toolCallTimeoutMs??12e4,r)}async listResources(){if(!this.connected)return[];try{return(await this.sendRequest("resources/list",{})).resources??[]}catch{return[]}}async readResource(e){if(!this.connected)throw new Error(`MCP server ${this.config.name} not connected`);return(await this.sendRequest("resources/read",{uri:e})).contents??[]}toPortableTools(){return this.toolsCache.map(e=>this.schemaToPortableTool(e))}getCachedTools(){return[...this.toolsCache]}get isConnected(){return this.connected}get info(){return{name:this.serverName,version:this.serverVersion}}setOnToolsChanged(e){this.onToolsChanged=e}async refreshTools(){let e=await this.sendRequest("tools/list",{});this.toolsCache=e.tools??[]}async sendRequest(e,t,r=3e4,s){let o=Cw(),i={jsonrpc:"2.0",id:o,method:e,params:t},a=new AbortController,c=setTimeout(()=>a.abort(),r);s&&s.addEventListener("abort",()=>a.abort(),{once:!0});try{let l={"Content-Type":"application/json",Accept:"application/json, text/event-stream",...this.config.headers};this.sessionId&&(l["Mcp-Session-Id"]=this.sessionId);let d=await fetch(this.config.url,{method:"POST",headers:l,body:JSON.stringify(i),signal:a.signal}),u=d.headers.get("mcp-session-id");if(u&&(this.sessionId=u),!d.ok)throw new Error(`MCP HTTP error ${d.status}: ${d.statusText}`);if((d.headers.get("content-type")??"").includes("text/event-stream"))return await this.parseSSEResponse(d,o);let m=await d.json();if(m.error)throw new Error(`MCP error ${m.error.code}: ${m.error.message}`);return m.result}finally{clearTimeout(c)}}async sendNotification(e,t){let r={jsonrpc:"2.0",method:e,params:t},s={"Content-Type":"application/json",...this.config.headers};this.sessionId&&(s["Mcp-Session-Id"]=this.sessionId),await fetch(this.config.url,{method:"POST",headers:s,body:JSON.stringify(r)}).catch(()=>{})}async parseSSEResponse(e,t){let r=e.body;if(!r)throw new Error("MCP SSE response has no body");let s=r.getReader(),o=new TextDecoder,i="";try{for(;;){let{done:a,value:c}=await s.read();if(a)break;i+=o.decode(c,{stream:!0});let l=i.split(`
|
|
625
625
|
`);i=l.pop()??"";for(let d of l){if(!d.startsWith("data: "))continue;let u=d.slice(6).trim();if(u)try{let p=JSON.parse(u);if("method"in p&&p.method==="notifications/tools/list_changed"){this.onToolsChanged?.();continue}if(p.id===t){if(p.error)throw new Error(`MCP error ${p.error.code}: ${p.error.message}`);return p.result}}catch(p){if(p instanceof Error&&p.message.startsWith("MCP error"))throw p}}}}finally{s.releaseLock()}throw new Error("MCP SSE stream ended without response")}schemaToPortableTool(e){let t=this;return{name:`mcp__${Mw(this.config.name)}__${e.name}`,label:`[${this.config.name}] ${e.name}`,description:e.description??`MCP tool from ${this.config.name}`,parameters:e.inputSchema??{type:"object",properties:{}},isConcurrencySafe:!0,isReadOnly:!1,searchHint:`mcp ${this.config.name} ${e.name}`,execute:async(s,o,i)=>{try{let a=await t.callTool(e.name,o,i);return{content:[{type:"text",text:(a.content??[]).filter(d=>d.type==="text"&&d.text).map(d=>d.text).join(`
|
|
626
|
-
`)||"(no output)"}],details:a.isError?{type:"mcp",error:"tool_error"}:{type:"mcp"}}}catch(a){let c=a instanceof Error?a.message:String(a);return{content:[{type:"text",text:`MCP tool error: ${c}`}],details:{type:"mcp",error:c}}}}}}};function Mw(n){return n.replace(/[^a-zA-Z0-9_]/g,"_").toLowerCase()}var Ds=class{clients=new Map;injected=!1;log;constructor(e){this.log=e.log??{info:()=>{},warn:()=>{}};for(let t of e.servers){if(t.disabled)continue;if((t.type??(t.url?"http":"stdio"))==="http"){if(!t.url){this.log.warn(`[mcp] server "${t.name}" is type "http" but has no url, skipping`);continue}let s={name:t.name,url:t.url,headers:t.headers,initTimeoutMs:t.initTimeoutMs};this.clients.set(t.name,new Ns(s))}else{if(!t.command){this.log.warn(`[mcp] server "${t.name}" is type "stdio" but has no command, skipping`);continue}let s={name:t.name,command:t.command,args:t.args,env:t.env,initTimeoutMs:t.initTimeoutMs};this.clients.set(t.name,new Ms(s))}}}async connectAll(){let e=Array.from(this.clients.entries()).map(async([t,r])=>{try{await r.connect(),this.log.info(`[mcp] connected to ${t} (${r.info.name} v${r.info.version})`),r.setOnToolsChanged(()=>{this.log.info(`[mcp] tools changed on ${t}, re-injecting`),this.injected&&this.reinjectTools(t,r)})}catch(s){this.log.warn(`[mcp] failed to connect to ${t}: ${s instanceof Error?s.message:s}`)}});await Promise.allSettled(e)}injectTools(){this.injected=!0;for(let[e,t]of this.clients){if(!t.isConnected)continue;let r=t.toPortableTools();_a(r),this.log.info(`[mcp] injected ${r.length} tools from ${e}`)}}getConnectedServers(){return Array.from(this.clients.entries()).filter(([,e])=>e.isConnected).map(([e])=>e)}getToolCount(){let e=0;for(let t of this.clients.values())t.isConnected&&(e+=t.getCachedTools().length);return e}async disconnectAll(){let e=Array.from(this.clients.values()).map(async t=>{try{await t.disconnect()}catch{}});await Promise.allSettled(e),this.clients.clear(),this.injected=!1}async listResources(e){let t=e?[[e,this.clients.get(e)]].filter(([,s])=>s):Array.from(this.clients.entries());return(await Promise.all(t.map(async([s,o])=>{if(!o?.isConnected||!o.listResources)return[];try{return(await o.listResources()).map(a=>({...a,server:s}))}catch{return this.log.warn(`[mcp] failed to list resources from ${s}`),[]}}))).flat()}async readResource(e,t){let r=this.clients.get(e);if(!r?.isConnected)throw new Error(`MCP server "${e}" is not connected`);if(!r.readResource)throw new Error(`MCP server "${e}" does not support resources`);return r.readResource(t)}reinjectTools(e,t){if(!this.injected)return;let r=`mcp__${e.replace(/[^a-zA-Z0-9_]/g,"_").toLowerCase()}__`;for(let o of Xt())o.startsWith(r)&&ks(o);let s=t.toPortableTools();_a(s),this.log.info(`[mcp] re-injected ${s.length} tools from ${e}`)}};function bc(n){if(!n||typeof n!="object")return[];let e=n,t=[],r=e.mcpServers??e.servers??e;for(let[s,o]of Object.entries(r)){if(!o||typeof o!="object")continue;let i=o;if(typeof i.url=="string"){t.push({name:s,type:"http",url:i.url,headers:i.headers&&typeof i.headers=="object"?i.headers:void 0,disabled:i.disabled===!0,initTimeoutMs:typeof i.initTimeoutMs=="number"?i.initTimeoutMs:void 0});continue}typeof i.command=="string"&&t.push({name:s,type:"stdio",command:i.command,args:Array.isArray(i.args)?i.args:void 0,env:i.env&&typeof i.env=="object"?i.env:void 0,disabled:i.disabled===!0})}return t}var Nw={type:"object",properties:{server:{type:"string",description:"MCP server name to list resources from. Omit to list from all connected servers."}}};function
|
|
627
|
-
`).trim()}],details:{type:"list_mcp_resources",count:s.length}}}}}var Dw={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
|
|
626
|
+
`)||"(no output)"}],details:a.isError?{type:"mcp",error:"tool_error"}:{type:"mcp"}}}catch(a){let c=a instanceof Error?a.message:String(a);return{content:[{type:"text",text:`MCP tool error: ${c}`}],details:{type:"mcp",error:c}}}}}}};function Mw(n){return n.replace(/[^a-zA-Z0-9_]/g,"_").toLowerCase()}var Ds=class{clients=new Map;injected=!1;log;constructor(e){this.log=e.log??{info:()=>{},warn:()=>{}};for(let t of e.servers){if(t.disabled)continue;if((t.type??(t.url?"http":"stdio"))==="http"){if(!t.url){this.log.warn(`[mcp] server "${t.name}" is type "http" but has no url, skipping`);continue}let s={name:t.name,url:t.url,headers:t.headers,initTimeoutMs:t.initTimeoutMs};this.clients.set(t.name,new Ns(s))}else{if(!t.command){this.log.warn(`[mcp] server "${t.name}" is type "stdio" but has no command, skipping`);continue}let s={name:t.name,command:t.command,args:t.args,env:t.env,initTimeoutMs:t.initTimeoutMs};this.clients.set(t.name,new Ms(s))}}}async connectAll(){let e=Array.from(this.clients.entries()).map(async([t,r])=>{try{await r.connect(),this.log.info(`[mcp] connected to ${t} (${r.info.name} v${r.info.version})`),r.setOnToolsChanged(()=>{this.log.info(`[mcp] tools changed on ${t}, re-injecting`),this.injected&&this.reinjectTools(t,r)})}catch(s){this.log.warn(`[mcp] failed to connect to ${t}: ${s instanceof Error?s.message:s}`)}});await Promise.allSettled(e)}injectTools(){this.injected=!0;for(let[e,t]of this.clients){if(!t.isConnected)continue;let r=t.toPortableTools();_a(r),this.log.info(`[mcp] injected ${r.length} tools from ${e}`)}}getConnectedServers(){return Array.from(this.clients.entries()).filter(([,e])=>e.isConnected).map(([e])=>e)}getToolCount(){let e=0;for(let t of this.clients.values())t.isConnected&&(e+=t.getCachedTools().length);return e}async disconnectAll(){let e=Array.from(this.clients.values()).map(async t=>{try{await t.disconnect()}catch{}});await Promise.allSettled(e),this.clients.clear(),this.injected=!1}async listResources(e){let t=e?[[e,this.clients.get(e)]].filter(([,s])=>s):Array.from(this.clients.entries());return(await Promise.all(t.map(async([s,o])=>{if(!o?.isConnected||!o.listResources)return[];try{return(await o.listResources()).map(a=>({...a,server:s}))}catch{return this.log.warn(`[mcp] failed to list resources from ${s}`),[]}}))).flat()}async readResource(e,t){let r=this.clients.get(e);if(!r?.isConnected)throw new Error(`MCP server "${e}" is not connected`);if(!r.readResource)throw new Error(`MCP server "${e}" does not support resources`);return r.readResource(t)}reinjectTools(e,t){if(!this.injected)return;let r=`mcp__${e.replace(/[^a-zA-Z0-9_]/g,"_").toLowerCase()}__`;for(let o of Xt())o.startsWith(r)&&ks(o);let s=t.toPortableTools();_a(s),this.log.info(`[mcp] re-injected ${s.length} tools from ${e}`)}};function bc(n){if(!n||typeof n!="object")return[];let e=n,t=[],r=e.mcpServers??e.servers??e;for(let[s,o]of Object.entries(r)){if(!o||typeof o!="object")continue;let i=o;if(typeof i.url=="string"){t.push({name:s,type:"http",url:i.url,headers:i.headers&&typeof i.headers=="object"?i.headers:void 0,disabled:i.disabled===!0,initTimeoutMs:typeof i.initTimeoutMs=="number"?i.initTimeoutMs:void 0});continue}typeof i.command=="string"&&t.push({name:s,type:"stdio",command:i.command,args:Array.isArray(i.args)?i.args:void 0,env:i.env&&typeof i.env=="object"?i.env:void 0,disabled:i.disabled===!0})}return t}var Nw={type:"object",properties:{server:{type:"string",description:"MCP server name to list resources from. Omit to list from all connected servers."}}};function Om(n){return{name:"list_mcp_resources",label:"List MCP Resources",description:"List resources available from connected MCP servers. Resources are data items (files, database records, API data) exposed by MCP servers that can be read with read_mcp_resource.",parameters:Nw,shouldDefer:!0,isConcurrencySafe:!0,isReadOnly:!0,searchHint:"mcp resource list browse discover",execute:async(e,t)=>{let r=n();if(!r)return{content:[{type:"text",text:"No MCP servers configured."}],details:{type:"list_mcp_resources",count:0}};let s=await r.listResources(t.server);if(s.length===0)return{content:[{type:"text",text:t.server?`No resources found from MCP server "${t.server}".`:"No resources found from any connected MCP server."}],details:{type:"list_mcp_resources",count:0}};let o=new Map;for(let a of s){let c=o.get(a.server)??[];c.push(a),o.set(a.server,c)}let i=[];for(let[a,c]of o){i.push(`Server: ${a} (${c.length} resources)`);for(let l of c){let d=l.mimeType?` [${l.mimeType}]`:"",u=l.description?` \u2014 ${l.description}`:"";i.push(` ${l.name}: ${l.uri}${d}${u}`)}i.push("")}return{content:[{type:"text",text:i.join(`
|
|
627
|
+
`).trim()}],details:{type:"list_mcp_resources",count:s.length}}}}}var Dw={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 Lm(n){return{name:"read_mcp_resource",label:"Read MCP Resource",description:"Read a specific resource from an MCP server by URI. Returns the resource content (text or binary metadata). Use list_mcp_resources first to discover available URIs.",parameters:Dw,shouldDefer:!0,isConcurrencySafe:!0,isReadOnly:!0,searchHint:"mcp resource read fetch content",execute:async(e,t)=>{let r=n();if(!r)return{content:[{type:"text",text:"No MCP servers configured."}],details:{error:"no_mcp"}};try{let s=await r.readResource(t.server,t.uri);if(s.length===0)return{content:[{type:"text",text:`Resource "${t.uri}" returned no content.`}],details:{type:"read_mcp_resource",empty:!0}};let o=[];for(let i of s)if(i.text){let a=i.mimeType?` (${i.mimeType})`:"";o.push({type:"text",text:`--- ${i.uri}${a}-
|
|
628
628
|
${i.text}`})}else if(i.blob){let a=Math.ceil(i.blob.length*3/4/1024);o.push({type:"text",text:`--- ${i.uri} (binary, ~${a}KB, ${i.mimeType??"unknown"})-
|
|
629
|
-
[Binary content not displayed. Use appropriate tool to process.]`})}return o.length===0?{content:[{type:"text",text:`Resource "${t.uri}" has no readable content.`}],details:{type:"read_mcp_resource",empty:!0}}:{content:o,details:{type:"read_mcp_resource",uri:t.uri,server:t.server,contentCount:s.length}}}catch(s){return{content:[{type:"text",text:`Error reading resource: ${s.message}`}],details:{error:s.message}}}}}}import*as It from"node:fs";import*as yr from"node:path";import{pathToFileURL as Ow}from"node:url";var
|
|
630
|
-
`).pop()?.trim();if(!l)return t.warn(`[marketplace] npm pack returned no output for ${a}`),null;let d=br.join(i,l),p=l.match(/^(.+)-(\d+\.\d+\.\d+.*)\.tgz$/)?.[2]??"0.0.0",m=br.join(i,`${n}@${p}`);Ne.existsSync(m)||Ne.mkdirSync(m,{recursive:!0}),await o("tar",["xzf",d,"-C",m,"--strip-components=1"],{timeout:3e4});try{Ne.unlinkSync(d)}catch{}let h=br.join(m,"package.json");if(Ne.existsSync(h))try{await o("npm",["install","--production","--no-save"],{cwd:m,timeout:12e4})}catch(f){t.warn(`[marketplace] npm install for ${n} failed: ${f.message}`)}return t.info(`[marketplace] installed ${n}@${p} from npm`),{name:n,version:p,installPath:m}}catch(c){return t.warn(`[marketplace] failed to install ${a} from npm: ${c.message}`),null}}function Uw(){return
|
|
629
|
+
[Binary content not displayed. Use appropriate tool to process.]`})}return o.length===0?{content:[{type:"text",text:`Resource "${t.uri}" has no readable content.`}],details:{type:"read_mcp_resource",empty:!0}}:{content:o,details:{type:"read_mcp_resource",uri:t.uri,server:t.server,contentCount:s.length}}}catch(s){return{content:[{type:"text",text:`Error reading resource: ${s.message}`}],details:{error:s.message}}}}}}import*as It from"node:fs";import*as yr from"node:path";import{pathToFileURL as Ow}from"node:url";var $m={preToolUse:"tool.before_invoke",postToolUse:"tool.after_invoke",onTurnStart:"turn.submitted",onTurnEnd:"turn.completed",onSessionEnd:"session.ended"};var Os=class{constructor(e){this.config=e;this.log=e.log??{info:()=>{},warn:()=>{}}}config;loaded=[];pluginSkills=[];activations=new Map;log;async loadAll(){for(let e of this.config.pluginDirs){if(!It.existsSync(e))continue;let t;try{t=It.readdirSync(e,{withFileTypes:!0})}catch{continue}for(let r of t){if(!r.isDirectory()||r.name.startsWith(".")||r.name.startsWith("_"))continue;let s=yr.join(e,r.name);await this.loadPlugin(r.name,s)}}return this.log.info(`[plugins] loaded ${this.loaded.length} plugin(s): ${this.loaded.map(e=>e.name).join(", ")||"(none)"}`),this.loaded}getPluginSkills(){return this.pluginSkills}getLoaded(){return this.loaded}async discoverNew(){let e=new Set(this.loaded.map(r=>r.name)),t=0;for(let r of this.config.pluginDirs){if(!It.existsSync(r))continue;let s;try{s=It.readdirSync(r,{withFileTypes:!0})}catch{continue}for(let o of s){if(!o.isDirectory()||o.name.startsWith(".")||o.name.startsWith("_")||e.has(o.name))continue;let i=yr.join(r,o.name);await this.loadPlugin(o.name,i),t++}}return t>0&&this.log.info(`[plugins] discovered ${t} new plugin(s)`),t}async refreshActivations(){let e=Date.now();for(let[t,r]of this.activations){if(e-r.lastCheckAt<r.ttlMs)continue;let s;try{s=await r.checkFn()}catch(o){this.log.warn(`[plugins] ${t}: check_fn error: ${o instanceof Error?o.message:o}`),s=r.lastResult}if(r.lastCheckAt=e,s!==r.lastResult){if(r.lastResult=s,s&&!r.active){for(let o of r.tools)Pe(o);r.active=!0,this.log.info(`[plugins] ${t}: reactivated (${r.tools.length} tools)`)}else if(!s&&r.active){for(let o of r.tools)ks(o.name);for(let o of r.hookUnregisterFns)o();r.active=!1,this.log.info(`[plugins] ${t}: deactivated`)}}}}async loadPlugin(e,t){let r=["index.js","index.mjs"],s=null;for(let f of r){let y=yr.join(t,f);if(It.existsSync(y)){s=y;break}}if(!s){this.log.warn(`[plugins] ${e}: no index.js found, skipping`);return}let o=0,i=0,a=0,c=[],l=[],d=null,u=6e4,p={},m=yr.join(t,"config.json");if(It.existsSync(m))try{p=JSON.parse(It.readFileSync(m,"utf8"))}catch{}let h={pluginName:e,registerTool:f=>{Pe(f),c.push(f),o++},registerHook:(f,y)=>{let b=$m[f];if(!b){this.log.warn(`[plugins] ${e}: unknown hook phase "${f}"`);return}let k=this.config.hookRegistry.register({point:b,handler:y,label:`plugin:${e}:${f}`,priority:200});l.push(k),i++},registerSkill:f=>{this.pluginSkills.push(f),a++},getConfig:()=>p,setActivationCheck:(f,y)=>{d=f,y!==void 0&&(u=y)}};try{let y=await import(Ow(s).href);if(typeof y.register!="function"){this.log.warn(`[plugins] ${e}: no register() export, skipping`);return}await y.register(h),d&&this.activations.set(e,{checkFn:d,ttlMs:u,lastCheckAt:Date.now(),lastResult:!0,tools:c,hookUnregisterFns:l,active:!0}),this.loaded.push({name:e,directory:t,toolCount:o,hookCount:i,skillCount:a}),this.log.info(`[plugins] ${e}: ${o} tools, ${i} hooks, ${a} skills`)}catch(f){this.log.warn(`[plugins] ${e}: load error: ${f instanceof Error?f.message:f}`)}}};ae();import*as Ne from"node:fs";import*as br from"node:path";function vc(){return kd()}function jm(){return br.join(vc(),"installed_plugins.json")}function Um(){let n=jm();if(!Ne.existsSync(n))return{version:1,plugins:[]};try{return JSON.parse(Ne.readFileSync(n,"utf-8"))}catch{return{version:1,plugins:[]}}}function Lw(n){let e=vc();Ne.existsSync(e)||Ne.mkdirSync(e,{recursive:!0}),Ne.writeFileSync(jm(),JSON.stringify(n,null,2),"utf-8")}function $w(n,e){return!(e.blocklist?.includes(n)||e.allowlist&&!e.allowlist.includes(n))}async function jw(n,e,t){let{execFile:r}=await import("node:child_process"),{promisify:s}=await import("node:util"),o=s(r),i=vc(),a=e?`${n}@${e}`:n;try{let{stdout:c}=await o("npm",["pack",a,"--pack-destination",i],{timeout:6e4,cwd:i}),l=c.trim().split(`
|
|
630
|
+
`).pop()?.trim();if(!l)return t.warn(`[marketplace] npm pack returned no output for ${a}`),null;let d=br.join(i,l),p=l.match(/^(.+)-(\d+\.\d+\.\d+.*)\.tgz$/)?.[2]??"0.0.0",m=br.join(i,`${n}@${p}`);Ne.existsSync(m)||Ne.mkdirSync(m,{recursive:!0}),await o("tar",["xzf",d,"-C",m,"--strip-components=1"],{timeout:3e4});try{Ne.unlinkSync(d)}catch{}let h=br.join(m,"package.json");if(Ne.existsSync(h))try{await o("npm",["install","--production","--no-save"],{cwd:m,timeout:12e4})}catch(f){t.warn(`[marketplace] npm install for ${n} failed: ${f.message}`)}return t.info(`[marketplace] installed ${n}@${p} from npm`),{name:n,version:p,installPath:m}}catch(c){return t.warn(`[marketplace] failed to install ${a} from npm: ${c.message}`),null}}function Uw(){return Um().plugins.filter(e=>Ne.existsSync(e.installPath)).map(e=>e.installPath)}async function Fw(n,e){let t=Um(),r=[];for(let s of n.enabledPlugins){let o=s.specifier.split("/").pop()??s.specifier;if(!$w(o,n)){e.warn(`[marketplace] plugin "${o}" blocked by enterprise policy`);continue}let i=t.plugins.find(c=>c.source.specifier===s.specifier&&c.source.type===s.type);if(i&&Ne.existsSync(i.installPath)&&(!s.version||i.version===s.version)){r.push(i.installPath);continue}let a=null;switch(s.type){case"npm":a=await jw(s.specifier,s.version,e);break;case"git":case"url":e.warn(`[marketplace] ${s.type} source not yet implemented for "${s.specifier}"`);break}if(a){let c={name:a.name,version:a.version,source:s,installPath:a.installPath,installedAt:new Date().toISOString()};t.plugins=t.plugins.filter(l=>!(l.source.specifier===s.specifier&&l.source.type===s.type)),t.plugins.push(c),r.push(a.installPath)}}return Lw(t),r}function Bw(){let n=Td();if(!Ne.existsSync(n))return null;try{return JSON.parse(Ne.readFileSync(n,"utf-8"))}catch{return null}}async function Fm(n,e){let t=[...n],r=Uw();t.push(...r);let s=Bw();if(s&&s.enabledPlugins.length>0)try{let o=await Fw(s,e),i=new Set(t);for(let a of o)i.has(a)||t.push(a)}catch(o){e.warn(`[marketplace] failed to update plugins: ${o.message}`)}return t}var Ls=class{mode;rules;defaultBehavior;compiledPatterns;constructor(e){this.mode=e.mode,this.rules=[...e.rules],this.defaultBehavior=e.defaultBehavior,this.compiledPatterns=this.compileRules(this.rules)}getMode(){return this.mode}setMode(e){this.mode=e}getRules(){return this.rules}getDefaultBehavior(){return this.defaultBehavior}replaceRules(e){this.rules=[...e],this.compiledPatterns=this.compileRules(this.rules)}setDefaultBehavior(e){this.defaultBehavior=e}addRule(e){this.rules.push(e),this.compiledPatterns=this.compileRules(this.rules)}applyUpdate(e){this.addRule({pattern:e.pattern,behavior:e.behavior,reason:e.description,source:"user"})}check(e){let{toolName:t,meta:r}=e;switch(this.mode){case"bypassPermissions":return{behavior:"allow",decisionReason:{type:"mode",mode:"bypassPermissions"}};case"dontAsk":return r?.isReadOnly?{behavior:"allow",decisionReason:{type:"mode",mode:"dontAsk"}}:{behavior:"deny",message:`Tool "${t}" denied \u2014 mode is dontAsk`,decisionReason:{type:"mode",mode:"dontAsk"}};case"plan":return{behavior:"deny",message:`Tool "${t}" paused \u2014 mode is plan (execution suspended)`,decisionReason:{type:"mode",mode:"plan"}}}for(let{rule:s,regex:o}of this.compiledPatterns)if(o.test(t))return qw(s,e);return r?.isReadOnly?{behavior:"allow",decisionReason:{type:"tool_check",reason:"isReadOnly"}}:r?.requiresApproval?{behavior:"ask",message:`Tool "${t}" requires approval`,toolName:t,input:e.arguments,decisionReason:{type:"tool_check",reason:"requiresApproval"}}:this.mode==="acceptEdits"?{behavior:"allow",decisionReason:{type:"mode",mode:"acceptEdits"}}:r?.isDangerous?{behavior:"ask",message:`Tool "${t}" is marked dangerous`,toolName:t,input:e.arguments,decisionReason:{type:"tool_check",reason:"isDangerous"}}:this.defaultBehavior==="allow"?{behavior:"allow"}:this.defaultBehavior==="deny"?{behavior:"deny",message:`Tool "${t}" denied by default policy`,decisionReason:{type:"other",reason:"default_deny"}}:{behavior:"ask",message:`Tool "${t}" requires approval (default policy)`,toolName:t,input:e.arguments}}compileRules(e){return e.map(t=>({rule:t,regex:Hw(t.pattern)}))}};function $s(n){if(!n||typeof n!="object")return{mode:"default",rules:[],defaultBehavior:"allow"};let e=n,t=[];for(let a of["allow","deny","ask"]){let c=e[a];if(Array.isArray(c))for(let l of c)typeof l=="string"&&t.push({pattern:l,behavior:a,source:"config"})}if(Array.isArray(e.rules)){for(let a of e.rules)if(a&&typeof a=="object"){let c=a,l=c.pattern,d=c.behavior??c.action;typeof l=="string"&&typeof d=="string"&&(d==="allow"||d==="deny"||d==="ask")&&t.push({pattern:l,behavior:d,reason:typeof c.reason=="string"?c.reason:void 0,source:typeof c.source=="string"?c.source:"config"})}}let r=e.mode,s=typeof r=="string"&&Ww(r)?r:"default",o=e.default??e.defaultBehavior,i=typeof o=="string"&&Gw(o)?o:"allow";return{mode:s,rules:t,defaultBehavior:i}}function Hw(n){let t=n.replace(/[.+^${}()|[\]\\]/g,"\\$&").replace(/\*+/g,".*");return new RegExp(`^${t}$`,"i")}function qw(n,e){let t={type:"rule",rule:n};return n.behavior==="allow"?{behavior:"allow",decisionReason:t}:n.behavior==="deny"?{behavior:"deny",message:n.reason??`Tool "${e.toolName}" denied by rule "${n.pattern}"`,decisionReason:t}:{behavior:"ask",message:n.reason??`Tool "${e.toolName}" requires approval (rule "${n.pattern}")`,toolName:e.toolName,input:e.arguments,decisionReason:t}}function Ww(n){return n==="default"||n==="bypassPermissions"||n==="acceptEdits"||n==="dontAsk"||n==="plan"}function Gw(n){return n==="allow"||n==="deny"||n==="ask"}import{randomUUID as nx}from"node:crypto";var Kw=new Set(["nodeversion","npmversion","npxversion","pnpmversion","yarnversion","bunversion","denoversion","pythonversion","python3version","pipversion","rubyversion","go version","rustcversion","cargoversion","java -version","javac -version","dotnetversion","gccversion","g++version","clangversion","gitversion","dockerversion","--help","-h"]),Bm=new Set(["ls","dir","find","fd","locate","which","where","type","cat","head","tail","less","more","bat","wc","file","stat","du","df","tree","exa","eza","grep","rg","ripgrep","ag","ack","fgrep","egrep","git status","git log","git diff","git show","git branch","git tag","git remote","git stash list","git blame","git shortlog","git describe","git rev-parse","git ls-files","git ls-tree","git cat-file","git reflog","ps","top","htop","uptime","uname","hostname","whoami","id","env","printenv","echo","ping","nslookup","dig","host","ifconfig","ip","netstat","ss","npm list","npm ls","npm info","npm view","npm outdated","npm audit","pnpm list","pnpm ls","pnpm outdated","pip list","pip show","pip freeze","cargo tree","npm test","npm run test","npm run build","npm run lint","pnpm test","pnpm run test","pnpm run build","pnpm run lint","yarn test","yarn build","yarn lint","cargo test","cargo build","cargo check","cargo clippy","go test","go build","go vet","make","cmake","pytest","python -m pytest","python3 -m pytest","jest","vitest","mocha","tsc","tscnoEmit","eslint","prettier","oxlint"]),Vw=[/\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],Hm=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 qm(n,e,t){let r=n.trim();if(!r)return{decision:"allow",reason:"empty command"};let s=Va(r)??za(r)??void 0;for(let l of Vw)if(l.test(r))return{decision:"deny",reason:`matches dangerous pattern: ${l.source}`,destructiveWarning:s};for(let l of Kw)if(r===l||r.startsWith(l+" "))return{decision:"allow",reason:`known safe command: ${l}`,destructiveWarning:s};let o=r.split(/\s+/),i=o[0],a=o.length>1?`${o[0]} ${o[1]}`:i;return Bm.has(i)||Bm.has(a)?{decision:"allow",reason:`known safe command: ${i}`,destructiveWarning:s}:e&&t&&e.startsWith(t)&&(Hm.has(i)||Hm.has(a))?{decision:"allow",reason:`safe in project: ${a}`,destructiveWarning:s}:{decision:"defer",reason:"unknown command \u2014 needs LLM classification",destructiveWarning:s}}function zw(n){let e=Object.keys(n).sort(),t={};for(let r of e){let s=n[r];typeof s=="string"?t[r]=s.replace(/\s+/g," ").trim():t[r]=s}return JSON.stringify(t)}function kc(n,e){return`${n}::${zw(e)}`}var Xw=500,js=class{cache=new Map;get(e,t){let r=kc(e,t),s=this.cache.get(r);if(s)return s.hitCount++,s}set(e,t,r){if(this.cache.size>=Xw){let o=this.cache.keys().next().value;o!==void 0&&this.cache.delete(o)}let s=kc(e,t);this.cache.set(s,{shouldBlock:r.shouldBlock,reason:r.reason,classifiedAt:Date.now(),hitCount:0})}has(e,t){return this.cache.has(kc(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 Yw=new Set(["read","search","instructions","think","task","memory","skill","tool_search","plan_mode","lsp","brief","web_search","checkpoint"]);function vr(n){return Yw.has(n)}var Wm=`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.
|
|
631
631
|
|
|
632
632
|
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).
|
|
633
633
|
|
|
@@ -657,7 +657,7 @@ ${o}
|
|
|
657
657
|
${i}
|
|
658
658
|
</action>
|
|
659
659
|
|
|
660
|
-
Should this action be blocked? Respond with <block>yes</block> or <block>no</block>. If blocking, add <reason>explanation</reason>.`;try{let c=await r({system:
|
|
660
|
+
Should this action be blocked? Respond with <block>yes</block> or <block>no</block>. If blocking, add <reason>explanation</reason>.`;try{let c=await r({system:Wm,messages:[{role:"user",content:a}],maxTokens:64,temperature:0,stop:["</reason>"],cacheSystemPrompt:!0}),l=Vm(c.text);if(Gm(l)===!1)return{shouldBlock:!1,reason:"classifier: safe",stage:"fast",durationMs:Date.now()-s};let u=`<transcript>
|
|
661
661
|
${o}
|
|
662
662
|
</transcript>
|
|
663
663
|
|
|
@@ -665,11 +665,11 @@ ${o}
|
|
|
665
665
|
${i}
|
|
666
666
|
</action>
|
|
667
667
|
|
|
668
|
-
The fast classifier flagged this action. Review carefullyis it actually dangerous, or is it safe development work? Consider the project context. Use <thinking> tags to reason, then respond with <block>yes</block> or <block>no</block> and <reason>explanation</reason>.`,p=await r({system:
|
|
668
|
+
The fast classifier flagged this action. Review carefullyis it actually dangerous, or is it safe development work? Consider the project context. Use <thinking> tags to reason, then respond with <block>yes</block> or <block>no</block> and <reason>explanation</reason>.`,p=await r({system:Wm,messages:[{role:"user",content:u}],maxTokens:4096,temperature:0,cacheSystemPrompt:!0}),m=Vm(p.text),h=Gm(m),f=Km(m)??Km(l)??"classifier decision";return{shouldBlock:h!==!1,reason:f,stage:"thinking",durationMs:Date.now()-s}}catch{return{shouldBlock:!0,reason:"classifier unavailable",stage:"fast",durationMs:Date.now()-s}}}function Jw(n){return n.slice(-20).map(t=>{let r=t.role==="user"?"User":t.role==="assistant"?"Assistant":"System",s=typeof t.content=="string"?t.content.slice(0,500):JSON.stringify(t.content).slice(0,500);return`${r}: ${s}`}).join(`
|
|
669
669
|
`)}function Qw(n,e){let t=JSON.stringify(e,null,0),r=t.length>2e3?t.slice(0,2e3)+"...":t;return`Tool: ${n}
|
|
670
|
-
Arguments: ${r}`}function
|
|
671
|
-
`;mt.appendFileSync(this.filePath,r,"utf-8")}catch{}}};function
|
|
672
|
-
`)},name:{type:"string",description:"Skill name (required for invoke/view/create/edit/patch/delete/promote)."},args:{type:"string",description:"Arguments or context to pass when invoking a skill."},category:{type:"string",description:"Filter skills by category (for 'list' action)."},content:{type:"string",description:"Full SKILL.md content for create/edit actions."},filePath:{type:"string",description:"View a specific file within the skill (for 'view' action)."},fileContent:{type:"string",description:"Content for writing supporting files."},oldString:{type:"string",description:"Text to find for patch action."},newString:{type:"string",description:"Replacement text for patch action."},url:{type:"string",description:"URL to download a skill from (for 'install' action). Supports skill stores (skillhub.cn, skill.io, GitHub raw links, etc.) and any direct .md URL."}},required:["action"]};function
|
|
670
|
+
Arguments: ${r}`}function Gm(n){let e=n.match(/<block>(yes|no)<\/block>/i);return e?e[1].toLowerCase()==="yes":null}function Km(n){let e=n.match(/<reason>([\s\S]*?)(?:<\/reason>|$)/i);return e?e[1].trim():null}function Vm(n){return n.replace(/<thinking>[\s\S]*?<\/thinking>/gi,"").trim()}var zm={maxConsecutive:3,maxTotal:20};function Xm(){return{consecutiveDenials:0,totalDenials:0}}function Tc(n){return{consecutiveDenials:n.consecutiveDenials+1,totalDenials:n.totalDenials+1}}function Rc(n){return n.consecutiveDenials===0?n:{...n,consecutiveDenials:0}}function Ym(n){return n.consecutiveDenials>=zm.maxConsecutive||n.totalDenials>=zm.maxTotal}import*as mt from"node:fs";import*as kr from"node:path";var Zw="audit",ex="denials.jsonl",tx=10*1024*1024,Us=class{filePath;writeQueue=Promise.resolve();constructor(e){let t=kr.join(e,".qlogicagent",Zw);this.filePath=kr.join(t,ex)}record(e){this.writeQueue=this.writeQueue.then(()=>this.doWrite(e)).catch(()=>{})}getFilePath(){return this.filePath}async doWrite(e){try{let t=kr.dirname(this.filePath);if(mt.existsSync(t)||mt.mkdirSync(t,{recursive:!0}),mt.existsSync(this.filePath)&&mt.statSync(this.filePath).size>tx){let o=this.filePath+".1";mt.renameSync(this.filePath,o)}let r=JSON.stringify(e)+`
|
|
671
|
+
`;mt.appendFileSync(this.filePath,r,"utf-8")}catch{}}};function Jm(n){if(!n)return;let e={},t=/key|secret|token|password|credential|auth/i;for(let[r,s]of Object.entries(n))t.test(r)?e[r]="[REDACTED]":typeof s=="string"&&s.length>500?e[r]=s.slice(0,500)+"...[truncated]":e[r]=s;return e}var rx=12e4,Fs=class{ruleEngine;hookRegistry;onRequestApproval;onPermissionUpdate;onDenied;classifierLLMCall;getRecentMessages;permissionRole;pendingApprovals=new Map;auditLogger;sessionId;getTurnId;unregisterHook=null;toolMetaCache=new Map;classifierCache=new js;denialTracking=Xm();constructor(e){this.ruleEngine=e.ruleEngine,this.hookRegistry=e.hookRegistry,this.onRequestApproval=e.onRequestApproval,this.onPermissionUpdate=e.onPermissionUpdate,this.onDenied=e.onDenied,this.classifierLLMCall=e.classifierLLMCall,this.getRecentMessages=e.getRecentMessages,this.permissionRole=e.permissionRole??"interactive",this.auditLogger=e.auditLogger,this.sessionId=e.sessionId??"",this.getTurnId=e.getTurnId??(()=>"")}register(){return this.unregisterHook&&this.unregisterHook(),this.classifierCache.clear(),this.unregisterHook=this.hookRegistry.register({point:"tool.before_invoke",priority:100,label:"permission-checker",handler:async(e,t)=>{let r=this.toolMetaCache.get(t.toolName),s={toolName:t.toolName,arguments:t.arguments,meta:r?{isReadOnly:r.isReadOnly,isDangerous:r.isDangerous,requiresApproval:r.requiresApproval,parallelSafe:r.parallelSafe}:void 0},o=this.ruleEngine.check(s);return this.handleResult(o,t.callId,t.toolName,t.arguments)}}),()=>{this.unregisterHook?.(),this.unregisterHook=null,this.cancelAllPending()}}resolveApproval(e){let t=this.pendingApprovals.get(e.approvalId);t&&(clearTimeout(t.timeoutId),this.pendingApprovals.delete(e.approvalId),t.resolve(e))}setToolMeta(e){this.toolMetaCache.clear();for(let t of e)t.meta&&this.toolMetaCache.set(t.function.name,t.meta)}get ruleEngineRef(){return this.ruleEngine}fireDenied(e,t,r,s="classifier",o){this.onDenied?.(t,r),this.hookRegistry.invoke("permission.denied",{sessionId:this.sessionId,turnId:this.getTurnId(),approvalId:e,callId:e,toolName:t,decision:"denied",reason:r}).catch(()=>{}),this.auditLogger&&this.auditLogger.record({timestamp:new Date().toISOString(),sessionId:this.sessionId,turnId:this.getTurnId(),toolName:t,reason:r,source:s,permissionRole:this.permissionRole,callId:e,toolArgs:Jm(o),cumulativeDenials:this.denialTracking.totalDenials,consecutiveDenials:this.denialTracking.consecutiveDenials})}async handleResult(e,t,r,s){if(e.behavior==="allow")return{action:"continue",context:e.updatedInput?{arguments:e.updatedInput}:void 0};if(e.behavior==="deny")return this.fireDenied(t,r,e.message,"rule-engine",s),{action:"abort",reason:e.message};if(e.decisionReason?.type==="tool_check"&&(e.decisionReason.reason==="isDangerous"||e.decisionReason.reason==="requiresApproval")&&this.permissionRole!=="interactive")return this.fireDenied(t,r,`safety check: ${e.message} (${this.permissionRole} cannot override)`,"safety",s),{action:"abort",reason:`Tool "${r}" blocked by safety check (${this.permissionRole} agents cannot override dangerous tool restrictions)`};if((r==="bash"||r==="execute_command"||r==="Bash"||r==="shell")&&s){let l=s.command??s.cmd??"";if(l){let d=qm(l);if(d.decision==="allow")return{action:"continue"};if(d.decision==="deny")return this.fireDenied(t,r,d.reason,"classifier",s),{action:"abort",reason:d.reason}}}if(s){let l=this.classifierCache.get(r,s);if(l)return l.shouldBlock?(this.fireDenied(t,r,`cached: ${l.reason}`,"classifier",s),{action:"abort",reason:l.reason}):{action:"continue"}}if(this.permissionRole==="worker")return this.handleWorkerAsk(t,r,s);if(this.permissionRole==="coordinator")return this.toolMetaCache.get(r)?.isReadOnly||vr(r)?{action:"continue"}:this.handleWorkerAsk(t,r,s);if(this.ruleEngine.getMode()==="auto"){if(vr(r))return{action:"continue"};let l=Ym(this.denialTracking);if(this.classifierLLMCall&&!l)try{let d=this.getRecentMessages?.()??[],u=await Sc(r,s??{},d,this.classifierLLMCall);if(s&&this.classifierCache.set(r,s,{shouldBlock:u.shouldBlock,reason:u.reason}),!u.shouldBlock)return this.denialTracking=Rc(this.denialTracking),{action:"continue",context:{decisionReason:{type:"classifier",classifier:"auto",reason:u.reason}}};this.denialTracking=Tc(this.denialTracking)}catch{}}let a=nx(),c={approvalId:a,callId:t,toolName:r,arguments:s,message:e.message,suggestions:e.suggestions};this.hookRegistry.invoke("approval.requested",{sessionId:"",turnId:"",approvalId:a,callId:t,toolName:r}).catch(()=>{});try{let l=await this.requestApproval(c);return this.hookRegistry.invoke("approval.responded",{sessionId:"",turnId:"",approvalId:a,callId:t,toolName:r,decision:l.decision==="approved"?"approved":"denied"}).catch(()=>{}),l.permissionUpdate&&(this.ruleEngine.applyUpdate(l.permissionUpdate),this.onPermissionUpdate?.(l.permissionUpdate)),l.decision==="approved"?{action:"continue",context:l.updatedInput?{arguments:l.updatedInput}:void 0}:(this.fireDenied(t,r,`denied by user (approval ${a})`,"user",s),{action:"abort",reason:`Tool "${r}" denied by user`})}catch{return this.fireDenied(t,r,`approval timeout or error (approval ${a})`,"timeout",s),{action:"abort",reason:`Tool "${r}"approval timed out`}}}async handleWorkerAsk(e,t,r){if(vr(t))return{action:"continue"};if(this.classifierLLMCall)try{let s=this.getRecentMessages?.()??[],o=await Sc(t,r??{},s,this.classifierLLMCall);return r&&this.classifierCache.set(t,r,{shouldBlock:o.shouldBlock,reason:o.reason}),o.shouldBlock?(this.denialTracking=Tc(this.denialTracking),this.fireDenied(e,t,`blocked by classifier in ${this.permissionRole} mode: ${o.reason}`,"classifier",r),{action:"abort",reason:`Tool "${t}" blocked by classifier (${this.permissionRole})`}):(this.denialTracking=Rc(this.denialTracking),{action:"continue",context:{decisionReason:{type:"classifier",classifier:this.permissionRole,reason:o.reason}}})}catch{}return this.fireDenied(e,t,`no classifier available in ${this.permissionRole} mode`,"static-deny"),{action:"abort",reason:`Tool "${t}" deniedno classifier for ${this.permissionRole} mode`}}requestApproval(e){return new Promise((t,r)=>{let s=setTimeout(()=>{this.pendingApprovals.delete(e.approvalId),r(new Error("Approval timed out"))},rx);this.pendingApprovals.set(e.approvalId,{resolve:t,reject:r,timeoutId:s}),this.onRequestApproval(e).then(o=>{let i=this.pendingApprovals.get(e.approvalId);i&&(clearTimeout(i.timeoutId),this.pendingApprovals.delete(e.approvalId),t(o))},o=>{let i=this.pendingApprovals.get(e.approvalId);i&&(clearTimeout(i.timeoutId),this.pendingApprovals.delete(e.approvalId),r(o))})})}clearClassifierCache(){this.classifierCache.clear(),this.denialTracking={consecutiveDenials:0,totalDenials:0}}cancelAllPending(){this.classifierCache.clear();for(let[e,t]of this.pendingApprovals)clearTimeout(t.timeoutId),t.reject(new Error("Permission checker destroyed")),this.pendingApprovals.delete(e)}};var sx="skill",ox={type:"object",properties:{action:{type:"string",enum:["invoke","list","view","create","edit","patch","delete","promote","install"],description:["The operation to perform:","\u2022 'invoke' \u2014 Run a skill by name (provide 'name', optional 'args')","\u2022 'list' \u2014 List all available skills (optional 'category' filter)","\u2022 'view' \u2014 View full skill content (provide 'name', optional 'filePath')","\u2022 'create' \u2014 Create a new skill (provide 'name', 'content')","\u2022 'edit' \u2014 Overwrite skill content (provide 'name', 'content')","\u2022 'patch' \u2014 Find/replace in skill (provide 'name', 'oldString', 'newString')","\u2022 'delete' \u2014 Remove a skill (provide 'name')","\u2022 'promote' \u2014 Promote a project-level skill to global/user-level (provide 'name')","\u2022 'install' \u2014 Download and install a skill from a URL (provide 'url', optional 'name')"].join(`
|
|
672
|
+
`)},name:{type:"string",description:"Skill name (required for invoke/view/create/edit/patch/delete/promote)."},args:{type:"string",description:"Arguments or context to pass when invoking a skill."},category:{type:"string",description:"Filter skills by category (for 'list' action)."},content:{type:"string",description:"Full SKILL.md content for create/edit actions."},filePath:{type:"string",description:"View a specific file within the skill (for 'view' action)."},fileContent:{type:"string",description:"Content for writing supporting files."},oldString:{type:"string",description:"Text to find for patch action."},newString:{type:"string",description:"Replacement text for patch action."},url:{type:"string",description:"URL to download a skill from (for 'install' action). Supports skill stores (skillhub.cn, skill.io, GitHub raw links, etc.) and any direct .md URL."}},required:["action"]};function Qm(n){return{name:sx,label:"Skill",description:px(n),parameters:ox,isConcurrencySafe:!1,isReadOnly:!1,searchHint:"skill invoke list view create edit delete command workflow",execute:async(e,t,r)=>{let{action:s}=t;switch(s){case"invoke":return ix(n,t,r);case"list":return ax(n,t);case"view":return cx(n,t);case"create":case"edit":case"patch":case"delete":return lx(n,t);case"promote":return dx(n,t);case"install":return ux(n,t);default:return{content:[{type:"text",text:`Unknown action: ${s}. Use invoke, list, view, create, edit, patch, delete, promote, or install.`}]}}}}}async function ix(n,e,t){let{name:r,args:s}=e;if(!r)return{content:[{type:"text",text:`Error: 'name' is required for invoke. Available skills: ${n.listSkills().map(l=>l.name).join(", ")||"(none)"}`}]};let o=await n.readSkillContent(r);if(!o){let c=n.listSkills().map(l=>l.name).join(", ");return{content:[{type:"text",text:`Skill "${r}" not found. Available skills: ${c||"(none)"}`}]}}if(n.executeSkillSubturn)try{return{content:[{type:"text",text:await n.executeSkillSubturn(r,o,s,t)}],details:{skillName:r,action:"invoke",mode:"subturn"}}}catch(c){let l=c instanceof Error?c.message:String(c);return{content:[{type:"text",text:`Skill execution error: ${l}`}],details:{error:l,skillName:r}}}let i=`## Skill: ${r}
|
|
673
673
|
|
|
674
674
|
`,a=s?`
|
|
675
675
|
|
|
@@ -688,13 +688,13 @@ CROSS-PROJECT RECALL: When you see '[Cross-project skill available]' in recalled
|
|
|
688
688
|
`);return`${t}
|
|
689
689
|
|
|
690
690
|
Available skills:
|
|
691
|
-
${r}`}var mx="agent",
|
|
691
|
+
${r}`}var mx="agent",Zm=["general","explore","plan","code","research","verify"],gx={type:"object",properties:{agent:{type:"string",enum:["general","explore","plan","code","research","verify"],description:`Sub-agent type to fork:
|
|
692
692
|
- general: Full tool access, any task
|
|
693
693
|
- explore: Read-only codebase exploration (search, read, analyze)
|
|
694
694
|
- plan: Planning mode (explore + produce plan, no writes)
|
|
695
695
|
- code: Coding agent with full tool access
|
|
696
696
|
- research: Web research and information gathering
|
|
697
|
-
- verify: Run tests, check builds, validate changes`},prompt:{type:"string",description:"Detailed task for the sub-agent. The sub-agent shares your conversation history as context (prompt cache shared). Be specific about what information to return in the final response."},description:{type:"string",description:"Short description (3-7 words) for status tracking."},maxTurns:{type:"number",description:"Max turns for the sub-agent. Defaults: general=200, explore=50, plan=80, code=200, research=30, verify=40."},background:{type:"boolean",description:"If true, runs in background and returns a task_id. Poll with task tool. Default: false."}},required:["agent","prompt"],additionalProperties:!1},
|
|
697
|
+
- verify: Run tests, check builds, validate changes`},prompt:{type:"string",description:"Detailed task for the sub-agent. The sub-agent shares your conversation history as context (prompt cache shared). Be specific about what information to return in the final response."},description:{type:"string",description:"Short description (3-7 words) for status tracking."},maxTurns:{type:"number",description:"Max turns for the sub-agent. Defaults: general=200, explore=50, plan=80, code=200, research=30, verify=40."},background:{type:"boolean",description:"If true, runs in background and returns a task_id. Poll with task tool. Default: false."}},required:["agent","prompt"],additionalProperties:!1},eg=4;function tg(n){return{name:mx,label:"Sub-Agent",description:"Fork a sub-agent to handle complex tasks autonomously. Sub-agents share your conversation context (prompt cache) and have isolated tool state. Use for: parallel research, code exploration, testing, delegating large tasks to specialized agents.",parameters:gx,searchHint:"fork subagent delegate spawn child parallel worker",isConcurrencySafe:!0,execute:async(e,t)=>{if(!t.prompt||t.prompt.trim().length<10)return{content:[{type:"text",text:"Error: prompt must be at least 10 characters."}],details:{type:"agent",error:"prompt_too_short"}};if(!Zm.includes(t.agent))return{content:[{type:"text",text:`Error: unknown agent "${t.agent}". Available: ${Zm.join(", ")}`}],details:{type:"agent",error:"invalid_agent_type"}};let r=n.currentForkDepth??0;if(r>=eg)return{content:[{type:"text",text:`Error: maximum fork depth (${eg}) reached. Cannot spawn more sub-agents. Complete current work instead.`}],details:{type:"agent",error:"max_depth_reached",depth:r}};try{let s=await n.forkAgent({agent:t.agent,prompt:t.prompt.trim(),description:t.description,maxTurns:t.maxTurns,background:t.background,abortSignal:n.abortSignal});if(t.background&&s.status==="running")return{content:[{type:"text",text:`Sub-agent "${t.agent}" started in background.
|
|
698
698
|
Agent ID: ${s.agentId}
|
|
699
699
|
Use task tool with this ID to check status and get output.`}],details:{type:"agent",agentId:s.agentId,status:"running",background:!0}};if(s.status==="failed")return{content:[{type:"text",text:`Sub-agent failed: ${s.error||"unknown error"}`}],details:{type:"agent",agentId:s.agentId,status:"failed",error:s.error}};let o=s.output||"(sub-agent returned no output)",i=s.maxTurnsReached?`
|
|
700
700
|
|
|
@@ -702,18 +702,18 @@ Use task tool with this ID to check status and get output.`}],details:{type:"age
|
|
|
702
702
|
- get: Read a config setting
|
|
703
703
|
- set: Write a config setting
|
|
704
704
|
- list: List all available settings
|
|
705
|
-
- reset: Reset a setting to default`},key:{type:"string",description:"Config key path (e.g. 'model', 'language', 'theme', 'permissions.defaultMode'). Required for get/set/reset."},value:{description:"Value to set. Type depends on the setting. Required for 'set' action."}},required:["action"]},Sr=["permissions.securityPolicy","api.key","api.secret","auth.token","system.adminMode"];function
|
|
705
|
+
- reset: Reset a setting to default`},key:{type:"string",description:"Config key path (e.g. 'model', 'language', 'theme', 'permissions.defaultMode'). Required for get/set/reset."},value:{description:"Value to set. Type depends on the setting. Required for 'set' action."}},required:["action"]},Sr=["permissions.securityPolicy","api.key","api.secret","auth.token","system.adminMode"];function ng(n){return{name:fx,label:"Config",description:"Read and write agent configuration settings. Supports preferences like model selection, language, theme, tool enablement, etc. Security-critical settings (API keys, permissions) are read-only. Changes persist across sessions.",parameters:hx,execute:async(e,t)=>{switch(t.action){case"get":{if(!t.key)return{content:[{type:"text",text:"Error: key is required for get."}],details:{type:"config",error:"missing_key"}};if(n.isValidKey&&!n.isValidKey(t.key))return{content:[{type:"text",text:`Error: unknown config key "${t.key}". Use action='list' to see available settings.`}],details:{type:"config",error:"unknown_key"}};let r=await n.getConfig(t.key);if(!r.success)return{content:[{type:"text",text:`Error: ${r.error}`}],details:{type:"config",error:r.error}};let s=r.setting,o=[`${s.key} = ${JSON.stringify(s.value)}`,` Type: ${s.type}${s.options?` (${s.options.join(" | ")})`:""}`,` ${s.description}`];return s.readOnly&&o.push(" \u26A0\uFE0F Read-only (cannot be changed)"),{content:[{type:"text",text:o.join(`
|
|
706
706
|
`)}],details:{type:"config",action:"get",key:t.key,value:s.value}}}case"set":{if(!t.key)return{content:[{type:"text",text:"Error: key is required for set."}],details:{type:"config",error:"missing_key"}};if(t.value===void 0)return{content:[{type:"text",text:"Error: value is required for set."}],details:{type:"config",error:"missing_value"}};if(Sr.includes(t.key))return{content:[{type:"text",text:`Error: "${t.key}" is a security-critical setting and cannot be modified.`}],details:{type:"config",error:"readonly_key"}};if(n.isValidKey&&!n.isValidKey(t.key))return{content:[{type:"text",text:`Error: unknown config key "${t.key}".`}],details:{type:"config",error:"unknown_key"}};let r=await n.setConfig(t.key,t.value);return r.success?{content:[{type:"text",text:`Updated "${t.key}": ${JSON.stringify(r.previousValue)} \u2192 ${JSON.stringify(t.value)}`}],details:{type:"config",action:"set",key:t.key,previousValue:r.previousValue,newValue:t.value}}:{content:[{type:"text",text:`Error: ${r.error}`}],details:{type:"config",error:r.error}}}case"list":{let r=await n.listConfig();if(!r.settings||r.settings.length===0)return{content:[{type:"text",text:"No config settings available."}],details:{type:"config",action:"list",count:0}};let s=[`Available settings (${r.settings.length}):`,""];for(let o of r.settings){let i=o.readOnly?" [read-only]":"",a=JSON.stringify(o.value);s.push(` ${o.key} = ${a}${i}`),s.push(` ${o.description}`)}return{content:[{type:"text",text:s.join(`
|
|
707
707
|
`)}],details:{type:"config",action:"list",count:r.settings.length}}}case"reset":{if(!t.key)return{content:[{type:"text",text:"Error: key is required for reset."}],details:{type:"config",error:"missing_key"}};if(Sr.includes(t.key))return{content:[{type:"text",text:`Error: "${t.key}" cannot be reset (security-critical).`}],details:{type:"config",error:"readonly_key"}};let r=await n.resetConfig(t.key);return r.success?{content:[{type:"text",text:`Reset "${t.key}" to default: ${JSON.stringify(r.setting?.value)}`}],details:{type:"config",action:"reset",key:t.key,value:r.setting?.value}}:{content:[{type:"text",text:`Error: ${r.error}`}],details:{type:"config",error:r.error}}}default:return{content:[{type:"text",text:`Error: unknown action "${t.action}".`}],details:{type:"config",error:"unknown_action"}}}}}}var yx="cron",bx={type:"object",properties:{action:{type:"string",enum:["create","list","get","update","delete","pause","resume","trigger"],description:"CRUD action: create/list/get/update/delete/pause/resume/trigger."},jobId:{type:"string",description:"Job ID. Required for get/update/delete/pause/resume/trigger."},prompt:{type:"string",description:"Task prompt to execute on schedule. Required for create."},schedule:{type:"string",description:`Schedule expression. Supports:
|
|
708
708
|
- Cron: '0 9 * * *' (every day at 9am)
|
|
709
709
|
- Shorthand: '5m' (every 5 min), '1h' (hourly), '1d' (daily)
|
|
710
|
-
Required for create.`},name:{type:"string",description:"Human-readable job name."},repeat:{type:"number",description:"Number of times to repeat (null = infinite). Default: null."},allowedTools:{type:"array",items:{type:"string"},description:"Tools the scheduled task is allowed to use."},enabled:{type:"boolean",description:"Whether the job is enabled (for update)."}},required:["action"]},
|
|
710
|
+
Required for create.`},name:{type:"string",description:"Human-readable job name."},repeat:{type:"number",description:"Number of times to repeat (null = infinite). Default: null."},allowedTools:{type:"array",items:{type:"string"},description:"Tools the scheduled task is allowed to use."},enabled:{type:"boolean",description:"Whether the job is enabled (for update)."}},required:["action"]},rg=50;function sg(n){return{name:yx,label:"Cron",description:"Manage scheduled tasks. Create recurring jobs with cron expressions or shorthand ('5m', '1h', '0 9 * * *'). Jobs persist locally and survive restarts. Actions: create, list, get, update, delete, pause, resume, trigger (run now).",parameters:bx,execute:async(e,t)=>{switch(t.action){case"create":{if(!t.prompt)return{content:[{type:"text",text:"Error: prompt is required for create."}],details:{type:"cron",error:"missing_prompt"}};if(!t.schedule)return{content:[{type:"text",text:"Error: schedule is required for create."}],details:{type:"cron",error:"missing_schedule"}};if(n.validateSchedule){let o=n.validateSchedule(t.schedule);if(o)return{content:[{type:"text",text:`Error: invalid schedule \u2014 ${o}`}],details:{type:"cron",error:"invalid_schedule"}}}let r=await n.listJobs();if(r.jobs&&r.jobs.length>=rg)return{content:[{type:"text",text:`Error: maximum ${rg} jobs reached. Delete unused jobs first.`}],details:{type:"cron",error:"max_jobs_reached"}};let s=await n.createJob({prompt:t.prompt,schedule:t.schedule,name:t.name,repeat:t.repeat,allowedTools:t.allowedTools});return s.success?{content:[{type:"text",text:Ac(s.job)}],details:{type:"cron",action:"create",jobId:s.job.id}}:{content:[{type:"text",text:`Error: ${s.error}`}],details:{type:"cron",error:s.error}}}case"list":{let r=await n.listJobs();if(!r.jobs||r.jobs.length===0)return{content:[{type:"text",text:"No scheduled jobs."}],details:{type:"cron",action:"list",count:0}};let s=[`Scheduled jobs (${r.jobs.length}):`,""];for(let o of r.jobs)s.push(`- **${o.name||o.id}** [${o.state}] ${o.scheduleDisplay} \u2014 next: ${o.nextRunAt||"N/A"}`);return{content:[{type:"text",text:s.join(`
|
|
711
711
|
`)}],details:{type:"cron",action:"list",count:r.jobs.length}}}case"get":{if(!t.jobId)return{content:[{type:"text",text:"Error: jobId required."}],details:{type:"cron",error:"missing_jobId"}};let r=await n.getJob(t.jobId);return r.success?{content:[{type:"text",text:Ac(r.job)}],details:{type:"cron",action:"get",jobId:t.jobId}}:{content:[{type:"text",text:`Error: ${r.error}`}],details:{type:"cron",error:r.error}}}case"update":{if(!t.jobId)return{content:[{type:"text",text:"Error: jobId required."}],details:{type:"cron",error:"missing_jobId"}};let r={};t.prompt!==void 0&&(r.prompt=t.prompt),t.schedule!==void 0&&(r.schedule=t.schedule),t.name!==void 0&&(r.name=t.name),t.enabled!==void 0&&(r.enabled=t.enabled),t.repeat!==void 0&&(r.repeat=t.repeat),t.allowedTools!==void 0&&(r.allowedTools=t.allowedTools);let s=await n.updateJob(t.jobId,r);return s.success?{content:[{type:"text",text:`Job updated.
|
|
712
712
|
${Ac(s.job)}`}],details:{type:"cron",action:"update",jobId:t.jobId}}:{content:[{type:"text",text:`Error: ${s.error}`}],details:{type:"cron",error:s.error}}}case"delete":{if(!t.jobId)return{content:[{type:"text",text:"Error: jobId required."}],details:{type:"cron",error:"missing_jobId"}};let r=await n.deleteJob(t.jobId);return r.success?{content:[{type:"text",text:`Job ${t.jobId} deleted.`}],details:{type:"cron",action:"delete",jobId:t.jobId}}:{content:[{type:"text",text:`Error: ${r.error}`}],details:{type:"cron",error:r.error}}}case"pause":{if(!t.jobId)return{content:[{type:"text",text:"Error: jobId required."}],details:{type:"cron",error:"missing_jobId"}};let r=await n.pauseJob(t.jobId);return r.success?{content:[{type:"text",text:`Job ${t.jobId} paused.`}],details:{type:"cron",action:"pause",jobId:t.jobId}}:{content:[{type:"text",text:`Error: ${r.error}`}],details:{type:"cron",error:r.error}}}case"resume":{if(!t.jobId)return{content:[{type:"text",text:"Error: jobId required."}],details:{type:"cron",error:"missing_jobId"}};let r=await n.resumeJob(t.jobId);return r.success?{content:[{type:"text",text:`Job ${t.jobId} resumed.`}],details:{type:"cron",action:"resume",jobId:t.jobId}}:{content:[{type:"text",text:`Error: ${r.error}`}],details:{type:"cron",error:r.error}}}case"trigger":{if(!t.jobId)return{content:[{type:"text",text:"Error: jobId required."}],details:{type:"cron",error:"missing_jobId"}};let r=await n.triggerJob(t.jobId);return r.success?{content:[{type:"text",text:`Job ${t.jobId} triggered (running now).`}],details:{type:"cron",action:"trigger",jobId:t.jobId}}:{content:[{type:"text",text:`Error: ${r.error}`}],details:{type:"cron",error:r.error}}}default:return{content:[{type:"text",text:`Error: unknown action "${t.action}".`}],details:{type:"cron",error:"unknown_action"}}}}}}function Ac(n){let e=[`Job: ${n.name||n.id}`,`ID: ${n.id}`,`Schedule: ${n.scheduleDisplay} (${n.schedule})`,`State: ${n.state}`,`Repeat: ${n.repeat.times===null?"infinite":`${n.repeat.completed}/${n.repeat.times}`}`];return n.nextRunAt&&e.push(`Next run: ${n.nextRunAt}`),n.lastRunAt&&e.push(`Last run: ${n.lastRunAt} (${n.lastStatus||"unknown"})`),e.push(`Prompt: ${n.prompt.slice(0,100)}${n.prompt.length>100?"...":""}`),e.join(`
|
|
713
|
-
`)}var vx="monitor",kx={type:"object",properties:{action:{type:"string",enum:["start","stop","list"],description:"Action to perform: start a new monitor, stop an existing one, or list active monitors."},monitorId:{type:"string",description:"Identifier for the monitor instance. Required for start/stop."},source:{type:"string",enum:["process","file","task","custom"],description:"Type of event source to watch."},target:{type:"string",description:"Selector for the monitored target. For process: PID or background job id. For file: glob pattern. For task: task ID. For custom: host-defined key."},conditions:{type:"array",items:{type:"object",properties:{type:{type:"string",enum:["exit","output_match","file_changed","task_status"]},value:{type:"string"}},required:["type"]},description:"Conditions that trigger a wake-up notification."},timeoutSeconds:{type:"number",description:"Auto-stop after this many seconds (default: 3600).",minimum:1,maximum:86400}},required:["action"]};function
|
|
713
|
+
`)}var vx="monitor",kx={type:"object",properties:{action:{type:"string",enum:["start","stop","list"],description:"Action to perform: start a new monitor, stop an existing one, or list active monitors."},monitorId:{type:"string",description:"Identifier for the monitor instance. Required for start/stop."},source:{type:"string",enum:["process","file","task","custom"],description:"Type of event source to watch."},target:{type:"string",description:"Selector for the monitored target. For process: PID or background job id. For file: glob pattern. For task: task ID. For custom: host-defined key."},conditions:{type:"array",items:{type:"object",properties:{type:{type:"string",enum:["exit","output_match","file_changed","task_status"]},value:{type:"string"}},required:["type"]},description:"Conditions that trigger a wake-up notification."},timeoutSeconds:{type:"number",description:"Auto-stop after this many seconds (default: 3600).",minimum:1,maximum:86400}},required:["action"]};function og(n){return{name:vx,label:"Monitor",shouldDefer:!0,description:["Set up event-driven monitoring to wake up when something happens.","","Use this to watch for:","\u2022 Background process completion or specific output patterns","\u2022 File system changes (new file, modification)","\u2022 Async task state transitions (pending \u2192 completed/failed)","\u2022 Custom host-defined events","","When a monitored condition triggers, you'll receive a notification in your next tick.","This is more efficient than polling with Sleep \u2014 you only wake up when there's work to do.","","Actions:","\u2022 start \u2014 register a new monitor (requires monitorId, source, target)","\u2022 stop \u2014 deregister an active monitor","\u2022 list \u2014 show all active monitors and their event counts"].join(`
|
|
714
714
|
`),parameters:kx,execute:async(e,t)=>{let{action:r}=t;if(r==="list"){let i=await n.listMonitors();return i.length===0?{content:[{type:"text",text:"No active monitors."}],details:{action:r,monitors:[]}}:{content:[{type:"text",text:`Active monitors:
|
|
715
715
|
${i.map(c=>`\u2022 ${c.monitorId} [${c.source}] \u2192 ${c.target} (events: ${c.eventCount}, timeout: ${c.timeoutSeconds}s)`).join(`
|
|
716
|
-
`)}`}],details:{action:r,monitors:i}}}if(!t.monitorId)return{content:[{type:"text",text:"Error: monitorId is required for start/stop."}],details:{action:r,success:!1,error:"missing_monitor_id"}};if(r==="stop"){let i=await n.stopMonitor(t.monitorId);return{content:[{type:"text",text:i.success?`Monitor "${t.monitorId}" stopped.`:`Failed to stop monitor "${t.monitorId}": ${i.error??"not found"}`}],details:{...i}}}if(!t.source||!t.target)return{content:[{type:"text",text:"Error: source and target are required to start a monitor."}],details:{action:r,success:!1,error:"missing_source_or_target"}};let s=await n.startMonitor({monitorId:t.monitorId,source:t.source,target:t.target,conditions:t.conditions??[],timeoutSeconds:t.timeoutSeconds??3600});return{content:[{type:"text",text:s.success?`Monitor "${t.monitorId}" started: watching ${t.source} "${t.target}".`:`Failed to start monitor: ${s.error??"unknown"}`}],details:{...s}}}}}var Sx="team",Tx={type:"object",properties:{action:{type:"string",enum:["create","delete","list","status"],description:"Team action: create (new team), delete (disband), list (all teams), status (team details)."},teamName:{type:"string",description:"Team name. Required for create/delete/status."},description:{type:"string",description:"Team description/objective. Used for create."},members:{type:"array",description:"Team members with roles and tool restrictions.",items:{type:"object",properties:{name:{type:"string",description:"Agent name/role identifier."},role:{type:"string",description:"Role description (e.g. 'frontend developer')."},tools:{type:"array",items:{type:"string"},description:"Allowed tools for this member."}},required:["name","role"]}}},required:["action"]};function
|
|
716
|
+
`)}`}],details:{action:r,monitors:i}}}if(!t.monitorId)return{content:[{type:"text",text:"Error: monitorId is required for start/stop."}],details:{action:r,success:!1,error:"missing_monitor_id"}};if(r==="stop"){let i=await n.stopMonitor(t.monitorId);return{content:[{type:"text",text:i.success?`Monitor "${t.monitorId}" stopped.`:`Failed to stop monitor "${t.monitorId}": ${i.error??"not found"}`}],details:{...i}}}if(!t.source||!t.target)return{content:[{type:"text",text:"Error: source and target are required to start a monitor."}],details:{action:r,success:!1,error:"missing_source_or_target"}};let s=await n.startMonitor({monitorId:t.monitorId,source:t.source,target:t.target,conditions:t.conditions??[],timeoutSeconds:t.timeoutSeconds??3600});return{content:[{type:"text",text:s.success?`Monitor "${t.monitorId}" started: watching ${t.source} "${t.target}".`:`Failed to start monitor: ${s.error??"unknown"}`}],details:{...s}}}}}var Sx="team",Tx={type:"object",properties:{action:{type:"string",enum:["create","delete","list","status"],description:"Team action: create (new team), delete (disband), list (all teams), status (team details)."},teamName:{type:"string",description:"Team name. Required for create/delete/status."},description:{type:"string",description:"Team description/objective. Used for create."},members:{type:"array",description:"Team members with roles and tool restrictions.",items:{type:"object",properties:{name:{type:"string",description:"Agent name/role identifier."},role:{type:"string",description:"Role description (e.g. 'frontend developer')."},tools:{type:"array",items:{type:"string"},description:"Allowed tools for this member."}},required:["name","role"]}}},required:["action"]};function ig(n){return{name:Sx,label:"Team",description:"Manage multi-agent teams. Create teams of specialized agents that collaborate via send_message. Each member has a role and optional tool restrictions. Use for complex tasks requiring parallel work.",parameters:Tx,execute:async(e,t)=>{switch(t.action){case"create":{if(!t.teamName)return{content:[{type:"text",text:"Error: teamName required for create."}],details:{type:"team",error:"missing_name"}};let r=await n.createTeam({teamName:t.teamName,description:t.description,members:t.members});if(!r.success)return{content:[{type:"text",text:`Error: ${r.error}`}],details:{type:"team",error:r.error}};let s=[`Team "${r.team.name}" created.`,`Lead: ${r.team.leadId}`,`Members: ${r.team.members.length}`];for(let o of r.team.members)s.push(` - ${o.name} (${o.role})`);return{content:[{type:"text",text:s.join(`
|
|
717
717
|
`)}],details:{type:"team",action:"create",teamName:r.team.name}}}case"delete":{if(!t.teamName)return{content:[{type:"text",text:"Error: teamName required for delete."}],details:{type:"team",error:"missing_name"}};let r=await n.deleteTeam(t.teamName);return r.success?{content:[{type:"text",text:`Team "${t.teamName}" disbanded.`}],details:{type:"team",action:"delete",teamName:t.teamName}}:{content:[{type:"text",text:`Error: ${r.error}`}],details:{type:"team",error:r.error}}}case"list":{let r=await n.listTeams();if(!r.teams||r.teams.length===0)return{content:[{type:"text",text:"No active teams."}],details:{type:"team",action:"list",count:0}};let s=[`Active teams (${r.teams.length}):`,""];for(let o of r.teams)s.push(`- **${o.name}**: ${o.description||"(no description)"} \u2014 ${o.members.length} members`);return{content:[{type:"text",text:s.join(`
|
|
718
718
|
`)}],details:{type:"team",action:"list",count:r.teams.length}}}case"status":{if(!t.teamName)return{content:[{type:"text",text:"Error: teamName required for status."}],details:{type:"team",error:"missing_name"}};let r=await n.getTeamStatus(t.teamName);if(!r.success)return{content:[{type:"text",text:`Error: ${r.error}`}],details:{type:"team",error:r.error}};let s=r.team,o=r.memberProgress??{},i=[`Team: ${s.name}`,`Description: ${s.description||"\u2014"}`,`Lead: ${s.leadId}`,`Created: ${s.createdAt}`,"",`Members (${s.members.length}):`];for(let a of s.members){let c=a.tools?` [tools: ${a.tools.join(", ")}]`:"",l=a.worktreePath?` [worktree: ${a.worktreePath}]`:a.cwd?` [cwd: ${a.cwd}]`:"",d=o[a.name],u=a.isActive===!1?" (idle)":" (active)";if(d){let p=[];if(d.runningFor&&p.push(`running ${Math.round(d.runningFor/1e3)}s`),d.lastToolCall&&p.push(`tool: ${d.lastToolCall}`),d.idleFor!==void 0&&d.idleFor>5&&p.push(`idle ${d.idleFor}s`),d.mediaProgress){let m=d.mediaProgress;p.push(`${m.mediaType} ${m.percent}% [${m.status}] taskId=${m.taskId}${m.provider?` provider=${m.provider}`:""}`)}p.length&&(u=` (${p.join(", ")})`)}i.push(` - ${a.name} (${a.role})${c}${l}${u}`)}return{content:[{type:"text",text:i.join(`
|
|
719
719
|
`)}],details:{type:"team",action:"status",teamName:s.name}}}default:return{content:[{type:"text",text:`Error: unknown action "${t.action}".`}],details:{type:"team",error:"unknown_action"}}}}}}var Ax="mcp",wx={type:"object",properties:{action:{type:"string",enum:["list_servers","list_tools","call_tool","list_resources","read_resource","list_prompts","get_prompt","authenticate","manage_server"],description:`MCP action:
|
|
@@ -725,7 +725,7 @@ ${i.map(c=>`\u2022 ${c.monitorId} [${c.source}] \u2192 ${c.target} (events: ${c.
|
|
|
725
725
|
- list_prompts: List prompts available from a server
|
|
726
726
|
- get_prompt: Get a specific prompt with arguments
|
|
727
727
|
- authenticate: Initiate OAuth authentication with a server
|
|
728
|
-
- manage_server: Add, remove, restart, or check server status`},server:{type:"string",description:"MCP server name. Required for all actions except list_servers."},toolName:{type:"string",description:"Tool name on the MCP server. Required for call_tool."},arguments:{type:"object",description:"Arguments for the tool call or prompt. Used with call_tool and get_prompt."},uri:{type:"string",description:"Resource URI. Required for read_resource."},promptName:{type:"string",description:"Prompt name. Required for get_prompt."},manageAction:{type:"string",enum:["add","remove","restart","health_check","enable","disable"],description:"Sub-action for manage_server."},config:{type:"object",description:"Server configuration. Required for manage_server add."}},required:["action"]};function
|
|
728
|
+
- manage_server: Add, remove, restart, or check server status`},server:{type:"string",description:"MCP server name. Required for all actions except list_servers."},toolName:{type:"string",description:"Tool name on the MCP server. Required for call_tool."},arguments:{type:"object",description:"Arguments for the tool call or prompt. Used with call_tool and get_prompt."},uri:{type:"string",description:"Resource URI. Required for read_resource."},promptName:{type:"string",description:"Prompt name. Required for get_prompt."},manageAction:{type:"string",enum:["add","remove","restart","health_check","enable","disable"],description:"Sub-action for manage_server."},config:{type:"object",description:"Server configuration. Required for manage_server add."}},required:["action"]};function ag(n){return{name:Ax,label:"MCP",description:`Interact with external MCP (Model Context Protocol) servers. Discover and call tools, read resources, get prompts, manage servers, and handle authentication. MCP servers extend agent capabilities with external integrations (databases, APIs, code analysis, custom tools).
|
|
729
729
|
|
|
730
730
|
Dynamic tools: When MCP servers are connected, their tools also appear as individual entries in the tool list (prefixed mcp__server__tool) for direct invocation without going through this management tool.`,parameters:wx,shouldDefer:!0,execute:async(e,t,r)=>{switch(t.action){case"list_servers":{let s=await n.listServers();if(s.length===0)return{content:[{type:"text",text:"No MCP servers configured. Use manage_server action to add one."}],details:{type:"mcp",action:"list_servers",count:0}};let o=[`MCP Servers (${s.length}):`,""];for(let i of s){let a=xx(i.status);if(o.push(`${a} **${i.name}** [${i.transport}] \u2014 ${i.status}`),o.push(` Tools: ${i.toolCount} | Resources: ${i.resourceCount} | Prompts: ${i.promptCount}`),i.capabilities){let c=[];i.capabilities.tools?.listChanged&&c.push("tools/listChanged"),i.capabilities.resources?.subscribe&&c.push("resources/subscribe"),i.capabilities.prompts?.listChanged&&c.push("prompts/listChanged"),c.length>0&&o.push(` Capabilities: ${c.join(", ")}`)}i.serverVersion&&o.push(` Version: ${i.serverVersion}`),i.error&&o.push(` \u26A0 Error: ${i.error}`),o.push("")}return{content:[{type:"text",text:o.join(`
|
|
731
731
|
`)}],details:{type:"mcp",action:"list_servers",count:s.length}}}case"list_tools":{if(!t.server)return Se("server is required for list_tools.");let s=await n.listTools(t.server);if(s.length===0)return{content:[{type:"text",text:`No tools available from server "${t.server}".`}],details:{type:"mcp",action:"list_tools",server:t.server,count:0}};let o=[`Tools from "${t.server}" (${s.length}):`,""];for(let i of s){let a=Px(i.annotations);o.push(`- **${i.name}**${a}${i.description?`: ${i.description}`:""}`),i.prefixedName&&o.push(` Direct call: \`${i.prefixedName}\``)}return{content:[{type:"text",text:o.join(`
|
|
@@ -741,18 +741,18 @@ ${s.message||"Once you complete authentication, the server's tools will become a
|
|
|
741
741
|
Required scopes: ${s.requiredScopes?.join(", ")||"unknown"}
|
|
742
742
|
|
|
743
743
|
`+(s.authUrl?`Re-authorize at: ${s.authUrl}`:"Please re-authenticate with elevated permissions.")}],details:{type:"mcp",action:"authenticate",server:t.server,status:"step_up_required"}};case"unsupported":return{content:[{type:"text",text:`Authentication not supported for "${t.server}" (${s.message||"uses local transport"}).`}],details:{type:"mcp",action:"authenticate",server:t.server,status:"unsupported"}};default:return{content:[{type:"text",text:`Authentication error for "${t.server}": ${s.message||"unknown error"}`}],details:{type:"mcp",action:"authenticate",server:t.server,status:"error"}}}}case"manage_server":{if(!t.server)return Se("server is required for manage_server.");if(!t.manageAction)return Se("manageAction is required for manage_server.");switch(t.manageAction){case"add":{if(!n.addServer)return Se("Server addition not supported by the current MCP host.");if(!t.config)return Se("config is required for manage_server add.");let s=await n.addServer(t.server,t.config);return Tr("add",t.server,s)}case"remove":{if(!n.removeServer)return Se("Server removal not supported by the current MCP host.");let s=await n.removeServer(t.server);return Tr("remove",t.server,s)}case"restart":{if(!n.restartServer)return Se("Server restart not supported by the current MCP host.");let s=await n.restartServer(t.server);return Tr("restart",t.server,s)}case"health_check":{if(!n.healthCheck)return Se("Health check not supported by the current MCP host.");let s=await n.healthCheck(t.server);return Tr("health_check",t.server,s)}case"enable":case"disable":{if(!n.setServerEnabled)return Se("Server enable/disable not supported by the current MCP host.");let s=await n.setServerEnabled(t.server,t.manageAction==="enable");return Tr(t.manageAction,t.server,s)}default:return Se(`Unknown manageAction: ${t.manageAction}`)}}default:return Se(`Unknown action: "${t.action}".`)}}}}function Se(n){return{content:[{type:"text",text:`Error: ${n}`}],details:{type:"mcp",error:n}}}function xx(n){switch(n){case"connected":return"\u2705";case"connecting":return"\u23F3";case"needs-auth":return"\u{1F511}";case"failed":return"\u274C";case"disconnected":return"\u26AA";case"disabled":return"\u{1F6AB}";default:return"\u2753"}}function Px(n){if(!n)return"";let e=[];return n.readOnlyHint&&e.push("\u{1F4D6}"),n.destructiveHint&&e.push("\u26A0\uFE0F"),n.idempotentHint&&e.push("\u267B\uFE0F"),e.length>0?` ${e.join("")}`:""}function Ix(n){return n<1024?`${n}B`:n<1024*1024?`${(n/1024).toFixed(1)}KB`:`${(n/(1024*1024)).toFixed(1)}MB`}function Tr(n,e,t){let r=[];return r.push(`${t.success?"\u2705":"\u274C"} ${n} "${e}": ${t.message}`),t.serverState&&(r.push(""),r.push(` Status: ${t.serverState.status}`),r.push(` Tools: ${t.serverState.toolCount} | Resources: ${t.serverState.resourceCount}`)),{content:[{type:"text",text:r.join(`
|
|
744
|
-
`)}],details:{type:"mcp",action:"manage_server",manageAction:n,server:e,success:t.success}}}var _x="checkpoint",Ex={type:"object",properties:{action:{type:"string",enum:["create","list","restore","diff"],description:"Action: create (snapshot current state), list (show checkpoints), restore (revert to checkpoint), diff (show changes since checkpoint)."},checkpointId:{type:"string",description:"Checkpoint ID. Required for restore and diff."},message:{type:"string",description:"Optional descriptive message for the checkpoint."},paths:{type:"array",items:{type:"string"},description:"File paths to restore (partial restore). Omit to restore everything."}},required:["action"]},
|
|
744
|
+
`)}],details:{type:"mcp",action:"manage_server",manageAction:n,server:e,success:t.success}}}var _x="checkpoint",Ex={type:"object",properties:{action:{type:"string",enum:["create","list","restore","diff"],description:"Action: create (snapshot current state), list (show checkpoints), restore (revert to checkpoint), diff (show changes since checkpoint)."},checkpointId:{type:"string",description:"Checkpoint ID. Required for restore and diff."},message:{type:"string",description:"Optional descriptive message for the checkpoint."},paths:{type:"array",items:{type:"string"},description:"File paths to restore (partial restore). Omit to restore everything."}},required:["action"]},cg=/^[0-9a-fA-F]{4,64}$/;function lg(n){return{name:_x,label:"Checkpoint",description:"Manage workspace checkpoints (shadow snapshots independent of user's git). Create snapshots before risky operations, list history, restore on errors, or diff to see what changed. Checkpoints do NOT affect user's .git.",parameters:Ex,execute:async(e,t)=>{switch(t.action){case"create":{let r=await n.createCheckpoint(t.message);return r.success?{content:[{type:"text",text:`Checkpoint created: ${r.checkpoint.id}
|
|
745
745
|
Message: ${r.checkpoint.message}
|
|
746
746
|
Files: ${r.checkpoint.fileCount}`}],details:{type:"checkpoint",action:"create",checkpointId:r.checkpoint.id}}:{content:[{type:"text",text:`Error: ${r.error}`}],details:{type:"checkpoint",error:r.error}}}case"list":{let r=await n.listCheckpoints();if(!r.checkpoints||r.checkpoints.length===0)return{content:[{type:"text",text:"No checkpoints available."}],details:{type:"checkpoint",action:"list",count:0}};let s=[`Checkpoints (${r.checkpoints.length}):`,""];for(let o of r.checkpoints)s.push(`- ${o.id.slice(0,8)} [${o.timestamp}] ${o.message} (${o.fileCount} files)`);return{content:[{type:"text",text:s.join(`
|
|
747
|
-
`)}],details:{type:"checkpoint",action:"list",count:r.checkpoints.length}}}case"restore":{if(!t.checkpointId)return{content:[{type:"text",text:"Error: checkpointId required for restore."}],details:{type:"checkpoint",error:"missing_id"}};if(!
|
|
748
|
-
`).map(a=>{let[c="",l="",...d]=a.split("|");return{id:c,timestamp:l,message:d.join("|"),fileCount:0}})}:{success:!0,checkpoints:[]}}catch(r){return{success:!1,error:r.message}}},restoreCheckpoint:async(r,s)=>{try{let{execSync:o}=await import("node:child_process");if(s&&s.length>0){o(`git checkout ${r} ${s.map(i=>`"${i.replace(/"/g,'\\"')}"`).join(" ")}`,{cwd:t,stdio:"pipe"});for(let i of s){let a=En.join(t,i),c=En.join(n,i);ze.existsSync(a)&&ze.cpSync(a,c,{recursive:!0})}}else{o(`git checkout ${r} .`,{cwd:t,stdio:"pipe"});let i=ze.readdirSync(n);for(let a of i){if(a===".git"||a==="node_modules")continue;let c=En.join(n,a);ze.rmSync(c,{recursive:!0,force:!0})}ze.cpSync(t,n,{recursive:!0,filter:a=>!a.includes(".git")})}return{success:!0}}catch(o){return{success:!1,error:o.message}}},diffCheckpoint:async r=>{try{let{execSync:s}=await import("node:child_process");return{success:!0,diff:s(`git diff ${r} HEAD`,{cwd:t,stdio:"pipe"}).toString()}}catch(s){return{success:!1,error:s.message}}}}}var Cx="notify",Mx={type:"object",properties:{message:{type:"string",description:"Notification content to send to the user."},title:{type:"string",description:"Optional notification title/subject line."},priority:{type:"string",enum:["low","normal","high"],description:"Notification priority (default: normal). High may trigger sound/vibration."},channel:{type:"string",description:"Target delivery channel (e.g. 'wechat', 'feishu', 'discord'). Default: user's primary."}},required:["message"]};function
|
|
747
|
+
`)}],details:{type:"checkpoint",action:"list",count:r.checkpoints.length}}}case"restore":{if(!t.checkpointId)return{content:[{type:"text",text:"Error: checkpointId required for restore."}],details:{type:"checkpoint",error:"missing_id"}};if(!cg.test(t.checkpointId))return{content:[{type:"text",text:"Error: invalid checkpoint ID format."}],details:{type:"checkpoint",error:"invalid_id"}};let r=await n.restoreCheckpoint(t.checkpointId,t.paths);if(!r.success)return{content:[{type:"text",text:`Error: ${r.error}`}],details:{type:"checkpoint",error:r.error}};let s=t.paths?`(${t.paths.length} files)`:"(full workspace)";return{content:[{type:"text",text:`Restored to checkpoint ${t.checkpointId.slice(0,8)} ${s}`}],details:{type:"checkpoint",action:"restore",checkpointId:t.checkpointId}}}case"diff":{if(!t.checkpointId)return{content:[{type:"text",text:"Error: checkpointId required for diff."}],details:{type:"checkpoint",error:"missing_id"}};if(!cg.test(t.checkpointId))return{content:[{type:"text",text:"Error: invalid checkpoint ID format."}],details:{type:"checkpoint",error:"invalid_id"}};let r=await n.diffCheckpoint(t.checkpointId);return r.success?{content:[{type:"text",text:r.diff||"(no changes since checkpoint)"}],details:{type:"checkpoint",action:"diff",checkpointId:t.checkpointId}}:{content:[{type:"text",text:`Error: ${r.error}`}],details:{type:"checkpoint",error:r.error}}}default:return{content:[{type:"text",text:`Error: unknown action "${t.action}".`}],details:{type:"checkpoint",error:"unknown_action"}}}}}}ae();import*as ze from"node:fs";import*as En from"node:path";function dg(n,e){let t=xd(n,e);return{createCheckpoint:async r=>{try{ze.mkdirSync(t,{recursive:!0});let{execSync:s}=await import("node:child_process"),o=En.join(t,".git");ze.existsSync(o)||(s("git init",{cwd:t,stdio:"pipe"}),s('git config user.email "checkpoint@agent"',{cwd:t,stdio:"pipe"}),s('git config user.name "Checkpoint"',{cwd:t,stdio:"pipe"})),ze.cpSync(n,t,{recursive:!0,filter:l=>!l.includes(".git")&&!l.includes("node_modules")}),s("git add -A",{cwd:t,stdio:"pipe"});let i=r||`checkpoint ${new Date().toISOString()}`;s(`git commitallow-empty -m "${i.replace(/"/g,'\\"')}"`,{cwd:t,stdio:"pipe"});let a=s("git rev-parse HEAD",{cwd:t,stdio:"pipe"}).toString().trim(),c=parseInt(s("git ls-files | wc -l",{cwd:t,stdio:"pipe"}).toString().trim(),10)||0;return{success:!0,checkpoint:{id:a,message:i,timestamp:new Date().toISOString(),fileCount:c}}}catch(s){return{success:!1,error:s.message}}},listCheckpoints:async()=>{try{let{execSync:r}=await import("node:child_process"),s=En.join(t,".git");if(!ze.existsSync(s))return{success:!0,checkpoints:[]};let o=r('git logformat="%H|%aI|%s"max-count=20',{cwd:t,stdio:"pipe"}).toString().trim();return o?{success:!0,checkpoints:o.split(`
|
|
748
|
+
`).map(a=>{let[c="",l="",...d]=a.split("|");return{id:c,timestamp:l,message:d.join("|"),fileCount:0}})}:{success:!0,checkpoints:[]}}catch(r){return{success:!1,error:r.message}}},restoreCheckpoint:async(r,s)=>{try{let{execSync:o}=await import("node:child_process");if(s&&s.length>0){o(`git checkout ${r} ${s.map(i=>`"${i.replace(/"/g,'\\"')}"`).join(" ")}`,{cwd:t,stdio:"pipe"});for(let i of s){let a=En.join(t,i),c=En.join(n,i);ze.existsSync(a)&&ze.cpSync(a,c,{recursive:!0})}}else{o(`git checkout ${r} .`,{cwd:t,stdio:"pipe"});let i=ze.readdirSync(n);for(let a of i){if(a===".git"||a==="node_modules")continue;let c=En.join(n,a);ze.rmSync(c,{recursive:!0,force:!0})}ze.cpSync(t,n,{recursive:!0,filter:a=>!a.includes(".git")})}return{success:!0}}catch(o){return{success:!1,error:o.message}}},diffCheckpoint:async r=>{try{let{execSync:s}=await import("node:child_process");return{success:!0,diff:s(`git diff ${r} HEAD`,{cwd:t,stdio:"pipe"}).toString()}}catch(s){return{success:!1,error:s.message}}}}}var Cx="notify",Mx={type:"object",properties:{message:{type:"string",description:"Notification content to send to the user."},title:{type:"string",description:"Optional notification title/subject line."},priority:{type:"string",enum:["low","normal","high"],description:"Notification priority (default: normal). High may trigger sound/vibration."},channel:{type:"string",description:"Target delivery channel (e.g. 'wechat', 'feishu', 'discord'). Default: user's primary."}},required:["message"]};function ug(n){return{name:Cx,label:"Notify",description:"Send a notification to the user. Used for alerting about completed long-running tasks, important updates, or requesting attention. Supports multiple channels (WeChat, Feishu, Discord, etc).",parameters:Mx,execute:async(e,t)=>{if(!t.message||t.message.trim().length===0)return{content:[{type:"text",text:"Error: message is required."}],details:{type:"notify",error:"empty_message"}};let r=await n.sendNotification({message:t.message.trim(),title:t.title,priority:t.priority||"normal",channel:t.channel});return r.delivered?{content:[{type:"text",text:`Notification sent via ${r.channel}.`}],details:{type:"notify",delivered:!0,channel:r.channel}}:{content:[{type:"text",text:`Notification failed: ${r.error||"delivery error"}`}],details:{type:"notify",delivered:!1,error:r.error}}}}}var Nx="send_message",Dx={type:"object",properties:{to:{type:"string",description:"Target agent name or '*' for broadcast to all team members. Must be a valid agent name within the current team."},message:{type:"string",description:"Message content to send to the target agent."},summary:{type:"string",description:"Optional short summary (for logging/routing)."}},required:["to","message"]};function pg(n){return{name:Nx,label:"Send Message",description:"Send a message to another agent in your team. Use '*' to broadcast to all teammates. Messages are delivered asynchronously. Use for coordination, delegation, and status updates.",parameters:Dx,execute:async(e,t)=>{if(!t.to||t.to.trim().length===0)return{content:[{type:"text",text:"Error: 'to' is required (agent name or '*')."}],details:{type:"send_message",error:"missing_target"}};if(!t.message||t.message.trim().length===0)return{content:[{type:"text",text:"Error: message is required."}],details:{type:"send_message",error:"empty_message"}};if(t.to!=="*"&&n.listTeammates){let o=n.listTeammates();if(!o.includes(t.to))return{content:[{type:"text",text:`Error: agent "${t.to}" not found in team. Available: ${o.join(", ")}`}],details:{type:"send_message",error:"target_not_found",available:o}}}let r=await n.sendMessage({to:t.to.trim(),message:t.message.trim(),summary:t.summary,senderId:n.getSenderId()});return r.success?{content:[{type:"text",text:`Message sent to ${t.to==="*"?`broadcast (${r.recipients?.length||0} recipients)`:t.to}.`}],details:{type:"send_message",success:!0,to:t.to,recipients:r.recipients}}:{content:[{type:"text",text:`Message delivery failed: ${r.error||"unknown error"}`}],details:{type:"send_message",success:!1,error:r.error}}}}}var Ox="repl",Lx={type:"object",properties:{code:{type:"string",description:`JavaScript code to execute. The VM has access to these built-in primitives:
|
|
749
749
|
- readFile(path): Promise<string> \u2014 read a file
|
|
750
750
|
- writeFile(path, content): Promise<void> \u2014 write a file
|
|
751
751
|
- editFile(path, edits): Promise<string> \u2014 apply edits [{oldText, newText}]
|
|
752
752
|
- exec(command): Promise<{stdout, stderr, exitCode}> \u2014 run shell command
|
|
753
753
|
- glob(pattern): Promise<string[]> \u2014 find files by glob
|
|
754
754
|
- grep(pattern, path?): Promise<{file,line,text}[]> \u2014 search files
|
|
755
|
-
Use this for batch operations (rename many files, transform data, etc) to reduce tool call round-trips.`}},required:["code"]};var
|
|
755
|
+
Use this for batch operations (rename many files, transform data, etc) to reduce tool call round-trips.`}},required:["code"]};var mg=1e5,gg=5e4;function fg(n){return{name:Ox,label:"REPL",description:"Execute JavaScript in a persistent VM with built-in file/shell primitives. Use for batch operations that would otherwise require many individual tool calls. The VM persists variables between calls within the same session. Each primitive (readFile, writeFile, exec, etc.) still goes through permission checks.",parameters:Lx,execute:async(e,t)=>{if(!t.code||t.code.trim().length===0)return{content:[{type:"text",text:"Error: code is required."}],details:{type:"repl",error:"empty_code"}};if(t.code.length>mg)return{content:[{type:"text",text:`Error: code too large (${t.code.length} chars, max ${mg}).`}],details:{type:"repl",error:"code_too_large"}};let r=await n.executeInVm(t.code),s=r.output||"";return s.length>gg&&(s=s.slice(0,gg)+`
|
|
756
756
|
... (truncated)`),r.error?{content:[{type:"text",text:`Error: ${r.error}
|
|
757
757
|
|
|
758
758
|
Output:
|
|
@@ -765,7 +765,7 @@ ${s}`}],details:{type:"repl",error:r.error,duration:r.duration}}:{content:[{type
|
|
|
765
765
|
- completion: get completions at position
|
|
766
766
|
- signatureHelp: get function signature at call site
|
|
767
767
|
- rename: preview rename of symbol
|
|
768
|
-
- codeAction: get available quick-fixes/refactorings`},filePath:{type:"string",description:"File path. Absolute or relative to workspace root."},line:{type:"number",description:"Line number (1-indexed). Required for positional operations."},character:{type:"number",description:"Character position (1-indexed). Required for positional operations."},newName:{type:"string",description:"New name for rename operation."},includeContext:{type:"boolean",description:"Include surrounding code context in results (default: true)."}},required:["operation","filePath"]},jx=10*1024*1024,Ux=["goToDefinition","findReferences","hover","completion","signatureHelp","rename","codeAction"];function
|
|
768
|
+
- codeAction: get available quick-fixes/refactorings`},filePath:{type:"string",description:"File path. Absolute or relative to workspace root."},line:{type:"number",description:"Line number (1-indexed). Required for positional operations."},character:{type:"number",description:"Character position (1-indexed). Required for positional operations."},newName:{type:"string",description:"New name for rename operation."},includeContext:{type:"boolean",description:"Include surrounding code context in results (default: true)."}},required:["operation","filePath"]},jx=10*1024*1024,Ux=["goToDefinition","findReferences","hover","completion","signatureHelp","rename","codeAction"];function hg(n){return{name:"lsp",label:"LSP",description:"Query language servers for code intelligence. Supports go-to-definition, find-references, hover (type info), document symbols, diagnostics (errors/warnings), completions, signature help, rename preview, and code actions. Read-only \u2014 does not modify files.",parameters:$x,execute:async(e,t)=>{if(!t.filePath||t.filePath.trim().length===0)return{content:[{type:"text",text:"Error: filePath is required."}],details:{type:"lsp",error:"missing_filePath"}};if(t.filePath.startsWith("\\\\")||t.filePath.startsWith("//"))return{content:[{type:"text",text:"Error: UNC paths are not allowed."}],details:{type:"lsp",error:"unc_blocked"}};if(Ux.includes(t.operation)){if(t.line==null||t.character==null)return{content:[{type:"text",text:`Error: line and character are required for ${t.operation}.`}],details:{type:"lsp",error:"missing_position"}};if(t.line<1||t.character<1)return{content:[{type:"text",text:"Error: line and character must be \u2265 1."}],details:{type:"lsp",error:"invalid_position"}}}if(t.operation==="rename"&&!t.newName)return{content:[{type:"text",text:"Error: newName is required for rename operation."}],details:{type:"lsp",error:"missing_newName"}};let r=n.resolvePath(t.filePath);if(n.statFile){let o=await n.statFile(r);if(!o||!o.exists)return{content:[{type:"text",text:`Error: file not found: ${t.filePath}`}],details:{type:"lsp",error:"file_not_found"}};if(o.size>jx)return{content:[{type:"text",text:`Error: file too large (${(o.size/1024/1024).toFixed(1)}MB, max 10MB).`}],details:{type:"lsp",error:"file_too_large"}}}let s=await n.executeOperation({operation:t.operation,filePath:r,line:t.line,character:t.character,newName:t.newName,includeContext:t.includeContext??!0});return{content:[{type:"text",text:Fx(t.operation,s)}],details:{type:"lsp",operation:t.operation}}}}}function Fx(n,e){switch(e.type){case"locations":{if(e.locations.length===0)return"No results found.";let t=[`Found ${e.locations.length} location(s):`,""];for(let r of e.locations.slice(0,50))t.push(` ${r.filePath}:${r.line}:${r.character}`),r.context&&t.push(` ${r.context.trim()}`);return e.locations.length>50&&t.push(` ... and ${e.locations.length-50} more`),t.join(`
|
|
769
769
|
`)}case"symbols":{if(e.symbols.length===0)return"No symbols found.";let t=[`Document symbols (${e.symbols.length}):`,""];for(let r of e.symbols)if(t.push(` ${r.kind} ${r.name} (L${r.range.startLine}-${r.range.endLine})`),r.children){for(let s of r.children.slice(0,10))t.push(` ${s.kind} ${s.name} (L${s.range.startLine})`);r.children.length>10&&t.push(` ... and ${r.children.length-10} more`)}return t.join(`
|
|
770
770
|
`)}case"diagnostics":{if(e.diagnostics.length===0)return"No diagnostics (clean file).";let t=[`Diagnostics (${e.diagnostics.length}):`,""];for(let r of e.diagnostics){let s=r.severity==="error"?"\u274C":r.severity==="warning"?"\u26A0\uFE0F":"\u2139\uFE0F";t.push(` ${s} L${r.line}:${r.character} [${r.source||""}${r.code?`:${r.code}`:""}] ${r.message}`)}return t.join(`
|
|
771
771
|
`)}case"hover":return e.hover?e.hover.contents:"No hover information available.";case"completions":{if(e.completions.length===0)return"No completions available.";let t=[`Completions (${e.completions.length}):`,""];for(let r of e.completions.slice(0,20))t.push(` [${r.kind}] ${r.label}${r.detail?` \u2014 ${r.detail}`:""}`);return e.completions.length>20&&t.push(` ... and ${e.completions.length-20} more`),t.join(`
|
|
@@ -774,20 +774,20 @@ ${s}`}],details:{type:"repl",error:r.error,duration:r.duration}}:{content:[{type
|
|
|
774
774
|
`)}case"codeActions":{if(e.actions.length===0)return"No code actions available.";let t=[`Available code actions (${e.actions.length}):`,""];for(let r of e.actions)t.push(` ${r.isPreferred?"\u2605":"-"} ${r.title}${r.kind?` [${r.kind}]`:""}`);return t.join(`
|
|
775
775
|
`)}default:return"Unknown result type."}}je();import{spawn as Cc}from"node:child_process";import{createInterface as Ws}from"node:readline";import{resolve as iP,join as Ir}from"node:path";import{createServer as aP}from"node:net";import{createWriteStream as cP,mkdirSync as lP}from"node:fs";import{tmpdir as dP}from"node:os";import{createInterface as Bx}from"node:readline";var Hx=1,qx=1,gt={USER_MESSAGE_CHUNK:"user_message_chunk",AGENT_MESSAGE_CHUNK:"agent_message_chunk",AGENT_THOUGHT_CHUNK:"agent_thought_chunk",TOOL_CALL:"tool_call",TOOL_CALL_UPDATE:"tool_call_update",PLAN:"plan",AVAILABLE_COMMANDS_UPDATE:"available_commands_update",CURRENT_MODE_UPDATE:"current_mode_update",CONFIG_OPTION_UPDATE:"config_option_update",SESSION_INFO_UPDATE:"session_info_update",USAGE_UPDATE:"usage_update"},Wx=1e4,un=class{pendingRpcs=new Map;rl=null;child=null;onNotification=null;hostHandler=null;attach(e,t,r){this.onNotification=t??null,this.hostHandler=r??null,this.child=e,this.rl=Bx({input:e.stdout,crlfDelay:Number.POSITIVE_INFINITY}),this.rl.on("line",s=>{let o=s.trim();if(!o)return;let i;try{i=JSON.parse(o)}catch{return}let a="id"in i&&(typeof i.id=="number"||typeof i.id=="string"),c="method"in i&&typeof i.method=="string";if(a&&!c){let l=this.pendingRpcs.get(i.id);if(l){clearTimeout(l.timer),this.pendingRpcs.delete(i.id);let d=i;d.error?l.reject(new Error(d.error.message)):l.resolve(d.result)}return}if(a&&c){this.handleAgentRequest(i.id,i.method,i.params);return}c&&!a&&this.onNotification?.(i.method,i.params)})}handleAgentRequest(e,t,r){let s=(c,l)=>{if(!this.child?.stdin?.writable)return;let d={jsonrpc:"2.0",id:e};l?d.error=l:d.result=c??{};try{this.child.stdin.write(`${JSON.stringify(d)}
|
|
776
776
|
`)}catch{}},o=this.hostHandler,i=r;(async()=>{switch(t){case"fs/read_text_file":return o?.readTextFile?.(i)??{};case"fs/write_text_file":return o?.writeTextFile?.(i)??{};case"session/request_permission":return o?.requestPermission?.(i??{})??{outcome:"cancelled"};case"session/elicitation":case"session/elicitation/complete":return o?.elicitation?.(i??{})??{};case"terminal/create":return o?.createTerminal?.(i??{})??{};case"terminal/output":return o?.terminalOutput?.(i??{})??{};case"terminal/release":return o?.releaseTerminal?.(i??{})??{};case"terminal/wait_for_exit":return o?.waitForTerminalExit?.(i??{})??{};case"terminal/kill":return o?.killTerminal?.(i??{})??{};default:if(o?.extMethod)return o.extMethod(t,r);throw new Error(`Method not found: ${t}`)}})().then(c=>s(c)).catch(c=>s(null,{code:-32601,message:c instanceof Error?c.message:String(c)}))}detach(){this.rl?.close(),this.rl=null,this.child=null,this.hostHandler=null;for(let[e,t]of this.pendingRpcs)clearTimeout(t.timer),t.reject(new Error("ACP adapter detached")),this.pendingRpcs.delete(e)}sendRpc(e,t,r,s=3e4){let o=Hx++,i={jsonrpc:"2.0",id:o,method:t,params:r};return new Promise((a,c)=>{let l=setTimeout(()=>{this.pendingRpcs.delete(o),c(new Error(`ACP RPC timeout: ${t} (${s}ms)`))},s);this.pendingRpcs.set(o,{resolve:a,reject:c,timer:l});try{e.stdin.write(`${JSON.stringify(i)}
|
|
777
|
-
`)}catch(d){clearTimeout(l),this.pendingRpcs.delete(o),c(d instanceof Error?d:new Error(String(d)))}})}async initialize(e){let t=await this.sendRpc(e,"initialize",{protocolVersion:qx,clientInfo:{name:"qlogicagent",version:"1.0.0"},clientCapabilities:{fs:{readTextFile:!0,writeTextFile:!0},terminal:!0,auth:{terminal:!1}}},Wx),r=t?.agentCapabilities??{};return{protocolVersion:typeof t?.protocolVersion=="number"?t.protocolVersion:0,agentCapabilities:{loadSession:r.loadSession===!0,mcpCapabilities:r.mcpCapabilities,promptCapabilities:r.promptCapabilities,sessionCapabilities:r.sessionCapabilities},agentInfo:t?.agentInfo,authMethods:t?.authMethods}}async createSession(e,t){let r={cwd:t.cwd,mcpServers:t.mcpServers??[]};t.additionalDirectories?.length&&(r.additionalDirectories=t.additionalDirectories),t.systemPrompt&&(r.systemPrompt=t.systemPrompt);let s=await this.sendRpc(e,"session/new",r);if(typeof s?.sessionId!="string")throw new Error("ACP session/new: agent did not return sessionId");return{sessionId:s.sessionId}}async sendPrompt(e,t,r,s=3e5){let o=await this.sendRpc(e,"session/prompt",{sessionId:t,prompt:[{type:"text",text:r}]},s);return{stopReason:o?.stopReason??"end_turn",usage:o?.usage,userMessageId:o?.userMessageId}}async resumeSession(e,t,r){let s={sessionId:t,cwd:r?.cwd??process.cwd(),mcpServers:r?.mcpServers??[]},o=await this.sendRpc(e,"session/load",s,3e4);if(typeof o?.sessionId!="string")throw new Error("ACP session/load: agent did not return sessionId");return{sessionId:o.sessionId}}async closeSession(e,t){try{await this.sendRpc(e,"session/close",{sessionId:t},5e3)}catch{}}static translateNotification(e,t){let r=t;if(e==="session/update"){if(!r)return null;let s=r.update;if(!s)return null;let o=s.sessionUpdate,i=r.sessionId;switch(o){case gt.AGENT_MESSAGE_CHUNK:{let a=s.content;return{method:"turn.delta",params:{text:a?.text??a?.content??"",sessionId:i,messageId:s.messageId}}}case gt.AGENT_THOUGHT_CHUNK:return{method:"turn.thought_delta",params:{text:s.content?.text??"",sessionId:i}};case gt.TOOL_CALL:return{method:"turn.tool_call",params:{callId:s.toolCallId,toolName:s.title,status:s.status??"running",content:s.content,kind:s.kind,rawInput:s.rawInput,sessionId:i}};case gt.TOOL_CALL_UPDATE:return{method:"turn.tool_result",params:{callId:s.toolCallId,toolName:s.title,status:s.status??"completed",content:s.content,rawOutput:s.rawOutput,sessionId:i}};case gt.USAGE_UPDATE:return{method:"turn.usage_update",params:s??{}};case gt.PLAN:return{method:"turn.plan",params:{steps:s.steps,sessionId:i}};case gt.AVAILABLE_COMMANDS_UPDATE:case gt.CURRENT_MODE_UPDATE:case gt.CONFIG_OPTION_UPDATE:case gt.SESSION_INFO_UPDATE:return{method:"turn.session_info",params:{type:o,...s,sessionId:i}};case gt.USER_MESSAGE_CHUNK:return null;default:return{method:`turn.${o??"unknown"}`,params:{...s,sessionId:i}}}}return null}};var Rr=class{usage={inputTokens:0,outputTokens:0,totalTokens:0,cachedReadTokens:0,thoughtTokens:0,cost:0,hasTier1:!1,turnCount:0};onUsageUpdate(e){this.usage.hasTier1=!0,typeof e.inputTokens=="number"&&(this.usage.inputTokens+=e.inputTokens),typeof e.outputTokens=="number"&&(this.usage.outputTokens+=e.outputTokens),typeof e.totalTokens=="number"&&(this.usage.totalTokens+=e.totalTokens),typeof e.cost=="number"&&(this.usage.cost+=e.cost)}onPromptResponseUsage(e){e&&(this.usage.hasTier1||(this.usage.turnCount++,typeof e.inputTokens=="number"&&(this.usage.inputTokens+=e.inputTokens),typeof e.outputTokens=="number"&&(this.usage.outputTokens+=e.outputTokens),typeof e.totalTokens=="number"&&(this.usage.totalTokens+=e.totalTokens),typeof e.cachedReadTokens=="number"&&(this.usage.cachedReadTokens+=e.cachedReadTokens),typeof e.thoughtTokens=="number"&&(this.usage.thoughtTokens+=e.thoughtTokens)))}getUsage(){return{...this.usage}}reset(){this.usage={inputTokens:0,outputTokens:0,totalTokens:0,cachedReadTokens:0,thoughtTokens:0,cost:0,hasTier1:!1,turnCount:0}}hasData(){return this.usage.hasTier1||this.usage.turnCount>0}};import{execSync as hg}from"node:child_process";import{existsSync as yg,readdirSync as Gx}from"node:fs";import{homedir as Kx,platform as Vx}from"node:os";import{join as Ar}from"node:path";var wc={claude:{id:"claude",name:"Claude Code",cliCommand:"claude",acpArgs:["--experimental-acp"],authRequired:!0,skillsDirs:[".claude/skills"],supportsBaseUrlOverride:!0,apiKeyEnvVar:"ANTHROPIC_API_KEY",baseUrlEnvVar:"ANTHROPIC_BASE_URL"},codex:{id:"codex",name:"OpenAI Codex CLI",cliCommand:"codex-acp",acpArgs:[],authRequired:!0,supportsBaseUrlOverride:!0,apiKeyEnvVar:"OPENAI_API_KEY",baseUrlEnvVar:"OPENAI_BASE_URL"},qwen:{id:"qwen",name:"Qwen Code",cliCommand:"qwen-code",acpArgs:["--acp","--experimental-skills"],defaultCliPath:"npx @qwen-code/qwen-code",authRequired:!0,skillsDirs:[".qwen/skills"],supportsBaseUrlOverride:!0,apiKeyEnvVar:"DASHSCOPE_API_KEY"},kimi:{id:"kimi",name:"Kimi CLI",cliCommand:"kimi",acpArgs:["acp"],authRequired:!1,skillsDirs:[".kimi/skills"],supportsBaseUrlOverride:!0},opencode:{id:"opencode",name:"OpenCode",cliCommand:"opencode",acpArgs:["acp"],authRequired:!1,skillsDirs:[".opencode/skills"],supportsBaseUrlOverride:!0},cursor:{id:"cursor",name:"Cursor Agent",cliCommand:"cursor-agent",acpArgs:["acp"],authRequired:!0,skillsDirs:[".cursor/skills"],supportsBaseUrlOverride:!1},hermes:{id:"hermes",name:"Hermes Agent",cliCommand:"hermes",acpArgs:["acp"],authRequired:!1,supportsBaseUrlOverride:!0},copilot:{id:"copilot",name:"GitHub Copilot",cliCommand:"copilot",acpArgs:["--acp"],authRequired:!0,supportsBaseUrlOverride:!1},codebuddy:{id:"codebuddy",name:"CodeBuddy",cliCommand:"codebuddy",acpArgs:["--acp"],authRequired:!0,skillsDirs:[".codebuddy/skills"],supportsBaseUrlOverride:!0},kiro:{id:"kiro",name:"Kiro CLI",cliCommand:"kiro-cli",acpArgs:["acp"],authRequired:!0,supportsBaseUrlOverride:!0},snow:{id:"snow",name:"Snow",cliCommand:"snow",acpArgs:["--acp"],authRequired:!0,supportsBaseUrlOverride:!0},qoder:{id:"qoder",name:"Qoder",cliCommand:"qodercli",acpArgs:["--acp"],authRequired:!0,supportsBaseUrlOverride:!0},gemini:{id:"gemini",name:"Gemini CLI",cliCommand:"gemini",acpArgs:["--acp"],defaultCliPath:"npx @google/gemini-cli",authRequired:!0,supportsBaseUrlOverride:!1},glm:{id:"glm",name:"GLM Agent",cliCommand:"glm-acp-agent",acpArgs:[],defaultCliPath:"npx glm-acp-agent",authRequired:!0,supportsBaseUrlOverride:!0,apiKeyEnvVar:"ZHIPU_API_KEY"},cline:{id:"cline",name:"Cline",cliCommand:"cline",acpArgs:["--acp"],defaultCliPath:"npx cline",authRequired:!0,supportsBaseUrlOverride:!0},nova:{id:"nova",name:"Nova",cliCommand:"nova",acpArgs:["acp"],defaultCliPath:"npx @compass-ai/nova",authRequired:!0,supportsBaseUrlOverride:!0},openclaw:{id:"openclaw",name:"OpenClaw",cliCommand:"openclaw",acpArgs:["--acp"],authRequired:!0,supportsBaseUrlOverride:!0,apiKeyEnvVar:"OPENCLAW_API_KEY",baseUrlEnvVar:"OPENCLAW_BASE_URL"}};var Pc=Vx()==="win32";function xc(n){try{let e=Pc?`where ${n}`:`which ${n}`;return hg(e,{encoding:"utf8",timeout:5e3,stdio:["pipe","pipe","pipe"]}).trim().split(/\r?\n/)[0]?.trim()||null}catch{return null}}function zx(n,e){let t=o=>{let i=o.match(/^(\d+)\.(\d+)\.(\d+)/);return i?[Number(i[1]),Number(i[2]),Number(i[3])]:[0,0,0]},r=t(n),s=t(e);for(let o=0;o<3;o+=1)if(r[o]!==s[o])return s[o]-r[o];return e.localeCompare(n)}function Xx(){if(!Pc)return null;let n=[process.env.COPILOT_CACHE_HOME?Ar(process.env.COPILOT_CACHE_HOME,"pkg","win32-x64"):null,process.env.LOCALAPPDATA?Ar(process.env.LOCALAPPDATA,"copilot","pkg","win32-x64"):null,process.env.COPILOT_HOME?Ar(process.env.COPILOT_HOME,"pkg","win32-x64"):null,Ar(Kx(),".copilot","pkg","win32-x64")].filter(e=>!!e);for(let e of n)try{let t=Gx(e,{withFileTypes:!0}).filter(r=>r.isDirectory()).map(r=>r.name).sort(zx);for(let r of t){let s=Ar(e,r,"npm-loader.js");if(yg(s))return s}}catch{}return null}function Yx(n){return n.id==="copilot"?Xx()??xc(n.cliCommand):xc(n.cliCommand)}function Jx(n){try{let e=n.endsWith("npm-loader.js")?`"${process.execPath}" "${n}" version`:`"${n}" version`;return hg(e,{encoding:"utf8",timeout:5e3,stdio:["pipe","pipe","pipe"]}).trim().match(/(\d+\.\d+[\w.-]*)/)?.[1]??null}catch{return null}}function Qx(n,e){if(!Pc)return{cliPath:n,acpArgs:e};if(n.endsWith("npm-loader.js")){let r=e.includes("--no-auto-update");return{cliPath:process.execPath,acpArgs:[n,...e,...r?[]:["--no-auto-update"]]}}let t=`${n}.ps1`;return yg(t)?{cliPath:"powershell.exe",acpArgs:["-NoProfile","-ExecutionPolicy","Bypass","-File",t,...e]}:{cliPath:n,acpArgs:e}}var Zx=6e4,Bs=class{cache=null;configStore=null;setConfigStore(e){this.configStore=e}scan(e=!1){if(!e&&this.cache&&Date.now()-this.cache.timestamp<Zx)return this.cache.agents;let t=[];for(let r of Object.values(wc))t.push(this.detectBackend(r));if(this.configStore?.customAgents)for(let r of Object.values(this.configStore.customAgents))t.push(this.detectCustomAgent(r));return this.cache={agents:t,timestamp:Date.now()},t}list(){return this.cache?this.cache.agents:this.scan()}clearCache(){this.cache=null}detectBackend(e){let t=Yx(e),r=this.hasAgentConfig(e.id);if(!t)return{id:e.id,name:e.name,category:"teammate",protocol:"acp",status:"not_installed",authRequired:e.authRequired,hasConfig:r,supportsBaseUrlOverride:e.supportsBaseUrlOverride,capabilities:{supportsMcp:!0,supportsResume:!1,supportsUsageUpdate:e.id==="claude"||e.id==="codex",skillsDirs:e.skillsDirs}};let s=Jx(t);return e.id==="copilot"&&!s?{id:e.id,name:e.name,category:"teammate",protocol:"acp",status:"not_installed",authRequired:e.authRequired,hasConfig:r,supportsBaseUrlOverride:e.supportsBaseUrlOverride,capabilities:{supportsMcp:!0,supportsResume:!1,supportsUsageUpdate:!1,skillsDirs:e.skillsDirs}}:{id:e.id,name:e.name,category:"teammate",protocol:"acp",status:"available",cliPath:t,version:s??void 0,authRequired:e.authRequired,hasConfig:r,supportsBaseUrlOverride:e.supportsBaseUrlOverride,capabilities:{supportsMcp:!0,supportsResume:e.id==="claude"||e.id==="goose"||e.id==="copilot",supportsUsageUpdate:e.id==="claude"||e.id==="codex"||e.id==="copilot",skillsDirs:e.skillsDirs}}}detectCustomAgent(e){let t=xc(e.cliCommand),r=this.hasAgentConfig(e.id);return{id:e.id,name:e.name,category:"teammate",protocol:"acp",status:t?"available":"not_installed",cliPath:t??void 0,authRequired:e.authRequired??!1,hasConfig:r,supportsBaseUrlOverride:e.supportsBaseUrlOverride??!1,capabilities:{supportsMcp:!0,supportsResume:!1,supportsUsageUpdate:!1,skillsDirs:e.skillsDirs}}}hasAgentConfig(e){if(!this.configStore)return!1;let t=this.configStore.agents[e];return!!(t?.apiKey||t?.baseUrl||t?.customCliPath)}buildExternalDescriptor(e){let t=this.list().find(i=>i.id===e);if(!t||t.protocol!=="acp"||t.status!=="available"||!t.cliPath)return null;let r=wc[e],s=this.configStore?.agents[e],o=s?.customCliPath?{cliPath:s.customCliPath,acpArgs:s?.customArgs??r?.acpArgs??[]}:Qx(t.cliPath,s?.customArgs??r?.acpArgs??[]);return{id:e,cliPath:o.cliPath,acpArgs:o.acpArgs,env:s?.env??r?.env,protocol:"acp"}}};var pn="1.0.0",v={PARSE_ERROR:-32700,INVALID_REQUEST:-32600,METHOD_NOT_FOUND:-32601,INVALID_PARAMS:-32602,INTERNAL_ERROR:-32603,TURN_ABORTED:-32e3,TURN_TIMEOUT:-32001,LLM_ERROR:-32010,LLM_AUTH_ERROR:-32011,LLM_RATE_LIMIT:-32012,LLM_QUOTA_EXHAUSTED:-32013,LLM_MODEL_NOT_FOUND:-32014,TOOL_INVOKE_FAILED:-32020,TOOL_TIMEOUT:-32021,PROTOCOL_MISMATCH:-32030,REQUEST_DEADLINE_EXCEEDED:-32040,REQUEST_CANCELLED:-32041,REQUEST_DEDUPED:-32042,REQUEST_IDEMPOTENCY_REQUIRED:-32043};function Ic(n){if(!n||typeof n!="object")return!1;let e=n;return e.jsonrpc==="2.0"&&typeof e.method=="string"&&e.method.length>0}import{randomUUID as eP}from"node:crypto";var tP=["settings.list","settings.get","settings.validate","provider.list","config.get","config.tunables","tools.list","todos.list","tasks.list","agents.list","agents.get","agents.processes","agents.scan","session.list","session.get","session.resolve","thread.list","project.list","files.list","files.gitStatus","instructions.list","instructions.read","skills.list","skills.stats","memory.atlas","memory.activity","memory.list","memory.read","memory.search","media.listModels","media.status","pet.status","agent.health","agent.metrics"],nP=new Set(["thread.turn","memory.dream","memory.propose","memory.consolidate","media.stt","pet.forge","solo.start","solo.evaluate","product.plan","product.create","product.message"]),rP=["memory.","pet.","usage."],sP=new Set(["memory.atlas","memory.activity","memory.list","memory.read","memory.search","pet.status"]);function Hs(n){return nP.has(n)?{channel:"task",mutability:"write",defaultTimeoutMs:n==="thread.turn"?3e5:12e4}:tP.some(e=>n===e||n.startsWith(`${e}.`)||n.startsWith(e))?{channel:"query",mutability:"read",defaultTimeoutMs:1e4}:{channel:"task",mutability:"write",defaultTimeoutMs:3e4}}function bg(n){return sP.has(n)||Hs(n).mutability==="read"?!1:rP.some(e=>n.startsWith(e))}function _c(n,e={}){let t=e.now??Date.now(),r=Hs(n),s=e.timeoutMs??r.defaultTimeoutMs;return{requestId:e.requestId??eP(),createdAt:t,deadlineAt:t+s,channel:e.channel??r.channel,idempotencyKey:e.idempotencyKey,traceId:e.traceId}}function qs(n,e=Date.now()){let t=n.meta;if(!t||typeof t!="object")return{ok:!1,error:{code:v.INVALID_REQUEST,message:"RPC request meta is required."}};if(typeof t.requestId!="string"||t.requestId.length===0)return{ok:!1,error:{code:v.INVALID_REQUEST,message:"RPC request meta.requestId is required."}};if(t.channel!=="query"&&t.channel!=="task")return{ok:!1,error:{code:v.INVALID_REQUEST,message:"RPC request meta.channel must be query or task."}};if(typeof t.createdAt!="number"||!Number.isFinite(t.createdAt))return{ok:!1,error:{code:v.INVALID_REQUEST,message:"RPC request meta.createdAt is required."}};if(typeof t.deadlineAt!="number"||!Number.isFinite(t.deadlineAt))return{ok:!1,error:{code:v.INVALID_REQUEST,message:"RPC request meta.deadlineAt is required."}};if(t.deadlineAt<=e)return{ok:!1,error:{code:v.REQUEST_DEADLINE_EXCEEDED,message:"RPC request deadline has already expired."}};let r=Hs(n.method).channel;return t.channel!==r?{ok:!1,error:{code:v.INVALID_REQUEST,message:`RPC request channel mismatch: expected ${r}, got ${t.channel}.`}}:bg(n.method)&&(typeof t.idempotencyKey!="string"||t.idempotencyKey.length===0)?{ok:!1,error:{code:v.REQUEST_IDEMPOTENCY_REQUIRED,message:`RPC method ${n.method} requires meta.idempotencyKey.`}}:{ok:!0,meta:t}}var wr=class{now;active=new Map;idempotency=new Map;counters={completedRequests:0,cancelledRequests:0,deadlineExceededRequests:0,dedupedRequests:0,lateResponsesDropped:0,invalidRequests:0};constructor(e={}){this.now=e.now??(()=>Date.now())}begin(e,t){let r=qs({method:e,meta:t},this.now());if(!r.ok)return this.counters.invalidRequests+=1,{status:"rejected",error:r.error};if(t.idempotencyKey){let s=this.idempotency.get(t.idempotencyKey);if(s)return this.counters.dedupedRequests+=1,s.error?{status:"deduped",error:s.error}:{status:"deduped",result:s.result}}return this.active.set(t.requestId,{method:e,meta:t,cancelled:!1,startedAt:this.now()}),{status:"started"}}cancel(e,t="cancelled"){let r=this.active.get(e);return!r||r.cancelled?!1:(r.cancelled=!0,r.cancelReason=t,this.counters.cancelledRequests+=1,!0)}expire(e){return this.active.get(e)?(this.active.delete(e),this.counters.deadlineExceededRequests+=1,!0):!1}settle(e,t,r){let s=this.active.get(e);return s?(this.active.delete(e),s.cancelled?(this.counters.lateResponsesDropped+=1,{accepted:!1,reason:"cancelled"}):s.meta.deadlineAt<=this.now()?(this.counters.deadlineExceededRequests+=1,this.counters.lateResponsesDropped+=1,{accepted:!1,reason:"deadline_exceeded"}):(this.counters.completedRequests+=1,s.meta.idempotencyKey&&this.idempotency.set(s.meta.idempotencyKey,{result:t,error:r,settledAt:this.now()}),{accepted:!0})):{accepted:!1,reason:"unknown"}}metrics(){return{activeRequests:this.active.size,...this.counters}}};var vg=["turn.start","turn.delta","turn.end","turn.error","turn.recovery","turn.tool_call","turn.tool_result","turn.tool_blocked","turn.reasoning_delta","turn.approval_request","turn.skill_instruction","turn.ask_user","turn.media_result","turn.media_progress","turn.plan_update","turn.suggestions","turn.sidechain_started","turn.subagent_delta","turn.sidechain_completed","turn.task_updated","turn.todos_updated","turn.exec_progress","turn.usage_update","team.member.notification","session.info","memory.updated","skills.updated","pet.soul_ready","pet.reaction","pet.growth","pet.state","pet.confirm","pet.forged","system.activity"],kg=["solo.progress","solo.agentDelta","solo.agentUsage","solo.agentDiff","solo.evaluation","product.taskStarted","product.taskOutput","product.taskCompleted","product.taskFailed","product.budgetUpdate","product.checkpointed","product.dagTopology","plan.interrupted"],oP=[...vg,...kg];var ft={INITIALIZE:"initialize",SESSION_NEW:"session/new",SESSION_PROMPT:"session/prompt",SESSION_END:"session/end",SESSION_SET_CONFIG:"session/set_config_option",SESSION_SET_MODEL:"session/set_model",SESSION_SET_MODE:"session/set_mode",SESSION_UPDATE:"session/update",SESSION_REQUEST_PERMISSION:"session/request_permission",FS_READ_TEXT_FILE:"fs/read_text_file",FS_WRITE_TEXT_FILE:"fs/write_text_file"},ye={ABORT:"x/abort",DREAM:"x/dream",AGENTS_LIST:"x/agents.list",SOLO_START:"x/solo.start",SOLO_STATUS:"x/solo.status",SOLO_SELECT:"x/solo.select",SOLO_CANCEL:"x/solo.cancel",PRODUCT_CREATE:"x/product.create",PRODUCT_PLAN:"x/product.plan",PRODUCT_CONFIRM:"x/product.confirm",PRODUCT_MESSAGE:"x/product.message",PRODUCT_RESUME:"x/product.resume",PRODUCT_PAUSE:"x/product.pause",PRODUCT_CANCEL:"x/product.cancel",PRODUCT_ROLLBACK:"x/product.rollback",PRODUCT_STATUS:"x/product.status",SOLO_SUBSCRIBE:"x/solo.subscribe",SOLO_MESSAGE:"x/solo.message",SOLO_EVALUATE:"x/solo.evaluate",PRODUCT_SUBSCRIBE:"x/product.subscribe",TEAM_DELEGATE:"x/team.delegate"},ht={AGENT_MESSAGE_CHUNK:"agent_message_chunk",AGENT_THOUGHT_CHUNK:"agent_thought_chunk",TOOL_CALL:"tool_call",TOOL_CALL_UPDATE:"tool_call_update",PLAN:"plan",USAGE_UPDATE:"usage_update",CONFIG_OPTION_UPDATE:"config_option_update",SESSION_INFO_UPDATE:"session_info_update",AVAILABLE_COMMANDS_UPDATE:"available_commands_update"},Te={X_SUBAGENT_STARTED:"x_subagent_started",X_SUBAGENT_DELTA:"x_subagent_delta",X_SUBAGENT_ENDED:"x_subagent_ended",X_MEDIA_RESULT:"x_media_result",X_MEDIA_PROGRESS:"x_media_progress",X_SKILL_INSTRUCTION:"x_skill_instruction",X_RECOVERY:"x_recovery",X_SIDECHAIN_STARTED:"x_sidechain_started",X_SIDECHAIN_COMPLETED:"x_sidechain_completed",X_SUGGESTIONS:"x_suggestions",X_ASK_USER:"x_ask_user",X_SESSION_INFO:"x_session_info",X_MEMORY_UPDATED:"x_memory_updated",X_TEAM_MEMBER_UPDATE:"x_team_member_update",X_SOLO_STARTED:"x_solo_started",X_SOLO_AGENT_FINISHED:"x_solo_agent_finished",X_SOLO_SELECTED:"x_solo_selected",X_PRODUCT_TASK_STARTED:"x_product_task_started",X_PRODUCT_TASK_COMPLETED:"x_product_task_completed",X_PRODUCT_CHECKPOINT:"x_product_checkpoint"};function xr(n){if(!n||typeof n!="object")return!1;let e=n;return e.jsonrpc==="2.0"&&typeof e.method=="string"&&"id"in e}function Pr(n){if(!n||typeof n!="object")return!1;let e=n;return e.jsonrpc==="2.0"&&typeof e.method=="string"&&!("id"in e)}function Ec(n){if(!n||typeof n!="object")return!1;let e=n;return e.jsonrpc==="2.0"&&"id"in e&&!("method"in e)}var Sg="openai-codex";var rL={anthropic:{providerFamily:"anthropic"},"amazon-bedrock":{providerFamily:"anthropic"},"kimi-coding":{anthropicToolSchemaMode:"openai-functions",anthropicToolChoiceMode:"openai-string-modes",preserveAnthropicThinkingSignatures:!1},mistral:{transcriptToolCallIdMode:"strict9",transcriptToolCallIdModelHints:["mistral","mixtral","codestral","pixtral","devstral","ministral","mistralai"]},openai:{providerFamily:"openai"},[Sg]:{providerFamily:"openai"},openrouter:{openAiCompatTurnValidation:!1,providerThoughtSignatureSanitization:!0,providerThoughtSignatureModelHints:["gemini"]},opencode:{openAiCompatTurnValidation:!1,providerThoughtSignatureSanitization:!0,providerThoughtSignatureModelHints:["gemini"]},kilocode:{providerThoughtSignatureSanitization:!0,providerThoughtSignatureModelHints:["gemini"]}};var uP=1;function pP(n,e){return{jsonrpc:"2.0",id:uP++,method:n,params:e,meta:_c(n)}}var mP=["NODE_ENV","HOME","PATH","TERM","OPENAI_API_KEY","OPENAI_BASE_URL","ANTHROPIC_API_KEY","ANTHROPIC_BASE_URL","HTTP_PROXY","HTTPS_PROXY","NO_PROXY","http_proxy","https_proxy","no_proxy"];function gP(n){let e={};for(let t of mP)process.env[t]&&(e[t]=process.env[t]);return n.apiKey&&(e.OPENAI_API_KEY=n.apiKey),n.baseUrl&&(e.OPENAI_BASE_URL=n.baseUrl),e.QLOGICAGENT_MEMBER_ID=n.memberId,e.QLOGICAGENT_MEMBER_NAME=n.name,n.agentType&&(e.QLOGICAGENT_AGENT_TYPE=n.agentType),n.model&&(e.QLOGICAGENT_MODEL=n.model),n.env&&Object.assign(e,n.env),e}var Mc=Ti,fP=Ri,Cn=Ai,Rg=wi;function hP(n){return new Promise(e=>setTimeout(e,n))}var _t=class n{processes=new Map;callbacks;cliBinaryPath;mcpBridgeScriptPath;constructor(e={}){this.callbacks=e;let t=iP(Ir(import.meta.url.startsWith("file://")?new URL(import.meta.url).pathname.replace(/^\/([A-Z]:)/,"$1"):process.cwd(),"..",".."));this.cliBinaryPath=Ir(t,"dist","cli.js"),this.mcpBridgeScriptPath=Ir(t,"dist","runtime","infra","mcp-bridge-server.js")}slog(e,t,r,s){let i=`[${new Date().toISOString()}] [${e}] [agent:${t}] [${r}] ${s}`;e==="warn"?this.callbacks.log?.warn(i):this.callbacks.log?.info(i)}async spawn(e){if(this.processes.has(e.memberId))throw new Error(`Agent process "${e.memberId}" already spawned`);let t=this.callbacks.log,r=gP(e),s={memberId:e.memberId,name:e.name,pid:-1,cwd:e.cwd,state:"starting",startedAt:Date.now()};if(e.external)return this.spawnAcpAgentWithRetry(e,s,r);let o=[this.cliBinaryPath];e.verbose&&o.push("--verbose"),this.slog("info",e.memberId,"spawn",`spawning ${e.name} in ${e.cwd}`);let i=Cc(process.execPath,o,{cwd:e.cwd,env:r,stdio:["pipe","pipe","pipe"],detached:!1});s.pid=i.pid??-1;let a=new Map;this.processes.set(e.memberId,{handle:s,child:i,pendingRpc:a}),Ws({input:i.stdout,crlfDelay:Number.POSITIVE_INFINITY}).on("line",l=>{let d=l.trim();if(d)try{let u=JSON.parse(d);if("id"in u&&typeof u.id=="number"){let p=a.get(u.id);if(p){clearTimeout(p.timer),a.delete(u.id);let m=u;m.error?p.reject(new Error(m.error.message)):p.resolve(m.result)}}if("method"in u&&!("id"in u)){let p=u;this.captureChildProgress(e.memberId,p.method,p.params),this.callbacks.onNotification?.(e.memberId,p.method,p.params)}}catch{this.slog("warn",e.memberId,"parse",`invalid JSON: ${d.slice(0,200)}`)}}),i.stderr&&Ws({input:i.stderr,crlfDelay:Number.POSITIVE_INFINITY}).on("line",d=>{this.callbacks.log?.debug?.(`[${new Date().toISOString()}] [debug] [agent:${e.memberId}] [stderr] ${d}`)}),i.on("exit",(l,d)=>{s.state!=="killed"&&(s.state=l===0?"completed":"failed"),s.endedAt=Date.now(),l!==0&&!s.error&&(s.error=`Process exited with code ${l} (signal: ${d})`);for(let[p,m]of a)clearTimeout(m.timer),m.reject(new Error(`Agent process exited (code=${l})`)),a.delete(p);this.callbacks.onStateChange?.(e.memberId,s.state),this.callbacks.onExit?.(e.memberId,l,d),this.slog("info",e.memberId,"exit",`exited (code=${l}, signal=${d})`)}),i.on("error",l=>{s.state="failed",s.error=l.message,s.endedAt=Date.now(),this.callbacks.onStateChange?.(e.memberId,"failed"),this.slog("warn",e.memberId,"error",l.message)}),this.callbacks.onStateChange?.(e.memberId,"starting");try{let l=await this.sendRpc(e.memberId,"initialize",{protocolVersion:"1.0",clientInfo:{name:"qlogicagent-team-leader",version:"1.0.0"}},15e3);s.state="ready",this.callbacks.onStateChange?.(e.memberId,"ready"),this.slog("info",e.memberId,"handshake",`initialized (pid=${s.pid})`);let d=l;d&&typeof d.sessionId=="string"&&(s.sessionId=d.sessionId)}catch(l){throw s.state="failed",s.error=`Initialize handshake failed: ${l instanceof Error?l.message:String(l)}`,s.endedAt=Date.now(),this.callbacks.onStateChange?.(e.memberId,"failed"),this.kill(e.memberId),new Error(s.error)}return s}async sendTask(e,t,r){let s=this.processes.get(e);if(!s)throw new Error(`No agent process: ${e}`);s.handle.state="running",this.callbacks.onStateChange?.(e,"running");try{let o;if(s.acpAdapter){let i=s.handle.sessionId??"default",a=await s.acpAdapter.sendPrompt(s.child,i,t,r?.timeout??3e5),c=s.handle.resultText??"";a.usage&&s.usageTracker&&s.usageTracker.onPromptResponseUsage(a.usage),o={content:c,stopReason:a.stopReason}}else{let i={content:t};r?.model&&(i.model=r.model),r?.apiKey&&(i.apiKey=r.apiKey),r?.baseUrl&&(i.baseUrl=r.baseUrl),r?.sessionId&&(i.sessionId=r.sessionId),o=await this.sendRpc(e,"thread.turn",i,r?.timeout??3e5);let a=o;a&&typeof a.content=="string"&&(s.handle.resultText=a.content)}return s.handle.state="completed",s.handle.endedAt=Date.now(),this.callbacks.onStateChange?.(e,"completed"),o}catch(o){throw s.handle.state="failed",s.handle.error=o instanceof Error?o.message:String(o),s.handle.endedAt=Date.now(),this.callbacks.onStateChange?.(e,"failed"),o}}async sendRpc(e,t,r,s=3e4){let o=this.processes.get(e);if(!o)throw new Error(`No agent process: ${e}`);let i=pP(t,r);return new Promise((a,c)=>{let l=setTimeout(()=>{o.pendingRpc.delete(i.id),c(new Error(`RPC timeout: ${t} (${s}ms)`))},s);o.pendingRpc.set(i.id,{resolve:a,reject:c,timer:l});try{o.child.stdin.write(`${JSON.stringify(i)}
|
|
777
|
+
`)}catch(d){clearTimeout(l),this.pendingRpcs.delete(o),c(d instanceof Error?d:new Error(String(d)))}})}async initialize(e){let t=await this.sendRpc(e,"initialize",{protocolVersion:qx,clientInfo:{name:"qlogicagent",version:"1.0.0"},clientCapabilities:{fs:{readTextFile:!0,writeTextFile:!0},terminal:!0,auth:{terminal:!1}}},Wx),r=t?.agentCapabilities??{};return{protocolVersion:typeof t?.protocolVersion=="number"?t.protocolVersion:0,agentCapabilities:{loadSession:r.loadSession===!0,mcpCapabilities:r.mcpCapabilities,promptCapabilities:r.promptCapabilities,sessionCapabilities:r.sessionCapabilities},agentInfo:t?.agentInfo,authMethods:t?.authMethods}}async createSession(e,t){let r={cwd:t.cwd,mcpServers:t.mcpServers??[]};t.additionalDirectories?.length&&(r.additionalDirectories=t.additionalDirectories),t.systemPrompt&&(r.systemPrompt=t.systemPrompt);let s=await this.sendRpc(e,"session/new",r);if(typeof s?.sessionId!="string")throw new Error("ACP session/new: agent did not return sessionId");return{sessionId:s.sessionId}}async sendPrompt(e,t,r,s=3e5){let o=await this.sendRpc(e,"session/prompt",{sessionId:t,prompt:[{type:"text",text:r}]},s);return{stopReason:o?.stopReason??"end_turn",usage:o?.usage,userMessageId:o?.userMessageId}}async resumeSession(e,t,r){let s={sessionId:t,cwd:r?.cwd??process.cwd(),mcpServers:r?.mcpServers??[]},o=await this.sendRpc(e,"session/load",s,3e4);if(typeof o?.sessionId!="string")throw new Error("ACP session/load: agent did not return sessionId");return{sessionId:o.sessionId}}async closeSession(e,t){try{await this.sendRpc(e,"session/close",{sessionId:t},5e3)}catch{}}static translateNotification(e,t){let r=t;if(e==="session/update"){if(!r)return null;let s=r.update;if(!s)return null;let o=s.sessionUpdate,i=r.sessionId;switch(o){case gt.AGENT_MESSAGE_CHUNK:{let a=s.content;return{method:"turn.delta",params:{text:a?.text??a?.content??"",sessionId:i,messageId:s.messageId}}}case gt.AGENT_THOUGHT_CHUNK:return{method:"turn.thought_delta",params:{text:s.content?.text??"",sessionId:i}};case gt.TOOL_CALL:return{method:"turn.tool_call",params:{callId:s.toolCallId,toolName:s.title,status:s.status??"running",content:s.content,kind:s.kind,rawInput:s.rawInput,sessionId:i}};case gt.TOOL_CALL_UPDATE:return{method:"turn.tool_result",params:{callId:s.toolCallId,toolName:s.title,status:s.status??"completed",content:s.content,rawOutput:s.rawOutput,sessionId:i}};case gt.USAGE_UPDATE:return{method:"turn.usage_update",params:s??{}};case gt.PLAN:return{method:"turn.plan",params:{steps:s.steps,sessionId:i}};case gt.AVAILABLE_COMMANDS_UPDATE:case gt.CURRENT_MODE_UPDATE:case gt.CONFIG_OPTION_UPDATE:case gt.SESSION_INFO_UPDATE:return{method:"turn.session_info",params:{type:o,...s,sessionId:i}};case gt.USER_MESSAGE_CHUNK:return null;default:return{method:`turn.${o??"unknown"}`,params:{...s,sessionId:i}}}}return null}};var Rr=class{usage={inputTokens:0,outputTokens:0,totalTokens:0,cachedReadTokens:0,thoughtTokens:0,cost:0,hasTier1:!1,turnCount:0};onUsageUpdate(e){this.usage.hasTier1=!0,typeof e.inputTokens=="number"&&(this.usage.inputTokens+=e.inputTokens),typeof e.outputTokens=="number"&&(this.usage.outputTokens+=e.outputTokens),typeof e.totalTokens=="number"&&(this.usage.totalTokens+=e.totalTokens),typeof e.cost=="number"&&(this.usage.cost+=e.cost)}onPromptResponseUsage(e){e&&(this.usage.hasTier1||(this.usage.turnCount++,typeof e.inputTokens=="number"&&(this.usage.inputTokens+=e.inputTokens),typeof e.outputTokens=="number"&&(this.usage.outputTokens+=e.outputTokens),typeof e.totalTokens=="number"&&(this.usage.totalTokens+=e.totalTokens),typeof e.cachedReadTokens=="number"&&(this.usage.cachedReadTokens+=e.cachedReadTokens),typeof e.thoughtTokens=="number"&&(this.usage.thoughtTokens+=e.thoughtTokens)))}getUsage(){return{...this.usage}}reset(){this.usage={inputTokens:0,outputTokens:0,totalTokens:0,cachedReadTokens:0,thoughtTokens:0,cost:0,hasTier1:!1,turnCount:0}}hasData(){return this.usage.hasTier1||this.usage.turnCount>0}};import{execSync as yg}from"node:child_process";import{existsSync as bg,readdirSync as Gx}from"node:fs";import{homedir as Kx,platform as Vx}from"node:os";import{join as Ar}from"node:path";var wc={claude:{id:"claude",name:"Claude Code",cliCommand:"claude",acpArgs:["--experimental-acp"],authRequired:!0,skillsDirs:[".claude/skills"],supportsBaseUrlOverride:!0,apiKeyEnvVar:"ANTHROPIC_API_KEY",baseUrlEnvVar:"ANTHROPIC_BASE_URL"},codex:{id:"codex",name:"OpenAI Codex CLI",cliCommand:"codex-acp",acpArgs:[],authRequired:!0,supportsBaseUrlOverride:!0,apiKeyEnvVar:"OPENAI_API_KEY",baseUrlEnvVar:"OPENAI_BASE_URL"},qwen:{id:"qwen",name:"Qwen Code",cliCommand:"qwen-code",acpArgs:["--acp","--experimental-skills"],defaultCliPath:"npx @qwen-code/qwen-code",authRequired:!0,skillsDirs:[".qwen/skills"],supportsBaseUrlOverride:!0,apiKeyEnvVar:"DASHSCOPE_API_KEY"},kimi:{id:"kimi",name:"Kimi CLI",cliCommand:"kimi",acpArgs:["acp"],authRequired:!1,skillsDirs:[".kimi/skills"],supportsBaseUrlOverride:!0},opencode:{id:"opencode",name:"OpenCode",cliCommand:"opencode",acpArgs:["acp"],authRequired:!1,skillsDirs:[".opencode/skills"],supportsBaseUrlOverride:!0},cursor:{id:"cursor",name:"Cursor Agent",cliCommand:"cursor-agent",acpArgs:["acp"],authRequired:!0,skillsDirs:[".cursor/skills"],supportsBaseUrlOverride:!1},hermes:{id:"hermes",name:"Hermes Agent",cliCommand:"hermes",acpArgs:["acp"],authRequired:!1,supportsBaseUrlOverride:!0},copilot:{id:"copilot",name:"GitHub Copilot",cliCommand:"copilot",acpArgs:["--acp"],authRequired:!0,supportsBaseUrlOverride:!1},codebuddy:{id:"codebuddy",name:"CodeBuddy",cliCommand:"codebuddy",acpArgs:["--acp"],authRequired:!0,skillsDirs:[".codebuddy/skills"],supportsBaseUrlOverride:!0},kiro:{id:"kiro",name:"Kiro CLI",cliCommand:"kiro-cli",acpArgs:["acp"],authRequired:!0,supportsBaseUrlOverride:!0},snow:{id:"snow",name:"Snow",cliCommand:"snow",acpArgs:["--acp"],authRequired:!0,supportsBaseUrlOverride:!0},qoder:{id:"qoder",name:"Qoder",cliCommand:"qodercli",acpArgs:["--acp"],authRequired:!0,supportsBaseUrlOverride:!0},gemini:{id:"gemini",name:"Gemini CLI",cliCommand:"gemini",acpArgs:["--acp"],defaultCliPath:"npx @google/gemini-cli",authRequired:!0,supportsBaseUrlOverride:!1},glm:{id:"glm",name:"GLM Agent",cliCommand:"glm-acp-agent",acpArgs:[],defaultCliPath:"npx glm-acp-agent",authRequired:!0,supportsBaseUrlOverride:!0,apiKeyEnvVar:"ZHIPU_API_KEY"},cline:{id:"cline",name:"Cline",cliCommand:"cline",acpArgs:["--acp"],defaultCliPath:"npx cline",authRequired:!0,supportsBaseUrlOverride:!0},nova:{id:"nova",name:"Nova",cliCommand:"nova",acpArgs:["acp"],defaultCliPath:"npx @compass-ai/nova",authRequired:!0,supportsBaseUrlOverride:!0},openclaw:{id:"openclaw",name:"OpenClaw",cliCommand:"openclaw",acpArgs:["--acp"],authRequired:!0,supportsBaseUrlOverride:!0,apiKeyEnvVar:"OPENCLAW_API_KEY",baseUrlEnvVar:"OPENCLAW_BASE_URL"}};var Pc=Vx()==="win32";function xc(n){try{let e=Pc?`where ${n}`:`which ${n}`;return yg(e,{encoding:"utf8",timeout:5e3,stdio:["pipe","pipe","pipe"]}).trim().split(/\r?\n/)[0]?.trim()||null}catch{return null}}function zx(n,e){let t=o=>{let i=o.match(/^(\d+)\.(\d+)\.(\d+)/);return i?[Number(i[1]),Number(i[2]),Number(i[3])]:[0,0,0]},r=t(n),s=t(e);for(let o=0;o<3;o+=1)if(r[o]!==s[o])return s[o]-r[o];return e.localeCompare(n)}function Xx(){if(!Pc)return null;let n=[process.env.COPILOT_CACHE_HOME?Ar(process.env.COPILOT_CACHE_HOME,"pkg","win32-x64"):null,process.env.LOCALAPPDATA?Ar(process.env.LOCALAPPDATA,"copilot","pkg","win32-x64"):null,process.env.COPILOT_HOME?Ar(process.env.COPILOT_HOME,"pkg","win32-x64"):null,Ar(Kx(),".copilot","pkg","win32-x64")].filter(e=>!!e);for(let e of n)try{let t=Gx(e,{withFileTypes:!0}).filter(r=>r.isDirectory()).map(r=>r.name).sort(zx);for(let r of t){let s=Ar(e,r,"npm-loader.js");if(bg(s))return s}}catch{}return null}function Yx(n){return n.id==="copilot"?Xx()??xc(n.cliCommand):xc(n.cliCommand)}function Jx(n){try{let e=n.endsWith("npm-loader.js")?`"${process.execPath}" "${n}" version`:`"${n}" version`;return yg(e,{encoding:"utf8",timeout:5e3,stdio:["pipe","pipe","pipe"]}).trim().match(/(\d+\.\d+[\w.-]*)/)?.[1]??null}catch{return null}}function Qx(n,e){if(!Pc)return{cliPath:n,acpArgs:e};if(n.endsWith("npm-loader.js")){let r=e.includes("--no-auto-update");return{cliPath:process.execPath,acpArgs:[n,...e,...r?[]:["--no-auto-update"]]}}let t=`${n}.ps1`;return bg(t)?{cliPath:"powershell.exe",acpArgs:["-NoProfile","-ExecutionPolicy","Bypass","-File",t,...e]}:{cliPath:n,acpArgs:e}}var Zx=6e4,Bs=class{cache=null;configStore=null;setConfigStore(e){this.configStore=e}scan(e=!1){if(!e&&this.cache&&Date.now()-this.cache.timestamp<Zx)return this.cache.agents;let t=[];for(let r of Object.values(wc))t.push(this.detectBackend(r));if(this.configStore?.customAgents)for(let r of Object.values(this.configStore.customAgents))t.push(this.detectCustomAgent(r));return this.cache={agents:t,timestamp:Date.now()},t}list(){return this.cache?this.cache.agents:this.scan()}clearCache(){this.cache=null}detectBackend(e){let t=Yx(e),r=this.hasAgentConfig(e.id);if(!t)return{id:e.id,name:e.name,category:"teammate",protocol:"acp",status:"not_installed",authRequired:e.authRequired,hasConfig:r,supportsBaseUrlOverride:e.supportsBaseUrlOverride,capabilities:{supportsMcp:!0,supportsResume:!1,supportsUsageUpdate:e.id==="claude"||e.id==="codex",skillsDirs:e.skillsDirs}};let s=Jx(t);return e.id==="copilot"&&!s?{id:e.id,name:e.name,category:"teammate",protocol:"acp",status:"not_installed",authRequired:e.authRequired,hasConfig:r,supportsBaseUrlOverride:e.supportsBaseUrlOverride,capabilities:{supportsMcp:!0,supportsResume:!1,supportsUsageUpdate:!1,skillsDirs:e.skillsDirs}}:{id:e.id,name:e.name,category:"teammate",protocol:"acp",status:"available",cliPath:t,version:s??void 0,authRequired:e.authRequired,hasConfig:r,supportsBaseUrlOverride:e.supportsBaseUrlOverride,capabilities:{supportsMcp:!0,supportsResume:e.id==="claude"||e.id==="goose"||e.id==="copilot",supportsUsageUpdate:e.id==="claude"||e.id==="codex"||e.id==="copilot",skillsDirs:e.skillsDirs}}}detectCustomAgent(e){let t=xc(e.cliCommand),r=this.hasAgentConfig(e.id);return{id:e.id,name:e.name,category:"teammate",protocol:"acp",status:t?"available":"not_installed",cliPath:t??void 0,authRequired:e.authRequired??!1,hasConfig:r,supportsBaseUrlOverride:e.supportsBaseUrlOverride??!1,capabilities:{supportsMcp:!0,supportsResume:!1,supportsUsageUpdate:!1,skillsDirs:e.skillsDirs}}}hasAgentConfig(e){if(!this.configStore)return!1;let t=this.configStore.agents[e];return!!(t?.apiKey||t?.baseUrl||t?.customCliPath)}buildExternalDescriptor(e){let t=this.list().find(i=>i.id===e);if(!t||t.protocol!=="acp"||t.status!=="available"||!t.cliPath)return null;let r=wc[e],s=this.configStore?.agents[e],o=s?.customCliPath?{cliPath:s.customCliPath,acpArgs:s?.customArgs??r?.acpArgs??[]}:Qx(t.cliPath,s?.customArgs??r?.acpArgs??[]);return{id:e,cliPath:o.cliPath,acpArgs:o.acpArgs,env:s?.env??r?.env,protocol:"acp"}}};var pn="1.0.0",v={PARSE_ERROR:-32700,INVALID_REQUEST:-32600,METHOD_NOT_FOUND:-32601,INVALID_PARAMS:-32602,INTERNAL_ERROR:-32603,TURN_ABORTED:-32e3,TURN_TIMEOUT:-32001,LLM_ERROR:-32010,LLM_AUTH_ERROR:-32011,LLM_RATE_LIMIT:-32012,LLM_QUOTA_EXHAUSTED:-32013,LLM_MODEL_NOT_FOUND:-32014,TOOL_INVOKE_FAILED:-32020,TOOL_TIMEOUT:-32021,PROTOCOL_MISMATCH:-32030,REQUEST_DEADLINE_EXCEEDED:-32040,REQUEST_CANCELLED:-32041,REQUEST_DEDUPED:-32042,REQUEST_IDEMPOTENCY_REQUIRED:-32043};function Ic(n){if(!n||typeof n!="object")return!1;let e=n;return e.jsonrpc==="2.0"&&typeof e.method=="string"&&e.method.length>0}import{randomUUID as eP}from"node:crypto";var tP=["settings.list","settings.get","settings.validate","provider.list","config.get","config.tunables","tools.list","todos.list","tasks.list","agents.list","agents.get","agents.processes","agents.scan","session.list","session.get","session.resolve","thread.list","project.list","files.list","files.gitStatus","instructions.list","instructions.read","skills.list","skills.stats","memory.atlas","memory.activity","memory.list","memory.read","memory.search","media.listModels","media.status","pet.status","agent.health","agent.metrics"],nP=new Set(["thread.turn","memory.dream","memory.propose","memory.consolidate","media.stt","pet.forge","solo.start","solo.evaluate","product.plan","product.create","product.message"]),rP=["memory.","pet.","usage."],sP=new Set(["memory.atlas","memory.activity","memory.list","memory.read","memory.search","pet.status"]);function Hs(n){return nP.has(n)?{channel:"task",mutability:"write",defaultTimeoutMs:n==="thread.turn"?3e5:12e4}:tP.some(e=>n===e||n.startsWith(`${e}.`)||n.startsWith(e))?{channel:"query",mutability:"read",defaultTimeoutMs:1e4}:{channel:"task",mutability:"write",defaultTimeoutMs:3e4}}function vg(n){return sP.has(n)||Hs(n).mutability==="read"?!1:rP.some(e=>n.startsWith(e))}function _c(n,e={}){let t=e.now??Date.now(),r=Hs(n),s=e.timeoutMs??r.defaultTimeoutMs;return{requestId:e.requestId??eP(),createdAt:t,deadlineAt:t+s,channel:e.channel??r.channel,idempotencyKey:e.idempotencyKey,traceId:e.traceId}}function qs(n,e=Date.now()){let t=n.meta;if(!t||typeof t!="object")return{ok:!1,error:{code:v.INVALID_REQUEST,message:"RPC request meta is required."}};if(typeof t.requestId!="string"||t.requestId.length===0)return{ok:!1,error:{code:v.INVALID_REQUEST,message:"RPC request meta.requestId is required."}};if(t.channel!=="query"&&t.channel!=="task")return{ok:!1,error:{code:v.INVALID_REQUEST,message:"RPC request meta.channel must be query or task."}};if(typeof t.createdAt!="number"||!Number.isFinite(t.createdAt))return{ok:!1,error:{code:v.INVALID_REQUEST,message:"RPC request meta.createdAt is required."}};if(typeof t.deadlineAt!="number"||!Number.isFinite(t.deadlineAt))return{ok:!1,error:{code:v.INVALID_REQUEST,message:"RPC request meta.deadlineAt is required."}};if(t.deadlineAt<=e)return{ok:!1,error:{code:v.REQUEST_DEADLINE_EXCEEDED,message:"RPC request deadline has already expired."}};let r=Hs(n.method).channel;return t.channel!==r?{ok:!1,error:{code:v.INVALID_REQUEST,message:`RPC request channel mismatch: expected ${r}, got ${t.channel}.`}}:vg(n.method)&&(typeof t.idempotencyKey!="string"||t.idempotencyKey.length===0)?{ok:!1,error:{code:v.REQUEST_IDEMPOTENCY_REQUIRED,message:`RPC method ${n.method} requires meta.idempotencyKey.`}}:{ok:!0,meta:t}}var wr=class{now;active=new Map;idempotency=new Map;counters={completedRequests:0,cancelledRequests:0,deadlineExceededRequests:0,dedupedRequests:0,lateResponsesDropped:0,invalidRequests:0};constructor(e={}){this.now=e.now??(()=>Date.now())}begin(e,t){let r=qs({method:e,meta:t},this.now());if(!r.ok)return this.counters.invalidRequests+=1,{status:"rejected",error:r.error};if(t.idempotencyKey){let s=this.idempotency.get(t.idempotencyKey);if(s)return this.counters.dedupedRequests+=1,s.error?{status:"deduped",error:s.error}:{status:"deduped",result:s.result}}return this.active.set(t.requestId,{method:e,meta:t,cancelled:!1,startedAt:this.now()}),{status:"started"}}cancel(e,t="cancelled"){let r=this.active.get(e);return!r||r.cancelled?!1:(r.cancelled=!0,r.cancelReason=t,this.counters.cancelledRequests+=1,!0)}expire(e){return this.active.get(e)?(this.active.delete(e),this.counters.deadlineExceededRequests+=1,!0):!1}settle(e,t,r){let s=this.active.get(e);return s?(this.active.delete(e),s.cancelled?(this.counters.lateResponsesDropped+=1,{accepted:!1,reason:"cancelled"}):s.meta.deadlineAt<=this.now()?(this.counters.deadlineExceededRequests+=1,this.counters.lateResponsesDropped+=1,{accepted:!1,reason:"deadline_exceeded"}):(this.counters.completedRequests+=1,s.meta.idempotencyKey&&this.idempotency.set(s.meta.idempotencyKey,{result:t,error:r,settledAt:this.now()}),{accepted:!0})):{accepted:!1,reason:"unknown"}}metrics(){return{activeRequests:this.active.size,...this.counters}}};var kg=["turn.start","turn.delta","turn.end","turn.error","turn.recovery","turn.tool_call","turn.tool_result","turn.tool_blocked","turn.reasoning_delta","turn.approval_request","turn.skill_instruction","turn.ask_user","turn.media_result","turn.media_progress","turn.plan_update","turn.suggestions","turn.sidechain_started","turn.subagent_delta","turn.sidechain_completed","turn.task_updated","turn.todos_updated","turn.exec_progress","turn.usage_update","team.member.notification","session.info","memory.updated","skills.updated","pet.soul_ready","pet.reaction","pet.growth","pet.state","pet.confirm","pet.forged","system.activity"],Sg=["solo.progress","solo.agentDelta","solo.agentUsage","solo.agentDiff","solo.evaluation","product.taskStarted","product.taskOutput","product.taskCompleted","product.taskFailed","product.budgetUpdate","product.checkpointed","product.dagTopology","plan.interrupted"],oP=[...kg,...Sg];var ft={INITIALIZE:"initialize",SESSION_NEW:"session/new",SESSION_PROMPT:"session/prompt",SESSION_END:"session/end",SESSION_SET_CONFIG:"session/set_config_option",SESSION_SET_MODEL:"session/set_model",SESSION_SET_MODE:"session/set_mode",SESSION_UPDATE:"session/update",SESSION_REQUEST_PERMISSION:"session/request_permission",FS_READ_TEXT_FILE:"fs/read_text_file",FS_WRITE_TEXT_FILE:"fs/write_text_file"},ye={ABORT:"x/abort",DREAM:"x/dream",AGENTS_LIST:"x/agents.list",SOLO_START:"x/solo.start",SOLO_STATUS:"x/solo.status",SOLO_SELECT:"x/solo.select",SOLO_CANCEL:"x/solo.cancel",PRODUCT_CREATE:"x/product.create",PRODUCT_PLAN:"x/product.plan",PRODUCT_CONFIRM:"x/product.confirm",PRODUCT_MESSAGE:"x/product.message",PRODUCT_RESUME:"x/product.resume",PRODUCT_PAUSE:"x/product.pause",PRODUCT_CANCEL:"x/product.cancel",PRODUCT_ROLLBACK:"x/product.rollback",PRODUCT_STATUS:"x/product.status",SOLO_SUBSCRIBE:"x/solo.subscribe",SOLO_MESSAGE:"x/solo.message",SOLO_EVALUATE:"x/solo.evaluate",PRODUCT_SUBSCRIBE:"x/product.subscribe",TEAM_DELEGATE:"x/team.delegate"},ht={AGENT_MESSAGE_CHUNK:"agent_message_chunk",AGENT_THOUGHT_CHUNK:"agent_thought_chunk",TOOL_CALL:"tool_call",TOOL_CALL_UPDATE:"tool_call_update",PLAN:"plan",USAGE_UPDATE:"usage_update",CONFIG_OPTION_UPDATE:"config_option_update",SESSION_INFO_UPDATE:"session_info_update",AVAILABLE_COMMANDS_UPDATE:"available_commands_update"},Te={X_SUBAGENT_STARTED:"x_subagent_started",X_SUBAGENT_DELTA:"x_subagent_delta",X_SUBAGENT_ENDED:"x_subagent_ended",X_MEDIA_RESULT:"x_media_result",X_MEDIA_PROGRESS:"x_media_progress",X_SKILL_INSTRUCTION:"x_skill_instruction",X_RECOVERY:"x_recovery",X_SIDECHAIN_STARTED:"x_sidechain_started",X_SIDECHAIN_COMPLETED:"x_sidechain_completed",X_SUGGESTIONS:"x_suggestions",X_ASK_USER:"x_ask_user",X_SESSION_INFO:"x_session_info",X_MEMORY_UPDATED:"x_memory_updated",X_TEAM_MEMBER_UPDATE:"x_team_member_update",X_SOLO_STARTED:"x_solo_started",X_SOLO_AGENT_FINISHED:"x_solo_agent_finished",X_SOLO_SELECTED:"x_solo_selected",X_PRODUCT_TASK_STARTED:"x_product_task_started",X_PRODUCT_TASK_COMPLETED:"x_product_task_completed",X_PRODUCT_CHECKPOINT:"x_product_checkpoint"};function xr(n){if(!n||typeof n!="object")return!1;let e=n;return e.jsonrpc==="2.0"&&typeof e.method=="string"&&"id"in e}function Pr(n){if(!n||typeof n!="object")return!1;let e=n;return e.jsonrpc==="2.0"&&typeof e.method=="string"&&!("id"in e)}function Ec(n){if(!n||typeof n!="object")return!1;let e=n;return e.jsonrpc==="2.0"&&"id"in e&&!("method"in e)}var Tg="openai-codex";var rL={anthropic:{providerFamily:"anthropic"},"amazon-bedrock":{providerFamily:"anthropic"},"kimi-coding":{anthropicToolSchemaMode:"openai-functions",anthropicToolChoiceMode:"openai-string-modes",preserveAnthropicThinkingSignatures:!1},mistral:{transcriptToolCallIdMode:"strict9",transcriptToolCallIdModelHints:["mistral","mixtral","codestral","pixtral","devstral","ministral","mistralai"]},openai:{providerFamily:"openai"},[Tg]:{providerFamily:"openai"},openrouter:{openAiCompatTurnValidation:!1,providerThoughtSignatureSanitization:!0,providerThoughtSignatureModelHints:["gemini"]},opencode:{openAiCompatTurnValidation:!1,providerThoughtSignatureSanitization:!0,providerThoughtSignatureModelHints:["gemini"]},kilocode:{providerThoughtSignatureSanitization:!0,providerThoughtSignatureModelHints:["gemini"]}};var uP=1;function pP(n,e){return{jsonrpc:"2.0",id:uP++,method:n,params:e,meta:_c(n)}}var mP=["NODE_ENV","HOME","PATH","TERM","OPENAI_API_KEY","OPENAI_BASE_URL","ANTHROPIC_API_KEY","ANTHROPIC_BASE_URL","HTTP_PROXY","HTTPS_PROXY","NO_PROXY","http_proxy","https_proxy","no_proxy"];function gP(n){let e={};for(let t of mP)process.env[t]&&(e[t]=process.env[t]);return n.apiKey&&(e.OPENAI_API_KEY=n.apiKey),n.baseUrl&&(e.OPENAI_BASE_URL=n.baseUrl),e.QLOGICAGENT_MEMBER_ID=n.memberId,e.QLOGICAGENT_MEMBER_NAME=n.name,n.agentType&&(e.QLOGICAGENT_AGENT_TYPE=n.agentType),n.model&&(e.QLOGICAGENT_MODEL=n.model),n.env&&Object.assign(e,n.env),e}var Mc=Ti,fP=Ri,Cn=Ai,Ag=wi;function hP(n){return new Promise(e=>setTimeout(e,n))}var _t=class n{processes=new Map;callbacks;cliBinaryPath;mcpBridgeScriptPath;constructor(e={}){this.callbacks=e;let t=iP(Ir(import.meta.url.startsWith("file://")?new URL(import.meta.url).pathname.replace(/^\/([A-Z]:)/,"$1"):process.cwd(),"..",".."));this.cliBinaryPath=Ir(t,"dist","cli.js"),this.mcpBridgeScriptPath=Ir(t,"dist","runtime","infra","mcp-bridge-server.js")}slog(e,t,r,s){let i=`[${new Date().toISOString()}] [${e}] [agent:${t}] [${r}] ${s}`;e==="warn"?this.callbacks.log?.warn(i):this.callbacks.log?.info(i)}async spawn(e){if(this.processes.has(e.memberId))throw new Error(`Agent process "${e.memberId}" already spawned`);let t=this.callbacks.log,r=gP(e),s={memberId:e.memberId,name:e.name,pid:-1,cwd:e.cwd,state:"starting",startedAt:Date.now()};if(e.external)return this.spawnAcpAgentWithRetry(e,s,r);let o=[this.cliBinaryPath];e.verbose&&o.push("--verbose"),this.slog("info",e.memberId,"spawn",`spawning ${e.name} in ${e.cwd}`);let i=Cc(process.execPath,o,{cwd:e.cwd,env:r,stdio:["pipe","pipe","pipe"],detached:!1});s.pid=i.pid??-1;let a=new Map;this.processes.set(e.memberId,{handle:s,child:i,pendingRpc:a}),Ws({input:i.stdout,crlfDelay:Number.POSITIVE_INFINITY}).on("line",l=>{let d=l.trim();if(d)try{let u=JSON.parse(d);if("id"in u&&typeof u.id=="number"){let p=a.get(u.id);if(p){clearTimeout(p.timer),a.delete(u.id);let m=u;m.error?p.reject(new Error(m.error.message)):p.resolve(m.result)}}if("method"in u&&!("id"in u)){let p=u;this.captureChildProgress(e.memberId,p.method,p.params),this.callbacks.onNotification?.(e.memberId,p.method,p.params)}}catch{this.slog("warn",e.memberId,"parse",`invalid JSON: ${d.slice(0,200)}`)}}),i.stderr&&Ws({input:i.stderr,crlfDelay:Number.POSITIVE_INFINITY}).on("line",d=>{this.callbacks.log?.debug?.(`[${new Date().toISOString()}] [debug] [agent:${e.memberId}] [stderr] ${d}`)}),i.on("exit",(l,d)=>{s.state!=="killed"&&(s.state=l===0?"completed":"failed"),s.endedAt=Date.now(),l!==0&&!s.error&&(s.error=`Process exited with code ${l} (signal: ${d})`);for(let[p,m]of a)clearTimeout(m.timer),m.reject(new Error(`Agent process exited (code=${l})`)),a.delete(p);this.callbacks.onStateChange?.(e.memberId,s.state),this.callbacks.onExit?.(e.memberId,l,d),this.slog("info",e.memberId,"exit",`exited (code=${l}, signal=${d})`)}),i.on("error",l=>{s.state="failed",s.error=l.message,s.endedAt=Date.now(),this.callbacks.onStateChange?.(e.memberId,"failed"),this.slog("warn",e.memberId,"error",l.message)}),this.callbacks.onStateChange?.(e.memberId,"starting");try{let l=await this.sendRpc(e.memberId,"initialize",{protocolVersion:"1.0",clientInfo:{name:"qlogicagent-team-leader",version:"1.0.0"}},15e3);s.state="ready",this.callbacks.onStateChange?.(e.memberId,"ready"),this.slog("info",e.memberId,"handshake",`initialized (pid=${s.pid})`);let d=l;d&&typeof d.sessionId=="string"&&(s.sessionId=d.sessionId)}catch(l){throw s.state="failed",s.error=`Initialize handshake failed: ${l instanceof Error?l.message:String(l)}`,s.endedAt=Date.now(),this.callbacks.onStateChange?.(e.memberId,"failed"),this.kill(e.memberId),new Error(s.error)}return s}async sendTask(e,t,r){let s=this.processes.get(e);if(!s)throw new Error(`No agent process: ${e}`);s.handle.state="running",this.callbacks.onStateChange?.(e,"running");try{let o;if(s.acpAdapter){let i=s.handle.sessionId??"default",a=await s.acpAdapter.sendPrompt(s.child,i,t,r?.timeout??3e5),c=s.handle.resultText??"";a.usage&&s.usageTracker&&s.usageTracker.onPromptResponseUsage(a.usage),o={content:c,stopReason:a.stopReason}}else{let i={content:t};r?.model&&(i.model=r.model),r?.apiKey&&(i.apiKey=r.apiKey),r?.baseUrl&&(i.baseUrl=r.baseUrl),r?.sessionId&&(i.sessionId=r.sessionId),o=await this.sendRpc(e,"thread.turn",i,r?.timeout??3e5);let a=o;a&&typeof a.content=="string"&&(s.handle.resultText=a.content)}return s.handle.state="completed",s.handle.endedAt=Date.now(),this.callbacks.onStateChange?.(e,"completed"),o}catch(o){throw s.handle.state="failed",s.handle.error=o instanceof Error?o.message:String(o),s.handle.endedAt=Date.now(),this.callbacks.onStateChange?.(e,"failed"),o}}async sendRpc(e,t,r,s=3e4){let o=this.processes.get(e);if(!o)throw new Error(`No agent process: ${e}`);let i=pP(t,r);return new Promise((a,c)=>{let l=setTimeout(()=>{o.pendingRpc.delete(i.id),c(new Error(`RPC timeout: ${t} (${s}ms)`))},s);o.pendingRpc.set(i.id,{resolve:a,reject:c,timer:l});try{o.child.stdin.write(`${JSON.stringify(i)}
|
|
778
778
|
`)}catch(d){clearTimeout(l),o.pendingRpc.delete(i.id),c(d instanceof Error?d:new Error(String(d)))}})}async sendTaskAsync(e,t,r){let s=this.processes.get(e);if(!s)throw new Error(`No agent process: ${e}`);s.handle.state="running",this.callbacks.onStateChange?.(e,"running");let o={content:t};r?.model&&(o.model=r.model),r?.apiKey&&(o.apiKey=r.apiKey),r?.baseUrl&&(o.baseUrl=r.baseUrl),r?.sessionId&&(o.sessionId=r.sessionId);let i=r?.pingInterval??6e4,a=r?.pingTimeout??1e4,c=r?.timeout??0,l=Date.now(),d=c>0?c:1440*60*1e3,u=this.sendRpc(e,"thread.turn",o,d),p=setInterval(async()=>{if(c>0&&Date.now()-l>c){clearInterval(p),s.handle.state="failed",s.handle.error="Task timed out",s.handle.endedAt=Date.now(),this.callbacks.onStateChange?.(e,"failed");return}try{await this.sendRpc(e,"ping",void 0,a)}catch{this.slog("warn",s.handle.memberId,"heartbeat","ping failed")}},i);try{let m=await u;clearInterval(p),s.handle.state="completed",s.handle.endedAt=Date.now();let h=m;return h&&typeof h.content=="string"&&(s.handle.resultText=h.content),this.callbacks.onStateChange?.(e,"completed"),m}catch(m){throw clearInterval(p),s.handle.state="failed",s.handle.error=m instanceof Error?m.message:String(m),s.handle.endedAt=Date.now(),this.callbacks.onStateChange?.(e,"failed"),m}}async ping(e,t=5e3){let r=this.processes.get(e);if(!r)return!1;if(r.acpAdapter){try{let i=JSON.stringify({jsonrpc:"2.0",method:"notifications/ping",params:{timestamp:Date.now()}})+`
|
|
779
779
|
`;r.child.stdin?.write(i)}catch{return!1}let s=r.handle.lastActivityAt??0,o=Date.now()+t;for(;Date.now()<o;)if(await new Promise(i=>setTimeout(i,500)),(r.handle.lastActivityAt??0)>s)return!0;try{return await this.sendRpc(e,"ping",void 0,Math.min(t,3e3)),!0}catch{return!1}}try{return await this.sendRpc(e,"ping",void 0,t),!0}catch{return!1}}getStatus(e){let t=this.processes.get(e);if(!t)return null;let{handle:r}=t,s=r.state==="starting"||r.state==="ready"||r.state==="running",o=s?Date.now()-r.startedAt:void 0,i=r.lastActivityAt&&s?Math.round((Date.now()-r.lastActivityAt)/1e3):void 0;return{alive:s,state:r.state,runningFor:o,resultText:r.resultText,error:r.error,mediaProgress:r.mediaProgress,lastToolCall:r.lastToolCall,idleFor:i}}captureChildProgress(e,t,r){let s=this.processes.get(e);if(!s)return;let{handle:o}=s;switch(o.lastActivityAt=Date.now(),t){case"turn.media_progress":{let i=r;i&&typeof i.taskId=="string"&&(o.mediaProgress={taskId:i.taskId,mediaType:i.mediaType??"unknown",percent:typeof i.percent=="number"?i.percent:0,status:i.status??"unknown",provider:i.provider,updatedAt:Date.now()});break}case"turn.tool_call":{let i=r;i&&typeof i.name=="string"&&(o.lastToolCall=i.name);break}case"turn.delta":{let i=r;if(i&&typeof i.text=="string"){let a=i.text;o.resultText=`${o.resultText??""}${a}`,o.lastDelta=a.slice(-200)}break}case"turn.tool_result":{r&&o.mediaProgress&&o.mediaProgress.percent>=100&&(o.mediaProgress=void 0);break}}}async spawnAcpAgentWithRetry(e,t,r){let s=null;for(let o=0;o<=Mc;o++)try{if(o>0){this.processes.delete(e.memberId),t.state="starting",t.error=void 0,t.endedAt=void 0;let i=fP*o;this.slog("info",e.memberId,"spawn",`retry ${o}/${Mc} after ${i}ms`),await hP(i)}return await this.spawnAcpAgent(e,t,r)}catch(i){s=i instanceof Error?i:new Error(String(i)),this.slog("warn",e.memberId,"spawn",`attempt ${o+1} failed: ${s.message}`)}throw t.state="failed",t.error=`ACP spawn failed after ${Mc+1} attempts: ${s?.message}`,t.endedAt=Date.now(),this.callbacks.onStateChange?.(e.memberId,"failed"),new Error(t.error)}async spawnAcpAgent(e,t,r){let s=this.callbacks.log,o=e.external;o.env&&Object.assign(r,o.env);let i=[...o.acpArgs];this.slog("info",e.memberId,"spawn",`spawning ACP ${e.name} via ${o.cliPath} ${i.join(" ")}`);let a=Cc(o.cliPath,i,{cwd:e.cwd,env:r,stdio:["pipe","pipe","pipe"],detached:!1});t.pid=a.pid??-1;let c=new Map,l=new un,d=new Rr,{server:u,pipePath:p}=this.createMcpIpcServer(e.memberId);r.QLOGICAGENT_PARENT_RPC=p;let m;if(this.callbacks.sessionDir)try{lP(this.callbacks.sessionDir,{recursive:!0}),m=cP(Ir(this.callbacks.sessionDir,`${e.memberId}.stderr.log`),{flags:"a"})}catch{}this.processes.set(e.memberId,{handle:t,child:a,pendingRpc:c,acpAdapter:l,usageTracker:d,ipcServer:u,ipcPath:p,stderrStream:m}),l.attach(a,(h,f)=>{h==="usage_update"&&d.onUsageUpdate(f);let y=un.translateNotification(h,f);y?(this.captureChildProgress(e.memberId,y.method,y.params),this.callbacks.onNotification?.(e.memberId,y.method,y.params)):(this.captureChildProgress(e.memberId,h,f),this.callbacks.onNotification?.(e.memberId,h,f))}),a.stderr&&Ws({input:a.stderr,crlfDelay:Number.POSITIVE_INFINITY}).on("line",f=>{this.callbacks.log?.debug?.(`[${new Date().toISOString()}] [debug] [agent:${e.memberId}] [stderr] ${f}`),m?.write(`${new Date().toISOString()} ${f}
|
|
780
|
-
`)}),a.on("exit",(h,f)=>{l.detach();let y=t.state;if(y!=="killed"&&y!=="completed"&&h!==0){let k=this.processes.get(e.memberId)?.runtimeRestartCount??0;if(k<Cn){let A=
|
|
780
|
+
`)}),a.on("exit",(h,f)=>{l.detach();let y=t.state;if(y!=="killed"&&y!=="completed"&&h!==0){let k=this.processes.get(e.memberId)?.runtimeRestartCount??0;if(k<Cn){let A=Ag*2**k;this.slog("warn",e.memberId,"crash",`crashed (code=${h}), restarting ${k+1}/${Cn} after ${A}ms`),this.callbacks.onNotification?.(e.memberId,"agents.error",{agentId:e.memberId,phase:"runtime",error:`Process crashed (code=${h}, signal=${f}), restarting`,retriesLeft:Cn-k-1}),setTimeout(()=>{this.attemptRuntimeRestart(e,r,k+1).catch(_=>{this.slog("warn",e.memberId,"restart",`failed: ${_ instanceof Error?_.message:String(_)}`)})},A);return}}y!=="killed"&&(t.state=h===0?"completed":"failed"),t.endedAt=Date.now(),h!==0&&!t.error&&(t.error=`ACP process exited with code ${h} (signal: ${f})`),this.callbacks.onStateChange?.(e.memberId,t.state),this.callbacks.onExit?.(e.memberId,h,f),this.slog("info",e.memberId,"exit",`ACP exited (code=${h}, signal=${f})`)}),a.on("error",h=>{l.detach(),t.state="failed",t.error=h.message,t.endedAt=Date.now(),this.callbacks.onStateChange?.(e.memberId,"failed"),this.callbacks.onNotification?.(e.memberId,"agents.error",{agentId:e.memberId,phase:"spawn",error:h.message,retriesLeft:0}),this.slog("warn",e.memberId,"error",h.message)}),this.callbacks.onStateChange?.(e.memberId,"starting");try{let h=await l.initialize(a);t.state="ready",t.supportsResume=h.agentCapabilities.loadSession===!0,this.callbacks.onStateChange?.(e.memberId,"ready"),this.slog("info",e.memberId,"handshake",`ACP initialized (protocol=${h.protocolVersion}, loadSession=${t.supportsResume}, pid=${t.pid})`);try{let f={cwd:e.cwd},y=[...e.mcpServers??[]],b=this.processes.get(e.memberId),A=h.agentCapabilities.mcpCapabilities?.stdio===!0;b?.ipcPath&&A&&y.push({name:"qlogicagent-tools",command:process.execPath,args:[this.mcpBridgeScriptPath],env:{QLOGICAGENT_PARENT_RPC:b.ipcPath,QLOGICAGENT_SESSION_ID:e.memberId}}),y.length>0&&(f.mcpServers=y),e.systemPrompt&&(f.systemPrompt=e.systemPrompt);let _=await l.createSession(a,f);t.sessionId=_.sessionId,this.slog("info",e.memberId,"session",`session created (id=${_.sessionId})`)}catch(f){this.slog("warn",e.memberId,"session",`session creation failed: ${f instanceof Error?f.message:String(f)}`)}this.startHeartbeat(e.memberId,f=>{this.slog("warn",f,"heartbeat","hang detected \u2014 force-killing"),this.callbacks.onNotification?.(f,"agents.error",{agentId:f,phase:"heartbeat",error:`Agent ${e.name} stopped responding (${n.MAX_MISSED_BEATS} missed heartbeats)`,retriesLeft:0}),this.kill(f)})}catch(h){throw t.state="failed",t.error=`ACP handshake failed: ${h instanceof Error?h.message:String(h)}`,t.endedAt=Date.now(),l.detach(),this.callbacks.onStateChange?.(e.memberId,"failed"),this.callbacks.onNotification?.(e.memberId,"agents.error",{agentId:e.memberId,phase:"handshake",error:t.error,retriesLeft:0}),this.kill(e.memberId),new Error(t.error)}return t}kill(e){let t=this.processes.get(e);if(t){this.stopHeartbeat(e),t.handle.state="killed",t.handle.endedAt=Date.now(),t.acpAdapter?.detach();try{t.ipcServer?.close()}catch{}try{t.stderrStream?.end()}catch{}try{t.child.kill("SIGTERM"),setTimeout(()=>{try{t.child.kill("SIGKILL")}catch{}},1e4)}catch{}this.callbacks.onStateChange?.(e,"killed"),this.slog("info",e,"kill",`killed (pid=${t.handle.pid})`)}}killAll(){for(let e of this.processes.keys())this.kill(e)}getHandle(e){return this.processes.get(e)?.handle}getAllHandles(){return[...this.processes.values()].map(e=>e.handle)}getUsageTracker(e){return this.processes.get(e)?.usageTracker??null}createMcpIpcServer(e){let t=e.replace(/[^a-zA-Z0-9-]/g,"-"),r=process.platform==="win32"?`\\\\.\\pipe\\qlogicagent-mcp-${t}-${Date.now()}`:Ir(dP(),`qlogicagent-mcp-${t}-${Date.now()}.sock`),s=aP(o=>{let i="";o.on("data",a=>{i+=a.toString();let c;for(;(c=i.indexOf(`
|
|
781
781
|
`))!==-1;){let l=i.slice(0,c).trim();i=i.slice(c+1),l&&this.handleMcpIpcMessage(e,l,o)}})});return s.listen(r),s.on("error",o=>{this.slog("warn",e,"mcp-ipc",`server error: ${o.message}`)}),{server:s,pipePath:r}}handleMcpIpcMessage(e,t,r){let s;try{s=JSON.parse(t)}catch{return}if(s.method==="mcp.toolCall"&&s.id!==void 0){let o=typeof s.params?.tool=="string"?s.params.tool:"",i=s.params?.arguments??{};if(!this.callbacks.onMcpToolCall){let a=JSON.stringify({jsonrpc:"2.0",id:s.id,error:{code:-32601,message:"No onMcpToolCall handler"}})+`
|
|
782
782
|
`;try{r.write(a)}catch{}return}this.callbacks.onMcpToolCall(e,o,i).then(a=>{let c=JSON.stringify({jsonrpc:"2.0",id:s.id,result:a})+`
|
|
783
783
|
`;try{r.write(c)}catch{}}).catch(a=>{let c=JSON.stringify({jsonrpc:"2.0",id:s.id,error:{code:-32603,message:a instanceof Error?a.message:String(a)}})+`
|
|
784
784
|
`;try{r.write(c)}catch{}})}else if(s.id!==void 0){let o=JSON.stringify({jsonrpc:"2.0",id:s.id,error:{code:-32601,message:`Unknown IPC method: ${s.method}`}})+`
|
|
785
785
|
`;try{r.write(o)}catch{}}}async attemptRuntimeRestart(e,t,r){let s=this.callbacks.log,o=this.processes.get(e.memberId),i=o?.ipcServer,a=o?.ipcPath,c=o?.stderrStream;this.processes.delete(e.memberId);try{let l={memberId:e.memberId,name:e.name,pid:-1,cwd:e.cwd,state:"starting",startedAt:Date.now()},d=e.external,u=[...d.acpArgs];a&&(t.QLOGICAGENT_PARENT_RPC=a);let p=Cc(d.cliPath,u,{cwd:e.cwd,env:t,stdio:["pipe","pipe","pipe"],detached:!1});l.pid=p.pid??-1;let m=new Map,h=new un,f=new Rr;this.processes.set(e.memberId,{handle:l,child:p,pendingRpc:m,acpAdapter:h,usageTracker:f,ipcServer:i,ipcPath:a,stderrStream:c,runtimeRestartCount:r}),h.attach(p,(k,A)=>{k==="usage_update"&&f.onUsageUpdate(A);let _=un.translateNotification(k,A);_?(this.captureChildProgress(e.memberId,_.method,_.params),this.callbacks.onNotification?.(e.memberId,_.method,_.params)):(this.captureChildProgress(e.memberId,k,A),this.callbacks.onNotification?.(e.memberId,k,A))}),p.stderr&&Ws({input:p.stderr,crlfDelay:Number.POSITIVE_INFINITY}).on("line",A=>{this.callbacks.log?.debug?.(`[${new Date().toISOString()}] [debug] [agent:${e.memberId}] [stderr] ${A}`),c?.write(`${new Date().toISOString()} ${A}
|
|
786
|
-
`)}),p.on("exit",(k,A)=>{h.detach();let _=l.state;if(_!=="killed"&&_!=="completed"&&k!==0){let N=this.processes.get(e.memberId)?.runtimeRestartCount??r;if(N<Cn){let L=
|
|
787
|
-
`)}var
|
|
786
|
+
`)}),p.on("exit",(k,A)=>{h.detach();let _=l.state;if(_!=="killed"&&_!=="completed"&&k!==0){let N=this.processes.get(e.memberId)?.runtimeRestartCount??r;if(N<Cn){let L=Ag*2**N;this.slog("warn",e.memberId,"crash",`crashed again (code=${k}), restart ${N+1}/${Cn}`),this.callbacks.onNotification?.(e.memberId,"agents.error",{agentId:e.memberId,phase:"runtime",error:`Process crashed (code=${k}), restarting`,retriesLeft:Cn-N-1}),setTimeout(()=>{this.attemptRuntimeRestart(e,t,N+1).catch(F=>{this.slog("warn",e.memberId,"restart",`failed: ${F instanceof Error?F.message:String(F)}`)})},L);return}}_!=="killed"&&(l.state=k===0?"completed":"failed"),l.endedAt=Date.now(),k!==0&&!l.error&&(l.error=`ACP process exited with code ${k} (signal: ${A})`),this.callbacks.onStateChange?.(e.memberId,l.state),this.callbacks.onExit?.(e.memberId,k,A)}),p.on("error",k=>{h.detach(),l.state="failed",l.error=k.message,l.endedAt=Date.now(),this.callbacks.onStateChange?.(e.memberId,"failed")}),this.callbacks.onStateChange?.(e.memberId,"starting");let y=await h.initialize(p);l.state="ready",l.supportsResume=y.agentCapabilities.loadSession===!0,this.callbacks.onStateChange?.(e.memberId,"ready"),this.slog("info",e.memberId,"restart",`ACP restarted (attempt=${r}, protocol=${y.protocolVersion}, loadSession=${l.supportsResume}, pid=${l.pid})`);let b=[...e.mcpServers??[]];a&&b.push({name:"qlogicagent-tools",command:process.execPath,args:[this.mcpBridgeScriptPath],env:{QLOGICAGENT_PARENT_RPC:a,QLOGICAGENT_SESSION_ID:e.memberId}});try{if(l.supportsResume&&l.sessionId){let k=await h.resumeSession(p,l.sessionId,{cwd:e.cwd,mcpServers:b.length>0?b:void 0});l.sessionId=k.sessionId,this.slog("info",e.memberId,"session",`session resumed (id=${l.sessionId})`)}else{let k={cwd:e.cwd};b.length>0&&(k.mcpServers=b),e.systemPrompt&&(k.systemPrompt=e.systemPrompt);let A=await h.createSession(p,k);l.sessionId=A.sessionId,this.slog("info",e.memberId,"session",`new session on restart (id=${l.sessionId})`)}}catch{this.slog("warn",e.memberId,"session","session re-creation failed on restart")}this.startHeartbeat(e.memberId,k=>{this.slog("warn",k,"heartbeat","hang detected \u2014 force-killing"),this.callbacks.onNotification?.(k,"agents.error",{agentId:k,phase:"heartbeat",error:`Agent ${e.name} stopped responding`,retriesLeft:0}),this.kill(k)})}catch(l){let d=this.processes.get(e.memberId);d&&(d.handle.state="failed",d.handle.error=`Runtime restart failed: ${l instanceof Error?l.message:String(l)}`,d.handle.endedAt=Date.now()),this.callbacks.onStateChange?.(e.memberId,"failed"),this.callbacks.onNotification?.(e.memberId,"agents.error",{agentId:e.memberId,phase:"runtime",error:`Restart failed after ${r} attempts: ${l instanceof Error?l.message:String(l)}`,retriesLeft:0})}}getMcpIpcPath(e){return this.processes.get(e)?.ipcPath}heartbeatTimers=new Map;missedBeats=new Map;static HEARTBEAT_INTERVAL=3e4;static MAX_MISSED_BEATS=3;startHeartbeat(e,t){this.stopHeartbeat(e),this.missedBeats.set(e,0);let r=setInterval(async()=>{let s=this.processes.get(e);if(!s||s.handle.state==="completed"||s.handle.state==="failed"||s.handle.state==="killed"){this.stopHeartbeat(e);return}if(await this.ping(e,1e4)){this.missedBeats.set(e,0);return}let i=(this.missedBeats.get(e)??0)+1;this.missedBeats.set(e,i),this.slog("warn",e,"heartbeat",`missed (${i}/${n.MAX_MISSED_BEATS})`),i>=n.MAX_MISSED_BEATS&&(this.slog("warn",e,"heartbeat","hang detected, force-killing"),this.stopHeartbeat(e),s.handle.error=`Hang detected: ${i} consecutive heartbeat failures`,this.kill(e),t?.(e))},n.HEARTBEAT_INTERVAL);this.heartbeatTimers.set(e,r)}stopHeartbeat(e){let t=this.heartbeatTimers.get(e);t&&(clearInterval(t),this.heartbeatTimers.delete(e)),this.missedBeats.delete(e)}getMissedBeats(e){return this.missedBeats.get(e)??0}activeCount(){return[...this.processes.values()].filter(e=>e.handle.state==="starting"||e.handle.state==="ready"||e.handle.state==="running").length}remove(e){let t=this.processes.get(e);t&&(this.stopHeartbeat(e),(t.handle.state==="running"||t.handle.state==="starting"||t.handle.state==="ready")&&this.kill(e),this.processes.delete(e))}dispose(){for(let e of this.heartbeatTimers.keys())this.stopHeartbeat(e);for(let e of this.processes.values()){try{e.ipcServer?.close()}catch{}try{e.stderrStream?.end()}catch{}}this.killAll(),this.processes.clear()}};ae();import{join as xg}from"node:path";import{chmod as wP}from"node:fs/promises";import{readFile as yP,writeFile as bP,mkdir as vP,rename as kP,unlink as SP}from"node:fs/promises";import{dirname as TP,join as RP}from"node:path";import{randomUUID as AP}from"node:crypto";async function Mn(n,e){let t=TP(n);await vP(t,{recursive:!0});let r=RP(t,`.tmp-${AP()}`);try{await bP(r,e,"utf-8");let s;for(let o=0;o<3;o++)try{await kP(r,n);return}catch(i){if(s=i,i.code!=="EPERM")throw i;await new Promise(a=>setTimeout(a,50*(o+1)))}throw s}catch(s){throw await SP(r).catch(()=>{}),s}}async function mn(n){try{let e=await yP(n,"utf-8");return JSON.parse(e)}catch(e){if(e.code==="ENOENT")return;throw e}}async function Nn(n,e){await Mn(n,JSON.stringify(e,null,2)+`
|
|
787
|
+
`)}var Pg="agent-configs.json";function wg(){return xg(q(),Pg)}function xP(n){return xg(Me(n),Pg)}function PP(){return{agents:{}}}var Gs=class{data=PP();cwd;constructor(e){this.cwd=e}async load(){let e=await mn(wg()),t=this.cwd?await mn(xP(this.cwd)):void 0,r={gatewayUrl:e?.gatewayUrl,agents:{...e?.agents},customAgents:{...e?.customAgents}};if(t){t.gatewayUrl&&(r.gatewayUrl=t.gatewayUrl);for(let[s,o]of Object.entries(t.agents??{}))r.agents[s]={...r.agents[s],...o};for(let[s,o]of Object.entries(t.customAgents??{}))r.customAgents??={},r.customAgents[s]=o}this.data=r}getData(){return this.data}getAgentConfig(e){return this.data.agents[e]??null}async setAgentConfig(e,t){this.data.agents[e]={...this.data.agents[e],...t},await this.save()}async removeAgentConfig(e){delete this.data.agents[e],await this.save()}getGatewayUrl(){return this.data.gatewayUrl}async setGatewayUrl(e){this.data.gatewayUrl=e,await this.save()}registerCustomAgent(e){this.data.customAgents??={},this.data.customAgents[e.id]=e}unregisterCustomAgent(e){this.data.customAgents&&delete this.data.customAgents[e]}getCustomAgents(){return{...this.data.customAgents}}async save(){let e=wg();await Nn(e,this.data);try{await wP(e,384)}catch{}}};var Ig="memory",_g="Memory",IP=["add","replace","remove","create_file","write_file","read_file","delete_file","list_files","search","remember","temporal","feedback"],Eg={type:"object",properties:{action:{type:"string",enum:IP,description:["Operation to perform:","","INDEX.md operations (project-level notes, always visible in system prompt):","- 'add' - Append a note to INDEX.md","- 'replace' - Replace text in INDEX.md (str_replace semantics)","- 'remove' - Remove text from INDEX.md","","Topic file operations (project-level, on-demand, for longer content):","- 'create_file' - Create a new .md topic file","- 'write_file' - Overwrite an existing topic file","- 'read_file' - Read a topic file","- 'delete_file' - Delete a topic file","- 'list_files' - List all memory topic files","","Long-term memory (user-level, persists across projects):","- 'remember' - Submit a fact/preference/lesson to the memory consolidation pipeline","- 'search' - Search long-term memory + local keyword match","- 'temporal' - Query memories by time range ('what happened last week')","","Feedback:","- 'feedback' - Mark memories as useful/irrelevant/outdated/wrong"].join(`
|
|
788
788
|
`)},content:{type:"string",description:["Content for add/replace/create_file/write_file.","For INDEX.md notes: write concise, factual statements.","For topic files: can be longer (up to 8KB), use markdown formatting."].join(`
|
|
789
|
-
`)},old_text:{type:"string",description:"For 'replace'/'remove': the exact text to find in INDEX.md."},new_text:{type:"string",description:"For 'replace': the replacement text."},file:{type:"string",description:"Filename for file operations (e.g. 'project-notes.md', 'lesson-esbuild.md'). Must be kebab-case .md."},query:{type:"string",description:"For 'search'/'temporal': natural language query to find relevant memories."},days:{type:"number",description:"For 'temporal': look back N days from today (default: 7)."},memory_ids:{type:"array",items:{type:"string"},description:"For 'feedback': IDs of memories to give feedback on."},signal:{type:"string",enum:["useful","irrelevant","outdated","wrong"],description:"For 'feedback': the feedback signal to apply."},category:{type:"string",enum:["preference","personal_fact","lesson","pattern","decision","context"],description:"For 'remember': categorize the memory (helps with future recall precision)."}},required:["action"]},
|
|
790
|
-
`),_P=[/ignore\s+(previous|all|above|prior)\s+instructions/i,/you\s+are\s+now\s+/i,/do\s+not\s+tell\s+the\s+user/i,/system\s+prompt\s+override/i];function EP(n){return!_P.some(e=>e.test(n))}async function
|
|
789
|
+
`)},old_text:{type:"string",description:"For 'replace'/'remove': the exact text to find in INDEX.md."},new_text:{type:"string",description:"For 'replace': the replacement text."},file:{type:"string",description:"Filename for file operations (e.g. 'project-notes.md', 'lesson-esbuild.md'). Must be kebab-case .md."},query:{type:"string",description:"For 'search'/'temporal': natural language query to find relevant memories."},days:{type:"number",description:"For 'temporal': look back N days from today (default: 7)."},memory_ids:{type:"array",items:{type:"string"},description:"For 'feedback': IDs of memories to give feedback on."},signal:{type:"string",enum:["useful","irrelevant","outdated","wrong"],description:"For 'feedback': the feedback signal to apply."},category:{type:"string",enum:["preference","personal_fact","lesson","pattern","decision","context"],description:"For 'remember': categorize the memory (helps with future recall precision)."}},required:["action"]},Cg=["Manage persistent memory across sessions. Two distinct systems with clear roles:","","## Project memory (INDEX.md + topic files)","Scope: current project / workspace. Visible every turn.","Use for: architecture decisions, file conventions, build commands, known issues, task logs.","Actions: add, replace, remove, create_file, write_file, read_file, delete_file, list_files.","","## Long-term memory (QMemory)","Scope: user-level, persists across all projects. Searched on demand.","Use for: user preferences, personal facts, recurring lessons, communication style, past insights.","Actions: remember, search, temporal, feedback.","","## When to store (guidelines):","- User explicitly says 'remember this' or 'note that' -> submit a high-priority memory candidate","- User states a preference (style, format, tools, habits) -> remember (long-term)","- Project-specific decision or fact -> add/create_file (project memory)","- A debugging lesson or insight that applies broadly -> remember (long-term)","- DO NOT store: trivial/obvious info, one-off questions, transient state","- DO NOT store: information the user did not share or confirm","","## When to recall:","- Use 'search' when you suspect relevant past context exists for the current task","- Use 'temporal' to find what happened in a specific time period","- Memory is auto-recalled each turn - manual search is for deeper queries"].join(`
|
|
790
|
+
`),_P=[/ignore\s+(previous|all|above|prior)\s+instructions/i,/you\s+are\s+now\s+/i,/do\s+not\s+tell\s+the\s+user/i,/system\s+prompt\s+override/i];function EP(n){return!_P.some(e=>e.test(n))}async function Mg(n,e){let{action:t}=n,{memdir:r}=e;if(t==="add"){let s=n.content?.trim();if(!s)return{ok:!1,message:"content is required for 'add'.",action:t};let o=await r.addToIndex(s);return{ok:o.ok,message:o.message,action:t}}if(t==="replace"){let s=n.old_text?.trim(),o=n.new_text?.trim()||n.content?.trim();if(!s)return{ok:!1,message:"old_text is required for 'replace'.",action:t};if(!o)return{ok:!1,message:"new_text (or content) is required for 'replace'.",action:t};let i=await r.replaceInIndex(s,o);return{ok:i.ok,message:i.message,action:t}}if(t==="remove"){let s=n.old_text?.trim();if(!s)return{ok:!1,message:"old_text is required for 'remove'.",action:t};let o=await r.removeFromIndex(s);return{ok:o.ok,message:o.message,action:t}}if(t==="create_file"){let s=n.file?.trim(),o=n.content?.trim();if(!s)return{ok:!1,message:"file is required for 'create_file'.",action:t};if(!o)return{ok:!1,message:"content is required for 'create_file'.",action:t};let i=await r.createFile(s,o);return{ok:i.ok,message:i.message,action:t}}if(t==="write_file"){let s=n.file?.trim(),o=n.content?.trim();if(!s)return{ok:!1,message:"file is required for 'write_file'.",action:t};if(!o)return{ok:!1,message:"content is required for 'write_file'.",action:t};let i=await r.writeFile(s,o);return{ok:i.ok,message:i.message,action:t}}if(t==="read_file"){let s=n.file?.trim();if(!s)return{ok:!1,message:"file is required for 'read_file'.",action:t};let o=await r.readFile(s);return o.ok?{ok:!0,message:o.content,action:t}:{ok:!1,message:o.message,action:t}}if(t==="delete_file"){let s=n.file?.trim();if(!s)return{ok:!1,message:"file is required for 'delete_file'.",action:t};let o=await r.deleteFile(s);return{ok:o.ok,message:o.message,action:t}}if(t==="list_files"){let s=await r.listFiles();if(s.length===0)return{ok:!0,message:"No topic files yet. Use 'create_file' to create one.",action:t};let o=s.map(i=>{let a=(i.size/1024).toFixed(1),c=i.modifiedAt.slice(0,10);return`--${i.name} (${a}KB, ${c})${i.preview?""+i.preview:""}`}).join(`
|
|
791
791
|
`);return{ok:!0,message:`Memory files (${s.length}):
|
|
792
792
|
${o}`,action:t}}if(t==="search"){let s=n.query?.trim();if(!s)return{ok:!1,message:"query is required for 'search'.",action:t};let o=[],i;try{let a=await r.searchLocal(s);a.length>0&&o.push(`## Local Memory
|
|
793
793
|
`+a.map(c=>`--[${c.file}] ${c.snippet}`).join(`
|
|
@@ -795,14 +795,14 @@ ${o}`,action:t}}if(t==="search"){let s=n.query?.trim();if(!s)return{ok:!1,messag
|
|
|
795
795
|
`+a.map((c,l)=>`${l+1}. ${c.text}`).join(`
|
|
796
796
|
`))}catch{}return o.length===0?{ok:!0,message:"No matching memories found.",action:t,results:[]}:{ok:!0,message:o.join(`
|
|
797
797
|
|
|
798
|
-
`),action:t,results:i}}if(t==="remember"){if(!e.localProvider)return{ok:!1,message:"Long-term memory requires local memory provider.",action:t};let s=n.content?.trim();if(!s)return{ok:!1,message:"content is required for 'remember'.",action:t};if(!EP(s))return{ok:!1,message:"Content blocked by safety filter.",action:t};if(s.length<10)return{ok:!1,message:"Memory too short - provide a meaningful fact or insight (>=10 chars).",action:t};if(s.length>2e3)return{ok:!1,message:"Memory too long (max 2000 chars). Condense the insight.",action:t};try{return await e.localProvider.addText(s,e.userId,{source:"agent-remember",category:n.category??"lesson",importance:.7}),{ok:!0,message:`Stored to long-term memory: "${s.slice(0,80)}${s.length>80?"...":""}"`,action:t}}catch(o){return{ok:!1,message:`Failed to store: ${o instanceof Error?o.message:String(o)}`,action:t}}}if(t==="temporal"){if(!e.localProvider)return{ok:!1,message:"Temporal query requires local memory provider.",action:t};let s=n.days??7,o=Date.now()-s*864e5;return{ok:!0,message:e.localProvider.synthesizeTimeline(e.userId,o,Date.now()),action:t}}if(t==="feedback"){if(!e.localProvider)return{ok:!1,message:"Feedback requires local memory provider.",action:t};let s=n.memory_ids,o=n.signal;if(!s||s.length===0)return{ok:!1,message:"memory_ids is required for 'feedback'.",action:t};if(!o)return{ok:!1,message:"signal is required for 'feedback' (useful/irrelevant/outdated/wrong).",action:t};let i=await e.localProvider.feedback(s,o);return{ok:!0,message:`Feedback '${o}' applied to ${i.affected} memories.`,action:t}}return{ok:!1,message:`Unknown action: "${t}".`,action:t}}ae();import{readFile as Nc,readdir as
|
|
799
|
-
`);jP(e,t)}}getIndexForPrompt(){let e=st(this.root,Qt);if(!yt(e))return"";let t;try{t=
|
|
798
|
+
`),action:t,results:i}}if(t==="remember"){if(!e.localProvider)return{ok:!1,message:"Long-term memory requires local memory provider.",action:t};let s=n.content?.trim();if(!s)return{ok:!1,message:"content is required for 'remember'.",action:t};if(!EP(s))return{ok:!1,message:"Content blocked by safety filter.",action:t};if(s.length<10)return{ok:!1,message:"Memory too short - provide a meaningful fact or insight (>=10 chars).",action:t};if(s.length>2e3)return{ok:!1,message:"Memory too long (max 2000 chars). Condense the insight.",action:t};try{return await e.localProvider.addText(s,e.userId,{source:"agent-remember",category:n.category??"lesson",importance:.7}),{ok:!0,message:`Stored to long-term memory: "${s.slice(0,80)}${s.length>80?"...":""}"`,action:t}}catch(o){return{ok:!1,message:`Failed to store: ${o instanceof Error?o.message:String(o)}`,action:t}}}if(t==="temporal"){if(!e.localProvider)return{ok:!1,message:"Temporal query requires local memory provider.",action:t};let s=n.days??7,o=Date.now()-s*864e5;return{ok:!0,message:e.localProvider.synthesizeTimeline(e.userId,o,Date.now()),action:t}}if(t==="feedback"){if(!e.localProvider)return{ok:!1,message:"Feedback requires local memory provider.",action:t};let s=n.memory_ids,o=n.signal;if(!s||s.length===0)return{ok:!1,message:"memory_ids is required for 'feedback'.",action:t};if(!o)return{ok:!1,message:"signal is required for 'feedback' (useful/irrelevant/outdated/wrong).",action:t};let i=await e.localProvider.feedback(s,o);return{ok:!0,message:`Feedback '${o}' applied to ${i.affected} memories.`,action:t}}return{ok:!1,message:`Unknown action: "${t}".`,action:t}}ae();import{readFile as Nc,readdir as Ng,unlink as CP,stat as MP,mkdir as NP}from"node:fs/promises";import{existsSync as yt,readFileSync as Dg,mkdirSync as Og,writeFileSync as DP}from"node:fs";import{join as st}from"node:path";var Ie=12288,Dc=200,Ks=8192,OP="memory",Qt="INDEX.md";function Oc(n){return st(Me(n),OP)}var LP=[/ignore\s+(previous|all|above|prior)\s+instructions/i,/you\s+are\s+now\s+/i,/do\s+not\s+tell\s+the\s+user/i,/system\s+prompt\s+override/i];function Vs(n){return!LP.some(e=>e.test(n))}var $P=/^[a-z0-9][a-z0-9\-_.]*\.md$/i;function zs(n){return!(!$P.test(n)||n===Qt||n.includes("..")||n.includes("/")||n.includes("\\"))}var Et=class{root;indexCache=null;constructor(e){this.root=Oc(e)}getRootPath(){return this.root}ensureInitialized(){yt(this.root)||Og(this.root,{recursive:!0});let e=st(this.root,Qt);if(!yt(e)){let t=["# Memory Index","","<!-- Agent-managed memory. Lines here are always visible in system prompt.>","<!-- Use memory tool to add notes, or create topic files for longer content.>","","## User Profile","","## Notes",""].join(`
|
|
799
|
+
`);jP(e,t)}}getIndexForPrompt(){let e=st(this.root,Qt);if(!yt(e))return"";let t;try{t=Dg(e,"utf-8")}catch{return""}this.indexCache=t;let r=t.split(`
|
|
800
800
|
`);return r.length>Dc&&(t=r.slice(0,Dc).join(`
|
|
801
801
|
`)+`
|
|
802
802
|
|
|
803
803
|
<!-- INDEX.md truncated: ${r.length} lines total, showing first ${Dc}>`),Buffer.byteLength(t,"utf-8")>Ie&&(t=Buffer.from(t,"utf-8").subarray(0,Ie).toString("utf-8")+`
|
|
804
804
|
|
|
805
|
-
<!-- INDEX.md truncated at ${Ie} bytes>`),t}getIndexRaw(){let e=st(this.root,Qt);if(!yt(e))return"";try{return
|
|
805
|
+
<!-- INDEX.md truncated at ${Ie} bytes>`),t}getIndexRaw(){let e=st(this.root,Qt);if(!yt(e))return"";try{return Dg(e,"utf-8")}catch{return""}}getIndexUsage(){let e=this.getIndexRaw(),t=Buffer.byteLength(e,"utf-8"),r=e.split(`
|
|
806
806
|
`).length;return{chars:t,lines:r,percent:Math.round(t/Ie*100)}}async addToIndex(e){if(!e.trim())return{ok:!1,message:"Content cannot be empty."};if(!Vs(e))return{ok:!1,message:"Content rejected: potential injection detected."};let t=this.getIndexRaw(),r=t.endsWith(`
|
|
807
807
|
`)?t+e.trim()+`
|
|
808
808
|
`:t+`
|
|
@@ -817,22 +817,22 @@ ${o}`,action:t}}if(t==="search"){let s=n.query?.trim();if(!s)return{ok:!1,messag
|
|
|
817
817
|
`+t+`
|
|
818
818
|
`;return Buffer.byteLength(p,"utf-8")<=Ie?p:null}async replaceInIndex(e,t){if(!e.trim())return{ok:!1,message:"old_text cannot be empty."};if(!t.trim())return{ok:!1,message:"new_text cannot be empty. Use 'remove' to delete."};if(!Vs(t))return{ok:!1,message:"Content rejected: potential injection detected."};let r=this.getIndexRaw(),s=r.split(e).length-1;if(s===0)return{ok:!1,message:`No match found for: "${e.slice(0,80)}"`};if(s>1)return{ok:!1,message:`Multiple matches (${s}) for: "${e.slice(0,80)}". Be more specific.`};let o=r.replace(e,t);if(Buffer.byteLength(o,"utf-8")>Ie)return{ok:!1,message:`Replacement would exceed INDEX.md limit (${Buffer.byteLength(o,"utf-8")}/${Ie} bytes).`};await this.writeIndex(o);let i=this.getIndexUsage();return{ok:!0,message:`Replaced in INDEX.md. [${i.chars}/${Ie} chars]`,indexUsage:`${i.chars}/${Ie}`}}async removeFromIndex(e){if(!e.trim())return{ok:!1,message:"old_text cannot be empty."};let t=this.getIndexRaw();if(!t.includes(e))return{ok:!1,message:`No match found for: "${e.slice(0,80)}"`};let r=t.replace(e,"");r=r.replace(/\n{3,}/g,`
|
|
819
819
|
|
|
820
|
-
`),await this.writeIndex(r);let s=this.getIndexUsage();return{ok:!0,message:`Removed from INDEX.md. [${s.chars}/${Ie} chars]`,indexUsage:`${s.chars}/${Ie}`}}async listFiles(){if(!yt(this.root))return[];let e=await
|
|
820
|
+
`),await this.writeIndex(r);let s=this.getIndexUsage();return{ok:!0,message:`Removed from INDEX.md. [${s.chars}/${Ie} chars]`,indexUsage:`${s.chars}/${Ie}`}}async listFiles(){if(!yt(this.root))return[];let e=await Ng(this.root),t=[];for(let r of e){if(r===Qt||!r.endsWith(".md"))continue;let s=st(this.root,r);try{let o=await MP(s);if(!o.isFile())continue;let a=(await Nc(s,"utf-8")).split(`
|
|
821
821
|
`).find(c=>c.trim()&&!c.startsWith("#"))?.trim();t.push({name:r,size:o.size,modifiedAt:o.mtime.toISOString(),preview:a?.slice(0,100)})}catch{}}return t.sort((r,s)=>s.modifiedAt.localeCompare(r.modifiedAt))}async createFile(e,t){if(!zs(e))return{ok:!1,message:`Invalid filename: "${e}". Use kebab-case .md files (e.g. "project-notes.md").`};if(!Vs(t))return{ok:!1,message:"Content rejected: potential injection detected."};if(t.length>Ks)return{ok:!1,message:`Content too long (${t.length} chars, max ${Ks}).`};let r=st(this.root,e);if(yt(r))return{ok:!1,message:`File already exists: "${e}". Use write_file to update.`};await this.ensureDir(),await Mn(r,t);let s=`- [${e}] \u2014 created ${new Date().toISOString().slice(0,10)}`;return await this.appendIndexEntry(s),{ok:!0,message:`Created "${e}" (${t.length} chars). Entry added to INDEX.md.`,file:e}}async writeFile(e,t){if(!zs(e))return{ok:!1,message:`Invalid filename: "${e}". Use kebab-case .md files.`};if(!Vs(t))return{ok:!1,message:"Content rejected: potential injection detected."};if(t.length>Ks)return this.writeFileSplit(e,t);let r=st(this.root,e),s=!yt(r);if(await this.ensureDir(),await Mn(r,t),s){let o=`- [${e}] \u2014 created ${new Date().toISOString().slice(0,10)}`;await this.appendIndexEntry(o)}return{ok:!0,message:`${s?"Created":"Updated"} "${e}" (${t.length} chars).`,file:e}}async writeFileSplit(e,t){let r=e.replace(/\.md$/,""),s=t.split(/\n{2,}/),o=[],i="";for(let l of s)i.length+l.length+2>Ks*.9&&i.length>0?(o.push(i),i=l):i=i?i+`
|
|
822
822
|
|
|
823
823
|
`+l:l;i&&o.push(i);let a=[];for(let l=0;l<o.length;l++){let d=`${r}-${l+1}.md`,u=st(this.root,d);await this.ensureDir(),await Mn(u,o[l]),a.push(d)}let c=this.getIndexRaw();for(let l of a)if(!c.includes(`[${l}]`)){let d=`- [${l}] \u2014 auto-split ${new Date().toISOString().slice(0,10)}`;await this.appendIndexEntry(d)}return{ok:!0,message:`Auto-split "${e}" into ${o.length} parts (${t.length} chars total): ${a.join(", ")}`,file:a[0]}}async readFile(e){if(!zs(e)&&e!==Qt)return{ok:!1,message:`Invalid filename: "${e}".`};let t=st(this.root,e);try{let r=await Nc(t,"utf-8");return{ok:!0,content:r,message:`Read "${e}" (${r.length} chars).`}}catch(r){return r.code==="ENOENT"?{ok:!1,message:`File not found: "${e}".`}:{ok:!1,message:`Error reading "${e}": ${r.message}`}}}async deleteFile(e){if(e===Qt)return{ok:!1,message:"Cannot delete INDEX.md. Use 'remove' to clear entries."};if(!zs(e))return{ok:!1,message:`Invalid filename: "${e}".`};let t=st(this.root,e);if(!yt(t))return{ok:!1,message:`File not found: "${e}".`};await CP(t);let r=this.getIndexRaw(),s=new RegExp(`^.*\\[${UP(e)}\\].*$\\n?`,"m");if(s.test(r)){let o=r.replace(s,"").replace(/\n{3,}/g,`
|
|
824
824
|
|
|
825
|
-
`);await this.writeIndex(o)}return{ok:!0,message:`Deleted "${e}" and removed INDEX.md entry.`,file:e}}async searchLocal(e){if(!yt(this.root))return[];let t=e.toLowerCase().split(/\s+/).filter(o=>o.length>1);if(t.length===0)return[];let r=await
|
|
825
|
+
`);await this.writeIndex(o)}return{ok:!0,message:`Deleted "${e}" and removed INDEX.md entry.`,file:e}}async searchLocal(e){if(!yt(this.root))return[];let t=e.toLowerCase().split(/\s+/).filter(o=>o.length>1);if(t.length===0)return[];let r=await Ng(this.root),s=[];for(let o of r){if(!o.endsWith(".md"))continue;let i=st(this.root,o);try{let a=await Nc(i,"utf-8"),c=a.toLowerCase(),l=t.filter(m=>c.includes(m)).length;if(l===0)continue;let d=a.split(`
|
|
826
826
|
`),u="",p=0;for(let m of d){let h=m.toLowerCase(),f=t.filter(y=>h.includes(y)).length;f>p&&(p=f,u=m.trim())}s.push({file:o,snippet:u.slice(0,200),score:l/t.length})}catch{}}return s.sort((o,i)=>i.score-o.score).slice(0,10)}async writeIndex(e){await this.ensureDir(),await Mn(st(this.root,Qt),e),this.indexCache=e}async ensureDir(){yt(this.root)||await NP(this.root,{recursive:!0})}async appendIndexEntry(e){let t=this.getIndexRaw();if(t.includes(e))return;let r=t.endsWith(`
|
|
827
827
|
`)?t+e+`
|
|
828
828
|
`:t+`
|
|
829
829
|
`+e+`
|
|
830
|
-
`;Buffer.byteLength(r,"utf-8")<=Ie&&await this.writeIndex(r)}};function jP(n,e){let t=st(n,"..");yt(t)||Dg(t,{recursive:!0}),DP(n,e,"utf-8")}function UP(n){return n.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function Og(){return{toolUseCount:0,latestInputTokens:0,cumulativeOutputTokens:0,recentActivities:[]}}function FP(n){return n.latestInputTokens+n.cumulativeOutputTokens}var BP=new Set(["grep","glob","search","Grep","Glob","list_dir","find_files"]),Lg=new Set(["read_file","file_read","cat","head","tail","FileRead"]);function HP(n){return{isSearch:BP.has(n)||void 0,isRead:Lg.has(n)||void 0}}function qP(n,e){let t=e.file_path??e.path??e.filePath;if(typeof t=="string")return`${Lg.has(n)?"Reading":n.includes("write")||n.includes("edit")?"Editing":"Using"} ${t}`;let r=e.command??e.cmd;if(typeof r=="string")return`Running: ${r.length>60?r.slice(0,60)+"\u2026":r}`;let s=e.query??e.pattern??e.search;if(typeof s=="string")return`Searching: ${s}`}function $g(n,e){n.latestInputTokens=(e.input_tokens??0)+(e.cache_creation_input_tokens??0)+(e.cache_read_input_tokens??0),n.cumulativeOutputTokens+=e.output_tokens??0}function jg(n,e,t,r){n.toolUseCount++;let s=HP(e),o={toolName:e,input:t,activityDescription:r?.(e,t)??qP(e,t),isSearch:s.isSearch,isRead:s.isRead};for(n.recentActivities.push(o);n.recentActivities.length>5;)n.recentActivities.shift()}function Lc(n){return{toolUseCount:n.toolUseCount,tokenCount:FP(n),lastActivity:n.recentActivities.length>0?n.recentActivities[n.recentActivities.length-1]:void 0,recentActivities:[...n.recentActivities]}}import{randomUUID as Ug}from"node:crypto";function WP(n){let e=new AbortController;return n&&(n.aborted?e.abort(n.reason):n.addEventListener("abort",()=>{e.abort(n.reason)},{once:!0})),e}async function $c(n){let e=Date.now(),t=[],r={inputTokens:0,outputTokens:0},s=Og(),{promptMessages:o,systemPrompt:i,tools:a,canUseTool:c,transport:l,toolInvoker:d,apiKey:u,model:p,log:m,hooks:h,forkLabel:f,maxTurns:y,temperature:b,parentSignal:k,onEvent:A,onProgress:_,budgetTokens:I,parentDepth:N}=n,L=WP(k),F=`fork-${f}-${Ug().slice(0,8)}`,T=`fork-session-${Ug().slice(0,8)}`;m.info(`[fork:${f}] starting \u2014 ${o.length} initial messages, model=${p}`);let ce=c?{invoke:async(oe,$e,te,J)=>{let R={};try{R=JSON.parse(te)}catch{}let B=c($e,R);return B.allowed?d.invoke(oe,$e,te,J):(m.info(`[fork:${f}] tool ${$e} denied: ${B.reason}`),{result:"",error:B.reason})}}:d,le=!0,j;try{let{Agent:oe}=await Promise.resolve().then(()=>(ia(),Zd)),$e=new oe({llmTransport:l,apiKey:u,toolInvoker:ce,log:m,hooks:h,maxRounds:y});for await(let te of $e.run({turnId:F,sessionId:T,messages:o,tools:a,systemPrompt:i,config:{model:p,apiKey:u,temperature:b,maxOutputTokens:n.maxOutputTokens,parentDepth:N}},L.signal)){if(t.push(te),A?.(te),te.type==="end"&&te.usage&&($g(s,{input_tokens:te.usage.inputTokens,output_tokens:te.usage.outputTokens}),r.inputTokens+=te.usage.inputTokens,r.outputTokens+=te.usage.outputTokens,te.usage.cacheRead&&(r.cacheRead=(r.cacheRead??0)+te.usage.cacheRead),te.usage.cacheWrite&&(r.cacheWrite=(r.cacheWrite??0)+te.usage.cacheWrite),I&&I>0)){let J=r.inputTokens+r.outputTokens+(r.reasoningTokens??0);J>=I&&(m.info(`[fork:${f}] budget exceeded (${J} / ${I} tokens), aborting`),L.abort("budget_exceeded"))}if(te.type==="tool_call"){let J={};try{J=JSON.parse(te.arguments??"{}")}catch{}jg(s,te.name,J),_?.(Lc(s))}te.type==="error"&&(le=!1,j=te.error)}}catch(oe){le=!1,j=oe instanceof Error?oe.message:String(oe),m.warn(`[fork:${f}] error: ${j}`)}finally{L.signal.aborted||L.abort("fork_complete")}let ve=Date.now()-e;return m.info(`[fork:${f}] finished in ${ve}ms \u2014 ${t.length} events, usage: prompt=${r.inputTokens} completion=${r.outputTokens}, ok=${le}`),{events:t,totalUsage:r,progress:Lc(s),durationMs:ve,ok:le,error:j}}Wi();Hi();je();var jc=class{teamBudget={tokensUsed:0,budgetTokens:mi};isTeamBudgetExceeded(){return this.teamBudget.budgetTokens>0&&this.teamBudget.tokensUsed>=this.teamBudget.budgetTokens}recordForkTokens(e){return this.teamBudget.tokensUsed+=e,this.teamBudget.tokensUsed}teamBudgetExceededError(){return`Team budget exceeded (${this.teamBudget.tokensUsed} / ${this.teamBudget.budgetTokens} tokens). No more sub-agents allowed.`}dream={idleMinutes:30,enabled:!1,lastDreamAt:0,cooldownMs:14400*1e3,maxDurationMs:300*1e3};resetAccumulators(){this.teamBudget.tokensUsed=0}},Re=new jc;ae();import{readFile as GP}from"node:fs/promises";import{watch as KP}from"node:fs";import{join as VP}from"node:path";var zP=qe,XP="settings.json";function YP(n){return VP(n,zP,XP)}async function JP(n){try{let e=await GP(n,"utf-8");return JSON.parse(e)}catch{return null}}function QP(n,e,t,r){let s=!1;n.permissionMode&&n.permissionMode!==e.getMode()&&(e.setMode(n.permissionMode),r?.(`settings: permission mode \u2192 ${n.permissionMode}`),s=!0),n.permissionRules&&(e.replaceRules(n.permissionRules),r?.(`settings: ${n.permissionRules.length} permission rules loaded`),s=!0),n.defaultBehavior&&(e.setDefaultBehavior(n.defaultBehavior),r?.(`settings: default behavior \u2192 ${n.defaultBehavior}`),s=!0),s&&t&&t.invoke("config.changed",{sessionId:"",key:"permissions",oldValue:void 0,newValue:n}).catch(()=>{})}function Fg(n){let e=YP(n.projectRoot),t=null,r=null,s=async()=>{let o=await JP(e);o&&QP(o,n.ruleEngine,n.hooks,n.log)};s().catch(()=>{});try{t=KP(e,{persistent:!1},o=>{r&&clearTimeout(r),r=setTimeout(()=>{s().catch(()=>{})},200)}),t.on("error",()=>{})}catch{}return()=>{r&&clearTimeout(r),t?.close(),t=null}}var Uc=new Set;function gn(n){return Uc.add(n),()=>{Uc.delete(n)}}async function Bg(){await Promise.all(Array.from(Uc).map(n=>n()))}ae();dt();var Xs="\u65E0\u6CD5\u8FDE\u63A5 llmrouter \u6A21\u578B\u76EE\u5F55",Dn=class extends Error{constructor(e=Xs){super(e),this.name="LlmrouterCatalogUnavailableError"}};function ZP(){let n=process.env.QLOGIC_LLMROUTER_BASE_URL?.trim().replace(/\/+$/,"");if(!n)throw new Dn;return n}function eI(){let n={accept:"application/json"},e=process.env.QLOGIC_LLMROUTER_ACCESS_TOKEN?.trim();return e&&(n.authorization=`Bearer ${e}`),n}async function Hg(n){let e=ZP(),t;try{t=await fetch(`${e}${n}`,{method:"GET",headers:eI(),signal:AbortSignal.timeout(1e4)})}catch{throw new Dn}if(!t.ok)throw new Dn;let r=await t.json().catch(()=>null),s=Array.isArray(r)?r:oI(r)&&Array.isArray(r.data)?r.data:null;if(!s)throw new Dn;return s}async function Ys(){return Hg("/ext/model-catalog/providers")}async function tI(){return Hg("/ext/model-catalog/models")}function Fc(n){let e={zhipu:"Zhipu GLM","zhipu-openai":"Zhipu GLM OpenAI","zhipu-coding":"Zhipu GLM Coding",volcengine:"Doubao / Volcengine"};return e[n.id]?e[n.id]:n.displayName??n.name??n.id}function Js(n){return n.baseUrl??n.base_url}async function Bc(n){return(await Ys()).find(t=>t.id===n)??null}async function _r(n){let e=await tI();n.migrateModelIds(nI(e));let t=e.map(rI).filter(r=>!!r);return n.replaceCatalogModels(t),t}function nI(n){let e=new Map;for(let t of n){let r=t.provider??t.owned_by,s=t.public_model??t.publicModel??t.id,o=t.native_model_id??t.nativeModelId??t.id;if(!r||!s||!o)continue;let i=`${r}:${s}`;for(let a of[o,t.id])!a||a===s||e.set(`${r}:${a}`,i)}return e}function rI(n){let e=n.provider??n.owned_by,t=n.public_model??n.publicModel??n.id,r=n.native_model_id??n.nativeModelId??n.id;return!e||!t||!r?null:{id:`${e}:${t}`,provider:e,model:t,displayName:n.display_name??n.displayName??n.name??n.id,purposes:sI(n.purposes,n.category),baseUrl:n.baseUrl??n.base_url,enabled:!0,nativeModelId:r,transport:n.provider_transport??n.providerTransport,contextWindow:n.context_window??n.contextWindow,maxOutput:n.max_output??n.maxOutput,streamRequired:n.stream_required??n.streamRequired,capabilities:n.capabilities,pricing:n.pricing}}function sI(n,e){let t=[...n??[],e].filter(o=>!!o),r=new Set(["textGeneration","smallModel","stt","tts","imageGeneration","imageUnderstanding","videoGeneration","videoUnderstanding","threeDGeneration","embedding","voiceClone","musicGeneration","realtimeAudio","realtimeVideo"]),s=t.filter(o=>r.has(o));return[...new Set(s.length?s:["textGeneration"])]}function oI(n){return!!n&&typeof n=="object"&&!Array.isArray(n)}je();import{join as Hc}from"node:path";import{mkdirSync as iI,existsSync as aI,createWriteStream as cI}from"node:fs";import{pipeline as lI}from"node:stream/promises";import{Readable as dI}from"node:stream";var uI=ki,pI=Si,qg={"image/png":".png","image/jpeg":".jpg","image/gif":".gif","image/webp":".webp","image/svg+xml":".svg","image/avif":".avif","video/mp4":".mp4","video/webm":".webm","video/quicktime":".mov","audio/mpeg":".mp3","audio/wav":".wav","audio/ogg":".ogg","audio/aac":".aac","audio/mp4":".m4a","audio/flac":".flac","application/pdf":".pdf","model/gltf-binary":".glb","model/gltf+json":".gltf"},Qs=class{projectDir;maxFileSize;timeoutMs;constructor(e){this.projectDir=e?.projectDir??null,this.maxFileSize=e?.maxFileSize??uI,this.timeoutMs=e?.timeoutMs??pI}setProjectDir(e){this.projectDir=e}resolveMediaDir(e){if(!this.projectDir)throw new Error("MediaPersistence requires projectDir \u2014 call setProjectDir() first");if(!e)return Hc(this.projectDir,".qlogicagent","media",mI());let t=e.replace(/[^a-zA-Z0-9_-]/g,"_");return t!==e&&t.length>0&&[...e].filter(s=>!/[a-zA-Z0-9_-]/.test(s)).length>e.length/2&&console.warn(`[media-persistence] sessionId heavily sanitized: "${e}" \u2192 "${t}" \u2014 potential collision risk`),Hc(this.projectDir,".qlogicagent","sessions",t,"media")}async download(e,t){let r=this.resolveMediaDir(t?.sessionId);if(r.length+60>255)throw new Error(`Media path too long (${r.length} chars) \u2014 would exceed OS limit. Use a shorter project path or session ID.`);aI(r)||iI(r,{recursive:!0});let s=new AbortController,o=setTimeout(()=>s.abort(),this.timeoutMs),i="";try{let a=await fetch(e,{signal:s.signal});if(!a.ok)throw new Error(`Download failed: ${a.status} ${a.statusText}`);let c=parseInt(a.headers.get("content-length")??"0",10);if(c>this.maxFileSize)throw new Error(`File too large: ${c} bytes (max: ${this.maxFileSize})`);let l=a.headers.get("content-type")?.split(";")[0].trim()||"application/octet-stream",d=fI(e,l),u=gI(t?.type??hI(l),d);i=Hc(r,u);let p=a.body;if(!p)throw new Error("No response body");let m=cI(i);await lI(dI.fromWeb(p),m);let{size:h}=await import("node:fs/promises").then(f=>f.stat(i));if(h===0)throw await import("node:fs/promises").then(f=>f.unlink(i).catch(()=>{})),new Error("Download produced empty file (connection dropped)");return{remoteUrl:e,localPath:i,bytes:h,mimeType:l}}catch(a){if(i)try{let{unlink:c}=await import("node:fs/promises");await c(i)}catch{}throw a}finally{clearTimeout(o)}}async downloadAll(e,t,r){let s=[];for(let o of e)try{let i=await this.download(o,t);s.push(i)}catch(i){r?.warn(`media-persistence: failed to download ${o}: ${i.message}`)}return s}getMediaDir(e){return this.resolveMediaDir(e)}getProjectDir(){return this.projectDir}};function mI(){let n=new Date;return`${n.getFullYear()}${String(n.getMonth()+1).padStart(2,"0")}${String(n.getDate()).padStart(2,"0")}`}function gI(n,e){let t=new Date,r=`${t.getFullYear()}${String(t.getMonth()+1).padStart(2,"0")}${String(t.getDate()).padStart(2,"0")}_${String(t.getHours()).padStart(2,"0")}${String(t.getMinutes()).padStart(2,"0")}${String(t.getSeconds()).padStart(2,"0")}`,s=Math.random().toString(36).slice(2,6);return`${n}_${r}_${s}${e}`}function fI(n,e){if(qg[e])return qg[e];try{let t=new URL(n).pathname,r=t.lastIndexOf(".");if(r>0){let s=t.slice(r).toLowerCase().split("?")[0];if(s.length<=5)return s}}catch{}return".bin"}function hI(n){return n.startsWith("image/")?"image":n.startsWith("video/")?"video":n.startsWith("audio/")?"audio":n.startsWith("model/")?"3d":"file"}import{join as yI}from"node:path";import{readFileSync as bI,writeFileSync as vI,mkdirSync as kI}from"node:fs";var fn=null,qc=!1;function Wg(n){return yI(n,"skill-stats.json")}function Wc(n){if(fn)return fn;try{fn=JSON.parse(bI(Wg(n),"utf8"))}catch{fn={}}return fn}function SI(n){if(!(!qc||!fn))try{kI(n,{recursive:!0}),vI(Wg(n),JSON.stringify(fn,null,2),"utf8"),qc=!1}catch{}}function Zs(n,e,t){let r=Wc(n);r[e]||(r[e]={invokeCount:0,activeCount:0,positiveCount:0,negativeCount:0}),r[e].invokeCount++,r[e].lastUsedAt=new Date().toISOString(),t?r[e].positiveCount++:r[e].negativeCount++,r[e].invokeCount>0&&(r[e].successRate=(r[e].invokeCount-r[e].negativeCount)/r[e].invokeCount),qc=!0,SI(n)}function Gg(n,e){return Wc(n)[e]}function Kg(n){return Wc(n)}import{existsSync as TI,readFileSync as RI,writeFileSync as AI,mkdirSync as zg,renameSync as wI}from"node:fs";import{join as Gc,dirname as Xg}from"node:path";var Vg=30,xI=90,PI="skill-lifecycle.json";function Yg(n){return Gc(n,PI)}function Be(n){let e=Yg(n);try{return JSON.parse(RI(e,"utf8"))}catch{return{version:1,records:{}}}}function We(n,e){let t=Yg(n);zg(Xg(t),{recursive:!0});let r=t+".tmp";AI(r,JSON.stringify(e,null,2),"utf8");let{renameSync:s}=Mo("node:fs");s(r,t)}function qt(n,e,t="learned"){return n.records[e]||(n.records[e]={name:e,state:"active",createdAt:new Date().toISOString(),pinned:!1,useCount:0,source:t}),n.records[e]}function Kc(n,e){let t=qt(n,e);t.lastUsedAt=new Date().toISOString(),t.useCount++,t.state==="stale"&&(t.state="active",t.staleAt=void 0)}function Vc(n,e){let t=qt(n,e);t.lastPatchedAt=new Date().toISOString(),t.state==="stale"&&(t.state="active",t.staleAt=void 0)}function Jg(n,e){let t=n.records[e];return t?(t.pinned=!0,!0):!1}function Qg(n,e){let t=n.records[e];return t?(t.pinned=!1,!0):!1}function II(n){let e=[n.lastUsedAt,n.lastViewedAt,n.lastPatchedAt,n.createdAt].filter(Boolean).map(t=>new Date(t));return new Date(Math.max(...e.map(t=>t.getTime())))}function _I(n){let e=Date.now(),t={transitioned:[],skippedPinned:[]};for(let[r,s]of Object.entries(n.records)){if(s.source==="installed")continue;if(s.pinned){s.state!=="active"&&t.skippedPinned.push(r);continue}let o=II(s),i=(e-o.getTime())/(1e3*60*60*24);s.state==="active"&&i>=Vg?(s.state="stale",s.staleAt=new Date().toISOString(),t.transitioned.push({name:r,from:"active",to:"stale"})):s.state==="stale"&&i>=xI?(s.state="archived",s.archivedAt=new Date().toISOString(),t.transitioned.push({name:r,from:"stale",to:"archived"})):s.state==="stale"&&i<Vg&&(s.state="active",s.staleAt=void 0,t.transitioned.push({name:r,from:"stale",to:"active"}))}return t}function EI(n,e){let t=Gc(n,e);if(!TI(t))return!1;let r=Gc(n,".archive",e);zg(Xg(r),{recursive:!0});try{return wI(t,r),!0}catch{return!1}}function Zg(n,e){let t=Be(n),r=_I(t);for(let s of r.transitioned)s.to==="archived"&&EI(e,s.name);return We(n,t),r}function ef(n,e){return Object.values(n.records).filter(t=>t.state===e)}function eo(n,e){delete n.records[e]}function CI(n){let e=n.replace(/\r\n/g,`
|
|
830
|
+
`;Buffer.byteLength(r,"utf-8")<=Ie&&await this.writeIndex(r)}};function jP(n,e){let t=st(n,"..");yt(t)||Og(t,{recursive:!0}),DP(n,e,"utf-8")}function UP(n){return n.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function Lg(){return{toolUseCount:0,latestInputTokens:0,cumulativeOutputTokens:0,recentActivities:[]}}function FP(n){return n.latestInputTokens+n.cumulativeOutputTokens}var BP=new Set(["grep","glob","search","Grep","Glob","list_dir","find_files"]),$g=new Set(["read_file","file_read","cat","head","tail","FileRead"]);function HP(n){return{isSearch:BP.has(n)||void 0,isRead:$g.has(n)||void 0}}function qP(n,e){let t=e.file_path??e.path??e.filePath;if(typeof t=="string")return`${$g.has(n)?"Reading":n.includes("write")||n.includes("edit")?"Editing":"Using"} ${t}`;let r=e.command??e.cmd;if(typeof r=="string")return`Running: ${r.length>60?r.slice(0,60)+"\u2026":r}`;let s=e.query??e.pattern??e.search;if(typeof s=="string")return`Searching: ${s}`}function jg(n,e){n.latestInputTokens=(e.input_tokens??0)+(e.cache_creation_input_tokens??0)+(e.cache_read_input_tokens??0),n.cumulativeOutputTokens+=e.output_tokens??0}function Ug(n,e,t,r){n.toolUseCount++;let s=HP(e),o={toolName:e,input:t,activityDescription:r?.(e,t)??qP(e,t),isSearch:s.isSearch,isRead:s.isRead};for(n.recentActivities.push(o);n.recentActivities.length>5;)n.recentActivities.shift()}function Lc(n){return{toolUseCount:n.toolUseCount,tokenCount:FP(n),lastActivity:n.recentActivities.length>0?n.recentActivities[n.recentActivities.length-1]:void 0,recentActivities:[...n.recentActivities]}}import{randomUUID as Fg}from"node:crypto";function WP(n){let e=new AbortController;return n&&(n.aborted?e.abort(n.reason):n.addEventListener("abort",()=>{e.abort(n.reason)},{once:!0})),e}async function $c(n){let e=Date.now(),t=[],r={inputTokens:0,outputTokens:0},s=Lg(),{promptMessages:o,systemPrompt:i,tools:a,canUseTool:c,transport:l,toolInvoker:d,apiKey:u,model:p,log:m,hooks:h,forkLabel:f,maxTurns:y,temperature:b,parentSignal:k,onEvent:A,onProgress:_,budgetTokens:I,parentDepth:N}=n,L=WP(k),F=`fork-${f}-${Fg().slice(0,8)}`,T=`fork-session-${Fg().slice(0,8)}`;m.info(`[fork:${f}] starting \u2014 ${o.length} initial messages, model=${p}`);let ce=c?{invoke:async(oe,$e,te,J)=>{let R={};try{R=JSON.parse(te)}catch{}let B=c($e,R);return B.allowed?d.invoke(oe,$e,te,J):(m.info(`[fork:${f}] tool ${$e} denied: ${B.reason}`),{result:"",error:B.reason})}}:d,le=!0,j;try{let{Agent:oe}=await Promise.resolve().then(()=>(ia(),eu)),$e=new oe({llmTransport:l,apiKey:u,toolInvoker:ce,log:m,hooks:h,maxRounds:y});for await(let te of $e.run({turnId:F,sessionId:T,messages:o,tools:a,systemPrompt:i,config:{model:p,apiKey:u,temperature:b,maxOutputTokens:n.maxOutputTokens,parentDepth:N}},L.signal)){if(t.push(te),A?.(te),te.type==="end"&&te.usage&&(jg(s,{input_tokens:te.usage.inputTokens,output_tokens:te.usage.outputTokens}),r.inputTokens+=te.usage.inputTokens,r.outputTokens+=te.usage.outputTokens,te.usage.cacheRead&&(r.cacheRead=(r.cacheRead??0)+te.usage.cacheRead),te.usage.cacheWrite&&(r.cacheWrite=(r.cacheWrite??0)+te.usage.cacheWrite),I&&I>0)){let J=r.inputTokens+r.outputTokens+(r.reasoningTokens??0);J>=I&&(m.info(`[fork:${f}] budget exceeded (${J} / ${I} tokens), aborting`),L.abort("budget_exceeded"))}if(te.type==="tool_call"){let J={};try{J=JSON.parse(te.arguments??"{}")}catch{}Ug(s,te.name,J),_?.(Lc(s))}te.type==="error"&&(le=!1,j=te.error)}}catch(oe){le=!1,j=oe instanceof Error?oe.message:String(oe),m.warn(`[fork:${f}] error: ${j}`)}finally{L.signal.aborted||L.abort("fork_complete")}let ve=Date.now()-e;return m.info(`[fork:${f}] finished in ${ve}ms \u2014 ${t.length} events, usage: prompt=${r.inputTokens} completion=${r.outputTokens}, ok=${le}`),{events:t,totalUsage:r,progress:Lc(s),durationMs:ve,ok:le,error:j}}Wi();Hi();je();var jc=class{teamBudget={tokensUsed:0,budgetTokens:mi};isTeamBudgetExceeded(){return this.teamBudget.budgetTokens>0&&this.teamBudget.tokensUsed>=this.teamBudget.budgetTokens}recordForkTokens(e){return this.teamBudget.tokensUsed+=e,this.teamBudget.tokensUsed}teamBudgetExceededError(){return`Team budget exceeded (${this.teamBudget.tokensUsed} / ${this.teamBudget.budgetTokens} tokens). No more sub-agents allowed.`}dream={idleMinutes:30,enabled:!1,lastDreamAt:0,cooldownMs:14400*1e3,maxDurationMs:300*1e3};resetAccumulators(){this.teamBudget.tokensUsed=0}},Re=new jc;ae();import{readFile as GP}from"node:fs/promises";import{watch as KP}from"node:fs";import{join as VP}from"node:path";var zP=qe,XP="settings.json";function YP(n){return VP(n,zP,XP)}async function JP(n){try{let e=await GP(n,"utf-8");return JSON.parse(e)}catch{return null}}function QP(n,e,t,r){let s=!1;n.permissionMode&&n.permissionMode!==e.getMode()&&(e.setMode(n.permissionMode),r?.(`settings: permission mode \u2192 ${n.permissionMode}`),s=!0),n.permissionRules&&(e.replaceRules(n.permissionRules),r?.(`settings: ${n.permissionRules.length} permission rules loaded`),s=!0),n.defaultBehavior&&(e.setDefaultBehavior(n.defaultBehavior),r?.(`settings: default behavior \u2192 ${n.defaultBehavior}`),s=!0),s&&t&&t.invoke("config.changed",{sessionId:"",key:"permissions",oldValue:void 0,newValue:n}).catch(()=>{})}function Bg(n){let e=YP(n.projectRoot),t=null,r=null,s=async()=>{let o=await JP(e);o&&QP(o,n.ruleEngine,n.hooks,n.log)};s().catch(()=>{});try{t=KP(e,{persistent:!1},o=>{r&&clearTimeout(r),r=setTimeout(()=>{s().catch(()=>{})},200)}),t.on("error",()=>{})}catch{}return()=>{r&&clearTimeout(r),t?.close(),t=null}}var Uc=new Set;function gn(n){return Uc.add(n),()=>{Uc.delete(n)}}async function Hg(){await Promise.all(Array.from(Uc).map(n=>n()))}ae();dt();var Xs="\u65E0\u6CD5\u8FDE\u63A5 llmrouter \u6A21\u578B\u76EE\u5F55",Dn=class extends Error{constructor(e=Xs){super(e),this.name="LlmrouterCatalogUnavailableError"}};function ZP(){let n=process.env.QLOGIC_LLMROUTER_BASE_URL?.trim().replace(/\/+$/,"");if(!n)throw new Dn;return n}function eI(){let n={accept:"application/json"},e=process.env.QLOGIC_LLMROUTER_ACCESS_TOKEN?.trim();return e&&(n.authorization=`Bearer ${e}`),n}async function qg(n){let e=ZP(),t;try{t=await fetch(`${e}${n}`,{method:"GET",headers:eI(),signal:AbortSignal.timeout(1e4)})}catch{throw new Dn}if(!t.ok)throw new Dn;let r=await t.json().catch(()=>null),s=Array.isArray(r)?r:oI(r)&&Array.isArray(r.data)?r.data:null;if(!s)throw new Dn;return s}async function Ys(){return qg("/ext/model-catalog/providers")}async function tI(){return qg("/ext/model-catalog/models")}function Fc(n){let e={zhipu:"Zhipu GLM","zhipu-openai":"Zhipu GLM OpenAI","zhipu-coding":"Zhipu GLM Coding",volcengine:"Doubao / Volcengine"};return e[n.id]?e[n.id]:n.displayName??n.name??n.id}function Js(n){return n.baseUrl??n.base_url}async function Bc(n){return(await Ys()).find(t=>t.id===n)??null}async function _r(n){let e=await tI();n.migrateModelIds(nI(e));let t=e.map(rI).filter(r=>!!r);return n.replaceCatalogModels(t),t}function nI(n){let e=new Map;for(let t of n){let r=t.provider??t.owned_by,s=t.public_model??t.publicModel??t.id,o=t.native_model_id??t.nativeModelId??t.id;if(!r||!s||!o)continue;let i=`${r}:${s}`;for(let a of[o,t.id])!a||a===s||e.set(`${r}:${a}`,i)}return e}function rI(n){let e=n.provider??n.owned_by,t=n.public_model??n.publicModel??n.id,r=n.native_model_id??n.nativeModelId??n.id;return!e||!t||!r?null:{id:`${e}:${t}`,provider:e,model:t,displayName:n.display_name??n.displayName??n.name??n.id,purposes:sI(n.purposes,n.category),baseUrl:n.baseUrl??n.base_url,enabled:!0,nativeModelId:r,transport:n.provider_transport??n.providerTransport,contextWindow:n.context_window??n.contextWindow,maxOutput:n.max_output??n.maxOutput,streamRequired:n.stream_required??n.streamRequired,capabilities:n.capabilities,pricing:n.pricing}}function sI(n,e){let t=[...n??[],e].filter(o=>!!o),r=new Set(["textGeneration","smallModel","stt","tts","imageGeneration","imageUnderstanding","videoGeneration","videoUnderstanding","threeDGeneration","embedding","voiceClone","musicGeneration","realtimeAudio","realtimeVideo"]),s=t.filter(o=>r.has(o));return[...new Set(s.length?s:["textGeneration"])]}function oI(n){return!!n&&typeof n=="object"&&!Array.isArray(n)}je();import{join as Hc}from"node:path";import{mkdirSync as iI,existsSync as aI,createWriteStream as cI}from"node:fs";import{pipeline as lI}from"node:stream/promises";import{Readable as dI}from"node:stream";var uI=ki,pI=Si,Wg={"image/png":".png","image/jpeg":".jpg","image/gif":".gif","image/webp":".webp","image/svg+xml":".svg","image/avif":".avif","video/mp4":".mp4","video/webm":".webm","video/quicktime":".mov","audio/mpeg":".mp3","audio/wav":".wav","audio/ogg":".ogg","audio/aac":".aac","audio/mp4":".m4a","audio/flac":".flac","application/pdf":".pdf","model/gltf-binary":".glb","model/gltf+json":".gltf"},Qs=class{projectDir;maxFileSize;timeoutMs;constructor(e){this.projectDir=e?.projectDir??null,this.maxFileSize=e?.maxFileSize??uI,this.timeoutMs=e?.timeoutMs??pI}setProjectDir(e){this.projectDir=e}resolveMediaDir(e){if(!this.projectDir)throw new Error("MediaPersistence requires projectDir \u2014 call setProjectDir() first");if(!e)return Hc(this.projectDir,".qlogicagent","media",mI());let t=e.replace(/[^a-zA-Z0-9_-]/g,"_");return t!==e&&t.length>0&&[...e].filter(s=>!/[a-zA-Z0-9_-]/.test(s)).length>e.length/2&&console.warn(`[media-persistence] sessionId heavily sanitized: "${e}" \u2192 "${t}" \u2014 potential collision risk`),Hc(this.projectDir,".qlogicagent","sessions",t,"media")}async download(e,t){let r=this.resolveMediaDir(t?.sessionId);if(r.length+60>255)throw new Error(`Media path too long (${r.length} chars) \u2014 would exceed OS limit. Use a shorter project path or session ID.`);aI(r)||iI(r,{recursive:!0});let s=new AbortController,o=setTimeout(()=>s.abort(),this.timeoutMs),i="";try{let a=await fetch(e,{signal:s.signal});if(!a.ok)throw new Error(`Download failed: ${a.status} ${a.statusText}`);let c=parseInt(a.headers.get("content-length")??"0",10);if(c>this.maxFileSize)throw new Error(`File too large: ${c} bytes (max: ${this.maxFileSize})`);let l=a.headers.get("content-type")?.split(";")[0].trim()||"application/octet-stream",d=fI(e,l),u=gI(t?.type??hI(l),d);i=Hc(r,u);let p=a.body;if(!p)throw new Error("No response body");let m=cI(i);await lI(dI.fromWeb(p),m);let{size:h}=await import("node:fs/promises").then(f=>f.stat(i));if(h===0)throw await import("node:fs/promises").then(f=>f.unlink(i).catch(()=>{})),new Error("Download produced empty file (connection dropped)");return{remoteUrl:e,localPath:i,bytes:h,mimeType:l}}catch(a){if(i)try{let{unlink:c}=await import("node:fs/promises");await c(i)}catch{}throw a}finally{clearTimeout(o)}}async downloadAll(e,t,r){let s=[];for(let o of e)try{let i=await this.download(o,t);s.push(i)}catch(i){r?.warn(`media-persistence: failed to download ${o}: ${i.message}`)}return s}getMediaDir(e){return this.resolveMediaDir(e)}getProjectDir(){return this.projectDir}};function mI(){let n=new Date;return`${n.getFullYear()}${String(n.getMonth()+1).padStart(2,"0")}${String(n.getDate()).padStart(2,"0")}`}function gI(n,e){let t=new Date,r=`${t.getFullYear()}${String(t.getMonth()+1).padStart(2,"0")}${String(t.getDate()).padStart(2,"0")}_${String(t.getHours()).padStart(2,"0")}${String(t.getMinutes()).padStart(2,"0")}${String(t.getSeconds()).padStart(2,"0")}`,s=Math.random().toString(36).slice(2,6);return`${n}_${r}_${s}${e}`}function fI(n,e){if(Wg[e])return Wg[e];try{let t=new URL(n).pathname,r=t.lastIndexOf(".");if(r>0){let s=t.slice(r).toLowerCase().split("?")[0];if(s.length<=5)return s}}catch{}return".bin"}function hI(n){return n.startsWith("image/")?"image":n.startsWith("video/")?"video":n.startsWith("audio/")?"audio":n.startsWith("model/")?"3d":"file"}import{join as yI}from"node:path";import{readFileSync as bI,writeFileSync as vI,mkdirSync as kI}from"node:fs";var fn=null,qc=!1;function Gg(n){return yI(n,"skill-stats.json")}function Wc(n){if(fn)return fn;try{fn=JSON.parse(bI(Gg(n),"utf8"))}catch{fn={}}return fn}function SI(n){if(!(!qc||!fn))try{kI(n,{recursive:!0}),vI(Gg(n),JSON.stringify(fn,null,2),"utf8"),qc=!1}catch{}}function Zs(n,e,t){let r=Wc(n);r[e]||(r[e]={invokeCount:0,activeCount:0,positiveCount:0,negativeCount:0}),r[e].invokeCount++,r[e].lastUsedAt=new Date().toISOString(),t?r[e].positiveCount++:r[e].negativeCount++,r[e].invokeCount>0&&(r[e].successRate=(r[e].invokeCount-r[e].negativeCount)/r[e].invokeCount),qc=!0,SI(n)}function Kg(n,e){return Wc(n)[e]}function Vg(n){return Wc(n)}import{existsSync as TI,readFileSync as RI,writeFileSync as AI,mkdirSync as Xg,renameSync as wI}from"node:fs";import{join as Gc,dirname as Yg}from"node:path";var zg=30,xI=90,PI="skill-lifecycle.json";function Jg(n){return Gc(n,PI)}function Be(n){let e=Jg(n);try{return JSON.parse(RI(e,"utf8"))}catch{return{version:1,records:{}}}}function We(n,e){let t=Jg(n);Xg(Yg(t),{recursive:!0});let r=t+".tmp";AI(r,JSON.stringify(e,null,2),"utf8");let{renameSync:s}=Mo("node:fs");s(r,t)}function qt(n,e,t="learned"){return n.records[e]||(n.records[e]={name:e,state:"active",createdAt:new Date().toISOString(),pinned:!1,useCount:0,source:t}),n.records[e]}function Kc(n,e){let t=qt(n,e);t.lastUsedAt=new Date().toISOString(),t.useCount++,t.state==="stale"&&(t.state="active",t.staleAt=void 0)}function Vc(n,e){let t=qt(n,e);t.lastPatchedAt=new Date().toISOString(),t.state==="stale"&&(t.state="active",t.staleAt=void 0)}function Qg(n,e){let t=n.records[e];return t?(t.pinned=!0,!0):!1}function Zg(n,e){let t=n.records[e];return t?(t.pinned=!1,!0):!1}function II(n){let e=[n.lastUsedAt,n.lastViewedAt,n.lastPatchedAt,n.createdAt].filter(Boolean).map(t=>new Date(t));return new Date(Math.max(...e.map(t=>t.getTime())))}function _I(n){let e=Date.now(),t={transitioned:[],skippedPinned:[]};for(let[r,s]of Object.entries(n.records)){if(s.source==="installed")continue;if(s.pinned){s.state!=="active"&&t.skippedPinned.push(r);continue}let o=II(s),i=(e-o.getTime())/(1e3*60*60*24);s.state==="active"&&i>=zg?(s.state="stale",s.staleAt=new Date().toISOString(),t.transitioned.push({name:r,from:"active",to:"stale"})):s.state==="stale"&&i>=xI?(s.state="archived",s.archivedAt=new Date().toISOString(),t.transitioned.push({name:r,from:"stale",to:"archived"})):s.state==="stale"&&i<zg&&(s.state="active",s.staleAt=void 0,t.transitioned.push({name:r,from:"stale",to:"active"}))}return t}function EI(n,e){let t=Gc(n,e);if(!TI(t))return!1;let r=Gc(n,".archive",e);Xg(Yg(r),{recursive:!0});try{return wI(t,r),!0}catch{return!1}}function ef(n,e){let t=Be(n),r=_I(t);for(let s of r.transitioned)s.to==="archived"&&EI(e,s.name);return We(n,t),r}function tf(n,e){return Object.values(n.records).filter(t=>t.state===e)}function eo(n,e){delete n.records[e]}function CI(n){let e=n.replace(/\r\n/g,`
|
|
831
831
|
`).replace(/\r/g,`
|
|
832
832
|
`);if(!e.startsWith("---"))return;let t=e.indexOf(`
|
|
833
833
|
---`,3);if(t!==-1)return e.slice(4,t)}function MI(n){return n.startsWith('"')&&n.endsWith('"')||n.startsWith("'")&&n.endsWith("'")?n.slice(1,-1):n}function NI(n,e){let t=[],r=e+1;for(;r<n.length;){let s=n[r];if(s.length>0&&!s.startsWith(" ")&&!s.startsWith(" "))break;t.push(s),r+=1}return{value:t.join(`
|
|
834
834
|
`).trim(),linesConsumed:r-e}}function zc(n){let e=CI(n);if(!e)return{};let t={},r=e.split(`
|
|
835
|
-
`),s=0;for(;s<r.length;){let i=r[s].match(/^([\w-]+):\s*(.*)$/);if(!i){s+=1;continue}let a=i[1],c=i[2].trim();if(!a){s+=1;continue}if(!c&&s+1<r.length){let d=r[s+1];if(d.startsWith(" ")||d.startsWith(" ")){let{value:u,linesConsumed:p}=NI(r,s);u&&(t[a]=u),s+=p;continue}}let l=MI(c);l&&(t[a]=l),s+=1}return t}var Xc=1024,
|
|
835
|
+
`),s=0;for(;s<r.length;){let i=r[s].match(/^([\w-]+):\s*(.*)$/);if(!i){s+=1;continue}let a=i[1],c=i[2].trim();if(!a){s+=1;continue}if(!c&&s+1<r.length){let d=r[s+1];if(d.startsWith(" ")||d.startsWith(" ")){let{value:u,linesConsumed:p}=NI(r,s);u&&(t[a]=u),s+=p;continue}}let l=MI(c);l&&(t[a]=l),s+=1}return t}var Xc=1024,nf=1e5,DI=/^[a-z0-9][a-z0-9._-]*$/;function no(n,e){let t=[],r=[];if(!n||n.trim().length===0)return{valid:!1,errors:["Content is empty"],warnings:[]};if(n.length>nf)return{valid:!1,errors:[`Content exceeds ${nf} chars`],warnings:[]};if(!n.trimStart().startsWith("---"))return t.push("SKILL.md must start with YAML frontmatter (---)"),{valid:!1,errors:t,warnings:r};let s=n.replace(/\r\n/g,`
|
|
836
836
|
`),o=s.indexOf(`
|
|
837
837
|
---`,3);if(o===-1)return t.push("YAML frontmatter has no closing delimiter (---)"),{valid:!1,errors:t,warnings:r};let i=zc(n);return i.name?(DI.test(i.name)||t.push(`Skill name '${i.name}' must be lowercase alphanumeric with dots, hyphens, or underscores`),e&&i.name!==e&&r.push(`Frontmatter name '${i.name}' differs from expected '${e}'`)):t.push("Frontmatter must include 'name' field"),i.description?i.description.length>Xc&&t.push(`Description exceeds ${Xc} characters`):t.push("Frontmatter must include 'description' field"),s.slice(o+4).trim()||t.push("SKILL.md must have content after frontmatter"),i.version&&(/^\d+\.\d+(\.\d+)?(-[\w.]+)?$/.test(i.version)||r.push(`Version '${i.version}' is not a valid semver format`)),{valid:t.length===0,errors:t,warnings:r,parsed:t.length===0?i:void 0}}function to(n){let e=["---"];if(e.push(`name: ${n.name}`),e.push(`description: ${n.description.slice(0,Xc)}`),n.version&&e.push(`version: ${n.version}`),n.category&&e.push(`category: ${n.category}`),n.tools&&n.tools.length>0){e.push("tools:");for(let t of n.tools)e.push(` - ${t}`)}return e.push("---"),e.push(""),e.push(n.body),e.join(`
|
|
838
838
|
`)}function Yc(n,e,t){let r=n.replace(/\r\n/g,`
|
|
@@ -847,25 +847,25 @@ ${c}`:n}import*as V from"node:fs";import*as ee from"node:path";import{randomUUID
|
|
|
847
847
|
`),this.handleRequest(t),!0}return Pr(e)?(this.handleNotification(e),!0):!1}emitSessionUpdate(e,t,r){if(t.startsWith("x_")&&!this.hostSupportsExtendedEvents)return;let s={jsonrpc:"2.0",method:ft.SESSION_UPDATE,params:{sessionId:e,update:{sessionUpdate:t,...r}}};this.transport.send(s)}async requestPermission(e){let t=`perm-${OI().slice(0,8)}`,r={jsonrpc:"2.0",method:ft.SESSION_REQUEST_PERMISSION,params:e,id:t};return new Promise(s=>{this.outboundRequestMap.set(t,e.permissionId),this.pendingPermissions.set(e.permissionId,{resolve:o=>s({optionId:o})}),this.transport.send(r)})}get supportsExtendedEvents(){return this.hostSupportsExtendedEvents}get supportsExtendedMethods(){return this.hostSupportsExtendedMethods}get sessionId(){return this.activeSessionId}async handleRequest(e){let{method:t,params:r,id:s}=e,o=r??{};try{switch(t){case ft.INITIALIZE:await this.onInitialize(s,o);break;case ft.SESSION_NEW:await this.onSessionNew(s,o);break;case ft.SESSION_PROMPT:await this.onSessionPrompt(s,o);break;case ft.SESSION_END:await this.onSessionEnd(s,o);break;case ft.SESSION_SET_CONFIG:await this.onSessionSetConfig(s,o);break;case ft.SESSION_SET_MODEL:await this.handler.handleAcpSessionSetModel(o.sessionId??this.activeSessionId??"",o.modelId??o.model??""),this.sendResult(s,{});break;case ft.SESSION_SET_MODE:await this.handler.handleAcpSessionSetMode(o.sessionId??this.activeSessionId??"",o.modeId??o.mode??""),this.sendResult(s,{});break;case ye.ABORT:await this.onAbort(s,o);break;case ye.DREAM:await this.onDream(s,o);break;case ye.AGENTS_LIST:{let i=await this.handler.handleAcpAgentsList();this.sendResult(s,i);break}case ye.SOLO_START:{let i=await this.handler.handleAcpSoloStart(o);this.sendResult(s,i);break}case ye.SOLO_STATUS:{let i=await this.handler.handleAcpSoloStatus(o);this.sendResult(s,i);break}case ye.SOLO_SELECT:{let i=await this.handler.handleAcpSoloSelect(o);this.sendResult(s,i);break}case ye.SOLO_CANCEL:{let i=await this.handler.handleAcpSoloCancel(o);this.sendResult(s,i);break}case ye.SOLO_SUBSCRIBE:{let i=await this.handler.handleAcpSoloSubscribe(o);this.sendResult(s,i);break}case ye.SOLO_MESSAGE:{let i=await this.handler.handleAcpSoloMessage(o);this.sendResult(s,i);break}case ye.SOLO_EVALUATE:{let i=await this.handler.handleAcpSoloEvaluate(o);this.sendResult(s,i);break}case ye.PRODUCT_CREATE:{let i=await this.handler.handleAcpProductCreate(o);this.sendResult(s,i);break}case ye.PRODUCT_PLAN:{let i=await this.handler.handleAcpProductPlan(o);this.sendResult(s,i);break}case ye.PRODUCT_CONFIRM:{let i=await this.handler.handleAcpProductConfirm(o);this.sendResult(s,i);break}case ye.PRODUCT_MESSAGE:{let i=await this.handler.handleAcpProductMessage(o);this.sendResult(s,i);break}case ye.PRODUCT_PAUSE:{let i=await this.handler.handleAcpProductPause(o);this.sendResult(s,i);break}case ye.PRODUCT_RESUME:{let i=await this.handler.handleAcpProductResume(o);this.sendResult(s,i);break}case ye.PRODUCT_CANCEL:{let i=await this.handler.handleAcpProductCancel(o);this.sendResult(s,i);break}case ye.PRODUCT_ROLLBACK:{let i=await this.handler.handleAcpProductRollback(o);this.sendResult(s,i);break}case ye.PRODUCT_STATUS:{let i=await this.handler.handleAcpProductStatus(o);this.sendResult(s,i);break}case ye.PRODUCT_SUBSCRIBE:{let i=await this.handler.handleAcpProductSubscribe(o);this.sendResult(s,i);break}case ye.TEAM_DELEGATE:{let i=await this.handler.handleAcpTeamDelegate(o);this.sendResult(s,i);break}default:this.sendError(s,ro.METHOD_NOT_FOUND,`Unknown method: ${t}`)}}catch(i){this.sendError(s,ro.INTERNAL_ERROR,i.message)}}handleNotification(e){this.log(`received notification: ${e.method}`)}handleResponse(e){let t=this.outboundRequestMap.get(e.id);if(t){this.outboundRequestMap.delete(e.id);let r=this.pendingPermissions.get(t);if(r){this.pendingPermissions.delete(t);let s=e.result;r.resolve(s?.optionId??"deny")}}else this.log(`received response for id=${String(e.id)} (no matching outbound request)`)}async onInitialize(e,t){this.hostCapabilities=t.clientCapabilities??{},this.hostSupportsExtendedEvents=this.hostCapabilities.extendedEvents??!1,this.hostSupportsExtendedMethods=this.hostCapabilities.extendedMethods??!1;let r=t.clientInfo?.name??"unknown",s=t.clientInfo?.version??"unknown";this.log(`initialize: host=${r} v=${s}, proto=${String(t.protocolVersion)}, extendedEvents=${this.hostSupportsExtendedEvents}, extendedMethods=${this.hostSupportsExtendedMethods}`);let o=await this.handler.handleAcpInitialize(t);this.sendResult(e,o)}async onSessionNew(e,t){let r=await this.handler.handleAcpSessionNew(t);this.activeSessionId=r.sessionId,this.sendResult(e,r)}async onSessionPrompt(e,t){if(!this.activeSessionId||this.activeSessionId!==t.sessionId){this.sendError(e,ro.SESSION_NOT_FOUND,`No active session with id: ${t.sessionId}`);return}let r=await this.handler.handleAcpSessionPrompt(t);this.sendResult(e,r)}async onSessionEnd(e,t){await this.handler.handleAcpSessionEnd(t),this.activeSessionId===t.sessionId&&(this.activeSessionId=null),this.sendResult(e,{})}async onSessionSetConfig(e,t){if(this.activeSessionId!==t.sessionId){this.sendError(e,ro.SESSION_NOT_FOUND,`No active session with id: ${t.sessionId}`);return}await this.handler.handleAcpSessionSetConfig(t),this.sendResult(e,{})}async onAbort(e,t){await this.handler.handleAcpAbort(t),this.sendResult(e,{aborted:!0})}async onDream(e,t){let r=await this.handler.handleAcpDream(t);this.sendResult(e,r)}sendResult(e,t){process.stderr.write(`[acp-server] \u922B?send id=${String(e)} result
|
|
848
848
|
`);let r={jsonrpc:"2.0",id:e,result:t};this.transport.send(r)}sendError(e,t,r,s){process.stderr.write(`[acp-server] \u922B?send id=${String(e)} error=${r}
|
|
849
849
|
`);let o={jsonrpc:"2.0",id:e,error:{code:t,message:r,...s!==void 0?{data:s}:{}}};this.transport.send(o)}isJsonRpcResponse(e){if(!e||typeof e!="object")return!1;let t=e;return t.jsonrpc==="2.0"&&"id"in t&&("result"in t||"error"in t)&&!("method"in t)}log(e){this.verbose&&process.stderr.write(`[acp-server] ${e}
|
|
850
|
-
`)}};function
|
|
850
|
+
`)}};function rf(n,e,t,r){let s=LI(t,r);s&&n.emitSessionUpdate(e,s.type,s.payload)}function LI(n,e){switch(n){case"turn.delta":return{type:ht.AGENT_MESSAGE_CHUNK,payload:{content:{type:"text",text:e.text}}};case"turn.reasoning_delta":return{type:ht.AGENT_THOUGHT_CHUNK,payload:{content:{type:"text",text:e.delta}}};case"turn.tool_call":return{type:ht.TOOL_CALL,payload:{toolCallId:e.callId,toolName:e.name,status:"in_progress",title:e.name,kind:"execute",rawInput:$I(e.arguments)}};case"turn.tool_result":return{type:ht.TOOL_CALL_UPDATE,payload:{toolCallId:e.callId,status:e.ok?"completed":"failed",...e.outputPreview?{content:[{type:"content",content:{type:"text",text:e.outputPreview}}]}:{},...e.error?{content:[{type:"content",content:{type:"text",text:e.error}}]}:{}}};case"turn.tool_blocked":return{type:ht.TOOL_CALL_UPDATE,payload:{toolCallId:e.callId,status:"failed",content:[{type:"content",content:{type:"text",text:e.reason??"blocked"}}]}};case"turn.plan_update":return{type:ht.PLAN,payload:{entries:[{content:e.content,priority:"medium",status:"in_progress"}]}};case"turn.usage_update":{let t=e.usage,r=t?.inputTokens??t?.input_tokens??0,s=t?.outputTokens??t?.output_tokens??0;return{type:ht.USAGE_UPDATE,payload:{used:r+s,size:t?.contextWindow??2e5}}}case"turn.end":return null;case"turn.error":return{type:ht.AGENT_MESSAGE_CHUNK,payload:{content:{type:"text",text:`[Error] ${e.error?.message??"Unknown error"}`}}};case"turn.suggestions":return{type:ht.AVAILABLE_COMMANDS_UPDATE,payload:{availableCommands:(e.items??[]).map(t=>({name:t.text,description:t.description??""}))}};case"turn.sidechain_started":return{type:Te.X_SUBAGENT_STARTED,payload:{agentId:String(e.depth??0),agentName:e.role,task:void 0}};case"turn.subagent_delta":return{type:Te.X_SUBAGENT_DELTA,payload:{agentId:e.subagentId??e.agentType,text:e.text}};case"turn.sidechain_completed":return{type:Te.X_SUBAGENT_ENDED,payload:{agentId:String(e.depth??0),result:void 0}};case"turn.media_result":return{type:Te.X_MEDIA_RESULT,payload:{mediaId:e.taskId??jI(),type:e.mediaType,url:e.url,metadata:{model:e.model,provider:e.provider}}};case"turn.media_progress":return{type:Te.X_MEDIA_PROGRESS,payload:{mediaId:e.taskId,progress:e.percent,stage:e.status}};case"turn.skill_instruction":return{type:Te.X_SKILL_INSTRUCTION,payload:{skillId:"unknown",instruction:String(e.instruction??"")}};case"turn.recovery":return{type:Te.X_RECOVERY,payload:{errorType:e.action,message:e.detail??"",action:"retry"}};case"turn.ask_user":return{type:Te.X_ASK_USER,payload:{question:(e.questions??[])[0]?.question??"",options:(e.questions??[])[0]?.options?.map(t=>t.label)}};case"session.info":return{type:Te.X_SESSION_INFO,payload:{sessionId:e.sessionId,model:e.model,metadata:{cwd:e.cwd,turnCount:e.turnCount}}};case"memory.updated":return{type:Te.X_MEMORY_UPDATED,payload:{memoryId:e.source,action:"updated",summary:e.summary}};case"team.member.notification":return{type:Te.X_TEAM_MEMBER_UPDATE,payload:{memberId:e.memberId,type:e.method,payload:e.params??{}}};case"solo.progress":return{type:Te.X_SOLO_STARTED,payload:{evaluationId:e.soloId,agents:[e.agentId],task:e.progress??""}};case"solo.agentDelta":return{type:Te.X_SUBAGENT_DELTA,payload:{agentId:e.agentId,text:e.text}};case"solo.evaluation":return{type:Te.X_SOLO_SELECTED,payload:{evaluationId:e.soloId,winnerId:e.winnerId,reason:e.reasoning}};case"product.taskStarted":return{type:Te.X_PRODUCT_TASK_STARTED,payload:{workflowId:e.productId,taskId:e.taskId,agentId:e.assignee}};case"product.taskCompleted":return{type:Te.X_PRODUCT_TASK_COMPLETED,payload:{workflowId:e.productId,taskId:e.taskId,agentId:"",result:e.result,status:"completed"}};case"product.taskFailed":return{type:Te.X_PRODUCT_TASK_COMPLETED,payload:{workflowId:e.productId,taskId:e.taskId,agentId:"",status:"failed"}};case"product.checkpointed":return{type:Te.X_PRODUCT_CHECKPOINT,payload:{workflowId:e.productId,checkpointId:e.timestamp,completedTasks:[]}};case"turn.start":case"turn.task_updated":case"turn.exec_progress":case"turn.heartbeat":case"turn.tool_use_summary":case"turn.artifact":case"turn.annotations":case"tool.approval.request":case"permission.rule_updated":case"pong":case"agents.status":case"agents.error":case"product.budgetWarning":case"product.completed":return null;default:return null}}function $I(n){if(n)try{return JSON.parse(n)}catch{return{raw:n}}}function jI(){return Math.random().toString(36).slice(2,10)}var sf=["initialize","thread.create","thread.list","thread.turn","session.resume","session.getInfo","session.getMessages","memory.list","memory.read","memory.write","memory.search","memory.delete","memory.dream","tools.list","media.listModels","config.get","config.update","todos.list","tasks.list","tasks.cancel","agent.ping","agent.abort","tool.approval.response","agents.scan","agents.list","agents.config","agents.setConfig","agents.getConfig","agents.removeConfig","agents.setGateway","solo.start","solo.status","solo.cancel","solo.select","solo.list","solo.delete","solo.message","solo.evaluate","product.plan","product.confirm","product.message","product.create","product.resume","product.pause","product.checkpoint","product.status","product.list","product.delete","product.cancel","product.rollback","project.create","project.list","project.delete","project.rename","project.archive","project.unarchive","project.update","project.archiveByGroup","session.switchProject","session.getState","session.create","session.list","session.get","session.update","session.delete","session.archive","instructions.list","instructions.read","instructions.write","instructions.delete","files.list","files.read","files.create","files.rename","files.delete","files.gitStatus","settings.listProviders","settings.addKey","settings.removeKey","settings.toggleKey","settings.listModels","settings.setActiveModel","settings.getActiveModel","settings.getOverview","settings.refreshModels","settings.validateKey"];import{randomUUID as lo}from"node:crypto";import*as Nr from"node:path";ae();dt();import*as of from"node:fs";import*as Jc from"node:path";ae();var On=class{getSessionsRoot(e){let t=ct(e);if(!t)throw new Error(`Project not found: ${e}`);return Ot(t.workspaceDir)}getProjectWorkspaceDir(e){let t=ct(e);if(!t)throw new Error(`Project not found: ${e}`);return t.workspaceDir}getSessionDir(e,t){return Jc.join(this.getSessionsRoot(e),t)}resolveWorkspaceDir(e,t){if(t)return this.getProjectWorkspaceDir(t);let r=me();for(let s of r){let o=Ot(s.workspaceDir),i=Jc.join(o,e);try{if(of.existsSync(i))return s.workspaceDir}catch{}}return this.getActiveProjectWorkspaceDir()}getActiveProjectWorkspaceDir(){let e=Oe();if(e)return e.workspaceDir;let t=me();if(t.length>0)return t[0].workspaceDir;throw new Error("No active project available")}getActiveProjectId(){let e=Oe();if(e)return e.id;let t=me();if(t.length>0)return t[0].id;throw new Error("No active project available")}};function io(n,e){return{name:n,compute:e,cacheBreak:!1}}function Er(n,e,t){return{name:n,compute:e,cacheBreak:!0}}var oo=new Map;async function UI(n){return(await Promise.all(n.map(async t=>{if(!t.cacheBreak&&oo.has(t.name))return oo.get(t.name)??null;let r=await t.compute();return oo.set(t.name,r),r}))).filter(t=>t!=null)}function af(){oo.clear()}async function cf(n){let e=[];if(n.instructionBlock&&e.push(n.instructionBlock),n.customSystemPrompt?e.push(n.customSystemPrompt):n.basePrompt&&e.push(n.basePrompt),n.sections?.length){let t=await UI(n.sections);e.push(...t)}return n.appendSystemPrompt&&e.push(n.appendSystemPrompt),e.filter(Boolean).join(`
|
|
851
851
|
|
|
852
|
-
`)}ae();import{existsSync as
|
|
852
|
+
`)}ae();import{existsSync as lf,mkdirSync as FI,readFileSync as Cr,writeFileSync as df}from"node:fs";import{join as Mr}from"node:path";var ao=new Set(["coding","office","creative","general"]),uf="settings.yaml";function BI(n){try{let e=Mr(n,qe,uf),r=Cr(e,"utf-8").match(/^taskDomain\s*:\s*(\w+)/m);if(r){let s=r[1].toLowerCase();if(ao.has(s))return s}}catch{}try{let e=Mr(n,qe,"INSTRUCTIONS.md"),r=Cr(e,"utf-8").match(/^---\r?\n[\s\S]*?\r?\n---/);if(r){let s=r[0].match(/^domain\s*:\s*(\w+)/m);if(s){let o=s[1].toLowerCase();if(ao.has(o))return o}}}catch{}try{let e=Mr(n,"INSTRUCTIONS.md"),r=Cr(e,"utf-8").match(/^---\r?\n[\s\S]*?\r?\n---/);if(r){let s=r[0].match(/^domain\s*:\s*(\w+)/m);if(s){let o=s[1].toLowerCase();if(ao.has(o))return o}}}catch{}}var HI=3;function qI(n,e){let t=VI(n);return e?t===e||t==="general"?e:(Zc(n)[t]??0)>=HI?t:e:t}var WI=/\b(?:code|coding|bug|debug|fix|refactor|function|class|method|api|compile|build|deploy|test|unittest|lint|git|commit|merge|branch|pull\s*request|PR|npm|pnpm|yarn|pip|docker|k8s|kubernetes|sql|database|migration|endpoint|route|middleware|typescript|javascript|python|java|rust|go(?:lang)?|css|html|react|vue|angular|nextjs|express|fastapi|flask|django|springboot|webpack|vite|rollup|esbuild|CI\/?CD|GitHub\s*Actions|workflow|pipeline|variable|const|let|var|import|export|module|package|dependency|dependencies|node_modules|tsconfig|eslint|prettier|interface|type\b|enum|struct|async|await|promise|callback|exception|error\s*handling|stack\s*trace|breakpoint|源码|代码|编程|编码|调试|重构|修复|Bug|函数|类|方法|接口|模块|依赖|组件|编译|构建|部署|测试|单元测试|提交|合并|分支|数据库|迁移|路由|中间件)\b/i,GI=/\b(?:report|document|spreadsheet|excel|csv|table|chart|graph|data\s*analysis|statistics|slides?|presentation|ppt|powerpoint|email|mail|memo|minutes|meeting|schedule|calendar|summary|summarize|brief|overview|outline|template|format|agenda|invoice|budget|forecast|dashboard|KPI|OKR|metric|analytics|insight|文档|报告|报表|表格|数据分析|统计|幻灯片|PPT|演示|邮件|信件|备忘录|会议纪要|日程|摘要|总结|概要|简报|模板|格式|议程|发票|预算|预测|看板|报表|分析)\b/i,KI=/\b(?:write|writing|essay|article|blog|story|novel|poem|poetry|lyrics|copywriting|copy|slogan|tagline|headline|marketing|campaign|branding|creative|brainstorm|idea|concept|draft|narrative|character|dialogue|script|screenplay|pitch|proposal|content\s*strategy|social\s*media|SEO|newsletter|press\s*release|写作|文章|博客|故事|小说|诗|歌词|文案|标语|营销|策划|品牌|创意|头脑风暴|灵感|构思|草稿|叙事|角色|对话|剧本|策划案|提案|内容策略|自媒体|公众号|推文|软文|种草)\b/i;function VI(n){if(!n||n.trim().length===0)return"general";let e=Zc(n),t=Math.max(e.coding,e.office,e.creative);return t===0||[e.coding,e.office,e.creative].filter(s=>s>=t-1&&s>0).length>=2&&t<=2?"general":e.coding===t?"coding":e.office===t?"office":e.creative===t?"creative":"general"}function Zc(n){return{coding:Qc(n,WI),office:Qc(n,GI),creative:Qc(n,KI),general:0}}function Qc(n,e){let t=new RegExp(e.source,"gi"),r=n.match(t);return r?r.length:0}function pf(n){let e=BI(n.cwd);if(e)return{domain:e,source:"project-file"};if(n.hostOverride&&ao.has(n.hostOverride))return{domain:n.hostOverride,source:"host-override"};let t=qI(n.userText,n.sessionDomain);return n.sessionDomain&&t===n.sessionDomain?{domain:t,source:"session-sticky"}:{domain:t,source:"auto-detect"}}var zI=3;function mf(n,e){if(e==="general")return!1;try{let t=Mr(n,qe),r=Mr(t,uf);if(lf(r)){let o=Cr(r,"utf-8");if(/^taskDomain\s*:/m.test(o))return!1}FI(t,{recursive:!0});let s=`# Auto-detected task domain for this workspace.
|
|
853
853
|
# Values: coding | office | creative | general
|
|
854
|
-
`;if(
|
|
854
|
+
`;if(lf(r)){let o=Cr(r,"utf-8");df(r,o.trimEnd()+`
|
|
855
855
|
|
|
856
856
|
`+s+`taskDomain: ${e}
|
|
857
|
-
`,"utf-8")}else
|
|
858
|
-
`,"utf-8");return!0}catch{return!1}}function
|
|
859
|
-
`)})}function co(){return["## Problem Solving","- If an approach fails, diagnose why before switching tactics \u2014 read the error, check your assumptions, try a focused fix. Don't retry the identical action blindly, but don't abandon a viable approach after a single failure either.","- Report outcomes faithfully: if verification fails, say so with the relevant output; if you did not run a verification step, say that rather than implying it succeeded.","- Do not create files unless they are absolutely necessary for achieving your goal. Prefer editing an existing file to creating a new one.","","## Safety","- Be careful not to introduce security vulnerabilities such as command injection, XSS, SQL injection, and other OWASP top 10 vulnerabilities.","- If you notice that you wrote insecure code, immediately fix it. Prioritize writing safe, secure, and correct code."]}function e_(){return["# Doing Tasks","","You will primarily perform software engineering tasks: solving bugs, adding new functionality, refactoring code, and more.","","## Code Quality","- In general, do not propose changes to code you haven't read. If you need to modify a file, read it first. Understand existing code before suggesting modifications.","","## Implementation Discipline",`- Don't add features, refactor code, or make "improvements" beyond what was asked. A bug fix doesn't need surrounding code cleaned up. A simple feature doesn't need extra configurability.`,"- Don't add error handling, fallbacks, or validation for scenarios that can't happen. Trust internal code and framework guarantees. Only validate at system boundaries (user input, external APIs).","- Don't create helpers, utilities, or abstractions for one-time operations. Don't design for hypothetical future requirements. Three similar lines of code is better than a premature abstraction.","- Default to writing no comments unless the WHY is non-obvious: a hidden constraint, a subtle invariant, a workaround for a specific bug. Don't explain WHAT the code does \u2014 well-named identifiers already do that.",'- Avoid backwards-compatibility hacks like renaming unused _vars, re-exporting types, adding "// removed" comments for removed code. If code is unused, delete it completely.',"","## Completeness and Correctness","- When a task lists multiple constraints or requirements, implement ALL of them explicitly. Do not drop any.","- When refactoring, commit fully to the new pattern. Do NOT mix old and new patterns in the same codebase.","- After making changes, verify you met every requirement from the original request.","- For security fixes, use standard proven patterns (parameterized queries, input validation, etc.).","- NEVER leave TODO comments, placeholder implementations, or stub functions. Every function you write must have a complete, working implementation.","- When creating multiple files that import from each other, ensure every import resolves to a real export. Do not leave dead imports or forward declarations without implementations.","- If you create a file with a function signature, you MUST provide the full body \u2014 not `// implement later` or `throw new Error('not implemented')`.","","## Proactive Action","- When asked to fix, change, or improve code, implement the changes directly by writing to the file. Do not merely describe what should be changed.","- When you identify issues (bugs, security vulnerabilities, style problems), fix them immediately using your tools rather than listing recommendations.","- Default to action: read the file, make the fix, write it back. Only describe without acting when explicitly asked for advice or review only.","","## Faithful Reporting","- Report outcomes faithfully: if a tool call failed, say so with the error output. Do not claim success when a tool returned an error.","- If you did not run a verification step, say that rather than implying it succeeded.","- Never claim 'all tests pass' or 'file created successfully' when tool output shows otherwise.","- If you are unsure whether your changes are complete, state that explicitly rather than asserting completeness."]}function t_(){return["# Doing Tasks","","You will assist with office and analytical tasks: reports, data analysis, documents, presentations, and more.","","## Accuracy and Rigor","- Verify numerical calculations and statistical claims. When presenting data, ensure totals, percentages, and comparisons are mathematically correct.","- Distinguish clearly between facts, inferences, and assumptions. Label uncertain information explicitly.","- When summarizing source material, preserve the original meaning. Do not introduce information not present in the source.","","## Structure and Formatting","- Use clear headings, bullet points, and tables to organize information. Match the formatting conventions of the document type (report, memo, email, slides).","- For data-heavy outputs, prefer tables over prose. Include units, time periods, and comparison baselines.","- Keep language professional and concise. Avoid filler, hedging, and unnecessary qualifiers.","","## Completeness","- When the task lists multiple sections, data points, or requirements, address ALL of them. Do not silently omit items.","- If source data is insufficient to answer a question, state what is missing rather than guessing."]}function n_(){return["# Doing Tasks","","You will assist with creative and content tasks: writing, copywriting, brainstorming, and content strategy.","","## Voice and Style","- Match the requested tone, register, and style. If no style is specified, adapt to the content type (formal for press releases, conversational for blog posts, punchy for ad copy).","- Vary sentence length and structure for rhythm. Avoid monotonous patterns.","- Show, don't tell where appropriate. Use concrete details and vivid language over abstract statements.","","## Audience Awareness","- Write for the intended audience. Consider their knowledge level, interests, and expectations.","- For marketing/copywriting, lead with the benefit. Focus on what matters to the reader, not the feature list.","- Respect cultural context and sensitivity in language choices.","","## Creative Process","- When brainstorming, provide diverse options rather than variations on a single idea. Quantity and variety first, then refine.","- When editing existing text, preserve the author's voice. Make targeted improvements rather than rewriting from scratch.","- If creative constraints are given (word count, format, platform), follow them precisely."]}function
|
|
860
|
-
`)})}function
|
|
861
|
-
`))}function
|
|
857
|
+
`,"utf-8")}else df(r,s+`taskDomain: ${e}
|
|
858
|
+
`,"utf-8");return!0}catch{return!1}}function gf(n,e){return e==="general"?!1:(Zc(n)[e]??0)>=zI}import{release as XI,homedir as YI}from"node:os";import{resolve as JI}from"node:path";function QI(){let e=(process.env.SHELL??process.env.ComSpec??"").toLowerCase();return e.includes("zsh")?"zsh":e.includes("bash")?"bash":e.includes("fish")?"fish":e.includes("powershell")||e.includes("pwsh")?"powershell":e.includes("cmd")?"cmd":process.platform==="win32"?"powershell":"bash"}function ZI(){let n=process.platform,e=XI();return n==="win32"?e.toLowerCase().includes("microsoft")||e.toLowerCase().includes("wsl")?"Windows (WSL)":`Windows ${e.split(".")[0]??""}`.trim():n==="darwin"?"macOS":n==="linux"?"Linux":n}function ff(n){return io("environment_context",()=>{let e=QI(),t=ZI(),r=n??process.cwd(),s=process.version,o=YI(),i=["# Environment","",`- Platform: ${t}`,`- Shell: ${e}`,`- Working directory: ${JI(r)}`,`- Home directory: ${o}`,`- Node.js: ${s}`];return e==="powershell"?i.push("- Note: Use PowerShell syntax (semicolons, not &&; use $env: for env vars)"):e==="cmd"&&i.push("- Note: Use CMD syntax (%VAR%, not $VAR)"),i.join(`
|
|
859
|
+
`)})}function co(){return["## Problem Solving","- If an approach fails, diagnose why before switching tactics \u2014 read the error, check your assumptions, try a focused fix. Don't retry the identical action blindly, but don't abandon a viable approach after a single failure either.","- Report outcomes faithfully: if verification fails, say so with the relevant output; if you did not run a verification step, say that rather than implying it succeeded.","- Do not create files unless they are absolutely necessary for achieving your goal. Prefer editing an existing file to creating a new one.","","## Safety","- Be careful not to introduce security vulnerabilities such as command injection, XSS, SQL injection, and other OWASP top 10 vulnerabilities.","- If you notice that you wrote insecure code, immediately fix it. Prioritize writing safe, secure, and correct code."]}function e_(){return["# Doing Tasks","","You will primarily perform software engineering tasks: solving bugs, adding new functionality, refactoring code, and more.","","## Code Quality","- In general, do not propose changes to code you haven't read. If you need to modify a file, read it first. Understand existing code before suggesting modifications.","","## Implementation Discipline",`- Don't add features, refactor code, or make "improvements" beyond what was asked. A bug fix doesn't need surrounding code cleaned up. A simple feature doesn't need extra configurability.`,"- Don't add error handling, fallbacks, or validation for scenarios that can't happen. Trust internal code and framework guarantees. Only validate at system boundaries (user input, external APIs).","- Don't create helpers, utilities, or abstractions for one-time operations. Don't design for hypothetical future requirements. Three similar lines of code is better than a premature abstraction.","- Default to writing no comments unless the WHY is non-obvious: a hidden constraint, a subtle invariant, a workaround for a specific bug. Don't explain WHAT the code does \u2014 well-named identifiers already do that.",'- Avoid backwards-compatibility hacks like renaming unused _vars, re-exporting types, adding "// removed" comments for removed code. If code is unused, delete it completely.',"","## Completeness and Correctness","- When a task lists multiple constraints or requirements, implement ALL of them explicitly. Do not drop any.","- When refactoring, commit fully to the new pattern. Do NOT mix old and new patterns in the same codebase.","- After making changes, verify you met every requirement from the original request.","- For security fixes, use standard proven patterns (parameterized queries, input validation, etc.).","- NEVER leave TODO comments, placeholder implementations, or stub functions. Every function you write must have a complete, working implementation.","- When creating multiple files that import from each other, ensure every import resolves to a real export. Do not leave dead imports or forward declarations without implementations.","- If you create a file with a function signature, you MUST provide the full body \u2014 not `// implement later` or `throw new Error('not implemented')`.","","## Proactive Action","- When asked to fix, change, or improve code, implement the changes directly by writing to the file. Do not merely describe what should be changed.","- When you identify issues (bugs, security vulnerabilities, style problems), fix them immediately using your tools rather than listing recommendations.","- Default to action: read the file, make the fix, write it back. Only describe without acting when explicitly asked for advice or review only.","","## Faithful Reporting","- Report outcomes faithfully: if a tool call failed, say so with the error output. Do not claim success when a tool returned an error.","- If you did not run a verification step, say that rather than implying it succeeded.","- Never claim 'all tests pass' or 'file created successfully' when tool output shows otherwise.","- If you are unsure whether your changes are complete, state that explicitly rather than asserting completeness."]}function t_(){return["# Doing Tasks","","You will assist with office and analytical tasks: reports, data analysis, documents, presentations, and more.","","## Accuracy and Rigor","- Verify numerical calculations and statistical claims. When presenting data, ensure totals, percentages, and comparisons are mathematically correct.","- Distinguish clearly between facts, inferences, and assumptions. Label uncertain information explicitly.","- When summarizing source material, preserve the original meaning. Do not introduce information not present in the source.","","## Structure and Formatting","- Use clear headings, bullet points, and tables to organize information. Match the formatting conventions of the document type (report, memo, email, slides).","- For data-heavy outputs, prefer tables over prose. Include units, time periods, and comparison baselines.","- Keep language professional and concise. Avoid filler, hedging, and unnecessary qualifiers.","","## Completeness","- When the task lists multiple sections, data points, or requirements, address ALL of them. Do not silently omit items.","- If source data is insufficient to answer a question, state what is missing rather than guessing."]}function n_(){return["# Doing Tasks","","You will assist with creative and content tasks: writing, copywriting, brainstorming, and content strategy.","","## Voice and Style","- Match the requested tone, register, and style. If no style is specified, adapt to the content type (formal for press releases, conversational for blog posts, punchy for ad copy).","- Vary sentence length and structure for rhythm. Avoid monotonous patterns.","- Show, don't tell where appropriate. Use concrete details and vivid language over abstract statements.","","## Audience Awareness","- Write for the intended audience. Consider their knowledge level, interests, and expectations.","- For marketing/copywriting, lead with the benefit. Focus on what matters to the reader, not the feature list.","- Respect cultural context and sensitivity in language choices.","","## Creative Process","- When brainstorming, provide diverse options rather than variations on a single idea. Quantity and variety first, then refine.","- When editing existing text, preserve the author's voice. Make targeted improvements rather than rewriting from scratch.","- If creative constraints are given (word count, format, platform), follow them precisely."]}function hf(n="general"){return Er("task_guidance",()=>{let e;switch(n){case"coding":e=[...e_(),"",...co()];break;case"office":e=[...t_(),"",...co()];break;case"creative":e=[...n_(),"",...co()];break;default:e=["# Doing Tasks","","You are a versatile assistant that handles software engineering, office, and creative tasks.","",...co(),"","## When Coding","- Read existing code before modifying it. Understand the structure before making changes.","- When refactoring, commit fully to the new pattern. Do NOT mix old and new patterns.","- Implement ALL listed constraints or requirements explicitly. Do not drop any.","- Don't add features or abstractions beyond what was asked.","- When asked to fix or change code, implement changes directly by writing to the file \u2014 do not merely describe what to change.","","## When Writing Documents or Analyzing Data","- Verify numerical calculations and statistical claims for correctness.","- Use clear structure: headings, tables, bullet points as appropriate.","- Distinguish facts from inferences. Label uncertain information.","","## When Creating Content","- Match the requested tone, style, and audience. Adapt if not specified.","- Lead with the benefit for marketing/copywriting tasks.","- Provide diverse options when brainstorming."];break}return e.join(`
|
|
860
|
+
`)})}function yf(){return io("tool_guidance",()=>["# Tool Usage Guidance","","You have access to specialized tools. Use them appropriately:","","## Agent Delegation","Use the `agent` tool to delegate complex, multi-step tasks to sub-agents:","- Research/exploration tasks that benefit from focused attention","- File analysis across multiple files that need independent reasoning","- Any task the user explicitly asks you to delegate","- **When the user says 'delegate', 'sub-agent', 'fork', or 'hand off', you MUST use the `agent` tool \u2014 never handle it yourself**","Do NOT use `agent` for simple file reads or single-step operations.","","## Skill System","Use the `skill` tool (unified meta-tool) for all skill operations:","- action 'invoke' \u2014 run a skill by name","- action 'list' \u2014 discover available skills (shows scope: project/global)","- action 'create' \u2014 save a new skill to current project","- action 'promote' \u2014 copy a project skill to global (user-level)","When recalled memories show '[Cross-project skill available]', proactively offer to use or save the skill.","","## Checkpoint","Use the `checkpoint` tool (not raw git commands) to:","- Save workspace state before making changes","- Restore to a previous state if changes go wrong","The checkpoint tool manages git shadow history automatically.","","## Ask User","Use `ask_user` to clarify ambiguous requests before proceeding,","especially for expensive operations like media generation.","","## Project Rules Management","You can create, edit, and delete project rule files at `.qlogicagent/rules/*.md`.","These files are loaded into your system prompt every turn \u2014 changes take effect immediately.","Use this to help users establish coding conventions, workflow guidelines, or project-specific instructions.","When the user asks to 'add a rule', 'set up conventions', or 'configure instructions', write to `.qlogicagent/rules/<descriptive-name>.md`.","You may also create or edit `.qlogicagent/INSTRUCTIONS.md` for a single top-level instruction file."].join(`
|
|
861
|
+
`))}function bf(n){return io("language",()=>n?["# Language","",`Always respond in ${n}.`,`Use ${n} for all text output, explanations, and descriptions.`,"Use English only for: code, file paths, tool arguments, variable names, and technical identifiers."].join(`
|
|
862
862
|
`):["# Language","","Respond in the same language as the user's message.","If the user writes in English, respond in English. If in Chinese, respond in Chinese.","Use English only for: code, file paths, tool arguments, variable names, and technical identifiers."].join(`
|
|
863
|
-
`))}je();import{randomUUID as
|
|
864
|
-
`):null},"memory INDEX.md may change between turns")]}),ce=[...s].reverse().find(R=>R.role==="user");ce&&Sa(r,ce,p,t).catch(()=>{}),await this.mcpReady;let le=wt(),j=new Set(le.map(R=>R.function.name)),ve=[...le,...o.filter(R=>!j.has(R.function.name))],oe=s;if(l&&s.length>0){let R=Oe(),B=me().filter(Ae=>Ae.status==="active").map(Ae=>Ae.name).slice(0,10).join(", ");oe=[{role:"system",content:`[\u6CE8\u610F\uFF1A\u7528\u6237\u4ECE IM \u7AEF\u53D1\u6765\u6D88\u606F\uFF0C\u4F46\u684C\u9762\u7AEF\u5DF2\u8D85\u8FC730\u5206\u949F\u672A\u6D3B\u8DC3\uFF0C\u65E0\u6CD5\u786E\u5B9A\u7528\u6237\u60F3\u5728\u54EA\u4E2A\u9879\u76EE\u4E2D\u5DE5\u4F5C\u3002\u5F53\u524D\u6D3B\u8DC3\u9879\u76EE\uFF1A${R?.name??"\u65E0"}\u3002\u53EF\u7528\u9879\u76EE\uFF1A${B||"\u65E0"}\u3002\u8BF7\u5728\u56DE\u590D\u5F00\u5934\u7B80\u77ED\u8BE2\u95EE\u7528\u6237\u60F3\u5728\u54EA\u4E2A\u9879\u76EE\u4E2D\u7EE7\u7EED\uFF0C\u4F8B\u5982\uFF1A"\u4F60\u60F3\u7EE7\u7EED\u5728\u300CXX\u300D\u9879\u76EE\u4E2D\u5DE5\u4F5C\u5417\uFF1F"]`},...s]}let $e=i?.desktopRecentContext;if(!l&&$e&&$e.length>0&&s.length>0){let R=s[s.length-1],B=R?.role==="user"&&typeof R.content=="string"?R.content:"";if(o_(B)){let U={role:"system",content:"[\u4EE5\u4E0B\u662F\u7528\u6237\u5728\u684C\u9762\u7AEF\u7684\u8FD1\u671F\u5BF9\u8BDD\uFF0C\u4F9B\u4F60\u53C2\u8003\u4EE5\u4FDD\u6301\u4E0A\u4E0B\u6587\u8FDE\u8D2F]"},Ae={role:"system",content:"[\u684C\u9762\u5BF9\u8BDD\u4E0A\u4E0B\u6587\u7ED3\u675F\uFF0C\u4EE5\u4E0B\u662F\u5F53\u524D IM \u7AEF\u7684\u5BF9\u8BDD]"};oe=[U,...$e,Ae,...oe],this.log(`[continuation] injected ${$e.length} desktop messages as reference`)}}if(!cn(r,p)?.title){let R=typeof ce?.content=="string"?ce.content:Array.isArray(ce?.content)?ce.content.filter(B=>B.type==="text").map(B=>B.text??"").join(""):"";if(R.trim()){let B=null,U=this.resolveClientForPurpose("smallModel");U&&(B=await
|
|
863
|
+
`))}je();import{randomUUID as vf}from"node:crypto";async function kf(n,e){let t=new Date(n.lastActiveAt).getTime();if(Date.now()-t<Gl)return{split:!1,activeSessionId:n.sessionId};let o=vf(),i=new Date().toISOString();await et(n.sessionId,{sealedAt:i},e);let a=n.taskSummary?`[\u4E0A\u4E00\u8F6E\u5BF9\u8BDD\u6458\u8981] ${n.taskSummary}`:void 0;return await et(o,{sessionId:o,projectId:n.projectId,type:"group",ownerId:n.ownerId,groupKey:n.groupKey,groupName:n.groupName,groupPlatform:n.groupPlatform,previousSessionId:n.sessionId,carryoverSummary:a},e),{split:!0,activeSessionId:o,sealedSessionId:n.sessionId}}async function Sf(n,e){if(n.type!=="group")return{split:!1,activeSessionId:n.sessionId};if(n.turnCount<Kl)return{split:!1,activeSessionId:n.sessionId};let t=vf(),r=new Date().toISOString();await et(n.sessionId,{sealedAt:r},e);let s=n.taskSummary?`[\u4E0A\u4E00\u8F6E\u5BF9\u8BDD\u6458\u8981 \u2014 \u56E0\u6D88\u606F\u6570\u8FBE\u5230\u4E0A\u9650\u81EA\u52A8\u5207\u5206] ${n.taskSummary}`:void 0;return await et(t,{sessionId:t,projectId:n.projectId,type:"group",ownerId:n.ownerId,groupKey:n.groupKey,groupName:n.groupName,groupPlatform:n.groupPlatform,previousSessionId:n.sessionId,carryoverSummary:s},e),{split:!0,activeSessionId:t,sealedSessionId:n.sessionId}}import*as Ln from"node:fs";var Tf=new On,s_=[/继续(桌面|电脑|刚才|上次|之前)的/,/接着(桌面|电脑|刚才|上次|之前)的/,/刚才(那个|那件|说的|聊的|做的)/,/上次(说到|聊到|做到|讲到)/,/桌面(端|上)?(那个|那边|的任务|的对话|在做)/,/电脑(端|上)?(那个|那边|的任务|的对话|在做)/,/之前(那个|在做的|讨论的|说的)/,/帮我继续/,/接着(做|干|搞|写|改)/,/continue (from |where |the )?desktop/i,/pick up where/i,/what were we (doing|working on|talking about)/i,/continue (the |our )?(last |previous )?(task|conversation|chat)/i];function o_(n){return!n||n.length<3?!1:s_.some(e=>e.test(n))}function Rf(n){let e=n.params?.turnId??"";this.log(`abort requested for turn ${e}`),this.activeTurn&&(this.activeTurn.abort(),this.activeTurn=null),n.id!==void 0&&this.sendResponse(n.id,{aborted:!0})}function Af(n){let e=n.params;if(!e)return;let t=e.approvalId,r=e.decision;if(!t||!r){this.log("[warn] tool.approval.response missing approvalId or decision");return}let s={approvalId:t,decision:r==="approved"?"approved":"denied",updatedInput:e.updatedInput,permissionUpdate:e.permissionUpdate};this.permissionChecker&&this.permissionChecker.resolveApproval(s),n.id!==void 0&&this.sendResponse(n.id,{received:!0})}function wf(n){let e=n.params,t=e?.requestId;if(!t){this.log("[warn] thread.user_response missing requestId"),n.id!==void 0&&this.sendResponse(n.id,{received:!1});return}let r=this.pendingAskUser.get(t);if(!r){this.log(`[warn] thread.user_response: no pending request ${t}`),n.id!==void 0&&this.sendResponse(n.id,{received:!1});return}if(this.pendingAskUser.delete(t),e?.declined===!0)r.resolve(null);else{let o=e?.answers??{};r.resolve(o)}n.id!==void 0&&this.sendResponse(n.id,{received:!0})}async function xf(n){let e=n.params??{},t=e.turnId??lo();this.currentTurnId=t;let r=e.sessionId,s=e.messages??[],o=e.tools??[],i=e.config;n.id!==void 0&&this.sendResponse(n.id,{accepted:!0,turnId:t});let a=this.resumedSessionHistory.get(r);if(a&&a.length>0&&(s=[...a,...s]),i?.workdir&&typeof i.workdir=="string"&&this.setActiveWorkdir(i.workdir),!i?.workdir&&r&&i?.projectId){let y=i.projectId;try{let b=Tf.getProjectWorkspaceDir(y);this.getActiveProjectRoot()!==b&&(this.log(`[turn] routing session ${r} to project ${y} (${b})`),this.setActiveWorkdir(b))}catch{this.log(`[turn] project ${y} not found, using active project`)}}if(i?.sessionType==="group"&&typeof i?.groupKey=="string"){let y=i.groupKey,b=y.split(":"),k=b.length>=3?b.slice(1).join(":"):y,A=cs(k);if(A)this.setActiveWorkdir(A.workspaceDir),Oe()?.id!==A.id&&ut(A.id);else{let _=i.groupName||k,I=k.replace(/[<>:"/\\|?*\x00-\x1f]/g,"_").trim()||"group",N=Nr.join(q(),"workspaces","groups",I),L=as({name:_,workspaceDir:N,type:"group",groupId:k});L&&(this.setActiveWorkdir(L.workspaceDir),ut(L.id),this.sendNotification("project.created",{id:L.id,name:L.name,type:"group",groupId:k,workspaceDir:L.workspaceDir}))}}let c=1800*1e3,l=!1,d=i?.projectHint,u=d&&typeof d=="object"&&"name"in d?d:typeof d=="string"?{name:d,updatedAt:Date.now()}:null;if(u&&i?.sessionType!=="group"){let y=Date.now()-u.updatedAt;if(y>c)l=!0,this.log(`[projectHint] stale (${Math.round(y/6e4)}min old), skipping auto-switch`);else{let b=u.name,k=Oe();if(!k||k.name.toLowerCase()!==b.toLowerCase()){let A=me(),_=b.toLowerCase(),I=A.find(N=>N.name.toLowerCase()===_)??A.find(N=>N.name.toLowerCase().includes(_));I&&I.status==="active"&&(ut(I.id),this.setActiveWorkdir(I.workspaceDir))}}}let p=(()=>{let y=i?.projectId;if(y)try{return Tf.getProjectWorkspaceDir(y)}catch{}return this.getActiveProjectRoot()})();{let y=Y(),b=y.snapshotProviderKeys();this.currentMediaApiKeys=b,Em(this.mediaClient,b,(A,_,I)=>{this.sessionState?.addMediaUsage(A,_,I)},i?.mediaProviders,(A,_,I,N,L)=>{this.sendNotification("turn.media_progress",{turnId:t,taskId:A,mediaType:_,percent:I,status:N,...L?{provider:L}:{}})});let k=y.getActiveModel("textGeneration");k?(fc(xm(k.provider,k.apiKey)),k.keyHandle.release({success:!0})):fc(void 0)}_m(async y=>{let b=`ask-${lo().slice(0,8)}`;return new Promise(k=>{this.pendingAskUser.set(b,{resolve:k}),this.sendNotification("turn.ask_user",{requestId:b,questions:y.map(A=>({header:A.header,question:A.question,options:A.options}))})})});let m=new AbortController;this.activeTurn&&(this.activeTurn.abort(),await this.turnDone),this.activeTurn=m;let h;this.turnDone=new Promise(y=>{h=y}),r&&r!==this.currentSessionId&&(this.currentSessionId&&this.currentHooks&&(this.currentHooks.invoke("session.ended",{sessionId:this.currentSessionId}).catch(()=>{}),af()),this.currentSessionId=r,this.sessionState=new zt(r),this.sessionTaskDomain=void 0,this.memoryPrefetchState=Lt(),this.enableIdleDream()),this.log(`turn ${t} starting (session: ${r})`),this.sendNotification("turn.start",{turnId:t,model:i?.model??(this.currentModel||void 0),provider:i?.provider||void 0,projectId:i?.projectId||void 0});let f=[...s].reverse().find(y=>y.role==="user");if(this.lastUserMessageForAutoExtract=typeof f?.content=="string"?f.content:void 0,!f||!String(f.content??"").trim()){this.sendNotification("turn.end",{turnId:t,content:"",item:{id:`${t}-end`,type:"message",role:"assistant",text:"",createdAt:new Date().toISOString()}});return}try{let y={provider:i?.provider,model:i?.model,apiKey:i?.apiKey,baseUrl:i?.baseUrl,maxRounds:i?.maxRounds,temperature:i?.temperature,contextWindowTokens:i?.contextWindowTokens,maxOutputTokens:i?.maxOutputTokens,modelMaxOutputTokens:i?.modelMaxOutputTokens,maxConcurrentTools:i?.maxConcurrentTools,mediaProviders:i?.mediaProviders,reasoning:i?.reasoning,promptCacheKey:i?.promptCacheKey,promptCacheRetention:i?.promptCacheRetention,serviceTier:i?.serviceTier,openaiBuiltinTools:i?.openaiBuiltinTools,maxToolCalls:i?.maxToolCalls,parallelToolCalls:i?.parallelToolCalls,textVerbosity:i?.textVerbosity,mcpServers:i?.mcpServers,fallbackModel:Y().resolveModelForPurpose("smallModel")??void 0};{let R=y.provider??"",B=y.model??"";R&&B&&Y().getModelInfo(R,B)?.streamRequired&&(y.streamRequired=!0)}let b=this.resolveAgent(y);if(this.permissionChecker&&i?.permissions){let R=i.permissions,B=$s(R);this.permissionChecker.ruleEngineRef.setMode(B.mode),B.rules.length>0&&this.permissionChecker.ruleEngineRef.replaceRules(B.rules),B.defaultBehavior&&this.permissionChecker.ruleEngineRef.setDefaultBehavior(B.defaultBehavior),B.mode}if(!b){this.sendNotification("turn.error",{turnId:t,error:{message:"No LLM provider configured. Provide provider/model/apiKey in agent.turn config, or set DEEPSEEK_API_KEY / OPENAI_API_KEY / ANTHROPIC_API_KEY environment variable.",code:"NO_PROVIDER"}});return}let k,A=i?.workdir??this.getActiveProjectRoot();this.setActiveWorkdir(A);try{let R=await Gu(A,this.currentHooks??void 0);R.length>0&&(k=Wu(R))}catch{}let _=s.filter(R=>R.role==="user").map(R=>typeof R.content=="string"?R.content:"").join(" "),{domain:I,source:N}=pf({cwd:A,hostOverride:i?.taskDomain,sessionDomain:this.sessionTaskDomain,userText:_});if(this.sessionTaskDomain=I,N==="auto-detect"&&gf(_,I)&&mf(A,I),!this.memdir||this.memdir.getRootPath()!==new Et(A).getRootPath()){let R=new Et(A);R.ensureInitialized(),this.memdir=R}let L=this.memdir,F;if(r){let R=cn(r,p);R?.carryoverSummary&&(F=R.carryoverSummary)}let T=await cf({basePrompt:i?.systemPrompt,instructionBlock:k,customSystemPrompt:i?.customSystemPrompt,appendSystemPrompt:i?.appendSystemPrompt,sections:[ff(A),bf(),hf(I),yf(),...F?[Er("carryover",()=>F,"carryover from predecessor session")]:[],Er("memory",()=>{if(!L)return null;let R=L.getIndexForPrompt();return R?["## Your Memory (project-level notes \u2014 always visible)","",R,"","<!-- Use memory(action='remember') for user-level long-term facts/preferences that persist across projects.>","<!-- Use memory(action='add') for project-specific notes that should be visible every turn.>"].join(`
|
|
864
|
+
`):null},"memory INDEX.md may change between turns")]}),ce=[...s].reverse().find(R=>R.role==="user");ce&&Sa(r,ce,p,t).catch(()=>{}),await this.mcpReady;let le=wt(),j=new Set(le.map(R=>R.function.name)),ve=[...le,...o.filter(R=>!j.has(R.function.name))],oe=s;if(l&&s.length>0){let R=Oe(),B=me().filter(Ae=>Ae.status==="active").map(Ae=>Ae.name).slice(0,10).join(", ");oe=[{role:"system",content:`[\u6CE8\u610F\uFF1A\u7528\u6237\u4ECE IM \u7AEF\u53D1\u6765\u6D88\u606F\uFF0C\u4F46\u684C\u9762\u7AEF\u5DF2\u8D85\u8FC730\u5206\u949F\u672A\u6D3B\u8DC3\uFF0C\u65E0\u6CD5\u786E\u5B9A\u7528\u6237\u60F3\u5728\u54EA\u4E2A\u9879\u76EE\u4E2D\u5DE5\u4F5C\u3002\u5F53\u524D\u6D3B\u8DC3\u9879\u76EE\uFF1A${R?.name??"\u65E0"}\u3002\u53EF\u7528\u9879\u76EE\uFF1A${B||"\u65E0"}\u3002\u8BF7\u5728\u56DE\u590D\u5F00\u5934\u7B80\u77ED\u8BE2\u95EE\u7528\u6237\u60F3\u5728\u54EA\u4E2A\u9879\u76EE\u4E2D\u7EE7\u7EED\uFF0C\u4F8B\u5982\uFF1A"\u4F60\u60F3\u7EE7\u7EED\u5728\u300CXX\u300D\u9879\u76EE\u4E2D\u5DE5\u4F5C\u5417\uFF1F"]`},...s]}let $e=i?.desktopRecentContext;if(!l&&$e&&$e.length>0&&s.length>0){let R=s[s.length-1],B=R?.role==="user"&&typeof R.content=="string"?R.content:"";if(o_(B)){let U={role:"system",content:"[\u4EE5\u4E0B\u662F\u7528\u6237\u5728\u684C\u9762\u7AEF\u7684\u8FD1\u671F\u5BF9\u8BDD\uFF0C\u4F9B\u4F60\u53C2\u8003\u4EE5\u4FDD\u6301\u4E0A\u4E0B\u6587\u8FDE\u8D2F]"},Ae={role:"system",content:"[\u684C\u9762\u5BF9\u8BDD\u4E0A\u4E0B\u6587\u7ED3\u675F\uFF0C\u4EE5\u4E0B\u662F\u5F53\u524D IM \u7AEF\u7684\u5BF9\u8BDD]"};oe=[U,...$e,Ae,...oe],this.log(`[continuation] injected ${$e.length} desktop messages as reference`)}}if(!cn(r,p)?.title){let R=typeof ce?.content=="string"?ce.content:Array.isArray(ce?.content)?ce.content.filter(B=>B.type==="text").map(B=>B.text??"").join(""):"";if(R.trim()){let B=null,U=this.resolveClientForPurpose("smallModel");U&&(B=await $u(R,{transport:U.transport,apiKey:U.apiKey,model:U.model})),B||(B=R.trim().slice(0,20)+(R.trim().length>20?"\u2026":"")),await et(r,{title:B},p).catch(()=>{}),this.sendNotification("session.info",{sessionId:r,title:B,projectId:i?.projectId||void 0}),this.log(`[title-gen] generated title for session ${r}: "${B}"`)}}for await(let R of b.run({turnId:t,sessionId:r,messages:oe,tools:ve,systemPrompt:T,config:y},m.signal)){let B=new Date().toISOString();switch(R.type){case"start":break;case"delta":this.sendNotification("turn.delta",{turnId:R.turnId,text:R.text,item:{id:`${t}-delta`,type:"message",role:"assistant",text:R.text,createdAt:B}});break;case"end":if(this.sendNotification("turn.end",{turnId:R.turnId,content:R.content,usage:R.usage,model:R.model,provider:R.provider,item:{id:`${t}-end`,type:"message",role:"assistant",text:R.content,createdAt:B}}),R.usage&&this.sessionState){this.sessionState.addUsage(R.usage,R.model??this.currentModel);let U=this.sessionState.createSnapshot();this.sendNotification("turn.usage_update",{turnId:R.turnId,usage:R.usage,model:R.model??this.currentModel,sessionCostUSD:U.totalInputTokens*3e-6+U.totalOutputTokens*15e-6})}R.content&&(this.lastAssistantMessageForExtract=R.content,Sa(r,{role:"assistant",content:R.content},p,t).catch(()=>{}));break;case"error":if(this.sendNotification("turn.error",{turnId:R.turnId,error:{message:R.error,code:R.code}}),R.usage&&this.sessionState){this.sessionState.addUsage(R.usage,this.currentModel);let U=this.sessionState.createSnapshot();this.sendNotification("turn.usage_update",{turnId:R.turnId,usage:R.usage,model:this.currentModel,sessionCostUSD:U.totalInputTokens*3e-6+U.totalOutputTokens*15e-6})}break;case"skill_instruction":if(this.sendNotification("turn.skill_instruction",{turnId:R.turnId,instruction:R.instruction}),R.instruction.type==="skill.create"){let U=R.instruction,fe=Nr.join(p,".qlogicagent","skills"),Mt=Nr.join(fe,U.suggestedName),g=Nr.join(Mt,"SKILL.md");if(!Ln.existsSync(g)){let S=to({name:U.suggestedName,description:U.description,tools:U.tools,body:`# ${U.suggestedName}
|
|
865
865
|
|
|
866
866
|
Auto-learned multi-step workflow using: ${U.tools.join(", ")}.
|
|
867
|
-
`,version:"1.0.0",category:"learned"}),x=no(S,U.suggestedName);if(x.valid){Ln.mkdirSync(Mt,{recursive:!0}),Ln.writeFileSync(g,S,"utf8"),pt();let E=q(),w=Be(E);qt(w,U.suggestedName,"learned"),We(E,w),this.log(`[skill-auto-persist] Created skill "${U.suggestedName}" from turn ${R.turnId}`)}else this.log(`[skill-auto-persist] Validation failed for "${U.suggestedName}": ${x.errors.join(", ")}`)}}break;case"tool_call":this.sendNotification("turn.tool_call",{turnId:R.turnId,callId:R.callId,name:R.name,arguments:R.arguments,item:{id:R.callId,type:"tool_call",role:"assistant",toolName:R.name,toolCallId:R.callId,arguments:R.arguments,createdAt:B}}),this.sessionState?.recordToolCall();break;case"tool_result":this.sendNotification("turn.tool_result",{turnId:R.turnId,callId:R.callId,name:R.name,ok:R.ok,...R.error?{error:R.error}:{},...R.outputPreview?{outputPreview:R.outputPreview}:{},item:{id:`${R.callId}-result`,type:"tool_result",role:"assistant",toolName:R.name,toolCallId:R.callId,output:R.ok?R.outputPreview??"":R.error,approved:R.ok,createdAt:B}});break;case"tool_blocked":this.sendNotification("turn.tool_blocked",{turnId:R.turnId,callId:R.callId,name:R.name,reason:R.reason,item:{id:`${R.callId}-blocked`,type:"tool_blocked",role:"system",toolName:R.name,toolCallId:R.callId,text:R.reason,approved:!1,createdAt:B}});break;case"recovery":this.sendNotification("turn.recovery",{turnId:R.turnId,action:R.action,...R.detail?{detail:R.detail}:{},item:{id:`${t}-recovery-${lo().slice(0,8)}`,type:"recovery",role:"system",strategy:R.action,text:R.detail,createdAt:B}});break;case"plan_update":this.sendNotification("turn.plan_update",{turnId:R.turnId,slug:R.slug,content:R.content,item:{id:`${t}-plan-${lo().slice(0,8)}`,type:"plan_update",role:"assistant",text:R.content,createdAt:B}});break;case"reasoning_delta":this.sendNotification("turn.reasoning_delta",{turnId:R.turnId,text:R.text});break;case"suggestions":this.sendNotification("turn.suggestions",{turnId:R.turnId,items:R.items});break;case"media_result":this.sendNotification("turn.media_result",{turnId:R.turnId,mediaType:R.mediaType,url:R.url,...R.model?{model:R.model}:{},...R.provider?{provider:R.provider}:{},...R.taskId?{taskId:R.taskId}:{}});break;case"artifact":this.sendNotification("turn.artifact",{turnId:R.turnId,artifactId:R.artifactId,type:R.artifactType,title:R.title,...R.filePath?{filePath:R.filePath}:{},...R.language?{language:R.language}:{},...R.content?{content:R.content}:{},...R.mimeType?{mimeType:R.mimeType}:{}});break;case"subagent_started":this.sendNotification("turn.subagent_started",{turnId:R.turnId,subagentId:R.subagentId,agentType:R.agentType,...R.prompt?{prompt:R.prompt}:{}});break;case"subagent_ended":this.sendNotification("turn.subagent_ended",{turnId:R.turnId,subagentId:R.subagentId,agentType:R.agentType,ok:R.ok,...R.outputPreview?{outputPreview:R.outputPreview}:{},...R.error?{error:R.error}:{}});break;case"annotations":this.sendNotification("turn.annotations",{turnId:R.turnId,annotations:R.annotations});break;case"heartbeat":this.sendNotification("turn.heartbeat",{turnId:R.turnId,message:R.message});break;case"tool_use_summary":this.sendNotification("turn.tool_use_summary",{turnId:R.turnId,summary:R.summary});break}}if(this.log(`turn ${t} completed`),this.sessionState?.recordTurnCompleted(),this.sessionState){
|
|
868
|
-
`),error:_.details?.error}}catch(A){return{result:"",error:A instanceof Error?A.message:String(A)}}}},tools:getToolManifest(),apiKey:this.currentApiKey,model:l.model??this.currentModel,log:{info:m=>this.log(m),warn:m=>this.log(`[warn] ${m}`),error:m=>this.log(`[error] ${m}`),debug:m=>{this.verbose&&this.log(`[debug] ${m}`)}},hooks:this.currentHooks??void 0,parentSignal:c.signal,memoryProvider:this.memoryProvider??void 0,memoryUserId:this.memoryUserId||void 0},p=await runDream(u);if(p.ok){if(this.memoryProvider&&this.memoryUserId)try{let m=await runDecayCycle({adapter:this.memoryProvider,userId:this.memoryUserId,memoryRoot:o,log:{info:h=>this.log(h),debug:h=>{this.verbose&&this.log(h)}}});m.ran&&(this.sendNotification("memory.decay.completed",{decayed:m.decayed,archived:m.archived,durationMs:m.durationMs}),this.sendNotification("system.activity",{category:"decay",level:"info",title:"\u8BB0\u5FC6\u8870\u51CF\u5B8C\u6210",detail:`\u8870\u51CF ${m.decayed} \u6761\uFF0C\u5F52\u6863 ${m.archived} \u6761 (${m.durationMs}ms)`}))}catch(m){this.log(`[decay] post-dream decay error: ${m instanceof Error?m.message:String(m)}`)}this.sendNotification("system.activity",{category:"dream",level:"success",title:"\u68A6\u5883\u6574\u7406\u5B8C\u6210",detail:`\u56DE\u987E ${p.sessionsReviewed} \u4E2A\u4F1A\u8BDD\uFF0C\u6574\u7406 ${p.filesTouched.length} \u4E2A\u8BB0\u5FC6\u6587\u4EF6\uFF0C\u8017\u65F6 ${p.durationMs}ms`}),this.sendNotification("turn.end",{turnId:t,content:`Dream consolidation completed. ${p.sessionsReviewed} sessions reviewed, ${p.filesTouched.length} files touched. Duration: ${p.durationMs}ms.`,usage:{inputTokens:0,outputTokens:0}})}else this.sendNotification("system.activity",{category:"dream",level:"error",title:"\u68A6\u5883\u6574\u7406\u5931\u8D25",detail:p.error??"\u672A\u77E5\u9519\u8BEF"}),this.sendNotification("turn.error",{turnId:t,error:{message:p.error??"Dream consolidation failed",code:"DREAM_FAILED"}});this.log(`dream ${t} completed`)}catch(u){if(c.signal.aborted)this.sendNotification("system.activity",{category:"dream",level:"warn",title:"\u68A6\u5883\u6574\u7406\u88AB\u4E2D\u65AD"}),this.sendNotification("turn.error",{turnId:t,error:{message:"Dream aborted",code:"ABORTED"}});else{let p=u instanceof Error?u.message:String(u);this.sendNotification("system.activity",{category:"dream",level:"error",title:"\u68A6\u5883\u6574\u7406\u5F02\u5E38",detail:p}),this.sendNotification("turn.error",{turnId:t,error:{message:p,code:"INTERNAL_ERROR"}})}}finally{this.activeTurn===c&&(this.activeTurn=null)}}import{randomUUID as p_}from"node:crypto";var Dr=class{nodes=new Map;constructor(e){for(let t of e){if(this.nodes.has(t.taskId))throw new Error(`Duplicate task ID: ${t.taskId}`);this.nodes.set(t.taskId,{taskId:t.taskId,assignee:t.assignee,prompt:t.prompt,dependsOn:t.dependsOn??[],status:"pending"})}this.validateDag()}getAllTasks(){return[...this.nodes.values()]}getTask(e){return this.nodes.get(e)}getReadyTasks(){let e=[];for(let t of this.nodes.values()){if(t.status!=="pending")continue;t.dependsOn.every(s=>this.nodes.get(s)?.status==="completed")&&e.push(t)}return e}markRunning(e){let t=this.nodes.get(e);if(!t)throw new Error(`Unknown task: ${e}`);if(t.status!=="pending")throw new Error(`Task ${e} is ${t.status}, cannot start`);t.status="running",t.startedAt=Date.now()}markCompleted(e,t){let r=this.nodes.get(e);if(!r)throw new Error(`Unknown task: ${e}`);if(r.status!=="running")throw new Error(`Task ${e} is ${r.status}, cannot complete`);r.status="completed",r.result=t,r.completedAt=Date.now()}markFailed(e,t){let r=this.nodes.get(e);if(!r)throw new Error(`Unknown task: ${e}`);r.status="failed",r.error=t,r.completedAt=Date.now()}markPaused(e){let t=this.nodes.get(e);if(!t)throw new Error(`Unknown task: ${e}`);t.status==="running"&&(t.status="paused")}resumePaused(e){let t=this.nodes.get(e);if(!t)throw new Error(`Unknown task: ${e}`);t.status==="paused"&&(t.status="pending")}isFinished(){for(let e of this.nodes.values())if(e.status==="running"||e.status==="paused"||e.status==="pending"&&!e.dependsOn.some(r=>this.nodes.get(r)?.status==="failed"))return!1;return!0}isAllCompleted(){return[...this.nodes.values()].every(e=>e.status==="completed")}getBlockedTasks(){return[...this.nodes.values()].filter(e=>e.status!=="pending"?!1:e.dependsOn.some(t=>this.nodes.get(t)?.status==="failed"))}pauseAll(){for(let e of this.nodes.values())e.status==="running"&&(e.status="paused")}resumeAll(){for(let e of this.nodes.values())e.status==="paused"&&(e.status="pending")}serialize(){return[...this.nodes.values()].map(e=>({taskId:e.taskId,assignee:e.assignee,prompt:e.prompt,dependsOn:e.dependsOn,status:e.status,result:e.result,error:e.error,startedAt:e.startedAt,completedAt:e.completedAt}))}restore(e){for(let t of e){let r=this.nodes.get(t.taskId);r&&(r.status=t.status==="running"?"pending":t.status,r.result=t.result,r.error=t.error,r.startedAt=t.startedAt,r.completedAt=t.completedAt)}}addTask(e){if(this.nodes.has(e.taskId))throw new Error(`Task "${e.taskId}" already exists`);for(let r of e.dependsOn??[])if(!this.nodes.has(r))throw new Error(`New task "${e.taskId}" depends on unknown task "${r}"`);let t={taskId:e.taskId,assignee:e.assignee,prompt:e.prompt,dependsOn:e.dependsOn??[],status:"pending"};this.nodes.set(e.taskId,t);try{this.validateDag()}catch(r){throw this.nodes.delete(e.taskId),r}}addTasks(e){let t=[];try{for(let r of e)this.addTask(r),t.push(r.taskId)}catch(r){for(let s of t)this.nodes.delete(s);throw r}}removeTask(e){let t=this.nodes.get(e);if(!t)throw new Error(`Unknown task: ${e}`);if(t.status==="running")throw new Error(`Cannot remove running task "${e}"`);if(t.status==="completed")throw new Error(`Cannot remove completed task "${e}"`);for(let r of this.nodes.values()){let s=r.dependsOn.indexOf(e);s!==-1&&r.dependsOn.splice(s,1)}this.nodes.delete(e)}retryTask(e,t){let r=this.nodes.get(e);if(!r)throw new Error(`Unknown task: ${e}`);if(r.status!=="failed")throw new Error(`Task "${e}" is ${r.status}, only failed tasks can be retried`);r.status="pending",r.error=void 0,r.result=void 0,r.startedAt=void 0,r.completedAt=void 0,t&&(r.prompt=t)}updateTaskPrompt(e,t){let r=this.nodes.get(e);if(!r)throw new Error(`Unknown task: ${e}`);if(r.status!=="pending")throw new Error(`Task "${e}" is ${r.status}, can only update pending tasks`);r.prompt=t}reassignTask(e,t){let r=this.nodes.get(e);if(!r)throw new Error(`Unknown task: ${e}`);if(r.status!=="pending")throw new Error(`Task "${e}" is ${r.status}, can only reassign pending tasks`);r.assignee=t}addDependency(e,t){let r=this.nodes.get(e);if(!r)throw new Error(`Unknown task: ${e}`);if(!this.nodes.has(t))throw new Error(`Unknown dependency task: ${t}`);if(!r.dependsOn.includes(t)){r.dependsOn.push(t);try{this.validateDag()}catch(s){throw r.dependsOn.pop(),s}}}getProgress(){let e=0,t=0,r=0,s=0,o=0;for(let i of this.nodes.values())switch(i.status){case"completed":e++;break;case"running":t++;break;case"failed":r++;break;case"pending":s++;break;case"paused":o++;break}return{total:this.nodes.size,completed:e,running:t,failed:r,pending:s,paused:o}}validateDag(){for(let s of this.nodes.values())for(let o of s.dependsOn)if(!this.nodes.has(o))throw new Error(`Task "${s.taskId}" depends on unknown task "${o}"`);let e=new Set,t=new Set,r=s=>{if(t.has(s))throw new Error(`Cycle detected involving task "${s}"`);if(e.has(s))return;t.add(s);let o=this.nodes.get(s);for(let i of o.dependsOn)r(i);t.delete(s),e.add(s)};for(let s of this.nodes.keys())r(s)}};var Or=class{maxTotalTokens;maxDuration;usedTokens=0;startedAt;warningEmitted=!1;constructor(e){this.maxTotalTokens=e?.maxTotalTokens,this.maxDuration=e?.maxDuration,this.startedAt=Date.now()}addUsage(e,t){this.usedTokens+=e+t}addFromTracker(e){if(!e.hasData())return;let t=e.getUsage();this.usedTokens+=t.totalTokens}getElapsed(){return Date.now()-this.startedAt}getBudget(){return{maxTotalTokens:this.maxTotalTokens,maxDuration:this.maxDuration,usedTokens:this.usedTokens,elapsed:this.getElapsed()}}check(){let e=this.getElapsed();if(this.maxDuration&&e>=this.maxDuration)return{action:"exceeded",percentage:Math.round(e/this.maxDuration*100),usedTokens:this.usedTokens,maxTotalTokens:this.maxTotalTokens,elapsed:e,maxDuration:this.maxDuration};if(this.maxTotalTokens){let r=Math.round(this.usedTokens/this.maxTotalTokens*100);if(this.usedTokens>=this.maxTotalTokens)return{action:"exceeded",percentage:r,usedTokens:this.usedTokens,maxTotalTokens:this.maxTotalTokens,elapsed:e,maxDuration:this.maxDuration};if(r>=80&&!this.warningEmitted)return this.warningEmitted=!0,{action:"warning",percentage:r,usedTokens:this.usedTokens,maxTotalTokens:this.maxTotalTokens,elapsed:e,maxDuration:this.maxDuration}}return{action:"ok",percentage:this.maxTotalTokens?Math.round(this.usedTokens/this.maxTotalTokens*100):0,usedTokens:this.usedTokens,maxTotalTokens:this.maxTotalTokens,elapsed:e,maxDuration:this.maxDuration}}restore(e){this.usedTokens=e.usedTokens,this.startedAt=e.startedAt,this.warningEmitted=e.warningEmitted}serialize(){return{usedTokens:this.usedTokens,startedAt:this.startedAt,warningEmitted:this.warningEmitted}}};import{join as el}from"node:path";import{mkdir as i_,readdir as a_}from"node:fs/promises";ae();function Pf(n){return el(Me(n),"products")}function If(n,e){return el(Pf(e),n)}function _f(n,e){return el(If(n,e),"product-state.json")}async function Ef(n,e){let t=If(n.productId,e);await i_(t,{recursive:!0}),await Nn(_f(n.productId,e),n)}async function tl(n,e){return mn(_f(n,e))}async function Cf(n){let e=Pf(n),t;try{t=await a_(e)}catch{return[]}let r=[];for(let s of t){let o=await tl(s,n);o&&r.push(o)}return r}var Lr=class n{constructor(e={}){this.callbacks=e}callbacks;static DEFAULT_INTERVAL=5*6e4;static LONG_RUNNING_INTERVAL=30*6e4;static LONG_RUNNING_THRESHOLD=2880*6e4;timer=null;lastCheckpointAt=0;cwd;start(e){this.cwd=e,this.stop(),this.timer=setInterval(()=>{let t=this.callbacks.getState?.();t&&this.checkpoint(t).catch(r=>{this.callbacks.log?.warn(`[checkpoint] periodic save failed: ${r instanceof Error?r.message:String(r)}`)})},n.DEFAULT_INTERVAL),this.timer.unref()}stop(){this.timer&&(clearInterval(this.timer),this.timer=null)}getInterval(e){return e>n.LONG_RUNNING_THRESHOLD?n.LONG_RUNNING_INTERVAL:n.DEFAULT_INTERVAL}isDue(e){if(this.lastCheckpointAt===0)return!0;let t=this.getInterval(e);return Date.now()-this.lastCheckpointAt>=t}async checkpoint(e){let t=new Date().toISOString();e.lastCheckpointAt=t,await Ef(e,this.cwd),this.lastCheckpointAt=Date.now(),this.callbacks.onCheckpoint?.(e.productId,t),this.callbacks.log?.info(`[checkpoint] saved ${e.productId} at ${t}`)}getLastCheckpointAt(){return this.lastCheckpointAt}};import{execFile as c_}from"node:child_process";import{promisify as l_}from"node:util";import{join as Mf}from"node:path";import{mkdir as d_,rm as u_}from"node:fs/promises";var $n=l_(c_);async function $r(n){try{let{stdout:e}=await $n("git",["rev-parse","--show-toplevel"],{cwd:n,encoding:"utf8"});return e.trim()}catch{return null}}async function po(n,e,t){let r=Mf(n,".worktrees");await d_(r,{recursive:!0});let s=Mf(r,e),i=["worktree","add","-B",`solo/${e}`,s];return t?i.push(t):i.push("HEAD"),await $n("git",i,{cwd:n,encoding:"utf8"}),s}async function nl(n){try{await $n("git",["add","-A"],{cwd:n});let{stdout:e}=await $n("git",["diff","--cached","--stat"],{cwd:n,encoding:"utf8"});return e.trim()}catch{return""}}async function Nf(n,e){try{await $n("git",["worktree","remove","--force",e],{cwd:n,encoding:"utf8"})}catch{try{await u_(e,{recursive:!0,force:!0})}catch{}}}async function Df(n,e){let{stdout:t}=await $n("git",["merge","--no-ff",e,"-m",`solo: merge ${e}`],{cwd:n,encoding:"utf8"});return t.trim()}var mo=class{constructor(e,t,r,s={}){this.processManager=e;this.acpDetector=t;this.configStore=r;this.callbacks=s}processManager;acpDetector;configStore;callbacks;sessions=new Map;async create(e){let{name:t,cwd:r,instances:s,tasks:o,budget:i}=e;if(s.length===0)throw new Error("Product requires at least 1 instance");if(o.length===0)throw new Error("Product requires at least 1 task");let a=new Set(s.map(b=>b.name));for(let b of o)if(!a.has(b.assignee))throw new Error(`Task "${b.taskId}" references unknown instance "${b.assignee}"`);let c=`product-${p_().slice(0,8)}`,l=new Dr(o),d=new Or(i),u=new Lr({onCheckpoint:(b,k)=>this.callbacks.onCheckpointed?.(b,k),getState:()=>{let b=this.sessions.get(c);return b?this.buildPersistedState(b):null},log:this.callbacks.log}),p=await $r(r),m=s.map((b,k)=>({instanceId:`${c}:${b.name}:${k}`,name:b.name,agentId:b.agentId,state:"idle"})),h={productId:c,name:t,cwd:r,phase:"active",instances:m,dag:l,budget:d,checkpoint:u,createdAt:new Date().toISOString(),gitRoot:p};this.sessions.set(c,h),u.start(r),this.callbacks.log?.info(`[product] created ${c} "${t}" with ${s.length} instances, ${o.length} tasks`);let f=o.map(b=>({id:b.taskId,label:b.taskId,deps:b.dependsOn??[]})),y=[];for(let b of o)if(b.dependsOn)for(let k of b.dependsOn)y.push({from:k,to:b.taskId});return this.callbacks.onDagTopology?.(c,f,y),setTimeout(()=>this.scheduleNext(h),0),c}async resume(e,t){let r=await tl(e,t);if(!r)throw new Error(`Product ${e} not found on disk`);let s=new Dr(r.tasks);s.restore(r.tasks);let o=new Or({maxTotalTokens:r.budget.maxTotalTokens,maxDuration:r.budget.maxDuration});o.restore(r.budget);let i=new Lr({onCheckpoint:(d,u)=>this.callbacks.onCheckpointed?.(d,u),getState:()=>{let d=this.sessions.get(e);return d?this.buildPersistedState(d):null},log:this.callbacks.log}),a=await $r(r.cwd),c=r.instances.map((d,u)=>({instanceId:`${e}:${d.name}:${u}`,name:d.name,agentId:d.agentId,state:"idle"})),l={productId:r.productId,name:r.name,cwd:r.cwd,phase:"active",instances:c,dag:s,budget:o,checkpoint:i,createdAt:r.createdAt,gitRoot:a};this.sessions.set(e,l),i.start(r.cwd),this.callbacks.log?.info(`[product] resumed ${e}`),this.scheduleNext(l)}async pause(e){let t=this.sessions.get(e);if(!t)throw new Error(`Product ${e} not found`);if(t.phase!=="active")throw new Error(`Product ${e} is not active`);t.phase="paused",t.dag.pauseAll();for(let r of t.instances)if(r.state==="running"&&r.memberId){try{this.processManager.kill(r.memberId)}catch{}r.state="paused"}await t.checkpoint.checkpoint(this.buildPersistedState(t)),t.checkpoint.stop(),this.callbacks.log?.info(`[product] paused ${e}`)}async checkpoint(e){let t=this.sessions.get(e);if(!t)throw new Error(`Product ${e} not found`);await t.checkpoint.checkpoint(this.buildPersistedState(t))}async delete(e){let t=this.sessions.get(e);if(!t)throw new Error(`Product ${e} not found`);if(t.phase==="active"){t.phase="failed",t.dag.pauseAll();for(let r of t.instances)if(r.state==="running"&&r.memberId){try{this.processManager.kill(r.memberId)}catch{}r.state="failed"}}t.checkpoint.stop(),this.sessions.delete(e),this.callbacks.log?.info(`[product] deleted ${e}`)}async rollback(e,t){let r=this.sessions.get(e);if(!r)throw new Error(`Product ${e} not found`);let s=r.cwd;await this.delete(e),await this.resume(e,s),this.callbacks.log?.info(`[product] rolled back ${e} to checkpoint ${t}`)}getStatus(e){let t=this.sessions.get(e);return t?{productId:t.productId,name:t.name,phase:t.phase,instances:t.instances.map(r=>{let o=(r.memberId?this.processManager.getUsageTracker(r.memberId):null)?.getUsage();return{instanceId:r.instanceId,name:r.name,agentId:r.agentId,state:r.state,worktreePath:r.worktreePath,usage:o&&(o.inputTokens>0||o.outputTokens>0)?{inputTokens:o.inputTokens,outputTokens:o.outputTokens}:void 0}}),tasks:t.dag.getAllTasks().map(r=>({taskId:r.taskId,assignee:r.assignee,status:r.status,result:r.result,error:r.error,startedAt:r.startedAt?new Date(r.startedAt).toISOString():void 0,completedAt:r.completedAt?new Date(r.completedAt).toISOString():void 0})),budget:t.budget.getBudget(),lastCheckpointAt:new Date(t.checkpoint.getLastCheckpointAt()||Date.now()).toISOString()}:null}async list(e){let t=[];for(let s of this.sessions.values()){let o=s.dag.getAllTasks();t.push({productId:s.productId,name:s.name,phase:s.phase,instanceCount:s.instances.length,taskCount:o.length,completedTasks:o.filter(i=>i.status==="completed").length,createdAt:s.createdAt,lastCheckpointAt:new Date(s.checkpoint.getLastCheckpointAt()||Date.now()).toISOString()})}let r=await Cf(e);for(let s of r)this.sessions.has(s.productId)||t.push({productId:s.productId,name:s.name,phase:s.phase,instanceCount:s.instances.length,taskCount:s.tasks.length,completedTasks:s.tasks.filter(o=>o.status==="completed").length,createdAt:s.createdAt,lastCheckpointAt:s.lastCheckpointAt});return t}scheduleNext(e){if(e.phase!=="active")return;let t=e.budget.check();if(t.action==="exceeded"){this.callbacks.log?.warn(`[product] ${e.productId} budget exceeded, auto-pausing`),this.pause(e.productId).catch(s=>{this.callbacks.log?.warn(`[product] auto-pause failed: ${s instanceof Error?s.message:String(s)}`)});return}if(t.action==="warning"&&this.callbacks.onBudgetWarning?.(e.productId,t.usedTokens,t.maxTotalTokens,t.percentage),e.dag.isFinished()){this.finishProduct(e);return}let r=e.dag.getReadyTasks();for(let s of r)this.dispatchTask(e,s)}dispatchTask(e,t){let r=e.instances.find(s=>s.name===t.assignee);if(!r){e.dag.markFailed(t.taskId,`No instance found for assignee "${t.assignee}"`),this.callbacks.onTaskFailed?.(e.productId,t.taskId,`No instance for "${t.assignee}"`),this.scheduleNext(e);return}e.dag.markRunning(t.taskId),r.state="running",this.callbacks.onTaskStarted?.(e.productId,t.taskId,t.assignee),this.callbacks.log?.info(`[product] ${e.productId} dispatching task ${t.taskId} to ${t.assignee}`),this.runTask(e,r,t).catch(s=>{this.callbacks.log?.warn(`[product] task dispatch error: ${s instanceof Error?s.message:String(s)}`)})}async runTask(e,t,r){let s=`${e.productId}:${t.name}:${r.taskId}`;t.memberId=s;try{let o=this.acpDetector.buildExternalDescriptor(t.agentId);if(!o)throw new Error(`Agent ${t.agentId} is not available`);let i=e.cwd;if(e.gitRoot){let d=`${e.productId}-${t.name}-${r.taskId}`;try{i=await po(e.gitRoot,d),t.worktreePath=i}catch{this.callbacks.log?.warn(`[product] worktree creation failed for ${r.taskId}, using project cwd`)}}await this.processManager.spawn({memberId:s,name:`product-${t.name}`,cwd:i,prompt:r.prompt,external:o});let a=await this.processManager.sendTask(s,r.prompt),c=typeof a=="string"?a:JSON.stringify(a),l=this.processManager.getUsageTracker(s);if(l?.hasData()){let d=l.getUsage();e.budget.addUsage(d.inputTokens,d.outputTokens);let u=e.budget.getBudget();this.callbacks.onBudgetUpdate?.(e.productId,u.usedTokens,0,u.elapsed,u.maxTotalTokens)}e.dag.markCompleted(r.taskId,c),t.state="completed",this.callbacks.onTaskCompleted?.(e.productId,r.taskId,c);try{this.processManager.kill(s)}catch{}this.processManager.remove(s)}catch(o){let i=o instanceof Error?o.message:String(o);e.dag.markFailed(r.taskId,i),t.state="failed",this.callbacks.onTaskFailed?.(e.productId,r.taskId,i);try{this.processManager.kill(s)}catch{}try{this.processManager.remove(s)}catch{}}try{await e.checkpoint.checkpoint(this.buildPersistedState(e))}catch(o){this.callbacks.log?.warn(`[product] checkpoint failed: ${o instanceof Error?o.message:String(o)}`)}this.scheduleNext(e)}finishProduct(e){if(e.dag.isAllCompleted()){e.phase="completed";let t=e.dag.getAllTasks(),r=`Product "${e.name}" completed: ${t.length} tasks all done.`;this.callbacks.onCompleted?.(e.productId,r)}else{e.phase="failed";let r=e.dag.getAllTasks().filter(i=>i.status==="failed").length,s=e.dag.getBlockedTasks().length,o=`Product "${e.name}" finished with ${r} failed, ${s} blocked tasks.`;this.callbacks.onCompleted?.(e.productId,o)}e.checkpoint.stop(),e.checkpoint.checkpoint(this.buildPersistedState(e)).catch(t=>{this.callbacks.log?.warn(`[product] final checkpoint failed: ${t instanceof Error?t.message:String(t)}`)}),this.callbacks.log?.info(`[product] ${e.productId} finished (phase=${e.phase})`)}buildPersistedState(e){return{productId:e.productId,name:e.name,phase:e.phase,cwd:e.cwd,instances:e.instances.map(t=>({name:t.name,role:"",agentId:t.agentId})),tasks:e.dag.serialize(),budget:e.budget.serialize(),createdAt:e.createdAt,lastCheckpointAt:new Date(e.checkpoint.getLastCheckpointAt()||Date.now()).toISOString()}}};import{randomUUID as Of}from"node:crypto";function m_(n,e){let t=e?`
|
|
867
|
+
`,version:"1.0.0",category:"learned"}),x=no(S,U.suggestedName);if(x.valid){Ln.mkdirSync(Mt,{recursive:!0}),Ln.writeFileSync(g,S,"utf8"),pt();let E=q(),w=Be(E);qt(w,U.suggestedName,"learned"),We(E,w),this.log(`[skill-auto-persist] Created skill "${U.suggestedName}" from turn ${R.turnId}`)}else this.log(`[skill-auto-persist] Validation failed for "${U.suggestedName}": ${x.errors.join(", ")}`)}}break;case"tool_call":this.sendNotification("turn.tool_call",{turnId:R.turnId,callId:R.callId,name:R.name,arguments:R.arguments,item:{id:R.callId,type:"tool_call",role:"assistant",toolName:R.name,toolCallId:R.callId,arguments:R.arguments,createdAt:B}}),this.sessionState?.recordToolCall();break;case"tool_result":this.sendNotification("turn.tool_result",{turnId:R.turnId,callId:R.callId,name:R.name,ok:R.ok,...R.error?{error:R.error}:{},...R.outputPreview?{outputPreview:R.outputPreview}:{},item:{id:`${R.callId}-result`,type:"tool_result",role:"assistant",toolName:R.name,toolCallId:R.callId,output:R.ok?R.outputPreview??"":R.error,approved:R.ok,createdAt:B}});break;case"tool_blocked":this.sendNotification("turn.tool_blocked",{turnId:R.turnId,callId:R.callId,name:R.name,reason:R.reason,item:{id:`${R.callId}-blocked`,type:"tool_blocked",role:"system",toolName:R.name,toolCallId:R.callId,text:R.reason,approved:!1,createdAt:B}});break;case"recovery":this.sendNotification("turn.recovery",{turnId:R.turnId,action:R.action,...R.detail?{detail:R.detail}:{},item:{id:`${t}-recovery-${lo().slice(0,8)}`,type:"recovery",role:"system",strategy:R.action,text:R.detail,createdAt:B}});break;case"plan_update":this.sendNotification("turn.plan_update",{turnId:R.turnId,slug:R.slug,content:R.content,item:{id:`${t}-plan-${lo().slice(0,8)}`,type:"plan_update",role:"assistant",text:R.content,createdAt:B}});break;case"reasoning_delta":this.sendNotification("turn.reasoning_delta",{turnId:R.turnId,text:R.text});break;case"suggestions":this.sendNotification("turn.suggestions",{turnId:R.turnId,items:R.items});break;case"media_result":this.sendNotification("turn.media_result",{turnId:R.turnId,mediaType:R.mediaType,url:R.url,...R.model?{model:R.model}:{},...R.provider?{provider:R.provider}:{},...R.taskId?{taskId:R.taskId}:{}});break;case"artifact":this.sendNotification("turn.artifact",{turnId:R.turnId,artifactId:R.artifactId,type:R.artifactType,title:R.title,...R.filePath?{filePath:R.filePath}:{},...R.language?{language:R.language}:{},...R.content?{content:R.content}:{},...R.mimeType?{mimeType:R.mimeType}:{}});break;case"subagent_started":this.sendNotification("turn.subagent_started",{turnId:R.turnId,subagentId:R.subagentId,agentType:R.agentType,...R.prompt?{prompt:R.prompt}:{}});break;case"subagent_ended":this.sendNotification("turn.subagent_ended",{turnId:R.turnId,subagentId:R.subagentId,agentType:R.agentType,ok:R.ok,...R.outputPreview?{outputPreview:R.outputPreview}:{},...R.error?{error:R.error}:{}});break;case"annotations":this.sendNotification("turn.annotations",{turnId:R.turnId,annotations:R.annotations});break;case"heartbeat":this.sendNotification("turn.heartbeat",{turnId:R.turnId,message:R.message});break;case"tool_use_summary":this.sendNotification("turn.tool_use_summary",{turnId:R.turnId,summary:R.summary});break}}if(this.log(`turn ${t} completed`),this.sessionState?.recordTurnCompleted(),this.sessionState){Lu(r,this.sessionState.createSnapshot(),{model:this.currentModel,cwd:p,messageCount:s.length},p).catch(()=>{});let R=this.sessionState.createSnapshot();this.sendNotification("session.info",{sessionId:r,model:this.currentModel||void 0,cwd:p,turnCount:R.turnCount,projectId:i?.projectId||void 0});let B=this.resolveClientForPurpose("smallModel");if(B&&ju(r,{sessionId:r,projectId:"",createdAt:"",lastActiveAt:"",turnCount:R.turnCount,messageCount:s.length},s,{transport:B.transport,apiKey:B.apiKey,model:B.model},p),this.generateSuggestions(t,s),this.petAwardXp("turn.end"),this.petReactionAfterTurn(s),i?.sessionType==="group"&&this.sessionState){let U=this.sessionState.createSnapshot(),Ae=cn(r,p);Ae&&Sf({...Ae,turnCount:U.turnCount},p).then(fe=>{fe.split&&this.sendNotification("session-update",{sessionId:fe.activeSessionId,projectId:i?.projectId??"",title:"",type:"group"})}).catch(()=>{})}}}catch(y){if(m.signal.aborted)this.sendNotification("turn.error",{turnId:t,error:{message:"Turn aborted",code:"ABORTED"}});else{let b=y instanceof Error?y.message:String(y);this.sendNotification("turn.error",{turnId:t,error:{message:b,code:"INTERNAL_ERROR"}})}}finally{this.activeTurn===m&&(this.activeTurn=null),h()}}dt();import{randomUUID as Pf}from"node:crypto";async function uo(n){let e=n.params??{},t=e.turnId??Pf(),r=e.sessionId,s=e.config,o=s?.memoryRoot??"",i=s?.transcriptDir??"",a=s?.dreamSessionIds??[];n.id!==void 0&&this.sendResponse(n.id,{accepted:!0,turnId:t});let c=new AbortController;this.activeTurn=c,this.log(`dream ${t} starting (session: ${r}, sessions reviewing: ${a.length})`),this.sendNotification("system.activity",{category:"dream",level:"info",title:"\u68A6\u5883\u6574\u7406\u542F\u52A8",detail:`\u6B63\u5728\u56DE\u987E ${a.length} \u4E2A\u4F1A\u8BDD\u7684\u8BB0\u5FC6...`});let l={provider:s?.provider,model:s?.model,apiKey:s?.apiKey,baseUrl:s?.baseUrl,maxRounds:s?.maxRounds,temperature:s?.temperature,contextWindowTokens:s?.contextWindowTokens,maxOutputTokens:s?.maxOutputTokens,modelMaxOutputTokens:s?.modelMaxOutputTokens,reasoning:s?.reasoning,promptCacheKey:s?.promptCacheKey,promptCacheRetention:s?.promptCacheRetention,serviceTier:s?.serviceTier,openaiBuiltinTools:s?.openaiBuiltinTools,maxToolCalls:s?.maxToolCalls,parallelToolCalls:s?.parallelToolCalls,textVerbosity:s?.textVerbosity};{let u=l.provider??"",p=l.model??"";if(u&&p){let m=Y().getModelInfo(u,p);m?.streamRequired&&(l.streamRequired=!0),!l.contextWindowTokens&&m?.contextWindow&&(l.contextWindowTokens=m.contextWindow)}}if(!this.resolveAgent(l)){this.sendNotification("turn.start",{turnId:t}),this.sendNotification("turn.error",{turnId:t,error:{message:"No LLM provider configured for dream.",code:"NO_PROVIDER"}});return}this.sendNotification("turn.start",{turnId:t});try{let u={context:{memoryRoot:o,transcriptDir:i,currentSessionId:r,listSessionsSince:async()=>a,currentSessionTurnCount:s?.currentSessionTurnCount??0},triggerConfig:{force:s?.force!==!1},transport:this.currentTransport,toolInvoker:{invoke:async(m,h,f,y)=>{if(h.startsWith("$"))return{result:f};let b=findTool(h);if(!b)return{result:"",error:`Unknown tool: ${h}`};let k=`tc_${Pf().slice(0,8)}`;try{let A=JSON.parse(f),_=await b.execute(k,A,y);return{result:_.content.map(N=>N.text??"").join(`
|
|
868
|
+
`),error:_.details?.error}}catch(A){return{result:"",error:A instanceof Error?A.message:String(A)}}}},tools:getToolManifest(),apiKey:this.currentApiKey,model:l.model??this.currentModel,log:{info:m=>this.log(m),warn:m=>this.log(`[warn] ${m}`),error:m=>this.log(`[error] ${m}`),debug:m=>{this.verbose&&this.log(`[debug] ${m}`)}},hooks:this.currentHooks??void 0,parentSignal:c.signal,memoryProvider:this.memoryProvider??void 0,memoryUserId:this.memoryUserId||void 0},p=await runDream(u);if(p.ok){if(this.memoryProvider&&this.memoryUserId)try{let m=await runDecayCycle({adapter:this.memoryProvider,userId:this.memoryUserId,memoryRoot:o,log:{info:h=>this.log(h),debug:h=>{this.verbose&&this.log(h)}}});m.ran&&(this.sendNotification("memory.decay.completed",{decayed:m.decayed,archived:m.archived,durationMs:m.durationMs}),this.sendNotification("system.activity",{category:"decay",level:"info",title:"\u8BB0\u5FC6\u8870\u51CF\u5B8C\u6210",detail:`\u8870\u51CF ${m.decayed} \u6761\uFF0C\u5F52\u6863 ${m.archived} \u6761 (${m.durationMs}ms)`}))}catch(m){this.log(`[decay] post-dream decay error: ${m instanceof Error?m.message:String(m)}`)}this.sendNotification("system.activity",{category:"dream",level:"success",title:"\u68A6\u5883\u6574\u7406\u5B8C\u6210",detail:`\u56DE\u987E ${p.sessionsReviewed} \u4E2A\u4F1A\u8BDD\uFF0C\u6574\u7406 ${p.filesTouched.length} \u4E2A\u8BB0\u5FC6\u6587\u4EF6\uFF0C\u8017\u65F6 ${p.durationMs}ms`}),this.sendNotification("turn.end",{turnId:t,content:`Dream consolidation completed. ${p.sessionsReviewed} sessions reviewed, ${p.filesTouched.length} files touched. Duration: ${p.durationMs}ms.`,usage:{inputTokens:0,outputTokens:0}})}else this.sendNotification("system.activity",{category:"dream",level:"error",title:"\u68A6\u5883\u6574\u7406\u5931\u8D25",detail:p.error??"\u672A\u77E5\u9519\u8BEF"}),this.sendNotification("turn.error",{turnId:t,error:{message:p.error??"Dream consolidation failed",code:"DREAM_FAILED"}});this.log(`dream ${t} completed`)}catch(u){if(c.signal.aborted)this.sendNotification("system.activity",{category:"dream",level:"warn",title:"\u68A6\u5883\u6574\u7406\u88AB\u4E2D\u65AD"}),this.sendNotification("turn.error",{turnId:t,error:{message:"Dream aborted",code:"ABORTED"}});else{let p=u instanceof Error?u.message:String(u);this.sendNotification("system.activity",{category:"dream",level:"error",title:"\u68A6\u5883\u6574\u7406\u5F02\u5E38",detail:p}),this.sendNotification("turn.error",{turnId:t,error:{message:p,code:"INTERNAL_ERROR"}})}}finally{this.activeTurn===c&&(this.activeTurn=null)}}import{randomUUID as p_}from"node:crypto";var Dr=class{nodes=new Map;constructor(e){for(let t of e){if(this.nodes.has(t.taskId))throw new Error(`Duplicate task ID: ${t.taskId}`);this.nodes.set(t.taskId,{taskId:t.taskId,assignee:t.assignee,prompt:t.prompt,dependsOn:t.dependsOn??[],status:"pending"})}this.validateDag()}getAllTasks(){return[...this.nodes.values()]}getTask(e){return this.nodes.get(e)}getReadyTasks(){let e=[];for(let t of this.nodes.values()){if(t.status!=="pending")continue;t.dependsOn.every(s=>this.nodes.get(s)?.status==="completed")&&e.push(t)}return e}markRunning(e){let t=this.nodes.get(e);if(!t)throw new Error(`Unknown task: ${e}`);if(t.status!=="pending")throw new Error(`Task ${e} is ${t.status}, cannot start`);t.status="running",t.startedAt=Date.now()}markCompleted(e,t){let r=this.nodes.get(e);if(!r)throw new Error(`Unknown task: ${e}`);if(r.status!=="running")throw new Error(`Task ${e} is ${r.status}, cannot complete`);r.status="completed",r.result=t,r.completedAt=Date.now()}markFailed(e,t){let r=this.nodes.get(e);if(!r)throw new Error(`Unknown task: ${e}`);r.status="failed",r.error=t,r.completedAt=Date.now()}markPaused(e){let t=this.nodes.get(e);if(!t)throw new Error(`Unknown task: ${e}`);t.status==="running"&&(t.status="paused")}resumePaused(e){let t=this.nodes.get(e);if(!t)throw new Error(`Unknown task: ${e}`);t.status==="paused"&&(t.status="pending")}isFinished(){for(let e of this.nodes.values())if(e.status==="running"||e.status==="paused"||e.status==="pending"&&!e.dependsOn.some(r=>this.nodes.get(r)?.status==="failed"))return!1;return!0}isAllCompleted(){return[...this.nodes.values()].every(e=>e.status==="completed")}getBlockedTasks(){return[...this.nodes.values()].filter(e=>e.status!=="pending"?!1:e.dependsOn.some(t=>this.nodes.get(t)?.status==="failed"))}pauseAll(){for(let e of this.nodes.values())e.status==="running"&&(e.status="paused")}resumeAll(){for(let e of this.nodes.values())e.status==="paused"&&(e.status="pending")}serialize(){return[...this.nodes.values()].map(e=>({taskId:e.taskId,assignee:e.assignee,prompt:e.prompt,dependsOn:e.dependsOn,status:e.status,result:e.result,error:e.error,startedAt:e.startedAt,completedAt:e.completedAt}))}restore(e){for(let t of e){let r=this.nodes.get(t.taskId);r&&(r.status=t.status==="running"?"pending":t.status,r.result=t.result,r.error=t.error,r.startedAt=t.startedAt,r.completedAt=t.completedAt)}}addTask(e){if(this.nodes.has(e.taskId))throw new Error(`Task "${e.taskId}" already exists`);for(let r of e.dependsOn??[])if(!this.nodes.has(r))throw new Error(`New task "${e.taskId}" depends on unknown task "${r}"`);let t={taskId:e.taskId,assignee:e.assignee,prompt:e.prompt,dependsOn:e.dependsOn??[],status:"pending"};this.nodes.set(e.taskId,t);try{this.validateDag()}catch(r){throw this.nodes.delete(e.taskId),r}}addTasks(e){let t=[];try{for(let r of e)this.addTask(r),t.push(r.taskId)}catch(r){for(let s of t)this.nodes.delete(s);throw r}}removeTask(e){let t=this.nodes.get(e);if(!t)throw new Error(`Unknown task: ${e}`);if(t.status==="running")throw new Error(`Cannot remove running task "${e}"`);if(t.status==="completed")throw new Error(`Cannot remove completed task "${e}"`);for(let r of this.nodes.values()){let s=r.dependsOn.indexOf(e);s!==-1&&r.dependsOn.splice(s,1)}this.nodes.delete(e)}retryTask(e,t){let r=this.nodes.get(e);if(!r)throw new Error(`Unknown task: ${e}`);if(r.status!=="failed")throw new Error(`Task "${e}" is ${r.status}, only failed tasks can be retried`);r.status="pending",r.error=void 0,r.result=void 0,r.startedAt=void 0,r.completedAt=void 0,t&&(r.prompt=t)}updateTaskPrompt(e,t){let r=this.nodes.get(e);if(!r)throw new Error(`Unknown task: ${e}`);if(r.status!=="pending")throw new Error(`Task "${e}" is ${r.status}, can only update pending tasks`);r.prompt=t}reassignTask(e,t){let r=this.nodes.get(e);if(!r)throw new Error(`Unknown task: ${e}`);if(r.status!=="pending")throw new Error(`Task "${e}" is ${r.status}, can only reassign pending tasks`);r.assignee=t}addDependency(e,t){let r=this.nodes.get(e);if(!r)throw new Error(`Unknown task: ${e}`);if(!this.nodes.has(t))throw new Error(`Unknown dependency task: ${t}`);if(!r.dependsOn.includes(t)){r.dependsOn.push(t);try{this.validateDag()}catch(s){throw r.dependsOn.pop(),s}}}getProgress(){let e=0,t=0,r=0,s=0,o=0;for(let i of this.nodes.values())switch(i.status){case"completed":e++;break;case"running":t++;break;case"failed":r++;break;case"pending":s++;break;case"paused":o++;break}return{total:this.nodes.size,completed:e,running:t,failed:r,pending:s,paused:o}}validateDag(){for(let s of this.nodes.values())for(let o of s.dependsOn)if(!this.nodes.has(o))throw new Error(`Task "${s.taskId}" depends on unknown task "${o}"`);let e=new Set,t=new Set,r=s=>{if(t.has(s))throw new Error(`Cycle detected involving task "${s}"`);if(e.has(s))return;t.add(s);let o=this.nodes.get(s);for(let i of o.dependsOn)r(i);t.delete(s),e.add(s)};for(let s of this.nodes.keys())r(s)}};var Or=class{maxTotalTokens;maxDuration;usedTokens=0;startedAt;warningEmitted=!1;constructor(e){this.maxTotalTokens=e?.maxTotalTokens,this.maxDuration=e?.maxDuration,this.startedAt=Date.now()}addUsage(e,t){this.usedTokens+=e+t}addFromTracker(e){if(!e.hasData())return;let t=e.getUsage();this.usedTokens+=t.totalTokens}getElapsed(){return Date.now()-this.startedAt}getBudget(){return{maxTotalTokens:this.maxTotalTokens,maxDuration:this.maxDuration,usedTokens:this.usedTokens,elapsed:this.getElapsed()}}check(){let e=this.getElapsed();if(this.maxDuration&&e>=this.maxDuration)return{action:"exceeded",percentage:Math.round(e/this.maxDuration*100),usedTokens:this.usedTokens,maxTotalTokens:this.maxTotalTokens,elapsed:e,maxDuration:this.maxDuration};if(this.maxTotalTokens){let r=Math.round(this.usedTokens/this.maxTotalTokens*100);if(this.usedTokens>=this.maxTotalTokens)return{action:"exceeded",percentage:r,usedTokens:this.usedTokens,maxTotalTokens:this.maxTotalTokens,elapsed:e,maxDuration:this.maxDuration};if(r>=80&&!this.warningEmitted)return this.warningEmitted=!0,{action:"warning",percentage:r,usedTokens:this.usedTokens,maxTotalTokens:this.maxTotalTokens,elapsed:e,maxDuration:this.maxDuration}}return{action:"ok",percentage:this.maxTotalTokens?Math.round(this.usedTokens/this.maxTotalTokens*100):0,usedTokens:this.usedTokens,maxTotalTokens:this.maxTotalTokens,elapsed:e,maxDuration:this.maxDuration}}restore(e){this.usedTokens=e.usedTokens,this.startedAt=e.startedAt,this.warningEmitted=e.warningEmitted}serialize(){return{usedTokens:this.usedTokens,startedAt:this.startedAt,warningEmitted:this.warningEmitted}}};import{join as el}from"node:path";import{mkdir as i_,readdir as a_}from"node:fs/promises";ae();function If(n){return el(Me(n),"products")}function _f(n,e){return el(If(e),n)}function Ef(n,e){return el(_f(n,e),"product-state.json")}async function Cf(n,e){let t=_f(n.productId,e);await i_(t,{recursive:!0}),await Nn(Ef(n.productId,e),n)}async function tl(n,e){return mn(Ef(n,e))}async function Mf(n){let e=If(n),t;try{t=await a_(e)}catch{return[]}let r=[];for(let s of t){let o=await tl(s,n);o&&r.push(o)}return r}var Lr=class n{constructor(e={}){this.callbacks=e}callbacks;static DEFAULT_INTERVAL=5*6e4;static LONG_RUNNING_INTERVAL=30*6e4;static LONG_RUNNING_THRESHOLD=2880*6e4;timer=null;lastCheckpointAt=0;cwd;start(e){this.cwd=e,this.stop(),this.timer=setInterval(()=>{let t=this.callbacks.getState?.();t&&this.checkpoint(t).catch(r=>{this.callbacks.log?.warn(`[checkpoint] periodic save failed: ${r instanceof Error?r.message:String(r)}`)})},n.DEFAULT_INTERVAL),this.timer.unref()}stop(){this.timer&&(clearInterval(this.timer),this.timer=null)}getInterval(e){return e>n.LONG_RUNNING_THRESHOLD?n.LONG_RUNNING_INTERVAL:n.DEFAULT_INTERVAL}isDue(e){if(this.lastCheckpointAt===0)return!0;let t=this.getInterval(e);return Date.now()-this.lastCheckpointAt>=t}async checkpoint(e){let t=new Date().toISOString();e.lastCheckpointAt=t,await Cf(e,this.cwd),this.lastCheckpointAt=Date.now(),this.callbacks.onCheckpoint?.(e.productId,t),this.callbacks.log?.info(`[checkpoint] saved ${e.productId} at ${t}`)}getLastCheckpointAt(){return this.lastCheckpointAt}};import{execFile as c_}from"node:child_process";import{promisify as l_}from"node:util";import{join as Nf}from"node:path";import{mkdir as d_,rm as u_}from"node:fs/promises";var $n=l_(c_);async function $r(n){try{let{stdout:e}=await $n("git",["rev-parse","--show-toplevel"],{cwd:n,encoding:"utf8"});return e.trim()}catch{return null}}async function po(n,e,t){let r=Nf(n,".worktrees");await d_(r,{recursive:!0});let s=Nf(r,e),i=["worktree","add","-B",`solo/${e}`,s];return t?i.push(t):i.push("HEAD"),await $n("git",i,{cwd:n,encoding:"utf8"}),s}async function nl(n){try{await $n("git",["add","-A"],{cwd:n});let{stdout:e}=await $n("git",["diff","--cached","--stat"],{cwd:n,encoding:"utf8"});return e.trim()}catch{return""}}async function Df(n,e){try{await $n("git",["worktree","remove","--force",e],{cwd:n,encoding:"utf8"})}catch{try{await u_(e,{recursive:!0,force:!0})}catch{}}}async function Of(n,e){let{stdout:t}=await $n("git",["merge","--no-ff",e,"-m",`solo: merge ${e}`],{cwd:n,encoding:"utf8"});return t.trim()}var mo=class{constructor(e,t,r,s={}){this.processManager=e;this.acpDetector=t;this.configStore=r;this.callbacks=s}processManager;acpDetector;configStore;callbacks;sessions=new Map;async create(e){let{name:t,cwd:r,instances:s,tasks:o,budget:i}=e;if(s.length===0)throw new Error("Product requires at least 1 instance");if(o.length===0)throw new Error("Product requires at least 1 task");let a=new Set(s.map(b=>b.name));for(let b of o)if(!a.has(b.assignee))throw new Error(`Task "${b.taskId}" references unknown instance "${b.assignee}"`);let c=`product-${p_().slice(0,8)}`,l=new Dr(o),d=new Or(i),u=new Lr({onCheckpoint:(b,k)=>this.callbacks.onCheckpointed?.(b,k),getState:()=>{let b=this.sessions.get(c);return b?this.buildPersistedState(b):null},log:this.callbacks.log}),p=await $r(r),m=s.map((b,k)=>({instanceId:`${c}:${b.name}:${k}`,name:b.name,agentId:b.agentId,state:"idle"})),h={productId:c,name:t,cwd:r,phase:"active",instances:m,dag:l,budget:d,checkpoint:u,createdAt:new Date().toISOString(),gitRoot:p};this.sessions.set(c,h),u.start(r),this.callbacks.log?.info(`[product] created ${c} "${t}" with ${s.length} instances, ${o.length} tasks`);let f=o.map(b=>({id:b.taskId,label:b.taskId,deps:b.dependsOn??[]})),y=[];for(let b of o)if(b.dependsOn)for(let k of b.dependsOn)y.push({from:k,to:b.taskId});return this.callbacks.onDagTopology?.(c,f,y),setTimeout(()=>this.scheduleNext(h),0),c}async resume(e,t){let r=await tl(e,t);if(!r)throw new Error(`Product ${e} not found on disk`);let s=new Dr(r.tasks);s.restore(r.tasks);let o=new Or({maxTotalTokens:r.budget.maxTotalTokens,maxDuration:r.budget.maxDuration});o.restore(r.budget);let i=new Lr({onCheckpoint:(d,u)=>this.callbacks.onCheckpointed?.(d,u),getState:()=>{let d=this.sessions.get(e);return d?this.buildPersistedState(d):null},log:this.callbacks.log}),a=await $r(r.cwd),c=r.instances.map((d,u)=>({instanceId:`${e}:${d.name}:${u}`,name:d.name,agentId:d.agentId,state:"idle"})),l={productId:r.productId,name:r.name,cwd:r.cwd,phase:"active",instances:c,dag:s,budget:o,checkpoint:i,createdAt:r.createdAt,gitRoot:a};this.sessions.set(e,l),i.start(r.cwd),this.callbacks.log?.info(`[product] resumed ${e}`),this.scheduleNext(l)}async pause(e){let t=this.sessions.get(e);if(!t)throw new Error(`Product ${e} not found`);if(t.phase!=="active")throw new Error(`Product ${e} is not active`);t.phase="paused",t.dag.pauseAll();for(let r of t.instances)if(r.state==="running"&&r.memberId){try{this.processManager.kill(r.memberId)}catch{}r.state="paused"}await t.checkpoint.checkpoint(this.buildPersistedState(t)),t.checkpoint.stop(),this.callbacks.log?.info(`[product] paused ${e}`)}async checkpoint(e){let t=this.sessions.get(e);if(!t)throw new Error(`Product ${e} not found`);await t.checkpoint.checkpoint(this.buildPersistedState(t))}async delete(e){let t=this.sessions.get(e);if(!t)throw new Error(`Product ${e} not found`);if(t.phase==="active"){t.phase="failed",t.dag.pauseAll();for(let r of t.instances)if(r.state==="running"&&r.memberId){try{this.processManager.kill(r.memberId)}catch{}r.state="failed"}}t.checkpoint.stop(),this.sessions.delete(e),this.callbacks.log?.info(`[product] deleted ${e}`)}async rollback(e,t){let r=this.sessions.get(e);if(!r)throw new Error(`Product ${e} not found`);let s=r.cwd;await this.delete(e),await this.resume(e,s),this.callbacks.log?.info(`[product] rolled back ${e} to checkpoint ${t}`)}getStatus(e){let t=this.sessions.get(e);return t?{productId:t.productId,name:t.name,phase:t.phase,instances:t.instances.map(r=>{let o=(r.memberId?this.processManager.getUsageTracker(r.memberId):null)?.getUsage();return{instanceId:r.instanceId,name:r.name,agentId:r.agentId,state:r.state,worktreePath:r.worktreePath,usage:o&&(o.inputTokens>0||o.outputTokens>0)?{inputTokens:o.inputTokens,outputTokens:o.outputTokens}:void 0}}),tasks:t.dag.getAllTasks().map(r=>({taskId:r.taskId,assignee:r.assignee,status:r.status,result:r.result,error:r.error,startedAt:r.startedAt?new Date(r.startedAt).toISOString():void 0,completedAt:r.completedAt?new Date(r.completedAt).toISOString():void 0})),budget:t.budget.getBudget(),lastCheckpointAt:new Date(t.checkpoint.getLastCheckpointAt()||Date.now()).toISOString()}:null}async list(e){let t=[];for(let s of this.sessions.values()){let o=s.dag.getAllTasks();t.push({productId:s.productId,name:s.name,phase:s.phase,instanceCount:s.instances.length,taskCount:o.length,completedTasks:o.filter(i=>i.status==="completed").length,createdAt:s.createdAt,lastCheckpointAt:new Date(s.checkpoint.getLastCheckpointAt()||Date.now()).toISOString()})}let r=await Mf(e);for(let s of r)this.sessions.has(s.productId)||t.push({productId:s.productId,name:s.name,phase:s.phase,instanceCount:s.instances.length,taskCount:s.tasks.length,completedTasks:s.tasks.filter(o=>o.status==="completed").length,createdAt:s.createdAt,lastCheckpointAt:s.lastCheckpointAt});return t}scheduleNext(e){if(e.phase!=="active")return;let t=e.budget.check();if(t.action==="exceeded"){this.callbacks.log?.warn(`[product] ${e.productId} budget exceeded, auto-pausing`),this.pause(e.productId).catch(s=>{this.callbacks.log?.warn(`[product] auto-pause failed: ${s instanceof Error?s.message:String(s)}`)});return}if(t.action==="warning"&&this.callbacks.onBudgetWarning?.(e.productId,t.usedTokens,t.maxTotalTokens,t.percentage),e.dag.isFinished()){this.finishProduct(e);return}let r=e.dag.getReadyTasks();for(let s of r)this.dispatchTask(e,s)}dispatchTask(e,t){let r=e.instances.find(s=>s.name===t.assignee);if(!r){e.dag.markFailed(t.taskId,`No instance found for assignee "${t.assignee}"`),this.callbacks.onTaskFailed?.(e.productId,t.taskId,`No instance for "${t.assignee}"`),this.scheduleNext(e);return}e.dag.markRunning(t.taskId),r.state="running",this.callbacks.onTaskStarted?.(e.productId,t.taskId,t.assignee),this.callbacks.log?.info(`[product] ${e.productId} dispatching task ${t.taskId} to ${t.assignee}`),this.runTask(e,r,t).catch(s=>{this.callbacks.log?.warn(`[product] task dispatch error: ${s instanceof Error?s.message:String(s)}`)})}async runTask(e,t,r){let s=`${e.productId}:${t.name}:${r.taskId}`;t.memberId=s;try{let o=this.acpDetector.buildExternalDescriptor(t.agentId);if(!o)throw new Error(`Agent ${t.agentId} is not available`);let i=e.cwd;if(e.gitRoot){let d=`${e.productId}-${t.name}-${r.taskId}`;try{i=await po(e.gitRoot,d),t.worktreePath=i}catch{this.callbacks.log?.warn(`[product] worktree creation failed for ${r.taskId}, using project cwd`)}}await this.processManager.spawn({memberId:s,name:`product-${t.name}`,cwd:i,prompt:r.prompt,external:o});let a=await this.processManager.sendTask(s,r.prompt),c=typeof a=="string"?a:JSON.stringify(a),l=this.processManager.getUsageTracker(s);if(l?.hasData()){let d=l.getUsage();e.budget.addUsage(d.inputTokens,d.outputTokens);let u=e.budget.getBudget();this.callbacks.onBudgetUpdate?.(e.productId,u.usedTokens,0,u.elapsed,u.maxTotalTokens)}e.dag.markCompleted(r.taskId,c),t.state="completed",this.callbacks.onTaskCompleted?.(e.productId,r.taskId,c);try{this.processManager.kill(s)}catch{}this.processManager.remove(s)}catch(o){let i=o instanceof Error?o.message:String(o);e.dag.markFailed(r.taskId,i),t.state="failed",this.callbacks.onTaskFailed?.(e.productId,r.taskId,i);try{this.processManager.kill(s)}catch{}try{this.processManager.remove(s)}catch{}}try{await e.checkpoint.checkpoint(this.buildPersistedState(e))}catch(o){this.callbacks.log?.warn(`[product] checkpoint failed: ${o instanceof Error?o.message:String(o)}`)}this.scheduleNext(e)}finishProduct(e){if(e.dag.isAllCompleted()){e.phase="completed";let t=e.dag.getAllTasks(),r=`Product "${e.name}" completed: ${t.length} tasks all done.`;this.callbacks.onCompleted?.(e.productId,r)}else{e.phase="failed";let r=e.dag.getAllTasks().filter(i=>i.status==="failed").length,s=e.dag.getBlockedTasks().length,o=`Product "${e.name}" finished with ${r} failed, ${s} blocked tasks.`;this.callbacks.onCompleted?.(e.productId,o)}e.checkpoint.stop(),e.checkpoint.checkpoint(this.buildPersistedState(e)).catch(t=>{this.callbacks.log?.warn(`[product] final checkpoint failed: ${t instanceof Error?t.message:String(t)}`)}),this.callbacks.log?.info(`[product] ${e.productId} finished (phase=${e.phase})`)}buildPersistedState(e){return{productId:e.productId,name:e.name,phase:e.phase,cwd:e.cwd,instances:e.instances.map(t=>({name:t.name,role:"",agentId:t.agentId})),tasks:e.dag.serialize(),budget:e.budget.serialize(),createdAt:e.createdAt,lastCheckpointAt:new Date(e.checkpoint.getLastCheckpointAt()||Date.now()).toISOString()}}};import{randomUUID as Lf}from"node:crypto";function m_(n,e){let t=e?`
|
|
869
869
|
|
|
870
870
|
Budget constraints: ${e.maxTotalTokens?`max ${e.maxTotalTokens} total tokens`:""}${e.maxDuration?` / max ${Math.round(e.maxDuration/6e4)} minutes`:""}`:"";return`You are a team leader agent managing a software development project.
|
|
871
871
|
|
|
@@ -901,7 +901,7 @@ Start by greeting the user and asking your first clarifying question about the p
|
|
|
901
901
|
|
|
902
902
|
[user]: ${e}
|
|
903
903
|
|
|
904
|
-
Continue the planning conversation. If you have enough information, output the final structured plan in a \`\`\`json code block. Otherwise, ask your next clarifying question.`}function
|
|
904
|
+
Continue the planning conversation. If you have enough information, output the final structured plan in a \`\`\`json code block. Otherwise, ask your next clarifying question.`}function $f(n){let e=`You are the team leader agent in EXECUTION phase.
|
|
905
905
|
|
|
906
906
|
## Current Progress
|
|
907
907
|
- Total tasks: ${n.progress.total}
|
|
@@ -928,13 +928,13 @@ To mutate the DAG, output a \`\`\`json block with an array of mutations:
|
|
|
928
928
|
{"type": "update_prompt", "taskId": "...", "prompt": "..."}
|
|
929
929
|
]
|
|
930
930
|
|
|
931
|
-
If no action needed, just respond with a progress update message to the user.`,e}var go=class{constructor(e,t,r,s={}){this.processManager=e;this.acpDetector=t;this.configStore=r;this.callbacks=s}processManager;acpDetector;configStore;callbacks;sessions=new Map;async plan(e){let{goal:t,cwd:r,leaderAgentId:s,name:o,budget:i}=e,a=`product-${
|
|
931
|
+
If no action needed, just respond with a progress update message to the user.`,e}var go=class{constructor(e,t,r,s={}){this.processManager=e;this.acpDetector=t;this.configStore=r;this.callbacks=s}processManager;acpDetector;configStore;callbacks;sessions=new Map;async plan(e){let{goal:t,cwd:r,leaderAgentId:s,name:o,budget:i}=e,a=`product-${Lf().slice(0,8)}`,c={productId:a,goal:t,cwd:r,leaderAgentId:s,phase:"planning",dialogue:[],budget:i,createdAt:new Date().toISOString()};this.sessions.set(a,c),this.callbacks.log?.info(`[planner] started planning ${a} with leader=${s}`);let l=await this.sendToLeader(c,m_(t,i));c.dialogue.push({role:"leader",content:l,timestamp:new Date().toISOString()});let d=this.tryParsePlan(l,c);if(d)return c.plan=d,c.phase="awaiting_confirmation",o&&(d.name=o),this.callbacks.onPlanReady?.(a,d),{productId:a,plan:d};this.callbacks.onLeaderMessage?.(a,l),this.callbacks.onPlanningDelta?.(a,l);let u={name:o??t.slice(0,50),modules:[],instances:[],tasks:[],reasoning:"Planning in progress \u2014 leader is asking clarifying questions. Use product.message to respond."};return{productId:a,plan:u}}async message(e,t){let r=this.sessions.get(e);if(!r)throw new Error(`Session ${e} not found`);if(r.dialogue.push({role:"user",content:t,timestamp:new Date().toISOString()}),r.phase==="planning")return this.handlePlanningMessage(r,t);if(r.phase==="executing"||r.phase==="paused")return this.handleExecutionMessage(r,t);if(r.phase==="awaiting_confirmation")return this.handlePlanningMessage(r,t);throw new Error(`Cannot message in phase "${r.phase}"`)}async confirm(e){let t=this.sessions.get(e.productId);if(!t)throw new Error(`Planning session ${e.productId} not found`);if(t.phase!=="awaiting_confirmation")throw new Error(`Session ${e.productId} is in phase "${t.phase}", not "awaiting_confirmation"`);return t.phase="confirmed",t.lastCheckpoint=new Date().toISOString(),this.callbacks.log?.info(`[planner] confirmed ${e.productId}: ${e.instances.length} instances, ${e.tasks.length} tasks`),{productId:e.productId,ok:!0}}markExecuting(e){let t=this.sessions.get(e);t&&(t.phase="executing",t.lastCheckpoint=new Date().toISOString())}markCompleted(e){let t=this.sessions.get(e);t&&(t.phase="completed")}getSession(e){return this.sessions.get(e)}async cancel(e){let t=this.sessions.get(e);if(t){if(t.phase="cancelled",t.leaderMemberId)try{await this.processManager.kill(t.leaderMemberId)}catch{}this.sessions.delete(e)}}listSessions(){return[...this.sessions.values()]}async consultLeader(e,t){let r=this.sessions.get(e);if(!r)return[];let s=$f(t),o=await this.sendToLeader(r,s);return r.dialogue.push({role:"leader",content:o,timestamp:new Date().toISOString()}),this.parseDagMutations(o)}serializeSession(e){return this.sessions.get(e)??null}restoreSession(e){this.sessions.set(e.productId,e),e.leaderMemberId=void 0}async handlePlanningMessage(e,t){let r=g_(e.dialogue.slice(0,-1),t),s=await this.sendToLeader(e,r);e.dialogue.push({role:"leader",content:s,timestamp:new Date().toISOString()});let o=this.tryParsePlan(s,e);return o?(e.plan=o,e.phase="awaiting_confirmation",this.callbacks.onPlanReady?.(e.productId,o),{response:s,plan:o}):(this.callbacks.onLeaderMessage?.(e.productId,s),{response:s})}async handleExecutionMessage(e,t){let r=$f({progress:{total:0,completed:0,running:0,failed:0},userMessage:t}),s=await this.sendToLeader(e,r);e.dialogue.push({role:"leader",content:s,timestamp:new Date().toISOString()});let o=this.parseDagMutations(s);for(let i of o)this.callbacks.onDagMutated?.(e.productId,i);return{response:s,mutations:o.length>0?o:void 0}}async sendToLeader(e,t){if(!e.leaderMemberId){let s=`${e.productId}:leader`,o=this.acpDetector.buildExternalDescriptor(e.leaderAgentId);if(!o)throw new Error(`Leader agent ${e.leaderAgentId} is not available`);await this.processManager.spawn({memberId:s,name:"product-leader",cwd:e.cwd,prompt:t,external:o}),e.leaderMemberId=s}let r=await this.processManager.sendTask(e.leaderMemberId,t);return typeof r=="string"?r:JSON.stringify(r)}tryParsePlan(e,t){let r=e.match(/```(?:json)?\s*\n([\s\S]*?)\n```/);if(!r)return null;try{let s=JSON.parse(r[1]);return!s.name||!Array.isArray(s.tasks)||s.tasks.length===0?null:{name:s.name,modules:(s.modules??[]).map(o=>({name:String(o.name??""),description:String(o.description??""),suggestedAgentId:o.suggestedAgentId?String(o.suggestedAgentId):void 0})),instances:(s.instances??[]).map(o=>({name:String(o.name??""),agentId:String(o.agentId??t.leaderAgentId),role:String(o.role??o.description??"")})),tasks:s.tasks.map(o=>({taskId:String(o.taskId??`task-${Lf().slice(0,6)}`),assignee:String(o.assignee??""),prompt:String(o.description??o.prompt??""),dependsOn:Array.isArray(o.dependsOn)?o.dependsOn.map(String):void 0})),reasoning:String(s.reasoning??"")}}catch{return null}}parseDagMutations(e){let t=e.match(/```(?:json)?\s*\n([\s\S]*?)\n```/);if(!t)return[];try{let r=JSON.parse(t[1]);return Array.isArray(r)?r.filter(s=>s.type).map(s=>({type:String(s.type),taskId:String(s.taskId??s.task?.taskId??""),details:s})):[]}catch{return[]}}};function De(){if(!this.productOrchestrator){let n=new _t({log:{info:t=>process.stderr.write(`[product:pm] ${t}
|
|
932
932
|
`),warn:t=>process.stderr.write(`[product:pm] WARN ${t}
|
|
933
933
|
`)},onNotification:(t,r,s)=>{(r==="agents.error"||r==="agents.status")&&this.sendNotification(r,s),this.sendNotification("team.member.notification",{memberId:t,method:r,params:s})},onStateChange:(t,r)=>{let s=n.getHandle(t),i=n.getUsageTracker(t)?.getUsage();this.emitAgentStatus(t,r,{missedBeats:n.getMissedBeats(t),lastActivityAt:s?.lastActivityAt,usage:i&&i.totalTokens>0?{inputTokens:i.inputTokens,outputTokens:i.outputTokens,totalTokens:i.totalTokens}:void 0})},onMcpToolCall:(t,r,s)=>this.handleMcpToolCall(t,r,s),sessionDir:path.join(getUserAgentHome(),"agent-logs")}),e={log:{info:t=>process.stderr.write(`${t}
|
|
934
934
|
`),warn:t=>process.stderr.write(`${t}
|
|
935
935
|
`)},onTaskStarted:(t,r,s)=>{this.sendNotification("product.taskStarted",{productId:t,taskId:r,assignee:s})},onTaskCompleted:(t,r,s)=>{this.sendNotification("product.taskCompleted",{productId:t,taskId:r,result:s})},onTaskFailed:(t,r,s)=>{this.sendNotification("product.taskFailed",{productId:t,taskId:r,error:s})},onCheckpointed:(t,r)=>{this.sendNotification("product.checkpointed",{productId:t,timestamp:r})},onBudgetWarning:(t,r,s,o)=>{this.sendNotification("product.budgetWarning",{productId:t,usedTokens:r,maxTotalTokens:s,percentage:o})},onCompleted:(t,r)=>{this.sendNotification("product.completed",{productId:t,summary:r})},onDagTopology:(t,r,s)=>{this.sendNotification("product.dagTopology",{productId:t,nodes:r,edges:s})},onBudgetUpdate:(t,r,s,o,i)=>{this.sendNotification("product.budgetUpdate",{productId:t,inputTokens:r,outputTokens:s,elapsed:o,maxTotalTokens:i})},onTaskOutputDelta:(t,r,s)=>{this.sendNotification("product.taskOutput",{productId:t,taskId:r,text:s})}};this.productOrchestrator=new mo(n,this.acpDetector,this.agentConfigStore,e),this.productProcessManager=n}return this.productOrchestrator}function hn(){if(!this.productPlanner){let n=De.call(this);this.productPlanner=new go(this.productProcessManager,this.acpDetector,this.agentConfigStore,{log:{info:e=>process.stderr.write(`${e}
|
|
936
936
|
`),warn:e=>process.stderr.write(`${e}
|
|
937
|
-
`)},onPlanReady:(e,t)=>{this.sendNotification("product.planReady",{productId:e,plan:t})},onPlanFailed:(e,t)=>{this.sendNotification("product.planFailed",{productId:e,error:t})},onPlanningDelta:(e,t)=>{this.sendNotification("product.planningDelta",{productId:e,text:t})}})}return this.productPlanner}async function $f(n){try{let e=n.params;if(!e?.goal||!e?.cwd||!e?.leaderAgentId){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:AGENT_RPC_ERROR_CODES.INVALID_PARAMS,message:"goal, cwd, and leaderAgentId are required."});return}let r=await hn.call(this).plan(e);n.id!==void 0&&this.sendResponse(n.id,r)}catch(e){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:AGENT_RPC_ERROR_CODES.INTERNAL_ERROR,message:e instanceof Error?e.message:String(e)})}}async function jf(n){try{let e=n.params;if(!e?.productId||!e?.instances||!e?.tasks){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:AGENT_RPC_ERROR_CODES.INVALID_PARAMS,message:"productId, instances, and tasks are required."});return}let t=hn.call(this),r=await t.confirm(e),s=t.getSession(e.productId);s&&await De.call(this).create({name:s.plan?.name??s.goal.slice(0,50),cwd:s.cwd,instances:e.instances,tasks:e.tasks,budget:e.budget}),n.id!==void 0&&this.sendResponse(n.id,r)}catch(e){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:AGENT_RPC_ERROR_CODES.INTERNAL_ERROR,message:e instanceof Error?e.message:String(e)})}}async function Uf(n){try{let e=n.params;if(!e?.productId||!e?.content){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:AGENT_RPC_ERROR_CODES.INVALID_PARAMS,message:"productId and content are required."});return}let r=await hn.call(this).message(e.productId,e.content);n.id!==void 0&&this.sendResponse(n.id,r)}catch(e){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:AGENT_RPC_ERROR_CODES.INTERNAL_ERROR,message:e instanceof Error?e.message:String(e)})}}async function Ff(n){try{let e=n.params,t;if(e?.name&&e?.cwd&&e?.instances&&e?.tasks)t=e;else if(e?.tasks&&Array.isArray(e.tasks)){let i=e.config?.workdir??this.getActiveProjectRoot(),a=e.tasks.map(c=>({taskId:String(c.id??c.taskId??`task_${Math.random().toString(36).slice(2,8)}`),assignee:String(c.assignee??"default"),prompt:String(c.description??c.prompt??""),dependsOn:c.dependsOn??[]}));t={name:String(e.name??`product_${Date.now()}`),cwd:i,instances:[{name:"default",role:"executor",agentId:"self"}],tasks:a},e.budget&&(t.budget=e.budget)}else{n.id!==void 0&&this.sendResponse(n.id,void 0,{code:AGENT_RPC_ERROR_CODES.INVALID_PARAMS,message:"tasks is required. Provide either {name, cwd, instances, tasks} or simplified {tasks, config}."});return}if(!t.projectId){let o=Oe();o&&(t.projectId=o.id)}let s=await De.call(this).create(t);n.id!==void 0&&this.sendResponse(n.id,{productId:s})}catch(e){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:AGENT_RPC_ERROR_CODES.INTERNAL_ERROR,message:e instanceof Error?e.message:String(e)})}}async function Bf(n){try{let e=n.params;if(!e?.productId){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:AGENT_RPC_ERROR_CODES.INVALID_PARAMS,message:"productId is required."});return}await De.call(this).resume(e.productId,this.getActiveProjectRoot()),n.id!==void 0&&this.sendResponse(n.id,{ok:!0})}catch(e){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:AGENT_RPC_ERROR_CODES.INTERNAL_ERROR,message:e instanceof Error?e.message:String(e)})}}async function Hf(n){try{let e=n.params;if(!e?.productId){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:AGENT_RPC_ERROR_CODES.INVALID_PARAMS,message:"productId is required."});return}await De.call(this).pause(e.productId),n.id!==void 0&&this.sendResponse(n.id,{ok:!0})}catch(e){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:AGENT_RPC_ERROR_CODES.INTERNAL_ERROR,message:e instanceof Error?e.message:String(e)})}}async function qf(n){try{let e=n.params;if(!e?.productId){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:AGENT_RPC_ERROR_CODES.INVALID_PARAMS,message:"productId is required."});return}await De.call(this).checkpoint(e.productId),n.id!==void 0&&this.sendResponse(n.id,{ok:!0})}catch(e){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:AGENT_RPC_ERROR_CODES.INTERNAL_ERROR,message:e instanceof Error?e.message:String(e)})}}async function Wf(n){try{let e=n.params;if(!e?.productId){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:AGENT_RPC_ERROR_CODES.INVALID_PARAMS,message:"productId is required."});return}let r=De.call(this).getStatus(e.productId);n.id!==void 0&&this.sendResponse(n.id,r)}catch(e){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:AGENT_RPC_ERROR_CODES.INTERNAL_ERROR,message:e instanceof Error?e.message:String(e)})}}async function Gf(n){try{let t=await De.call(this).list(this.getActiveProjectRoot());n.id!==void 0&&this.sendResponse(n.id,t)}catch(e){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:AGENT_RPC_ERROR_CODES.INTERNAL_ERROR,message:e instanceof Error?e.message:String(e)})}}async function Kf(n){try{let e=n.params;if(!e?.productId){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:AGENT_RPC_ERROR_CODES.INVALID_PARAMS,message:"productId is required."});return}await De.call(this).delete(e.productId),n.id!==void 0&&this.sendResponse(n.id,{ok:!0})}catch(e){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:AGENT_RPC_ERROR_CODES.INTERNAL_ERROR,message:e instanceof Error?e.message:String(e)})}}async function Vf(n){try{let e=n.params;if(!e?.productId){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:AGENT_RPC_ERROR_CODES.INVALID_PARAMS,message:"productId is required."});return}await De.call(this).delete(e.productId),n.id!==void 0&&this.sendResponse(n.id,{ok:!0})}catch(e){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:AGENT_RPC_ERROR_CODES.INTERNAL_ERROR,message:e instanceof Error?e.message:String(e)})}}async function zf(n){try{let e=n.params;if(!e?.productId){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:AGENT_RPC_ERROR_CODES.INVALID_PARAMS,message:"productId is required."});return}await De.call(this).rollback(e.productId,e.checkpoint??"latest"),n.id!==void 0&&this.sendResponse(n.id,{ok:!0})}catch(e){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:AGENT_RPC_ERROR_CODES.INTERNAL_ERROR,message:e instanceof Error?e.message:String(e)})}}import{randomUUID as rl}from"node:crypto";import*as Xe from"node:fs";import*as yn from"node:path";ae();var _e=new On;function Xf(n){let e=n.params,t=e?.id??rl();this.log(`[thread.create] id=${t} title=${e?.title??"(none)"}`),e?.cwd&&typeof e.cwd=="string"&&this.setActiveWorkdir(e.cwd),this.currentSessionId=t,this.sessionState=new zt(t),this.sessionTaskDomain=void 0,this.memoryPrefetchState=Lt(),this.enableIdleDream(),n.id!==void 0&&this.sendResponse(n.id,{id:t,title:e?.title,status:"active",createdAt:new Date().toISOString()})}async function Yf(n){let e=n.params,t=e?.limit??20;try{let r=e?.projectId??_e.getActiveProjectId(),s=_e.getProjectWorkspaceDir(r),i=(await At(t,s)).map(a=>({id:a.sessionId,title:a.title,status:"active",turnCount:a.messageCount,createdAt:a.createdAt,lastActiveAt:a.lastActiveAt}));n.id!==void 0&&this.sendResponse(n.id,{threads:i})}catch(r){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:`Failed to list threads: ${r.message}`})}}async function Jf(n){let e=n.params,t=e?.sessionId??rl();try{let r=e?.projectId??_e.getActiveProjectId(),s=_e.getProjectWorkspaceDir(r);await et(t,{sessionId:t,title:e?.title,type:e?.type,ownerId:e?.ownerId,groupKey:e?.groupKey,groupName:e?.groupName,groupPlatform:e?.groupPlatform,projectId:r},s),n.id!==void 0&&this.sendResponse(n.id,{sessionId:t,title:e?.title})}catch(r){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:`Failed to create session: ${r.message}`})}}async function Qf(n){let e=n.params;if(n.id===void 0)return;let t=e?.platform??"desktop",r=e?.chatId,s=e?.chatType,o=e?.userId??"local";try{if(t==="desktop"&&r){let d=e?.projectId??_e.getActiveProjectId(),u=_e.getProjectWorkspaceDir(d),m=(await At(500,u)).find(h=>h.sessionId===r);if(m){this.sendResponse(n.id,{sessionId:r,title:m.title,type:m.type??"personal",ownerId:o,projectId:d});return}await et(r,{sessionId:r,type:"personal",ownerId:o,projectId:d},u),this.sendResponse(n.id,{sessionId:r,type:"personal",ownerId:o,projectId:d});return}if(s==="group"&&r&&t){let d=`group:${t}:${r}`,u=me();for(let p of u){if(!p.workspaceDir)continue;let h=(await At(500,p.workspaceDir)).find(f=>f.groupKey===d&&!f.sealedAt);if(h){let f=cn(h.sessionId,p.workspaceDir);if(f){let y=await vf(f,p.workspaceDir);if(y.split){this.sendResponse(n.id,{sessionId:y.activeSessionId,title:void 0,type:"group",ownerId:o,groupKey:d,groupPlatform:t,groupName:e?.groupName,projectId:p.id,previousSessionId:y.sealedSessionId});return}}this.sendResponse(n.id,{sessionId:h.sessionId,title:h.title,type:"group",ownerId:o,groupKey:d,groupPlatform:t,groupName:e?.groupName,projectId:p.id});return}}}let i=rl(),a=_e.getActiveProjectId(),c=_e.getProjectWorkspaceDir(a),l=s==="group"?`group:${t}:${r}`:void 0;await et(i,{sessionId:i,type:s==="group"?"group":"personal",ownerId:o,groupKey:l,groupPlatform:s==="group"?t:void 0,groupName:e?.groupName,projectId:a},c),this.sendResponse(n.id,{sessionId:i,type:s==="group"?"group":"personal",ownerId:o,groupKey:l,groupPlatform:s==="group"?t:void 0,groupName:e?.groupName,projectId:a})}catch(i){this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:`Failed to resolve session: ${i.message}`})}}async function Zf(n){let e=n.params,t=e?.limit??50;try{let r;if(e?.projectId){let o=ct(e.projectId);if(!o){n.id!==void 0&&this.sendResponse(n.id,{sessions:[]});return}let i=o.workspaceDir;r=await At(t*2,i),r=r.filter(a=>a.projectId===e.projectId);for(let a of r)a.projectId=e.projectId}else{let o=me(),i=new Set,a=[];for(let c of o){if(!c.workspaceDir)continue;let l=await At(t,c.workspaceDir);for(let d of l)i.has(d.sessionId)||d.projectId&&(i.add(d.sessionId),a.push(d))}a.sort((c,l)=>c.lastActiveAt>l.lastActiveAt?-1:c.lastActiveAt<l.lastActiveAt?1:0),r=a}e?.archived===!0?r=r.filter(o=>o.archivedAt!=null):e?.archived===!1&&(r=r.filter(o=>o.archivedAt==null));let s=r.slice(0,t).map(o=>({sessionId:o.sessionId,title:o.title,type:o.type,lastActiveAt:o.lastActiveAt,pinnedAt:o.pinnedAt??null,archivedAt:o.archivedAt??null,sealedAt:o.sealedAt??null,projectId:o.projectId,previousSessionId:o.previousSessionId??null,carryoverSummary:o.carryoverSummary??null}));n.id!==void 0&&this.sendResponse(n.id,{sessions:s})}catch(r){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:`Failed to list sessions: ${r.message}`})}}async function eh(n){let e=n.params;if(!e?.sessionId){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:"Missing required param: sessionId"});return}try{let t=_e.resolveWorkspaceDir(e.sessionId,e.projectId),s=(await At(500,t)).find(o=>o.sessionId===e.sessionId);n.id!==void 0&&this.sendResponse(n.id,{session:s?{sessionId:s.sessionId,title:s.title,type:s.type,lastActiveAt:s.lastActiveAt,pinnedAt:s.pinnedAt??null,archivedAt:s.archivedAt??null,projectId:s.projectId}:null})}catch(t){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:`Failed to get session: ${t.message}`})}}async function th(n){let e=n.params;if(!e?.sessionId){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:"Missing required param: sessionId"});return}try{let t=_e.resolveWorkspaceDir(e.sessionId,e.projectId),r=await Ta(e.sessionId,t);if(!r){n.id!==void 0&&this.sendResponse(n.id,{messages:[],total:0});return}let s=r.messages,o=e.limit&&e.limit>0?e.limit:s.length,i=s.slice(-o);n.id!==void 0&&this.sendResponse(n.id,{messages:i,total:s.length})}catch(t){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:`Failed to get messages: ${t.message}`})}}async function nh(n){let e=n.params;if(!e?.sessionId){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:"Missing required param: sessionId"});return}try{let t=_e.resolveWorkspaceDir(e.sessionId,e.projectId),r=await et(e.sessionId,{...e.title!==void 0?{title:e.title}:{},...e.pinnedAt!==void 0?{pinnedAt:e.pinnedAt}:{},...e.archivedAt!==void 0?{archivedAt:e.archivedAt}:{}},t);r&&this.sendNotification("session.info",{sessionId:e.sessionId,title:r.title,pinnedAt:r.pinnedAt??null,archivedAt:r.archivedAt??null,projectId:e.projectId||void 0}),n.id!==void 0&&this.sendResponse(n.id,{ok:r!==null})}catch(t){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:`Failed to update session: ${t.message}`})}}async function rh(n){let e=n.params;if(!e?.sessionId){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:"Missing required param: sessionId"});return}try{let t=_e.resolveWorkspaceDir(e.sessionId,e.projectId);await Ra(e.sessionId,t),n.id!==void 0&&this.sendResponse(n.id,{ok:!0})}catch(t){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:`Failed to delete session: ${t.message}`})}}async function sh(n){let e=n.params;if(!e?.projectId){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:"Missing required param: projectId"});return}try{let t=_e.getProjectWorkspaceDir(e.projectId),r=await At(1e4,t),s=0;for(let o of r)await Ra(o.sessionId,t),s++;n.id!==void 0&&this.sendResponse(n.id,{ok:!0,deletedCount:s})}catch(t){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:`Failed to delete all sessions: ${t.message}`})}}async function oh(n){let e=n.params;if(!e?.sessionId){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:"Missing required param: sessionId"});return}try{let t=_e.resolveWorkspaceDir(e.sessionId,e.projectId);await et(e.sessionId,{archivedAt:new Date().toISOString()},t),n.id!==void 0&&this.sendResponse(n.id,{ok:!0})}catch(t){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:`Failed to archive session: ${t.message}`})}}async function ih(n){let e=n.params,t=e?.sessionId;if(!t){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:"sessionId is required"});return}try{let r=_e.resolveWorkspaceDir(t,e?.projectId),s=await Ta(t,r);if(!s){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:`Session not found: ${t}`});return}s.messages&&s.messages.length>0&&this.resumedSessionHistory.set(t,s.messages),n.id!==void 0&&this.sendResponse(n.id,{metadata:s.metadata,messages:s.messages})}catch(r){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:`Failed to resume session: ${r.message}`})}}function ah(n){let e=this.currentSessionId||"default",t=this.sessionState?.createSnapshot(),r,s=this.getActiveProjectRoot();s&&(r=yn.join(Ot(s),e));let o={sessionId:e,model:this.currentModel||void 0,cwd:process.cwd(),paths:{sessionDir:r,agentHome:q(),settings:it()},usage:t?{turnCount:t.turnCount,inputTokens:t.totalInputTokens,outputTokens:t.totalOutputTokens}:void 0};n.id!==void 0&&this.sendResponse(n.id,o)}function ch(n){let e=n.params,t=null;if(e?.projectId)t=ct(e.projectId);else if(e?.projectName){let o=me(),i=e.projectName.toLowerCase();if(t=o.find(a=>a.name.toLowerCase()===i)??null,t||(t=o.find(a=>a.name.toLowerCase().includes(i))??null),!t){let a=o.map(c=>c.name).slice(0,10);n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:`No project matching "${e.projectName}". Available: ${a.join(", ")||"(none)"}`});return}}else{n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:"Missing required param: projectId or projectName"});return}if(!t||t.status!=="active"){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:`Project not found or archived: ${e.projectId??e.projectName}`});return}let r=e.workspaceDir??t.workspaceDir;if(!Xe.existsSync(r)){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:`Workspace directory does not exist: ${r}`});return}let s=ut(t.id);if(!s){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:"Switch failed"});return}this.setActiveWorkdir(s.workspaceDir),this.sendNotification("project.switched",{id:s.id,name:s.name,workspaceDir:s.workspaceDir}),n.id!==void 0&&this.sendResponse(n.id,{ok:!0,project:s})}function lh(n){let e=Oe(),t=me();n.id!==void 0&&this.sendResponse(n.id,{sessionId:this.currentSessionId,activeProject:e,projects:t})}async function dh(n){let e=n.params,t=e?.sessionId;if(!t){n.id!==void 0&&this.sendResponse(n.id,{ok:!1});return}let r=me();for(let s of r)try{let o=_e.getProjectWorkspaceDir(s.id),i=await cn(t,o);if(i&&i.projectId===s.id){ut(s.id),this.setActiveWorkdir(o),this.log(`[session.focus] switched to project ${s.id} for session ${t}`),n.id!==void 0&&this.sendResponse(n.id,{ok:!0,projectId:s.id});return}}catch{}if(e?.projectName){let s=r.find(o=>o.name===e.projectName);if(s){let o=_e.getProjectWorkspaceDir(s.id);this.getActiveProjectRoot()!==o&&(this.setActiveWorkdir(o),this.log(`[session.focus] switched to project ${s.id} by name "${e.projectName}"`)),n.id!==void 0&&this.sendResponse(n.id,{ok:!0,projectId:s.id});return}}n.id!==void 0&&this.sendResponse(n.id,{ok:!1})}async function uh(n){let e=n.params,{sessionId:t,fromProjectId:r,toProjectId:s}=e??{};if(!t||!r||!s){n.id!==void 0&&this.sendError(n.id,v.INVALID_PARAMS,"sessionId, fromProjectId, and toProjectId are required");return}if(r===s){n.id!==void 0&&this.sendResponse(n.id,{ok:!0});return}let o=ct(r),i=ct(s);if(!o||!i){n.id!==void 0&&this.sendError(n.id,v.INVALID_PARAMS,"Source or target project not found");return}let a=yn.join(_e.getProjectWorkspaceDir(r),".qlogicagent","sessions",t),c=yn.join(_e.getProjectWorkspaceDir(s),".qlogicagent","sessions",t);if(!Xe.existsSync(a)){n.id!==void 0&&this.sendError(n.id,v.INVALID_PARAMS,`Session ${t} not found in project ${r}`);return}try{Xe.mkdirSync(yn.dirname(c),{recursive:!0}),Xe.cpSync(a,c,{recursive:!0});let l=yn.join(c,"metadata.json");if(Xe.existsSync(l)){let d=JSON.parse(Xe.readFileSync(l,"utf-8"));d.projectId=s,Xe.writeFileSync(l,JSON.stringify(d,null,2))}Xe.rmSync(a,{recursive:!0,force:!0}),this.sendNotification("session-update",{sessionId:t,projectId:s}),this.log(`[session.moveToProject] moved ${t}: ${r} \u2192 ${s}`),n.id!==void 0&&this.sendResponse(n.id,{ok:!0,projectId:s})}catch(l){this.log(`[session.moveToProject] error: ${l.message}`),n.id!==void 0&&this.sendError(n.id,v.INTERNAL_ERROR,`Move failed: ${l.message}`)}}import*as hh from"node:path";import{randomUUID as b_}from"node:crypto";import{join as sl}from"node:path";import{mkdir as f_,readdir as h_}from"node:fs/promises";ae();function ph(n){return sl(Me(n),"solos")}function ol(n,e){return sl(ph(e),n)}function mh(n,e){return sl(ol(n,e),"solo-state.json")}async function gh(n,e){let t=ol(n.soloId,e);await f_(t,{recursive:!0}),await Nn(mh(n.soloId,e),n)}async function y_(n,e){return mn(mh(n,e))}async function fh(n){let e=ph(n),t;try{t=await h_(e)}catch{return[]}let r=[];for(let s of t){let o=await y_(s,n);o&&r.push(o)}return r}async function il(n,e){let{rm:t}=await import("node:fs/promises"),r=ol(n,e);try{return await t(r,{recursive:!0,force:!0}),!0}catch{return!1}}var fo=class{constructor(e,t,r,s={}){this.processManager=e;this.acpDetector=t;this.configStore=r;this.callbacks=s}processManager;acpDetector;configStore;callbacks;sessions=new Map;persistSession(e){let t={soloId:e.soloId,state:e.state,task:e.task,cwd:e.cwd,gitRoot:e.gitRoot,agents:e.agents.map(r=>({agentId:r.agentId,memberId:r.memberId,worktreePath:r.worktreePath,worktreeBranch:r.worktreeBranch,state:r.state,resultText:r.resultText,diff:r.diff,usage:r.usage,error:r.error,turns:r.turns})),evaluation:e.evaluation,createdAt:e.createdAt};gh(t,e.cwd).catch(()=>{})}async restoreFromDisk(e){let t=await fh(e);for(let r of t)this.sessions.has(r.soloId)||this.sessions.set(r.soloId,{soloId:r.soloId,state:r.state,task:r.task,cwd:r.cwd,gitRoot:r.gitRoot,agents:r.agents.map(s=>({...s,turns:s.turns??[]})),evaluation:r.evaluation,createdAt:r.createdAt});return t.length}async deleteSolo(e){return this.sessions.delete(e),il(e)}async start(e){let{task:t,agents:r,cwd:s,sharedConfig:o}=e;if(r.length<2)throw new Error("Solo Mode requires at least 2 agents");let i=await $r(s);if(!i)throw new Error("Solo Mode requires a git repository");let a=t;if(o){let p=[];o.rules?.length&&p.push(`<rules>
|
|
937
|
+
`)},onPlanReady:(e,t)=>{this.sendNotification("product.planReady",{productId:e,plan:t})},onPlanFailed:(e,t)=>{this.sendNotification("product.planFailed",{productId:e,error:t})},onPlanningDelta:(e,t)=>{this.sendNotification("product.planningDelta",{productId:e,text:t})}})}return this.productPlanner}async function jf(n){try{let e=n.params;if(!e?.goal||!e?.cwd||!e?.leaderAgentId){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:AGENT_RPC_ERROR_CODES.INVALID_PARAMS,message:"goal, cwd, and leaderAgentId are required."});return}let r=await hn.call(this).plan(e);n.id!==void 0&&this.sendResponse(n.id,r)}catch(e){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:AGENT_RPC_ERROR_CODES.INTERNAL_ERROR,message:e instanceof Error?e.message:String(e)})}}async function Uf(n){try{let e=n.params;if(!e?.productId||!e?.instances||!e?.tasks){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:AGENT_RPC_ERROR_CODES.INVALID_PARAMS,message:"productId, instances, and tasks are required."});return}let t=hn.call(this),r=await t.confirm(e),s=t.getSession(e.productId);s&&await De.call(this).create({name:s.plan?.name??s.goal.slice(0,50),cwd:s.cwd,instances:e.instances,tasks:e.tasks,budget:e.budget}),n.id!==void 0&&this.sendResponse(n.id,r)}catch(e){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:AGENT_RPC_ERROR_CODES.INTERNAL_ERROR,message:e instanceof Error?e.message:String(e)})}}async function Ff(n){try{let e=n.params;if(!e?.productId||!e?.content){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:AGENT_RPC_ERROR_CODES.INVALID_PARAMS,message:"productId and content are required."});return}let r=await hn.call(this).message(e.productId,e.content);n.id!==void 0&&this.sendResponse(n.id,r)}catch(e){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:AGENT_RPC_ERROR_CODES.INTERNAL_ERROR,message:e instanceof Error?e.message:String(e)})}}async function Bf(n){try{let e=n.params,t;if(e?.name&&e?.cwd&&e?.instances&&e?.tasks)t=e;else if(e?.tasks&&Array.isArray(e.tasks)){let i=e.config?.workdir??this.getActiveProjectRoot(),a=e.tasks.map(c=>({taskId:String(c.id??c.taskId??`task_${Math.random().toString(36).slice(2,8)}`),assignee:String(c.assignee??"default"),prompt:String(c.description??c.prompt??""),dependsOn:c.dependsOn??[]}));t={name:String(e.name??`product_${Date.now()}`),cwd:i,instances:[{name:"default",role:"executor",agentId:"self"}],tasks:a},e.budget&&(t.budget=e.budget)}else{n.id!==void 0&&this.sendResponse(n.id,void 0,{code:AGENT_RPC_ERROR_CODES.INVALID_PARAMS,message:"tasks is required. Provide either {name, cwd, instances, tasks} or simplified {tasks, config}."});return}if(!t.projectId){let o=Oe();o&&(t.projectId=o.id)}let s=await De.call(this).create(t);n.id!==void 0&&this.sendResponse(n.id,{productId:s})}catch(e){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:AGENT_RPC_ERROR_CODES.INTERNAL_ERROR,message:e instanceof Error?e.message:String(e)})}}async function Hf(n){try{let e=n.params;if(!e?.productId){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:AGENT_RPC_ERROR_CODES.INVALID_PARAMS,message:"productId is required."});return}await De.call(this).resume(e.productId,this.getActiveProjectRoot()),n.id!==void 0&&this.sendResponse(n.id,{ok:!0})}catch(e){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:AGENT_RPC_ERROR_CODES.INTERNAL_ERROR,message:e instanceof Error?e.message:String(e)})}}async function qf(n){try{let e=n.params;if(!e?.productId){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:AGENT_RPC_ERROR_CODES.INVALID_PARAMS,message:"productId is required."});return}await De.call(this).pause(e.productId),n.id!==void 0&&this.sendResponse(n.id,{ok:!0})}catch(e){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:AGENT_RPC_ERROR_CODES.INTERNAL_ERROR,message:e instanceof Error?e.message:String(e)})}}async function Wf(n){try{let e=n.params;if(!e?.productId){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:AGENT_RPC_ERROR_CODES.INVALID_PARAMS,message:"productId is required."});return}await De.call(this).checkpoint(e.productId),n.id!==void 0&&this.sendResponse(n.id,{ok:!0})}catch(e){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:AGENT_RPC_ERROR_CODES.INTERNAL_ERROR,message:e instanceof Error?e.message:String(e)})}}async function Gf(n){try{let e=n.params;if(!e?.productId){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:AGENT_RPC_ERROR_CODES.INVALID_PARAMS,message:"productId is required."});return}let r=De.call(this).getStatus(e.productId);n.id!==void 0&&this.sendResponse(n.id,r)}catch(e){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:AGENT_RPC_ERROR_CODES.INTERNAL_ERROR,message:e instanceof Error?e.message:String(e)})}}async function Kf(n){try{let t=await De.call(this).list(this.getActiveProjectRoot());n.id!==void 0&&this.sendResponse(n.id,t)}catch(e){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:AGENT_RPC_ERROR_CODES.INTERNAL_ERROR,message:e instanceof Error?e.message:String(e)})}}async function Vf(n){try{let e=n.params;if(!e?.productId){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:AGENT_RPC_ERROR_CODES.INVALID_PARAMS,message:"productId is required."});return}await De.call(this).delete(e.productId),n.id!==void 0&&this.sendResponse(n.id,{ok:!0})}catch(e){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:AGENT_RPC_ERROR_CODES.INTERNAL_ERROR,message:e instanceof Error?e.message:String(e)})}}async function zf(n){try{let e=n.params;if(!e?.productId){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:AGENT_RPC_ERROR_CODES.INVALID_PARAMS,message:"productId is required."});return}await De.call(this).delete(e.productId),n.id!==void 0&&this.sendResponse(n.id,{ok:!0})}catch(e){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:AGENT_RPC_ERROR_CODES.INTERNAL_ERROR,message:e instanceof Error?e.message:String(e)})}}async function Xf(n){try{let e=n.params;if(!e?.productId){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:AGENT_RPC_ERROR_CODES.INVALID_PARAMS,message:"productId is required."});return}await De.call(this).rollback(e.productId,e.checkpoint??"latest"),n.id!==void 0&&this.sendResponse(n.id,{ok:!0})}catch(e){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:AGENT_RPC_ERROR_CODES.INTERNAL_ERROR,message:e instanceof Error?e.message:String(e)})}}import{randomUUID as rl}from"node:crypto";import*as Xe from"node:fs";import*as yn from"node:path";ae();var _e=new On;function Yf(n){let e=n.params,t=e?.id??rl();this.log(`[thread.create] id=${t} title=${e?.title??"(none)"}`),e?.cwd&&typeof e.cwd=="string"&&this.setActiveWorkdir(e.cwd),this.currentSessionId=t,this.sessionState=new zt(t),this.sessionTaskDomain=void 0,this.memoryPrefetchState=Lt(),this.enableIdleDream(),n.id!==void 0&&this.sendResponse(n.id,{id:t,title:e?.title,status:"active",createdAt:new Date().toISOString()})}async function Jf(n){let e=n.params,t=e?.limit??20;try{let r=e?.projectId??_e.getActiveProjectId(),s=_e.getProjectWorkspaceDir(r),i=(await At(t,s)).map(a=>({id:a.sessionId,title:a.title,status:"active",turnCount:a.messageCount,createdAt:a.createdAt,lastActiveAt:a.lastActiveAt}));n.id!==void 0&&this.sendResponse(n.id,{threads:i})}catch(r){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:`Failed to list threads: ${r.message}`})}}async function Qf(n){let e=n.params,t=e?.sessionId??rl();try{let r=e?.projectId??_e.getActiveProjectId(),s=_e.getProjectWorkspaceDir(r);await et(t,{sessionId:t,title:e?.title,type:e?.type,ownerId:e?.ownerId,groupKey:e?.groupKey,groupName:e?.groupName,groupPlatform:e?.groupPlatform,projectId:r},s),n.id!==void 0&&this.sendResponse(n.id,{sessionId:t,title:e?.title})}catch(r){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:`Failed to create session: ${r.message}`})}}async function Zf(n){let e=n.params;if(n.id===void 0)return;let t=e?.platform??"desktop",r=e?.chatId,s=e?.chatType,o=e?.userId??"local";try{if(t==="desktop"&&r){let d=e?.projectId??_e.getActiveProjectId(),u=_e.getProjectWorkspaceDir(d),m=(await At(500,u)).find(h=>h.sessionId===r);if(m){this.sendResponse(n.id,{sessionId:r,title:m.title,type:m.type??"personal",ownerId:o,projectId:d});return}await et(r,{sessionId:r,type:"personal",ownerId:o,projectId:d},u),this.sendResponse(n.id,{sessionId:r,type:"personal",ownerId:o,projectId:d});return}if(s==="group"&&r&&t){let d=`group:${t}:${r}`,u=me();for(let p of u){if(!p.workspaceDir)continue;let h=(await At(500,p.workspaceDir)).find(f=>f.groupKey===d&&!f.sealedAt);if(h){let f=cn(h.sessionId,p.workspaceDir);if(f){let y=await kf(f,p.workspaceDir);if(y.split){this.sendResponse(n.id,{sessionId:y.activeSessionId,title:void 0,type:"group",ownerId:o,groupKey:d,groupPlatform:t,groupName:e?.groupName,projectId:p.id,previousSessionId:y.sealedSessionId});return}}this.sendResponse(n.id,{sessionId:h.sessionId,title:h.title,type:"group",ownerId:o,groupKey:d,groupPlatform:t,groupName:e?.groupName,projectId:p.id});return}}}let i=rl(),a=_e.getActiveProjectId(),c=_e.getProjectWorkspaceDir(a),l=s==="group"?`group:${t}:${r}`:void 0;await et(i,{sessionId:i,type:s==="group"?"group":"personal",ownerId:o,groupKey:l,groupPlatform:s==="group"?t:void 0,groupName:e?.groupName,projectId:a},c),this.sendResponse(n.id,{sessionId:i,type:s==="group"?"group":"personal",ownerId:o,groupKey:l,groupPlatform:s==="group"?t:void 0,groupName:e?.groupName,projectId:a})}catch(i){this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:`Failed to resolve session: ${i.message}`})}}async function eh(n){let e=n.params,t=e?.limit??50;try{let r;if(e?.projectId){let o=ct(e.projectId);if(!o){n.id!==void 0&&this.sendResponse(n.id,{sessions:[]});return}let i=o.workspaceDir;r=await At(t*2,i),r=r.filter(a=>a.projectId===e.projectId);for(let a of r)a.projectId=e.projectId}else{let o=me(),i=new Set,a=[];for(let c of o){if(!c.workspaceDir)continue;let l=await At(t,c.workspaceDir);for(let d of l)i.has(d.sessionId)||d.projectId&&(i.add(d.sessionId),a.push(d))}a.sort((c,l)=>c.lastActiveAt>l.lastActiveAt?-1:c.lastActiveAt<l.lastActiveAt?1:0),r=a}e?.archived===!0?r=r.filter(o=>o.archivedAt!=null):e?.archived===!1&&(r=r.filter(o=>o.archivedAt==null));let s=r.slice(0,t).map(o=>({sessionId:o.sessionId,title:o.title,type:o.type,lastActiveAt:o.lastActiveAt,pinnedAt:o.pinnedAt??null,archivedAt:o.archivedAt??null,sealedAt:o.sealedAt??null,projectId:o.projectId,previousSessionId:o.previousSessionId??null,carryoverSummary:o.carryoverSummary??null}));n.id!==void 0&&this.sendResponse(n.id,{sessions:s})}catch(r){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:`Failed to list sessions: ${r.message}`})}}async function th(n){let e=n.params;if(!e?.sessionId){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:"Missing required param: sessionId"});return}try{let t=_e.resolveWorkspaceDir(e.sessionId,e.projectId),s=(await At(500,t)).find(o=>o.sessionId===e.sessionId);n.id!==void 0&&this.sendResponse(n.id,{session:s?{sessionId:s.sessionId,title:s.title,type:s.type,lastActiveAt:s.lastActiveAt,pinnedAt:s.pinnedAt??null,archivedAt:s.archivedAt??null,projectId:s.projectId}:null})}catch(t){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:`Failed to get session: ${t.message}`})}}async function nh(n){let e=n.params;if(!e?.sessionId){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:"Missing required param: sessionId"});return}try{let t=_e.resolveWorkspaceDir(e.sessionId,e.projectId),r=await Ta(e.sessionId,t);if(!r){n.id!==void 0&&this.sendResponse(n.id,{messages:[],total:0});return}let s=r.messages,o=e.limit&&e.limit>0?e.limit:s.length,i=s.slice(-o);n.id!==void 0&&this.sendResponse(n.id,{messages:i,total:s.length})}catch(t){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:`Failed to get messages: ${t.message}`})}}async function rh(n){let e=n.params;if(!e?.sessionId){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:"Missing required param: sessionId"});return}try{let t=_e.resolveWorkspaceDir(e.sessionId,e.projectId),r=await et(e.sessionId,{...e.title!==void 0?{title:e.title}:{},...e.pinnedAt!==void 0?{pinnedAt:e.pinnedAt}:{},...e.archivedAt!==void 0?{archivedAt:e.archivedAt}:{}},t);r&&this.sendNotification("session.info",{sessionId:e.sessionId,title:r.title,pinnedAt:r.pinnedAt??null,archivedAt:r.archivedAt??null,projectId:e.projectId||void 0}),n.id!==void 0&&this.sendResponse(n.id,{ok:r!==null})}catch(t){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:`Failed to update session: ${t.message}`})}}async function sh(n){let e=n.params;if(!e?.sessionId){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:"Missing required param: sessionId"});return}try{let t=_e.resolveWorkspaceDir(e.sessionId,e.projectId);await Ra(e.sessionId,t),n.id!==void 0&&this.sendResponse(n.id,{ok:!0})}catch(t){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:`Failed to delete session: ${t.message}`})}}async function oh(n){let e=n.params;if(!e?.projectId){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:"Missing required param: projectId"});return}try{let t=_e.getProjectWorkspaceDir(e.projectId),r=await At(1e4,t),s=0;for(let o of r)await Ra(o.sessionId,t),s++;n.id!==void 0&&this.sendResponse(n.id,{ok:!0,deletedCount:s})}catch(t){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:`Failed to delete all sessions: ${t.message}`})}}async function ih(n){let e=n.params;if(!e?.sessionId){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:"Missing required param: sessionId"});return}try{let t=_e.resolveWorkspaceDir(e.sessionId,e.projectId);await et(e.sessionId,{archivedAt:new Date().toISOString()},t),n.id!==void 0&&this.sendResponse(n.id,{ok:!0})}catch(t){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:`Failed to archive session: ${t.message}`})}}async function ah(n){let e=n.params,t=e?.sessionId;if(!t){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:"sessionId is required"});return}try{let r=_e.resolveWorkspaceDir(t,e?.projectId),s=await Ta(t,r);if(!s){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:`Session not found: ${t}`});return}s.messages&&s.messages.length>0&&this.resumedSessionHistory.set(t,s.messages),n.id!==void 0&&this.sendResponse(n.id,{metadata:s.metadata,messages:s.messages})}catch(r){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:`Failed to resume session: ${r.message}`})}}function ch(n){let e=this.currentSessionId||"default",t=this.sessionState?.createSnapshot(),r,s=this.getActiveProjectRoot();s&&(r=yn.join(Ot(s),e));let o={sessionId:e,model:this.currentModel||void 0,cwd:process.cwd(),paths:{sessionDir:r,agentHome:q(),settings:it()},usage:t?{turnCount:t.turnCount,inputTokens:t.totalInputTokens,outputTokens:t.totalOutputTokens}:void 0};n.id!==void 0&&this.sendResponse(n.id,o)}function lh(n){let e=n.params,t=null;if(e?.projectId)t=ct(e.projectId);else if(e?.projectName){let o=me(),i=e.projectName.toLowerCase();if(t=o.find(a=>a.name.toLowerCase()===i)??null,t||(t=o.find(a=>a.name.toLowerCase().includes(i))??null),!t){let a=o.map(c=>c.name).slice(0,10);n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:`No project matching "${e.projectName}". Available: ${a.join(", ")||"(none)"}`});return}}else{n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:"Missing required param: projectId or projectName"});return}if(!t||t.status!=="active"){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:`Project not found or archived: ${e.projectId??e.projectName}`});return}let r=e.workspaceDir??t.workspaceDir;if(!Xe.existsSync(r)){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:`Workspace directory does not exist: ${r}`});return}let s=ut(t.id);if(!s){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:"Switch failed"});return}this.setActiveWorkdir(s.workspaceDir),this.sendNotification("project.switched",{id:s.id,name:s.name,workspaceDir:s.workspaceDir}),n.id!==void 0&&this.sendResponse(n.id,{ok:!0,project:s})}function dh(n){let e=Oe(),t=me();n.id!==void 0&&this.sendResponse(n.id,{sessionId:this.currentSessionId,activeProject:e,projects:t})}async function uh(n){let e=n.params,t=e?.sessionId;if(!t){n.id!==void 0&&this.sendResponse(n.id,{ok:!1});return}let r=me();for(let s of r)try{let o=_e.getProjectWorkspaceDir(s.id),i=await cn(t,o);if(i&&i.projectId===s.id){ut(s.id),this.setActiveWorkdir(o),this.log(`[session.focus] switched to project ${s.id} for session ${t}`),n.id!==void 0&&this.sendResponse(n.id,{ok:!0,projectId:s.id});return}}catch{}if(e?.projectName){let s=r.find(o=>o.name===e.projectName);if(s){let o=_e.getProjectWorkspaceDir(s.id);this.getActiveProjectRoot()!==o&&(this.setActiveWorkdir(o),this.log(`[session.focus] switched to project ${s.id} by name "${e.projectName}"`)),n.id!==void 0&&this.sendResponse(n.id,{ok:!0,projectId:s.id});return}}n.id!==void 0&&this.sendResponse(n.id,{ok:!1})}async function ph(n){let e=n.params,{sessionId:t,fromProjectId:r,toProjectId:s}=e??{};if(!t||!r||!s){n.id!==void 0&&this.sendError(n.id,v.INVALID_PARAMS,"sessionId, fromProjectId, and toProjectId are required");return}if(r===s){n.id!==void 0&&this.sendResponse(n.id,{ok:!0});return}let o=ct(r),i=ct(s);if(!o||!i){n.id!==void 0&&this.sendError(n.id,v.INVALID_PARAMS,"Source or target project not found");return}let a=yn.join(_e.getProjectWorkspaceDir(r),".qlogicagent","sessions",t),c=yn.join(_e.getProjectWorkspaceDir(s),".qlogicagent","sessions",t);if(!Xe.existsSync(a)){n.id!==void 0&&this.sendError(n.id,v.INVALID_PARAMS,`Session ${t} not found in project ${r}`);return}try{Xe.mkdirSync(yn.dirname(c),{recursive:!0}),Xe.cpSync(a,c,{recursive:!0});let l=yn.join(c,"metadata.json");if(Xe.existsSync(l)){let d=JSON.parse(Xe.readFileSync(l,"utf-8"));d.projectId=s,Xe.writeFileSync(l,JSON.stringify(d,null,2))}Xe.rmSync(a,{recursive:!0,force:!0}),this.sendNotification("session-update",{sessionId:t,projectId:s}),this.log(`[session.moveToProject] moved ${t}: ${r} \u2192 ${s}`),n.id!==void 0&&this.sendResponse(n.id,{ok:!0,projectId:s})}catch(l){this.log(`[session.moveToProject] error: ${l.message}`),n.id!==void 0&&this.sendError(n.id,v.INTERNAL_ERROR,`Move failed: ${l.message}`)}}import*as yh from"node:path";import{randomUUID as b_}from"node:crypto";import{join as sl}from"node:path";import{mkdir as f_,readdir as h_}from"node:fs/promises";ae();function mh(n){return sl(Me(n),"solos")}function ol(n,e){return sl(mh(e),n)}function gh(n,e){return sl(ol(n,e),"solo-state.json")}async function fh(n,e){let t=ol(n.soloId,e);await f_(t,{recursive:!0}),await Nn(gh(n.soloId,e),n)}async function y_(n,e){return mn(gh(n,e))}async function hh(n){let e=mh(n),t;try{t=await h_(e)}catch{return[]}let r=[];for(let s of t){let o=await y_(s,n);o&&r.push(o)}return r}async function il(n,e){let{rm:t}=await import("node:fs/promises"),r=ol(n,e);try{return await t(r,{recursive:!0,force:!0}),!0}catch{return!1}}var fo=class{constructor(e,t,r,s={}){this.processManager=e;this.acpDetector=t;this.configStore=r;this.callbacks=s}processManager;acpDetector;configStore;callbacks;sessions=new Map;persistSession(e){let t={soloId:e.soloId,state:e.state,task:e.task,cwd:e.cwd,gitRoot:e.gitRoot,agents:e.agents.map(r=>({agentId:r.agentId,memberId:r.memberId,worktreePath:r.worktreePath,worktreeBranch:r.worktreeBranch,state:r.state,resultText:r.resultText,diff:r.diff,usage:r.usage,error:r.error,turns:r.turns})),evaluation:e.evaluation,createdAt:e.createdAt};fh(t,e.cwd).catch(()=>{})}async restoreFromDisk(e){let t=await hh(e);for(let r of t)this.sessions.has(r.soloId)||this.sessions.set(r.soloId,{soloId:r.soloId,state:r.state,task:r.task,cwd:r.cwd,gitRoot:r.gitRoot,agents:r.agents.map(s=>({...s,turns:s.turns??[]})),evaluation:r.evaluation,createdAt:r.createdAt});return t.length}async deleteSolo(e){return this.sessions.delete(e),il(e)}async start(e){let{task:t,agents:r,cwd:s,sharedConfig:o}=e;if(r.length<2)throw new Error("Solo Mode requires at least 2 agents");let i=await $r(s);if(!i)throw new Error("Solo Mode requires a git repository");let a=t;if(o){let p=[];o.rules?.length&&p.push(`<rules>
|
|
938
938
|
${o.rules.join(`
|
|
939
939
|
`)}
|
|
940
940
|
</rules>`),o.memory?.length&&p.push(`<memory>
|
|
@@ -944,30 +944,30 @@ ${o.memory.join(`
|
|
|
944
944
|
|
|
945
945
|
`)}
|
|
946
946
|
|
|
947
|
-
${t}`)}let c=`solo-${b_().slice(0,8)}`,l={soloId:c,state:"running",task:t,cwd:s,gitRoot:i,agents:[],createdAt:Date.now()};this.sessions.set(c,l),this.persistSession(l),this.callbacks.log?.info(`[solo] starting ${c} with ${r.length} agents`);let d=r.map(async(p,m)=>{let h=`${c}-${p}-${m}`,f=`solo/${h}`,y=`${c}:${p}:${m}`,b;try{b=await po(i,h)}catch(A){this.callbacks.log?.warn(`[solo] worktree creation failed for ${p}: ${A instanceof Error?A.message:String(A)}`);let _={agentId:p,memberId:y,worktreePath:"",worktreeBranch:f,state:"failed",error:`Worktree creation failed: ${A instanceof Error?A.message:String(A)}`,turns:[]};l.agents.push(_);return}let k={agentId:p,memberId:y,worktreePath:b,worktreeBranch:f,state:"pending",turns:[]};l.agents.push(k);try{k.state="running",this.callbacks.onProgress?.(c,p,"running");let A=this.acpDetector.buildExternalDescriptor(p);if(!A)throw new Error(`Agent ${p} is not available or not ACP-compatible`);await this.processManager.spawn({memberId:y,name:`solo-${p}`,cwd:b,prompt:a,external:A});let _=this.processManager.getHandle(y);if(!_||_.state!=="ready")throw new Error(`Agent ${p} spawn did not reach ready state`);let I=await this.processManager.sendTask(y,a);k.state="completed",k.resultText=typeof I=="string"?I:JSON.stringify(I),k.diff=await nl(b),k.turns.push({role:"user",content:t,timestamp:Date.now()}),k.turns.push({role:"agent",content:k.resultText,timestamp:Date.now()});let N=this.processManager.getUsageTracker(y);if(N?.hasData()){let L=N.getUsage();k.usage={inputTokens:L.inputTokens,outputTokens:L.outputTokens}}this.callbacks.onProgress?.(c,p,"completed"),k.diff&&this.callbacks.onAgentDiff?.(c,p,[{path:".",hunks:k.diff}]),k.usage&&this.callbacks.onAgentUsage?.(c,p,k.usage.inputTokens,k.usage.outputTokens),this.callbacks.log?.info(`[solo] ${p} completed (diff: ${k.diff?"yes":"none"})`)}catch(A){k.state="failed",k.error=A instanceof Error?A.message:String(A),this.callbacks.onProgress?.(c,p,"failed",k.error),this.callbacks.log?.warn(`[solo] ${p} failed: ${k.error}`)}});await Promise.allSettled(d);let u=l.agents.filter(p=>p.state==="completed");if(u.length===0)return l.state="failed",this.persistSession(l),this.callbacks.log?.warn(`[solo] all agents failed for ${c}`),c;for(let p of l.agents)p.state==="completed"&&(p.state="idle");return this.persistSession(l),this.callbacks.log?.info(`[solo] ${u.length}/${l.agents.length} agents ready for interaction`),c}async message(e,t,r,s){let o=this.sessions.get(e);if(!o)throw new Error(`Solo session ${e} not found`);if(o.state!=="running")throw new Error(`Solo session ${e} is not active (state: ${o.state})`);let i=o.agents.filter(l=>l.agentId===t),a=s!==void 0?i[s]:i[0];if(!a)throw new Error(`Agent ${t} not found in solo session ${e}`);if(!["idle","completed"].includes(a.state))throw new Error(`Agent ${t} is not ready for messages (state: ${a.state})`);a.turns.push({role:"user",content:r,timestamp:Date.now()}),a.state="running",this.callbacks.onProgress?.(e,t,"running");try{let l=await this.processManager.sendTask(a.memberId,r),d=typeof l=="string"?l:l?.content??JSON.stringify(l);a.turns.push({role:"agent",content:d,timestamp:Date.now()}),a.resultText=d,a.diff=await nl(a.worktreePath),a.state="idle";let u=this.processManager.getUsageTracker(a.memberId);if(u?.hasData()){let p=u.getUsage();a.usage={inputTokens:p.inputTokens,outputTokens:p.outputTokens}}return this.callbacks.onProgress?.(e,t,"idle"),this.persistSession(o),{resultText:d}}catch(l){throw a.state="failed",a.error=l instanceof Error?l.message:String(l),this.callbacks.onProgress?.(e,t,"failed",a.error),this.persistSession(o),l}}async triggerEvaluation(e,t,r){let s=this.sessions.get(e);if(!s)throw new Error(`Solo session ${e} not found`);let o=s.agents.filter(c=>c.state==="completed"||c.state==="idle");if(o.length===0)throw new Error(`No agents have completed work in session ${e}`);let i=s.agents.filter(c=>c.agentId===t),a=r!==void 0?i[r]:i[0];if(!a)throw new Error(`Evaluator agent ${t} not found in session ${e}`);if(a.state!=="idle"&&a.state!=="completed")throw new Error(`Evaluator agent ${t} is not ready (state: ${a.state})`);s.state="evaluating",this.callbacks.log?.info(`[solo] user-triggered evaluation for ${e} by ${t} (${o.length} candidates)`);try{let c=await this.evaluate(s,o,a);return s.evaluation=c,s.state="running",this.callbacks.onEvaluation?.(e,c),this.persistSession(s),c}catch(c){throw s.state="running",this.persistSession(s),new Error(`Evaluation failed: ${c instanceof Error?c.message:String(c)}`)}}getStatus(e){let t=this.sessions.get(e);return t?{soloId:t.soloId,state:t.state,agents:t.agents.map(r=>({id:r.agentId,state:r.state,progress:r.state==="running"?"Working...":void 0,resultText:r.resultText,diff:r.diff,usage:r.usage,error:r.error,worktreePath:r.worktreePath})),evaluation:t.evaluation}:null}async cancel(e){let t=this.sessions.get(e);if(!t)throw new Error(`Solo session ${e} not found`);if(t.state!=="running"&&t.state!=="evaluating")throw new Error(`Solo session ${e} is not running (state: ${t.state})`);t.state="cancelled";for(let r of t.agents)if(r.state==="running"||r.state==="pending"||r.state==="idle"){r.state="failed",r.error="Cancelled by user";try{this.processManager.kill(r.memberId)}catch{}}await this.cleanupWorktrees(t),this.callbacks.log?.info(`[solo] cancelled ${e}`)}async select(e){let t=this.sessions.get(e.soloId);if(!t)throw new Error(`Solo session ${e.soloId} not found`);if(t.state!=="completed"&&t.state!=="running")throw new Error(`Solo session ${e.soloId} is not ready for selection (state: ${t.state})`);let r=t.agents.find(o=>o.agentId===e.winnerId&&(o.state==="completed"||o.state==="idle"));if(!r)throw new Error(`Agent ${e.winnerId} is not a completed participant in ${e.soloId}`);let s=await
|
|
948
|
-
`),i=r.memberId;try{let a=await this.processManager.sendTask(i,o),c=typeof a=="string"?a:JSON.stringify(a);return this.parseEvaluationResponse(c,t)}catch{return{winnerId:t[0].agentId,reasoning:"Evaluation failed; defaulting to first completed agent."}}}parseEvaluationResponse(e,t){let r=e.match(/WINNER:\s*(\S+)/i),s=e.match(/REASONING:\s*(.+)/is),o=t.map(a=>a.agentId),i=r?.[1];if(i&&o.includes(i))return{winnerId:i,reasoning:s?.[1]?.trim()||"Selected by leader evaluation."};for(let a of o)if(e.includes(a))return{winnerId:a,reasoning:s?.[1]?.trim()||e.slice(0,500)};return{winnerId:t[0].agentId,reasoning:`Could not parse evaluation. Full response: ${e.slice(0,500)}`}}async cleanupWorktrees(e){for(let t of e.agents)if(t.worktreePath)try{try{this.processManager.kill(t.memberId)}catch{}this.processManager.remove(t.memberId),await
|
|
947
|
+
${t}`)}let c=`solo-${b_().slice(0,8)}`,l={soloId:c,state:"running",task:t,cwd:s,gitRoot:i,agents:[],createdAt:Date.now()};this.sessions.set(c,l),this.persistSession(l),this.callbacks.log?.info(`[solo] starting ${c} with ${r.length} agents`);let d=r.map(async(p,m)=>{let h=`${c}-${p}-${m}`,f=`solo/${h}`,y=`${c}:${p}:${m}`,b;try{b=await po(i,h)}catch(A){this.callbacks.log?.warn(`[solo] worktree creation failed for ${p}: ${A instanceof Error?A.message:String(A)}`);let _={agentId:p,memberId:y,worktreePath:"",worktreeBranch:f,state:"failed",error:`Worktree creation failed: ${A instanceof Error?A.message:String(A)}`,turns:[]};l.agents.push(_);return}let k={agentId:p,memberId:y,worktreePath:b,worktreeBranch:f,state:"pending",turns:[]};l.agents.push(k);try{k.state="running",this.callbacks.onProgress?.(c,p,"running");let A=this.acpDetector.buildExternalDescriptor(p);if(!A)throw new Error(`Agent ${p} is not available or not ACP-compatible`);await this.processManager.spawn({memberId:y,name:`solo-${p}`,cwd:b,prompt:a,external:A});let _=this.processManager.getHandle(y);if(!_||_.state!=="ready")throw new Error(`Agent ${p} spawn did not reach ready state`);let I=await this.processManager.sendTask(y,a);k.state="completed",k.resultText=typeof I=="string"?I:JSON.stringify(I),k.diff=await nl(b),k.turns.push({role:"user",content:t,timestamp:Date.now()}),k.turns.push({role:"agent",content:k.resultText,timestamp:Date.now()});let N=this.processManager.getUsageTracker(y);if(N?.hasData()){let L=N.getUsage();k.usage={inputTokens:L.inputTokens,outputTokens:L.outputTokens}}this.callbacks.onProgress?.(c,p,"completed"),k.diff&&this.callbacks.onAgentDiff?.(c,p,[{path:".",hunks:k.diff}]),k.usage&&this.callbacks.onAgentUsage?.(c,p,k.usage.inputTokens,k.usage.outputTokens),this.callbacks.log?.info(`[solo] ${p} completed (diff: ${k.diff?"yes":"none"})`)}catch(A){k.state="failed",k.error=A instanceof Error?A.message:String(A),this.callbacks.onProgress?.(c,p,"failed",k.error),this.callbacks.log?.warn(`[solo] ${p} failed: ${k.error}`)}});await Promise.allSettled(d);let u=l.agents.filter(p=>p.state==="completed");if(u.length===0)return l.state="failed",this.persistSession(l),this.callbacks.log?.warn(`[solo] all agents failed for ${c}`),c;for(let p of l.agents)p.state==="completed"&&(p.state="idle");return this.persistSession(l),this.callbacks.log?.info(`[solo] ${u.length}/${l.agents.length} agents ready for interaction`),c}async message(e,t,r,s){let o=this.sessions.get(e);if(!o)throw new Error(`Solo session ${e} not found`);if(o.state!=="running")throw new Error(`Solo session ${e} is not active (state: ${o.state})`);let i=o.agents.filter(l=>l.agentId===t),a=s!==void 0?i[s]:i[0];if(!a)throw new Error(`Agent ${t} not found in solo session ${e}`);if(!["idle","completed"].includes(a.state))throw new Error(`Agent ${t} is not ready for messages (state: ${a.state})`);a.turns.push({role:"user",content:r,timestamp:Date.now()}),a.state="running",this.callbacks.onProgress?.(e,t,"running");try{let l=await this.processManager.sendTask(a.memberId,r),d=typeof l=="string"?l:l?.content??JSON.stringify(l);a.turns.push({role:"agent",content:d,timestamp:Date.now()}),a.resultText=d,a.diff=await nl(a.worktreePath),a.state="idle";let u=this.processManager.getUsageTracker(a.memberId);if(u?.hasData()){let p=u.getUsage();a.usage={inputTokens:p.inputTokens,outputTokens:p.outputTokens}}return this.callbacks.onProgress?.(e,t,"idle"),this.persistSession(o),{resultText:d}}catch(l){throw a.state="failed",a.error=l instanceof Error?l.message:String(l),this.callbacks.onProgress?.(e,t,"failed",a.error),this.persistSession(o),l}}async triggerEvaluation(e,t,r){let s=this.sessions.get(e);if(!s)throw new Error(`Solo session ${e} not found`);let o=s.agents.filter(c=>c.state==="completed"||c.state==="idle");if(o.length===0)throw new Error(`No agents have completed work in session ${e}`);let i=s.agents.filter(c=>c.agentId===t),a=r!==void 0?i[r]:i[0];if(!a)throw new Error(`Evaluator agent ${t} not found in session ${e}`);if(a.state!=="idle"&&a.state!=="completed")throw new Error(`Evaluator agent ${t} is not ready (state: ${a.state})`);s.state="evaluating",this.callbacks.log?.info(`[solo] user-triggered evaluation for ${e} by ${t} (${o.length} candidates)`);try{let c=await this.evaluate(s,o,a);return s.evaluation=c,s.state="running",this.callbacks.onEvaluation?.(e,c),this.persistSession(s),c}catch(c){throw s.state="running",this.persistSession(s),new Error(`Evaluation failed: ${c instanceof Error?c.message:String(c)}`)}}getStatus(e){let t=this.sessions.get(e);return t?{soloId:t.soloId,state:t.state,agents:t.agents.map(r=>({id:r.agentId,state:r.state,progress:r.state==="running"?"Working...":void 0,resultText:r.resultText,diff:r.diff,usage:r.usage,error:r.error,worktreePath:r.worktreePath})),evaluation:t.evaluation}:null}async cancel(e){let t=this.sessions.get(e);if(!t)throw new Error(`Solo session ${e} not found`);if(t.state!=="running"&&t.state!=="evaluating")throw new Error(`Solo session ${e} is not running (state: ${t.state})`);t.state="cancelled";for(let r of t.agents)if(r.state==="running"||r.state==="pending"||r.state==="idle"){r.state="failed",r.error="Cancelled by user";try{this.processManager.kill(r.memberId)}catch{}}await this.cleanupWorktrees(t),this.callbacks.log?.info(`[solo] cancelled ${e}`)}async select(e){let t=this.sessions.get(e.soloId);if(!t)throw new Error(`Solo session ${e.soloId} not found`);if(t.state!=="completed"&&t.state!=="running")throw new Error(`Solo session ${e.soloId} is not ready for selection (state: ${t.state})`);let r=t.agents.find(o=>o.agentId===e.winnerId&&(o.state==="completed"||o.state==="idle"));if(!r)throw new Error(`Agent ${e.winnerId} is not a completed participant in ${e.soloId}`);let s=await Of(t.gitRoot,r.worktreeBranch);return this.callbacks.log?.info(`[solo] merged ${r.worktreeBranch}: ${s}`),t.state="completed",await this.cleanupWorktrees(t),this.persistSession(t),r.worktreeBranch}listSessions(){return[...this.sessions.values()].map(e=>this.getStatus(e.soloId))}async delete(e){let t=this.sessions.get(e);if(!t)throw new Error(`Solo session ${e} not found`);if(t.state==="running"||t.state==="evaluating"){t.state="cancelled";for(let r of t.agents)if(r.state==="running"||r.state==="pending"||r.state==="idle"){r.state="failed",r.error="Deleted";try{this.processManager.kill(r.memberId)}catch{}}await this.cleanupWorktrees(t)}this.sessions.delete(e),await il(e,t?.cwd),this.callbacks.log?.info(`[solo] deleted ${e}`)}async evaluate(e,t,r){if(t.length===1)return{winnerId:t[0].agentId,reasoning:`Only one agent (${t[0].agentId}) completed successfully.`};let s=["# Task Evaluation","","## Original Task",e.task,"","## Agent Results",""];for(let a of t)s.push(`### Agent: ${a.agentId}`,"","**Result:**",a.resultText??"(no output)","","**Changes (git diff stat):**",a.diff||"(no changes)","");s.push("## Instructions","","Review all agent results above. Select the best implementation and explain your reasoning.","Respond in this exact format:","","WINNER: <agent-id>","REASONING: <your explanation>");let o=s.join(`
|
|
948
|
+
`),i=r.memberId;try{let a=await this.processManager.sendTask(i,o),c=typeof a=="string"?a:JSON.stringify(a);return this.parseEvaluationResponse(c,t)}catch{return{winnerId:t[0].agentId,reasoning:"Evaluation failed; defaulting to first completed agent."}}}parseEvaluationResponse(e,t){let r=e.match(/WINNER:\s*(\S+)/i),s=e.match(/REASONING:\s*(.+)/is),o=t.map(a=>a.agentId),i=r?.[1];if(i&&o.includes(i))return{winnerId:i,reasoning:s?.[1]?.trim()||"Selected by leader evaluation."};for(let a of o)if(e.includes(a))return{winnerId:a,reasoning:s?.[1]?.trim()||e.slice(0,500)};return{winnerId:t[0].agentId,reasoning:`Could not parse evaluation. Full response: ${e.slice(0,500)}`}}async cleanupWorktrees(e){for(let t of e.agents)if(t.worktreePath)try{try{this.processManager.kill(t.memberId)}catch{}this.processManager.remove(t.memberId),await Df(e.gitRoot,t.worktreePath)}catch(r){this.callbacks.log?.warn(`[solo] failed to clean worktree for ${t.agentId}: ${r instanceof Error?r.message:String(r)}`)}}};ae();function Ye(){if(!this.soloEvaluator){let n=new _t({log:{info:t=>process.stderr.write(`[solo:pm] ${t}
|
|
949
949
|
`),warn:t=>process.stderr.write(`[solo:pm] WARN ${t}
|
|
950
|
-
`)},onNotification:(t,r,s)=>{(r==="agents.error"||r==="agents.status")&&this.sendNotification(r,s),this.sendNotification("team.member.notification",{memberId:t,method:r,params:s})},onStateChange:(t,r)=>{let s=n.getHandle(t),i=n.getUsageTracker(t)?.getUsage();this.emitAgentStatus(t,r,{missedBeats:n.getMissedBeats(t),lastActivityAt:s?.lastActivityAt,usage:i&&i.totalTokens>0?{inputTokens:i.inputTokens,outputTokens:i.outputTokens,totalTokens:i.totalTokens}:void 0})},onMcpToolCall:(t,r,s)=>this.handleMcpToolCall(t,r,s),sessionDir:
|
|
950
|
+
`)},onNotification:(t,r,s)=>{(r==="agents.error"||r==="agents.status")&&this.sendNotification(r,s),this.sendNotification("team.member.notification",{memberId:t,method:r,params:s})},onStateChange:(t,r)=>{let s=n.getHandle(t),i=n.getUsageTracker(t)?.getUsage();this.emitAgentStatus(t,r,{missedBeats:n.getMissedBeats(t),lastActivityAt:s?.lastActivityAt,usage:i&&i.totalTokens>0?{inputTokens:i.inputTokens,outputTokens:i.outputTokens,totalTokens:i.totalTokens}:void 0})},onMcpToolCall:(t,r,s)=>this.handleMcpToolCall(t,r,s),sessionDir:yh.join(q(),"agent-logs")}),e={log:{info:t=>process.stderr.write(`${t}
|
|
951
951
|
`),warn:t=>process.stderr.write(`${t}
|
|
952
|
-
`)},onProgress:(t,r,s,o)=>{this.sendNotification("solo.progress",{soloId:t,agentId:r,state:s,progress:o})},onEvaluation:(t,r)=>{this.sendNotification("solo.evaluation",{soloId:t,winnerId:r.winnerId,reasoning:r.reasoning})},onAgentDelta:(t,r,s)=>{this.sendNotification("solo.agentDelta",{soloId:t,agentId:r,text:s})},onAgentDiff:(t,r,s)=>{this.sendNotification("solo.agentDiff",{soloId:t,agentId:r,files:s})},onAgentUsage:(t,r,s,o)=>{this.sendNotification("solo.agentUsage",{soloId:t,agentId:r,inputTokens:s,outputTokens:o})}};this.soloEvaluator=new fo(n,this.acpDetector,this.agentConfigStore,e),this.soloProcessManager=n}return this.soloEvaluator}async function yh(n){try{let e=n.params;if(!e?.task||!e?.agents||!e?.cwd){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:"task, agents, and cwd are required."});return}if(!e.projectId){let o=Oe();o&&(e.projectId=o.id)}let t=Ye.call(this),r=await t.start(e),s=t.getStatus(r);n.id!==void 0&&this.sendResponse(n.id,s)}catch(e){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:e instanceof Error?e.message:String(e)})}}async function bh(n){try{let e=n.params;if(!e?.soloId){this.soloEvaluator?n.id!==void 0&&this.sendResponse(n.id,this.soloEvaluator.listSessions()):n.id!==void 0&&this.sendResponse(n.id,[]);return}let r=Ye.call(this).getStatus(e.soloId);if(!r){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:`Solo session ${e.soloId} not found.`});return}n.id!==void 0&&this.sendResponse(n.id,r)}catch(e){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:e instanceof Error?e.message:String(e)})}}async function vh(n){try{let e=n.params;if(!e?.soloId){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:"soloId is required."});return}await Ye.call(this).cancel(e.soloId),n.id!==void 0&&this.sendResponse(n.id,{ok:!0})}catch(e){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:e instanceof Error?e.message:String(e)})}}async function kh(n){try{let e=n.params;if(!e?.soloId||!e?.winnerId){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:"soloId and winnerId are required."});return}let r=await Ye.call(this).select(e);n.id!==void 0&&this.sendResponse(n.id,{ok:!0,mergedBranch:r})}catch(e){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:e instanceof Error?e.message:String(e)})}}function Sh(n){try{this.soloEvaluator?n.id!==void 0&&this.sendResponse(n.id,this.soloEvaluator.listSessions()):n.id!==void 0&&this.sendResponse(n.id,[])}catch(e){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:e instanceof Error?e.message:String(e)})}}async function Th(n){try{let e=n.params;if(!e?.soloId){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:"soloId is required."});return}await Ye.call(this).delete(e.soloId),n.id!==void 0&&this.sendResponse(n.id,{ok:!0})}catch(e){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:e instanceof Error?e.message:String(e)})}}async function Rh(n){try{let e=n.params;if(!e?.soloId||!e?.agentId||!e?.content){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:"soloId, agentId, and content are required."});return}let r=await Ye.call(this).message(e.soloId,e.agentId,e.content,e.agentIndex);n.id!==void 0&&this.sendResponse(n.id,r)}catch(e){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:e instanceof Error?e.message:String(e)})}}async function Ah(n){try{let e=n.params;if(!e?.soloId||!e?.evaluatorAgentId){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:"soloId and evaluatorAgentId are required."});return}let r=await Ye.call(this).triggerEvaluation(e.soloId,e.evaluatorAgentId,e.evaluatorIndex);n.id!==void 0&&this.sendResponse(n.id,r)}catch(e){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:e instanceof Error?e.message:String(e)})}}ae();import*as se from"node:fs";import*as be from"node:path";function wh(n){try{let e=se.readFileSync(n,"utf8"),t=e.match(/^---\n[\s\S]*?^version:\s*(\S+)/m),r=e.match(/^---\n[\s\S]*?^description:\s*(.+)/m);return{version:t?.[1],description:r?.[1]?.trim()}}catch{return{}}}function xh(n){let t=n.params?.projectId,r=this.getActiveProjectRoot();if(t&&this.projectLocator){let a=this.projectLocator.resolveProjectRoot(t);a&&(r=a)}let s=r?Tt(r):void 0,o=Dt(),i=[];if(s&&se.existsSync(s))for(let a of se.readdirSync(s)){let c=be.join(s,a);if(!se.statSync(c).isDirectory())continue;let l=be.join(c,"SKILL.md"),d=be.join(c,"SKILL.md.disabled"),u=se.existsSync(l)?l:null;if(u||se.existsSync(d)){let p=u?wh(u):{};i.push({name:a,path:c,active:!!u,scope:"project",version:p.version,description:p.description})}}if(se.existsSync(o))for(let a of se.readdirSync(o)){let c=be.join(o,a);try{if(!se.statSync(c).isDirectory())continue}catch{continue}let l=be.join(c,"SKILL.md"),d=be.join(c,"SKILL.md.disabled"),u=se.existsSync(l)?l:null;if(u||se.existsSync(d)){let p=u?wh(u):{};i.push({name:a,path:c,active:!!u,scope:"global",version:p.version,description:p.description})}}n.id!==void 0&&this.sendResponse(n.id,{skills:i})}function Ph(n){let t=n.params?.name;if(!t){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:"Missing required param: name"});return}let r=this.getActiveProjectRoot(),s=r?Tt(r):void 0;if(!s){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:"No active project workspace"});return}let o=be.join(s,t),i=be.join(o,"SKILL.md.disabled"),a=be.join(o,"SKILL.md");if(se.existsSync(a)){n.id!==void 0&&this.sendResponse(n.id,{ok:!0,already:!0});return}if(se.existsSync(i))try{se.renameSync(i,a);let c=q(),l=Be(c),d=qt(l,t);d.state!=="active"&&(d.state="active",d.staleAt=void 0,d.archivedAt=void 0),We(c,l),n.id!==void 0&&this.sendResponse(n.id,{ok:!0}),this.sendNotification("skills.updated",{action:"activate",name:t})}catch(c){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:`Failed to activate skill: ${c instanceof Error?c.message:c}`})}else n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:`Skill "${t}" not found`})}function Ih(n){let t=n.params?.name;if(!t){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:"Missing required param: name"});return}let r=this.getActiveProjectRoot(),s=r?Tt(r):void 0;if(!s){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:"No active project workspace"});return}let o=be.join(s,t),i=be.join(o,"SKILL.md"),a=be.join(o,"SKILL.md.disabled");if(!se.existsSync(i)){n.id!==void 0&&this.sendResponse(n.id,{ok:!0,already:!0});return}try{se.renameSync(i,a),n.id!==void 0&&this.sendResponse(n.id,{ok:!0}),this.sendNotification("skills.updated",{action:"deactivate",name:t})}catch(c){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:`Failed to deactivate skill: ${c instanceof Error?c.message:c}`})}}function _h(n){let e=n.params,t=e?.name;if(!t||/[\/\\]|\.\./.test(t)){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:"Missing or invalid skill name"});return}let r=q(),s=Be(r);if(s.records[t]?.pinned){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:`Skill "${t}" is pinned. Unpin it first.`});return}let o=e?.scope??"project",i;if(o==="global")i=be.join(Dt(),t);else{let a=this.getActiveProjectRoot(),c=a?Tt(a):void 0;if(!c){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:"No active project workspace"});return}i=be.join(c,t)}if(!se.existsSync(i)){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:`Skill "${t}" not found in ${o} scope`});return}try{se.rmSync(i,{recursive:!0,force:!0}),pt(),eo(s,t),We(r,s),n.id!==void 0&&this.sendResponse(n.id,{ok:!0,deleted:t,scope:o}),this.sendNotification("skills.updated",{action:"delete",name:t})}catch(a){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:`Failed to delete skill: ${a instanceof Error?a.message:a}`})}}function Eh(n){let e=n.params,t=e?.name;if(!t||/[\/\\]|\.\./.test(t)){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:"Missing or invalid skill name"});return}let r=this.getActiveProjectRoot(),s=r?Tt(r):void 0;if(!s){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:"No active project workspace"});return}let o=be.join(s,t),i=be.join(o,"SKILL.md");if(!se.existsSync(i)){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:`Skill "${t}" not found in project scope`});return}let a=Dt(),c=be.join(a,t);try{se.mkdirSync(c,{recursive:!0});let l=se.readdirSync(o);for(let d of l){let u=se.readFileSync(be.join(o,d));se.writeFileSync(be.join(c,d),u)}e?.keepLocal||se.rmSync(o,{recursive:!0,force:!0}),pt(),n.id!==void 0&&this.sendResponse(n.id,{ok:!0,promoted:t,globalPath:c,removedFromProject:!e?.keepLocal})}catch(l){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:`Failed to promote skill: ${l instanceof Error?l.message:l}`})}}function Ch(n){let e=n.params,t=q();if(e?.name){let r=Gg(t,e.name);n.id!==void 0&&this.sendResponse(n.id,{name:e.name,stats:r??null})}else{let r=Kg(t);n.id!==void 0&&this.sendResponse(n.id,{stats:r})}}function Mh(n){let e=n.params;if(!e?.name){n.id!==void 0&&this.sendResponse(n.id,null,{code:-32602,message:"Missing 'name' parameter"});return}let t=q(),r=Be(t);qt(r,e.name),Jg(r,e.name),We(t,r),n.id!==void 0&&this.sendResponse(n.id,{name:e.name,pinned:!0})}function Nh(n){let e=n.params;if(!e?.name){n.id!==void 0&&this.sendResponse(n.id,null,{code:-32602,message:"Missing 'name' parameter"});return}let t=q(),r=Be(t);Qg(r,e.name),We(t,r),n.id!==void 0&&this.sendResponse(n.id,{name:e.name,pinned:!1})}function Dh(n){let e=q(),t=this.getActiveProjectRoot(),r=t?be.join(t,".qlogicagent","skills"):be.join(e,"skills"),s=Zg(e,r);s.transitioned.length>0&&pt(),n.id!==void 0&&this.sendResponse(n.id,s)}function Oh(n){let e=n.params,t=q(),r=Be(t);if(e?.name){let s=r.records[e.name]??null;n.id!==void 0&&this.sendResponse(n.id,{record:s})}else if(e?.state){let s=ef(r,e.state);n.id!==void 0&&this.sendResponse(n.id,{records:s})}else n.id!==void 0&&this.sendResponse(n.id,{records:Object.values(r.records)})}import*as z from"node:fs";import*as ue from"node:path";ae();function al(n){let e=q(),t=Me(n);z.existsSync(t)||z.mkdirSync(t,{recursive:!0});let r=ue.join(e,"INSTRUCTIONS.md"),s=ue.join(t,"INSTRUCTIONS.md");if(z.existsSync(r)&&!z.existsSync(s))try{z.copyFileSync(r,s)}catch{}let o=Ad(),i=wn(n);if(z.existsSync(o)&&!z.existsSync(i))try{z.mkdirSync(i,{recursive:!0});for(let a of z.readdirSync(o)){if(!a.endsWith(".md"))continue;let c=ue.join(o,a),l=ue.join(i,a);z.statSync(c).isFile()&&z.copyFileSync(c,l)}}catch{}}function Lh(n){let e=n.params;if(!e?.name){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:"Missing required param: name"});return}let t=e.workspaceDir||ue.join(q(),"workspaces",e.name);if(e.groupId){let c=cs(e.groupId);if(c){n.id!==void 0&&this.sendResponse(n.id,{ok:!0,project:c,deduplicated:!0});return}}let s=me().find(c=>c.name===e.name);if(!z.existsSync(t))try{z.mkdirSync(t,{recursive:!0})}catch{n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:`Cannot create workspace directory: ${t}`});return}let o=as({name:e.name,workspaceDir:t,type:e.type??"personal",groupId:e.groupId,skipAutoSwitch:e.type==="solo"||e.type==="product"}),i=o.type==="solo"||o.type==="product";i||(ut(o.id),this.setActiveWorkdir(o.workspaceDir)),al(o.workspaceDir);let a=new Et(o.workspaceDir);if(a.ensureInitialized(),i||(this.memdir=a),i||this.mediaPersistence.setProjectDir(o.workspaceDir),o.type==="solo"){let c=ue.join(Me(o.workspaceDir),"solo-state.json");z.existsSync(c)||z.writeFileSync(c,JSON.stringify({agents:[],status:"idle",createdAt:new Date().toISOString()},null,2))}else if(o.type==="product"){let c=ue.join(Me(o.workspaceDir),"product-state.json");z.existsSync(c)||z.writeFileSync(c,JSON.stringify({tasks:[],instances:[],status:"idle",createdAt:new Date().toISOString()},null,2))}if(this.sendNotification("project.created",{id:o.id,name:o.name,workspaceDir:o.workspaceDir,type:o.type}),i||this.sendNotification("project.switched",{id:o.id,name:o.name,workspaceDir:o.workspaceDir}),n.id!==void 0){let c={ok:!0,project:o};s&&(c.warning=`\u5DF2\u5B58\u5728\u540C\u540D\u9879\u76EE\u300C${s.name}\u300D\uFF08\u4F4D\u4E8E ${s.workspaceDir}\uFF09\uFF0C\u5EFA\u8BAE\u4FEE\u6539\u540D\u79F0\u4EE5\u4FBF\u533A\u5206`),this.sendResponse(n.id,c)}}function $h(n){let e=me();n.id!==void 0&&this.sendResponse(n.id,{projects:e})}function jh(n){let e=n.params;if(!e?.projectId){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:"Missing required param: projectId"});return}let t=ct(e.projectId),r=la(e.projectId);if(!r.deleted){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:"Cannot delete project (not found or is default project)"});return}let s=!1,o;if(t?.workspaceDir){let i=ue.join(q(),"workspaces"),a=ue.resolve(t.workspaceDir);if(a.startsWith(ue.resolve(i)+ue.sep)){try{this.mediaPersistence?.releaseProjectDir?.(a)}catch{}for(let c=0;c<3;c++)try{z.rmSync(a,{recursive:!0,force:!0}),s=!0;break}catch(l){if(c<2&&(l.code==="EBUSY"||l.code==="EPERM"||l.code==="ENOTEMPTY")){let d=Date.now();for(;Date.now()-d<200;);}else{o=l.message??String(l);break}}}else o="\u9879\u76EE\u76EE\u5F55\u4E0D\u5728\u6258\u7BA1\u76EE\u5F55\u4E0B\uFF0C\u4E0D\u4F1A\u81EA\u52A8\u5220\u9664"}this.sendNotification("project.deleted",{id:e.projectId}),r.switchedTo&&(this.setActiveWorkdir(r.switchedTo.workspaceDir),this.sendNotification("project.switched",{id:r.switchedTo.id,name:r.switchedTo.name,workspaceDir:r.switchedTo.workspaceDir})),n.id!==void 0&&this.sendResponse(n.id,{ok:!0,switchedTo:r.switchedTo,dirDeleted:s,dirDeleteError:o})}function Uh(n){let e=me(),t=ue.join(q(),"workspaces"),r=ue.resolve(t)+ue.sep,s=0,o=[];for(let a of e)if(a.type!=="default"){if(la(a.id),s++,a.workspaceDir){let c=ue.resolve(a.workspaceDir);try{this.mediaPersistence?.releaseProjectDir?.(c)}catch{}for(let l=0;l<3;l++)try{z.existsSync(c)&&z.rmSync(c,{recursive:!0,force:!0});break}catch(d){if(l<2&&(d.code==="EBUSY"||d.code==="EPERM"||d.code==="ENOTEMPTY")){let u=Date.now();for(;Date.now()-u<300;);}else{o.push(`${a.name}: ${d.message??d}`);break}}}this.sendNotification("project.deleted",{id:a.id})}if(z.existsSync(t)){let a=me().find(d=>d.type==="default"),c=new Set;a?.workspaceDir&&c.add(ue.resolve(a.workspaceDir));let l=d=>{try{let u=z.readdirSync(d,{withFileTypes:!0});for(let p of u){if(!p.isDirectory())continue;let m=ue.join(d,p.name);if(!c.has(ue.resolve(m))){if(p.name==="groups"){l(m);try{z.readdirSync(m).length===0&&z.rmdirSync(m)}catch{}continue}try{z.rmSync(m,{recursive:!0,force:!0})}catch(h){o.push(`orphan:${p.name}: ${h.message??h}`)}}}}catch{}};l(t)}let i=me().find(a=>a.type==="default");i&&(this.setActiveWorkdir(i.workspaceDir),this.sendNotification("project.switched",{id:i.id,name:i.name,workspaceDir:i.workspaceDir})),n.id!==void 0&&this.sendResponse(n.id,{ok:!0,deletedCount:s,dirErrors:o.length?o:void 0})}function Fh(n){let e=n.params;if(!e?.projectId||!e?.newName){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:"Missing required params: projectId, newName"});return}let t=gu(e.projectId,e.newName);if(!t){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:"Cannot rename project (not found, is default, or name already taken)"});return}let r=ue.join(q(),"workspaces"),s=ue.resolve(t.workspaceDir);if(s.startsWith(ue.resolve(r)+ue.sep)){let o=ue.join(r,e.newName);if(z.existsSync(s)&&!z.existsSync(o))try{z.renameSync(s,o),fu(e.projectId,o),t.workspaceDir=o,this.getActiveProjectRoot()===s&&this.setActiveWorkdir(o)}catch{}}this.sendNotification("project.renamed",{id:t.id,name:t.name,workspaceDir:t.workspaceDir}),n.id!==void 0&&this.sendResponse(n.id,{ok:!0,project:t})}function Bh(n){let e=n.params;if(!e?.projectId){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:"Missing required param: projectId"});return}let t=hu(e.projectId);if(!t.archived){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:"Cannot archive project (not found or is default project)"});return}this.sendNotification("project.archived",{id:e.projectId}),t.switchedTo&&(this.setActiveWorkdir(t.switchedTo.workspaceDir),this.sendNotification("project.switched",{id:t.switchedTo.id,name:t.switchedTo.name,workspaceDir:t.switchedTo.workspaceDir})),n.id!==void 0&&this.sendResponse(n.id,{ok:!0,switchedTo:t.switchedTo})}function Hh(n){let e=n.params;if(!e?.projectId){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:"Missing required param: projectId"});return}let t=yu(e.projectId);if(!t){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:"Cannot unarchive project (not found or not archived)"});return}this.sendNotification("project.unarchived",{id:t.id,name:t.name,workspaceDir:t.workspaceDir}),n.id!==void 0&&this.sendResponse(n.id,{ok:!0,project:t})}function qh(n){let e=n.params;if(!e?.groupId){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:"Missing required param: groupId"});return}let t=bu(e.groupId);if(!t.archived){n.id!==void 0&&this.sendResponse(n.id,{ok:!1,error:"No active project with this groupId"});return}this.sendNotification("project.deleted",{id:t.projectId}),t.switchedTo&&(this.setActiveWorkdir(t.switchedTo.workspaceDir),this.sendNotification("project.switched",{id:t.switchedTo.id,name:t.switchedTo.name,workspaceDir:t.switchedTo.workspaceDir})),n.id!==void 0&&this.sendResponse(n.id,{ok:!0,projectId:t.projectId})}function Wh(n){let e=n.params;if(!e?.projectId){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:"projectId is required"});return}let t={};"planStatus"in e&&(t.planStatus=e.planStatus),"planAgents"in e&&(t.planAgents=e.planAgents),"planWinnerId"in e&&(t.planWinnerId=e.planWinnerId),"leaderSessionId"in e&&(t.leaderSessionId=e.leaderSessionId);let r=pu(e.projectId,t);n.id!==void 0&&this.sendResponse(n.id,{ok:r})}import*as bt from"node:fs";import*as vt from"node:path";ae();je();import Je from"node:fs";import jr from"node:path";var Gh=bi,Kh=vi,ho=class{dir;constructor(e){this.dir=wn(e)}list(){if(!Je.existsSync(this.dir))return[];let e=[];for(let t of Je.readdirSync(this.dir)){if(!t.endsWith(".md"))continue;let r=jr.join(this.dir,t);try{let s=Je.statSync(r);if(!s.isFile())continue;let o=Je.readFileSync(r,"utf8");e.push({filename:t,content:o,sizeBytes:s.size})}catch{}}return e}read(e){if(!this.isValidFilename(e))return null;let t=jr.join(this.dir,e);if(!Je.existsSync(t))return null;try{let r=Je.readFileSync(t,"utf8"),s=Je.statSync(t);return{filename:e,content:r,sizeBytes:s.size}}catch{return null}}write(e,t){if(!this.isValidFilename(e))throw new Error("Invalid filename: must end with .md and contain no path separators");let r=Buffer.byteLength(t,"utf8");if(r>Gh)throw new Error(`File too large: ${r} bytes exceeds ${Gh} limit`);if(this.getDirSize(e)+r>Kh)throw new Error(`Total instructions size would exceed ${Kh} byte limit`);Je.mkdirSync(this.dir,{recursive:!0});let o=jr.join(this.dir,e);return Je.writeFileSync(o,t,"utf8"),{filename:e,content:t,sizeBytes:r}}remove(e){if(!this.isValidFilename(e))return!1;let t=jr.join(this.dir,e);return Je.existsSync(t)?(Je.unlinkSync(t),!0):!1}loadAll(){let e=this.list();return e.length===0?"":`<project-instructions>
|
|
952
|
+
`)},onProgress:(t,r,s,o)=>{this.sendNotification("solo.progress",{soloId:t,agentId:r,state:s,progress:o})},onEvaluation:(t,r)=>{this.sendNotification("solo.evaluation",{soloId:t,winnerId:r.winnerId,reasoning:r.reasoning})},onAgentDelta:(t,r,s)=>{this.sendNotification("solo.agentDelta",{soloId:t,agentId:r,text:s})},onAgentDiff:(t,r,s)=>{this.sendNotification("solo.agentDiff",{soloId:t,agentId:r,files:s})},onAgentUsage:(t,r,s,o)=>{this.sendNotification("solo.agentUsage",{soloId:t,agentId:r,inputTokens:s,outputTokens:o})}};this.soloEvaluator=new fo(n,this.acpDetector,this.agentConfigStore,e),this.soloProcessManager=n}return this.soloEvaluator}async function bh(n){try{let e=n.params;if(!e?.task||!e?.agents||!e?.cwd){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:"task, agents, and cwd are required."});return}if(!e.projectId){let o=Oe();o&&(e.projectId=o.id)}let t=Ye.call(this),r=await t.start(e),s=t.getStatus(r);n.id!==void 0&&this.sendResponse(n.id,s)}catch(e){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:e instanceof Error?e.message:String(e)})}}async function vh(n){try{let e=n.params;if(!e?.soloId){this.soloEvaluator?n.id!==void 0&&this.sendResponse(n.id,this.soloEvaluator.listSessions()):n.id!==void 0&&this.sendResponse(n.id,[]);return}let r=Ye.call(this).getStatus(e.soloId);if(!r){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:`Solo session ${e.soloId} not found.`});return}n.id!==void 0&&this.sendResponse(n.id,r)}catch(e){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:e instanceof Error?e.message:String(e)})}}async function kh(n){try{let e=n.params;if(!e?.soloId){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:"soloId is required."});return}await Ye.call(this).cancel(e.soloId),n.id!==void 0&&this.sendResponse(n.id,{ok:!0})}catch(e){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:e instanceof Error?e.message:String(e)})}}async function Sh(n){try{let e=n.params;if(!e?.soloId||!e?.winnerId){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:"soloId and winnerId are required."});return}let r=await Ye.call(this).select(e);n.id!==void 0&&this.sendResponse(n.id,{ok:!0,mergedBranch:r})}catch(e){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:e instanceof Error?e.message:String(e)})}}function Th(n){try{this.soloEvaluator?n.id!==void 0&&this.sendResponse(n.id,this.soloEvaluator.listSessions()):n.id!==void 0&&this.sendResponse(n.id,[])}catch(e){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:e instanceof Error?e.message:String(e)})}}async function Rh(n){try{let e=n.params;if(!e?.soloId){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:"soloId is required."});return}await Ye.call(this).delete(e.soloId),n.id!==void 0&&this.sendResponse(n.id,{ok:!0})}catch(e){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:e instanceof Error?e.message:String(e)})}}async function Ah(n){try{let e=n.params;if(!e?.soloId||!e?.agentId||!e?.content){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:"soloId, agentId, and content are required."});return}let r=await Ye.call(this).message(e.soloId,e.agentId,e.content,e.agentIndex);n.id!==void 0&&this.sendResponse(n.id,r)}catch(e){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:e instanceof Error?e.message:String(e)})}}async function wh(n){try{let e=n.params;if(!e?.soloId||!e?.evaluatorAgentId){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:"soloId and evaluatorAgentId are required."});return}let r=await Ye.call(this).triggerEvaluation(e.soloId,e.evaluatorAgentId,e.evaluatorIndex);n.id!==void 0&&this.sendResponse(n.id,r)}catch(e){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:e instanceof Error?e.message:String(e)})}}ae();import*as se from"node:fs";import*as be from"node:path";function xh(n){try{let e=se.readFileSync(n,"utf8"),t=e.match(/^---\n[\s\S]*?^version:\s*(\S+)/m),r=e.match(/^---\n[\s\S]*?^description:\s*(.+)/m);return{version:t?.[1],description:r?.[1]?.trim()}}catch{return{}}}function Ph(n){let t=n.params?.projectId,r=this.getActiveProjectRoot();if(t&&this.projectLocator){let a=this.projectLocator.resolveProjectRoot(t);a&&(r=a)}let s=r?Tt(r):void 0,o=Dt(),i=[];if(s&&se.existsSync(s))for(let a of se.readdirSync(s)){let c=be.join(s,a);if(!se.statSync(c).isDirectory())continue;let l=be.join(c,"SKILL.md"),d=be.join(c,"SKILL.md.disabled"),u=se.existsSync(l)?l:null;if(u||se.existsSync(d)){let p=u?xh(u):{};i.push({name:a,path:c,active:!!u,scope:"project",version:p.version,description:p.description})}}if(se.existsSync(o))for(let a of se.readdirSync(o)){let c=be.join(o,a);try{if(!se.statSync(c).isDirectory())continue}catch{continue}let l=be.join(c,"SKILL.md"),d=be.join(c,"SKILL.md.disabled"),u=se.existsSync(l)?l:null;if(u||se.existsSync(d)){let p=u?xh(u):{};i.push({name:a,path:c,active:!!u,scope:"global",version:p.version,description:p.description})}}n.id!==void 0&&this.sendResponse(n.id,{skills:i})}function Ih(n){let t=n.params?.name;if(!t){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:"Missing required param: name"});return}let r=this.getActiveProjectRoot(),s=r?Tt(r):void 0;if(!s){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:"No active project workspace"});return}let o=be.join(s,t),i=be.join(o,"SKILL.md.disabled"),a=be.join(o,"SKILL.md");if(se.existsSync(a)){n.id!==void 0&&this.sendResponse(n.id,{ok:!0,already:!0});return}if(se.existsSync(i))try{se.renameSync(i,a);let c=q(),l=Be(c),d=qt(l,t);d.state!=="active"&&(d.state="active",d.staleAt=void 0,d.archivedAt=void 0),We(c,l),n.id!==void 0&&this.sendResponse(n.id,{ok:!0}),this.sendNotification("skills.updated",{action:"activate",name:t})}catch(c){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:`Failed to activate skill: ${c instanceof Error?c.message:c}`})}else n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:`Skill "${t}" not found`})}function _h(n){let t=n.params?.name;if(!t){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:"Missing required param: name"});return}let r=this.getActiveProjectRoot(),s=r?Tt(r):void 0;if(!s){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:"No active project workspace"});return}let o=be.join(s,t),i=be.join(o,"SKILL.md"),a=be.join(o,"SKILL.md.disabled");if(!se.existsSync(i)){n.id!==void 0&&this.sendResponse(n.id,{ok:!0,already:!0});return}try{se.renameSync(i,a),n.id!==void 0&&this.sendResponse(n.id,{ok:!0}),this.sendNotification("skills.updated",{action:"deactivate",name:t})}catch(c){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:`Failed to deactivate skill: ${c instanceof Error?c.message:c}`})}}function Eh(n){let e=n.params,t=e?.name;if(!t||/[\/\\]|\.\./.test(t)){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:"Missing or invalid skill name"});return}let r=q(),s=Be(r);if(s.records[t]?.pinned){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:`Skill "${t}" is pinned. Unpin it first.`});return}let o=e?.scope??"project",i;if(o==="global")i=be.join(Dt(),t);else{let a=this.getActiveProjectRoot(),c=a?Tt(a):void 0;if(!c){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:"No active project workspace"});return}i=be.join(c,t)}if(!se.existsSync(i)){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:`Skill "${t}" not found in ${o} scope`});return}try{se.rmSync(i,{recursive:!0,force:!0}),pt(),eo(s,t),We(r,s),n.id!==void 0&&this.sendResponse(n.id,{ok:!0,deleted:t,scope:o}),this.sendNotification("skills.updated",{action:"delete",name:t})}catch(a){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:`Failed to delete skill: ${a instanceof Error?a.message:a}`})}}function Ch(n){let e=n.params,t=e?.name;if(!t||/[\/\\]|\.\./.test(t)){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:"Missing or invalid skill name"});return}let r=this.getActiveProjectRoot(),s=r?Tt(r):void 0;if(!s){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:"No active project workspace"});return}let o=be.join(s,t),i=be.join(o,"SKILL.md");if(!se.existsSync(i)){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:`Skill "${t}" not found in project scope`});return}let a=Dt(),c=be.join(a,t);try{se.mkdirSync(c,{recursive:!0});let l=se.readdirSync(o);for(let d of l){let u=se.readFileSync(be.join(o,d));se.writeFileSync(be.join(c,d),u)}e?.keepLocal||se.rmSync(o,{recursive:!0,force:!0}),pt(),n.id!==void 0&&this.sendResponse(n.id,{ok:!0,promoted:t,globalPath:c,removedFromProject:!e?.keepLocal})}catch(l){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:`Failed to promote skill: ${l instanceof Error?l.message:l}`})}}function Mh(n){let e=n.params,t=q();if(e?.name){let r=Kg(t,e.name);n.id!==void 0&&this.sendResponse(n.id,{name:e.name,stats:r??null})}else{let r=Vg(t);n.id!==void 0&&this.sendResponse(n.id,{stats:r})}}function Nh(n){let e=n.params;if(!e?.name){n.id!==void 0&&this.sendResponse(n.id,null,{code:-32602,message:"Missing 'name' parameter"});return}let t=q(),r=Be(t);qt(r,e.name),Qg(r,e.name),We(t,r),n.id!==void 0&&this.sendResponse(n.id,{name:e.name,pinned:!0})}function Dh(n){let e=n.params;if(!e?.name){n.id!==void 0&&this.sendResponse(n.id,null,{code:-32602,message:"Missing 'name' parameter"});return}let t=q(),r=Be(t);Zg(r,e.name),We(t,r),n.id!==void 0&&this.sendResponse(n.id,{name:e.name,pinned:!1})}function Oh(n){let e=q(),t=this.getActiveProjectRoot(),r=t?be.join(t,".qlogicagent","skills"):be.join(e,"skills"),s=ef(e,r);s.transitioned.length>0&&pt(),n.id!==void 0&&this.sendResponse(n.id,s)}function Lh(n){let e=n.params,t=q(),r=Be(t);if(e?.name){let s=r.records[e.name]??null;n.id!==void 0&&this.sendResponse(n.id,{record:s})}else if(e?.state){let s=tf(r,e.state);n.id!==void 0&&this.sendResponse(n.id,{records:s})}else n.id!==void 0&&this.sendResponse(n.id,{records:Object.values(r.records)})}import*as z from"node:fs";import*as ue from"node:path";ae();function al(n){let e=q(),t=Me(n);z.existsSync(t)||z.mkdirSync(t,{recursive:!0});let r=ue.join(e,"INSTRUCTIONS.md"),s=ue.join(t,"INSTRUCTIONS.md");if(z.existsSync(r)&&!z.existsSync(s))try{z.copyFileSync(r,s)}catch{}let o=Ad(),i=wn(n);if(z.existsSync(o)&&!z.existsSync(i))try{z.mkdirSync(i,{recursive:!0});for(let a of z.readdirSync(o)){if(!a.endsWith(".md"))continue;let c=ue.join(o,a),l=ue.join(i,a);z.statSync(c).isFile()&&z.copyFileSync(c,l)}}catch{}}function $h(n){let e=n.params;if(!e?.name){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:"Missing required param: name"});return}let t=e.workspaceDir||ue.join(q(),"workspaces",e.name);if(e.groupId){let c=cs(e.groupId);if(c){n.id!==void 0&&this.sendResponse(n.id,{ok:!0,project:c,deduplicated:!0});return}}let s=me().find(c=>c.name===e.name);if(!z.existsSync(t))try{z.mkdirSync(t,{recursive:!0})}catch{n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:`Cannot create workspace directory: ${t}`});return}let o=as({name:e.name,workspaceDir:t,type:e.type??"personal",groupId:e.groupId,skipAutoSwitch:e.type==="solo"||e.type==="product"}),i=o.type==="solo"||o.type==="product";i||(ut(o.id),this.setActiveWorkdir(o.workspaceDir)),al(o.workspaceDir);let a=new Et(o.workspaceDir);if(a.ensureInitialized(),i||(this.memdir=a),i||this.mediaPersistence.setProjectDir(o.workspaceDir),o.type==="solo"){let c=ue.join(Me(o.workspaceDir),"solo-state.json");z.existsSync(c)||z.writeFileSync(c,JSON.stringify({agents:[],status:"idle",createdAt:new Date().toISOString()},null,2))}else if(o.type==="product"){let c=ue.join(Me(o.workspaceDir),"product-state.json");z.existsSync(c)||z.writeFileSync(c,JSON.stringify({tasks:[],instances:[],status:"idle",createdAt:new Date().toISOString()},null,2))}if(this.sendNotification("project.created",{id:o.id,name:o.name,workspaceDir:o.workspaceDir,type:o.type}),i||this.sendNotification("project.switched",{id:o.id,name:o.name,workspaceDir:o.workspaceDir}),n.id!==void 0){let c={ok:!0,project:o};s&&(c.warning=`\u5DF2\u5B58\u5728\u540C\u540D\u9879\u76EE\u300C${s.name}\u300D\uFF08\u4F4D\u4E8E ${s.workspaceDir}\uFF09\uFF0C\u5EFA\u8BAE\u4FEE\u6539\u540D\u79F0\u4EE5\u4FBF\u533A\u5206`),this.sendResponse(n.id,c)}}function jh(n){let e=me();n.id!==void 0&&this.sendResponse(n.id,{projects:e})}function Uh(n){let e=n.params;if(!e?.projectId){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:"Missing required param: projectId"});return}let t=ct(e.projectId),r=la(e.projectId);if(!r.deleted){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:"Cannot delete project (not found or is default project)"});return}let s=!1,o;if(t?.workspaceDir){let i=ue.join(q(),"workspaces"),a=ue.resolve(t.workspaceDir);if(a.startsWith(ue.resolve(i)+ue.sep)){try{this.mediaPersistence?.releaseProjectDir?.(a)}catch{}for(let c=0;c<3;c++)try{z.rmSync(a,{recursive:!0,force:!0}),s=!0;break}catch(l){if(c<2&&(l.code==="EBUSY"||l.code==="EPERM"||l.code==="ENOTEMPTY")){let d=Date.now();for(;Date.now()-d<200;);}else{o=l.message??String(l);break}}}else o="\u9879\u76EE\u76EE\u5F55\u4E0D\u5728\u6258\u7BA1\u76EE\u5F55\u4E0B\uFF0C\u4E0D\u4F1A\u81EA\u52A8\u5220\u9664"}this.sendNotification("project.deleted",{id:e.projectId}),r.switchedTo&&(this.setActiveWorkdir(r.switchedTo.workspaceDir),this.sendNotification("project.switched",{id:r.switchedTo.id,name:r.switchedTo.name,workspaceDir:r.switchedTo.workspaceDir})),n.id!==void 0&&this.sendResponse(n.id,{ok:!0,switchedTo:r.switchedTo,dirDeleted:s,dirDeleteError:o})}function Fh(n){let e=me(),t=ue.join(q(),"workspaces"),r=ue.resolve(t)+ue.sep,s=0,o=[];for(let a of e)if(a.type!=="default"){if(la(a.id),s++,a.workspaceDir){let c=ue.resolve(a.workspaceDir);try{this.mediaPersistence?.releaseProjectDir?.(c)}catch{}for(let l=0;l<3;l++)try{z.existsSync(c)&&z.rmSync(c,{recursive:!0,force:!0});break}catch(d){if(l<2&&(d.code==="EBUSY"||d.code==="EPERM"||d.code==="ENOTEMPTY")){let u=Date.now();for(;Date.now()-u<300;);}else{o.push(`${a.name}: ${d.message??d}`);break}}}this.sendNotification("project.deleted",{id:a.id})}if(z.existsSync(t)){let a=me().find(d=>d.type==="default"),c=new Set;a?.workspaceDir&&c.add(ue.resolve(a.workspaceDir));let l=d=>{try{let u=z.readdirSync(d,{withFileTypes:!0});for(let p of u){if(!p.isDirectory())continue;let m=ue.join(d,p.name);if(!c.has(ue.resolve(m))){if(p.name==="groups"){l(m);try{z.readdirSync(m).length===0&&z.rmdirSync(m)}catch{}continue}try{z.rmSync(m,{recursive:!0,force:!0})}catch(h){o.push(`orphan:${p.name}: ${h.message??h}`)}}}}catch{}};l(t)}let i=me().find(a=>a.type==="default");i&&(this.setActiveWorkdir(i.workspaceDir),this.sendNotification("project.switched",{id:i.id,name:i.name,workspaceDir:i.workspaceDir})),n.id!==void 0&&this.sendResponse(n.id,{ok:!0,deletedCount:s,dirErrors:o.length?o:void 0})}function Bh(n){let e=n.params;if(!e?.projectId||!e?.newName){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:"Missing required params: projectId, newName"});return}let t=fu(e.projectId,e.newName);if(!t){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:"Cannot rename project (not found, is default, or name already taken)"});return}let r=ue.join(q(),"workspaces"),s=ue.resolve(t.workspaceDir);if(s.startsWith(ue.resolve(r)+ue.sep)){let o=ue.join(r,e.newName);if(z.existsSync(s)&&!z.existsSync(o))try{z.renameSync(s,o),hu(e.projectId,o),t.workspaceDir=o,this.getActiveProjectRoot()===s&&this.setActiveWorkdir(o)}catch{}}this.sendNotification("project.renamed",{id:t.id,name:t.name,workspaceDir:t.workspaceDir}),n.id!==void 0&&this.sendResponse(n.id,{ok:!0,project:t})}function Hh(n){let e=n.params;if(!e?.projectId){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:"Missing required param: projectId"});return}let t=yu(e.projectId);if(!t.archived){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:"Cannot archive project (not found or is default project)"});return}this.sendNotification("project.archived",{id:e.projectId}),t.switchedTo&&(this.setActiveWorkdir(t.switchedTo.workspaceDir),this.sendNotification("project.switched",{id:t.switchedTo.id,name:t.switchedTo.name,workspaceDir:t.switchedTo.workspaceDir})),n.id!==void 0&&this.sendResponse(n.id,{ok:!0,switchedTo:t.switchedTo})}function qh(n){let e=n.params;if(!e?.projectId){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:"Missing required param: projectId"});return}let t=bu(e.projectId);if(!t){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:"Cannot unarchive project (not found or not archived)"});return}this.sendNotification("project.unarchived",{id:t.id,name:t.name,workspaceDir:t.workspaceDir}),n.id!==void 0&&this.sendResponse(n.id,{ok:!0,project:t})}function Wh(n){let e=n.params;if(!e?.groupId){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:"Missing required param: groupId"});return}let t=vu(e.groupId);if(!t.archived){n.id!==void 0&&this.sendResponse(n.id,{ok:!1,error:"No active project with this groupId"});return}this.sendNotification("project.deleted",{id:t.projectId}),t.switchedTo&&(this.setActiveWorkdir(t.switchedTo.workspaceDir),this.sendNotification("project.switched",{id:t.switchedTo.id,name:t.switchedTo.name,workspaceDir:t.switchedTo.workspaceDir})),n.id!==void 0&&this.sendResponse(n.id,{ok:!0,projectId:t.projectId})}function Gh(n){let e=n.params;if(!e?.projectId){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:"projectId is required"});return}let t={};"planStatus"in e&&(t.planStatus=e.planStatus),"planAgents"in e&&(t.planAgents=e.planAgents),"planWinnerId"in e&&(t.planWinnerId=e.planWinnerId),"leaderSessionId"in e&&(t.leaderSessionId=e.leaderSessionId);let r=mu(e.projectId,t);n.id!==void 0&&this.sendResponse(n.id,{ok:r})}import*as bt from"node:fs";import*as vt from"node:path";ae();je();import Je from"node:fs";import jr from"node:path";var Kh=bi,Vh=vi,ho=class{dir;constructor(e){this.dir=wn(e)}list(){if(!Je.existsSync(this.dir))return[];let e=[];for(let t of Je.readdirSync(this.dir)){if(!t.endsWith(".md"))continue;let r=jr.join(this.dir,t);try{let s=Je.statSync(r);if(!s.isFile())continue;let o=Je.readFileSync(r,"utf8");e.push({filename:t,content:o,sizeBytes:s.size})}catch{}}return e}read(e){if(!this.isValidFilename(e))return null;let t=jr.join(this.dir,e);if(!Je.existsSync(t))return null;try{let r=Je.readFileSync(t,"utf8"),s=Je.statSync(t);return{filename:e,content:r,sizeBytes:s.size}}catch{return null}}write(e,t){if(!this.isValidFilename(e))throw new Error("Invalid filename: must end with .md and contain no path separators");let r=Buffer.byteLength(t,"utf8");if(r>Kh)throw new Error(`File too large: ${r} bytes exceeds ${Kh} limit`);if(this.getDirSize(e)+r>Vh)throw new Error(`Total instructions size would exceed ${Vh} byte limit`);Je.mkdirSync(this.dir,{recursive:!0});let o=jr.join(this.dir,e);return Je.writeFileSync(o,t,"utf8"),{filename:e,content:t,sizeBytes:r}}remove(e){if(!this.isValidFilename(e))return!1;let t=jr.join(this.dir,e);return Je.existsSync(t)?(Je.unlinkSync(t),!0):!1}loadAll(){let e=this.list();return e.length===0?"":`<project-instructions>
|
|
953
953
|
${e.map(r=>`<!-- file: ${r.filename}>
|
|
954
954
|
${r.content}`).join(`
|
|
955
955
|
|
|
956
956
|
`)}
|
|
957
|
-
</project-instructions>`}isValidFilename(e){return!(!e.endsWith(".md")||e.includes("/")||e.includes("\\")||e.includes("..")||e.startsWith("."))}getDirSize(e){if(!Je.existsSync(this.dir))return 0;let t=0;for(let r of Je.readdirSync(this.dir)){if(r===e)continue;let s=jr.join(this.dir,r);try{let o=Je.statSync(s);o.isFile()&&(t+=o.size)}catch{}}return t}};ae();function bn(n){return ct(n)?.workspaceDir??null}function yo(n){return n?new ho(n):null}async function
|
|
958
|
-
`).filter(Boolean).map(i=>({path:i.slice(3),status:i.slice(0,2).trim()}));n.id!==void 0&&this.sendResponse(n.id,{files:o})}catch{n.id!==void 0&&this.sendResponse(n.id,{files:[]})}}function
|
|
957
|
+
</project-instructions>`}isValidFilename(e){return!(!e.endsWith(".md")||e.includes("/")||e.includes("\\")||e.includes("..")||e.startsWith("."))}getDirSize(e){if(!Je.existsSync(this.dir))return 0;let t=0;for(let r of Je.readdirSync(this.dir)){if(r===e)continue;let s=jr.join(this.dir,r);try{let o=Je.statSync(s);o.isFile()&&(t+=o.size)}catch{}}return t}};ae();function bn(n){return ct(n)?.workspaceDir??null}function yo(n){return n?new ho(n):null}async function zh(n){let e=n.params;if(!e?.projectId){n.id!==void 0&&this.sendResponse(n.id,{entries:[]});return}let t=bn(e.projectId);if(!t){n.id!==void 0&&this.sendResponse(n.id,{entries:[]});return}try{let r=e.path?vt.join(t,e.path):t,o=(await bt.promises.readdir(r,{withFileTypes:!0})).filter(i=>!i.name.startsWith(".")).map(i=>({name:i.name,path:e.path?`${e.path}/${i.name}`:i.name,type:i.isDirectory()?"directory":"file"}));n.id!==void 0&&this.sendResponse(n.id,{entries:o})}catch{n.id!==void 0&&this.sendResponse(n.id,{entries:[]})}}async function Xh(n){let e=n.params;if(!e?.projectId||!e?.path){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:"Missing required params: projectId, path"});return}let t=bn(e.projectId);if(!t){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:"Project not found"});return}let r=vt.join(t,e.path);if(!r.startsWith(t)){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:"Path escapes project directory"});return}try{e.type==="directory"?await bt.promises.mkdir(r,{recursive:!0}):(await bt.promises.mkdir(vt.dirname(r),{recursive:!0}),await bt.promises.writeFile(r,e.content??"","utf-8")),n.id!==void 0&&this.sendResponse(n.id,{ok:!0,path:e.path})}catch(s){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:`Failed to create: ${s.message}`})}}async function Yh(n){let e=n.params;if(!e?.projectId||!e?.oldPath||!e?.newName){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:"Missing required params: projectId, oldPath, newName"});return}let t=bn(e.projectId);if(!t){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:"Project not found"});return}let r=vt.join(t,e.oldPath),s=vt.join(vt.dirname(r),e.newName);if(!r.startsWith(t)||!s.startsWith(t)){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:"Path escapes project directory"});return}try{await bt.promises.rename(r,s);let o=vt.relative(t,s).replace(/\\/g,"/");n.id!==void 0&&this.sendResponse(n.id,{ok:!0,newPath:o})}catch(o){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:`Failed to rename: ${o.message}`})}}async function Jh(n){let e=n.params;if(!e?.projectId||!e?.path){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:"Missing required params: projectId, path"});return}let t=bn(e.projectId);if(!t){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:"Project not found"});return}let r=vt.join(t,e.path);if(!r.startsWith(t)){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:"Path escapes project directory"});return}try{await bt.promises.rm(r,{recursive:!0}),n.id!==void 0&&this.sendResponse(n.id,{ok:!0})}catch(s){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:`Failed to delete: ${s.message}`})}}async function Qh(n){let e=n.params;if(!e?.projectId){n.id!==void 0&&this.sendResponse(n.id,{files:[]});return}let t=bn(e.projectId);if(!t){n.id!==void 0&&this.sendResponse(n.id,{files:[]});return}try{let{execSync:r}=await import("node:child_process"),o=r("git statusporcelain",{cwd:t,encoding:"utf-8",timeout:5e3}).split(`
|
|
958
|
+
`).filter(Boolean).map(i=>({path:i.slice(3),status:i.slice(0,2).trim()}));n.id!==void 0&&this.sendResponse(n.id,{files:o})}catch{n.id!==void 0&&this.sendResponse(n.id,{files:[]})}}function Zh(n){let e=n.params,t;if(e?.projectId&&(t=bn(e.projectId)??void 0),t||(t=this.getActiveProjectRoot()),!t){n.id!==void 0&&this.sendResponse(n.id,{instructions:[]});return}let r=[],s=tr(t);try{let i=bt.statSync(s);i.isFile()&&r.push({name:"INSTRUCTIONS.md",path:"INSTRUCTIONS.md",size:i.size})}catch{}let o=yo(t);if(o)for(let i of o.list())r.push({name:i.filename,path:`rules/${i.filename}`,size:i.sizeBytes});n.id!==void 0&&this.sendResponse(n.id,{instructions:r})}function ey(n){let e=n.params;if(!e?.path){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:"Missing required param: path"});return}let t;if(e?.projectId&&(t=bn(e.projectId)??void 0),t||(t=this.getActiveProjectRoot()),!t){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:"No active project workspace"});return}if(e.path==="INSTRUCTIONS.md"){let i=tr(t);try{let a=bt.readFileSync(i,"utf8");this.sendResponse(n.id,{content:a,metadata:{filename:"INSTRUCTIONS.md",sizeBytes:Buffer.byteLength(a)}})}catch{this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:"Instruction file not found"})}return}let r=e.path.startsWith("rules/")?e.path.slice(6):e.path,s=yo(t);if(!s){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:"No active project workspace"});return}let o=s.read(r);if(!o){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:"Instruction file not found"});return}n.id!==void 0&&this.sendResponse(n.id,{content:o.content,metadata:{filename:o.filename,sizeBytes:o.sizeBytes}})}function ty(n){let e=n.params;if(!e?.path||typeof e?.content!="string"){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:"Missing required params: path, content"});return}let t=yo(this.getActiveProjectRoot());if(!t){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:"No active project workspace"});return}try{t.write(e.path,e.content),n.id!==void 0&&this.sendResponse(n.id,{ok:!0})}catch(r){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:r instanceof Error?r.message:String(r)})}}function ny(n){let e=n.params;if(!e?.path){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:"Missing required param: path"});return}let t=yo(this.getActiveProjectRoot());if(!t){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:"No active project workspace"});return}if(!t.remove(e.path)){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:"Instruction file not found"});return}n.id!==void 0&&this.sendResponse(n.id,{ok:!0})}import{randomUUID as sy}from"node:crypto";var v_=new Set(["fact","preference","insight","lesson","decision","plan","event","general"]);function vn(n,e,t,r){let s=typeof n=="number"&&Number.isFinite(n)?n:r;return Math.max(e,Math.min(t,s))}function jn(n){return typeof n=="string"&&v_.has(n)?n:"general"}function Un(n){if(!Array.isArray(n))return[];let e=new Set;for(let t of n){if(typeof t!="string")continue;let r=t.trim().replace(/\s+/g,"-").slice(0,48);r&&e.add(r)}return Array.from(e).slice(0,12)}function cl(n){let e=typeof n?.type=="string"?n.type:"file",t=typeof n?.filename=="string"&&n.filename.trim()?n.filename.trim():"attachment",r=typeof n?.mimeType=="string"?n.mimeType:"",s=typeof n?.text=="string"?n.text.slice(0,12e3):"",o=typeof n?.url=="string"?n.url:"",i=typeof n?.path=="string"?n.path:"",a=typeof n?.size=="number"&&Number.isFinite(n.size)?n.size:void 0;return{type:e,filename:t,mimeType:r,text:s,url:o,path:i,size:a}}function ll(n){let e=[`${n.type}:${n.filename}`];return n.mimeType&&e.push(n.mimeType),n.size&&e.push(`${n.size} bytes`),n.text&&e.push(`content=${n.text.slice(0,1500)}`),n.url&&e.push(`url=${n.url}`),n.path&&e.push(`path=${n.path}`),e.join(" | ")}function k_(n){let t=n.match(/```(?:json)?\s*([\s\S]*?)```/i)?.[1]??n,r=t.indexOf("{"),s=t.lastIndexOf("}");if(r<0||s<=r)return null;try{return JSON.parse(t.slice(r,s+1))}catch{return null}}async function S_(n,e,t){if(!n.memoryProvider||typeof n.memoryProvider.search!="function"||!e.trim())return[];try{return(await n.memoryProvider.search(e,t,{limit:5,minScore:.12})).map(s=>({id:s.blockId,text:s.text,score:typeof s.score=="number"?s.score:0,category:typeof s.metadata?.category=="string"?s.metadata.category:void 0})).filter(s=>s.id&&s.text)}catch{return[]}}function T_(n,e){let t=typeof n?.text=="string"?n.text.trim():"",r=Array.isArray(n?.attachments)?n.attachments.map(cl):[],s=r.map(ll).join(`
|
|
959
959
|
`),o=[t,s].filter(Boolean).join(`
|
|
960
960
|
|
|
961
|
-
`).trim();if(!o)return[];let i=Un([...n?.tags??[],...r.map(a=>`asset:${a.type}`),...r.map(a=>a.filename.split(".").slice(0,-1).join(".")||a.filename)]);return[{id:`candidate-${
|
|
961
|
+
`).trim();if(!o)return[];let i=Un([...n?.tags??[],...r.map(a=>`asset:${a.type}`),...r.map(a=>a.filename.split(".").slice(0,-1).join(".")||a.filename)]);return[{id:`candidate-${sy()}`,text:o.slice(0,1400),category:jn(n?.category),importance:vn(n?.importance,.1,1,r.length>0?.72:.62),confidence:.58,source:typeof n?.source=="string"&&n.source.trim()?n.source.trim():"manual",eventDate:"",tags:i,relatedMemoryIds:e.map(a=>a.id).slice(0,5),evidence:[...t?[{type:"text",excerpt:t.slice(0,500)}]:[],...r.map(a=>({type:a.type,filename:a.filename,mimeType:a.mimeType}))],requiresConfirmation:!0,reason:"\u5F85\u7528\u6237\u786E\u8BA4\u540E\u5199\u5165\u957F\u671F\u8BB0\u5FC6\u3002"}]}async function R_(n,e,t){let r=typeof n.resolveClientForPurpose=="function"?n.resolveClientForPurpose.bind(n):null,s=r?.("smallModel")??r?.("textGeneration")??null;if(!s)return null;let o=typeof e?.text=="string"?e.text.trim():"",i=Array.isArray(e?.attachments)?e.attachments.map(cl):[],a=i.map(ll).join(`
|
|
962
962
|
`),c=t.map((h,f)=>`${f+1}. [${h.id}] ${h.text}`).join(`
|
|
963
963
|
`),l=["\u4F60\u662F qlogicagent \u7684\u957F\u671F\u8BB0\u5FC6\u63D0\u53D6\u5668\u3002\u8BF7\u4ECE\u7528\u6237\u8F93\u5165\u548C\u9644\u4EF6\u6458\u8981\u4E2D\u63D0\u53D6\u503C\u5F97\u957F\u671F\u4FDD\u5B58\u7684\u8BB0\u5FC6\u3002","\u8981\u6C42\uFF1A","1. \u53EA\u4FDD\u5B58\u957F\u671F\u6709\u7528\u7684\u4FE1\u606F\uFF0C\u4E0D\u4FDD\u5B58\u4E34\u65F6\u5BD2\u6684\u548C\u4F4E\u4EF7\u503C\u788E\u7247\u3002","2. \u5982\u679C\u5185\u5BB9\u4E0E\u5DF2\u6709\u8BB0\u5FC6\u76F8\u5173\uFF0C\u628A relatedMemoryIds \u586B\u5165\u5BF9\u5E94 id\u3002","3. \u5BF9\u5BA2\u6237\u3001\u5408\u540C\u3001\u91D1\u989D\u3001\u8EAB\u4EFD\u3001\u8D26\u53F7\u3001\u9690\u79C1\u3001\u5546\u4E1A\u51B3\u7B56\u7C7B\u5185\u5BB9\uFF0CrequiresConfirmation \u5FC5\u987B\u4E3A true\u3002","4. category \u53EA\u80FD\u662F fact/preference/insight/lesson/decision/plan/event/general\u3002","5. \u8F93\u51FA JSON\uFF0C\u4E0D\u8981\u89E3\u91CA\u3002","","JSON \u683C\u5F0F\uFF1A",'{"memories":[{"text":"\u53EF\u76F4\u63A5\u5199\u5165\u957F\u671F\u8BB0\u5FC6\u7684\u4E00\u53E5\u8BDD","category":"event","importance":0.7,"confidence":0.8,"source":"manual","eventDate":"YYYY-MM-DD\u6216\u7A7A\u5B57\u7B26\u4E32","tags":["\u5BA2\u6237","\u5408\u540C"],"relatedMemoryIds":["..."],"requiresConfirmation":true,"reason":"\u4E3A\u4EC0\u4E48\u503C\u5F97\u8BB0\u4F4F"}]}',"",`\u7528\u6237\u8F93\u5165\uFF1A
|
|
964
964
|
${o||"(\u65E0)"}`,`\u9644\u4EF6\u6458\u8981\uFF1A
|
|
965
965
|
${a||"(\u65E0)"}`,`\u76F8\u5173\u65E7\u8BB0\u5FC6\uFF1A
|
|
966
966
|
${c||"(\u65E0)"}`].join(`
|
|
967
|
-
`),d="";try{for await(let h of s.transport.stream({model:s.model,messages:[{role:"user",content:l}],temperature:.1,maxTokens:900,tools:[]},s.apiKey))h.type==="delta"&&(d+=h.text)}catch{return null}let u=k_(d),m=(Array.isArray(u?.memories)?u.memories:[]).map(h=>({id:`candidate-${
|
|
968
|
-
`),t),i=e?.autoExtract===!1?null:await R_(n,e,o);return{candidates:i??T_(e,o),relatedMemories:o,extractor:i?"llm":"deterministic"}}async function A_(n,e,t){let r=0,s=0,o=0,i=0,a=0,c=[],l=[];for(let d of t){let u=typeof d?.text=="string"?d.text.trim():"";if(!u)continue;let p=Un([...d.tags??[],...(d.relatedMemoryIds??[]).map(f=>`related:${f}`)]),m={text:u,category:jn(d.category),importance:vn(d.importance,.1,1,.6),event_date:typeof d.eventDate=="string"?d.eventDate:"",tags:p};if(typeof n.memoryProvider.ingestExtracted!="function")throw new Error("Memory provider must expose the consolidation entrypoint ingestExtracted.");let h=await n.memoryProvider.ingestExtracted([m],e,{source:typeof d.source=="string"&&d.source.trim()?d.source.trim():"manual"});r+=h?.memoriesAdded??0,s+=h?.observationsAdded??0,o+=h?.proposalsAdded??0,i+=h?.claimsAdded??0,a+=h?.conflictsAdded??0,c.push(...h?.claimIds??[]),l.push(...h?.conflictIds??[])}return{memoriesAdded:r,observationsAdded:s,proposalsAdded:o,claimsAdded:i,conflictsAdded:a,claimIds:c,conflictIds:l}}function Fn(n,e){let r=(typeof e=="string"&&e.trim()?e:typeof n.memoryUserId=="string"&&n.memoryUserId.trim()?n.memoryUserId:"").trim();return r||null}function ny(){return{totalCount:0,records:[],buckets:[],clusters:[],windowCursor:null,timeRange:null,stats:{formed:0,insights:0,preferences:0}}}function w_(n,e){let t=0,r=0;for(let s of e??[])s?.kind==="category"&&((s.label==="insight"||s.label==="lesson")&&(t+=Number(s.count??0)),s.label==="preference"&&(r+=Number(s.count??0)));return{formed:n,insights:t,preferences:r}}async function oy(n){let e=[];this.memdir&&e.push({id:"memdir",type:"file",path:Oc(this.getActiveProjectRoot())}),this.memoryProvider&&e.push({id:"local",type:"vector"}),n.id!==void 0&&this.sendResponse(n.id,{sources:e})}async function iy(n){let e=n.params;if(this.ensureMemoryProvider?.(),!this.memoryProvider||typeof this.memoryProvider.getAtlas!="function"){n.id!==void 0&&this.sendResponse(n.id,ny());return}try{let t=Fn(this,e?.userId);if(!t){n.id!==void 0&&this.sendResponse(n.id,ny());return}let r=this.memoryProvider.getAtlas(t,{pageSize:e?.pageSize??360,windowStartAt:e?.windowStartAt,windowEndAt:e?.windowEndAt,windowCenterAt:e?.windowCenterAt,bucketCount:e?.bucketCount??96,clusterLimit:e?.clusterLimit??48,activeOnly:!0}),s=(r.records??[]).map(a=>({id:a.id,text:a.text,category:a.category,importance:a.importance,confidence:a.confidence,source:a.source,sessionId:a.sessionId,eventDate:a.eventDate,tags:a.tags,createdAt:a.createdAt,updatedAt:a.updatedAt,accessCount:a.accessCount,lastAccessedAt:a.lastAccessedAt,isArchived:a.isArchived})),o=Number(r.totalCount??s.length),i=r.clusters??[];n.id!==void 0&&this.sendResponse(n.id,{totalCount:o,records:s,buckets:r.buckets??[],clusters:i,windowCursor:r.windowCursor??null,timeRange:r.timeRange??null,stats:w_(o,i)})}catch(t){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:t instanceof Error?t.message:String(t)})}}async function ay(n){let e=n.params;if(this.ensureMemoryProvider?.(),!this.memoryProvider||typeof this.memoryProvider.getActivitySummary!="function"){n.id!==void 0&&this.sendResponse(n.id,{dailyCounts:[],highlights:[]});return}try{let t=Fn(this,e?.userId);if(!t){n.id!==void 0&&this.sendResponse(n.id,{dailyCounts:[],highlights:[]});return}let r=this.memoryProvider.getActivitySummary(t,e?.days??180);n.id!==void 0&&this.sendResponse(n.id,r)}catch(t){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:t instanceof Error?t.message:String(t)})}}async function cy(n){let e=n.params;if(this.ensureMemoryProvider?.(),!this.memoryProvider||typeof this.memoryProvider.observeExtracted!="function"){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:"Long-term memory provider does not support observations."});return}let t=typeof e?.text=="string"?e.text.trim():"";if(!t){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:"text is required."});return}let r=Fn(this,e?.userId);if(!r){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:"llmrouter user id is required for long-term memory."});return}try{let s=await this.memoryProvider.observeExtracted([{text:t,category:jn(e?.category),importance:vn(e?.importance,.1,1,.5),tags:Un(e?.tags??[])}],r,{source:e?.source??"turn"});n.id!==void 0&&this.sendResponse(n.id,{ok:!0,...s})}catch(s){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:s instanceof Error?s.message:String(s)})}}async function ly(n){let e=n.params;if(this.ensureMemoryProvider?.(),!this.memoryProvider||typeof this.memoryProvider.proposeExtracted!="function"){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:"Long-term memory provider does not support proposals."});return}let t=Fn(this,e?.userId);if(!t){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:"llmrouter user id is required for long-term memory."});return}try{let r=await sy(this,e??{},t),s=r.candidates.map(i=>({text:typeof i?.text=="string"?i.text.trim():"",category:jn(i.category),importance:vn(i.importance,.1,1,.6),event_date:typeof i.eventDate=="string"?i.eventDate:"",tags:Un([...i.tags??[],...(i.relatedMemoryIds??[]).map(a=>`related:${a}`)])})).filter(i=>i.text),o=await this.memoryProvider.proposeExtracted(s,t,{source:e?.source??"manual"});n.id!==void 0&&this.sendResponse(n.id,{ok:!0,candidates:r.candidates,relatedMemories:r.relatedMemories,extractor:r.extractor,...o})}catch(r){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:r instanceof Error?r.message:String(r)})}}async function dy(n){let e=n.params;if(this.ensureMemoryProvider?.(),!this.memoryProvider||typeof this.memoryProvider.ingestExtracted!="function"){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:"Long-term memory provider is not initialized."});return}let t=Fn(this,e?.userId);if(!t){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:"llmrouter user id is required for long-term memory."});return}let r=Array.isArray(e?.candidates)?e.candidates:[],s=typeof e?.text=="string"?e.text.trim():"",o=Array.isArray(e?.attachments)?e.attachments:[];if(r.length===0&&!s&&o.length===0){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:"candidates, text, or attachments are required."});return}try{if(r.length===0){let a=await sy(this,{...e,text:s,source:typeof e?.source=="string"&&e.source.trim()?e.source.trim():"manual",autoExtract:e?.autoExtract??!0},t);r.push(...a.candidates)}if(r.length===0){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:"no memory candidates were produced."});return}let i=await A_(this,t,r);n.id!==void 0&&this.sendResponse(n.id,{ok:!0,...i}),this.sendNotification?.("memory.updated",{source:"local",target:"atlas"})}catch(i){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:i instanceof Error?i.message:String(i)})}}async function uy(n){let e=n.params,t=e?.source??"memdir",r=e?.target??"index";if(t==="memdir"||t==="local"){if(!this.memdir){n.id!==void 0&&this.sendResponse(n.id,{source:"memdir",target:r,content:""});return}try{if(r==="index"){let s=this.memdir.getIndexRaw();n.id!==void 0&&this.sendResponse(n.id,{source:"memdir",target:"index",content:s})}else{let s=await this.memdir.readFile(r);n.id!==void 0&&this.sendResponse(n.id,{source:"memdir",target:r,content:s.content??""})}}catch{n.id!==void 0&&this.sendResponse(n.id,{source:"memdir",target:r,content:""})}}else n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:`Unknown memory source: ${t}`})}async function py(n){let e=n.params,t=e?.target??"index",r=e?.content;if(r==null){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:"content is required."});return}if(!this.memdir){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:"Memory system not initialized."});return}try{if(t==="index"){let s=await this.memdir.addToIndex(r);n.id!==void 0&&this.sendResponse(n.id,{ok:s.ok,target:"index",message:s.message})}else{let s=await this.memdir.writeFile(t,r);n.id!==void 0&&this.sendResponse(n.id,{ok:s.ok,target:t,message:s.message})}this.sendNotification("memory.updated",{target:t,source:"rpc"})}catch(s){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:s instanceof Error?s.message:String(s)})}}async function my(n){let e=n.params;if(!e?.query){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:"query is required."});return}if(this.memoryProvider){let t=Fn(this,e.userId);if(!t){n.id!==void 0&&this.sendResponse(n.id,{results:[]});return}try{let r=await this.memoryProvider.search(e.query,t,{limit:e.limit??10});n.id!==void 0&&this.sendResponse(n.id,{results:r.map(s=>({id:s.blockId??"",text:s.text,score:s.score,source:"local",metadata:s.metadata}))})}catch(r){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:r instanceof Error?r.message:String(r)})}}else if(this.memdir)try{let t=await this.memdir.searchLocal(e.query);n.id!==void 0&&this.sendResponse(n.id,{results:t.slice(0,e.limit??10).map((r,s)=>({id:`memdir-${s}`,text:r.snippet,score:r.score,source:"memdir",metadata:{file:r.file}}))})}catch{n.id!==void 0&&this.sendResponse(n.id,{results:[]})}else n.id!==void 0&&this.sendResponse(n.id,{results:[]})}async function gy(n){let e=n.params;if(!e?.match){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:"match is required."});return}let t=e.source??"memdir";if(t==="memdir"||t==="local"){if(!this.memdir){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:"Memory system not initialized."});return}let r=e.target??"index";try{if(r==="index"){let s=await this.memdir.removeFromIndex(e.match);n.id!==void 0&&this.sendResponse(n.id,{ok:s.ok,removedCount:s.ok?1:0,message:s.message}),s.ok&&this.sendNotification("memory.updated",{source:"memdir",target:"index"})}else{let s=await this.memdir.deleteFile(r);n.id!==void 0&&this.sendResponse(n.id,{ok:s.ok,removedCount:s.ok?1:0,message:s.message}),s.ok&&this.sendNotification("memory.updated",{source:"memdir",target:r})}}catch(s){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:s instanceof Error?s.message:String(s)})}}else if(t==="vector"&&this.memoryProvider)try{await this.memoryProvider.remove(e.match),n.id!==void 0&&this.sendResponse(n.id,{ok:!0,removedCount:1,message:"Removed from local memory."}),this.sendNotification("memory.updated",{source:"local"})}catch(r){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:r instanceof Error?r.message:String(r)})}else n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:`Unknown or unavailable source: ${t}`})}async function fy(n){let e=n.params,t=typeof e?.id=="string"?e.id.trim():"";if(!t){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:"id is required."});return}if(this.ensureMemoryProvider?.(),!this.memoryProvider||typeof this.memoryProvider.update!="function"){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:"Long-term memory provider does not support updates."});return}try{let r=await this.memoryProvider.update(t,{text:typeof e?.text=="string"?e.text:void 0,category:typeof e?.category=="string"?jn(e.category):void 0,importance:typeof e?.importance=="number"?vn(e.importance,.1,1,.6):void 0,source:typeof e?.source=="string"?e.source.trim().slice(0,80):void 0,eventDate:typeof e?.eventDate=="string"?e.eventDate.trim().slice(0,32):void 0,tags:Array.isArray(e?.tags)?Un(e.tags):void 0});n.id!==void 0&&this.sendResponse(n.id,{ok:r,updated:r?1:0}),r&&this.sendNotification("memory.updated",{source:"local",target:"atlas"})}catch(r){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:r instanceof Error?r.message:String(r)})}}ae();dt();import*as Ct from"node:fs";import*as dl from"node:path";je();function hy(n){let e=n.params,r=wt(e?.includeDeferred??!1).map(s=>({name:s.function.name,description:s.function.description??"",parameters:s.function.parameters,source:"builtin"}));if(e?.category){let s=r.filter(o=>o.name.startsWith(e.category)||o.description.toLowerCase().includes(e.category.toLowerCase()));n.id!==void 0&&this.sendResponse(n.id,{tools:s,total:s.length})}else n.id!==void 0&&this.sendResponse(n.id,{tools:r,total:r.length})}function yy(n){let e=Y().listProviderDefs(),t=new Map;for(let s of e){let o=s.group??s.id;t.has(o)||t.set(o,[]);let i=!!Y().resolveProviderApiKey(s.id);t.get(o).push({id:s.id,name:s.name,transport:s.transport,baseUrl:s.baseUrl,defaultModel:s.defaultModel,modelCount:s.models?.length??0,available:i})}let r=[...t.entries()].map(([s,o])=>({group:s,variants:o}));n.id!==void 0&&this.sendResponse(n.id,{providers:r})}function by(n){try{let t=Y().exportConfig(),r=it(),s={};try{s=JSON.parse(Ct.readFileSync(r,"utf-8"))}catch{}n.id!==void 0&&this.sendResponse(n.id,{config:{providers:t.providers,models:t.models,bindings:t.bindings,permissions:s.permissions,permissionMode:s.permissionMode,permissionRules:s.permissionRules,defaultBehavior:s.defaultBehavior},paths:{userSettings:it(),agentHome:q()}})}catch(e){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:e instanceof Error?e.message:String(e)})}}var x_=new Set(["providers","models","bindings","provider","model","apiKey","baseUrl","providerKeys"]);async function vy(n){let e=n.params;if(!e?.updates||typeof e.updates!="object"){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:"updates (object) is required."});return}let t=[],r={};for(let[s,o]of Object.entries(e.updates))x_.has(s)?t.push({key:s,reason:"Use settings.* RPC methods for model/key management"}):r[s]=o;if(t.length>0&&Object.keys(r).length===0){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:`Rejected keys: ${t.map(s=>s.key).join(", ")}. Use settings.* RPC for model management.`});return}try{let s=it(),o={};try{let i=await Ct.promises.readFile(s,"utf-8");o=JSON.parse(i)}catch{}Object.assign(o,r),await Ct.promises.mkdir(dl.dirname(s),{recursive:!0}),await Ct.promises.writeFile(s,JSON.stringify(o,null,2),"utf-8"),n.id!==void 0&&this.sendResponse(n.id,{ok:!0,applied:Object.keys(r),rejected:t})}catch(s){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:s instanceof Error?s.message:String(s)})}}function ky(n){try{let e=_i(),t=it(),r={};try{let s=Ct.readFileSync(t,"utf-8"),o=JSON.parse(s);o.tunables&&typeof o.tunables=="object"&&(r=o.tunables)}catch{}n.id!==void 0&&this.sendResponse(n.id,{defaults:e,overrides:r})}catch(e){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:e instanceof Error?e.message:String(e)})}}async function Sy(n){let e=n.params,t=e?.key,r=e?.value;if(!t||typeof t!="string"){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:"Missing required param: key (string)"});return}let s=_i();if(!(t in s)){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:`Unknown tunable key: "${t}". Valid keys: ${Object.keys(s).join(", ")}`});return}let o=typeof s[t];if(r==null||typeof r!==o){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:`Invalid value for "${t}": expected ${o}, got ${typeof r}`});return}try{let i=it(),a={};try{let c=await Ct.promises.readFile(i,"utf-8");a=JSON.parse(c)}catch{}(!a.tunables||typeof a.tunables!="object")&&(a.tunables={}),a.tunables[t]=r,await Ct.promises.mkdir(dl.dirname(i),{recursive:!0}),await Ct.promises.writeFile(i,JSON.stringify(a,null,2),"utf-8"),t==="teamBudgetTokens"&&typeof r=="number"&&(Re.teamBudget.budgetTokens=r),n.id!==void 0&&this.sendResponse(n.id,{ok:!0,key:t,value:r})}catch(i){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:i instanceof Error?i.message:String(i)})}}async function Ty(n){let e=tt("task");if(!e){n.id!==void 0&&this.sendResponse(n.id,{items:[],summary:dr([])});return}try{let s=(await e.execute("rpc-todos-list",{action:"list"},void 0)).details?.taskList??[];n.id!==void 0&&this.sendResponse(n.id,{items:s,summary:dr(s)})}catch{n.id!==void 0&&this.sendResponse(n.id,{items:[],summary:dr([])})}}function Ry(n){let t=n.params?.lifecycle??"all",r=this.taskStore.getAllTasks(),s=t==="all"?r:r.filter(o=>o.lifecycle===t);n.id!==void 0&&this.sendResponse(n.id,{tasks:s.map(o=>({taskId:o.taskId,type:o.type,lifecycle:o.lifecycle,label:o.label}))})}function Ay(n){let e=n.params;if(!e?.taskId){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:"taskId is required."});return}let r=this.taskStore.getAllTasks().find(s=>s.taskId===e.taskId);if(!r){n.id!==void 0&&this.sendResponse(n.id,{ok:!1,message:`Task ${e.taskId} not found.`});return}if(r.lifecycle!=="running"&&r.lifecycle!=="pending"){n.id!==void 0&&this.sendResponse(n.id,{ok:!1,message:`Task ${e.taskId} is already ${r.lifecycle}.`});return}this.taskStore.updateTask(e.taskId,s=>(s.lifecycle="cancelled",s)),n.id!==void 0&&this.sendResponse(n.id,{ok:!0,message:`Task ${e.taskId} cancelled.`})}ae();import*as wy from"node:fs";import*as bo from"node:path";import{randomUUID as P_}from"node:crypto";async function xy(n){try{let e=n.params,t=await this.ensureAgentConfigStore();this.acpDetector.setConfigStore(t.getData());let r=this.acpDetector.scan(e?.force);n.id!==void 0&&this.sendResponse(n.id,r)}catch(e){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:e instanceof Error?e.message:String(e)})}}async function Py(n){try{let e=await this.ensureAgentConfigStore();this.acpDetector.setConfigStore(e.getData());let t=this.acpDetector.list();n.id!==void 0&&this.sendResponse(n.id,t)}catch(e){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:e instanceof Error?e.message:String(e)})}}async function Iy(n){try{let e=n.params;if(!e?.action||!e?.agent){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:"action and agent are required."});return}let t=await this.ensureAgentConfigStore();switch(e.action){case"register":t.registerCustomAgent(e.agent);break;case"unregister":t.unregisterCustomAgent(e.agent.id);break;case"update":t.registerCustomAgent(e.agent);break}this.acpDetector.setConfigStore(t.getData()),this.acpDetector.clearCache(),n.id!==void 0&&this.sendResponse(n.id,{ok:!0})}catch(e){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:e instanceof Error?e.message:String(e)})}}async function _y(n){try{let e=n.params;if(!e?.agentId){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:"agentId is required."});return}let t=await this.ensureAgentConfigStore(),{agentId:r,...s}=e;await t.setAgentConfig(r,s),this.acpDetector.setConfigStore(t.getData()),n.id!==void 0&&this.sendResponse(n.id,{ok:!0})}catch(e){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:e instanceof Error?e.message:String(e)})}}async function Ey(n){try{let e=n.params;if(!e?.agentId){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:"agentId is required."});return}let r=(await this.ensureAgentConfigStore()).getAgentConfig(e.agentId);n.id!==void 0&&this.sendResponse(n.id,r)}catch(e){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:e instanceof Error?e.message:String(e)})}}async function Cy(n){try{let e=n.params;if(!e?.agentId){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:"agentId is required."});return}let t=await this.ensureAgentConfigStore();await t.removeAgentConfig(e.agentId),this.acpDetector.setConfigStore(t.getData()),n.id!==void 0&&this.sendResponse(n.id,{ok:!0})}catch(e){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:e instanceof Error?e.message:String(e)})}}async function My(n){try{let e=n.params;if(!e?.url){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:"url is required."});return}await(await this.ensureAgentConfigStore()).setGatewayUrl(e.url),n.id!==void 0&&this.sendResponse(n.id,{ok:!0})}catch(e){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:e instanceof Error?e.message:String(e)})}}async function Ny(n){try{let t=(await this.ensureAgentConfigStore()).getGatewayUrl();n.id!==void 0&&this.sendResponse(n.id,{url:t})}catch(e){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:e instanceof Error?e.message:String(e)})}}async function Dy(n){try{let t=(await this.ensureAgentConfigStore()).getData(),r=Object.entries(t.agents).map(([s,o])=>({agentId:s,hasApiKey:!!o.apiKey,hasBaseUrl:!!o.baseUrl,hasModel:!!o.model}));n.id!==void 0&&this.sendResponse(n.id,r)}catch(e){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:e instanceof Error?e.message:String(e)})}}function Oy(n){try{let e=[],t=(r,s)=>{if(r)for(let o of r.getAllHandles())e.push({memberId:o.memberId,name:o.name,pid:o.pid,state:o.state,startedAt:o.startedAt,endedAt:o.endedAt,source:s})};t(this.soloProcessManager,"solo"),t(this.productProcessManager,"product"),n.id!==void 0&&this.sendResponse(n.id,e)}catch(e){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:e instanceof Error?e.message:String(e)})}}function Ly(n){try{let e=n.params;if(!e?.memberId){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:"memberId is required."});return}let t=!1;for(let r of[this.soloProcessManager,this.productProcessManager])if(r?.getHandle(e.memberId)){r.kill(e.memberId),t=!0;break}n.id!==void 0&&this.sendResponse(n.id,{ok:t})}catch(e){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:e instanceof Error?e.message:String(e)})}}async function $y(n){try{let e=n.params;if(!e?.agentId){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:"agentId is required."});return}let t=bo.join(q(),"agent-logs"),r=bo.join(t,`${e.agentId}.stderr.log`),s="";try{s=wy.readFileSync(r,"utf-8")}catch{}e.tail&&e.tail>0&&s&&(s=s.split(`
|
|
967
|
+
`),d="";try{for await(let h of s.transport.stream({model:s.model,messages:[{role:"user",content:l}],temperature:.1,maxTokens:900,tools:[]},s.apiKey))h.type==="delta"&&(d+=h.text)}catch{return null}let u=k_(d),m=(Array.isArray(u?.memories)?u.memories:[]).map(h=>({id:`candidate-${sy()}`,text:typeof h?.text=="string"?h.text.trim().slice(0,1400):"",category:jn(h?.category),importance:vn(h?.importance,.1,1,.65),confidence:vn(h?.confidence,.05,1,.65),source:typeof h?.source=="string"&&h.source.trim()?h.source.trim().slice(0,80):"manual",eventDate:typeof h?.eventDate=="string"?h.eventDate.trim().slice(0,32):"",tags:Un(h?.tags),relatedMemoryIds:Array.isArray(h?.relatedMemoryIds)?h.relatedMemoryIds.filter(f=>typeof f=="string").slice(0,8):[],evidence:[...o?[{type:"text",excerpt:o.slice(0,500)}]:[],...i.map(f=>({type:f.type,filename:f.filename,mimeType:f.mimeType}))],requiresConfirmation:h?.requiresConfirmation!==!1,reason:typeof h?.reason=="string"?h.reason.trim().slice(0,300):""})).filter(h=>h.text.length>=6);return m.length>0?m:null}async function oy(n,e,t){let r=typeof e?.text=="string"?e.text.trim():"",s=Array.isArray(e?.attachments)?e.attachments.map(cl):[],o=await S_(n,[r,...s.map(ll)].join(`
|
|
968
|
+
`),t),i=e?.autoExtract===!1?null:await R_(n,e,o);return{candidates:i??T_(e,o),relatedMemories:o,extractor:i?"llm":"deterministic"}}async function A_(n,e,t){let r=0,s=0,o=0,i=0,a=0,c=[],l=[];for(let d of t){let u=typeof d?.text=="string"?d.text.trim():"";if(!u)continue;let p=Un([...d.tags??[],...(d.relatedMemoryIds??[]).map(f=>`related:${f}`)]),m={text:u,category:jn(d.category),importance:vn(d.importance,.1,1,.6),event_date:typeof d.eventDate=="string"?d.eventDate:"",tags:p};if(typeof n.memoryProvider.ingestExtracted!="function")throw new Error("Memory provider must expose the consolidation entrypoint ingestExtracted.");let h=await n.memoryProvider.ingestExtracted([m],e,{source:typeof d.source=="string"&&d.source.trim()?d.source.trim():"manual"});r+=h?.memoriesAdded??0,s+=h?.observationsAdded??0,o+=h?.proposalsAdded??0,i+=h?.claimsAdded??0,a+=h?.conflictsAdded??0,c.push(...h?.claimIds??[]),l.push(...h?.conflictIds??[])}return{memoriesAdded:r,observationsAdded:s,proposalsAdded:o,claimsAdded:i,conflictsAdded:a,claimIds:c,conflictIds:l}}function Fn(n,e){let r=(typeof e=="string"&&e.trim()?e:typeof n.memoryUserId=="string"&&n.memoryUserId.trim()?n.memoryUserId:"").trim();return r||null}function ry(){return{totalCount:0,records:[],buckets:[],clusters:[],windowCursor:null,timeRange:null,stats:{formed:0,insights:0,preferences:0}}}function w_(n,e){let t=0,r=0;for(let s of e??[])s?.kind==="category"&&((s.label==="insight"||s.label==="lesson")&&(t+=Number(s.count??0)),s.label==="preference"&&(r+=Number(s.count??0)));return{formed:n,insights:t,preferences:r}}async function iy(n){let e=[];this.memdir&&e.push({id:"memdir",type:"file",path:Oc(this.getActiveProjectRoot())}),this.memoryProvider&&e.push({id:"local",type:"vector"}),n.id!==void 0&&this.sendResponse(n.id,{sources:e})}async function ay(n){let e=n.params;if(this.ensureMemoryProvider?.(),!this.memoryProvider||typeof this.memoryProvider.getAtlas!="function"){n.id!==void 0&&this.sendResponse(n.id,ry());return}try{let t=Fn(this,e?.userId);if(!t){n.id!==void 0&&this.sendResponse(n.id,ry());return}let r=this.memoryProvider.getAtlas(t,{pageSize:e?.pageSize??360,windowStartAt:e?.windowStartAt,windowEndAt:e?.windowEndAt,windowCenterAt:e?.windowCenterAt,bucketCount:e?.bucketCount??96,clusterLimit:e?.clusterLimit??48,activeOnly:!0}),s=(r.records??[]).map(a=>({id:a.id,text:a.text,category:a.category,importance:a.importance,confidence:a.confidence,source:a.source,sessionId:a.sessionId,eventDate:a.eventDate,tags:a.tags,createdAt:a.createdAt,updatedAt:a.updatedAt,accessCount:a.accessCount,lastAccessedAt:a.lastAccessedAt,isArchived:a.isArchived})),o=Number(r.totalCount??s.length),i=r.clusters??[];n.id!==void 0&&this.sendResponse(n.id,{totalCount:o,records:s,buckets:r.buckets??[],clusters:i,windowCursor:r.windowCursor??null,timeRange:r.timeRange??null,stats:w_(o,i)})}catch(t){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:t instanceof Error?t.message:String(t)})}}async function cy(n){let e=n.params;if(this.ensureMemoryProvider?.(),!this.memoryProvider||typeof this.memoryProvider.getActivitySummary!="function"){n.id!==void 0&&this.sendResponse(n.id,{dailyCounts:[],highlights:[]});return}try{let t=Fn(this,e?.userId);if(!t){n.id!==void 0&&this.sendResponse(n.id,{dailyCounts:[],highlights:[]});return}let r=this.memoryProvider.getActivitySummary(t,e?.days??180);n.id!==void 0&&this.sendResponse(n.id,r)}catch(t){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:t instanceof Error?t.message:String(t)})}}async function ly(n){let e=n.params;if(this.ensureMemoryProvider?.(),!this.memoryProvider||typeof this.memoryProvider.observeExtracted!="function"){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:"Long-term memory provider does not support observations."});return}let t=typeof e?.text=="string"?e.text.trim():"";if(!t){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:"text is required."});return}let r=Fn(this,e?.userId);if(!r){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:"llmrouter user id is required for long-term memory."});return}try{let s=await this.memoryProvider.observeExtracted([{text:t,category:jn(e?.category),importance:vn(e?.importance,.1,1,.5),tags:Un(e?.tags??[])}],r,{source:e?.source??"turn"});n.id!==void 0&&this.sendResponse(n.id,{ok:!0,...s})}catch(s){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:s instanceof Error?s.message:String(s)})}}async function dy(n){let e=n.params;if(this.ensureMemoryProvider?.(),!this.memoryProvider||typeof this.memoryProvider.proposeExtracted!="function"){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:"Long-term memory provider does not support proposals."});return}let t=Fn(this,e?.userId);if(!t){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:"llmrouter user id is required for long-term memory."});return}try{let r=await oy(this,e??{},t),s=r.candidates.map(i=>({text:typeof i?.text=="string"?i.text.trim():"",category:jn(i.category),importance:vn(i.importance,.1,1,.6),event_date:typeof i.eventDate=="string"?i.eventDate:"",tags:Un([...i.tags??[],...(i.relatedMemoryIds??[]).map(a=>`related:${a}`)])})).filter(i=>i.text),o=await this.memoryProvider.proposeExtracted(s,t,{source:e?.source??"manual"});n.id!==void 0&&this.sendResponse(n.id,{ok:!0,candidates:r.candidates,relatedMemories:r.relatedMemories,extractor:r.extractor,...o})}catch(r){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:r instanceof Error?r.message:String(r)})}}async function uy(n){let e=n.params;if(this.ensureMemoryProvider?.(),!this.memoryProvider||typeof this.memoryProvider.ingestExtracted!="function"){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:"Long-term memory provider is not initialized."});return}let t=Fn(this,e?.userId);if(!t){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:"llmrouter user id is required for long-term memory."});return}let r=Array.isArray(e?.candidates)?e.candidates:[],s=typeof e?.text=="string"?e.text.trim():"",o=Array.isArray(e?.attachments)?e.attachments:[];if(r.length===0&&!s&&o.length===0){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:"candidates, text, or attachments are required."});return}try{if(r.length===0){let a=await oy(this,{...e,text:s,source:typeof e?.source=="string"&&e.source.trim()?e.source.trim():"manual",autoExtract:e?.autoExtract??!0},t);r.push(...a.candidates)}if(r.length===0){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:"no memory candidates were produced."});return}let i=await A_(this,t,r);n.id!==void 0&&this.sendResponse(n.id,{ok:!0,...i}),this.sendNotification?.("memory.updated",{source:"local",target:"atlas"})}catch(i){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:i instanceof Error?i.message:String(i)})}}async function py(n){let e=n.params,t=e?.source??"memdir",r=e?.target??"index";if(t==="memdir"||t==="local"){if(!this.memdir){n.id!==void 0&&this.sendResponse(n.id,{source:"memdir",target:r,content:""});return}try{if(r==="index"){let s=this.memdir.getIndexRaw();n.id!==void 0&&this.sendResponse(n.id,{source:"memdir",target:"index",content:s})}else{let s=await this.memdir.readFile(r);n.id!==void 0&&this.sendResponse(n.id,{source:"memdir",target:r,content:s.content??""})}}catch{n.id!==void 0&&this.sendResponse(n.id,{source:"memdir",target:r,content:""})}}else n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:`Unknown memory source: ${t}`})}async function my(n){let e=n.params,t=e?.target??"index",r=e?.content;if(r==null){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:"content is required."});return}if(!this.memdir){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:"Memory system not initialized."});return}try{if(t==="index"){let s=await this.memdir.addToIndex(r);n.id!==void 0&&this.sendResponse(n.id,{ok:s.ok,target:"index",message:s.message})}else{let s=await this.memdir.writeFile(t,r);n.id!==void 0&&this.sendResponse(n.id,{ok:s.ok,target:t,message:s.message})}this.sendNotification("memory.updated",{target:t,source:"rpc"})}catch(s){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:s instanceof Error?s.message:String(s)})}}async function gy(n){let e=n.params;if(!e?.query){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:"query is required."});return}if(this.memoryProvider){let t=Fn(this,e.userId);if(!t){n.id!==void 0&&this.sendResponse(n.id,{results:[]});return}try{let r=await this.memoryProvider.search(e.query,t,{limit:e.limit??10});n.id!==void 0&&this.sendResponse(n.id,{results:r.map(s=>({id:s.blockId??"",text:s.text,score:s.score,source:"local",metadata:s.metadata}))})}catch(r){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:r instanceof Error?r.message:String(r)})}}else if(this.memdir)try{let t=await this.memdir.searchLocal(e.query);n.id!==void 0&&this.sendResponse(n.id,{results:t.slice(0,e.limit??10).map((r,s)=>({id:`memdir-${s}`,text:r.snippet,score:r.score,source:"memdir",metadata:{file:r.file}}))})}catch{n.id!==void 0&&this.sendResponse(n.id,{results:[]})}else n.id!==void 0&&this.sendResponse(n.id,{results:[]})}async function fy(n){let e=n.params;if(!e?.match){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:"match is required."});return}let t=e.source??"memdir";if(t==="memdir"||t==="local"){if(!this.memdir){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:"Memory system not initialized."});return}let r=e.target??"index";try{if(r==="index"){let s=await this.memdir.removeFromIndex(e.match);n.id!==void 0&&this.sendResponse(n.id,{ok:s.ok,removedCount:s.ok?1:0,message:s.message}),s.ok&&this.sendNotification("memory.updated",{source:"memdir",target:"index"})}else{let s=await this.memdir.deleteFile(r);n.id!==void 0&&this.sendResponse(n.id,{ok:s.ok,removedCount:s.ok?1:0,message:s.message}),s.ok&&this.sendNotification("memory.updated",{source:"memdir",target:r})}}catch(s){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:s instanceof Error?s.message:String(s)})}}else if(t==="vector"&&this.memoryProvider)try{await this.memoryProvider.remove(e.match),n.id!==void 0&&this.sendResponse(n.id,{ok:!0,removedCount:1,message:"Removed from local memory."}),this.sendNotification("memory.updated",{source:"local"})}catch(r){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:r instanceof Error?r.message:String(r)})}else n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:`Unknown or unavailable source: ${t}`})}async function hy(n){let e=n.params,t=typeof e?.id=="string"?e.id.trim():"";if(!t){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:"id is required."});return}if(this.ensureMemoryProvider?.(),!this.memoryProvider||typeof this.memoryProvider.update!="function"){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:"Long-term memory provider does not support updates."});return}try{let r=await this.memoryProvider.update(t,{text:typeof e?.text=="string"?e.text:void 0,category:typeof e?.category=="string"?jn(e.category):void 0,importance:typeof e?.importance=="number"?vn(e.importance,.1,1,.6):void 0,source:typeof e?.source=="string"?e.source.trim().slice(0,80):void 0,eventDate:typeof e?.eventDate=="string"?e.eventDate.trim().slice(0,32):void 0,tags:Array.isArray(e?.tags)?Un(e.tags):void 0});n.id!==void 0&&this.sendResponse(n.id,{ok:r,updated:r?1:0}),r&&this.sendNotification("memory.updated",{source:"local",target:"atlas"})}catch(r){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:r instanceof Error?r.message:String(r)})}}ae();dt();import*as Ct from"node:fs";import*as dl from"node:path";je();function yy(n){let e=n.params,r=wt(e?.includeDeferred??!1).map(s=>({name:s.function.name,description:s.function.description??"",parameters:s.function.parameters,source:"builtin"}));if(e?.category){let s=r.filter(o=>o.name.startsWith(e.category)||o.description.toLowerCase().includes(e.category.toLowerCase()));n.id!==void 0&&this.sendResponse(n.id,{tools:s,total:s.length})}else n.id!==void 0&&this.sendResponse(n.id,{tools:r,total:r.length})}function by(n){let e=Y().listProviderDefs(),t=new Map;for(let s of e){let o=s.group??s.id;t.has(o)||t.set(o,[]);let i=!!Y().resolveProviderApiKey(s.id);t.get(o).push({id:s.id,name:s.name,transport:s.transport,baseUrl:s.baseUrl,defaultModel:s.defaultModel,modelCount:s.models?.length??0,available:i})}let r=[...t.entries()].map(([s,o])=>({group:s,variants:o}));n.id!==void 0&&this.sendResponse(n.id,{providers:r})}function vy(n){try{let t=Y().exportConfig(),r=it(),s={};try{s=JSON.parse(Ct.readFileSync(r,"utf-8"))}catch{}n.id!==void 0&&this.sendResponse(n.id,{config:{providers:t.providers,models:t.models,bindings:t.bindings,permissions:s.permissions,permissionMode:s.permissionMode,permissionRules:s.permissionRules,defaultBehavior:s.defaultBehavior},paths:{userSettings:it(),agentHome:q()}})}catch(e){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:e instanceof Error?e.message:String(e)})}}var x_=new Set(["providers","models","bindings","provider","model","apiKey","baseUrl","providerKeys"]);async function ky(n){let e=n.params;if(!e?.updates||typeof e.updates!="object"){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:"updates (object) is required."});return}let t=[],r={};for(let[s,o]of Object.entries(e.updates))x_.has(s)?t.push({key:s,reason:"Use settings.* RPC methods for model/key management"}):r[s]=o;if(t.length>0&&Object.keys(r).length===0){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:`Rejected keys: ${t.map(s=>s.key).join(", ")}. Use settings.* RPC for model management.`});return}try{let s=it(),o={};try{let i=await Ct.promises.readFile(s,"utf-8");o=JSON.parse(i)}catch{}Object.assign(o,r),await Ct.promises.mkdir(dl.dirname(s),{recursive:!0}),await Ct.promises.writeFile(s,JSON.stringify(o,null,2),"utf-8"),n.id!==void 0&&this.sendResponse(n.id,{ok:!0,applied:Object.keys(r),rejected:t})}catch(s){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:s instanceof Error?s.message:String(s)})}}function Sy(n){try{let e=_i(),t=it(),r={};try{let s=Ct.readFileSync(t,"utf-8"),o=JSON.parse(s);o.tunables&&typeof o.tunables=="object"&&(r=o.tunables)}catch{}n.id!==void 0&&this.sendResponse(n.id,{defaults:e,overrides:r})}catch(e){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:e instanceof Error?e.message:String(e)})}}async function Ty(n){let e=n.params,t=e?.key,r=e?.value;if(!t||typeof t!="string"){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:"Missing required param: key (string)"});return}let s=_i();if(!(t in s)){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:`Unknown tunable key: "${t}". Valid keys: ${Object.keys(s).join(", ")}`});return}let o=typeof s[t];if(r==null||typeof r!==o){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:`Invalid value for "${t}": expected ${o}, got ${typeof r}`});return}try{let i=it(),a={};try{let c=await Ct.promises.readFile(i,"utf-8");a=JSON.parse(c)}catch{}(!a.tunables||typeof a.tunables!="object")&&(a.tunables={}),a.tunables[t]=r,await Ct.promises.mkdir(dl.dirname(i),{recursive:!0}),await Ct.promises.writeFile(i,JSON.stringify(a,null,2),"utf-8"),t==="teamBudgetTokens"&&typeof r=="number"&&(Re.teamBudget.budgetTokens=r),n.id!==void 0&&this.sendResponse(n.id,{ok:!0,key:t,value:r})}catch(i){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:i instanceof Error?i.message:String(i)})}}async function Ry(n){let e=tt("task");if(!e){n.id!==void 0&&this.sendResponse(n.id,{items:[],summary:dr([])});return}try{let s=(await e.execute("rpc-todos-list",{action:"list"},void 0)).details?.taskList??[];n.id!==void 0&&this.sendResponse(n.id,{items:s,summary:dr(s)})}catch{n.id!==void 0&&this.sendResponse(n.id,{items:[],summary:dr([])})}}function Ay(n){let t=n.params?.lifecycle??"all",r=this.taskStore.getAllTasks(),s=t==="all"?r:r.filter(o=>o.lifecycle===t);n.id!==void 0&&this.sendResponse(n.id,{tasks:s.map(o=>({taskId:o.taskId,type:o.type,lifecycle:o.lifecycle,label:o.label}))})}function wy(n){let e=n.params;if(!e?.taskId){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:"taskId is required."});return}let r=this.taskStore.getAllTasks().find(s=>s.taskId===e.taskId);if(!r){n.id!==void 0&&this.sendResponse(n.id,{ok:!1,message:`Task ${e.taskId} not found.`});return}if(r.lifecycle!=="running"&&r.lifecycle!=="pending"){n.id!==void 0&&this.sendResponse(n.id,{ok:!1,message:`Task ${e.taskId} is already ${r.lifecycle}.`});return}this.taskStore.updateTask(e.taskId,s=>(s.lifecycle="cancelled",s)),n.id!==void 0&&this.sendResponse(n.id,{ok:!0,message:`Task ${e.taskId} cancelled.`})}ae();import*as xy from"node:fs";import*as bo from"node:path";import{randomUUID as P_}from"node:crypto";async function Py(n){try{let e=n.params,t=await this.ensureAgentConfigStore();this.acpDetector.setConfigStore(t.getData());let r=this.acpDetector.scan(e?.force);n.id!==void 0&&this.sendResponse(n.id,r)}catch(e){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:e instanceof Error?e.message:String(e)})}}async function Iy(n){try{let e=await this.ensureAgentConfigStore();this.acpDetector.setConfigStore(e.getData());let t=this.acpDetector.list();n.id!==void 0&&this.sendResponse(n.id,t)}catch(e){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:e instanceof Error?e.message:String(e)})}}async function _y(n){try{let e=n.params;if(!e?.action||!e?.agent){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:"action and agent are required."});return}let t=await this.ensureAgentConfigStore();switch(e.action){case"register":t.registerCustomAgent(e.agent);break;case"unregister":t.unregisterCustomAgent(e.agent.id);break;case"update":t.registerCustomAgent(e.agent);break}this.acpDetector.setConfigStore(t.getData()),this.acpDetector.clearCache(),n.id!==void 0&&this.sendResponse(n.id,{ok:!0})}catch(e){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:e instanceof Error?e.message:String(e)})}}async function Ey(n){try{let e=n.params;if(!e?.agentId){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:"agentId is required."});return}let t=await this.ensureAgentConfigStore(),{agentId:r,...s}=e;await t.setAgentConfig(r,s),this.acpDetector.setConfigStore(t.getData()),n.id!==void 0&&this.sendResponse(n.id,{ok:!0})}catch(e){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:e instanceof Error?e.message:String(e)})}}async function Cy(n){try{let e=n.params;if(!e?.agentId){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:"agentId is required."});return}let r=(await this.ensureAgentConfigStore()).getAgentConfig(e.agentId);n.id!==void 0&&this.sendResponse(n.id,r)}catch(e){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:e instanceof Error?e.message:String(e)})}}async function My(n){try{let e=n.params;if(!e?.agentId){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:"agentId is required."});return}let t=await this.ensureAgentConfigStore();await t.removeAgentConfig(e.agentId),this.acpDetector.setConfigStore(t.getData()),n.id!==void 0&&this.sendResponse(n.id,{ok:!0})}catch(e){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:e instanceof Error?e.message:String(e)})}}async function Ny(n){try{let e=n.params;if(!e?.url){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:"url is required."});return}await(await this.ensureAgentConfigStore()).setGatewayUrl(e.url),n.id!==void 0&&this.sendResponse(n.id,{ok:!0})}catch(e){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:e instanceof Error?e.message:String(e)})}}async function Dy(n){try{let t=(await this.ensureAgentConfigStore()).getGatewayUrl();n.id!==void 0&&this.sendResponse(n.id,{url:t})}catch(e){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:e instanceof Error?e.message:String(e)})}}async function Oy(n){try{let t=(await this.ensureAgentConfigStore()).getData(),r=Object.entries(t.agents).map(([s,o])=>({agentId:s,hasApiKey:!!o.apiKey,hasBaseUrl:!!o.baseUrl,hasModel:!!o.model}));n.id!==void 0&&this.sendResponse(n.id,r)}catch(e){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:e instanceof Error?e.message:String(e)})}}function Ly(n){try{let e=[],t=(r,s)=>{if(r)for(let o of r.getAllHandles())e.push({memberId:o.memberId,name:o.name,pid:o.pid,state:o.state,startedAt:o.startedAt,endedAt:o.endedAt,source:s})};t(this.soloProcessManager,"solo"),t(this.productProcessManager,"product"),n.id!==void 0&&this.sendResponse(n.id,e)}catch(e){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:e instanceof Error?e.message:String(e)})}}function $y(n){try{let e=n.params;if(!e?.memberId){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:"memberId is required."});return}let t=!1;for(let r of[this.soloProcessManager,this.productProcessManager])if(r?.getHandle(e.memberId)){r.kill(e.memberId),t=!0;break}n.id!==void 0&&this.sendResponse(n.id,{ok:t})}catch(e){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:e instanceof Error?e.message:String(e)})}}async function jy(n){try{let e=n.params;if(!e?.agentId){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:"agentId is required."});return}let t=bo.join(q(),"agent-logs"),r=bo.join(t,`${e.agentId}.stderr.log`),s="";try{s=xy.readFileSync(r,"utf-8")}catch{}e.tail&&e.tail>0&&s&&(s=s.split(`
|
|
969
969
|
`).slice(-e.tail).join(`
|
|
970
|
-
`)),n.id!==void 0&&this.sendResponse(n.id,{log:s})}catch(e){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:e instanceof Error?e.message:String(e)})}}async function
|
|
970
|
+
`)),n.id!==void 0&&this.sendResponse(n.id,{log:s})}catch(e){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:e instanceof Error?e.message:String(e)})}}async function Uy(n){try{let e=n.params;if(!e?.agentId){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:"agentId is required."});return}let t=await this.ensureAgentConfigStore();this.acpDetector.setConfigStore(t.getData());let s=this.acpDetector.list().find(i=>i.id===e.agentId);if(!s){n.id!==void 0&&this.sendResponse(n.id,{ok:!1,error:`Agent ${e.agentId} not found`,durationMs:0});return}if(s.status==="not_installed"){n.id!==void 0&&this.sendResponse(n.id,{ok:!1,error:`Agent ${e.agentId} is not installed`,durationMs:0});return}let o=Date.now();n.id!==void 0&&this.sendResponse(n.id,{ok:s.status==="available",version:s.version,capabilities:s.capabilities,error:s.status!=="available"?`Agent status: ${s.status}`:void 0,durationMs:Date.now()-o})}catch(e){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:e instanceof Error?e.message:String(e)})}}async function Fy(n){let e=null,t="";try{let r=n.params??{},s=typeof r.agentId=="string"?r.agentId.trim():"",o=typeof r.prompt=="string"?r.prompt:"";if(!s||!o.trim()){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:"agentId and prompt are required."});return}let i=await this.ensureAgentConfigStore();this.acpDetector.setConfigStore(i.getData()),this.acpDetector.scan(!1);let a=this.acpDetector.buildExternalDescriptor(s);if(!a){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:`Agent ${s} is not available or not ACP-compatible.`});return}let c=typeof r.cwd=="string"&&r.cwd?r.cwd:typeof this.getActiveProjectRoot=="function"?this.getActiveProjectRoot():process.cwd(),l=typeof r.timeoutMs=="number"&&r.timeoutMs>0?r.timeoutMs:3e5;t=`chat-${s}-${P_().slice(0,8)}`;let d=[];e=new _t({onNotification:(h,f,y)=>{if(f!=="turn.delta")return;let b=typeof y?.text=="string"?y.text:"";b&&d.push(b)},onMcpToolCall:async(h,f,y)=>typeof this.handleMcpToolCall=="function"?this.handleMcpToolCall(h,f,y):{ok:!1,error:"MCP tool call unavailable"},log:{info:h=>this.log?.(`[agents.prompt] ${h}`),warn:h=>this.log?.(`[agents.prompt] WARN: ${h}`),debug:h=>this.log?.(`[agents.prompt] ${h}`)},sessionDir:bo.join(q(),"agent-logs")}),await e.spawn({memberId:t,name:`chat-${s}`,cwd:c,prompt:o,external:a,systemPrompt:typeof r.systemPrompt=="string"?r.systemPrompt:void 0});let u=await e.sendTask(t,o,{timeout:l}),p=d.join("")||(typeof u?.content=="string"?u.content:""),m=e.getUsageTracker(t)?.getUsage();n.id!==void 0&&this.sendResponse(n.id,{ok:!0,agentId:s,content:p,stopReason:u?.stopReason,usage:m?{inputTokens:m.inputTokens,outputTokens:m.outputTokens,totalTokens:m.totalTokens,cacheRead:m.cachedReadTokens,thoughtTokens:m.thoughtTokens,cost:m.cost}:void 0})}catch(r){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:r instanceof Error?r.message:String(r)})}finally{if(e&&t){try{e.kill(t)}catch{}try{e.dispose()}catch{}}}}import{isAsyncMediaTransport as By}from"@xiaozhiclaw/provider-core";dt();async function Hy(n){try{if(!this.mediaClient){n.id!==void 0&&this.sendResponse(n.id,{models:[]});return}let e=await this.mediaClient.listModels();n.id!==void 0&&this.sendResponse(n.id,{models:e})}catch(e){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:e instanceof Error?e.message:String(e)})}}async function qy(n){let e=n.params;if(!e?.taskId){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:"taskId is required."});return}try{if(!this.mediaClient||!By(this.mediaClient)){n.id!==void 0&&this.sendResponse(n.id,{ok:!1,message:"Media client does not support async cancel."});return}await this.mediaClient.cancel(e.taskId),n.id!==void 0&&this.sendResponse(n.id,{ok:!0})}catch(t){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:t instanceof Error?t.message:String(t)})}}async function Wy(n){let e=n.params;if(!e?.taskId){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:"taskId is required."});return}try{if(!this.mediaClient||!By(this.mediaClient)){n.id!==void 0&&this.sendResponse(n.id,{status:"unknown",message:"Media client does not support status queries."});return}let t=await this.mediaClient.queryStatus(e.taskId);n.id!==void 0&&this.sendResponse(n.id,t)}catch(t){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:t instanceof Error?t.message:String(t)})}}async function Gy(n){let e=n.params;if(!e?.audioBase64){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:"audioBase64 is required."});return}let r=Y().getActiveModel("stt");if(!r){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:"STT not configured. Add an STT model and bind it in settings."});return}let{apiKey:s,model:o,baseUrl:i,keyHandle:a}=r;if(!i){a.release({success:!1}),n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:"STT baseUrl not configured. Set baseUrl on the STT model entry."});return}try{let c=`----STTBoundary${Date.now()}`,l=[];l.push(`--${c}\r
|
|
971
971
|
Content-Disposition: form-data; name="model"\r
|
|
972
972
|
\r
|
|
973
973
|
${o}`),l.push(`--${c}\r
|
|
@@ -978,13 +978,13 @@ Content-Disposition: form-data; name="prompt"\r
|
|
|
978
978
|
\r
|
|
979
979
|
\u8BF7\u7528${e.language==="zh"?"\u4E2D\u6587":"\u82F1\u6587"}\u8F6C\u5F55`),l.push(`--${c}--`);let d=l.join(`\r
|
|
980
980
|
`)+`\r
|
|
981
|
-
`,u=await fetch(i,{method:"POST",headers:{Authorization:`Bearer ${s}`,"Content-Type":`multipart/form-data; boundary=${c}`},body:d});if(!u.ok){let m=await u.text();a.release({success:!1,errorCode:u.status}),n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:`STT API error (${u.status}): ${m.slice(0,200)}`});return}let p=await u.json();a.release({success:!0}),n.id!==void 0&&this.sendResponse(n.id,{text:p.text??"",model:p.model})}catch(c){a.release({success:!1}),n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:c instanceof Error?c.message:String(c)})}}dt();function I_(n){return n.length<=8?"****":`${n.slice(0,3)}***${n.slice(-4)}`}function lt(n,e,t,r=v.INTERNAL_ERROR){if(e.id!==void 0){if(typeof n.sendError=="function"){n.sendError(e.id,r,t);return}n.sendResponse(e.id,void 0,{code:r,message:t})}}function vo(n,e){lt(n,e,Xs)}function __(n){let e={};for(let t of n)for(let r of t.purposes)e[r]??=[],e[r].push(t);return e}async function ul(){let n=Y(),e=await _r(n);return n.save(),e}async function Gy(n){try{let e=(await Ys()).map(t=>({id:t.id,displayName:Fc(t),baseUrl:Js(t)??"",modelCount:t.models?.length??0}));n.id!==void 0&&this.sendResponse(n.id,{providers:e})}catch{vo(this,n)}}async function Ky(n){let e=n.params;if(!e?.providerId||!e?.key){lt(this,n,"Required: providerId (string), key (string)",v.INVALID_PARAMS);return}let{providerId:t,key:r,label:s}=e;try{let o=await Bc(t);if(!o){lt(this,n,`Unknown provider: ${t}`,v.INVALID_PARAMS);return}let i=Y();if(i.getProviderStatus(t)?.keys.some(l=>l.key===r)){n.id!==void 0&&this.sendResponse(n.id,{ok:!1,error:"\u8BE5 Key \u5DF2\u5B58\u5728\uFF0C\u65E0\u9700\u91CD\u590D\u6DFB\u52A0"});return}i.addProvider(t,{baseUrl:Js(o)});let c=i.addKey(t,r,{label:s});await ul();for(let l of rr)if(!i.getBinding(l)){let d=i.listModels({purpose:l,provider:t,enabledOnly:!0});d.length>0&&i.setBinding(l,d[0].id)}i.setKeyHealth(c,"healthy"),i.save(),n.id!==void 0&&this.sendResponse(n.id,{ok:!0,keyId:c,providerId:t})}catch(o){let i=o instanceof Error?o.message:Xs;lt(this,n,i)}}function Vy(n){let e=n.params;if(!e?.keyId){lt(this,n,"Required: keyId (string)",v.INVALID_PARAMS);return}let t=Y();t.removeKey(e.keyId),t.save(),n.id!==void 0&&this.sendResponse(n.id,{ok:!0})}function zy(n){let e=n.params;if(!e?.keyId||typeof e.enabled!="boolean"){lt(this,n,"Required: keyId (string), enabled (boolean)",v.INVALID_PARAMS);return}let t=Y();t.updateKey(e.keyId,{enabled:e.enabled}),t.save(),n.id!==void 0&&this.sendResponse(n.id,{ok:!0})}function Xy(n){let e=n.params;if(!e?.modelId||typeof e.enabled!="boolean"){lt(this,n,"Required: modelId (string), enabled (boolean)",v.INVALID_PARAMS);return}let t=Y();e.enabled?t.enableModel(e.modelId):t.disableModel(e.modelId),t.save(),n.id!==void 0&&this.sendResponse(n.id,{ok:!0})}async function Yy(n){let e=n.params;try{await ul();let t=Y(),r=new Set(t.getAllProviderStatus().filter(o=>o.keys.length>0).map(o=>o.providerId)),s=t.listModels({purpose:e?.purpose,provider:e?.provider}).filter(o=>t.hasConfiguredKeyForProviderVariant(o.provider));n.id!==void 0&&this.sendResponse(n.id,{models:s,grouped:__(s),configuredProviderIds:[...r]})}catch{vo(this,n)}}function Jy(n){let e=n.params;if(!e?.purpose||!e?.modelId){lt(this,n,"Required: purpose (string), modelId (string)",v.INVALID_PARAMS);return}try{let t=Y();t.setBinding(e.purpose,e.modelId),t.save(),n.id!==void 0&&this.sendResponse(n.id,{ok:!0})}catch(t){lt(this,n,t instanceof Error?t.message:String(t),v.INVALID_PARAMS)}}function Qy(n){let e=n.params;if(!e?.purpose){lt(this,n,"Required: purpose (string)",v.INVALID_PARAMS);return}let t=Y(),r=t.getBinding(e.purpose);n.id!==void 0&&this.sendResponse(n.id,{model:r?{id:r.id,provider:r.provider,model:r.model,displayName:r.displayName,purposes:r.purposes,enabled:r.enabled}:null,available:t.isAvailable(e.purpose)})}async function Zy(n){try{let e=await Ys(),t=new Map(e.map(a=>[a.id,Fc(a)]));await ul();let r=Y(),s=r.getAllProviderStatus().map(a=>({providerId:a.providerId,displayName:t.get(a.providerId)??a.providerId,baseUrl:a.baseUrl,keyCount:a.keys.length,healthyKeys:a.keys.filter(c=>c.healthStatus==="healthy"&&c.enabled).length,totalKeys:a.keys.length,keys:a.keys.map(c=>({id:c.id,label:c.label,maskedKey:I_(c.key),enabled:c.enabled,health:c.healthStatus}))})),o=r.getAllBindings(),i={};for(let a of rr){let c=o[a];i[a]={bound:!!c,modelId:c?.id,modelName:c?.displayName,available:r.isAvailable(a)}}n.id!==void 0&&this.sendResponse(n.id,{providers:s,purposes:i})}catch{vo(this,n)}}async function eb(n){try{let e=Y();e.load(),await _r(e),e.save(),n.id!==void 0&&this.sendResponse(n.id,{ok:!0,catalogRefreshed:!0})}catch{vo(this,n)}}async function tb(n){let e=n.params;if(!e?.providerId||!e?.apiKey){lt(this,n,"providerId and apiKey required",v.INVALID_PARAMS);return}try{let t=await Bc(e.providerId),r=e.baseUrl||(t?Js(t):void 0);if(!r){lt(this,n,`Unknown provider: ${e.providerId}`,v.INVALID_PARAMS);return}let s=`${r.replace(/\/$/,"")}/models`,o=await fetch(s,{method:"GET",headers:{Authorization:`Bearer ${e.apiKey}`},signal:AbortSignal.timeout(1e4)});if(o.ok){n.id!==void 0&&this.sendResponse(n.id,{valid:!0,status:o.status});return}let i=await o.text().catch(()=>"");n.id!==void 0&&this.sendResponse(n.id,{valid:!1,status:o.status,error:i.slice(0,500)})}catch(t){let r=t instanceof Error?t.message:String(t);n.id!==void 0&&this.sendResponse(n.id,{valid:!1,status:0,error:r})}}wo();To();fl();Ro();Ao();function Tl(n){let e=Ee.getNextAbility(n.level);return{level:n.level,experience:n.experience,xpNeeded:Ee.xpForLevel(n.level),abilities:Ee.getUnlockedAbilities(n.level).map(t=>t.name),nextAbility:e?{name:e.name,level:e.unlockedAtLevel}:void 0}}async function fb(n){let e=n.params,t=this.getActiveProjectRoot(),r=new Zt(t),s=r.load();if(s){this.sendNotification("pet.soul_ready",{name:s.name,species:s.species,personality:s.personality,catchphrase:s.catchphrase,stats:s.stats,rarity:s.rarity,breed:s.breed,breedColors:s.breedColors}),n.id!==void 0&&this.sendResponse(n.id,{ok:!0,soul:s,growth:Tl(s)});return}let o=this.deviceId??"default-user";try{let i=this.createPetSoulGenerator?.(),a=await r.hatch(o,i,e?.breed);this.sendNotification("pet.soul_ready",{name:a.name,species:a.species,personality:a.personality,catchphrase:a.catchphrase,stats:a.stats,rarity:a.rarity,breed:a.breed,breedColors:a.breedColors}),this.sendNotification("pet.growth",{level:a.level,experience:a.experience,xpNeeded:Ee.xpForLevel(a.level),abilities:Ee.getUnlockedAbilities(a.level).map(c=>c.name)}),n.id!==void 0&&this.sendResponse(n.id,{ok:!0,soul:a,growth:Tl(a)})}catch(i){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:i.message??"Failed to hatch pet"})}}async function hb(n){let t=n.params?.action??"pat",r=this.getActiveProjectRoot(),s=new Zt(r),o=s.load();if(!o){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:"Pet not hatched yet"});return}let i=Ee.xpForEvent(`interact.${t}`),{newLevel:a,newXp:c,events:l,statBoosts:d}=Ee.processXpGain(o,i);o.level=a,o.experience=c;for(let[b,k]of Object.entries(d)){let A=b;o.stats[A]=Math.min(10,o.stats[A]+(k??0))}s.updateSoul(o),this.sendNotification("pet.state",{state:"happy"});let u=Ee.getUnlockedAbilities(a).map(b=>b.name),p=Ee.getNextAbility(a);this.sendNotification("pet.growth",{level:a,experience:c,xpNeeded:Ee.xpForLevel(a),abilities:u,nextAbility:p?{name:p.name,level:p.unlockedAtLevel}:void 0});for(let b of l)b.type==="molt"?this.sendNotification("pet.reaction",{text:`\u2728 \u8131\u58F3\u4E86\uFF01\u7B2C ${b.moltStage} \u6B21\u8715\u53D8`,style:"excited"}):b.type==="ability_unlock"&&b.ability&&this.sendNotification("pet.reaction",{text:`\u{1F389} \u89E3\u9501\u65B0\u80FD\u529B\uFF1A${b.ability.name}`,style:"excited"});let m=null,h="excited";try{let b=[],k=this.getActiveProjectRoot?.()??"";if(k){let L=k.split(/[\\/]/).pop()??k;b.push(`\u7528\u6237\u6B63\u5728\u9879\u76EE\u300C${L}\u300D\u4E2D\u5DE5\u4F5C`)}if(this.sessionState){let L=this.sessionState.turnCount??0;L>0&&b.push(`\u672C\u6B21\u4F1A\u8BDD\u5DF2\u8FDB\u884C\u4E86 ${L} \u8F6E\u5BF9\u8BDD`)}if(this.memoryProvider&&this.memoryUserId)try{let L=this.memoryProvider.getActivitySummary(this.memoryUserId,7);if(L?.highlights?.length){let F=L.highlights.slice(0,3).map(T=>T.text);b.push(`\u7528\u6237\u8FD1\u671F\u8BB0\u5FC6\u4EAE\u70B9: ${F.join("\uFF1B")}`)}}catch{}let A=new Date().getHours(),_=A<6?"\u6DF1\u591C":A<9?"\u65E9\u6668":A<12?"\u4E0A\u5348":A<14?"\u4E2D\u5348":A<18?"\u4E0B\u5348":A<22?"\u665A\u4E0A":"\u6DF1\u591C";b.push(`\u5F53\u524D\u65F6\u6BB5: ${_}`);let I=t==="pat"?"\u7528\u6237\u6478\u4E86\u6478\u4F60":t==="feed"?"\u7528\u6237\u5582\u4E86\u4F60\u4E1C\u897F":`\u7528\u6237\u5BF9\u4F60\u505A\u4E86\u300C${t}\u300D`;b.push(I);let N=b.join("\u3002");if(this.createSmallLLMCall){let L=this.createSmallLLMCall();if(L){let F=await So({turnSummary:N,soul:o},L);F&&(m=F.text,h=F.style)}}}catch{}if(!m){let b=ko("session.created");m=b?.text??null,h=b?.style??"excited"}let f=[],y=new Date().getHours();y>=22||y<6?f.push({label:"\u5E2E\u6211\u6574\u7406\u4ECA\u5929\u7684\u8FDB\u5EA6",action:"summarize-today"}):this.sessionState?.turnCount&&this.sessionState.turnCount>5&&f.push({label:"\u7EE7\u7EED\u521A\u624D\u7684\u5BF9\u8BDD",action:"resume-session"}),t==="click"&&f.push({label:"\u6709\u4EC0\u4E48\u80FD\u5E2E\u4F60\u7684\uFF1F",action:"start-chat"}),m&&this.sendNotification("pet.reaction",{text:m,style:h,actions:f.length>0?f:void 0}),n.id!==void 0&&this.sendResponse(n.id,{ok:!0,action:t,level:a,experience:c,events:l.map(b=>({type:b.type,level:b.level})),reaction:m?{text:m,style:h,actions:f.length>0?f:void 0}:null})}async function yb(n){let e=this.getActiveProjectRoot(),r=new Zt(e).load();if(n.id!==void 0&&this.sendResponse(n.id,{ok:!0,soul:r??null,growth:r?Tl(r):null}),r){this.sendNotification("pet.soul_ready",{name:r.name,species:r.species,personality:r.personality,catchphrase:r.catchphrase,stats:r.stats,rarity:r.rarity,breed:r.breed,breedColors:r.breedColors});let s=Ee.getUnlockedAbilities(r.level).map(i=>i.name),o=Ee.getNextAbility(r.level);this.sendNotification("pet.growth",{level:r.level,experience:r.experience,xpNeeded:Ee.xpForLevel(r.level),abilities:s,nextAbility:o?{name:o.name,level:o.unlockedAtLevel}:void 0})}}async function bb(n){let e=n.params;if(!e?.description&&!e?.imageBase64){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:"Provide description or imageBase64"});return}typeof this.ensureModelRegistryHydrated=="function"&&await this.ensureModelRegistryHydrated(),this.sendNotification("pet.state",{state:"building"}),this.sendNotification("pet.reaction",{text:"\u6B63\u5728\u5B75\u5316\u4F60\u7684\u4E13\u5C5E\u5BA0\u7269...",style:"thinking"});try{let t=e.description?.slice(0,10)??"\u81EA\u5B9A\u4E49\u5BA0\u7269",r=e.description??"";e.imageBase64&&(r=await this.forgeAnalyzeImage(e.imageBase64,e.description),this.sendNotification("pet.reaction",{text:"\u5206\u6790\u5B8C\u6210\uFF0C\u6B63\u5728\u751F\u6210\u9AA8\u67B6...",style:"thinking"}));let s=await this.forgeGenerateSkeleton(r),o=Wt(s),i=Wn(o),a=0;for(;i.length>0&&a<2;){a++,this.sendNotification("pet.reaction",{text:`\u9AA8\u67B6\u7F3A\u5C11 ${i.join("\u3001")}\uFF0C\u91CD\u65B0\u751F\u6210 (${a}/${2})...`,style:"thinking",duration:3e3});let m=`\u4E0A\u6B21\u751F\u6210\u7F3A\u5C11\u4EE5\u4E0B\u90E8\u4F4D: ${i.join(", ")}\u3002\u8BF7\u786E\u4FDD\u6240\u6709 id \u5C5E\u6027\u90FD\u5B58\u5728\u3002`;s=await this.forgeGenerateSkeleton(r+`
|
|
981
|
+
`,u=await fetch(i,{method:"POST",headers:{Authorization:`Bearer ${s}`,"Content-Type":`multipart/form-data; boundary=${c}`},body:d});if(!u.ok){let m=await u.text();a.release({success:!1,errorCode:u.status}),n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:`STT API error (${u.status}): ${m.slice(0,200)}`});return}let p=await u.json();a.release({success:!0}),n.id!==void 0&&this.sendResponse(n.id,{text:p.text??"",model:p.model})}catch(c){a.release({success:!1}),n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:c instanceof Error?c.message:String(c)})}}dt();function I_(n){return n.length<=8?"****":`${n.slice(0,3)}***${n.slice(-4)}`}function lt(n,e,t,r=v.INTERNAL_ERROR){if(e.id!==void 0){if(typeof n.sendError=="function"){n.sendError(e.id,r,t);return}n.sendResponse(e.id,void 0,{code:r,message:t})}}function vo(n,e){lt(n,e,Xs)}function __(n){let e={};for(let t of n)for(let r of t.purposes)e[r]??=[],e[r].push(t);return e}async function ul(){let n=Y(),e=await _r(n);return n.save(),e}async function Ky(n){try{let e=(await Ys()).map(t=>({id:t.id,displayName:Fc(t),baseUrl:Js(t)??"",modelCount:t.models?.length??0}));n.id!==void 0&&this.sendResponse(n.id,{providers:e})}catch{vo(this,n)}}async function Vy(n){let e=n.params;if(!e?.providerId||!e?.key){lt(this,n,"Required: providerId (string), key (string)",v.INVALID_PARAMS);return}let{providerId:t,key:r,label:s}=e;try{let o=await Bc(t);if(!o){lt(this,n,`Unknown provider: ${t}`,v.INVALID_PARAMS);return}let i=Y();if(i.getProviderStatus(t)?.keys.some(l=>l.key===r)){n.id!==void 0&&this.sendResponse(n.id,{ok:!1,error:"\u8BE5 Key \u5DF2\u5B58\u5728\uFF0C\u65E0\u9700\u91CD\u590D\u6DFB\u52A0"});return}i.addProvider(t,{baseUrl:Js(o)});let c=i.addKey(t,r,{label:s});await ul();for(let l of rr)if(!i.getBinding(l)){let d=i.listModels({purpose:l,provider:t,enabledOnly:!0});d.length>0&&i.setBinding(l,d[0].id)}i.setKeyHealth(c,"healthy"),i.save(),n.id!==void 0&&this.sendResponse(n.id,{ok:!0,keyId:c,providerId:t})}catch(o){let i=o instanceof Error?o.message:Xs;lt(this,n,i)}}function zy(n){let e=n.params;if(!e?.keyId){lt(this,n,"Required: keyId (string)",v.INVALID_PARAMS);return}let t=Y();t.removeKey(e.keyId),t.save(),n.id!==void 0&&this.sendResponse(n.id,{ok:!0})}function Xy(n){let e=n.params;if(!e?.keyId||typeof e.enabled!="boolean"){lt(this,n,"Required: keyId (string), enabled (boolean)",v.INVALID_PARAMS);return}let t=Y();t.updateKey(e.keyId,{enabled:e.enabled}),t.save(),n.id!==void 0&&this.sendResponse(n.id,{ok:!0})}function Yy(n){let e=n.params;if(!e?.modelId||typeof e.enabled!="boolean"){lt(this,n,"Required: modelId (string), enabled (boolean)",v.INVALID_PARAMS);return}let t=Y();e.enabled?t.enableModel(e.modelId):t.disableModel(e.modelId),t.save(),n.id!==void 0&&this.sendResponse(n.id,{ok:!0})}async function Jy(n){let e=n.params;try{await ul();let t=Y(),r=new Set(t.getAllProviderStatus().filter(o=>o.keys.length>0).map(o=>o.providerId)),s=t.listModels({purpose:e?.purpose,provider:e?.provider}).filter(o=>t.hasConfiguredKeyForProviderVariant(o.provider));n.id!==void 0&&this.sendResponse(n.id,{models:s,grouped:__(s),configuredProviderIds:[...r]})}catch{vo(this,n)}}function Qy(n){let e=n.params;if(!e?.purpose||!e?.modelId){lt(this,n,"Required: purpose (string), modelId (string)",v.INVALID_PARAMS);return}try{let t=Y();t.setBinding(e.purpose,e.modelId),t.save(),n.id!==void 0&&this.sendResponse(n.id,{ok:!0})}catch(t){lt(this,n,t instanceof Error?t.message:String(t),v.INVALID_PARAMS)}}function Zy(n){let e=n.params;if(!e?.purpose){lt(this,n,"Required: purpose (string)",v.INVALID_PARAMS);return}let t=Y(),r=t.getBinding(e.purpose);n.id!==void 0&&this.sendResponse(n.id,{model:r?{id:r.id,provider:r.provider,model:r.model,displayName:r.displayName,purposes:r.purposes,enabled:r.enabled}:null,available:t.isAvailable(e.purpose)})}async function eb(n){try{let e=await Ys(),t=new Map(e.map(a=>[a.id,Fc(a)]));await ul();let r=Y(),s=r.getAllProviderStatus().map(a=>({providerId:a.providerId,displayName:t.get(a.providerId)??a.providerId,baseUrl:a.baseUrl,keyCount:a.keys.length,healthyKeys:a.keys.filter(c=>c.healthStatus==="healthy"&&c.enabled).length,totalKeys:a.keys.length,keys:a.keys.map(c=>({id:c.id,label:c.label,maskedKey:I_(c.key),enabled:c.enabled,health:c.healthStatus}))})),o=r.getAllBindings(),i={};for(let a of rr){let c=o[a];i[a]={bound:!!c,modelId:c?.id,modelName:c?.displayName,available:r.isAvailable(a)}}n.id!==void 0&&this.sendResponse(n.id,{providers:s,purposes:i})}catch{vo(this,n)}}async function tb(n){try{let e=Y();e.load(),await _r(e),e.save(),n.id!==void 0&&this.sendResponse(n.id,{ok:!0,catalogRefreshed:!0})}catch{vo(this,n)}}async function nb(n){let e=n.params;if(!e?.providerId||!e?.apiKey){lt(this,n,"providerId and apiKey required",v.INVALID_PARAMS);return}try{let t=await Bc(e.providerId),r=e.baseUrl||(t?Js(t):void 0);if(!r){lt(this,n,`Unknown provider: ${e.providerId}`,v.INVALID_PARAMS);return}let s=`${r.replace(/\/$/,"")}/models`,o=await fetch(s,{method:"GET",headers:{Authorization:`Bearer ${e.apiKey}`},signal:AbortSignal.timeout(1e4)});if(o.ok){n.id!==void 0&&this.sendResponse(n.id,{valid:!0,status:o.status});return}let i=await o.text().catch(()=>"");n.id!==void 0&&this.sendResponse(n.id,{valid:!1,status:o.status,error:i.slice(0,500)})}catch(t){let r=t instanceof Error?t.message:String(t);n.id!==void 0&&this.sendResponse(n.id,{valid:!1,status:0,error:r})}}wo();To();fl();Ro();Ao();function Tl(n){let e=Ee.getNextAbility(n.level);return{level:n.level,experience:n.experience,xpNeeded:Ee.xpForLevel(n.level),abilities:Ee.getUnlockedAbilities(n.level).map(t=>t.name),nextAbility:e?{name:e.name,level:e.unlockedAtLevel}:void 0}}async function hb(n){let e=n.params,t=this.getActiveProjectRoot(),r=new Zt(t),s=r.load();if(s){this.sendNotification("pet.soul_ready",{name:s.name,species:s.species,personality:s.personality,catchphrase:s.catchphrase,stats:s.stats,rarity:s.rarity,breed:s.breed,breedColors:s.breedColors}),n.id!==void 0&&this.sendResponse(n.id,{ok:!0,soul:s,growth:Tl(s)});return}let o=this.deviceId??"default-user";try{let i=this.createPetSoulGenerator?.(),a=await r.hatch(o,i,e?.breed);this.sendNotification("pet.soul_ready",{name:a.name,species:a.species,personality:a.personality,catchphrase:a.catchphrase,stats:a.stats,rarity:a.rarity,breed:a.breed,breedColors:a.breedColors}),this.sendNotification("pet.growth",{level:a.level,experience:a.experience,xpNeeded:Ee.xpForLevel(a.level),abilities:Ee.getUnlockedAbilities(a.level).map(c=>c.name)}),n.id!==void 0&&this.sendResponse(n.id,{ok:!0,soul:a,growth:Tl(a)})}catch(i){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:i.message??"Failed to hatch pet"})}}async function yb(n){let t=n.params?.action??"pat",r=this.getActiveProjectRoot(),s=new Zt(r),o=s.load();if(!o){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:"Pet not hatched yet"});return}let i=Ee.xpForEvent(`interact.${t}`),{newLevel:a,newXp:c,events:l,statBoosts:d}=Ee.processXpGain(o,i);o.level=a,o.experience=c;for(let[b,k]of Object.entries(d)){let A=b;o.stats[A]=Math.min(10,o.stats[A]+(k??0))}s.updateSoul(o),this.sendNotification("pet.state",{state:"happy"});let u=Ee.getUnlockedAbilities(a).map(b=>b.name),p=Ee.getNextAbility(a);this.sendNotification("pet.growth",{level:a,experience:c,xpNeeded:Ee.xpForLevel(a),abilities:u,nextAbility:p?{name:p.name,level:p.unlockedAtLevel}:void 0});for(let b of l)b.type==="molt"?this.sendNotification("pet.reaction",{text:`\u2728 \u8131\u58F3\u4E86\uFF01\u7B2C ${b.moltStage} \u6B21\u8715\u53D8`,style:"excited"}):b.type==="ability_unlock"&&b.ability&&this.sendNotification("pet.reaction",{text:`\u{1F389} \u89E3\u9501\u65B0\u80FD\u529B\uFF1A${b.ability.name}`,style:"excited"});let m=null,h="excited";try{let b=[],k=this.getActiveProjectRoot?.()??"";if(k){let L=k.split(/[\\/]/).pop()??k;b.push(`\u7528\u6237\u6B63\u5728\u9879\u76EE\u300C${L}\u300D\u4E2D\u5DE5\u4F5C`)}if(this.sessionState){let L=this.sessionState.turnCount??0;L>0&&b.push(`\u672C\u6B21\u4F1A\u8BDD\u5DF2\u8FDB\u884C\u4E86 ${L} \u8F6E\u5BF9\u8BDD`)}if(this.memoryProvider&&this.memoryUserId)try{let L=this.memoryProvider.getActivitySummary(this.memoryUserId,7);if(L?.highlights?.length){let F=L.highlights.slice(0,3).map(T=>T.text);b.push(`\u7528\u6237\u8FD1\u671F\u8BB0\u5FC6\u4EAE\u70B9: ${F.join("\uFF1B")}`)}}catch{}let A=new Date().getHours(),_=A<6?"\u6DF1\u591C":A<9?"\u65E9\u6668":A<12?"\u4E0A\u5348":A<14?"\u4E2D\u5348":A<18?"\u4E0B\u5348":A<22?"\u665A\u4E0A":"\u6DF1\u591C";b.push(`\u5F53\u524D\u65F6\u6BB5: ${_}`);let I=t==="pat"?"\u7528\u6237\u6478\u4E86\u6478\u4F60":t==="feed"?"\u7528\u6237\u5582\u4E86\u4F60\u4E1C\u897F":`\u7528\u6237\u5BF9\u4F60\u505A\u4E86\u300C${t}\u300D`;b.push(I);let N=b.join("\u3002");if(this.createSmallLLMCall){let L=this.createSmallLLMCall();if(L){let F=await So({turnSummary:N,soul:o},L);F&&(m=F.text,h=F.style)}}}catch{}if(!m){let b=ko("session.created");m=b?.text??null,h=b?.style??"excited"}let f=[],y=new Date().getHours();y>=22||y<6?f.push({label:"\u5E2E\u6211\u6574\u7406\u4ECA\u5929\u7684\u8FDB\u5EA6",action:"summarize-today"}):this.sessionState?.turnCount&&this.sessionState.turnCount>5&&f.push({label:"\u7EE7\u7EED\u521A\u624D\u7684\u5BF9\u8BDD",action:"resume-session"}),t==="click"&&f.push({label:"\u6709\u4EC0\u4E48\u80FD\u5E2E\u4F60\u7684\uFF1F",action:"start-chat"}),m&&this.sendNotification("pet.reaction",{text:m,style:h,actions:f.length>0?f:void 0}),n.id!==void 0&&this.sendResponse(n.id,{ok:!0,action:t,level:a,experience:c,events:l.map(b=>({type:b.type,level:b.level})),reaction:m?{text:m,style:h,actions:f.length>0?f:void 0}:null})}async function bb(n){let e=this.getActiveProjectRoot(),r=new Zt(e).load();if(n.id!==void 0&&this.sendResponse(n.id,{ok:!0,soul:r??null,growth:r?Tl(r):null}),r){this.sendNotification("pet.soul_ready",{name:r.name,species:r.species,personality:r.personality,catchphrase:r.catchphrase,stats:r.stats,rarity:r.rarity,breed:r.breed,breedColors:r.breedColors});let s=Ee.getUnlockedAbilities(r.level).map(i=>i.name),o=Ee.getNextAbility(r.level);this.sendNotification("pet.growth",{level:r.level,experience:r.experience,xpNeeded:Ee.xpForLevel(r.level),abilities:s,nextAbility:o?{name:o.name,level:o.unlockedAtLevel}:void 0})}}async function vb(n){let e=n.params;if(!e?.description&&!e?.imageBase64){n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INVALID_PARAMS,message:"Provide description or imageBase64"});return}typeof this.ensureModelRegistryHydrated=="function"&&await this.ensureModelRegistryHydrated(),this.sendNotification("pet.state",{state:"building"}),this.sendNotification("pet.reaction",{text:"\u6B63\u5728\u5B75\u5316\u4F60\u7684\u4E13\u5C5E\u5BA0\u7269...",style:"thinking"});try{let t=e.description?.slice(0,10)??"\u81EA\u5B9A\u4E49\u5BA0\u7269",r=e.description??"";e.imageBase64&&(r=await this.forgeAnalyzeImage(e.imageBase64,e.description),this.sendNotification("pet.reaction",{text:"\u5206\u6790\u5B8C\u6210\uFF0C\u6B63\u5728\u751F\u6210\u9AA8\u67B6...",style:"thinking"}));let s=await this.forgeGenerateSkeleton(r),o=Wt(s),i=Wn(o),a=0;for(;i.length>0&&a<2;){a++,this.sendNotification("pet.reaction",{text:`\u9AA8\u67B6\u7F3A\u5C11 ${i.join("\u3001")}\uFF0C\u91CD\u65B0\u751F\u6210 (${a}/${2})...`,style:"thinking",duration:3e3});let m=`\u4E0A\u6B21\u751F\u6210\u7F3A\u5C11\u4EE5\u4E0B\u90E8\u4F4D: ${i.join(", ")}\u3002\u8BF7\u786E\u4FDD\u6240\u6709 id \u5C5E\u6027\u90FD\u5B58\u5728\u3002`;s=await this.forgeGenerateSkeleton(r+`
|
|
982
982
|
|
|
983
|
-
`+m),o=Wt(s),i=Wn(o)}i.length>0&&this.sendNotification("pet.reaction",{text:"\u9AA8\u67B6\u4E0D\u5B8C\u6574\uFF0C\u90E8\u5206\u52A8\u753B\u53EF\u80FD\u7F3A\u5931\uFF0C\u7EE7\u7EED\u751F\u6210...",style:"normal",duration:3e3}),this.sendNotification("pet.reaction",{text:"\u9AA8\u67B6\u751F\u6210\u5B8C\u6210\uFF0C\u5F00\u59CB\u6E32\u67D3\u5404\u72B6\u6001...",style:"thinking"});let c=["idle","thinking","working","done","happy","error","sleeping","eating"],l={baseSvg:o,parts:Bn(o),colors:qn(o),characterDesc:r},d={};for(let m of c)d[m]=Hn(l,m),this.sendNotification("pet.reaction",{text:`\u6E32\u67D3 ${m} \u72B6\u6001... (${Object.keys(d).length}/${c.length})`,style:"thinking",duration:2e3});let u=Wr(d.idle,d,{threshold:6});if(!u.passedAll&&u.retryStates.length>0&&(this.sendNotification("pet.reaction",{text:`\u4E00\u81F4\u6027\u68C0\u67E5\uFF1A${u.retryStates.length} \u4E2A\u72B6\u6001\u9700\u4F18\u5316...`,style:"thinking",duration:3e3}),u.overallScore<4)){let m=Gr(r,"all","\u9AA8\u67B6\u7ED3\u6784\u4E0D\u5B8C\u6574\u5BFC\u81F4\u591A\u72B6\u6001\u4E00\u81F4\u6027\u5DEE",1);s=await this.forgeGenerateSkeleton(m);let h={baseSvg:Wt(s),parts:Bn(Wt(s)),colors:qn(Wt(s)),characterDesc:r};for(let f of c)d[f]=Hn(h,f)}let p={version:1,name:t,author:"user-generated",created:new Date().toISOString(),generator:"xiaozhi-pet-forge-v2-skeleton",source:{type:e.imageBase64?"image":"text",prompt:e.description},dimensions:{width:200,height:200},states:Object.fromEntries(c.map(m=>[m,{file:`states/${m}.svg`,loop:m!=="done"&&m!=="happy"&&m!=="eating",...m==="done"||m==="happy"?{duration:3e3}:m==="eating"?{duration:4e3}:{}}])),eyeTracking:{enabled:!0,pupils:[".left-eye .pupil",".right-eye .pupil"],maxOffset:3},colors:l.colors,consistency:{score:u.overallScore,method:"skeleton-parameterized"}};Br(p),this.sendNotification("pet.reaction",{text:`\u2705 \u5BA0\u7269\u300C${t}\u300D\u5DF2\u953B\u9020\u5B8C\u6210\uFF01\u4E00\u81F4\u6027\u8BC4\u5206 ${u.overallScore.toFixed(1)}/10`,style:"excited"}),this.sendNotification("pet.state",{state:"done"}),this.sendNotification("pet.forged",{name:t,svgs:d}),n.id!==void 0&&this.sendResponse(n.id,{ok:!0,manifest:p,svgs:d,status:"complete",consistency:{score:u.overallScore,passedAll:u.passedAll}})}catch(t){this.sendNotification("pet.state",{state:"error"}),this.sendNotification("pet.reaction",{text:"\u953B\u9020\u5931\u8D25\u4E86...",style:"normal"}),n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:t.message??"Forge failed"})}}var V_=K_(import.meta.url);function z_(){for(let n of["../package.json","../../package.json"])try{return V_(n).version}catch{}return"0.0.0"}var vb=z_();function Z_(n){let e=n.pathname.split("/").filter(Boolean),r=(e[e.length-1]??"").replace(/\.md$/i,"").replace(/[^a-zA-Z0-9_-]/g,"-");return/^(skill|readme|index|install|main)$/i.test(r)&&e.length>=2?e[e.length-2].replace(/[^a-zA-Z0-9_-]/g,"-"):r||""}var xo=class n{running=!1;startedAt=Date.now();rpcContract=new wr;rpcIds=new Map;rpcDeadlineTimers=new Map;activeTurn=null;turnDone=Promise.resolve();verbose;transport;registry;mediaClient;agent=null;lastLlmConfigKey="";currentSessionId="";currentTurnId="";currentHooks=null;mcpManager=null;mcpReady=Promise.resolve();pluginLoader=null;permissionChecker=null;permissionUnregister=null;currentTransport=null;currentApiKey="";currentModel="";currentProvider="";currentBaseUrl="";sessionState=null;currentMediaApiKeys=null;taskStore=new bs;mediaPersistence=new Qs;memoryPrefetchState=Lt();memoryProvider=null;memoryUserId="";lastUserMessageForAutoExtract;lastAssistantMessageForExtract;memdir=null;fileWatcher=null;pendingAskUser=new Map;sessionTaskDomain;acpDetector=new Bs;agentConfigStore=null;soloEvaluator=null;productOrchestrator=null;productPlanner=null;soloProcessManager=null;productProcessManager=null;acpServer=null;acpSessionHistory=new Map;resumedSessionHistory=new Map;idleDreamTimer=null;modelRegistryHydration=null;constructor(e){this.verbose=e.verbose,this.registry=new X_,this.mediaClient=new Y_({registry:this.registry}),Y().onChange(()=>{this.lastLlmConfigKey=""}),this.ensureModelRegistryHydrated().catch(()=>{});let t=Number(process.env.QLOGICAGENT_IDLE_DREAM_MS);t>0&&(Re.dream.idleMinutes=t/6e4);let r=Number(process.env.QLOGICAGENT_DREAM_COOLDOWN_MS);r>=0&&(Re.dream.cooldownMs=r),this.transport=e.transport??new kn({verbose:e.verbose}),this.taskStore.onTaskChange((s,o)=>{o&&this.sendNotification("task.updated",{taskId:s,type:o.type,lifecycle:o.lifecycle,label:o.label})}),Nm({log:{info:s=>this.log(s),warn:s=>this.log(`[warn] ${s}`),error:s=>this.log(`[error] ${s}`),debug:s=>{e.verbose&&this.log(`[debug] ${s}`)}},onExecProgress:s=>{this.sendNotification("turn.exec_progress",{output:s.output,elapsedTimeSeconds:s.elapsedTimeSeconds,totalLines:s.totalLines,totalBytes:s.totalBytes})}})}getActiveProjectRoot(){let e=Oe();return e?.workspaceDir?e.workspaceDir:process.cwd()}async ensureModelRegistryHydrated(){return this.modelRegistryHydration||(this.modelRegistryHydration=(async()=>{let e=Y();e.load(),await _r(e),e.save()})().catch(e=>{this.modelRegistryHydration=null;let t=e instanceof Error?e.message:String(e);throw this.log(`[model-registry] failed to refresh llmrouter catalog: ${t}`),e})),this.modelRegistryHydration}setActiveWorkdir(e){e!==this.getActiveProjectRoot()&&(Em(e),this.mediaPersistence.setProjectDir(e))}start(){this.running=!0,this.log("qlogicagent started, waiting for JSON-RPC messages..."),this.transport.onMessage(e=>{if(this.acpServer){if(Ec(e)||Pr(e)){this.acpServer.dispatchMessage(e);return}if(xr(e)){let t=e.method;if(t==="initialize"||t.startsWith("session/")||t.startsWith("x/")||t.startsWith("fs/")){this.acpServer.dispatchMessage(e);return}}}if(!Ic(e)){this.log("[warn] ignoring non-request message");return}this.handleMessage(e)}),this.transport.onClose(()=>{this.log("transport closed, shutting down"),this.stop()}),this.transport.start()}stop(){if(this.running){this.running=!1,this.cancelIdleDreamTimer();for(let e of this.rpcDeadlineTimers.values())clearTimeout(e);this.rpcDeadlineTimers.clear(),this.rpcIds.clear(),this.currentSessionId&&this.currentHooks&&(this.currentHooks.invoke("stop",{sessionId:this.currentSessionId,reason:"shutdown"}).catch(()=>{}),this.currentHooks.invoke("session.ended",{sessionId:this.currentSessionId}).catch(()=>{}));try{Bg().catch(()=>{}),this.fileWatcher&&(this.fileWatcher.stop(),this.fileWatcher=null),this.mcpManager&&(this.mcpManager.disconnectAll().catch(()=>{}),this.mcpManager=null),this.permissionUnregister&&(this.permissionUnregister(),this.permissionUnregister=null),this.activeTurn&&(this.activeTurn.abort(),this.activeTurn=null),this.transport.close()}catch(e){this.currentSessionId&&this.currentHooks&&this.currentHooks.invoke("stop.failed",{sessionId:this.currentSessionId,reason:"cleanup_error",error:e.message}).catch(()=>{})}this.log("stopped")}}methodHandlers=new Map([["initialize",e=>this.handleInitialize(e)],["agent.ping",e=>this.handlePing(e)],["agent.health",e=>this.handleHealth(e)],["agent.metrics",e=>this.handleMetrics(e)],["agent.cancel",e=>this.handleCancel(e)],["thread.turn",e=>wf.call(this,e)],["memory.dream",e=>uo.call(this,e)],["agent.abort",e=>Tf.call(this,e)],["tool.approval.response",e=>Rf.call(this,e)],["thread.user_response",e=>Af.call(this,e)],["thread.list",e=>Yf.call(this,e)],["session.resume",e=>ih.call(this,e)],["thread.create",e=>Xf.call(this,e)],["session.getInfo",e=>ah.call(this,e)],["session.create",e=>Jf.call(this,e)],["session.resolve",e=>Qf.call(this,e)],["session.list",e=>Zf.call(this,e)],["session.get",e=>eh.call(this,e)],["session.getMessages",e=>th.call(this,e)],["session.update",e=>nh.call(this,e)],["session.delete",e=>rh.call(this,e)],["session.deleteAll",e=>sh.call(this,e)],["session.archive",e=>oh.call(this,e)],["memory.list",e=>oy.call(this,e)],["memory.atlas",e=>iy.call(this,e)],["memory.activity",e=>ay.call(this,e)],["memory.observe",e=>cy.call(this,e)],["memory.propose",e=>ly.call(this,e)],["memory.consolidate",e=>dy.call(this,e)],["memory.read",e=>uy.call(this,e)],["memory.write",e=>py.call(this,e)],["memory.search",e=>my.call(this,e)],["memory.delete",e=>gy.call(this,e)],["memory.update",e=>fy.call(this,e)],["tools.list",e=>hy.call(this,e)],["media.listModels",e=>By.call(this,e)],["media.cancel",e=>Hy.call(this,e)],["media.status",e=>qy.call(this,e)],["media.stt",e=>Wy.call(this,e)],["settings.listProviders",e=>Gy.call(this,e)],["settings.addKey",e=>Ky.call(this,e)],["settings.removeKey",e=>Vy.call(this,e)],["settings.toggleKey",e=>zy.call(this,e)],["settings.toggleModel",e=>Xy.call(this,e)],["settings.listModels",e=>Yy.call(this,e)],["settings.setActiveModel",e=>Jy.call(this,e)],["settings.getActiveModel",e=>Qy.call(this,e)],["settings.getOverview",e=>Zy.call(this,e)],["settings.refreshModels",e=>eb.call(this,e)],["settings.validateKey",e=>tb.call(this,e)],["provider.list",e=>yy.call(this,e)],["config.get",e=>by.call(this,e)],["config.update",e=>vy.call(this,e)],["config.tunables",e=>ky.call(this,e)],["config.updateTunable",e=>Sy.call(this,e)],["todos.list",e=>Ty.call(this,e)],["tasks.list",e=>Ry.call(this,e)],["tasks.cancel",e=>Ay.call(this,e)],["agents.scan",e=>xy.call(this,e)],["agents.list",e=>Py.call(this,e)],["agents.prompt",e=>Uy.call(this,e)],["agents.config",e=>Iy.call(this,e)],["agents.setConfig",e=>_y.call(this,e)],["agents.getConfig",e=>Ey.call(this,e)],["agents.removeConfig",e=>Cy.call(this,e)],["agents.setGateway",e=>My.call(this,e)],["agents.getGateway",e=>Ny.call(this,e)],["agents.processes",e=>Oy.call(this,e)],["agents.kill",e=>Ly.call(this,e)],["agents.listConfigured",e=>Dy.call(this,e)],["agents.getLog",e=>$y.call(this,e)],["agents.testConnection",e=>jy.call(this,e)],["solo.start",e=>yh.call(this,e)],["solo.status",e=>bh.call(this,e)],["solo.cancel",e=>vh.call(this,e)],["solo.select",e=>kh.call(this,e)],["solo.list",e=>Sh.call(this,e)],["solo.delete",e=>Th.call(this,e)],["solo.message",e=>Rh.call(this,e)],["solo.evaluate",e=>Ah.call(this,e)],["product.plan",e=>$f.call(this,e)],["product.confirm",e=>jf.call(this,e)],["product.message",e=>Uf.call(this,e)],["product.create",e=>Ff.call(this,e)],["product.resume",e=>Bf.call(this,e)],["product.pause",e=>Hf.call(this,e)],["product.checkpoint",e=>qf.call(this,e)],["product.status",e=>Wf.call(this,e)],["product.list",e=>Gf.call(this,e)],["product.delete",e=>Kf.call(this,e)],["product.cancel",e=>Vf.call(this,e)],["product.rollback",e=>zf.call(this,e)],["project.create",e=>Lh.call(this,e)],["project.list",e=>$h.call(this,e)],["project.delete",e=>jh.call(this,e)],["project.purgeAll",e=>Uh.call(this,e)],["project.rename",e=>Fh.call(this,e)],["project.archive",e=>Bh.call(this,e)],["project.unarchive",e=>Hh.call(this,e)],["project.update",e=>Wh.call(this,e)],["project.archiveByGroup",e=>qh.call(this,e)],["session.switchProject",e=>ch.call(this,e)],["session.focus",e=>dh.call(this,e)],["session.moveToProject",e=>uh.call(this,e)],["session.getState",e=>lh.call(this,e)],["files.list",e=>Vh.call(this,e)],["files.create",e=>zh.call(this,e)],["files.rename",e=>Xh.call(this,e)],["files.delete",e=>Yh.call(this,e)],["files.gitStatus",e=>Jh.call(this,e)],["instructions.list",e=>Qh.call(this,e)],["instructions.read",e=>Zh.call(this,e)],["instructions.write",e=>ey.call(this,e)],["instructions.delete",e=>ty.call(this,e)],["skills.list",e=>xh.call(this,e)],["skills.activate",e=>Ph.call(this,e)],["skills.deactivate",e=>Ih.call(this,e)],["skills.delete",e=>_h.call(this,e)],["skills.promote",e=>Eh.call(this,e)],["skills.stats",e=>Ch.call(this,e)],["skills.pin",e=>Mh.call(this,e)],["skills.unpin",e=>Nh.call(this,e)],["skills.curator",e=>Dh.call(this,e)],["skills.lifecycle",e=>Oh.call(this,e)],["pet.hatch",e=>fb.call(this,e)],["pet.interact",e=>hb.call(this,e)],["pet.status",e=>yb.call(this,e)],["pet.forge",e=>bb.call(this,e)],["pet.confirm_response",e=>this.handlePetConfirmResponse(e)]]);handleMessage(e){if(e.id!==void 0){let r=qs(e);if(!r.ok){this.sendContractError(e.id,r.error);return}let s=this.rpcContract.begin(e.method,r.meta);if(s.status==="rejected"){this.sendContractError(e.id,s.error);return}if(s.status==="deduped"){this.sendContractErrorOrResult(e.id,s.result,s.error);return}this.rpcIds.set(e.id,r.meta),this.scheduleRpcDeadline(e.id,e.method,r.meta)}let t=this.methodHandlers.get(e.method);t?t(e):e.id!==void 0&&this.sendResponse(e.id,void 0,{code:v.METHOD_NOT_FOUND,message:`Unknown method: ${e.method}`})}handleInitialize(e){let t=e.params,r=t?.protocolVersion??"unknown",s=t?.host?.name??t?.hostName??"unknown",o=t?.host?.version??t?.hostVersion??"?",i=r.split(".")[0],a=pn.split(".")[0];if(i!==a){this.log(`[initialize] protocol mismatch: host=${r} agent=${pn}`),e.id!==void 0&&this.sendResponse(e.id,void 0,{code:v.PROTOCOL_MISMATCH,message:`Protocol version mismatch: host=${r}, agent=${pn}`});return}this.log(`[initialize] host=${s} v${o}`),e.id!==void 0&&this.sendResponse(e.id,{protocolVersion:pn,agent:{name:"qlogicagent",version:"0.1.0"},capabilities:{tools:wt().map(c=>c.function.name),streaming:!0,threads:!0,notifications:["turn.start","turn.delta","turn.end","turn.error","turn.recovery","turn.tool_call","turn.tool_result","turn.tool_blocked","turn.reasoning_delta","turn.plan_update","turn.suggestions","turn.subagent_started","turn.subagent_delta","turn.subagent_ended","turn.media_result","turn.todos_updated","task.updated","turn.exec_progress","turn.artifact","tool.approval.request","turn.skill_instruction","turn.ask_user","memory.updated","session.info","permission.rule_updated","team.updated","turn.usage_update","pong"],methods:[...rf]}}),this.ensureDefaultProject()}ensureDefaultProject(){let e=Oe();if(e)e.workspaceDir&&this.setActiveWorkdir(e.workspaceDir);else{let t=ee.join(q(),"workspaces","default");V.existsSync(t)||V.mkdirSync(t,{recursive:!0});let r=mu(t);al(t),this.setActiveWorkdir(t),this.sendNotification("project.created",{id:r.id,name:r.name,workspaceDir:r.workspaceDir,type:r.type})}this.ensureDefaultProjectDir();{let t=this.getActiveProjectRoot(),r=new Et(t);r.ensureInitialized(),this.memdir=r}}ensureDefaultProjectDir(){let t=me().find(r=>r.type==="default"&&r.status==="active");t&&(V.existsSync(t.workspaceDir)||V.mkdirSync(t.workspaceDir,{recursive:!0}))}handlePing(e){e.id!==void 0&&this.sendResponse(e.id,{status:"ok"}),this.sendNotification("pong",{})}handleHealth(e){e.id!==void 0&&this.sendResponse(e.id,{ok:!0,status:this.running?"healthy":"stopping",uptimeMs:Date.now()-this.startedAt,protocolVersion:pn,version:vb})}handleMetrics(e){e.id!==void 0&&this.sendResponse(e.id,{rpc:this.rpcContract.metrics()})}handleCancel(e){let t=e.params,r=t?.requestId,s=typeof r=="string"?this.rpcContract.cancel(r,t?.reason??"host-cancelled"):!1;s&&this.activeTurn&&this.activeTurn.abort(),e.id!==void 0&&this.sendResponse(e.id,{ok:!0,cancelled:s})}static SUGGESTION_PROMPT=`[SUGGESTION MODE]
|
|
983
|
+
`+m),o=Wt(s),i=Wn(o)}i.length>0&&this.sendNotification("pet.reaction",{text:"\u9AA8\u67B6\u4E0D\u5B8C\u6574\uFF0C\u90E8\u5206\u52A8\u753B\u53EF\u80FD\u7F3A\u5931\uFF0C\u7EE7\u7EED\u751F\u6210...",style:"normal",duration:3e3}),this.sendNotification("pet.reaction",{text:"\u9AA8\u67B6\u751F\u6210\u5B8C\u6210\uFF0C\u5F00\u59CB\u6E32\u67D3\u5404\u72B6\u6001...",style:"thinking"});let c=["idle","thinking","working","done","happy","error","sleeping","eating"],l={baseSvg:o,parts:Bn(o),colors:qn(o),characterDesc:r},d={};for(let m of c)d[m]=Hn(l,m),this.sendNotification("pet.reaction",{text:`\u6E32\u67D3 ${m} \u72B6\u6001... (${Object.keys(d).length}/${c.length})`,style:"thinking",duration:2e3});let u=Wr(d.idle,d,{threshold:6});if(!u.passedAll&&u.retryStates.length>0&&(this.sendNotification("pet.reaction",{text:`\u4E00\u81F4\u6027\u68C0\u67E5\uFF1A${u.retryStates.length} \u4E2A\u72B6\u6001\u9700\u4F18\u5316...`,style:"thinking",duration:3e3}),u.overallScore<4)){let m=Gr(r,"all","\u9AA8\u67B6\u7ED3\u6784\u4E0D\u5B8C\u6574\u5BFC\u81F4\u591A\u72B6\u6001\u4E00\u81F4\u6027\u5DEE",1);s=await this.forgeGenerateSkeleton(m);let h={baseSvg:Wt(s),parts:Bn(Wt(s)),colors:qn(Wt(s)),characterDesc:r};for(let f of c)d[f]=Hn(h,f)}let p={version:1,name:t,author:"user-generated",created:new Date().toISOString(),generator:"xiaozhi-pet-forge-v2-skeleton",source:{type:e.imageBase64?"image":"text",prompt:e.description},dimensions:{width:200,height:200},states:Object.fromEntries(c.map(m=>[m,{file:`states/${m}.svg`,loop:m!=="done"&&m!=="happy"&&m!=="eating",...m==="done"||m==="happy"?{duration:3e3}:m==="eating"?{duration:4e3}:{}}])),eyeTracking:{enabled:!0,pupils:[".left-eye .pupil",".right-eye .pupil"],maxOffset:3},colors:l.colors,consistency:{score:u.overallScore,method:"skeleton-parameterized"}};Br(p),this.sendNotification("pet.reaction",{text:`\u2705 \u5BA0\u7269\u300C${t}\u300D\u5DF2\u953B\u9020\u5B8C\u6210\uFF01\u4E00\u81F4\u6027\u8BC4\u5206 ${u.overallScore.toFixed(1)}/10`,style:"excited"}),this.sendNotification("pet.state",{state:"done"}),this.sendNotification("pet.forged",{name:t,svgs:d}),n.id!==void 0&&this.sendResponse(n.id,{ok:!0,manifest:p,svgs:d,status:"complete",consistency:{score:u.overallScore,passedAll:u.passedAll}})}catch(t){this.sendNotification("pet.state",{state:"error"}),this.sendNotification("pet.reaction",{text:"\u953B\u9020\u5931\u8D25\u4E86...",style:"normal"}),n.id!==void 0&&this.sendResponse(n.id,void 0,{code:v.INTERNAL_ERROR,message:t.message??"Forge failed"})}}var V_=K_(import.meta.url);function z_(){for(let n of["../package.json","../../package.json"])try{return V_(n).version}catch{}return"0.0.0"}var kb=z_();function Z_(n){let e=n.pathname.split("/").filter(Boolean),r=(e[e.length-1]??"").replace(/\.md$/i,"").replace(/[^a-zA-Z0-9_-]/g,"-");return/^(skill|readme|index|install|main)$/i.test(r)&&e.length>=2?e[e.length-2].replace(/[^a-zA-Z0-9_-]/g,"-"):r||""}var xo=class n{running=!1;startedAt=Date.now();rpcContract=new wr;rpcIds=new Map;rpcDeadlineTimers=new Map;activeTurn=null;turnDone=Promise.resolve();verbose;transport;registry;mediaClient;agent=null;lastLlmConfigKey="";currentSessionId="";currentTurnId="";currentHooks=null;mcpManager=null;mcpReady=Promise.resolve();pluginLoader=null;permissionChecker=null;permissionUnregister=null;currentTransport=null;currentApiKey="";currentModel="";currentProvider="";currentBaseUrl="";sessionState=null;currentMediaApiKeys=null;taskStore=new bs;mediaPersistence=new Qs;memoryPrefetchState=Lt();memoryProvider=null;memoryUserId="";lastUserMessageForAutoExtract;lastAssistantMessageForExtract;memdir=null;fileWatcher=null;pendingAskUser=new Map;sessionTaskDomain;acpDetector=new Bs;agentConfigStore=null;soloEvaluator=null;productOrchestrator=null;productPlanner=null;soloProcessManager=null;productProcessManager=null;acpServer=null;acpSessionHistory=new Map;resumedSessionHistory=new Map;idleDreamTimer=null;modelRegistryHydration=null;constructor(e){this.verbose=e.verbose,this.registry=new X_,this.mediaClient=new Y_({registry:this.registry}),Y().onChange(()=>{this.lastLlmConfigKey=""}),this.ensureModelRegistryHydrated().catch(()=>{});let t=Number(process.env.QLOGICAGENT_IDLE_DREAM_MS);t>0&&(Re.dream.idleMinutes=t/6e4);let r=Number(process.env.QLOGICAGENT_DREAM_COOLDOWN_MS);r>=0&&(Re.dream.cooldownMs=r),this.transport=e.transport??new kn({verbose:e.verbose}),this.taskStore.onTaskChange((s,o)=>{o&&this.sendNotification("task.updated",{taskId:s,type:o.type,lifecycle:o.lifecycle,label:o.label})}),Dm({log:{info:s=>this.log(s),warn:s=>this.log(`[warn] ${s}`),error:s=>this.log(`[error] ${s}`),debug:s=>{e.verbose&&this.log(`[debug] ${s}`)}},onExecProgress:s=>{this.sendNotification("turn.exec_progress",{output:s.output,elapsedTimeSeconds:s.elapsedTimeSeconds,totalLines:s.totalLines,totalBytes:s.totalBytes})}})}getActiveProjectRoot(){let e=Oe();return e?.workspaceDir?e.workspaceDir:process.cwd()}async ensureModelRegistryHydrated(){return this.modelRegistryHydration||(this.modelRegistryHydration=(async()=>{let e=Y();e.load(),await _r(e),e.save()})().catch(e=>{this.modelRegistryHydration=null;let t=e instanceof Error?e.message:String(e);throw this.log(`[model-registry] failed to refresh llmrouter catalog: ${t}`),e})),this.modelRegistryHydration}setActiveWorkdir(e){e!==this.getActiveProjectRoot()&&(Cm(e),this.mediaPersistence.setProjectDir(e))}start(){this.running=!0,this.log("qlogicagent started, waiting for JSON-RPC messages..."),this.transport.onMessage(e=>{if(this.acpServer){if(Ec(e)||Pr(e)){this.acpServer.dispatchMessage(e);return}if(xr(e)){let t=e.method;if(t==="initialize"||t.startsWith("session/")||t.startsWith("x/")||t.startsWith("fs/")){this.acpServer.dispatchMessage(e);return}}}if(!Ic(e)){this.log("[warn] ignoring non-request message");return}this.handleMessage(e)}),this.transport.onClose(()=>{this.log("transport closed, shutting down"),this.stop()}),this.transport.start()}stop(){if(this.running){this.running=!1,this.cancelIdleDreamTimer();for(let e of this.rpcDeadlineTimers.values())clearTimeout(e);this.rpcDeadlineTimers.clear(),this.rpcIds.clear(),this.currentSessionId&&this.currentHooks&&(this.currentHooks.invoke("stop",{sessionId:this.currentSessionId,reason:"shutdown"}).catch(()=>{}),this.currentHooks.invoke("session.ended",{sessionId:this.currentSessionId}).catch(()=>{}));try{Hg().catch(()=>{}),this.fileWatcher&&(this.fileWatcher.stop(),this.fileWatcher=null),this.mcpManager&&(this.mcpManager.disconnectAll().catch(()=>{}),this.mcpManager=null),this.permissionUnregister&&(this.permissionUnregister(),this.permissionUnregister=null),this.activeTurn&&(this.activeTurn.abort(),this.activeTurn=null),this.transport.close()}catch(e){this.currentSessionId&&this.currentHooks&&this.currentHooks.invoke("stop.failed",{sessionId:this.currentSessionId,reason:"cleanup_error",error:e.message}).catch(()=>{})}this.log("stopped")}}methodHandlers=new Map([["initialize",e=>this.handleInitialize(e)],["agent.ping",e=>this.handlePing(e)],["agent.health",e=>this.handleHealth(e)],["agent.metrics",e=>this.handleMetrics(e)],["agent.cancel",e=>this.handleCancel(e)],["thread.turn",e=>xf.call(this,e)],["memory.dream",e=>uo.call(this,e)],["agent.abort",e=>Rf.call(this,e)],["tool.approval.response",e=>Af.call(this,e)],["thread.user_response",e=>wf.call(this,e)],["thread.list",e=>Jf.call(this,e)],["session.resume",e=>ah.call(this,e)],["thread.create",e=>Yf.call(this,e)],["session.getInfo",e=>ch.call(this,e)],["session.create",e=>Qf.call(this,e)],["session.resolve",e=>Zf.call(this,e)],["session.list",e=>eh.call(this,e)],["session.get",e=>th.call(this,e)],["session.getMessages",e=>nh.call(this,e)],["session.update",e=>rh.call(this,e)],["session.delete",e=>sh.call(this,e)],["session.deleteAll",e=>oh.call(this,e)],["session.archive",e=>ih.call(this,e)],["memory.list",e=>iy.call(this,e)],["memory.atlas",e=>ay.call(this,e)],["memory.activity",e=>cy.call(this,e)],["memory.observe",e=>ly.call(this,e)],["memory.propose",e=>dy.call(this,e)],["memory.consolidate",e=>uy.call(this,e)],["memory.read",e=>py.call(this,e)],["memory.write",e=>my.call(this,e)],["memory.search",e=>gy.call(this,e)],["memory.delete",e=>fy.call(this,e)],["memory.update",e=>hy.call(this,e)],["tools.list",e=>yy.call(this,e)],["media.listModels",e=>Hy.call(this,e)],["media.cancel",e=>qy.call(this,e)],["media.status",e=>Wy.call(this,e)],["media.stt",e=>Gy.call(this,e)],["settings.listProviders",e=>Ky.call(this,e)],["settings.addKey",e=>Vy.call(this,e)],["settings.removeKey",e=>zy.call(this,e)],["settings.toggleKey",e=>Xy.call(this,e)],["settings.toggleModel",e=>Yy.call(this,e)],["settings.listModels",e=>Jy.call(this,e)],["settings.setActiveModel",e=>Qy.call(this,e)],["settings.getActiveModel",e=>Zy.call(this,e)],["settings.getOverview",e=>eb.call(this,e)],["settings.refreshModels",e=>tb.call(this,e)],["settings.validateKey",e=>nb.call(this,e)],["provider.list",e=>by.call(this,e)],["config.get",e=>vy.call(this,e)],["config.update",e=>ky.call(this,e)],["config.tunables",e=>Sy.call(this,e)],["config.updateTunable",e=>Ty.call(this,e)],["todos.list",e=>Ry.call(this,e)],["tasks.list",e=>Ay.call(this,e)],["tasks.cancel",e=>wy.call(this,e)],["agents.scan",e=>Py.call(this,e)],["agents.list",e=>Iy.call(this,e)],["agents.prompt",e=>Fy.call(this,e)],["agents.config",e=>_y.call(this,e)],["agents.setConfig",e=>Ey.call(this,e)],["agents.getConfig",e=>Cy.call(this,e)],["agents.removeConfig",e=>My.call(this,e)],["agents.setGateway",e=>Ny.call(this,e)],["agents.getGateway",e=>Dy.call(this,e)],["agents.processes",e=>Ly.call(this,e)],["agents.kill",e=>$y.call(this,e)],["agents.listConfigured",e=>Oy.call(this,e)],["agents.getLog",e=>jy.call(this,e)],["agents.testConnection",e=>Uy.call(this,e)],["solo.start",e=>bh.call(this,e)],["solo.status",e=>vh.call(this,e)],["solo.cancel",e=>kh.call(this,e)],["solo.select",e=>Sh.call(this,e)],["solo.list",e=>Th.call(this,e)],["solo.delete",e=>Rh.call(this,e)],["solo.message",e=>Ah.call(this,e)],["solo.evaluate",e=>wh.call(this,e)],["product.plan",e=>jf.call(this,e)],["product.confirm",e=>Uf.call(this,e)],["product.message",e=>Ff.call(this,e)],["product.create",e=>Bf.call(this,e)],["product.resume",e=>Hf.call(this,e)],["product.pause",e=>qf.call(this,e)],["product.checkpoint",e=>Wf.call(this,e)],["product.status",e=>Gf.call(this,e)],["product.list",e=>Kf.call(this,e)],["product.delete",e=>Vf.call(this,e)],["product.cancel",e=>zf.call(this,e)],["product.rollback",e=>Xf.call(this,e)],["project.create",e=>$h.call(this,e)],["project.list",e=>jh.call(this,e)],["project.delete",e=>Uh.call(this,e)],["project.purgeAll",e=>Fh.call(this,e)],["project.rename",e=>Bh.call(this,e)],["project.archive",e=>Hh.call(this,e)],["project.unarchive",e=>qh.call(this,e)],["project.update",e=>Gh.call(this,e)],["project.archiveByGroup",e=>Wh.call(this,e)],["session.switchProject",e=>lh.call(this,e)],["session.focus",e=>uh.call(this,e)],["session.moveToProject",e=>ph.call(this,e)],["session.getState",e=>dh.call(this,e)],["files.list",e=>zh.call(this,e)],["files.create",e=>Xh.call(this,e)],["files.rename",e=>Yh.call(this,e)],["files.delete",e=>Jh.call(this,e)],["files.gitStatus",e=>Qh.call(this,e)],["instructions.list",e=>Zh.call(this,e)],["instructions.read",e=>ey.call(this,e)],["instructions.write",e=>ty.call(this,e)],["instructions.delete",e=>ny.call(this,e)],["skills.list",e=>Ph.call(this,e)],["skills.activate",e=>Ih.call(this,e)],["skills.deactivate",e=>_h.call(this,e)],["skills.delete",e=>Eh.call(this,e)],["skills.promote",e=>Ch.call(this,e)],["skills.stats",e=>Mh.call(this,e)],["skills.pin",e=>Nh.call(this,e)],["skills.unpin",e=>Dh.call(this,e)],["skills.curator",e=>Oh.call(this,e)],["skills.lifecycle",e=>Lh.call(this,e)],["pet.hatch",e=>hb.call(this,e)],["pet.interact",e=>yb.call(this,e)],["pet.status",e=>bb.call(this,e)],["pet.forge",e=>vb.call(this,e)],["pet.confirm_response",e=>this.handlePetConfirmResponse(e)]]);handleMessage(e){if(e.id!==void 0){let r=qs(e);if(!r.ok){this.sendContractError(e.id,r.error);return}let s=this.rpcContract.begin(e.method,r.meta);if(s.status==="rejected"){this.sendContractError(e.id,s.error);return}if(s.status==="deduped"){this.sendContractErrorOrResult(e.id,s.result,s.error);return}this.rpcIds.set(e.id,r.meta),this.scheduleRpcDeadline(e.id,e.method,r.meta)}let t=this.methodHandlers.get(e.method);t?t(e):e.id!==void 0&&this.sendResponse(e.id,void 0,{code:v.METHOD_NOT_FOUND,message:`Unknown method: ${e.method}`})}handleInitialize(e){let t=e.params,r=t?.protocolVersion??"unknown",s=t?.host?.name??t?.hostName??"unknown",o=t?.host?.version??t?.hostVersion??"?",i=r.split(".")[0],a=pn.split(".")[0];if(i!==a){this.log(`[initialize] protocol mismatch: host=${r} agent=${pn}`),e.id!==void 0&&this.sendResponse(e.id,void 0,{code:v.PROTOCOL_MISMATCH,message:`Protocol version mismatch: host=${r}, agent=${pn}`});return}this.log(`[initialize] host=${s} v${o}`),e.id!==void 0&&this.sendResponse(e.id,{protocolVersion:pn,agent:{name:"qlogicagent",version:"0.1.0"},capabilities:{tools:wt().map(c=>c.function.name),streaming:!0,threads:!0,notifications:["turn.start","turn.delta","turn.end","turn.error","turn.recovery","turn.tool_call","turn.tool_result","turn.tool_blocked","turn.reasoning_delta","turn.plan_update","turn.suggestions","turn.subagent_started","turn.subagent_delta","turn.subagent_ended","turn.media_result","turn.todos_updated","task.updated","turn.exec_progress","turn.artifact","tool.approval.request","turn.skill_instruction","turn.ask_user","memory.updated","session.info","permission.rule_updated","team.updated","turn.usage_update","pong"],methods:[...sf]}}),this.ensureDefaultProject()}ensureDefaultProject(){let e=Oe();if(e)e.workspaceDir&&this.setActiveWorkdir(e.workspaceDir);else{let t=ee.join(q(),"workspaces","default");V.existsSync(t)||V.mkdirSync(t,{recursive:!0});let r=gu(t);al(t),this.setActiveWorkdir(t),this.sendNotification("project.created",{id:r.id,name:r.name,workspaceDir:r.workspaceDir,type:r.type})}this.ensureDefaultProjectDir();{let t=this.getActiveProjectRoot(),r=new Et(t);r.ensureInitialized(),this.memdir=r}}ensureDefaultProjectDir(){let t=me().find(r=>r.type==="default"&&r.status==="active");t&&(V.existsSync(t.workspaceDir)||V.mkdirSync(t.workspaceDir,{recursive:!0}))}handlePing(e){e.id!==void 0&&this.sendResponse(e.id,{status:"ok"}),this.sendNotification("pong",{})}handleHealth(e){e.id!==void 0&&this.sendResponse(e.id,{ok:!0,status:this.running?"healthy":"stopping",uptimeMs:Date.now()-this.startedAt,protocolVersion:pn,version:kb})}handleMetrics(e){e.id!==void 0&&this.sendResponse(e.id,{rpc:this.rpcContract.metrics()})}handleCancel(e){let t=e.params,r=t?.requestId,s=typeof r=="string"?this.rpcContract.cancel(r,t?.reason??"host-cancelled"):!1;s&&this.activeTurn&&this.activeTurn.abort(),e.id!==void 0&&this.sendResponse(e.id,{ok:!0,cancelled:s})}static SUGGESTION_PROMPT=`[SUGGESTION MODE]
|
|
984
984
|
Based on the conversation, suggest 1-3 short follow-up actions the user might naturally do next.
|
|
985
985
|
Be specific: "run the tests" beats "continue".
|
|
986
986
|
Stay silent if the next step isn't obvious.
|
|
987
|
-
Reply with ONLY a JSON array: [{"text":"short suggestion"}]. No explanation.`;resolveClientForPurpose(e){let r=Y().getActiveModel(e);if(!r)return null;let{provider:s,model:o,apiKey:i,baseUrl:a,keyHandle:c}=r;return c.release({success:!0}),s===this.currentProvider&&this.currentTransport?{transport:this.currentTransport,apiKey:i,model:o}:{transport:
|
|
987
|
+
Reply with ONLY a JSON array: [{"text":"short suggestion"}]. No explanation.`;resolveClientForPurpose(e){let r=Y().getActiveModel(e);if(!r)return null;let{provider:s,model:o,apiKey:i,baseUrl:a,keyHandle:c}=r;return c.release({success:!0}),s===this.currentProvider&&this.currentTransport?{transport:this.currentTransport,apiKey:i,model:o}:{transport:Sb({provider:s,model:o,apiKey:i,baseUrl:a},this.registry).transport,apiKey:i,model:o}}async generateSuggestions(e,t){if(t.filter(a=>a.role==="assistant").length<1)return;let s=this.resolveClientForPurpose("textGeneration");if(!s)return;let i=[...t.slice(-6),{role:"user",content:n.SUGGESTION_PROMPT}];try{let a="";for await(let l of s.transport.stream({model:s.model,messages:i,temperature:.3,maxTokens:200},s.apiKey))l.type==="delta"&&(a+=l.text);let c=a.match(/\[[\s\S]*\]/);if(c){let l=JSON.parse(c[0]),d=Array.isArray(l)?l.filter(u=>typeof u.text=="string"&&u.text.length>0).slice(0,5):[];d.length>0&&this.sendNotification("turn.suggestions",{turnId:e,items:d})}}catch{}}createPetSoulGenerator(){let e=this.resolveClientForPurpose("smallModel");if(e)return async(t,r)=>{let s=`\u4F60\u662F\u4E00\u4E2A\u5BA0\u7269\u540D\u5B57\u751F\u6210\u5668\u3002\u4E3A\u4E00\u53EA${t==="legendary"?"\u4F20\u8BF4\u7EA7":t==="epic"?"\u53F2\u8BD7\u7EA7":t==="rare"?"\u7A00\u6709":"\u666E\u901A"}\u84DD\u8272\u9F99\u867E\u684C\u9762\u5BA0\u7269\u751F\u6210\uFF1A
|
|
988
988
|
1. \u540D\u5B57\uFF1A2-4\u5B57\u4E2D\u6587\u540D\uFF08\u5982"\u963F\u84DD"\u3001"\u94B3\u94B3"\u3001"\u6CE1\u6CE1"\uFF09
|
|
989
989
|
2. \u6027\u683C\uFF1A\u4E00\u53E5\u8BDD\u63CF\u8FF0\uFF0815\u5B57\u5185\uFF09
|
|
990
990
|
3. \u53E3\u5934\u7985\uFF1A\u4E00\u4E2A\u8BED\u6C14\u8BCD\u6216\u77ED\u53E5\uFF086\u5B57\u5185\uFF0C\u5982"\u563F\u563F~"\u3001"\u8BA9\u6211\u60F3\u60F3..."\uFF09
|
|
@@ -1010,13 +1010,13 @@ ${t?`\u7528\u6237\u8865\u5145\u63CF\u8FF0\uFF1A${t}`:""}
|
|
|
1010
1010
|
- \u5355\u6587\u4EF6 < 15KB
|
|
1011
1011
|
- \u4E0D\u8981\u8F93\u51FA\u4EFB\u4F55\u4EE3\u7801\u56F4\u680F\u6216\u89E3\u91CA\uFF0C\u76F4\u63A5\u8F93\u51FA <svg> \u6807\u7B7E
|
|
1012
1012
|
|
|
1013
|
-
\u76F4\u63A5\u8F93\u51FA SVG \u4EE3\u7801\uFF1A`,i="";for await(let c of r.transport.stream({model:r.model,messages:[{role:"user",content:o}],maxTokens:4e3},r.apiKey))c.type==="delta"&&(i+=c.text);let a=i.match(/<svg[\s\S]*?<\/svg>/i);if(!a)throw new Error(`Failed to generate SVG for state: ${t}`);return a[0]}async forgeGenerateSkeleton(e){let{buildSkeletonPrompt:t}=await Promise.resolve().then(()=>(Ro(),
|
|
1014
|
-
`);W.length>0&&(M.imageUrls=[...W,...M.imageUrls??[]]);let Z=M.details?.error,ne=Z?ie:void 0,pe=M.details?.type,He=pe?.split("_")[0];if(pe==="three_d_generate"&&(He="3d"),He&&["image","tts","video","music","3d"].includes(He)){let ge=M.details?.mediaUrls??[],Nt=He;for(let St of ge)this.sendNotification("turn.media_result",{turnId:g,mediaType:Nt,url:St,model:M.details?.model,provider:M.details?.provider,...M.details?.durationMs?{durationSeconds:M.details.durationMs/1e3}:{},...M.details?.taskId?{taskId:M.details.taskId}:{}});if(ge.length>0)try{let St=await this.mediaPersistence.downloadAll(ge,{type:He,sessionId:this.currentSessionId||void 0},{warn:Ge=>this.log(Ge)});if(St.length>0){for(let Ge of St)ie=ie.replaceAll(Ge.remoteUrl,Ge.localPath);this.sendNotification("turn.media_persisted",{turnId:g,files:St.map(Ge=>({remoteUrl:Ge.remoteUrl,localPath:Ge.localPath,bytes:Ge.bytes,mimeType:Ge.mimeType}))})}}catch{}}if(pe==="task"&&!Z&&M.details?.taskList)try{let ge=M.details;ge?.taskList&&this.sendNotification("turn.todos_updated",{turnId:g,items:ge.taskList,summary:{total:ge.total??ge.taskList.length,completed:ge.completed??0,inProgress:ge.inProgress??0,notStarted:ge.notStarted??0}})}catch{}let Ce=Array.isArray(M.details?.matches)?M.details.matches:void 0,Gt=M.imageUrls;return{result:ie,error:ne,toolReferences:Ce,imageUrls:Gt}}catch(D){return{result:"",error:D instanceof Error?D.message:String(D)}}}},d=
|
|
1015
|
-
`)}}catch(W){return{success:!1,error:W.message}}},listResources:async S=>{let x=this.mcpManager;return x?(await x.listResources(S)).map(w=>({uri:w.uri,name:w.name,mimeType:w.mimeType,description:w.description,server:w.server})):[]},readResource:async(S,x)=>{let E=this.mcpManager;if(!E)throw new Error("MCP not initialized");return(await E.readResource(S,x)).map($=>({uri:$.uri,mimeType:$.mimeType,text:$.text}))},authenticate:async()=>({status:"unsupported",message:"OAuth not yet implemented in McpManager"})})),this.mcpReady=this.mcpManager.connectAll().then(()=>{this.mcpManager?.injectTools(),c.info(`[mcp] ${this.mcpManager?.getToolCount()??0} tools from ${this.mcpManager?.getConnectedServers().length??0} servers`)}).catch(S=>{c.warn(`[mcp] connection error: ${S instanceof Error?S.message:S}`)})}let y=[],b=vd();V.existsSync(b)&&y.push(b);let k=e?.pluginPaths;if(Array.isArray(k))for(let g of k)typeof g=="string"&&V.existsSync(g)&&y.push(g);
|
|
1013
|
+
\u76F4\u63A5\u8F93\u51FA SVG \u4EE3\u7801\uFF1A`,i="";for await(let c of r.transport.stream({model:r.model,messages:[{role:"user",content:o}],maxTokens:4e3},r.apiKey))c.type==="delta"&&(i+=c.text);let a=i.match(/<svg[\s\S]*?<\/svg>/i);if(!a)throw new Error(`Failed to generate SVG for state: ${t}`);return a[0]}async forgeGenerateSkeleton(e){let{buildSkeletonPrompt:t}=await Promise.resolve().then(()=>(Ro(),mb)),r=this.resolveClientForPurpose("textGeneration");if(!r)throw new Error("No model available for skeleton generation");let s=t(e),o="";for await(let a of r.transport.stream({model:r.model,messages:[{role:"user",content:s}],maxTokens:6e3},r.apiKey))a.type==="delta"&&(o+=a.text);let i=o.match(/<svg[\s\S]*?<\/svg>/i);if(!i)throw new Error("Failed to generate skeleton SVG");return i[0]}async forgeScoreConsistency(e,t,r,s){let{buildConsistencyPrompt:o,parseConsistencyResponse:i}=await Promise.resolve().then(()=>(Ao(),fb)),a=this.resolveClientForPurpose("imageUnderstanding");if(!a)throw new Error("No vision model available for consistency scoring");let c=o(s,r),l=`data:image/svg+xml;base64,${Buffer.from(e).toString("base64")}`,d=`data:image/svg+xml;base64,${Buffer.from(t).toString("base64")}`,u="";for await(let p of a.transport.stream({model:a.model,messages:[{role:"user",content:c,imageUrls:[l,d]}],maxTokens:200},a.apiKey))p.type==="delta"&&(u+=p.text);return i(u)}async petAwardXp(e){try{let{PetSoulService:t}=await Promise.resolve().then(()=>(wo(),Sl)),{PetGrowthEngine:r}=await Promise.resolve().then(()=>(To(),cb)),s=this.getActiveProjectRoot(),o=new t(s),i=o.load();if(!i)return;let a=r.xpForEvent(e),{newLevel:c,newXp:l,events:d,statBoosts:u}=r.processXpGain(i,a);i.level=c,i.experience=l;for(let[p,m]of Object.entries(u)){let h=p;i.stats[h]=Math.min(10,i.stats[h]+(m??0))}o.updateSoul(i),this.sendNotification("pet.growth",{level:c,experience:l,xpNeeded:r.xpForLevel(c)});for(let p of d)p.type==="molt"?this.sendNotification("pet.reaction",{text:`\u2728 \u8131\u58F3\u4E86\uFF01\u7B2C ${p.moltStage} \u6B21\u8715\u53D8`,style:"excited"}):p.type==="ability_unlock"&&p.ability&&this.sendNotification("pet.reaction",{text:`\u{1F389} \u89E3\u9501\uFF1A${p.ability.name}`,style:"excited"})}catch{}}isPetActive(){try{let e=Mo("node:fs"),t=Mo("node:path"),r=this.getActiveProjectRoot(),s=t.join(r,".qlogicagent","pet","soul.json");return e.existsSync(s)}catch{return!1}}pendingConfirms=new Map;async requestPetConfirm(e,t,r,s=3e4){let o=`confirm_${Date.now()}_${Math.random().toString(36).slice(2,8)}`;return this.sendNotification("pet.confirm",{confirmId:o,toolName:e,description:t,risk:r,timeoutMs:s}),new Promise(i=>{let a=setTimeout(()=>{this.pendingConfirms.delete(o),i(!1)},s+2e3);this.pendingConfirms.set(o,c=>{clearTimeout(a),i(c)})})}handlePetConfirmResponse(e){let{confirmId:t,approved:r}=e.params;this.permissionChecker&&this.permissionChecker.resolveApproval({approvalId:t,decision:r?"approved":"denied"});let s=this.pendingConfirms.get(t);s&&(this.pendingConfirms.delete(t),s(!!r)),e.id!=null&&this.sendResponse(e.id,{ok:!0})}async petReactionAfterTurn(e){try{let{maybeGenerateReaction:t,generateLLMReaction:r,PetSoulService:s}=await Promise.resolve().then(()=>(wo(),Sl)),o=this.getActiveProjectRoot(),a=new s(o).load();if(a){let l=this.resolveClientForPurpose("smallModel");if(l){let d=[...e].reverse().find(m=>m.role==="assistant"),u=typeof d?.content=="string"?d.content.slice(0,100):"\u5B8C\u6210\u4E86\u4E00\u4E2A\u4EFB\u52A1",p=await r({turnSummary:u,soul:a},async(m,h)=>{let f="";for await(let y of l.transport.stream({model:l.model,messages:[{role:"user",content:m}],maxTokens:h},l.apiKey))y.type==="delta"&&(f+=y.text);return f.trim()||null});if(p){this.sendNotification("pet.reaction",{text:p.text,style:p.style,duration:1e4});return}}}let c=t("turn.end");c&&this.sendNotification("pet.reaction",{text:c.text,style:c.style,duration:1e4})}catch{}}ensureMemoryProvider(){if(!this.memoryProvider)try{let e=ka(this.getActiveProjectRoot()),t=va(e);if(t.provider){this.memoryProvider=t.provider;let r=process.env.QLOGIC_LLMROUTER_USER_ID?.trim();r&&(this.memoryUserId=r)}}catch{}}resolveAgent(e){let t=e.provider,r=e.model,s=e.apiKey,o=e.baseUrl;if(!t||!s){let S=Y().getActiveModel("textGeneration");S&&(t=t??S.provider,r=r??S.model,s=s??S.apiKey,o=o??S.baseUrl,S.keyHandle.release({success:!0}),this.log(`[resolveAgent] from ModelRegistry: ${t}/${r}`))}if(!t||!s)return null;r=r??Y().getProviderDefaultModel(t)??"";let i=`${t}:${r}:${s.slice(0,8)}:${o??""}`;if(this.agent&&this.lastLlmConfigKey===i)return e.model=r,e.provider=t,e.apiKey=s,o&&(e.baseUrl=o),this.agent;e.model=r,e.provider=t,e.apiKey=s,o&&(e.baseUrl=o);let a=Sb({provider:t,model:r,apiKey:s,baseUrl:o},this.registry);J_()&&(a.transport=Q_(a.transport,this.currentSessionId||"default"));let c={info:g=>this.log(g),warn:g=>this.log(`[warn] ${g}`),error:g=>this.log(`[error] ${g}`),debug:g=>{this.verbose&&this.log(`[debug] ${g}`)}},l={invoke:async(g,S,x,E)=>{if(S.startsWith("$"))return{result:x};let w=tt(S);if(!w)return{result:"",error:`Unknown tool: ${S}`};let $=`tc_${kt().slice(0,8)}`;try{let D=JSON.parse(x),M=await w.execute($,D,E),W=[],ie=M.content.map(ge=>{if(ge.type==="image"&&ge.data){let Nt=ge.mimeType||"image/png";return W.push(`data:${Nt};base64,${ge.data}`),"[Image]"}return ge.text??""}).join(`
|
|
1014
|
+
`);W.length>0&&(M.imageUrls=[...W,...M.imageUrls??[]]);let Z=M.details?.error,ne=Z?ie:void 0,pe=M.details?.type,He=pe?.split("_")[0];if(pe==="three_d_generate"&&(He="3d"),He&&["image","tts","video","music","3d"].includes(He)){let ge=M.details?.mediaUrls??[],Nt=He;for(let St of ge)this.sendNotification("turn.media_result",{turnId:g,mediaType:Nt,url:St,model:M.details?.model,provider:M.details?.provider,...M.details?.durationMs?{durationSeconds:M.details.durationMs/1e3}:{},...M.details?.taskId?{taskId:M.details.taskId}:{}});if(ge.length>0)try{let St=await this.mediaPersistence.downloadAll(ge,{type:He,sessionId:this.currentSessionId||void 0},{warn:Ge=>this.log(Ge)});if(St.length>0){for(let Ge of St)ie=ie.replaceAll(Ge.remoteUrl,Ge.localPath);this.sendNotification("turn.media_persisted",{turnId:g,files:St.map(Ge=>({remoteUrl:Ge.remoteUrl,localPath:Ge.localPath,bytes:Ge.bytes,mimeType:Ge.mimeType}))})}}catch{}}if(pe==="task"&&!Z&&M.details?.taskList)try{let ge=M.details;ge?.taskList&&this.sendNotification("turn.todos_updated",{turnId:g,items:ge.taskList,summary:{total:ge.total??ge.taskList.length,completed:ge.completed??0,inProgress:ge.inProgress??0,notStarted:ge.notStarted??0}})}catch{}let Ce=Array.isArray(M.details?.matches)?M.details.matches:void 0,Gt=M.imageUrls;return{result:ie,error:ne,toolReferences:Ce,imageUrls:Gt}}catch(D){return{result:"",error:D instanceof Error?D.message:String(D)}}}},d=tu(c);this.currentHooks=d,this.taskStore.setHooks(d,this.currentSessionId??""),Im({onTaskCreated:g=>{d.invoke("task.created",{sessionId:this.currentSessionId??"",taskId:String(g.id),taskType:"planning",label:g.title}).catch(()=>{})},onTaskCompleted:g=>{d.invoke("task.completed",{sessionId:this.currentSessionId??"",taskId:String(g.id),taskType:"planning",label:g.title}).catch(()=>{})}});let u=ka(this.getActiveProjectRoot()),p=va(u);if(p.provider){this.memoryProvider=p.provider;let g=process.env.QLOGIC_LLMROUTER_USER_ID?.trim();this.memoryUserId=g||this.memoryUserId,this.memoryUserId&&cu(d,{memoryProvider:p.provider,localMemoryProvider:p.provider,userId:this.memoryUserId,log:{debug:S=>c.debug(S),warn:S=>c.warn(S)},getLastUserMessage:()=>this.lastUserMessageForAutoExtract,getLastAssistantMessage:()=>this.lastAssistantMessageForExtract,llmExtract:async S=>{let x=this.resolveClientForPurpose("smallModel");if(!x)return null;try{let E="";for await(let w of x.transport.stream({model:x.model,messages:[{role:"user",content:S}],tools:[],maxTokens:512},x.apiKey))w.type==="delta"&&(E+=w.text);return E.trim()||null}catch{return null}}},this.memoryPrefetchState),c.info("[memory] local provider initialized")}else p.error&&c.warn(`[memory] provider unavailable: ${p.error}`);ku(d,{currentCwd:this.getActiveProjectRoot(),log:{debug:g=>c.debug(g),warn:g=>c.warn(g)}}),$d(d,c,{transport:a.transport,apiKey:a.apiKey});let m=e?.mcpServers,h=bc(m??{}),f=Sd();try{if(V.existsSync(f)){let g=JSON.parse(V.readFileSync(f,"utf8")),S=bc(g),x=new Set(h.map(E=>E.name));h=[...h,...S.filter(E=>!x.has(E.name))]}}catch{}if(h.length>0){this.mcpManager&&this.mcpManager.disconnectAll().catch(()=>{}),this.mcpManager=new Ds({servers:h,log:c}),gn(async()=>{await this.mcpManager?.disconnectAll()});let g=()=>this.mcpManager;Pe(Om(g)),Pe(Lm(g)),Pe(ag({listServers:async()=>{let S=this.mcpManager;return S?S.getConnectedServers().map(E=>({name:E,status:"connected",transport:"stdio",toolCount:0,resourceCount:0,promptCount:0})):[]},listTools:async S=>{if(!this.mcpManager)return[];let E=`mcp__${S.replace(/[^a-zA-Z0-9_]/g,"_").toLowerCase()}__`;return Xt().filter(w=>w.startsWith(E)).map(w=>({name:w.slice(E.length),prefixedName:w}))},callTool:async(S,x,E,w)=>{let D=`mcp__${S.replace(/[^a-zA-Z0-9_]/g,"_").toLowerCase()}__`+x,M=tt(D);if(!M)return{success:!1,error:`Tool not found: ${D}`};try{return{success:!0,content:(await M.execute(`mcp_${Date.now()}`,E??{},w)).content.map(Z=>Z.text??"").join(`
|
|
1015
|
+
`)}}catch(W){return{success:!1,error:W.message}}},listResources:async S=>{let x=this.mcpManager;return x?(await x.listResources(S)).map(w=>({uri:w.uri,name:w.name,mimeType:w.mimeType,description:w.description,server:w.server})):[]},readResource:async(S,x)=>{let E=this.mcpManager;if(!E)throw new Error("MCP not initialized");return(await E.readResource(S,x)).map($=>({uri:$.uri,mimeType:$.mimeType,text:$.text}))},authenticate:async()=>({status:"unsupported",message:"OAuth not yet implemented in McpManager"})})),this.mcpReady=this.mcpManager.connectAll().then(()=>{this.mcpManager?.injectTools(),c.info(`[mcp] ${this.mcpManager?.getToolCount()??0} tools from ${this.mcpManager?.getConnectedServers().length??0} servers`)}).catch(S=>{c.warn(`[mcp] connection error: ${S instanceof Error?S.message:S}`)})}let y=[],b=vd();V.existsSync(b)&&y.push(b);let k=e?.pluginPaths;if(Array.isArray(k))for(let g of k)typeof g=="string"&&V.existsSync(g)&&y.push(g);Fm(y,c).then(g=>{if(g.length===0)return;this.pluginLoader=new Os({pluginDirs:g,hookRegistry:d,log:c}),this.pluginLoader.loadAll().then(x=>{c.info(`[plugins] ${x.length} loaded, ${this.pluginLoader?.getPluginSkills().length??0} skills`)}).catch(x=>{c.warn(`[plugins] load error: ${x instanceof Error?x.message:x}`)});let S=this.pluginLoader;d.register({point:"turn.submitted",handler:async()=>(await S.discoverNew(),await S.refreshActivations(),{action:"continue"}),label:"plugin-activation-refresh",priority:50})}).catch(g=>{c.warn(`[plugins] marketplace resolve error: ${g instanceof Error?g.message:g}`)});let A=e?.permissions,_=$s(A),I=new Ls(_);if(_.mode,Oe()?.type==="group"){let g=km();for(let S of g)I.addRule(S);gc(!0),c.info(`[permissions] group security mode active: ${g.length} rules injected`)}else gc(!1);this.permissionUnregister&&this.permissionUnregister(),this.permissionChecker=new Fs({ruleEngine:I,hookRegistry:d,auditLogger:new Us(this.getActiveProjectRoot()),sessionId:this.currentSessionId,getTurnId:()=>this.currentTurnId,onRequestApproval:async g=>{if(this.acpServer&&this.acpServer.sessionId)try{let S=await this.acpServer.requestPermission({sessionId:this.acpServer.sessionId,permissionId:g.approvalId,toolCall:{callId:g.callId,toolName:g.toolName,arguments:g.arguments?JSON.stringify(g.arguments):""},message:g.message,options:[{id:"allow",label:"Allow"},{id:"deny",label:"Deny"},{id:"allowAlways",label:"Always allow",persistent:!0}]});return{approvalId:g.approvalId,decision:S.optionId==="allow"||S.optionId==="allowAlways"?"approved":"denied"}}catch{return{approvalId:g.approvalId,decision:"denied"}}if(this.sendNotification("tool.approval.request",{approvalId:g.approvalId,callId:g.callId,toolName:g.toolName,arguments:g.arguments?JSON.stringify(g.arguments):"",message:g.message,suggestions:g.suggestions?.map(S=>`${S.pattern}:${S.behavior}`)}),this.isPetActive()){let S=g.toolName.match(/delete|rm|drop|reset|force/i)?"high":g.toolName.match(/write|exec|bash|shell|move/i)?"medium":"low";this.sendNotification("pet.confirm",{confirmId:g.approvalId,toolName:g.toolName,description:g.message??`\u5141\u8BB8\u6267\u884C ${g.toolName}\uFF1F`,risk:S,timeoutMs:3e4})}return new Promise(()=>{})},onPermissionUpdate:g=>{c.info(`[permissions] rule saved: ${g.pattern} \u2192 ${g.behavior}`),this.sendNotification("permission.rule_updated",{pattern:g.pattern,behavior:g.behavior})},onDenied:(g,S)=>{c.warn(`[permissions] blocked "${g}": ${S}`)}});let L=wt();this.permissionChecker.setToolMeta(L),this.permissionUnregister=this.permissionChecker.register();let F=Tt(this.getActiveProjectRoot()),T=[F,Dt(),...Array.isArray(e?.skillPaths)?e.skillPaths:[]];Pe(Qm({listSkills:()=>{let g=[];this.pluginLoader&&g.push(...this.pluginLoader.getPluginSkills());let S=e?.skillPaths;if(Array.isArray(S)){for(let x of S)if(typeof x=="string"){let E=ee.basename(x);g.some(w=>w.name===E)||g.push({name:E,source:"gateway",filePath:ee.join(x,"SKILL.md"),baseDir:x})}}return g},listSkillsFull:async g=>{let S=[],x=new Set,E=Dt();for(let w of T)try{let $=await V.promises.readdir(w,{withFileTypes:!0});for(let D of $){if(!D.isDirectory())continue;let M=ee.join(w,D.name,"SKILL.md");try{let W=await V.promises.readFile(M,"utf8"),ie=ee.basename(w);if(g&&ie!==g)continue;x.add(ie);let Z=w===E?"global":w===F?"project":"config",pe=W.match(/^---\n[\s\S]*?^version:\s*(\S+)/m)?.[1],He=W.startsWith(`---
|
|
1016
1016
|
`)?W.indexOf("---",4):-1,ge=(He>=0?W.slice(He+3).trimStart():W).split(`
|
|
1017
1017
|
`).find(Nt=>Nt.trim()&&!Nt.startsWith("#"))?.trim()??`Skill from ${ie}`;S.push({name:D.name,description:ge,category:ie,scope:Z,version:pe})}catch{}}}catch{}if(this.pluginLoader)for(let w of this.pluginLoader.getPluginSkills())g&&w.source!==g||(x.add(w.source??"plugin"),S.push({name:w.name,description:`Plugin skill (${w.source})`,category:w.source,scope:"plugin"}));return{skills:S,categories:[...x]}},readSkillContent:async g=>{for(let S of T){let x=ee.join(S,g,"SKILL.md");try{return await V.promises.readFile(x,"utf8")}catch{}}return null},viewSkill:async(g,S)=>{for(let x of T){let E=S?ee.join(x,g,S):ee.join(x,g,"SKILL.md");try{let w=await V.promises.readFile(E,"utf8");return{name:g,content:w}}catch{}}return null},executeSkillSubturn:async(g,S,x,E)=>{let w=`skill_${g}_${kt().slice(0,8)}`,$=this.agent;if(!$)return"[skill] Cannot execute: no LLM provider configured";let D=q(),M=this.currentSessionId??"skill";this.currentHooks?.invoke("subagent.started",{sessionId:M,turnId:w,subagentId:w,agentType:`skill:${g}`}).catch(()=>{});let W=new Set(["skill","agent"]),ie=wt().filter(Ce=>!W.has(Ce.function.name)),Z=x??`Execute skill "${g}" instructions.`,ne=[],pe;for await(let Ce of $.run({turnId:w,sessionId:M,messages:[{role:"user",content:Z}],tools:ie,systemPrompt:S,config:{parentDepth:1,maxRounds:5}},E)){if(Ce.type==="end"&&Ce.content){this.currentHooks?.invoke("subagent.stopped",{sessionId:M,turnId:w,subagentId:w,agentType:`skill:${g}`,reason:"normal"}).catch(()=>{}),Zs(D,g,!0);let Gt=Be(D);return Kc(Gt,g),We(D,Gt),Ce.content}if(Ce.type==="delta"&&Ce.text&&ne.push(Ce.text),Ce.type==="error"){pe=Ce.error;break}}if(this.currentHooks?.invoke("subagent.stopped",{sessionId:M,turnId:w,subagentId:w,agentType:`skill:${g}`,reason:pe?"error":"normal",error:pe}).catch(()=>{}),pe)return Zs(D,g,!1),`[skill "${g}"] error: ${pe}`;Zs(D,g,!0);let He=Be(D);return Kc(He,g),We(D,He),ne.join("")||`[skill "${g}"] completed (no output)`},manageSkill:async g=>{let S=this.getActiveProjectRoot(),x=Tt(S),E=ee.join(x,g.name),w=ee.join(E,"SKILL.md"),$=q();switch(g.action){case"create":{let D=g.content??"",W=Yc(D,g.name,`Skill: ${g.name}`)??D,ie=no(W,g.name);if(!ie.valid)return{success:!1,message:`Skill validation failed: ${ie.errors.join("; ")}`};let Z=Be($);if(Z.records[g.name]?.pinned&&V.existsSync(w))return{success:!1,message:`Skill "${g.name}" is pinned. Unpin it first.`};if(await V.promises.mkdir(E,{recursive:!0}),await V.promises.writeFile(w,W,"utf8"),this.sendNotification("turn.skill_instruction",{turnId:`skill-create-${Date.now()}`,instruction:{name:g.name,category:g.category??"learned",content:W,scope:"project"}}),pt(),qt(Z,g.name,"created"),We($,Z),this.memoryProvider&&this.memoryUserId){let pe=W.split(`
|
|
1018
|
-
`).slice(0,3).join(" ").slice(0,200),He=S?ee.basename(S):"unknown";this.memoryProvider.ingestExtracted([{text:`Learned skill "${g.name}" in project "${He}": ${pe}`,category:"skill-learning"}],this.memoryUserId).catch(()=>{})}let ne=S?` (project-scoped). To make it available across all projects, use: skill promote name:"${g.name}"`:"";return{success:!0,message:`Skill "${g.name}" created${ne}`,path:E}}case"edit":{let D=Be($);if(D.records[g.name]?.pinned)return{success:!1,message:`Skill "${g.name}" is pinned. Unpin it first.`};let M=g.content??"",ie=Yc(M,g.name)??M;return await V.promises.writeFile(w,ie,"utf8"),Vc(D,g.name),We($,D),this.sendNotification("turn.skill_instruction",{turnId:`skill-edit-${Date.now()}`,instruction:{name:g.name,category:g.category??"learned",content:ie,scope:"project"}}),{success:!0,message:`Skill "${g.name}" updated`,path:w}}case"patch":{let D=Be($);if(D.records[g.name]?.pinned)return{success:!1,message:`Skill "${g.name}" is pinned. Unpin it first.`};let M=await V.promises.readFile(w,"utf8");if(!g.oldString||!M.includes(g.oldString))return{success:!1,message:"oldString not found in SKILL.md"};let W=M.replace(g.oldString,g.newString??"");return await V.promises.writeFile(w,W,"utf8"),Vc(D,g.name),We($,D),this.sendNotification("turn.skill_instruction",{turnId:`skill-patch-${Date.now()}`,instruction:{name:g.name,category:g.category??"learned",content:W,scope:"project"}}),{success:!0,message:`Skill "${g.name}" patched`,path:w}}case"delete":{let D=Be($);return D.records[g.name]?.pinned?{success:!1,message:`Skill "${g.name}" is pinned. Unpin it first.`}:(await V.promises.rm(E,{recursive:!0,force:!0}),eo(D,g.name),We($,D),this.sendNotification("turn.skill_instruction",{turnId:`skill-delete-${Date.now()}`,instruction:{name:g.name,category:g.category??"learned",action:"delete",scope:"project"}}),pt(),{success:!0,message:`Skill "${g.name}" deleted`})}default:return{success:!1,message:`Unknown action: ${g.action}`}}},promoteSkill:async g=>{let S=Tt(this.getActiveProjectRoot()),x=ee.join(S,g,"SKILL.md");try{await V.promises.access(x)}catch{return{success:!1,message:`Skill "${g}" not found in project skills. Cannot promote.`}}let E=Dt(),w=ee.join(E,g);await V.promises.mkdir(w,{recursive:!0});let $=ee.join(S,g),D=await V.promises.readdir($);for(let M of D){let W=await V.promises.readFile(ee.join($,M));await V.promises.writeFile(ee.join(w,M),W)}return this.sendNotification("turn.skill_instruction",{turnId:`skill-promote-${Date.now()}`,instruction:{name:g,category:"promoted",content:await V.promises.readFile(x,"utf8"),scope:"global"}}),await V.promises.rm($,{recursive:!0,force:!0}),this.sendNotification("turn.skill_instruction",{turnId:`skill-promote-cleanup-${Date.now()}`,instruction:{name:g,category:"learned",action:"delete",scope:"project"}}),pt(),{success:!0,message:`Skill "${g}" promoted to global (user-level) and removed from project scope. It will now be available across all projects.`,path:w}},installSkill:async(g,S)=>{let x;try{if(x=new URL(g),!["http:","https:"].includes(x.protocol))return{success:!1,message:`Invalid URL scheme: ${x.protocol}. Only http/https allowed.`}}catch{return{success:!1,message:`Invalid URL: ${g}`}}let E=S??Z_(x);if(!E)return{success:!1,message:"Cannot derive skill name from URL. Please provide 'name' parameter."};try{let w=await fetch(g,{signal:AbortSignal.timeout(3e4)});if(!w.ok)return{success:!1,message:`Download failed: HTTP ${w.status} ${w.statusText}`};let $=w.headers.get("content-length");if($&&parseInt($,10)>512e3)return{success:!1,message:"Content too large (>512KB). Skill files should be small markdown documents."};let D=await w.text();if(!D.trim())return{success:!1,message:"Downloaded content is empty."};if(D.length>512e3)return{success:!1,message:"Content too large (>512KB). Skill files should be small markdown documents."};if(D.trimStart().startsWith("<!DOCTYPE")||D.trimStart().startsWith("<html"))return{success:!1,message:"URL returned an HTML page, not a raw markdown file. Use a raw/direct download link."};let M=Dt(),W=ee.join(M,E);return await V.promises.mkdir(W,{recursive:!0}),await V.promises.writeFile(ee.join(W,"SKILL.md"),D,"utf8"),this.sendNotification("turn.skill_instruction",{turnId:`skill-install-${Date.now()}`,instruction:{name:E,category:"installed",content:D,scope:"global"}}),pt(),{success:!0,message:`Skill "${E}" installed from ${x.host}. Available globally across all projects.`,path:W}}catch(w){return{success:!1,message:`Install failed: ${w instanceof Error?w.message:String(w)}`}}}})),Pe(eg({abortSignal:void 0,currentForkDepth:0,forkAgent:async g=>{let S=rs(g.agent);if(!S)return{agentId:"",status:"failed",error:`Unknown agent type: ${g.agent}`};if(!this.agent||!this.currentTransport||!this.currentApiKey||!this.currentModel)return{agentId:"",status:"failed",error:"No LLM provider configured"};let x=Xt(),E=Bi(x,S),$=wt().filter(ne=>E.includes(ne.function.name)),D=Pa($,!0),M=g.maxTurns??S.maxTurns??200;if(Re.isTeamBudgetExceeded())return{agentId:`fork-${g.agent}-budget-exceeded`,status:"failed",output:void 0,error:Re.teamBudgetExceededError(),tokensUsed:0};let W=await $c({promptMessages:[{role:"user",content:g.prompt}],tools:D,transport:this.currentTransport,toolInvoker:l,apiKey:this.currentApiKey,model:this.currentModel,log:c,hooks:d,forkLabel:`agent-${g.agent}`,maxTurns:M,parentSignal:g.abortSignal,parentDepth:0,onEvent:ne=>{ne.type==="delta"&&ne.text&&this.sendNotification("turn.subagent_delta",{agentType:g.agent,text:ne.text})}}),ie=W.events.filter(ne=>ne.type==="end"&&"content"in ne).map(ne=>ne.content??"").join("")||W.events.filter(ne=>ne.type==="delta"&&"text"in ne).map(ne=>ne.text).join(""),Z=W.totalUsage.inputTokens+W.totalUsage.outputTokens;return Re.recordForkTokens(Z),{agentId:`fork-${g.agent}-${kt().slice(0,8)}`,status:W.ok?"completed":"failed",output:ie||void 0,error:W.error,tokensUsed:Z}}}));let ce=it(),le=new Map([["model",{key:"model",value:this.currentModel??"",type:"string",description:"Default LLM model"}],["language",{key:"language",value:"zh-cn",type:"string",description:"UI / response language"}],["verbose",{key:"verbose",value:this.verbose,type:"boolean",description:"Enable verbose logging"}],["maxRounds",{key:"maxRounds",value:25,type:"number",description:"Default max tool-call rounds per turn"}],["theme",{key:"theme",value:"auto",type:"enum",description:"Color theme",options:["auto","light","dark"]}]]),j=async()=>{try{return JSON.parse(await V.promises.readFile(ce,"utf8"))}catch{return{}}},ve=async g=>{await V.promises.mkdir(ee.dirname(ce),{recursive:!0}),await V.promises.writeFile(ce,JSON.stringify(g,null,2),"utf8")};Pe(tg({getConfig:async g=>{let S=le.get(g);if(!S)return{success:!1,error:`Unknown key: ${g}`};let x=await j(),E=g in x?x[g]:S.value;return{success:!0,setting:{...S,value:E,readOnly:Sr.includes(g)}}},setConfig:async(g,S)=>{let x=le.get(g);if(!x)return{success:!1,error:`Unknown key: ${g}`};let E=await j(),w=g in E?E[g]:x.value;return E[g]=S,await ve(E),{success:!0,previousValue:w,setting:{...x,value:S}}},listConfig:async()=>{let g=await j();return{success:!0,settings:[...le.values()].map(x=>({...x,value:x.key in g?g[x.key]:x.value,readOnly:Sr.includes(x.key)}))}},resetConfig:async g=>{let S=le.get(g);if(!S)return{success:!1,error:`Unknown key: ${g}`};let x=await j();return delete x[g],await ve(x),{success:!0,setting:S}},isValidKey:g=>le.has(g)}));let oe=new Map,$e=g=>{let S=/^(\d+)([smhd])$/.exec(g.trim());if(!S)return null;let x=parseInt(S[1],10),E=S[2];return x*({s:1e3,m:6e4,h:36e5,d:864e5}[E]??6e4)},te=g=>{g.timerId&&clearTimeout(g.timerId);let S=$e(g.schedule);if(!S)return;let x=Date.now(),E=S-x%S||S;g.timerId=setTimeout(()=>{g.lastRunAt=new Date().toISOString(),g.repeat.completed++,g.lastStatus="success",c.info(`[cron] triggered job ${g.id} (${g.name})`),this.sendNotification("system.activity",{category:"cron",level:"info",title:`\u5B9A\u65F6\u4EFB\u52A1\u89E6\u53D1: ${g.name}`,detail:`\u8C03\u5EA6 ${g.scheduleDisplay}\uFF0C\u7B2C ${g.repeat.completed} \u6B21\u6267\u884C`}),g.repeat.times===null||g.repeat.completed<g.repeat.times?te(g):(g.state="paused",g.enabled=!1,this.sendNotification("system.activity",{category:"cron",level:"info",title:`\u5B9A\u65F6\u4EFB\u52A1\u5B8C\u6210: ${g.name}`,detail:`\u5DF2\u8FBE\u5230\u6700\u5927\u6267\u884C\u6B21\u6570 (${g.repeat.completed}\u6B21)`}))},E),g.nextRunAt=new Date(x+E).toISOString()};gn(async()=>{for(let g of oe.values())g.timerId&&clearTimeout(g.timerId)}),Pe(rg({createJob:async g=>{let S=`cron_${kt().slice(0,8)}`,x={id:S,name:g.name??`Job ${S}`,prompt:g.prompt,schedule:g.schedule,scheduleDisplay:g.schedule,state:"scheduled",enabled:!0,repeat:{times:g.repeat??null,completed:0},allowedTools:g.allowedTools};return oe.set(S,x),te(x),{success:!0,job:{...x,timerId:void 0}}},listJobs:async()=>({success:!0,jobs:[...oe.values()].map(S=>({...S,timerId:void 0}))}),getJob:async g=>{let S=oe.get(g);return S?{success:!0,job:{...S,timerId:void 0}}:{success:!1,error:`Job not found: ${g}`}},updateJob:async(g,S)=>{let x=oe.get(g);return x?(S.prompt!==void 0&&(x.prompt=S.prompt),S.schedule!==void 0&&(x.schedule=S.schedule,x.scheduleDisplay=S.schedule),S.name!==void 0&&(x.name=S.name),S.enabled!==void 0&&(x.enabled=S.enabled,x.state=S.enabled?"scheduled":"paused"),S.repeat!==void 0&&(x.repeat.times=S.repeat),S.allowedTools!==void 0&&(x.allowedTools=S.allowedTools),x.enabled?te(x):x.timerId&&(clearTimeout(x.timerId),x.timerId=void 0),{success:!0,job:{...x,timerId:void 0}}):{success:!1,error:`Job not found: ${g}`}},deleteJob:async g=>{let S=oe.get(g);return S?(S.timerId&&clearTimeout(S.timerId),oe.delete(g),{success:!0}):{success:!1,error:`Job not found: ${g}`}},pauseJob:async g=>{let S=oe.get(g);return S?(S.state="paused",S.enabled=!1,S.timerId&&(clearTimeout(S.timerId),S.timerId=void 0),{success:!0,job:{...S,timerId:void 0}}):{success:!1,error:`Job not found: ${g}`}},resumeJob:async g=>{let S=oe.get(g);return S?(S.state="scheduled",S.enabled=!0,te(S),{success:!0,job:{...S,timerId:void 0}}):{success:!1,error:`Job not found: ${g}`}},triggerJob:async g=>{let S=oe.get(g);return S?(S.lastRunAt=new Date().toISOString(),S.repeat.completed++,S.lastStatus="success",{success:!0,job:{...S,timerId:void 0}}):{success:!1,error:`Job not found: ${g}`}},validateSchedule:g=>$e(g)!==null||/^\d{1,2}\s/.test(g)?null:`Invalid schedule: ${g}. Use shorthand (5m, 1h, 1d) or cron expression.`}));let J=new Map;gn(async()=>{for(let g of J.values())g.cleanup();J.clear()}),Pe(sg({startMonitor:async g=>{if(J.has(g.monitorId))return{action:"start",success:!1,error:`Monitor "${g.monitorId}" already exists.`};let S={monitorId:g.monitorId,source:g.source,target:g.target,conditions:g.conditions,startedAt:Date.now(),timeoutSeconds:g.timeoutSeconds,eventCount:0},x=()=>{};if(g.source==="file")try{let E=V.watch(g.target,{persistent:!1},()=>{S.eventCount++,c.info(`[monitor] file change detected: ${g.target}`)});x=()=>E.close()}catch{return{action:"start",success:!1,error:`Cannot watch: ${g.target}`}}if(g.timeoutSeconds>0){let E=setTimeout(()=>{let $=J.get(g.monitorId);$&&($.cleanup(),J.delete(g.monitorId))},g.timeoutSeconds*1e3),w=x;x=()=>{clearTimeout(E),w()}}return J.set(g.monitorId,{info:S,cleanup:x}),{action:"start",success:!0,monitorId:g.monitorId}},stopMonitor:async g=>{let S=J.get(g);return S?(S.cleanup(),J.delete(g),{action:"stop",success:!0,monitorId:g}):{action:"stop",success:!1,error:`Monitor "${g}" not found.`}},listMonitors:async()=>[...J.values()].map(g=>g.info)}));let R=new Map,B={info:g=>c.info(g),warn:g=>c.warn(g)},U=new _t({onNotification:(g,S,x)=>{this.sendNotification("team.member.notification",{memberId:g,method:S,params:x})},onStateChange:(g,S)=>{this.sendNotification("team.member.state",{memberId:g,state:S});let x=U.getHandle(g),w=U.getUsageTracker(g)?.getUsage();this.emitAgentStatus(g,S,{missedBeats:U.getMissedBeats(g),lastActivityAt:x?.lastActivityAt,usage:w&&w.totalTokens>0?{inputTokens:w.inputTokens,outputTokens:w.outputTokens,totalTokens:w.totalTokens}:void 0})},onExit:(g,S,x)=>{for(let E of R.values()){let w=E.members.find($=>$.cwd&&`team-${E.name}-${$.name}`.replace(/[^a-zA-Z0-9-]/g,"-").toLowerCase()===g.replace(/^team-/,""));w&&(w.isActive=!1)}c.info(`[team] member ${g} exited (code=${S}, signal=${x})`)},onMcpToolCall:(g,S,x)=>this.handleMcpToolCall(g,S,x),log:{info:g=>c.info(g),warn:g=>c.warn(g),debug:g=>c.debug(g)},sessionDir:ee.join(q(),"agent-logs")});gn(async()=>{U.dispose()}),Pe(og({createTeam:async g=>{if(R.has(g.teamName))return{success:!1,error:`Team "${g.teamName}" already exists.`};let S=await mr(),x=[];for(let w of g.members??[]){let $={...w,isActive:!0};if(S){let D=`team-${g.teamName}-${w.name}`.replace(/[^a-zA-Z0-9-]/g,"-").toLowerCase(),M=await qp(S,D,B);M?($.worktreePath=M.worktreePath,$.worktreeBranch=M.branch,$.cwd=M.worktreePath,c.info(`[team] provisioned worktree for ${w.name}: ${M.worktreePath}`)):($.cwd=process.cwd(),c.warn(`[team] worktree provision failed for ${w.name}, using shared cwd`))}else $.cwd=process.cwd();x.push($)}let E={name:g.teamName,description:g.description,leadId:this.currentSessionId??"default",members:x,createdAt:new Date().toISOString()};R.set(g.teamName,E);for(let w of x){if(!w.cwd)continue;let $=`team-${g.teamName}-${w.name}`.replace(/[^a-zA-Z0-9-]/g,"-").toLowerCase();try{await U.spawn({memberId:$,name:w.name,cwd:w.cwd,prompt:`You are the "${w.name}" team member. Role: ${w.role}.`,agentType:w.role,verbose:this.verbose}),c.info(`[team] spawned child process for ${w.name} in ${w.cwd}`)}catch(D){c.warn(`[team] failed to spawn child process for ${w.name}: ${D instanceof Error?D.message:String(D)}`),w.isActive=!1}}return this.sendNotification("team.updated",{teamName:g.teamName,action:"created",members:E.members.map(w=>({agentName:w.name,role:w.role,worktreePath:w.worktreePath,pid:U.getHandle(`team-${g.teamName}-${w.name}`.replace(/[^a-zA-Z0-9-]/g,"-").toLowerCase())?.pid}))}),{success:!0,team:E}},deleteTeam:async g=>{let S=R.get(g);if(!S)return{success:!1,error:`Team "${g}" not found.`};for(let E of S.members){let w=`team-${g}-${E.name}`.replace(/[^a-zA-Z0-9-]/g,"-").toLowerCase();U.kill(w),U.remove(w)}let x=await mr();if(x)for(let E of S.members)E.worktreePath&&E.worktreeBranch&&(await Wp(x,E.worktreePath,E.worktreeBranch,B),c.info(`[team] cleaned up worktree for ${E.name}: ${E.worktreePath}`));return R.delete(g),this.sendNotification("team.updated",{teamName:g,action:"destroyed",members:[]}),{success:!0}},listTeams:async()=>({success:!0,teams:[...R.values()]}),getTeamStatus:async g=>{let S=R.get(g);if(!S)return{success:!1,error:`Team "${g}" not found.`};let x={};for(let E of S.members){let w=`team-${g}-${E.name}`.replace(/[^a-zA-Z0-9-]/g,"-").toLowerCase(),$=U.getStatus(w);$&&(E.isActive=$.alive,x[E.name]={mediaProgress:$.mediaProgress,lastToolCall:$.lastToolCall,idleFor:$.idleFor,runningFor:$.runningFor})}return{success:!0,team:S,memberProgress:x}}}));{let g=this.memdir;Pe({name:Pg,label:Ig,description:Eg,parameters:_g,execute:async(S,x)=>{let E=await Cg(x,{memdir:g,provider:this.memoryUserId?this.memoryProvider??void 0:void 0,localProvider:this.memoryUserId?this.memoryProvider??void 0:void 0,userId:this.memoryUserId});return{content:[{type:"text",text:E.message}],details:{type:"memory",action:E.action,ok:E.ok}}}})}cu(d,{getMemdir:()=>this.memdir,log:{debug:g=>c.debug(g),warn:g=>c.warn(g)}},this.memoryPrefetchState);{let g=e?.workdir??process.cwd(),S=lg(g,this.currentSessionId||"default");Pe(cg(S))}Pe(dg({sendNotification:async g=>(c.info(`[notify] ${g.title??""}: ${g.message}`),{delivered:!0,channel:g.channel??"cli"})})),Pe(ug({sendMessage:async g=>(c.info(`[send_message] ${g.senderId} \u2192 ${g.to}: ${g.message}`),{success:!0,recipients:[g.to]}),getSenderId:()=>this.currentSessionId??"default",listTeammates:()=>[]}));{let g=e?.workdir??process.cwd(),S,x=()=>(S||(S=Po.createContext({...{readFile:async w=>V.promises.readFile(ee.resolve(g,w),"utf8"),writeFile:async(w,$)=>{await V.promises.writeFile(ee.resolve(g,w),$,"utf8")},editFile:async(w,$)=>{let D=await V.promises.readFile(ee.resolve(g,w),"utf8");for(let M of $)D=D.replace(M.oldText,M.newText);return await V.promises.writeFile(ee.resolve(g,w),D,"utf8"),D},exec:async w=>{let $=await import("node:child_process");return new Promise(D=>{$.execFile("bash",["-c",w],{cwd:g,timeout:3e4},(M,W,ie)=>{D({stdout:W?.toString()??"",stderr:ie?.toString()??"",exitCode:M?M.code??1:0})})})},glob:async w=>{try{let{globSync:$}=await import("node:fs");return $(w,{cwd:g})}catch{return[]}},grep:async(w,$)=>{let D=[],M=ee.resolve(g,$??".");try{let W=await import("node:child_process"),ie=await new Promise(Z=>{W.execFile("grep",["-rn",w,M,"--include=*"],{timeout:1e4},(ne,pe)=>Z(pe?.toString()??""))});for(let Z of ie.split(`
|
|
1019
|
-
`).filter(Boolean).slice(0,100)){let ne=Z.match(/^(.+?):(\d+):(.*)$/);ne&&D.push({file:ne[1],line:parseInt(ne[2]),text:ne[3]})}}catch{}return D},console:{log:(...w)=>w.map(String).join(" ")}},setTimeout,clearTimeout,Promise,JSON,Math,Date,Array,Object,String,Number,Boolean,RegExp,Map,Set,Error,Buffer})),S);Pe(
|
|
1020
|
-
`)||"OK"}catch(i){return`Error: ${i instanceof Error?i.message:String(i)}`}}async ensureAgentConfigStore(){return this.agentConfigStore||(this.agentConfigStore=new Gs(this.getActiveProjectRoot()),await this.agentConfigStore.load(),this.acpDetector.setConfigStore(this.agentConfigStore.getData())),this.agentConfigStore}sendResponse(e,t,r){let s=this.rpcIds.get(e);if(s){let i=this.rpcContract.settle(s.requestId,t,r);if(this.clearRpcLifecycle(e),!i.accepted){this.log(`[rpc] dropped late response id=${String(e)} requestId=${s.requestId} reason=${i.reason}`);return}}let o={jsonrpc:"2.0",id:e};r?o.error=r:o.result=t,this.writeStdout(o)}sendContractError(e,t){let r={jsonrpc:"2.0",id:e,error:t};this.writeStdout(r)}sendContractErrorOrResult(e,t,r){if(r){this.sendContractError(e,r);return}let s={jsonrpc:"2.0",id:e,result:t};this.writeStdout(s)}scheduleRpcDeadline(e,t,r){let s=Math.max(0,r.deadlineAt-Date.now()),o=setTimeout(()=>{if(!this.rpcIds.has(e))return;let i=this.rpcContract.expire(r.requestId);this.clearRpcLifecycle(e),i&&(this.log(`[rpc] deadline exceeded method=${t} id=${String(e)} requestId=${r.requestId}`),this.writeStdout({jsonrpc:"2.0",id:e,error:{code:v.REQUEST_DEADLINE_EXCEEDED,message:`RPC request deadline exceeded: ${t}.`}}))},s);o.unref?.(),this.rpcDeadlineTimers.set(e,o)}clearRpcLifecycle(e){let t=this.rpcDeadlineTimers.get(e);t&&clearTimeout(t),this.rpcDeadlineTimers.delete(e),this.rpcIds.delete(e)}sendNotification(e,t){if(this.acpServer&&this.acpServer.sessionId)
|
|
1021
|
-
`)}enableIdleDream(e){Re.dream.enabled=!0,e&&e>0&&(Re.dream.idleMinutes=e),this.resetIdleDreamTimer()}resetIdleDreamTimer(){this.cancelIdleDreamTimer(),Re.dream.enabled&&this.currentSessionId&&(this.idleDreamTimer=setTimeout(()=>{this.triggerIdleDream()},Re.dream.idleMinutes*6e4),this.idleDreamTimer.unref?.())}cancelIdleDreamTimer(){this.idleDreamTimer&&(clearTimeout(this.idleDreamTimer),this.idleDreamTimer=null)}async triggerIdleDream(){if(Date.now()-Re.dream.lastDreamAt<Re.dream.cooldownMs){this.log("[dream:idle] Skipped \u2014 cooldown not elapsed");return}let e=this.resolveClientForPurpose("textGeneration");if(!e){this.log("[dream:idle] Skipped \u2014 no LLM transport configured");return}if(this.activeTurn){this.log("[dream:idle] Skipped \u2014 turn in progress");return}this.log("[dream:idle] Triggering idle dream consolidation"),Re.dream.lastDreamAt=Date.now(),this.sendNotification("system.activity",{category:"dream",level:"info",title:"\u7A7A\u95F2\u68A6\u5883\u6574\u7406\u89E6\u53D1",detail:`\u7A7A\u95F2 ${Re.dream.idleMinutes} \u5206\u949F\u540E\u81EA\u52A8\u89E6\u53D1`});let t=setTimeout(()=>{this.activeTurn&&(this.log("[dream:idle] Aborting \u2014 max duration reached"),this.activeTurn.abort())},Re.dream.maxDurationMs);t.unref?.();let r=q(),s=[];try{s=(await At(20,this.getActiveProjectRoot())).filter(a=>a.sessionId!==this.currentSessionId).map(a=>a.sessionId)}catch{}let o={jsonrpc:"2.0",id:void 0,method:"memory.dream",params:{turnId:`idle-dream-${kt().slice(0,8)}`,sessionId:this.currentSessionId,config:{memoryRoot:r,transcriptDir:ee.join(r,"agent-logs"),dreamSessionIds:s,currentSessionTurnCount:this.sessionState?.turnCount??0,model:e.model,apiKey:e.apiKey,force:!1}}};try{await uo.call(this,o)}finally{clearTimeout(t)}this.resetIdleDreamTimer()}initAcpServer(){let e={handleAcpInitialize:t=>this.acpHandleInitialize(t),handleAcpSessionNew:t=>this.acpHandleSessionNew(t),handleAcpSessionPrompt:t=>this.acpHandleSessionPrompt(t),handleAcpSessionEnd:t=>this.acpHandleSessionEnd(t),handleAcpSessionSetConfig:t=>this.acpHandleSessionSetConfig(t),handleAcpSessionSetModel:(t,r)=>this.acpHandleSessionSetModel(t,r),handleAcpSessionSetMode:(t,r)=>this.acpHandleSessionSetMode(t,r),handleAcpPermissionResponse:(t,r)=>this.acpHandlePermissionResponse(t,r),handleAcpAbort:t=>this.acpHandleAbort(t),handleAcpDream:t=>this.acpHandleDream(t),handleAcpAgentsList:()=>this.acpHandleAgentsList(),handleAcpSoloStart:t=>this.acpHandleSoloStart(t),handleAcpSoloStatus:t=>this.acpHandleSoloStatus(t),handleAcpSoloSelect:t=>this.acpHandleSoloSelect(t),handleAcpSoloCancel:t=>this.acpHandleSoloCancel(t),handleAcpSoloSubscribe:t=>this.acpHandleSoloSubscribe(t),handleAcpSoloMessage:t=>this.acpHandleSoloMessage(t),handleAcpSoloEvaluate:t=>this.acpHandleSoloEvaluate(t),handleAcpProductCreate:t=>this.acpHandleProductCreate(t),handleAcpProductPlan:t=>this.acpHandleProductPlan(t),handleAcpProductConfirm:t=>this.acpHandleProductConfirm(t),handleAcpProductMessage:t=>this.acpHandleProductMessage(t),handleAcpProductPause:t=>this.acpHandleProductPause(t),handleAcpProductResume:t=>this.acpHandleProductResume(t),handleAcpProductCancel:t=>this.acpHandleProductCancel(t),handleAcpProductRollback:t=>this.acpHandleProductRollback(t),handleAcpProductStatus:t=>this.acpHandleProductStatus(t),handleAcpProductSubscribe:t=>this.acpHandleProductSubscribe(t),handleAcpTeamDelegate:t=>this.acpHandleTeamDelegate(t)};this.acpServer=new so(this.transport,e,{verbose:this.verbose})}getAcpServer(){return this.acpServer}async acpHandleInitialize(e){let t=e.clientInfo?.name??"unknown";this.log(`[acp] initialize: host=${t}`);let r={extendedEvents:!0,extendedMethods:!0,orchestration:!0,configOptions:[{name:"model",type:"string",description:"LLM model identifier"},{name:"provider",type:"string",description:"LLM provider identifier"},{name:"maxRounds",type:"number",description:"Max tool loop rounds"},{name:"temperature",type:"number",description:"Sampling temperature"}]};return this.ensureDefaultProject(),{protocolVersion:1,agentInfo:{name:"qlogicagent",version:vb},agentCapabilities:r}}async acpHandleSessionNew(e){let t=e.sessionId??kt();return this.log(`[acp] session/new: id=${t}`),this.currentSessionId=t,this.sessionState=new zt(t),this.sessionTaskDomain=void 0,this.memoryPrefetchState=Lt(),e.cwd&&typeof e.cwd=="string"&&this.setActiveWorkdir(e.cwd),this.enableIdleDream(),{sessionId:t}}async acpHandleSessionPrompt(e){let t=kt(),r=e.sessionId,s=e.prompt.map(c=>c.type==="text"?c.text:`[${c.type}]`).join("");if(!s.trim())return this.sendNotification("turn.start",{turnId:t,model:this.currentModel||void 0}),this.sendNotification("turn.end",{turnId:t,content:"",item:{id:`${t}-end`,type:"message",role:"assistant",text:"",createdAt:new Date().toISOString()}}),{stopReason:"end_turn"};let o=this.acpSessionHistory.get(r);o||(o=[],this.acpSessionHistory.set(r,o)),o.push({role:"user",content:s});let i=[...o],a=await this.runAcpTurn(t,r,i);return a.content&&o.push({role:"assistant",content:a.content}),a}async runAcpTurn(e,t,r){let s=new AbortController;this.activeTurn=s,this.sendNotification("turn.start",{turnId:e,model:this.currentModel||void 0});try{let o={model:this.currentModel||void 0,provider:this.currentProvider||void 0,apiKey:this.currentApiKey||void 0,baseUrl:this.currentBaseUrl||void 0},i=this.resolveAgent(o);if(!i)return this.sendNotification("turn.delta",{turnId:e,text:"Error: No LLM provider configured. Configure via ~/.qlogicagent/settings.json or pass provider/apiKey in session config.",item:{id:`${e}-err`,type:"message",role:"assistant",text:"",createdAt:new Date().toISOString()}}),this.sendNotification("turn.end",{turnId:e,content:"",item:{id:`${e}-end`,type:"message",role:"assistant",text:"",createdAt:new Date().toISOString()}}),this.activeTurn=null,{stopReason:"end_turn"};await this.mcpReady;let a=wt(),c,l="end_turn",d="";for await(let u of i.run({turnId:e,sessionId:t,messages:r,tools:a,config:o},s.signal)){let p=new Date().toISOString();switch(u.type){case"start":break;case"delta":this.sendNotification("turn.delta",{turnId:u.turnId,text:u.text,item:{id:`${e}-delta`,type:"message",role:"assistant",text:u.text,createdAt:p}});break;case"end":u.usage&&(c={inputTokens:u.usage.inputTokens??0,outputTokens:u.usage.outputTokens??0,cacheReadTokens:u.usage.cacheRead,cacheWriteTokens:u.usage.cacheWrite}),d=u.content??"",this.sendNotification("turn.end",{turnId:u.turnId,content:u.content,usage:u.usage,model:u.model,provider:u.provider,item:{id:`${e}-end`,type:"message",role:"assistant",text:u.content,createdAt:p}});break;case"error":l="end_turn",this.sendNotification("turn.error",{turnId:u.turnId,error:{message:u.error,code:u.code}});break;case"tool_call":this.sendNotification("turn.tool_call",{turnId:u.turnId,callId:u.callId,name:u.name,arguments:u.arguments,item:{id:u.callId,type:"tool_call",role:"assistant",toolName:u.name,toolCallId:u.callId,arguments:u.arguments,createdAt:p}});break;case"tool_result":this.sendNotification("turn.tool_result",{turnId:u.turnId,callId:u.callId,name:u.name,ok:u.ok,...u.error?{error:u.error}:{},...u.outputPreview?{outputPreview:u.outputPreview}:{},item:{id:`${u.callId}-result`,type:"tool_result",role:"assistant",toolName:u.name,toolCallId:u.callId,output:u.ok?u.outputPreview??"":u.error,approved:u.ok,createdAt:p}});break;case"tool_blocked":this.sendNotification("turn.tool_blocked",{turnId:u.turnId,callId:u.callId,name:u.name,reason:u.reason,item:{id:`${u.callId}-blocked`,type:"tool_blocked",role:"system",toolName:u.name,toolCallId:u.callId,text:u.reason,approved:!1,createdAt:p}});break;case"recovery":this.sendNotification("turn.recovery",{turnId:u.turnId,action:u.action,...u.detail?{detail:u.detail}:{},item:{id:`${e}-recovery-${kt().slice(0,8)}`,type:"recovery",role:"system",strategy:u.action,text:u.detail,createdAt:p}});break;case"reasoning_delta":this.sendNotification("turn.reasoning_delta",{turnId:u.turnId,text:u.text});break;case"subagent_started":this.sendNotification("turn.subagent_started",{turnId:u.turnId,subagentId:u.subagentId,agentType:u.agentType,...u.prompt?{prompt:u.prompt}:{}});break;case"subagent_ended":this.sendNotification("turn.subagent_ended",{turnId:u.turnId,subagentId:u.subagentId,agentType:u.agentType,ok:u.ok,...u.outputPreview?{outputPreview:u.outputPreview}:{},...u.error?{error:u.error}:{}});break;case"media_result":this.sendNotification("turn.media_result",{turnId:u.turnId,mediaType:u.mediaType,url:u.url,...u.model?{model:u.model}:{},...u.provider?{provider:u.provider}:{},...u.taskId?{taskId:u.taskId}:{}});break}}return this.activeTurn=null,{stopReason:l,usage:c,content:d}}catch(o){this.activeTurn=null;let i=o instanceof Error?o.message:String(o);return this.log(`[acp] runAcpTurn error: ${i}`),this.sendNotification("turn.error",{turnId:e,error:{message:i,code:"INTERNAL_ERROR"}}),{stopReason:"end_turn"}}}async acpHandleSessionEnd(e){this.log(`[acp] session/end: id=${e.sessionId}`),this.acpSessionHistory.delete(e.sessionId),this.currentSessionId===e.sessionId&&(this.cancelIdleDreamTimer(),this.currentHooks&&await this.currentHooks.invoke("session.ended",{sessionId:e.sessionId}).catch(()=>{}),this.currentSessionId="",this.sessionState=null)}async acpHandleSessionSetConfig(e){let t=e.configId??e.option;this.log(`[acp] session/set_config: ${t}=${JSON.stringify(e.value)}`);let r=typeof e.value=="string"?e.value:"";switch(t){case"model":this.currentModel=r;break;case"provider":this.currentProvider=r;break;case"apiKey":this.currentApiKey=r;break;case"baseUrl":this.currentBaseUrl=r;break}}async acpHandleSessionSetModel(e,t){this.log(`[acp] session/set_model: ${t} (note: model is managed by ModelRegistry, this is a hint only)`),t&&(this.currentModel=t)}async acpHandleSessionSetMode(e,t){this.log(`[acp] session/set_mode: ${t}`)}acpHandlePermissionResponse(e,t){this.log(`[acp] permission response: ${e} \u2192 ${t}`),this.permissionChecker&&this.permissionChecker.resolveApproval({approvalId:e,decision:t==="allow"?"approved":"denied"})}async acpHandleAbort(e){this.log(`[acp] abort: session=${e.sessionId}`),this.activeTurn&&(this.activeTurn.abort(),this.activeTurn=null)}async acpHandleDream(e){this.log(`[acp] x/dream: session=${e.sessionId}`);let t=this.resolveClientForPurpose("textGeneration");if(!t)return{ok:!1,summary:"No LLM transport configured for dream"};let r=q(),s={jsonrpc:"2.0",id:`acp-dream-${kt().slice(0,8)}`,method:"memory.dream",params:{turnId:`dream-${kt().slice(0,8)}`,sessionId:e.sessionId||this.currentSessionId,config:{memoryRoot:e.config?.memoryRoot||r,transcriptDir:e.config?.transcriptDir||ee.join(r,"agent-logs"),model:t.model,apiKey:t.apiKey,...e.config}}};return await uo.call(this,s),{ok:!0,summary:"Dream consolidation triggered"}}async acpHandleSoloStart(e){this.log("[acp] x/solo.start");let t=Ye.call(this),r=await t.start(e);return t.getStatus(r)}async acpHandleSoloStatus(e){this.log("[acp] x/solo.status");let t=e.soloId;if(!t)return this.soloEvaluator?this.soloEvaluator.listSessions():[];let s=Ye.call(this).getStatus(t);if(!s)throw new Error(`Solo session ${t} not found`);return s}async acpHandleSoloSelect(e){return this.log("[acp] x/solo.select"),{ok:!0,mergedBranch:await Ye.call(this).select(e)}}async acpHandleSoloCancel(e){this.log("[acp] x/solo.cancel");let t=Ye.call(this),r=e.soloId;return await t.cancel(r),{ok:!0}}async acpHandleSoloSubscribe(e){return this.log("[acp] x/solo.subscribe"),{ok:!0,soloId:e.soloId}}async acpHandleSoloMessage(e){this.log("[acp] x/solo.message");let t=Ye.call(this),{soloId:r,agentId:s,content:o,agentIndex:i}=e;return t.message(r,s,o,i)}async acpHandleSoloEvaluate(e){this.log("[acp] x/solo.evaluate");let t=Ye.call(this),{soloId:r,evaluatorAgentId:s,evaluatorIndex:o}=e;return t.triggerEvaluation(r,s,o)}async acpHandleAgentsList(){return this.log("[acp] x/agents.list"),qi()}async acpHandleProductCreate(e){return this.log("[acp] x/product.create"),{productId:await De.call(this).create(e)}}async acpHandleProductPlan(e){return this.log("[acp] x/product.plan"),await hn.call(this).plan(e)}async acpHandleProductConfirm(e){this.log("[acp] x/product.confirm");let t=hn.call(this),r=e,s=await t.confirm(r),o=t.getSession(r.productId);return o&&await De.call(this).create({name:o.plan?.name??o.goal.slice(0,50),cwd:o.cwd,instances:r.instances,tasks:r.tasks,budget:r.budget}),s}async acpHandleProductMessage(e){this.log("[acp] x/product.message");let t=hn.call(this),r=e;return t.message(r.productId,r.content)}async acpHandleProductResume(e){this.log("[acp] x/product.resume");let t=De.call(this),r=e.productId;return await t.resume(r,this.getActiveProjectRoot()),{ok:!0}}async acpHandleProductStatus(e){this.log("[acp] x/product.status");let t=e.productId;if(!this.productOrchestrator)return t?null:[];if(!t)return this.productOrchestrator.list(this.getActiveProjectRoot());let r=this.productOrchestrator.getStatus(t);if(!r)throw new Error(`Product session ${t} not found`);return r}async acpHandleProductPause(e){this.log("[acp] x/product.pause");let t=De.call(this),r=e.productId;return await t.pause(r),{ok:!0}}async acpHandleProductCancel(e){this.log("[acp] x/product.cancel");let t=De.call(this),r=e.productId;return await t.delete(r),{ok:!0}}async acpHandleProductRollback(e){this.log("[acp] x/product.rollback");let t=De.call(this),r=e.productId,s=e.checkpointId??"latest";return await t.rollback(r,s),{ok:!0}}async acpHandleProductSubscribe(e){return this.log("[acp] x/product.subscribe"),{ok:!0,productId:e.productId}}async acpHandleTeamDelegate(e){let t=e.agentType,r=e.prompt,s=e.maxTurns;if(!r)throw new Error("Missing required param: prompt");if(!t)throw new Error("Missing required param: agentType");let o=rs(t);if(!o)throw new Error(`Unknown agent type: ${t}`);let i=this.resolveClientForPurpose("textGeneration");if(!i)throw new Error("No LLM provider configured \u2014 send a prompt first to configure the model");if(this.log(`[acp] x/team.delegate: agent=${t}, maxTurns=${s??o.maxTurns}`),Re.isTeamBudgetExceeded())return{ok:!1,agentType:t,output:void 0,error:Re.teamBudgetExceededError(),tokensUsed:0};let a={invoke:async()=>({result:"Tool execution not available in delegated mode"})},c={info:p=>this.log(`[delegate:${t}] ${p}`),warn:p=>this.log(`[delegate:${t}] WARN: ${p}`),error:p=>this.log(`[delegate:${t}] ERROR: ${p}`),debug:p=>this.log(`[delegate:${t}] ${p}`)},l=await $c({promptMessages:[{role:"user",content:r}],tools:[],transport:i.transport,toolInvoker:a,apiKey:i.apiKey,model:i.model,log:c,forkLabel:`team-delegate-${t}`,maxTurns:s??o.maxTurns,parentSignal:this.activeTurn?.signal,parentDepth:0}),d=l.events.filter(p=>p.type==="end"&&"content"in p).map(p=>p.content??"").join("")||l.events.filter(p=>p.type==="delta"&&"text"in p).map(p=>p.text).join(""),u=l.totalUsage.inputTokens+l.totalUsage.outputTokens;return Re.recordForkTokens(u),{ok:l.ok,agentType:t,output:d||void 0,error:l.error,tokensUsed:u}}};function Sb(n){let e={verbose:!1};for(let t of n.slice(2))(t==="--verbose"||t==="-v")&&(e.verbose=!0);return e}import{writeFileSync as eE,appendFileSync as Tb,mkdirSync as tE}from"node:fs";import{join as Rl}from"node:path";import{homedir as nE}from"node:os";var Rb=Rl(process.env.QLOGICAGENT_HOME||Rl(nE(),".qlogicagent"),"debug-logs");try{tE(Rb,{recursive:!0})}catch{}var Al=Rl(Rb,"acp-session.log");try{eE(Al,"")}catch{}function Qe(n){let e=`[${new Date().toISOString()}] ${n}
|
|
1022
|
-
`;
|
|
1018
|
+
`).slice(0,3).join(" ").slice(0,200),He=S?ee.basename(S):"unknown";this.memoryProvider.ingestExtracted([{text:`Learned skill "${g.name}" in project "${He}": ${pe}`,category:"skill-learning"}],this.memoryUserId).catch(()=>{})}let ne=S?` (project-scoped). To make it available across all projects, use: skill promote name:"${g.name}"`:"";return{success:!0,message:`Skill "${g.name}" created${ne}`,path:E}}case"edit":{let D=Be($);if(D.records[g.name]?.pinned)return{success:!1,message:`Skill "${g.name}" is pinned. Unpin it first.`};let M=g.content??"",ie=Yc(M,g.name)??M;return await V.promises.writeFile(w,ie,"utf8"),Vc(D,g.name),We($,D),this.sendNotification("turn.skill_instruction",{turnId:`skill-edit-${Date.now()}`,instruction:{name:g.name,category:g.category??"learned",content:ie,scope:"project"}}),{success:!0,message:`Skill "${g.name}" updated`,path:w}}case"patch":{let D=Be($);if(D.records[g.name]?.pinned)return{success:!1,message:`Skill "${g.name}" is pinned. Unpin it first.`};let M=await V.promises.readFile(w,"utf8");if(!g.oldString||!M.includes(g.oldString))return{success:!1,message:"oldString not found in SKILL.md"};let W=M.replace(g.oldString,g.newString??"");return await V.promises.writeFile(w,W,"utf8"),Vc(D,g.name),We($,D),this.sendNotification("turn.skill_instruction",{turnId:`skill-patch-${Date.now()}`,instruction:{name:g.name,category:g.category??"learned",content:W,scope:"project"}}),{success:!0,message:`Skill "${g.name}" patched`,path:w}}case"delete":{let D=Be($);return D.records[g.name]?.pinned?{success:!1,message:`Skill "${g.name}" is pinned. Unpin it first.`}:(await V.promises.rm(E,{recursive:!0,force:!0}),eo(D,g.name),We($,D),this.sendNotification("turn.skill_instruction",{turnId:`skill-delete-${Date.now()}`,instruction:{name:g.name,category:g.category??"learned",action:"delete",scope:"project"}}),pt(),{success:!0,message:`Skill "${g.name}" deleted`})}default:return{success:!1,message:`Unknown action: ${g.action}`}}},promoteSkill:async g=>{let S=Tt(this.getActiveProjectRoot()),x=ee.join(S,g,"SKILL.md");try{await V.promises.access(x)}catch{return{success:!1,message:`Skill "${g}" not found in project skills. Cannot promote.`}}let E=Dt(),w=ee.join(E,g);await V.promises.mkdir(w,{recursive:!0});let $=ee.join(S,g),D=await V.promises.readdir($);for(let M of D){let W=await V.promises.readFile(ee.join($,M));await V.promises.writeFile(ee.join(w,M),W)}return this.sendNotification("turn.skill_instruction",{turnId:`skill-promote-${Date.now()}`,instruction:{name:g,category:"promoted",content:await V.promises.readFile(x,"utf8"),scope:"global"}}),await V.promises.rm($,{recursive:!0,force:!0}),this.sendNotification("turn.skill_instruction",{turnId:`skill-promote-cleanup-${Date.now()}`,instruction:{name:g,category:"learned",action:"delete",scope:"project"}}),pt(),{success:!0,message:`Skill "${g}" promoted to global (user-level) and removed from project scope. It will now be available across all projects.`,path:w}},installSkill:async(g,S)=>{let x;try{if(x=new URL(g),!["http:","https:"].includes(x.protocol))return{success:!1,message:`Invalid URL scheme: ${x.protocol}. Only http/https allowed.`}}catch{return{success:!1,message:`Invalid URL: ${g}`}}let E=S??Z_(x);if(!E)return{success:!1,message:"Cannot derive skill name from URL. Please provide 'name' parameter."};try{let w=await fetch(g,{signal:AbortSignal.timeout(3e4)});if(!w.ok)return{success:!1,message:`Download failed: HTTP ${w.status} ${w.statusText}`};let $=w.headers.get("content-length");if($&&parseInt($,10)>512e3)return{success:!1,message:"Content too large (>512KB). Skill files should be small markdown documents."};let D=await w.text();if(!D.trim())return{success:!1,message:"Downloaded content is empty."};if(D.length>512e3)return{success:!1,message:"Content too large (>512KB). Skill files should be small markdown documents."};if(D.trimStart().startsWith("<!DOCTYPE")||D.trimStart().startsWith("<html"))return{success:!1,message:"URL returned an HTML page, not a raw markdown file. Use a raw/direct download link."};let M=Dt(),W=ee.join(M,E);return await V.promises.mkdir(W,{recursive:!0}),await V.promises.writeFile(ee.join(W,"SKILL.md"),D,"utf8"),this.sendNotification("turn.skill_instruction",{turnId:`skill-install-${Date.now()}`,instruction:{name:E,category:"installed",content:D,scope:"global"}}),pt(),{success:!0,message:`Skill "${E}" installed from ${x.host}. Available globally across all projects.`,path:W}}catch(w){return{success:!1,message:`Install failed: ${w instanceof Error?w.message:String(w)}`}}}})),Pe(tg({abortSignal:void 0,currentForkDepth:0,forkAgent:async g=>{let S=rs(g.agent);if(!S)return{agentId:"",status:"failed",error:`Unknown agent type: ${g.agent}`};if(!this.agent||!this.currentTransport||!this.currentApiKey||!this.currentModel)return{agentId:"",status:"failed",error:"No LLM provider configured"};let x=Xt(),E=Bi(x,S),$=wt().filter(ne=>E.includes(ne.function.name)),D=Pa($,!0),M=g.maxTurns??S.maxTurns??200;if(Re.isTeamBudgetExceeded())return{agentId:`fork-${g.agent}-budget-exceeded`,status:"failed",output:void 0,error:Re.teamBudgetExceededError(),tokensUsed:0};let W=await $c({promptMessages:[{role:"user",content:g.prompt}],tools:D,transport:this.currentTransport,toolInvoker:l,apiKey:this.currentApiKey,model:this.currentModel,log:c,hooks:d,forkLabel:`agent-${g.agent}`,maxTurns:M,parentSignal:g.abortSignal,parentDepth:0,onEvent:ne=>{ne.type==="delta"&&ne.text&&this.sendNotification("turn.subagent_delta",{agentType:g.agent,text:ne.text})}}),ie=W.events.filter(ne=>ne.type==="end"&&"content"in ne).map(ne=>ne.content??"").join("")||W.events.filter(ne=>ne.type==="delta"&&"text"in ne).map(ne=>ne.text).join(""),Z=W.totalUsage.inputTokens+W.totalUsage.outputTokens;return Re.recordForkTokens(Z),{agentId:`fork-${g.agent}-${kt().slice(0,8)}`,status:W.ok?"completed":"failed",output:ie||void 0,error:W.error,tokensUsed:Z}}}));let ce=it(),le=new Map([["model",{key:"model",value:this.currentModel??"",type:"string",description:"Default LLM model"}],["language",{key:"language",value:"zh-cn",type:"string",description:"UI / response language"}],["verbose",{key:"verbose",value:this.verbose,type:"boolean",description:"Enable verbose logging"}],["maxRounds",{key:"maxRounds",value:25,type:"number",description:"Default max tool-call rounds per turn"}],["theme",{key:"theme",value:"auto",type:"enum",description:"Color theme",options:["auto","light","dark"]}]]),j=async()=>{try{return JSON.parse(await V.promises.readFile(ce,"utf8"))}catch{return{}}},ve=async g=>{await V.promises.mkdir(ee.dirname(ce),{recursive:!0}),await V.promises.writeFile(ce,JSON.stringify(g,null,2),"utf8")};Pe(ng({getConfig:async g=>{let S=le.get(g);if(!S)return{success:!1,error:`Unknown key: ${g}`};let x=await j(),E=g in x?x[g]:S.value;return{success:!0,setting:{...S,value:E,readOnly:Sr.includes(g)}}},setConfig:async(g,S)=>{let x=le.get(g);if(!x)return{success:!1,error:`Unknown key: ${g}`};let E=await j(),w=g in E?E[g]:x.value;return E[g]=S,await ve(E),{success:!0,previousValue:w,setting:{...x,value:S}}},listConfig:async()=>{let g=await j();return{success:!0,settings:[...le.values()].map(x=>({...x,value:x.key in g?g[x.key]:x.value,readOnly:Sr.includes(x.key)}))}},resetConfig:async g=>{let S=le.get(g);if(!S)return{success:!1,error:`Unknown key: ${g}`};let x=await j();return delete x[g],await ve(x),{success:!0,setting:S}},isValidKey:g=>le.has(g)}));let oe=new Map,$e=g=>{let S=/^(\d+)([smhd])$/.exec(g.trim());if(!S)return null;let x=parseInt(S[1],10),E=S[2];return x*({s:1e3,m:6e4,h:36e5,d:864e5}[E]??6e4)},te=g=>{g.timerId&&clearTimeout(g.timerId);let S=$e(g.schedule);if(!S)return;let x=Date.now(),E=S-x%S||S;g.timerId=setTimeout(()=>{g.lastRunAt=new Date().toISOString(),g.repeat.completed++,g.lastStatus="success",c.info(`[cron] triggered job ${g.id} (${g.name})`),this.sendNotification("system.activity",{category:"cron",level:"info",title:`\u5B9A\u65F6\u4EFB\u52A1\u89E6\u53D1: ${g.name}`,detail:`\u8C03\u5EA6 ${g.scheduleDisplay}\uFF0C\u7B2C ${g.repeat.completed} \u6B21\u6267\u884C`}),g.repeat.times===null||g.repeat.completed<g.repeat.times?te(g):(g.state="paused",g.enabled=!1,this.sendNotification("system.activity",{category:"cron",level:"info",title:`\u5B9A\u65F6\u4EFB\u52A1\u5B8C\u6210: ${g.name}`,detail:`\u5DF2\u8FBE\u5230\u6700\u5927\u6267\u884C\u6B21\u6570 (${g.repeat.completed}\u6B21)`}))},E),g.nextRunAt=new Date(x+E).toISOString()};gn(async()=>{for(let g of oe.values())g.timerId&&clearTimeout(g.timerId)}),Pe(sg({createJob:async g=>{let S=`cron_${kt().slice(0,8)}`,x={id:S,name:g.name??`Job ${S}`,prompt:g.prompt,schedule:g.schedule,scheduleDisplay:g.schedule,state:"scheduled",enabled:!0,repeat:{times:g.repeat??null,completed:0},allowedTools:g.allowedTools};return oe.set(S,x),te(x),{success:!0,job:{...x,timerId:void 0}}},listJobs:async()=>({success:!0,jobs:[...oe.values()].map(S=>({...S,timerId:void 0}))}),getJob:async g=>{let S=oe.get(g);return S?{success:!0,job:{...S,timerId:void 0}}:{success:!1,error:`Job not found: ${g}`}},updateJob:async(g,S)=>{let x=oe.get(g);return x?(S.prompt!==void 0&&(x.prompt=S.prompt),S.schedule!==void 0&&(x.schedule=S.schedule,x.scheduleDisplay=S.schedule),S.name!==void 0&&(x.name=S.name),S.enabled!==void 0&&(x.enabled=S.enabled,x.state=S.enabled?"scheduled":"paused"),S.repeat!==void 0&&(x.repeat.times=S.repeat),S.allowedTools!==void 0&&(x.allowedTools=S.allowedTools),x.enabled?te(x):x.timerId&&(clearTimeout(x.timerId),x.timerId=void 0),{success:!0,job:{...x,timerId:void 0}}):{success:!1,error:`Job not found: ${g}`}},deleteJob:async g=>{let S=oe.get(g);return S?(S.timerId&&clearTimeout(S.timerId),oe.delete(g),{success:!0}):{success:!1,error:`Job not found: ${g}`}},pauseJob:async g=>{let S=oe.get(g);return S?(S.state="paused",S.enabled=!1,S.timerId&&(clearTimeout(S.timerId),S.timerId=void 0),{success:!0,job:{...S,timerId:void 0}}):{success:!1,error:`Job not found: ${g}`}},resumeJob:async g=>{let S=oe.get(g);return S?(S.state="scheduled",S.enabled=!0,te(S),{success:!0,job:{...S,timerId:void 0}}):{success:!1,error:`Job not found: ${g}`}},triggerJob:async g=>{let S=oe.get(g);return S?(S.lastRunAt=new Date().toISOString(),S.repeat.completed++,S.lastStatus="success",{success:!0,job:{...S,timerId:void 0}}):{success:!1,error:`Job not found: ${g}`}},validateSchedule:g=>$e(g)!==null||/^\d{1,2}\s/.test(g)?null:`Invalid schedule: ${g}. Use shorthand (5m, 1h, 1d) or cron expression.`}));let J=new Map;gn(async()=>{for(let g of J.values())g.cleanup();J.clear()}),Pe(og({startMonitor:async g=>{if(J.has(g.monitorId))return{action:"start",success:!1,error:`Monitor "${g.monitorId}" already exists.`};let S={monitorId:g.monitorId,source:g.source,target:g.target,conditions:g.conditions,startedAt:Date.now(),timeoutSeconds:g.timeoutSeconds,eventCount:0},x=()=>{};if(g.source==="file")try{let E=V.watch(g.target,{persistent:!1},()=>{S.eventCount++,c.info(`[monitor] file change detected: ${g.target}`)});x=()=>E.close()}catch{return{action:"start",success:!1,error:`Cannot watch: ${g.target}`}}if(g.timeoutSeconds>0){let E=setTimeout(()=>{let $=J.get(g.monitorId);$&&($.cleanup(),J.delete(g.monitorId))},g.timeoutSeconds*1e3),w=x;x=()=>{clearTimeout(E),w()}}return J.set(g.monitorId,{info:S,cleanup:x}),{action:"start",success:!0,monitorId:g.monitorId}},stopMonitor:async g=>{let S=J.get(g);return S?(S.cleanup(),J.delete(g),{action:"stop",success:!0,monitorId:g}):{action:"stop",success:!1,error:`Monitor "${g}" not found.`}},listMonitors:async()=>[...J.values()].map(g=>g.info)}));let R=new Map,B={info:g=>c.info(g),warn:g=>c.warn(g)},U=new _t({onNotification:(g,S,x)=>{this.sendNotification("team.member.notification",{memberId:g,method:S,params:x})},onStateChange:(g,S)=>{this.sendNotification("team.member.state",{memberId:g,state:S});let x=U.getHandle(g),w=U.getUsageTracker(g)?.getUsage();this.emitAgentStatus(g,S,{missedBeats:U.getMissedBeats(g),lastActivityAt:x?.lastActivityAt,usage:w&&w.totalTokens>0?{inputTokens:w.inputTokens,outputTokens:w.outputTokens,totalTokens:w.totalTokens}:void 0})},onExit:(g,S,x)=>{for(let E of R.values()){let w=E.members.find($=>$.cwd&&`team-${E.name}-${$.name}`.replace(/[^a-zA-Z0-9-]/g,"-").toLowerCase()===g.replace(/^team-/,""));w&&(w.isActive=!1)}c.info(`[team] member ${g} exited (code=${S}, signal=${x})`)},onMcpToolCall:(g,S,x)=>this.handleMcpToolCall(g,S,x),log:{info:g=>c.info(g),warn:g=>c.warn(g),debug:g=>c.debug(g)},sessionDir:ee.join(q(),"agent-logs")});gn(async()=>{U.dispose()}),Pe(ig({createTeam:async g=>{if(R.has(g.teamName))return{success:!1,error:`Team "${g.teamName}" already exists.`};let S=await mr(),x=[];for(let w of g.members??[]){let $={...w,isActive:!0};if(S){let D=`team-${g.teamName}-${w.name}`.replace(/[^a-zA-Z0-9-]/g,"-").toLowerCase(),M=await Wp(S,D,B);M?($.worktreePath=M.worktreePath,$.worktreeBranch=M.branch,$.cwd=M.worktreePath,c.info(`[team] provisioned worktree for ${w.name}: ${M.worktreePath}`)):($.cwd=process.cwd(),c.warn(`[team] worktree provision failed for ${w.name}, using shared cwd`))}else $.cwd=process.cwd();x.push($)}let E={name:g.teamName,description:g.description,leadId:this.currentSessionId??"default",members:x,createdAt:new Date().toISOString()};R.set(g.teamName,E);for(let w of x){if(!w.cwd)continue;let $=`team-${g.teamName}-${w.name}`.replace(/[^a-zA-Z0-9-]/g,"-").toLowerCase();try{await U.spawn({memberId:$,name:w.name,cwd:w.cwd,prompt:`You are the "${w.name}" team member. Role: ${w.role}.`,agentType:w.role,verbose:this.verbose}),c.info(`[team] spawned child process for ${w.name} in ${w.cwd}`)}catch(D){c.warn(`[team] failed to spawn child process for ${w.name}: ${D instanceof Error?D.message:String(D)}`),w.isActive=!1}}return this.sendNotification("team.updated",{teamName:g.teamName,action:"created",members:E.members.map(w=>({agentName:w.name,role:w.role,worktreePath:w.worktreePath,pid:U.getHandle(`team-${g.teamName}-${w.name}`.replace(/[^a-zA-Z0-9-]/g,"-").toLowerCase())?.pid}))}),{success:!0,team:E}},deleteTeam:async g=>{let S=R.get(g);if(!S)return{success:!1,error:`Team "${g}" not found.`};for(let E of S.members){let w=`team-${g}-${E.name}`.replace(/[^a-zA-Z0-9-]/g,"-").toLowerCase();U.kill(w),U.remove(w)}let x=await mr();if(x)for(let E of S.members)E.worktreePath&&E.worktreeBranch&&(await Gp(x,E.worktreePath,E.worktreeBranch,B),c.info(`[team] cleaned up worktree for ${E.name}: ${E.worktreePath}`));return R.delete(g),this.sendNotification("team.updated",{teamName:g,action:"destroyed",members:[]}),{success:!0}},listTeams:async()=>({success:!0,teams:[...R.values()]}),getTeamStatus:async g=>{let S=R.get(g);if(!S)return{success:!1,error:`Team "${g}" not found.`};let x={};for(let E of S.members){let w=`team-${g}-${E.name}`.replace(/[^a-zA-Z0-9-]/g,"-").toLowerCase(),$=U.getStatus(w);$&&(E.isActive=$.alive,x[E.name]={mediaProgress:$.mediaProgress,lastToolCall:$.lastToolCall,idleFor:$.idleFor,runningFor:$.runningFor})}return{success:!0,team:S,memberProgress:x}}}));{let g=this.memdir;Pe({name:Ig,label:_g,description:Cg,parameters:Eg,execute:async(S,x)=>{let E=await Mg(x,{memdir:g,provider:this.memoryUserId?this.memoryProvider??void 0:void 0,localProvider:this.memoryUserId?this.memoryProvider??void 0:void 0,userId:this.memoryUserId});return{content:[{type:"text",text:E.message}],details:{type:"memory",action:E.action,ok:E.ok}}}})}lu(d,{getMemdir:()=>this.memdir,log:{debug:g=>c.debug(g),warn:g=>c.warn(g)}},this.memoryPrefetchState);{let g=e?.workdir??process.cwd(),S=dg(g,this.currentSessionId||"default");Pe(lg(S))}Pe(ug({sendNotification:async g=>(c.info(`[notify] ${g.title??""}: ${g.message}`),{delivered:!0,channel:g.channel??"cli"})})),Pe(pg({sendMessage:async g=>(c.info(`[send_message] ${g.senderId} \u2192 ${g.to}: ${g.message}`),{success:!0,recipients:[g.to]}),getSenderId:()=>this.currentSessionId??"default",listTeammates:()=>[]}));{let g=e?.workdir??process.cwd(),S,x=()=>(S||(S=Po.createContext({...{readFile:async w=>V.promises.readFile(ee.resolve(g,w),"utf8"),writeFile:async(w,$)=>{await V.promises.writeFile(ee.resolve(g,w),$,"utf8")},editFile:async(w,$)=>{let D=await V.promises.readFile(ee.resolve(g,w),"utf8");for(let M of $)D=D.replace(M.oldText,M.newText);return await V.promises.writeFile(ee.resolve(g,w),D,"utf8"),D},exec:async w=>{let $=await import("node:child_process");return new Promise(D=>{$.execFile("bash",["-c",w],{cwd:g,timeout:3e4},(M,W,ie)=>{D({stdout:W?.toString()??"",stderr:ie?.toString()??"",exitCode:M?M.code??1:0})})})},glob:async w=>{try{let{globSync:$}=await import("node:fs");return $(w,{cwd:g})}catch{return[]}},grep:async(w,$)=>{let D=[],M=ee.resolve(g,$??".");try{let W=await import("node:child_process"),ie=await new Promise(Z=>{W.execFile("grep",["-rn",w,M,"--include=*"],{timeout:1e4},(ne,pe)=>Z(pe?.toString()??""))});for(let Z of ie.split(`
|
|
1019
|
+
`).filter(Boolean).slice(0,100)){let ne=Z.match(/^(.+?):(\d+):(.*)$/);ne&&D.push({file:ne[1],line:parseInt(ne[2]),text:ne[3]})}}catch{}return D},console:{log:(...w)=>w.map(String).join(" ")}},setTimeout,clearTimeout,Promise,JSON,Math,Date,Array,Object,String,Number,Boolean,RegExp,Map,Set,Error,Buffer})),S);Pe(fg({executeInVm:async E=>{let w=Date.now();try{let $=x(),D=await Po.runInContext(`(async () => { ${E} })()`,$,{timeout:3e4});return{output:D!==void 0?String(D):"",duration:Date.now()-w}}catch($){return{output:"",error:$ instanceof Error?$.message:String($),duration:Date.now()-w}}},resetVm:()=>{S=void 0}}))}{let g=e?.workdir??process.cwd();Pe(hg({executeOperation:async S=>{switch(S.operation){case"goToDefinition":case"findReferences":return{type:"locations",locations:[]};case"hover":return{type:"hover",hover:null};case"documentSymbol":return{type:"symbols",symbols:[]};case"diagnostics":return{type:"diagnostics",diagnostics:[]};case"completion":return{type:"completions",completions:[]};case"signatureHelp":return{type:"signatureHelp",signatures:[]};case"rename":return{type:"rename",edits:[]};case"codeAction":return{type:"codeActions",actions:[]};default:return{type:"locations",locations:[]}}},resolvePath:S=>ee.isAbsolute(S)?S:ee.resolve(g,S)}))}let Ae=e?.workdir??process.cwd(),fe=Bg({projectRoot:Ae,ruleEngine:I,hooks:d,log:g=>c.info(`[settings] ${g}`)});gn(async()=>{fe()}),this.currentSessionId&&d.invoke("session.created",{sessionId:this.currentSessionId}).catch(()=>{}),this.fileWatcher&&this.fileWatcher.stop();let Mt=e?.workdir??process.cwd();return Fu({projectRoot:Mt,sessionId:this.currentSessionId,hooks:d,log:g=>c.debug(g),onInstructionCacheReset:Ku}).then(g=>{this.fileWatcher=g,gn(async()=>{this.fileWatcher?.stop()})}).catch(g=>{c.warn(`[file-watcher] init error: ${g instanceof Error?g.message:g}`)}),this.agent=new or({llmTransport:a.transport,apiKey:a.apiKey,toolInvoker:l,log:c,hooks:d,maxRounds:e.maxRounds,verbose:this.verbose,projectRoot:this.getActiveProjectRoot()}),this.lastLlmConfigKey=i,this.currentTransport=a.transport,this.currentApiKey=a.apiKey,this.currentModel=r,this.currentProvider=t,this.currentBaseUrl=o??"",this.log(`created Agent (provider: ${t}, model: ${r})`),this.agent}static STATE_TO_STATUS={starting:"spawning",ready:"available",running:"running",completed:"available",failed:"failed",killed:"unavailable"};emitAgentStatus(e,t,r){let s=n.STATE_TO_STATUS[t]??"unavailable",o={agentId:e,status:s};(r?.missedBeats!==void 0||r?.lastActivityAt!==void 0)&&(o.health={missedBeats:r.missedBeats??0,lastActiveAt:r.lastActivityAt?new Date(r.lastActivityAt).toISOString():new Date().toISOString()}),r?.usage&&(o.usage=r.usage),this.sendNotification("agents.status",o)}async handleMcpToolCall(e,t,r){let s=tt(t);if(!s)return`Error: Unknown tool "${t}"`;let o=`mcp_${e}_${kt().slice(0,8)}`;try{return(await s.execute(o,r)).content.map(a=>a.text??"").join(`
|
|
1020
|
+
`)||"OK"}catch(i){return`Error: ${i instanceof Error?i.message:String(i)}`}}async ensureAgentConfigStore(){return this.agentConfigStore||(this.agentConfigStore=new Gs(this.getActiveProjectRoot()),await this.agentConfigStore.load(),this.acpDetector.setConfigStore(this.agentConfigStore.getData())),this.agentConfigStore}sendResponse(e,t,r){let s=this.rpcIds.get(e);if(s){let i=this.rpcContract.settle(s.requestId,t,r);if(this.clearRpcLifecycle(e),!i.accepted){this.log(`[rpc] dropped late response id=${String(e)} requestId=${s.requestId} reason=${i.reason}`);return}}let o={jsonrpc:"2.0",id:e};r?o.error=r:o.result=t,this.writeStdout(o)}sendContractError(e,t){let r={jsonrpc:"2.0",id:e,error:t};this.writeStdout(r)}sendContractErrorOrResult(e,t,r){if(r){this.sendContractError(e,r);return}let s={jsonrpc:"2.0",id:e,result:t};this.writeStdout(s)}scheduleRpcDeadline(e,t,r){let s=Math.max(0,r.deadlineAt-Date.now()),o=setTimeout(()=>{if(!this.rpcIds.has(e))return;let i=this.rpcContract.expire(r.requestId);this.clearRpcLifecycle(e),i&&(this.log(`[rpc] deadline exceeded method=${t} id=${String(e)} requestId=${r.requestId}`),this.writeStdout({jsonrpc:"2.0",id:e,error:{code:v.REQUEST_DEADLINE_EXCEEDED,message:`RPC request deadline exceeded: ${t}.`}}))},s);o.unref?.(),this.rpcDeadlineTimers.set(e,o)}clearRpcLifecycle(e){let t=this.rpcDeadlineTimers.get(e);t&&clearTimeout(t),this.rpcDeadlineTimers.delete(e),this.rpcIds.delete(e)}sendNotification(e,t){if(this.acpServer&&this.acpServer.sessionId)rf(this.acpServer,this.acpServer.sessionId,e,t);else{let r={jsonrpc:"2.0",method:e,params:t};this.writeStdout(r)}e==="turn.end"&&this.resetIdleDreamTimer(),e==="turn.start"&&this.cancelIdleDreamTimer()}writeStdout(e){this.transport.send(e)}log(e){this.verbose&&process.stderr.write(`${JSON.stringify({ts:new Date().toISOString(),level:"info",service:"qlogicagent",message:e})}
|
|
1021
|
+
`)}enableIdleDream(e){Re.dream.enabled=!0,e&&e>0&&(Re.dream.idleMinutes=e),this.resetIdleDreamTimer()}resetIdleDreamTimer(){this.cancelIdleDreamTimer(),Re.dream.enabled&&this.currentSessionId&&(this.idleDreamTimer=setTimeout(()=>{this.triggerIdleDream()},Re.dream.idleMinutes*6e4),this.idleDreamTimer.unref?.())}cancelIdleDreamTimer(){this.idleDreamTimer&&(clearTimeout(this.idleDreamTimer),this.idleDreamTimer=null)}async triggerIdleDream(){if(Date.now()-Re.dream.lastDreamAt<Re.dream.cooldownMs){this.log("[dream:idle] Skipped \u2014 cooldown not elapsed");return}let e=this.resolveClientForPurpose("textGeneration");if(!e){this.log("[dream:idle] Skipped \u2014 no LLM transport configured");return}if(this.activeTurn){this.log("[dream:idle] Skipped \u2014 turn in progress");return}this.log("[dream:idle] Triggering idle dream consolidation"),Re.dream.lastDreamAt=Date.now(),this.sendNotification("system.activity",{category:"dream",level:"info",title:"\u7A7A\u95F2\u68A6\u5883\u6574\u7406\u89E6\u53D1",detail:`\u7A7A\u95F2 ${Re.dream.idleMinutes} \u5206\u949F\u540E\u81EA\u52A8\u89E6\u53D1`});let t=setTimeout(()=>{this.activeTurn&&(this.log("[dream:idle] Aborting \u2014 max duration reached"),this.activeTurn.abort())},Re.dream.maxDurationMs);t.unref?.();let r=q(),s=[];try{s=(await At(20,this.getActiveProjectRoot())).filter(a=>a.sessionId!==this.currentSessionId).map(a=>a.sessionId)}catch{}let o={jsonrpc:"2.0",id:void 0,method:"memory.dream",params:{turnId:`idle-dream-${kt().slice(0,8)}`,sessionId:this.currentSessionId,config:{memoryRoot:r,transcriptDir:ee.join(r,"agent-logs"),dreamSessionIds:s,currentSessionTurnCount:this.sessionState?.turnCount??0,model:e.model,apiKey:e.apiKey,force:!1}}};try{await uo.call(this,o)}finally{clearTimeout(t)}this.resetIdleDreamTimer()}initAcpServer(){let e={handleAcpInitialize:t=>this.acpHandleInitialize(t),handleAcpSessionNew:t=>this.acpHandleSessionNew(t),handleAcpSessionPrompt:t=>this.acpHandleSessionPrompt(t),handleAcpSessionEnd:t=>this.acpHandleSessionEnd(t),handleAcpSessionSetConfig:t=>this.acpHandleSessionSetConfig(t),handleAcpSessionSetModel:(t,r)=>this.acpHandleSessionSetModel(t,r),handleAcpSessionSetMode:(t,r)=>this.acpHandleSessionSetMode(t,r),handleAcpPermissionResponse:(t,r)=>this.acpHandlePermissionResponse(t,r),handleAcpAbort:t=>this.acpHandleAbort(t),handleAcpDream:t=>this.acpHandleDream(t),handleAcpAgentsList:()=>this.acpHandleAgentsList(),handleAcpSoloStart:t=>this.acpHandleSoloStart(t),handleAcpSoloStatus:t=>this.acpHandleSoloStatus(t),handleAcpSoloSelect:t=>this.acpHandleSoloSelect(t),handleAcpSoloCancel:t=>this.acpHandleSoloCancel(t),handleAcpSoloSubscribe:t=>this.acpHandleSoloSubscribe(t),handleAcpSoloMessage:t=>this.acpHandleSoloMessage(t),handleAcpSoloEvaluate:t=>this.acpHandleSoloEvaluate(t),handleAcpProductCreate:t=>this.acpHandleProductCreate(t),handleAcpProductPlan:t=>this.acpHandleProductPlan(t),handleAcpProductConfirm:t=>this.acpHandleProductConfirm(t),handleAcpProductMessage:t=>this.acpHandleProductMessage(t),handleAcpProductPause:t=>this.acpHandleProductPause(t),handleAcpProductResume:t=>this.acpHandleProductResume(t),handleAcpProductCancel:t=>this.acpHandleProductCancel(t),handleAcpProductRollback:t=>this.acpHandleProductRollback(t),handleAcpProductStatus:t=>this.acpHandleProductStatus(t),handleAcpProductSubscribe:t=>this.acpHandleProductSubscribe(t),handleAcpTeamDelegate:t=>this.acpHandleTeamDelegate(t)};this.acpServer=new so(this.transport,e,{verbose:this.verbose})}getAcpServer(){return this.acpServer}async acpHandleInitialize(e){let t=e.clientInfo?.name??"unknown";this.log(`[acp] initialize: host=${t}`);let r={extendedEvents:!0,extendedMethods:!0,orchestration:!0,configOptions:[{name:"model",type:"string",description:"LLM model identifier"},{name:"provider",type:"string",description:"LLM provider identifier"},{name:"maxRounds",type:"number",description:"Max tool loop rounds"},{name:"temperature",type:"number",description:"Sampling temperature"}]};return this.ensureDefaultProject(),{protocolVersion:1,agentInfo:{name:"qlogicagent",version:kb},agentCapabilities:r}}async acpHandleSessionNew(e){let t=e.sessionId??kt();return this.log(`[acp] session/new: id=${t}`),this.currentSessionId=t,this.sessionState=new zt(t),this.sessionTaskDomain=void 0,this.memoryPrefetchState=Lt(),e.cwd&&typeof e.cwd=="string"&&this.setActiveWorkdir(e.cwd),this.enableIdleDream(),{sessionId:t}}async acpHandleSessionPrompt(e){let t=kt(),r=e.sessionId,s=e.prompt.map(c=>c.type==="text"?c.text:`[${c.type}]`).join("");if(!s.trim())return this.sendNotification("turn.start",{turnId:t,model:this.currentModel||void 0}),this.sendNotification("turn.end",{turnId:t,content:"",item:{id:`${t}-end`,type:"message",role:"assistant",text:"",createdAt:new Date().toISOString()}}),{stopReason:"end_turn"};let o=this.acpSessionHistory.get(r);o||(o=[],this.acpSessionHistory.set(r,o)),o.push({role:"user",content:s});let i=[...o],a=await this.runAcpTurn(t,r,i);return a.content&&o.push({role:"assistant",content:a.content}),a}async runAcpTurn(e,t,r){let s=new AbortController;this.activeTurn=s,this.sendNotification("turn.start",{turnId:e,model:this.currentModel||void 0});try{let o={model:this.currentModel||void 0,provider:this.currentProvider||void 0,apiKey:this.currentApiKey||void 0,baseUrl:this.currentBaseUrl||void 0},i=this.resolveAgent(o);if(!i)return this.sendNotification("turn.delta",{turnId:e,text:"Error: No LLM provider configured. Configure via ~/.qlogicagent/settings.json or pass provider/apiKey in session config.",item:{id:`${e}-err`,type:"message",role:"assistant",text:"",createdAt:new Date().toISOString()}}),this.sendNotification("turn.end",{turnId:e,content:"",item:{id:`${e}-end`,type:"message",role:"assistant",text:"",createdAt:new Date().toISOString()}}),this.activeTurn=null,{stopReason:"end_turn"};await this.mcpReady;let a=wt(),c,l="end_turn",d="";for await(let u of i.run({turnId:e,sessionId:t,messages:r,tools:a,config:o},s.signal)){let p=new Date().toISOString();switch(u.type){case"start":break;case"delta":this.sendNotification("turn.delta",{turnId:u.turnId,text:u.text,item:{id:`${e}-delta`,type:"message",role:"assistant",text:u.text,createdAt:p}});break;case"end":u.usage&&(c={inputTokens:u.usage.inputTokens??0,outputTokens:u.usage.outputTokens??0,cacheReadTokens:u.usage.cacheRead,cacheWriteTokens:u.usage.cacheWrite}),d=u.content??"",this.sendNotification("turn.end",{turnId:u.turnId,content:u.content,usage:u.usage,model:u.model,provider:u.provider,item:{id:`${e}-end`,type:"message",role:"assistant",text:u.content,createdAt:p}});break;case"error":l="end_turn",this.sendNotification("turn.error",{turnId:u.turnId,error:{message:u.error,code:u.code}});break;case"tool_call":this.sendNotification("turn.tool_call",{turnId:u.turnId,callId:u.callId,name:u.name,arguments:u.arguments,item:{id:u.callId,type:"tool_call",role:"assistant",toolName:u.name,toolCallId:u.callId,arguments:u.arguments,createdAt:p}});break;case"tool_result":this.sendNotification("turn.tool_result",{turnId:u.turnId,callId:u.callId,name:u.name,ok:u.ok,...u.error?{error:u.error}:{},...u.outputPreview?{outputPreview:u.outputPreview}:{},item:{id:`${u.callId}-result`,type:"tool_result",role:"assistant",toolName:u.name,toolCallId:u.callId,output:u.ok?u.outputPreview??"":u.error,approved:u.ok,createdAt:p}});break;case"tool_blocked":this.sendNotification("turn.tool_blocked",{turnId:u.turnId,callId:u.callId,name:u.name,reason:u.reason,item:{id:`${u.callId}-blocked`,type:"tool_blocked",role:"system",toolName:u.name,toolCallId:u.callId,text:u.reason,approved:!1,createdAt:p}});break;case"recovery":this.sendNotification("turn.recovery",{turnId:u.turnId,action:u.action,...u.detail?{detail:u.detail}:{},item:{id:`${e}-recovery-${kt().slice(0,8)}`,type:"recovery",role:"system",strategy:u.action,text:u.detail,createdAt:p}});break;case"reasoning_delta":this.sendNotification("turn.reasoning_delta",{turnId:u.turnId,text:u.text});break;case"subagent_started":this.sendNotification("turn.subagent_started",{turnId:u.turnId,subagentId:u.subagentId,agentType:u.agentType,...u.prompt?{prompt:u.prompt}:{}});break;case"subagent_ended":this.sendNotification("turn.subagent_ended",{turnId:u.turnId,subagentId:u.subagentId,agentType:u.agentType,ok:u.ok,...u.outputPreview?{outputPreview:u.outputPreview}:{},...u.error?{error:u.error}:{}});break;case"media_result":this.sendNotification("turn.media_result",{turnId:u.turnId,mediaType:u.mediaType,url:u.url,...u.model?{model:u.model}:{},...u.provider?{provider:u.provider}:{},...u.taskId?{taskId:u.taskId}:{}});break}}return this.activeTurn=null,{stopReason:l,usage:c,content:d}}catch(o){this.activeTurn=null;let i=o instanceof Error?o.message:String(o);return this.log(`[acp] runAcpTurn error: ${i}`),this.sendNotification("turn.error",{turnId:e,error:{message:i,code:"INTERNAL_ERROR"}}),{stopReason:"end_turn"}}}async acpHandleSessionEnd(e){this.log(`[acp] session/end: id=${e.sessionId}`),this.acpSessionHistory.delete(e.sessionId),this.currentSessionId===e.sessionId&&(this.cancelIdleDreamTimer(),this.currentHooks&&await this.currentHooks.invoke("session.ended",{sessionId:e.sessionId}).catch(()=>{}),this.currentSessionId="",this.sessionState=null)}async acpHandleSessionSetConfig(e){let t=e.configId??e.option;this.log(`[acp] session/set_config: ${t}=${JSON.stringify(e.value)}`);let r=typeof e.value=="string"?e.value:"";switch(t){case"model":this.currentModel=r;break;case"provider":this.currentProvider=r;break;case"apiKey":this.currentApiKey=r;break;case"baseUrl":this.currentBaseUrl=r;break}}async acpHandleSessionSetModel(e,t){this.log(`[acp] session/set_model: ${t} (note: model is managed by ModelRegistry, this is a hint only)`),t&&(this.currentModel=t)}async acpHandleSessionSetMode(e,t){this.log(`[acp] session/set_mode: ${t}`)}acpHandlePermissionResponse(e,t){this.log(`[acp] permission response: ${e} \u2192 ${t}`),this.permissionChecker&&this.permissionChecker.resolveApproval({approvalId:e,decision:t==="allow"?"approved":"denied"})}async acpHandleAbort(e){this.log(`[acp] abort: session=${e.sessionId}`),this.activeTurn&&(this.activeTurn.abort(),this.activeTurn=null)}async acpHandleDream(e){this.log(`[acp] x/dream: session=${e.sessionId}`);let t=this.resolveClientForPurpose("textGeneration");if(!t)return{ok:!1,summary:"No LLM transport configured for dream"};let r=q(),s={jsonrpc:"2.0",id:`acp-dream-${kt().slice(0,8)}`,method:"memory.dream",params:{turnId:`dream-${kt().slice(0,8)}`,sessionId:e.sessionId||this.currentSessionId,config:{memoryRoot:e.config?.memoryRoot||r,transcriptDir:e.config?.transcriptDir||ee.join(r,"agent-logs"),model:t.model,apiKey:t.apiKey,...e.config}}};return await uo.call(this,s),{ok:!0,summary:"Dream consolidation triggered"}}async acpHandleSoloStart(e){this.log("[acp] x/solo.start");let t=Ye.call(this),r=await t.start(e);return t.getStatus(r)}async acpHandleSoloStatus(e){this.log("[acp] x/solo.status");let t=e.soloId;if(!t)return this.soloEvaluator?this.soloEvaluator.listSessions():[];let s=Ye.call(this).getStatus(t);if(!s)throw new Error(`Solo session ${t} not found`);return s}async acpHandleSoloSelect(e){return this.log("[acp] x/solo.select"),{ok:!0,mergedBranch:await Ye.call(this).select(e)}}async acpHandleSoloCancel(e){this.log("[acp] x/solo.cancel");let t=Ye.call(this),r=e.soloId;return await t.cancel(r),{ok:!0}}async acpHandleSoloSubscribe(e){return this.log("[acp] x/solo.subscribe"),{ok:!0,soloId:e.soloId}}async acpHandleSoloMessage(e){this.log("[acp] x/solo.message");let t=Ye.call(this),{soloId:r,agentId:s,content:o,agentIndex:i}=e;return t.message(r,s,o,i)}async acpHandleSoloEvaluate(e){this.log("[acp] x/solo.evaluate");let t=Ye.call(this),{soloId:r,evaluatorAgentId:s,evaluatorIndex:o}=e;return t.triggerEvaluation(r,s,o)}async acpHandleAgentsList(){return this.log("[acp] x/agents.list"),qi()}async acpHandleProductCreate(e){return this.log("[acp] x/product.create"),{productId:await De.call(this).create(e)}}async acpHandleProductPlan(e){return this.log("[acp] x/product.plan"),await hn.call(this).plan(e)}async acpHandleProductConfirm(e){this.log("[acp] x/product.confirm");let t=hn.call(this),r=e,s=await t.confirm(r),o=t.getSession(r.productId);return o&&await De.call(this).create({name:o.plan?.name??o.goal.slice(0,50),cwd:o.cwd,instances:r.instances,tasks:r.tasks,budget:r.budget}),s}async acpHandleProductMessage(e){this.log("[acp] x/product.message");let t=hn.call(this),r=e;return t.message(r.productId,r.content)}async acpHandleProductResume(e){this.log("[acp] x/product.resume");let t=De.call(this),r=e.productId;return await t.resume(r,this.getActiveProjectRoot()),{ok:!0}}async acpHandleProductStatus(e){this.log("[acp] x/product.status");let t=e.productId;if(!this.productOrchestrator)return t?null:[];if(!t)return this.productOrchestrator.list(this.getActiveProjectRoot());let r=this.productOrchestrator.getStatus(t);if(!r)throw new Error(`Product session ${t} not found`);return r}async acpHandleProductPause(e){this.log("[acp] x/product.pause");let t=De.call(this),r=e.productId;return await t.pause(r),{ok:!0}}async acpHandleProductCancel(e){this.log("[acp] x/product.cancel");let t=De.call(this),r=e.productId;return await t.delete(r),{ok:!0}}async acpHandleProductRollback(e){this.log("[acp] x/product.rollback");let t=De.call(this),r=e.productId,s=e.checkpointId??"latest";return await t.rollback(r,s),{ok:!0}}async acpHandleProductSubscribe(e){return this.log("[acp] x/product.subscribe"),{ok:!0,productId:e.productId}}async acpHandleTeamDelegate(e){let t=e.agentType,r=e.prompt,s=e.maxTurns;if(!r)throw new Error("Missing required param: prompt");if(!t)throw new Error("Missing required param: agentType");let o=rs(t);if(!o)throw new Error(`Unknown agent type: ${t}`);let i=this.resolveClientForPurpose("textGeneration");if(!i)throw new Error("No LLM provider configured \u2014 send a prompt first to configure the model");if(this.log(`[acp] x/team.delegate: agent=${t}, maxTurns=${s??o.maxTurns}`),Re.isTeamBudgetExceeded())return{ok:!1,agentType:t,output:void 0,error:Re.teamBudgetExceededError(),tokensUsed:0};let a={invoke:async()=>({result:"Tool execution not available in delegated mode"})},c={info:p=>this.log(`[delegate:${t}] ${p}`),warn:p=>this.log(`[delegate:${t}] WARN: ${p}`),error:p=>this.log(`[delegate:${t}] ERROR: ${p}`),debug:p=>this.log(`[delegate:${t}] ${p}`)},l=await $c({promptMessages:[{role:"user",content:r}],tools:[],transport:i.transport,toolInvoker:a,apiKey:i.apiKey,model:i.model,log:c,forkLabel:`team-delegate-${t}`,maxTurns:s??o.maxTurns,parentSignal:this.activeTurn?.signal,parentDepth:0}),d=l.events.filter(p=>p.type==="end"&&"content"in p).map(p=>p.content??"").join("")||l.events.filter(p=>p.type==="delta"&&"text"in p).map(p=>p.text).join(""),u=l.totalUsage.inputTokens+l.totalUsage.outputTokens;return Re.recordForkTokens(u),{ok:l.ok,agentType:t,output:d||void 0,error:l.error,tokensUsed:u}}};function Tb(n){let e={verbose:!1};for(let t of n.slice(2))(t==="--verbose"||t==="-v")&&(e.verbose=!0);return e}import{writeFileSync as eE,appendFileSync as Rb,mkdirSync as tE}from"node:fs";import{join as Rl}from"node:path";import{homedir as nE}from"node:os";var Ab=Rl(process.env.QLOGICAGENT_HOME||Rl(nE(),".qlogicagent"),"debug-logs");try{tE(Ab,{recursive:!0})}catch{}var Al=Rl(Ab,"acp-session.log");try{eE(Al,"")}catch{}function Qe(n){let e=`[${new Date().toISOString()}] ${n}
|
|
1022
|
+
`;wb.call(process.stderr,e);try{Rb(Al,e)}catch{}}var wb=process.stderr.write.bind(process.stderr);process.stderr.write=((n,...e)=>{let t=typeof n=="string"?n:Buffer.from(n).toString();try{Rb(Al,t)}catch{}return wb(n,...e)});Qe(`PID=${process.pid} argv=${JSON.stringify(process.argv.slice(1))} cwd=${process.cwd()} HOME=${process.env.QLOGICAGENT_HOME??"(unset)"} NODE=${process.version}`);var xb=Tb(process.argv),rE=!process.argv.includes("--no-acp"),sE=new kn({verbose:xb.verbose}),Io=new xo({verbose:xb.verbose,transport:sE});rE&&(Io.initAcpServer(),Qe("ACP server initialized, waiting for messages"));process.on("unhandledRejection",n=>{Qe(`unhandledRejection: ${n instanceof Error?n.stack??n.message:String(n)}`)});process.on("uncaughtException",n=>{Qe(`uncaughtException: ${n.stack??n.message}`)});process.stdin.on("end",()=>{Qe("stdin END received")});process.stdin.on("close",()=>{Qe("stdin CLOSE received")});process.stdout.on("error",n=>{Qe(`stdout ERROR: ${n.message}`)});process.stdout.on("close",()=>{Qe("stdout CLOSE")});process.on("exit",n=>{Qe(`process.exit code=${n}`)});process.on("SIGTERM",()=>{Qe("SIGTERM received"),Io.stop(),process.exit(0)});process.on("SIGINT",()=>{Qe("SIGINT received"),Io.stop(),process.exit(0)});process.on("SIGHUP",()=>{Qe("SIGHUP received")});Qe("calling server.start()");Io.start();Qe("server.start() returned, event loop active");
|