goatchain 0.0.13 → 0.0.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +171 -137
- package/dist/lib/access-control/controller.d.ts +57 -0
- package/dist/lib/access-control/index.d.ts +29 -0
- package/dist/lib/access-control/policies.d.ts +40 -0
- package/dist/lib/access-control/types.d.ts +35 -0
- package/dist/lib/access-control/validators/bash.d.ts +50 -0
- package/dist/lib/access-control/validators/index.d.ts +6 -0
- package/dist/middleware/parallelSubagentMiddleware.d.ts +2 -2
- package/dist/middleware/planModeMiddleware.d.ts +6 -0
- package/dist/subagent/bash-validator.d.ts +47 -0
- package/dist/subagent/explore.d.ts +38 -0
- package/dist/subagent/index.d.ts +2 -1
- package/dist/tool/builtin/task.d.ts +3 -4
- package/dist/tool/types.d.ts +10 -0
- package/dist/types/event.d.ts +1 -1
- package/package.json +6 -4
- package/dist/subagent/file-search-specialist.d.ts +0 -16
package/dist/index.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import{createRequire as
|
|
1
|
+
import{createRequire as S4}from"node:module";var E4=Object.create;var{getPrototypeOf:L4,defineProperty:m1,getOwnPropertyNames:M4}=Object;var T4=Object.prototype.hasOwnProperty;var t0=($,W,Q)=>{Q=$!=null?E4(L4($)):{};let Z=W||!$||!$.__esModule?m1(Q,"default",{value:$,enumerable:!0}):Q;for(let J of M4($))if(!T4.call(Z,J))m1(Z,J,{get:()=>$[J],enumerable:!0});return Z};var e0=S4(import.meta.url);class M0{debug;constructor($){this.debug=$?.debug??!1}async*convertToACP($){let W=!1;for await(let Q of $){if(Q.type==="text_delta"&&Q?.delta)W=!0;if(Q.type==="subagent_event"){let J=Q.nestedEvent;if(J?.type==="text_delta"&&J.delta)W=!0;let Y=this.convertSubagentEventToACP(Q);for(let H of Y)yield H;continue}if(Q.type==="done"){let J=Q;if(!W){let Y=typeof J.finalResponse==="string"?J.finalResponse.trim():"";if(Y)yield{role:"assistant",content:Y,metadata:{final:!0}},W=!0;else if(J?.stopReason==="error"&&J?.error?.message)yield{role:"assistant",content:`Error: ${String(J.error.message)}`,metadata:{error:!0}},W=!0}}let Z=this.convertRegularEvent(Q);for(let J of Z)yield J}}convertSubagentEventToACP($){let{subagentId:W,subagentType:Q,taskDescription:Z,nestedEvent:J}=$,Y=this.convertRegularEvent(J);if(Y.length===0)return[];return Y.map((H)=>({...H,metadata:{...H.metadata??{},subagent:!0,subagentId:W,subagentType:Q,taskDescription:Z,originalEventType:J.type}}))}convertRegularEvent($){let W=$.metadata;switch($.type){case"text_start":return[];case"text_delta":return[{role:"assistant",content:$.delta,metadata:W?{...W,originalEventType:$.type}:void 0}];case"text_end":return[];case"tool_call_start":return[];case"tool_call_delta":return[];case"tool_call_end":{let Q=$;return[{role:"assistant",content:"",tool_calls:[this.convertToolCallToACP(Q.toolCall)],metadata:W?{...W,originalEventType:$.type}:void 0}]}case"tool_result":{let Q=$;return[{role:"tool",tool_call_id:Q.tool_call_id,content:this.formatToolResult(Q.result),metadata:Q.isError?{error:!0}:void 0}]}case"tool_output_start":{let Q=$;return[{role:"assistant",content:"",metadata:{tool_output_start:!0,tool_call_id:Q.tool_call_id,tool_name:Q.toolName}}]}case"tool_output_delta":{let Q=$;return[{role:"assistant",content:Q.delta,metadata:{tool_output_delta:!0,tool_call_id:Q.tool_call_id,isStderr:Q.isStderr}}]}case"tool_approval_requested":{let Q=$;return[{role:"assistant",content:`Tool approval requested: ${Q.toolName}
|
|
2
2
|
|
|
3
3
|
`,metadata:{approval_requested:!0,tool_call_id:Q.tool_call_id,tool_name:Q.toolName,risk_level:Q.riskLevel,approval_args:Q.args}}]}case"requires_action":{let Q=$,Z={requires_action:!0,kind:Q.kind,tool_call_id:Q.toolCallId};if(Q.kind==="ask_user"&&"questions"in Q)Z.questions=Q.questions;return[{role:"assistant",content:`Action required: ${Q.kind}
|
|
4
4
|
|
|
5
5
|
`,metadata:Z}]}case"tool_skipped":{let Q=$;return[{role:"assistant",content:`Tool skipped: ${Q.toolName} - ${Q.reason}`,metadata:{tool_skipped:!0,tool_call_id:Q.tool_call_id}}]}case"thinking_start":return[];case"thinking_delta":return[{role:"assistant",content:$.delta,metadata:{thinking:!0}}];case"thinking_end":return[];case"iteration_start":return[];case"iteration_end":return[];case"session_created":return[];case"done":{let Q=$,Z={done:!0,stopReason:Q.stopReason,modelStopReason:Q.modelStopReason,usage:Q.usage,error:Q.error};if(Q.finalResponse)Z.final=!0;return[{role:"assistant",content:"",metadata:Z}]}default:if(this.debug)console.warn(`[ProtocolConverter] Unhandled event type: ${$.type}`);return[]}}convertFromACP($){return $.map((W)=>this.convertSingleMessage(W))}convertSingleMessage($){switch($.role){case"system":return{role:"system",content:this.extractTextContent($.content)};case"user":return{role:"user",content:this.extractTextContent($.content),name:$.name};case"assistant":{let W={role:"assistant",content:this.extractTextContent($.content)};if($.tool_calls&&$.tool_calls.length>0)W.tool_calls=$.tool_calls.map((Q)=>this.convertToolCallFromACP(Q));return W}case"tool":return{role:"tool",content:this.extractTextContent($.content),tool_call_id:$.tool_call_id||"",isError:$.metadata?.error===!0};default:return{role:"user",content:this.extractTextContent($.content)}}}convertToolCallToACP($){return{id:$.id,type:"function",function:{name:$.function.name,arguments:$.function.arguments}}}convertToolCallFromACP($){return{id:$.id,type:"function",function:{name:$.function.name,arguments:typeof $.function.arguments==="string"?$.function.arguments:JSON.stringify($.function.arguments)}}}extractTextContent($){if(!$)return"";if(typeof $==="string")return $;if(Array.isArray($))return $.map((W)=>W.text||"").join("");return""}formatToolResult($){if(typeof $==="string")return $;if(Array.isArray($))return $.map((W)=>{if(typeof W==="object"&&W&&"text"in W)return W.text;return JSON.stringify(W)}).join(`
|
|
6
|
-
`);return JSON.stringify($,null,2)}}class
|
|
6
|
+
`);return JSON.stringify($,null,2)}}class T0{sessions=new Map;sessionContexts=new Map;sessionTimeout;maxConcurrentSessions;maxIterations;cleanupTimer;constructor($){this.sessionTimeout=$?.sessionTimeout??1800000,this.maxConcurrentSessions=$?.maxConcurrentSessions??10,this.maxIterations=$?.maxIterations,this.cleanupTimer=setInterval(()=>{this.cleanupExpiredSessions()},300000)}async getOrCreateSession($,W){let Q=this.sessions.get($);if(Q){let Y=this.sessionContexts.get($);if(Y)Y.lastAccessedAt=Date.now();return Q}if(this.sessions.size>=this.maxConcurrentSessions)this.removeOldestSession();let Z=W.sessionManager;if(Z)try{if(await Z.get($)){let H=await W.resumeSession($,{maxIterations:this.maxIterations});return this.sessions.set($,H),this.sessionContexts.set($,{sessionId:$,createdAt:Date.now(),lastAccessedAt:Date.now()}),H}}catch{}let J=await W.createSession({sessionId:$,maxIterations:this.maxIterations});return this.sessions.set($,J),this.sessionContexts.set($,{sessionId:$,createdAt:Date.now(),lastAccessedAt:Date.now()}),J}getSession($){let W=this.sessions.get($);if(W){let Q=this.sessionContexts.get($);if(Q)Q.lastAccessedAt=Date.now()}return W}removeSession($){let W=this.sessions.delete($);return this.sessionContexts.delete($),W}getActiveSessions(){return Array.from(this.sessions.keys())}getSessionCount(){return this.sessions.size}cleanupExpiredSessions(){let $=Date.now(),W=[];for(let[Q,Z]of this.sessionContexts.entries())if($-Z.lastAccessedAt>this.sessionTimeout)W.push(Q);for(let Q of W)this.removeSession(Q);if(W.length>0)console.warn(`[SessionRouter] Cleaned up ${W.length} expired sessions`)}removeOldestSession(){let $,W=1/0;for(let[Q,Z]of this.sessionContexts.entries())if(Z.createdAt<W)W=Z.createdAt,$=Q;if($)this.removeSession($),console.warn(`[SessionRouter] Removed oldest session: ${$}`)}destroy(){if(this.cleanupTimer)clearInterval(this.cleanupTimer),this.cleanupTimer=void 0;this.sessions.clear(),this.sessionContexts.clear()}}class S0{agent;router;converter;debug;constructor($,W){if(this.agent=$,this.debug=W?.debug??!1,this.router=new T0({sessionTimeout:W?.sessionTimeout,maxConcurrentSessions:W?.maxConcurrentSessions,maxIterations:W?.maxIterations}),this.converter=new M0({debug:this.debug}),this.debug)console.warn("[ACPAgent] Initialized with agent:",$.name),console.warn("[ACPAgent] Middlewares:",$.middlewareNames)}async*receiveMessage($,W){let Q=W?.session_id??this.generateSessionId();if(this.debug)console.warn(`[ACPAgent] Receiving ${$.length} messages for session: ${Q}`);try{let Z=await this.router.getOrCreateSession(Q,this.agent),J=this.converter.convertFromACP($);if(this.debug)console.warn(`[ACPAgent] Converted to ${J.length} GoatChain messages`);let Y={},H=[];for(let j of $)if(j.role==="tool"&&j.tool_call_id){H.push(this.converter.convertFromACP([j])[0]);try{let _=typeof j.content==="string"?JSON.parse(j.content):j.content;if(_.answers)Y[j.tool_call_id]=_.answers}catch{}}let X=Object.keys(Y).length>0,G=await Z.hasCheckpoint();if(this.debug)console.warn(`[ACPAgent] Has tool results: ${X}, Has checkpoint: ${G}`);let V=J.filter((j)=>j.role==="user");if(V.length>0){let j=V[V.length-1],_=X?{askUser:{answers:Y}}:void 0;if(this.debug)console.warn(`[ACPAgent] Sending user message ${j.content} ${_?" with toolContext":""} `);Z.send(j.content,_?{toolContext:_}:void 0)}else if(G&&!X){if(this.debug)console.warn("[ACPAgent] Resuming from checkpoint without new input")}let K=0,z=!1;for await(let j of this.converter.convertToACP(Z.receive())){if(K++,this.debug)console.warn(`[ACPAgent] Event #${K}:`,j.role,j.metadata?.done?"(done)":"");if(yield j,j.metadata?.done)z=!0}if(z&&this.debug)console.warn(`[ACPAgent] Session ${Q} completed with ${K} events`)}catch(Z){console.error("[ACPAgent] Error processing messages:",Z),yield{role:"assistant",content:`Error: ${Z instanceof Error?Z.message:String(Z)}`,metadata:{error:!0,done:!0}}}}async*receiveWithApprovals($,W){let Q=W?.session_id??this.generateSessionId();if(this.debug)console.warn(`[ACPAgent] Resuming with approvals for session: ${Q}`);try{let Z=await this.router.getOrCreateSession(Q,this.agent),J=0,Y=!1;for await(let H of this.converter.convertToACP(Z.receiveWithApprovals($))){if(J++,this.debug)console.warn(`[ACPAgent] Event #${J}:`,H.role,H.metadata?.done?"(done)":"");if(yield H,H.metadata?.done)Y=!0}if(Y&&this.debug)console.warn(`[ACPAgent] Session ${Q} completed with ${J} events`)}catch(Z){console.error("[ACPAgent] Error processing approvals:",Z),yield{role:"assistant",content:`Error: ${Z instanceof Error?Z.message:String(Z)}`,metadata:{error:!0,done:!0}}}}getSessionInfo(){return{activeSessions:this.router.getActiveSessions(),sessionCount:this.router.getSessionCount()}}getSession($){return this.router.getSession($)}closeSession($){return this.router.removeSession($)}getAgent(){return this.agent}destroy(){if(this.router.destroy(),this.debug)console.warn("[ACPAgent] Destroyed")}generateSessionId(){return`acp-session-${Date.now()}-${Math.random().toString(36).slice(2,11)}`}}import W$ from"node:path";import O$ from"node:process";import{Readable as d9,Writable as l9}from"node:stream";import*as o0 from"@agentclientprotocol/sdk";import{appendFileSync as I4}from"node:fs";import{join as v4}from"node:path";import{createRequire as P4}from"node:module";var x4="gpt-4o",p1=P4(import.meta.url);function X0(){return globalThis?.process?.env}function $1($){return String(($??{}).GOATCHAIN_TOKEN_COUNT_MODE??"").trim().toLowerCase()==="precise"?"precise":"estimate"}function l1($){let W=$??{};return String(W.GOATCHAIN_PROFILE_1SHOT??"").trim()==="1"||String(W.GOATCHAIN_PERF_LOG??"").trim()==="1"}function c1($,W){let Q=X0();if(!l1(Q))return;let Z=String($??"").trim();if(!Z)return;let J=W!==void 0?String(W??"").trim():"",Y=globalThis,H=Y.__GOATCHAIN_PERF_SPAN__??(Y.__GOATCHAIN_PERF_SPAN__={stack:[]}),X=Array.isArray(H.stack)?H.stack:H.stack=[];if(X.push({name:Z,startedAt:Date.now(),...J?{detail:J}:{}}),X.length>64)X.splice(0,X.length-64)}function d1($){let W=X0();if(!l1(W))return;let Z=globalThis.__GOATCHAIN_PERF_SPAN__?.stack;if(!Array.isArray(Z)||Z.length===0)return;for(let J=Z.length-1;J>=0;J--)if(Z.pop()?.name===$)break}function z$($,W){if(!$)return 0;let Q=X0();if($1(Q)!=="precise")return X$($);let Z,J=null;try{Z=p1("tiktoken");let Y=W??x4,H=Z.encoding_for_model(Y);return J=H,H.encode($).length}catch{try{Z=Z??p1("tiktoken");let Y=Z.get_encoding("cl100k_base");return J=Y,Y.encode($).length}catch{return X$($)}}finally{J?.free()}}function i1($,W){if(typeof $==="string")return z$($,W);if(Array.isArray($))return $.reduce((Q,Z)=>{if(typeof Z==="object"&&Z!==null&&"text"in Z)return Q+z$(String(Z.text),W);return Q},0);return 0}function r1($,W){let Q=X0();if($1(Q)!=="precise")return n1($);try{let Z=JSON.stringify($);return z$(Z,W)}catch{return w4($,W)}}function w4($,W){let Z=4;if(Z+=i1($.content,W),$.role==="assistant"&&$.tool_calls)for(let J of $.tool_calls){Z+=z$(J.function.name,W);let Y=typeof J.function.arguments==="string"?J.function.arguments:JSON.stringify(J.function.arguments);Z+=z$(Y,W),Z+=10}if($.role==="tool"&&$.name)Z+=z$($.name,W);if($.role==="assistant"&&$.reasoning_content)Z+=z$($.reasoning_content,W);return Z}function q$($,W){if(!$||$.length===0)return 0;let Q=X0();if($1(Q)!=="precise"){c1("tokenCounter.messages.estimate",`msgs=${$.length}`);try{return y4($)}finally{d1("tokenCounter.messages.estimate")}}try{c1("tokenCounter.messages.precise",`msgs=${$.length}`);let J=JSON.stringify($);return z$(J,W)}catch{return $.reduce((Y,H)=>Y+r1(H,W),3)}finally{d1("tokenCounter.messages.precise")}}function X$($){if(!$)return 0;return Math.ceil($.length/4)}function n1($){let W=6;if(W+=b4($.content),$.role==="assistant"&&$.tool_calls)for(let Q of $.tool_calls){W+=X$(String(Q?.function?.name??""));let Z=Q?.function?.arguments;if(typeof Z==="string")W+=X$(Z);else if(Z!=null)W+=X$(JSON.stringify(Z));W+=10}if($.role==="tool"&&$.name)W+=X$(String($.name??""));if($.role==="assistant"&&$.reasoning_content)W+=X$(String($.reasoning_content??""));return W}function b4($){if(typeof $==="string")return X$($);if(Array.isArray($)){let W=0;for(let Q of $)if(typeof Q==="object"&&Q!==null&&"text"in Q)W+=X$(String(Q.text??""));return W}return 0}function y4($){if(!$||$.length===0)return 0;let W=12;for(let Q of $)W+=n1(Q);return W}var n={CHECKPOINT:"checkpoint",COMPRESSION:"compression",SESSION:"session",COMPRESSION_SNAPSHOT:"compression-snapshot"};function _$($,W,Q="[Previous conversation context]"){let Z=[...$],J=Z.findIndex((j)=>j.role==="system");if(J===-1)return Z;let Y=Z[J],H=Y.content;if(!W||W.trim().length===0)return Z;let G={type:"text",text:`${Q}
|
|
7
7
|
|
|
8
|
-
${W}`},K=[...
|
|
9
|
-
`;
|
|
8
|
+
${W}`},K=[...C4(H,Q),G],z={...Y,content:K};return Z[J]=z,Z}function C4($,W){let Q=(Z)=>{let J=Z.indexOf(W);if(J>=0)return Z.slice(0,J).trimEnd();return Z};if(typeof $==="string"){let Z=Q($);return Z.trim().length>0?[{type:"text",text:Z}]:[]}if(Array.isArray($)){let Z=[];for(let J of $){if(typeof J==="string"){let Y=Q(J);if(Y.trim().length>0)Z.push({type:"text",text:Y});continue}if(J&&typeof J==="object"&&"type"in J){let Y=J;if(Y.type==="text"){let H=typeof Y.text==="string"?Y.text:"",X=Q(H);if(X.trim().length>0)Z.push({...Y,text:X});continue}Z.push(Y)}}return Z}if($&&typeof $==="object"&&"type"in $){let Z=$;if(Z.type==="text"){let J=typeof Z.text==="string"?Z.text:"",Y=Q(J);return Y.trim().length>0?[{...Z,text:Y}]:[]}return[Z]}return[]}function V0($,W){let Q=[...$],Z=-1;for(let V=Q.length-1;V>=0;V--)if(Q[V].role==="user"){Z=V;break}if(Z===-1){let V={role:"user",content:W};return[...Q,V]}let J=Q[Z],Y=J.content,H,X={type:"text",text:W};if(typeof Y==="string")H=[{type:"text",text:Y},X];else if(Array.isArray(Y))H=[...Y,X];else H=[Y,X];let G={...J,content:H};return Q[Z]=G,Q}var o1="[Old tool result content cleared]";function r($,W){try{let Q=$.startsWith("/")?$:v4("./",$),Z={...W,timestamp:W.timestamp||Date.now(),iso8601:new Date(W.timestamp||Date.now()).toISOString()},J=`${JSON.stringify(Z)}
|
|
9
|
+
`;I4(Q,J,"utf-8")}catch(Q){console.warn("[ContextCompression] Failed to write log:",Q)}}var f4=`
|
|
10
10
|
Summarize the conversation context for future continuation.
|
|
11
11
|
|
|
12
12
|
Rules:
|
|
@@ -22,26 +22,26 @@ Existing summary (if any):
|
|
|
22
22
|
|
|
23
23
|
Content to summarize:
|
|
24
24
|
{{content}}
|
|
25
|
-
`;function
|
|
25
|
+
`;function m$($){let{maxTokens:W,protectedTurns:Q=0,model:Z,stateStore:J,toolCompressionTarget:Y=0.45,minKeepToolResults:H=5,enableLogging:X=!1,logFilePath:G="compression-logs.jsonl"}=$,V=Math.floor(W*0.5),K=Math.floor(W*0.8),z=async(j,_)=>{let B=Date.now();if(X)r(G,{sessionId:j.sessionId,event:"compress_enter",timestamp:Date.now()});let F=await J.load(j.sessionId,n.COMPRESSION),A=j.messages,N=!!F?.summary;if(F?.summary&&F?.compressedRange){let{firstTurnEnd:E,protectedStart:w,totalMessagesAtCompression:x}=F.compressedRange;if(A.length>=x-5){if(A=[...A.slice(0,E),...A.slice(w)],X)r(G,{sessionId:j.sessionId,event:"compressed_messages_removed",firstTurnEnd:E,protectedStart:w,removedCount:w-E,messageCountBefore:j.messages.length,messageCountAfter:A.length,timestamp:Date.now()})}if(A=_$(A,F.summary),X)r(G,{sessionId:j.sessionId,event:"summary_injected",summaryLength:F.summary.length,timestamp:Date.now()})}let U=q$(A),R=A.length,q=A.filter((E)=>E.role==="tool").length,D=0,O=0,T=F?.summary,S=!1,f,L,y;if(X)r(G,{sessionId:j.sessionId,event:"compression_check",tokensBefore:U,messageCount:R,toolMessageCount:q,summaryCompressionThreshold:K,toolCompressionThreshold:V,hadExistingSummary:N,timestamp:Date.now()});if(U>K){let E=u4(A),w=m4(A,Q),x=w-E;if(X)r(G,{sessionId:j.sessionId,event:"summary_compression_triggered",tokensBefore:U,threshold:K,exceededBy:U-K,firstTurnEnd:E,protectedStart:w,summarizableCount:x,timestamp:Date.now()});let h=await h4(A,Z,F?.summary,E,w);if(h.summaryApplied){if(A=h.compressedMessages,T=h.newSummary,O=h.removedCount,S=!0,f=E,L=w,y=j.messages.length,A=_$(A,T),X)r(G,{sessionId:j.sessionId,event:"summary_compression_applied",removedMessages:O,summaryLength:T?.length??0,messagesAfter:A.length,elapsedMs:h.elapsedMs,details:h.details,timestamp:Date.now()})}else if(X)r(G,{sessionId:j.sessionId,event:"summary_compression_skipped",reason:"no_messages_to_summarize",elapsedMs:h.elapsedMs,timestamp:Date.now()})}else if(X&&U>K*0.7)r(G,{sessionId:j.sessionId,event:"approaching_summary_threshold",tokensBefore:U,threshold:K,percentUsed:(U/K*100).toFixed(1),timestamp:Date.now()});let b=S?q$(A):U;if(b>V){let E=Math.floor(W*Y),w=A.filter((h)=>h.role==="tool").length;if(X)r(G,{sessionId:j.sessionId,event:"tool_compression_triggered",tokensAfterSummary:b,threshold:V,exceededBy:b-V,targetTokens:E,toolMessageCount:w,minKeepToolResults:H,timestamp:Date.now()});let x=k4(A,E,H);if(A=x.compressedMessages,D=x.clearedCount,X)r(G,{sessionId:j.sessionId,event:"tool_compression_applied",clearedToolOutputs:D,clearedTools:x.clearedTools,tokensAfter:q$(A),targetTokens:E,timestamp:Date.now()})}else if(X&&b>V*0.8)r(G,{sessionId:j.sessionId,event:"approaching_tool_threshold",tokensAfterSummary:b,threshold:V,percentUsed:(b/V*100).toFixed(1),timestamp:Date.now()});let u=S||D>0,g=u?q$(A):U,c=u?Date.now():0,o=Date.now()-B;if(X)r(G,{sessionId:j.sessionId,event:u?"compression_completed":"compression_not_needed",tokensBefore:U,tokensAfter:g,tokensSaved:U-g,reductionPercent:u?((U-g)/U*100).toFixed(1):"0",messagesBefore:R,messagesAfter:A.length,clearedToolOutputs:D,removedMessages:O,summaryGenerated:S,elapsedMs:o,timestamp:c||Date.now()});if(S){let E={tokensBefore:U,tokensAfter:g,clearedToolOutputs:D,removedMessages:O,summaryGenerated:!0,timestamp:c},w={lastStats:E,history:[...F?.history??[],E],summary:T,updatedAt:c,compressedRange:f!==void 0&&L!==void 0&&y!==void 0?{firstTurnEnd:f,protectedStart:L,totalMessagesAtCompression:y}:F?.compressedRange};if(await J.save(j.sessionId,n.COMPRESSION,w),X)r(G,{sessionId:j.sessionId,stats:E,summaryLength:T?.length??0,compressedRange:w.compressedRange})}if(D>0&&!S&&X){let E={tokensBefore:U,tokensAfter:g,clearedToolOutputs:D,removedMessages:0,summaryGenerated:!1,timestamp:c};r(G,{sessionId:j.sessionId,stats:E,summaryLength:0})}let M={...j,messages:A,metadata:u?{...j.metadata,lastCompression:{tokensBefore:U,tokensAfter:g,clearedToolOutputs:D,removedMessages:O,summaryGenerated:S,timestamp:c}}:j.metadata};return _(M)};return z.__middlewareName="context-compression",z}function k4($,W,Q){let Z=[],J=[];if($.forEach((K,z)=>{if(K.role==="tool")Z.push(z),J.push(K.name||"unknown")}),Z.length===0)return{compressedMessages:$,clearedCount:0};let Y=Math.min(Q,Z.length),H=Z.slice(0,Z.length-Y),X=$,G=0,V=[];for(let K of H){let z=X[K];if(typeof z.content==="string"&&z.content===o1)continue;let j=typeof z.content==="string"?z.content.length:JSON.stringify(z.content).length;if(X=X.map((B,F)=>{if(F===K)return{...z,content:o1};return B}),G++,V.push({index:K,name:z.name||"unknown",originalSize:j}),q$(X)<=W)break}return{compressedMessages:X,clearedCount:G,clearedTools:V}}async function h4($,W,Q,Z,J){let Y=Date.now(),H=$.slice(Z,J);if(H.length===0)return{compressedMessages:$,newSummary:Q??"",removedCount:0,summaryApplied:!1,elapsedMs:Date.now()-Y};let X=H.filter((F)=>F.role==="user").length,G=H.filter((F)=>F.role==="assistant").length,V=H.filter((F)=>F.role==="tool").length,K=a1(H),z=K.length,j=await s1(K,W,Q),_=Date.now()-Y;if(!j)return{compressedMessages:$,newSummary:Q??"",removedCount:0,summaryApplied:!1,elapsedMs:_};return{compressedMessages:[...$.slice(0,Z),...$.slice(J)],newSummary:j,removedCount:H.length,summaryApplied:!0,elapsedMs:_,details:{userMessages:X,assistantMessages:G,toolMessages:V,contentLength:z,existingSummaryLength:Q?.length??0,newSummaryLength:j.length}}}function a1($){let W=[];for(let Q of $)if(Q.role==="user"){let Z=typeof Q.content==="string"?Q.content:JSON.stringify(Q.content);W.push(`## User
|
|
26
26
|
${Z}`)}else if(Q.role==="assistant"){let Z=typeof Q.content==="string"?Q.content:JSON.stringify(Q.content);W.push(`## Assistant
|
|
27
27
|
${Z}`)}else if(Q.role==="tool"){let Z=Q,J=typeof Z.content==="string"?Z.content:JSON.stringify(Z.content),Y=J.length>5000?`${J.slice(0,5000)}...[truncated]`:J;W.push(`## Tool: ${Z.name||"unknown"}
|
|
28
28
|
${Y}`)}return W.join(`
|
|
29
29
|
|
|
30
30
|
---
|
|
31
31
|
|
|
32
|
-
`)}async function
|
|
32
|
+
`)}async function s1($,W,Q,Z){let J=g4(Z??f4,Q,$),Y=[{role:"system",content:"You are a helpful assistant that creates concise rolling summaries."},{role:"user",content:J}],H="";for await(let X of W.stream({messages:Y,maxOutputTokens:500}))if(X.type==="delta"&&X.chunk.kind==="text")H+=X.chunk.text;else if(X.type==="response_end")break;return H.trim()}function g4($,W,Q){let Z=$.includes("{{existingSummary}}"),J=$.includes("{{content}}"),Y=$;if(Z)Y=Y.replace("{{existingSummary}}",W??"(none)");if(J)Y=Y.replace("{{content}}",Q);if(Z&&J)return Y;let H=[];if(!Z)H.push(`Existing summary (if any):
|
|
33
33
|
${W??"(none)"}`);if(!J)H.push(`Content to summarize:
|
|
34
34
|
${Q}`);return`${Y.trim()}
|
|
35
35
|
|
|
36
36
|
${H.join(`
|
|
37
37
|
|
|
38
38
|
`)}
|
|
39
|
-
`}async function d1($){let{sessionId:W,fullMessages:Q,model:Z,stateStore:J,summaryPrompt:Y,enableLogging:H=!1,logFilePath:X="compression-logs.jsonl"}=$,G=Date.now(),V=Q.length,K=Q.filter((N)=>N.role==="tool").length,z=Q.filter((N)=>N.role!=="system");if(H)r(X,{sessionId:W,event:"manual_compression_started",messageCount:V,toolOutputCount:K,messagesToSummarizeCount:z.length,timestamp:Date.now()});if(z.length===0){if(H)r(X,{sessionId:W,event:"manual_compression_skipped",reason:"no_messages_to_summarize",timestamp:Date.now()});return{summary:"",messageCount:V,toolOutputCount:K}}let j=await J.load(W,n.COMPRESSION),B=p1(z),U=await c1(B,Z,j?.summary,Y);if(!U){if(H)r(X,{sessionId:W,event:"manual_compression_failed",reason:"empty_summary_generated",timestamp:Date.now()});return{summary:"",messageCount:V,toolOutputCount:K}}let F=Date.now(),R=F-G,q=q$(Q),_={tokensBefore:q,tokensAfter:q,clearedToolOutputs:0,removedMessages:z.length,summaryGenerated:!0,timestamp:F},D={lastStats:_,history:[...j?.history??[],_],summary:U,updatedAt:F};if(await J.save(W,n.COMPRESSION,D),H)r(X,{sessionId:W,event:"manual_compression_completed",messageCount:V,toolOutputCount:K,summaryLength:U.length,tokensBefore:q,elapsedMs:R,timestamp:F});return{summary:U,messageCount:V,toolOutputCount:K}}function b4($){let W=-1;for(let Z=0;Z<$.length;Z++)if($[Z].role==="user"){W=Z;break}if(W===-1)return 0;let Q=-1;for(let Z=W+1;Z<$.length;Z++)if($[Z].role==="assistant"){Q=Z;break}if(Q===-1)return W+1;for(let Z=Q+1;Z<$.length;Z++)if($[Z].role==="user")return Z;return $.length}function y4($,W){if(W<=0)return $.length;let Q=0,Z=[];for(let Y=$.length-1;Y>=0;Y--)if($[Y].role==="user"){if(Q++,Z.unshift(Y),Q>=W)return Y}let J=6;return Math.max(0,$.length-J)}var C4=["planMode","planModeMiddleware","parallelMode","parallelSubagentMiddleware","blockedTools","commitProcessed","_pendingUserInput"];function P0($){let W={};for(let[Q,Z]of Object.entries($))if(!C4.includes(Q))W[Q]=Z;return W}function l1($){return{...$,metadata:P0($.metadata)}}var I4=1;function S0($,W){let Q=W?.phase;if(!Q)if(!$.shouldContinue)Q="completed";else if($.pendingToolCalls.length>0)Q="tool_execution";else Q="llm_call";let Z=W?.status;if(!Z)if(Q==="completed")Z=`Completed: ${$.stopReason??"unknown"}`;else if(Q==="tool_execution")Z=`Executing tools: ${$.pendingToolCalls.map((H)=>H.toolCall.function.name).join(", ")}`;else if(Q==="approval_pending")Z="Waiting for user approval";else Z=`Iteration ${$.iteration}: Calling LLM`;let J=W?.messages??$.messages;return{schemaVersion:I4,sessionId:$.sessionId,agentName:W?.agentName,iteration:$.iteration,phase:Q,status:Z,modelConfig:W?.modelConfig,requestParams:W?.requestParams,messages:[...J],pendingToolCalls:$.pendingToolCalls.map((Y)=>({toolCall:{...Y.toolCall},result:Y.result,isError:Y.isError})),currentResponse:$.currentResponse,currentThinking:$.currentThinking,shouldContinue:$.shouldContinue,stopReason:$.stopReason,lastModelStopReason:$.lastModelStopReason,usage:{...$.usage},metadata:P0($.metadata),savedAt:Date.now()}}function X0($){let W=$.schemaVersion??1;if(W!==1)throw Error(`Unsupported checkpoint schemaVersion: ${W}. Please migrate checkpoints or upgrade GoatChain.`);return{sessionId:$.sessionId,iteration:$.iteration,messages:[...$.messages],pendingToolCalls:$.pendingToolCalls.map((Q)=>({toolCall:{...Q.toolCall},result:Q.result,isError:Q.isError})),currentResponse:$.currentResponse,currentThinking:$.currentThinking,shouldContinue:$.shouldContinue,stopReason:$.stopReason,lastModelStopReason:$.lastModelStopReason,usage:{...$.usage},metadata:{...$.metadata}}}class e0{stateStore;constructor($){this.stateStore=$}hasStore(){return Boolean(this.stateStore)}async saveCheckpoint($){if(!this.stateStore)return;await this.stateStore.saveCheckpoint($)}async loadCheckpoint($){return this.stateStore?.loadCheckpoint($)}async clearCheckpoint($){if(!this.stateStore)return;await this.stateStore.deleteCheckpoint($)}}import{EventEmitter as p4}from"node:events";class N$ extends Error{constructor($="Agent execution aborted"){super($);this.name="AgentAbortError"}}class $1 extends Error{iterations;constructor($,W){super(W??`Agent exceeded maximum iterations (${$})`);this.name="AgentMaxIterationsError",this.iterations=$}}class S$ extends Error{constructor($="Agent execution paused"){super($);this.name="AgentPauseError"}}function U$($,W){if(!$?.aborted)return;let Q=$?.reason;if(Q instanceof Error)throw Q;throw new N$(typeof Q==="string"?Q:W?`${W} aborted`:"Agent execution aborted")}function x0($){return(W,Q)=>{let Z=-1,J=async(Y,H)=>{if(Y<=Z)throw Error("next() called multiple times");if(Z=Y,Y===$.length)return Q?await Q(H):H;let X=$[Y];return X(H,(G)=>J(Y+1,G))};return J(0,W)}}function w0($,W){let Q=[{role:"system",content:W},...$.messages??[],{role:"user",content:$.input}];return{sessionId:$.sessionId??"",messages:Q,iteration:0,pendingToolCalls:[],currentResponse:"",shouldContinue:!0,usage:{promptTokens:0,completionTokens:0,totalTokens:0},metadata:{}}}class I extends Error{code;retryable;status;constructor($,W){super($);this.name="ModelError",this.code=W.code,this.retryable=W.retryable??!1,this.status=W.status}}class A${static isRetryableStatus($){return $===408||$===409||$===429||$>=500&&$<=599}static async sleep($,W){if($<=0)return Promise.resolve();return new Promise((Q,Z)=>{let J=setTimeout(()=>{Y(),Q()},$);function Y(){if(clearTimeout(J),W)W.removeEventListener("abort",H)}function H(){Y(),Z(Error("Aborted"))}if(W){if(W.aborted)return H();W.addEventListener("abort",H)}})}}function m$($="req"){let W=Math.random().toString(16).slice(2),Q=Date.now().toString(16);return`${$}_${Q}_${W}`}async function*i1($,W){let Q=new Map,Z=new Map;for await(let J of $){if(J.type==="response.created"){yield{type:"response_start",requestId:W,model:{provider:"codex",modelId:J.response.model}};continue}if(J.type==="response.output_item.added"){let Y=J;if(Y.item.type==="reasoning")yield{type:"delta",requestId:W,chunk:{kind:"thinking_start"}};else if(Y.item.type==="function_call"){let H=Y.item.call_id;Q.set(H,{toolId:Y.item.name,argsText:""}),Z.set(Y.output_index,H)}continue}if(J.type==="response.output_text.delta"){yield{type:"delta",requestId:W,chunk:{kind:"text",text:J.delta}};continue}if(J.type==="response.reasoning_summary_text.delta"){yield{type:"delta",requestId:W,chunk:{kind:"thinking_delta",text:J.delta}};continue}if(J.type==="response.function_call_arguments.delta"){let Y=J,H=Z.get(Y.output_index);if(H){let X=Q.get(H);if(X)X.argsText+=Y.delta,yield{type:"delta",requestId:W,chunk:{kind:"tool_call_delta",callId:H,toolId:X.toolId,argsTextDelta:Y.delta}}}continue}if(J.type==="response.output_item.done"){let Y=J;if(Y.item.type==="reasoning")yield{type:"delta",requestId:W,chunk:{kind:"thinking_end"}};else if(Y.item.type==="function_call"){let H=Y.item.call_id;if(Q.get(H))yield{type:"delta",requestId:W,chunk:{kind:"tool_call_delta",callId:H,toolId:Y.item.name,argsTextDelta:void 0}}}continue}if(J.type==="response.completed"){yield{type:"response_end",requestId:W,stopReason:"final",usage:J.response.usage};continue}if(J.type==="response.incomplete"){let Y=J,H=Y.response.incomplete_details?.reason,X="error";if(H==="max_tokens"||H==="max_output_tokens")X="length";else if(H==="tool_calls"||H==="function_call")X="tool_call";else if(H==="stop"||H==="end_turn")X="final";yield{type:"response_end",requestId:W,stopReason:X,usage:Y.response.usage};continue}if(J.type==="error"){let Y=J;yield{type:"error",requestId:W,terminal:!0,source:"adapter",error:{code:Y.code,message:Y.message,retryable:!1}};continue}}}function W1($){try{let W=$.split(".");if(W.length!==3)throw new I("Invalid JWT token format",{code:"invalid_jwt_format",retryable:!1});let Q=W[1],Z=atob(Q.replace(/-/g,"+").replace(/_/g,"/")),J=JSON.parse(Z),Y=J["https://api.openai.com/auth"]?.chatgpt_account_id||J.chatgpt_account_id||J.organizations?.[0]?.id;if(!Y)throw new I("ChatGPT account ID not found in token",{code:"account_id_not_found",retryable:!1});return Y}catch(W){if(W instanceof I)throw W;throw new I("Failed to extract account ID from token",{code:"token_decode_error",retryable:!1})}}function v4($){let W=($.baseUrl||"https://chatgpt.com/backend-api").replace(/\/$/,"");async function Q(){let X=typeof $.accessToken==="function"?await $.accessToken():$.accessToken;if(!X||typeof X!=="string"||!X.trim())throw new I("Missing Codex access token",{code:"missing_access_token",retryable:!1});return X.trim()}async function Z(){if($.accountId){let X=typeof $.accountId==="function"?await $.accountId():$.accountId;if(!X||typeof X!=="string"||!X.trim())throw new I("Invalid ChatGPT account ID",{code:"invalid_account_id",retryable:!1});return X.trim()}try{let X=await Q();return W1(X)}catch(X){if(X instanceof I)throw X;throw new I("Failed to extract account ID from token",{code:"account_id_extraction_failed",retryable:!1})}}async function J(){if(!$.codexInstructions)return"You are an AI coding assistant. Help the user with their coding tasks.";return(typeof $.codexInstructions==="function"?await $.codexInstructions():$.codexInstructions)||"You are an AI coding assistant. Help the user with their coding tasks."}function Y(X){let G=[];for(let V of X)if(V.role==="system")G.push({role:"developer",content:[{type:"input_text",text:typeof V.content==="string"?V.content:JSON.stringify(V.content)}]});else if(V.role==="user")G.push({role:"user",content:[{type:"input_text",text:typeof V.content==="string"?V.content:JSON.stringify(V.content)}]});else if(V.role==="assistant"){if(G.push({role:"assistant",content:[{type:"output_text",text:typeof V.content==="string"?V.content:JSON.stringify(V.content)}]}),V.tool_calls&&V.tool_calls.length>0)for(let K of V.tool_calls)G.push({type:"function_call",call_id:K.id,name:K.function.name,arguments:typeof K.function.arguments==="string"?K.function.arguments:JSON.stringify(K.function.arguments)})}else if(V.role==="tool")G.push({type:"function_call_output",call_id:V.tool_call_id,output:typeof V.content==="string"?V.content:JSON.stringify(V.content)});return G}async function*H(X){let{request:G}=X,V=G.requestId||m$("req");try{let K=[];if(G.instructions)K.push({role:"developer",content:[{type:"input_text",text:G.instructions}]});if(G.messages&&G.messages.length>0)K.push(...Y(G.messages));else if(G.input)K.push({role:"user",content:[{type:"input_text",text:G.input}]});let[z,j,B]=await Promise.all([Q(),Z(),J()]),U=k4(G.model.modelId),F={model:U,input:K,stream:!0,store:!1,instructions:B},R=G.reasoning?.effort||h4(U);if(F.reasoning={effort:R,summary:G.reasoning?.summary||"auto"},F.text={verbosity:"medium"},F.include=["reasoning.encrypted_content"],G.metadata)F.metadata=G.metadata;let q=G.metadata?.promptCacheKey;if(q)F.prompt_cache_key=q;if(G.tools&&G.tools.length>0)F.tools=G.tools.map((A)=>({type:"function",name:A.function.name,description:A.function.description,parameters:A.function.parameters}));let _={"Content-Type":"application/json",Authorization:`Bearer ${z}`,"chatgpt-account-id":j,"OpenAI-Beta":"responses=experimental",originator:"codex_cli_rs",accept:"text/event-stream"};if(q)_.conversation_id=q,_.session_id=q;let D=await fetch(`${W}/codex/responses`,{method:"POST",headers:_,body:JSON.stringify(F),signal:G.signal});if(!D.ok){let A=await D.text().catch(()=>"");throw new I(`Codex API error: ${D.status} ${A}`,{code:`codex_http_${D.status}`,retryable:A$.isRetryableStatus(D.status),status:D.status})}if(!D.body)throw new I("No response body",{code:"no_response_body",retryable:!1});let N=f4(D.body);yield*i1(N,V)}catch(K){if(K?.name==="AbortError")throw new I("Request aborted",{code:"aborted",retryable:!1});if(K instanceof I)throw K;throw new I(K?.message||"Unknown error",{code:K?.code||"unknown_error",retryable:!1})}}return{provider:"codex",defaultModelId:$.defaultModelId,stream:H}}async function*f4($){let W=$.getReader(),Q=new TextDecoder,Z="";try{while(!0){let{done:J,value:Y}=await W.read();if(J)break;Z+=Q.decode(Y,{stream:!0});let H=Z.split(`
|
|
40
|
-
`);Z=H.pop()||"";for(let X of H)if(X.startsWith("data: ")){let G=X.slice(6);if(G==="[DONE]")return;try{yield JSON.parse(G)}catch(V){continue}}}}finally{W.releaseLock()}}function k4($){if(!$)return"gpt-5.1";let Q=($.includes("/")?$.split("/").pop():$).toLowerCase();if(Q.includes("gpt-5.2-codex")||Q.includes("gpt 5.2 codex"))return"gpt-5.2-codex";if(Q.includes("gpt-5.2")||Q.includes("gpt 5.2"))return"gpt-5.2";if(Q.includes("gpt-5.1-codex-max")||Q.includes("gpt 5.1 codex max"))return"gpt-5.1-codex-max";if(Q.includes("gpt-5.1-codex-mini")||Q.includes("gpt 5.1 codex mini"))return"gpt-5.1-codex-mini";if(Q.includes("codex-mini-latest")||Q.includes("gpt-5-codex-mini")||Q.includes("gpt 5 codex mini"))return"codex-mini-latest";if(Q.includes("gpt-5.1-codex")||Q.includes("gpt 5.1 codex"))return"gpt-5.1-codex";if(Q.includes("gpt-5.1")||Q.includes("gpt 5.1"))return"gpt-5.1";if(Q.includes("codex"))return"gpt-5.1-codex";if(Q.includes("gpt-5")||Q.includes("gpt 5"))return"gpt-5.1";return"gpt-5.1"}function h4($){let W=$.toLowerCase();if(W.includes("codex-mini"))return"medium";if(W.includes("gpt-5.2-codex")||W.includes("codex-max"))return"high";if(W.includes("nano")||W.includes("mini"))return"low";return"medium"}class x${maxAttempts;baseDelayMs;maxDelayMs;strategy;jitter;multiplier;_previousDelay;constructor($={}){this.maxAttempts=$.maxAttempts??3,this.baseDelayMs=$.baseDelayMs??500,this.maxDelayMs=$.maxDelayMs??30000,this.strategy=$.strategy??"exponential",this.jitter=$.jitter??"equal",this.multiplier=$.multiplier??2,this._previousDelay=this.baseDelayMs}getDelay($){let W;switch(this.strategy){case"exponential":W=this.baseDelayMs*this.multiplier**($-1);break;case"linear":W=this.baseDelayMs*$;break;case"fixed":W=this.baseDelayMs;break}return W=Math.min(W,this.maxDelayMs),W=this.applyJitter(W),this._previousDelay=W,Math.floor(W)}applyJitter($){switch(this.jitter){case"full":return Math.random()*$;case"equal":return $/2+Math.random()*$/2;case"decorrelated":return Math.min(this.maxDelayMs,Math.random()*(this._previousDelay*3-this.baseDelayMs)+this.baseDelayMs);case"none":default:return $}}canRetry($){return $<this.maxAttempts}reset(){this._previousDelay=this.baseDelayMs}toString(){return`RetryPolicy(${this.strategy}, max=${this.maxAttempts}, base=${this.baseDelayMs}ms, cap=${this.maxDelayMs}ms, jitter=${this.jitter})`}static default=new x$;static aggressive=new x$({maxAttempts:5,baseDelayMs:1000,maxDelayMs:60000});static gentle=new x$({maxAttempts:3,baseDelayMs:2000,maxDelayMs:30000,jitter:"full"})}function b0($){let W=$.adapter;if(!W)throw new I("Missing adapter. Provide `adapter` option.",{code:"missing_adapter",retryable:!1});if(!W.defaultModelId)throw new I("Adapter must have a defaultModelId.",{code:"missing_model_id",retryable:!1});let Q={provider:W.provider,modelId:W.defaultModelId},Z=new x$({maxAttempts:$.retry?.maxAttempts??3,baseDelayMs:$.retry?.baseDelayMs??500,maxDelayMs:$.retry?.maxDelayMs??30000,strategy:$.retry?.strategy??"exponential",jitter:$.retry?.jitter??"equal"}),J=$.timeoutMs??1800000;async function*Y(X){let G=X.requestId||m$("req"),{model:V,variants:K,...z}=X,j=X.model??Q,B=(()=>{let A=[j,...Array.isArray(K)?K:[]],O=new Set,T=[];for(let P of A){if(!P||typeof P.provider!=="string"||typeof P.modelId!=="string")continue;let v=`${P.provider}:${P.modelId}`;if(O.has(v))continue;O.add(v),T.push(P)}return T.length>0?T:[j]})(),U=X.timeoutMs??J,F=new AbortController,R=X.signal,q=setTimeout(()=>F.abort(),U),_=()=>F.abort();if(R)if(R.aborted)F.abort();else R.addEventListener("abort",_);let D,N=0;try{let A=0;for(let O=0;O<B.length;O++){let T=B[O],P=!1;A=0;let v={...z,requestId:G,model:T,stream:X.stream??!0,signal:F.signal,timeoutMs:U};try{for(let L=1;L<=Z.maxAttempts;L++){A=L;try{for await(let y of W.stream({request:v})){if(y.type==="delta")P=!0;yield y}return}catch(y){let b=Q1(y),u=b.retryable;if(P||!u||!Z.canRetry(L))throw b;let g=Z.getDelay(L);$.retry?.onRetry?.({attempt:L,maxAttempts:Z.maxAttempts,delayMs:g,error:{code:b.code,message:b.message,retryable:b.retryable},model:T,request:v}),await A$.sleep(g,F.signal)}}}catch(L){let y=Q1(L);D=T,N=A||1;let b=O<B.length-1;if(!P&&b){yield{type:"error",requestId:G,terminal:!1,model:T,attempt:N,source:"client",error:{code:y.code,message:y.message,retryable:y.retryable}};continue}throw y}}}catch(A){let O=Q1(A);throw yield{type:"error",requestId:G,terminal:!0,model:D??j,attempt:N||1,source:"client",error:{code:O.code,message:O.message,retryable:O.retryable}},O}finally{if(clearTimeout(q),R)R.removeEventListener("abort",_)}throw new I("Max retry attempts exceeded",{code:"max_retries_exceeded",retryable:!1})}async function H(X){let G="",V="",K="error",z,j,B=X.requestId||"",U=!1;for await(let F of Y({...X,stream:!0}))if(F.type==="response_start")U=!0,B=F.requestId,j=F.model,G="";else if(F.type==="delta"&&F.chunk.kind==="text")G+=F.chunk.text;else if(F.type==="response_end")V=G,K=F.stopReason,z=F.usage;else if(F.type==="error")K="error";if(!j)throw new I("Missing response_start from adapter",{code:"protocol_error",retryable:!1});return{requestId:B,model:j,text:U?V:G,stopReason:K,usage:z}}return{get modelId(){return Q.modelId},get modelRef(){return Q},setModelId(X){Q={provider:Q.provider,modelId:X}},stream:Y,run:H}}function Q1($){if($ instanceof I)return $;if($&&typeof $==="object"){let W=typeof $.status==="number"?$.status:void 0,Q=typeof $.code==="string"?$.code:W?`http_${W}`:"unknown_error",Z=typeof $.message==="string"?$.message:"Unknown error",J=W?A$.isRetryableStatus(W):!1;return new I(Z,{code:Q,retryable:J,status:W})}return new I(String($||"Unknown error"),{code:"unknown_error",retryable:!1})}import r1 from"openai";function g4($){function W(Q,Z){if(typeof Q!=="string")return"";let J=Q.trim();if(!J)return"";if(/^data:/i.test(J)||/^https?:\/\//i.test(J))return J;if(typeof Z==="string"&&Z.trim())return`data:${Z.trim()};base64,${J}`;return J}if(typeof $==="string")return $.trim().length===0?"":$;if($===null||$===void 0)return"";if(typeof $==="object"&&"type"in $){let Q=$;if(Q.type==="text"&&Q.text)return Q.text;if(Q.type==="image"){let Z=W(Q.data??Q.source?.data,Q.mimeType??Q.source?.media_type??Q.source?.mimeType);if(!Z)return"";return[{type:"image_url",image_url:{url:Z}}]}}if(Array.isArray($)){let Q=[];for(let Z of $)if(typeof Z==="string")Q.push({type:"text",text:Z});else if(Z&&typeof Z==="object"&&"type"in Z){let J=Z;if(J.type==="text"&&J.text)Q.push({type:"text",text:J.text});else if(J.type==="image"){let Y=W(J.data??J.source?.data,J.mimeType??J.source?.media_type??J.source?.mimeType);if(Y)Q.push({type:"image_url",image_url:{url:Y}})}}return Q.length>0?Q:""}return String($)}function u4($){return{...$,content:g4($.content)}}function m4($,W){if(typeof W==="string"&&/deepseek/i.test(W))return!0;return/^deepseek-/i.test($)}function y0($={}){let W=$.baseUrl;function Q(){if(typeof $.apiKey==="function"){let V=$.apiKey();if(typeof V==="string"){let K=V.trim();if(!K)throw new I("Missing apiKey",{code:"missing_api_key",retryable:!1});return K}if(V!=null)throw new I("Invalid apiKey provider",{code:"invalid_api_key",retryable:!1})}if(typeof $.apiKey==="string"){let V=$.apiKey.trim();if(!V)throw new I("Missing apiKey",{code:"missing_api_key",retryable:!1});return V}let G=typeof process<"u"?process.env?.OPENAI_API_KEY:void 0;if(typeof G!=="string"||!G.trim())throw new I("Missing OPENAI_API_KEY",{code:"missing_api_key",retryable:!1});return G.trim()}function Z(){if(!(typeof globalThis.window<"u"))return!1;let V=typeof process<"u"&&!!process?.versions?.node,K=typeof globalThis.Bun<"u"||typeof process<"u"&&!!process?.versions?.bun;return V||K}function J(){let G=Q(),V=Z();if(typeof W==="string"&&/\/chat\/completions\/?$/.test(W))return new r1({apiKey:G,dangerouslyAllowBrowser:V,organization:$.organization,project:$.project,baseURL:"https://api.openai.com/v1",fetch:(z,j)=>{return fetch(W,j)}});return new r1({apiKey:G,dangerouslyAllowBrowser:V,organization:$.organization,project:$.project,baseURL:W||void 0})}function Y(G){return{provider:"openai",modelId:G.model.modelId}}function H(G){if(G instanceof I)return G;let V=typeof G?.status==="number"?G.status:void 0,K=typeof G?.message==="string"?G.message:"OpenAI error",z=typeof G?.code==="string"?G.code:V?`openai_http_${V}`:"openai_error",j=V?A$.isRetryableStatus(V):!1;return new I(K,{code:z,retryable:j,status:V})}async function*X(G){let{request:V}=G,K=V.requestId||m$("req"),z=J(),j=V.model.modelId,B=$.compat?.interleavedThinking,U=typeof B==="boolean"?B:m4(j,W),F=V.stream!==!1,R=[];if(V.messages&&Array.isArray(V.messages)){let D=-1;for(let N=V.messages.length-1;N>=0;N--)if(V.messages[N].role==="user"){D=N;break}for(let N=0;N<V.messages.length;N++){let A=V.messages[N],O=u4(A),T=N<D;if(O&&typeof O==="object"&&O.role==="assistant"){if(T){if("reasoning_content"in O)delete O.reasoning_content}else if(!U){if("reasoning_content"in O)delete O.reasoning_content}else if(Array.isArray(O?.tool_calls)&&O.tool_calls.length>0){let P=O.reasoning_content;if(typeof P!=="string"||P.length===0)O.reasoning_content="."}}R.push(O)}}else{if(typeof V.instructions==="string"&&V.instructions.length>0)R.push({role:"system",content:V.instructions});R.push({role:"user",content:V.input})}let q=(()=>{let D=V.reasoning?.effort;if(typeof D!=="string")return;if(D==="none"||D==="minimal"||D==="low"||D==="medium"||D==="high"||D==="xhigh")return D;return})(),_={model:j,messages:R,stream:F,stream_options:F?{include_usage:!0}:void 0,metadata:V.metadata??void 0,reasoning_effort:q,max_tokens:V.maxOutputTokens??void 0,stop:V.stop??void 0,temperature:V.temperature??void 0,top_p:V.topP??void 0};if(V.tools&&Array.isArray(V.tools)&&V.tools.length>0)_.tools=V.tools;try{let D=Y(V);if(yield{type:"response_start",requestId:K,model:D},!F){let L=await z.chat.completions.create({..._,stream:!1},{signal:V.signal,timeout:V.timeoutMs}),y=Array.isArray(L?.choices)?L.choices[0]:void 0,b=y?.message,u=typeof b?.reasoning_content==="string"?b.reasoning_content:"";if(u.length>0)yield{type:"delta",requestId:K,chunk:{kind:"thinking_start"}},yield{type:"delta",requestId:K,chunk:{kind:"thinking_delta",text:u}},yield{type:"delta",requestId:K,chunk:{kind:"thinking_end",text:u}};let g=typeof b?.content==="string"?b.content:"";if(g.length>0)yield{type:"delta",requestId:K,chunk:{kind:"text",text:g}};let c=Array.isArray(b?.tool_calls)?b.tool_calls:[];for(let l=0;l<c.length;l++){let M=c[l],E=typeof M?.id==="string"?M.id:`call_${l}`,w=typeof M?.function?.name==="string"?M.function.name:void 0,x=typeof M?.function?.arguments==="string"?M.function.arguments:void 0;if(x||w)yield{type:"delta",requestId:K,chunk:{kind:"tool_call_delta",callId:E,toolId:w,argsTextDelta:x}}}let o=n1(y?.finish_reason);yield{type:"response_end",requestId:K,stopReason:o,usage:L?.usage};return}let N=await z.chat.completions.create({..._,stream:!0},{signal:V.signal,timeout:V.timeoutMs}),A=null,O,T=new Map,P=!1,v="";for await(let L of N){if(L?.usage!=null)O=L.usage;let y=Array.isArray(L?.choices)?L.choices:[];for(let b of y){if(b?.finish_reason!=null)A=b.finish_reason;let u=b?.delta,g=u?.reasoning_content;if(typeof g==="string"&&g.length>0){if(!P)P=!0,yield{type:"delta",requestId:K,chunk:{kind:"thinking_start"}};v+=g,yield{type:"delta",requestId:K,chunk:{kind:"thinking_delta",text:g}}}let c=u?.content;if(typeof c==="string"&&c.length>0){if(P)P=!1,yield{type:"delta",requestId:K,chunk:{kind:"thinking_end",text:v||void 0}};yield{type:"delta",requestId:K,chunk:{kind:"text",text:c}}}let o=Array.isArray(u?.tool_calls)?u.tool_calls:[];for(let l of o){let M=typeof l?.index==="number"?l.index:0,w=T.get(M)||(typeof l?.id==="string"?l.id:`call_${M}`);T.set(M,w);let x=typeof l?.function?.name==="string"?l.function.name:void 0,f=typeof l?.function?.arguments==="string"?l.function.arguments:void 0;if(x||f)yield{type:"delta",requestId:K,chunk:{kind:"tool_call_delta",callId:w,toolId:x,argsTextDelta:f}}}}}if(P)yield{type:"delta",requestId:K,chunk:{kind:"thinking_end",text:v||void 0}};yield{type:"response_end",requestId:K,stopReason:n1(A),usage:O}}catch(D){if(D?.name==="AbortError")throw new I("Aborted",{code:"aborted",retryable:!1});throw H(D)}}return{provider:"openai",defaultModelId:$.defaultModelId,stream:X}}function n1($){if($==="tool_calls"||$==="function_call")return"tool_call";if($==="length")return"length";if($==="content_filter")return"error";if($==="stop"||$==null)return"final";return"final"}class C0{queue=[];waiters=[];enqueue($){let W=this.waiters.shift();if(W){W($);return}this.queue.push($)}isEmpty(){return this.queue.length===0}async dequeueOrWait($){if(this.queue.length>0)return this.queue.shift();return new Promise((W)=>{let Q=setTimeout(()=>{let Z=this.waiters.indexOf(W);if(Z>=0)this.waiters.splice(Z,1);W(void 0)},$);this.waiters.push((Z)=>{clearTimeout(Q),W(Z)})})}}class Z1{tools;options;eventQueue=new C0;constructor($,W){this.tools=$;this.options=W}async*executeTasksInParallel($,W,Q){this.eventQueue=new C0;let Z=!1,J=$.map(async(X)=>{let G=X.toolCall.function.name,V=this.tools?.get(G);if(!V)return{tc:X,result:`Tool "${G}" not found`,isError:!0};try{let K=typeof X.toolCall.function.arguments==="string"?JSON.parse(X.toolCall.function.arguments):X.toolCall.function.arguments,z=`${W.sessionId}:subagent:${crypto.randomUUID()}`,j={...Q,sessionId:z,emitEvent:(U)=>{this.eventQueue.enqueue({...U,sessionId:W.sessionId})}},B=await V.execute(K,j);return{tc:X,result:B,isError:!1}}catch(K){return{tc:X,result:`Task execution failed: ${K instanceof Error?K.message:String(K)}`,isError:!0}}}),Y=Promise.allSettled(J).then((X)=>{return Z=!0,X});while(!Z||!this.eventQueue.isEmpty()){let X=await this.eventQueue.dequeueOrWait(5);if(X)yield X}let H=await Y;for(let[X,G]of H.entries()){let V=$[X];if(G.status==="fulfilled"){let{result:K,isError:z}=G.value;V.result=K,V.isError=z}else V.result=`Task execution rejected: ${G.reason}`,V.isError=!0;if(!this.options.hasAssistantToolCallMessage(W,V.toolCall.id))this.options.addAssistantMessageWithToolCalls(W);yield{type:"tool_result",tool_call_id:V.toolCall.id,result:V.result,isError:V.isError,sessionId:W.sessionId},this.options.addToolResultToHistory(W,V)}}}class w${hooks;constructor($){this.hooks=$??{}}async executePreToolUse($){let W=this.hooks.preToolUse;if(!W)return{allow:!0};return await W($)}async executePostToolUse($,W){let Q=this.hooks.postToolUse;if(!Q)return;await Q($,W)}async executePostToolUseFailure($,W){let Q=this.hooks.postToolUseFailure;if(!Q)return;await Q($,W)}}class J1{options;toolEventQueue=[];constructor($){this.options=$}_log(...$){if(this.options.log)this.options.log(...$)}createToolExecutionContext($,W,Q,Z){return{sessionId:$.sessionId,toolCallId:Q,toolName:Z,signal:W,usage:$.usage,emitEvent:(J)=>{this.toolEventQueue.push({...J,sessionId:$.sessionId})}}}async executeToolCall($,W,Q,Z,J){U$(Q,`Tool execution: ${$.toolCall.function.name}`);let Y=Z?new w$(Z):void 0,H=$.toolCall.id,X=$.toolCall,G=X,V=(B)=>({sessionId:W.sessionId,toolCall:B,toolContext:W});if(J){if(!J.allow)return $.result="Tool execution blocked by PreToolUse hook",$.isError=!0,{type:"tool_result",tool_call_id:H,result:$.result,isError:!0,sessionId:W.sessionId};if(J.modifiedToolCall)G={...J.modifiedToolCall,id:H,type:X.type}}else if(Y){let B=await Y.executePreToolUse(V(G));if(!B.allow)return $.result="Tool execution blocked by PreToolUse hook",$.isError=!0,{type:"tool_result",tool_call_id:H,result:$.result,isError:!0,sessionId:W.sessionId};if(B.modifiedToolCall)G={...B.modifiedToolCall,id:H,type:X.type}}let K=this.options.tools?.get(G.function.name);if(!K)return this._log(`Tool NOT FOUND: ${G.function.name}`),$.result=`Tool not found: ${G.function.name}`,$.isError=!0,{type:"tool_result",tool_call_id:H,result:$.result,isError:!0,sessionId:W.sessionId};let z;try{z=typeof G.function.arguments==="string"?G.function.arguments.trim()===""?{}:JSON.parse(G.function.arguments):G.function.arguments??{}}catch(B){this._log(`Warning: Failed to parse tool arguments for ${G.function.name}, using empty object`),z={}}let j={...W,toolCallId:H,toolName:G.function.name};try{if($.result=await K.execute(z,j),$.isError=!1,Y)await Y.executePostToolUse(V(G),$.result);return{type:"tool_result",tool_call_id:H,result:$.result,sessionId:W.sessionId}}catch(B){let U=B instanceof Error?B:Error(String(B));if(this._log(`Tool execution threw ERROR: ${G.function.name} - ${U.message}`),$.result=U.message,$.isError=!0,Y)await Y.executePostToolUseFailure(V(G),U);return{type:"tool_result",tool_call_id:H,result:$.result,isError:!0,sessionId:W.sessionId}}}async*handleToolCalls($,W,Q){let Z=$.pendingToolCalls.length,J=Q?.signal,Y=Q?.toolContextInput,H=Y?.approval,X=H?.decisions??{},G=(q)=>{return this.options.approvalHandler.shouldRequireApproval(H,q)},V=(q)=>{return $.messages.some((_)=>{if(!_||typeof _!=="object"||_.role!=="assistant")return!1;let D=_.tool_calls;return Array.isArray(D)&&D.some((N)=>N?.id===q)})},K=(q)=>{if(!V(q))this.options.addAssistantMessageWithToolCalls($)},z=(q)=>{return $.messages.some((_)=>_&&typeof _==="object"&&_.role==="tool"&&_.tool_call_id===q)},j=new Set,B=(q)=>{try{return typeof q.function.arguments==="string"?JSON.parse(q.function.arguments):q.function.arguments}catch(_){let D=_ instanceof Error?_.message:String(_);return{_raw:q.function.arguments,_parseError:D}}},U=(q)=>{let _=[];for(let D=q;D<$.pendingToolCalls.length;D++){let N=$.pendingToolCalls[D];if(z(N.toolCall.id))continue;if(j.has(N.toolCall.id))continue;if(X[N.toolCall.id])continue;let A=this.options.tools?.get(N.toolCall.function.name),O=A?.riskLevel??"safe";if(A&&this.options.isToolDisabled(N.toolCall.function.name))continue;if(A&&this.options.isToolBlocked($,N.toolCall.function.name))continue;if(!A||!G(O))continue;j.add(N.toolCall.id),_.push({type:"tool_approval_requested",tool_call_id:N.toolCall.id,toolName:N.toolCall.function.name,riskLevel:O,args:B(N.toolCall),sessionId:$.sessionId})}return _};if($.metadata?.parallelMode===!0){let q=$.pendingToolCalls.filter((_)=>{let D=_.toolCall.function.name;return D==="Task"||D.endsWith("_Task")});if(q.length>1)yield*this.options.parallelTaskExecutor.executeTasksInParallel(q,$,W),$.pendingToolCalls=$.pendingToolCalls.filter((_)=>!q.includes(_))}let R=this.options.checkpointManager.hasStore();for(let q=0;q<$.pendingToolCalls.length;q++){let _=$.pendingToolCalls[q];if(z(_.toolCall.id)){$.pendingToolCalls.splice(q,1),q--;continue}let D=_.toolCall.function.name,N;if(Q?.hooks?.preToolUse){let L=new w$(Q.hooks),y=(b)=>({sessionId:$.sessionId,toolCall:b,toolContext:W});if(N=await L.executePreToolUse(y(_.toolCall)),!N.allow){this._log(`Tool BLOCKED by preToolUse hook: ${D}`),_.result="Tool execution blocked by PreToolUse hook",_.isError=!0,K(_.toolCall.id),yield{type:"tool_result",tool_call_id:_.toolCall.id,result:_.result,isError:!0,sessionId:$.sessionId},this.options.addToolResultToHistory($,_),$.pendingToolCalls.splice(q,1),q--,await this.options.saveCheckpoint($,{phase:"tool_execution",status:`Tool blocked by preToolUse hook: ${D}`,modelConfig:Q?.checkpointModelConfig,requestParams:Q?.requestParams});continue}}if(N?.modifiedToolCall)_.toolCall={...N.modifiedToolCall,id:_.toolCall.id,type:_.toolCall.type};let A=_.toolCall.function.name,O=this.options.tools?.get(A),T=O?.riskLevel??"safe";if(O&&this.options.isToolBlocked($,A)){let L=`Tool "${A}" is blocked by middleware`;this._log(`Tool BLOCKED: ${A} - ${L}`),_.result=`Tool execution skipped: ${L}`,_.isError=!0,K(_.toolCall.id),yield{type:"tool_skipped",tool_call_id:_.toolCall.id,toolName:A,reason:L,sessionId:$.sessionId},yield{type:"tool_result",tool_call_id:_.toolCall.id,result:_.result,isError:!0,sessionId:$.sessionId},this.options.addToolResultToHistory($,_),$.pendingToolCalls.splice(q,1),q--,await this.options.saveCheckpoint($,{phase:"tool_execution",status:`Tool blocked: ${A}`,modelConfig:Q?.checkpointModelConfig,requestParams:Q?.requestParams});continue}if(O&&this.options.isToolDisabled(A)){let L=`Tool "${A}" is disabled for this session`;this._log(`Tool DISABLED: ${A}`),_.result=`Tool execution skipped: ${L}`,_.isError=!0,K(_.toolCall.id),yield{type:"tool_skipped",tool_call_id:_.toolCall.id,toolName:A,reason:L,sessionId:$.sessionId},yield{type:"tool_result",tool_call_id:_.toolCall.id,result:_.result,isError:!0,sessionId:$.sessionId},this.options.addToolResultToHistory($,_),$.pendingToolCalls.splice(q,1),q--,await this.options.saveCheckpoint($,{phase:"tool_execution",status:`Tool disabled: ${A}`,modelConfig:Q?.checkpointModelConfig,requestParams:Q?.requestParams});continue}if(O&&G(T)){let L=X[_.toolCall.id];if(!L){this._log(`Tool approval required: ${A} (risk: ${T})`),$.stopReason="approval_required";for(let b of U(q)){if(b.type==="tool_approval_requested")this._log(` - Requesting approval for: ${b.toolName}`);yield b}let y=await this.options.saveCheckpoint($,{phase:"approval_pending",status:`Waiting for approval: ${A}`,modelConfig:Q?.checkpointModelConfig,requestParams:Q?.requestParams});throw yield{type:"requires_action",kind:"tool_approval",checkpoint:R?void 0:y,checkpointRef:R?{sessionId:y.sessionId}:void 0,sessionId:$.sessionId},await this.options.persistSessionState($),yield{type:"done",finalResponse:$.currentResponse,stopReason:"approval_required",modelStopReason:$.lastModelStopReason,usage:{...$.usage},sessionId:$.sessionId},new S$}if(!L.approved){let y=L.reason??"User denied approval";this._log(`Tool approval REJECTED: ${A} - ${y}`),_.result=`Tool execution skipped: ${y}`,_.isError=!0,K(_.toolCall.id),yield{type:"tool_skipped",tool_call_id:_.toolCall.id,toolName:_.toolCall.function.name,reason:y,sessionId:$.sessionId},yield{type:"tool_result",tool_call_id:_.toolCall.id,result:_.result,isError:!0,sessionId:$.sessionId},this.options.addToolResultToHistory($,_),$.pendingToolCalls.splice(q,1),q--,await this.options.saveCheckpoint($,{phase:"tool_execution",status:`Tool approval rejected: ${A}`,modelConfig:Q?.checkpointModelConfig,requestParams:Q?.requestParams});continue}this._log(`Tool approval APPROVED: ${A}`)}K(_.toolCall.id),this._log(`Executing tool: ${A}`),this.toolEventQueue=[];let P=await this.executeToolCall(_,W,J,Q?.hooks,N);for(let L of this.toolEventQueue)yield L;if(this.toolEventQueue=[],P.type==="tool_result")if(P.isError||P.result&&typeof P.result==="object"&&P.result.isError===!0){let y=typeof P.result==="string"?P.result:JSON.stringify(P.result);this._log(`Tool execution ERROR: ${A} - ${y.slice(0,100)}`)}else{let y=typeof P.result==="string"?P.result.slice(0,100):JSON.stringify(P.result).slice(0,100);this._log(`Tool execution SUCCESS: ${A} - ${y}${y.length>=100?"...":""}`)}let v=P.type==="tool_result"&&(P.isError||P.result&&typeof P.result==="object"&&P.result.isError===!0);if(O&&O.name==="AskUserQuestion"&&v){let L=Y?.askUser?.rejected?.[_.toolCall.id];if(L!==void 0){let b=L||"User cancelled the question";this._log(`AskUser CANCELLED: ${b}`),_.result=`User cancelled the question: ${b}`,_.isError=!0,K(_.toolCall.id),yield{type:"tool_skipped",tool_call_id:_.toolCall.id,toolName:O.name,reason:b,sessionId:$.sessionId},yield{type:"tool_result",tool_call_id:_.toolCall.id,result:_.result,isError:!0,sessionId:$.sessionId},this.options.addToolResultToHistory($,_),$.pendingToolCalls.splice(q,1),q--,await this.options.saveCheckpoint($,{phase:"tool_execution",status:`AskUser cancelled: ${O.name}`,modelConfig:Q?.checkpointModelConfig,requestParams:Q?.requestParams});continue}let y=Y?.askUser?.answers?.[_.toolCall.id];if(!y){let u=(typeof _.toolCall.function.arguments==="string"?JSON.parse(_.toolCall.function.arguments):_.toolCall.function.arguments)?.questions||[];this._log(`AskUser waiting for answers (${u.length} questions)`),yield P,$.stopReason="approval_required";let g=await this.options.saveCheckpoint($,{phase:"approval_pending",status:`Waiting for user answers: ${O.name}`,modelConfig:Q?.checkpointModelConfig,requestParams:Q?.requestParams});throw await this.options.persistSessionState($),yield{type:"requires_action",kind:"ask_user",toolCallId:_.toolCall.id,questions:u,checkpoint:R?void 0:g,checkpointRef:R?{sessionId:g.sessionId}:void 0,sessionId:$.sessionId},yield{type:"done",finalResponse:$.currentResponse,stopReason:"approval_required",modelStopReason:$.lastModelStopReason,usage:{...$.usage},sessionId:$.sessionId},new S$}else{let u={...typeof _.toolCall.function.arguments==="string"?JSON.parse(_.toolCall.function.arguments):_.toolCall.function.arguments,answers:y};_.toolCall.function.arguments=JSON.stringify(u),this.toolEventQueue=[];let g=await this.executeToolCall(_,W,J,Q?.hooks,N);for(let c of this.toolEventQueue)yield c;this.toolEventQueue=[],yield g,this.options.addToolResultToHistory($,_),$.pendingToolCalls.splice(q,1),q--,await this.options.saveCheckpoint($,{phase:"tool_execution",status:_.isError?`AskUser error: ${O.name}`:`AskUser completed: ${O.name}`,modelConfig:Q?.checkpointModelConfig,requestParams:Q?.requestParams});continue}}yield P,this.options.addToolResultToHistory($,_),$.pendingToolCalls.splice(q,1),q--,await this.options.saveCheckpoint($,{phase:"tool_execution",status:_.isError?`Tool error: ${A}`:`Tool completed: ${A}`,modelConfig:Q?.checkpointModelConfig,requestParams:Q?.requestParams})}$.pendingToolCalls=[],$.iteration++,yield{type:"iteration_end",iteration:$.iteration-1,willContinue:!0,toolCallCount:Z,usage:{...$.usage},sessionId:$.sessionId}}}class I0{static APPROVAL_REQUIRED_LEVELS=new Set(["high","critical"]);requiresApproval($){return I0.APPROVAL_REQUIRED_LEVELS.has($)}shouldRequireApproval($,W){if($?.autoApprove===!0)return!1;if(($?.strategy??"high_risk")==="all")return!0;return this.requiresApproval(W)}}class Y1{saveHandler;onError;constructor($,W){this.saveHandler=$;this.onError=W}async trigger(){try{await this.saveHandler()}catch($){let W=$ instanceof Error?$:Error(String($));console.warn("[Session] Auto-save failed:",W.message),this.onError?.(W)}}}var c4=1000;function d4($){if(!$)return;if($ instanceof I)return{code:$.code,message:$.message,status:$.status,retryable:$.retryable};if($ instanceof Error){let W=$,Q=typeof W.code==="string"?W.code:void 0,Z=typeof W.status==="number"?W.status:void 0,J=typeof W.retryable==="boolean"?W.retryable:void 0;return{code:Q,message:$.message,status:Z,retryable:J}}return{message:String($)}}function a1($){let W=$?.function?.arguments;if(typeof W==="string")try{return JSON.parse(W),$}catch(Q){let Z=Q instanceof Error?Q.message:String(Q);return{...$,function:{...$.function,arguments:JSON.stringify({_raw:W,_parseError:Z})}}}if(W&&typeof W==="object")return{...$,function:{...$.function,arguments:JSON.stringify(W)}};return{...$,function:{...$.function,arguments:JSON.stringify(W??null)}}}function o1($){let W=!1,Q=$.map((Z)=>{if(!Z||typeof Z!=="object"||Z.role!=="assistant")return Z;let J=Z.tool_calls;if(!Array.isArray(J)||J.length===0)return Z;let Y=!1,H=J.map((X)=>{let G=a1(X);if(G!==X)Y=!0;return G});if(!Y)return Z;return W=!0,{...Z,tool_calls:H}});return W?Q:$}class e extends p4{id;createdAt;status;title;updatedAt;lastActiveAt;errorMessage;configOverride;metadata;messages;toolCallCount;usage;responseCount;avgResponseTime;_stateStore;_checkpointManager;_approvalHandler;_parallelTaskExecutor;_toolExecutor;_autoSave;_autoSaveManager;_modelClient;_tools;_middlewares;_systemPrompt;_agentName;_onUsage;_pendingInput=null;_isReceiving=!1;_hooks;_modelOverride;_modelVariantsOverride;_maxIterations;_requestParams;_emitSessionCreatedEvent;_sessionCreatedEventEmitted=!1;_abortController=null;_enableLogging;_checkpointOriginalMessages;_checkpointNewMessages=[];_checkpointSkipSnapshot;getDisabledToolNames(){let $=this.configOverride?.disabledTools;if(!$||$.length===0)return new Set;return new Set($)}isToolDisabled($){return this.getDisabledToolNames().has($)}collectBlockedTools($){let W=new Set;for(let Q of this._middlewares)if(typeof Q.__getBlockedTools==="function"){let Z=Q.__getBlockedTools($);(Array.isArray(Z)?Z:Array.from(Z)).forEach((Y)=>W.add(Y))}return W}isToolBlocked($,W){let Q=$.metadata?.blockedTools;if(!Q)return!1;if(Q instanceof Set)return Q.has(W);if(Array.isArray(Q))return Q.includes(W);return!1}getToolsForModel($){let W=this._tools?.toOpenAIFormat();if(!W||W.length===0)return;let Q=this.getDisabledToolNames(),Z=Q.size===0?W:W.filter((Y)=>!Q.has(Y.function.name)),J=$.metadata?.blockedTools;if(J&&J.size>0)Z=Z.filter((Y)=>!J.has(Y.function.name));return Z.length>0?Z:void 0}getEffectiveSystemPrompt(){let $=this.configOverride?.systemPromptOverride;if(typeof $==="string")return $;return this._systemPrompt}_log(...$){if(this._enableLogging){let W=this._agentName?`[GoatChain:Session:${this._agentName}:${this.id.slice(0,8)}]`:`[GoatChain:Session:${this.id.slice(0,8)}]`;console.warn(W,...$)}}constructor($,W,Q,Z){super();if(this._stateStore=$,this._checkpointManager=new e0($),this._approvalHandler=new I0,this.id=W,Q)this.createdAt=Q.createdAt,this.restoreFromSnapshot(Q);else{let J=Date.now();this.createdAt=J,this.status="active",this.updatedAt=J,this.lastActiveAt=J,this.messages=[],this.toolCallCount=0,this.metadata=void 0,this.usage={promptTokens:0,completionTokens:0,totalTokens:0},this.responseCount=0}this._autoSave=!0,this._autoSaveManager=new Y1(()=>this.save(),(J)=>{this.emit("auto-save-failed",{error:J})}),this._modelClient=Z?.modelClient,this._tools=Z?.tools,this._middlewares=Z?.middlewares??[],this._systemPrompt=Z?.systemPrompt,this._agentName=Z?.agentName,this._onUsage=Z?.onUsage,this._hooks=Z?.hooks,this._modelOverride=Z?.model,this._modelVariantsOverride=Z?.variants,this._maxIterations=Z?.maxIterations,this._requestParams=Z?.requestParams,this._emitSessionCreatedEvent=Z?.emitSessionCreatedEvent===!0,this._enableLogging=Z?.enableLogging??!1,this._parallelTaskExecutor=new Z1(this._tools,{hasAssistantToolCallMessage:(J,Y)=>this.hasAssistantToolCallMessage(J,Y),addAssistantMessageWithToolCalls:(J)=>this.addAssistantMessageWithToolCalls(J),addToolResultToHistory:(J,Y)=>this.addToolResultToHistory(J,Y)}),this._toolExecutor=new J1({tools:this._tools,approvalHandler:this._approvalHandler,checkpointManager:this._checkpointManager,saveCheckpoint:(J,Y)=>this.saveCheckpointForState(J,Y),parallelTaskExecutor:this._parallelTaskExecutor,isToolDisabled:(J)=>this.isToolDisabled(J),isToolBlocked:(J,Y)=>this.isToolBlocked(J,Y),addAssistantMessageWithToolCalls:(J)=>this.addAssistantMessageWithToolCalls(J),addToolResultToHistory:(J,Y)=>this.addToolResultToHistory(J,Y),persistSessionState:(J)=>this.persistSessionState(J),log:(...J)=>this._log(...J)})}async hasCheckpoint(){try{return await this._checkpointManager.loadCheckpoint(this.id)!=null}catch{return!1}}send($,W){if(this._ensureRuntimeConfigured(!0),this._isReceiving)throw Error("Cannot send while receiving messages");if(this._pendingInput)throw Error("Pending input already exists; call receive() to consume it before sending another message");let Q=typeof $==="string"?$:JSON.stringify($);this._log("send() called with input:",Q.slice(0,100)+(Q.length>100?"...":"")),this._pendingInput={input:$,options:W}}cancel(){if(this._abortController)this._abortController.abort("Session cancelled by user")}async*receive($){if(this._isReceiving)throw Error("Cannot receive concurrently");let W=await this._checkpointManager.loadCheckpoint(this.id).catch(()=>null),Q=W!=null;if(!Q&&!this._pendingInput)throw Error("Nothing to receive; call send() first (or resume from a session that has a checkpoint)");this._log(`receive() started, hasCheckpoint: ${Q}, hasPendingInput: ${!!this._pendingInput}`),this._abortController=new AbortController;let Z=this._abortController.signal;this._isReceiving=!0;try{if(this._emitSessionCreatedEvent&&!this._sessionCreatedEventEmitted)this._sessionCreatedEventEmitted=!0,yield{type:"session_created",sessionId:this.id};if(Q&&this._pendingInput){this._log("Resuming from checkpoint with new user message");let{input:J,options:Y}=this._pendingInput;this._pendingInput=null;let H=X0(W);if(H.sessionId!==this.id)H.sessionId=this.id;H.shouldContinue=!0,H.stopReason=void 0,H.metadata={...H.metadata,_pendingUserInput:J};let X=this._requestParams??W.requestParams,G=Y??$,V=this.buildAutoRejectToolContext(H,G?.toolContext),{model:K,variants:z}=this.getRuntimeModelRoute();if(!(yield*this._streamWithPauseDetection(H,{maxIterations:this._maxIterations,signal:Z,model:K,variants:z,toolContext:V,hooks:this._hooks,requestParams:X})))await this._finalizeRun(H,Date.now());return}if(Q){this._log("Resuming from checkpoint without new message");let J=X0(W);if(J.sessionId!==this.id)J.sessionId=this.id;let Y=this._requestParams??W.requestParams,H=this.buildAutoRejectToolContext(J,$?.toolContext),{model:X,variants:G}=this.getRuntimeModelRoute();if(!(yield*this._streamWithPauseDetection(J,{maxIterations:this._maxIterations,signal:Z,model:X,variants:G,toolContext:H,hooks:this._hooks,requestParams:Y})))await this._finalizeRun(J,Date.now());return}if(this._pendingInput){this._log("Starting new message flow");let{input:J,options:Y}=this._pendingInput;this._pendingInput=null,yield*this._stream(J,Y)}}catch(J){if(J instanceof N$){yield{type:"done",finalResponse:"",stopReason:"cancelled",usage:{promptTokens:0,completionTokens:0,totalTokens:0},sessionId:this.id};return}throw J}finally{this._isReceiving=!1,this._abortController=null}}async*receiveWithApprovals($,W){let Q=W?.toolContext,Z={...Q??{},approval:{...Q?.approval??{},decisions:{...Q?.approval?.decisions??{},...$}}};yield*this.receive({...W,toolContext:Z})}async*_stream($,W){this._ensureRuntimeConfigured(!0);let Q=Date.now(),{model:Z,variants:J}=this.getRuntimeModelRoute(),Y=this._abortController?.signal;if(!this.title&&this.messages.length===0){let V=this.extractTextFromContent($);if(V)this.title=this.createTitle(V)}let H=this.messages.filter((V)=>V.role!=="system");this._log(`Starting agent loop with ${H.length} existing messages`);let X=w0({sessionId:this.id,input:$,messages:H},this.getEffectiveSystemPrompt()??"");if(!(yield*this._streamWithPauseDetection(X,{maxIterations:this._maxIterations,signal:Y,model:Z,variants:J,toolContext:W?.toolContext,hooks:this._hooks,requestParams:this._requestParams})))await this._finalizeRun(X,Q)}async*_streamWithPauseDetection($,W){try{return yield*this._streamWithState($,W),!1}catch(Q){if(Q instanceof S$)return this.messages=$.messages.filter((Z)=>Z.role!=="system"),!0;throw Q}}resolveModelRef($){if($.provider)return{provider:$.provider,modelId:$.modelId};let W=this._modelClient?.modelRef?.provider;if(W)return{provider:W,modelId:$.modelId};return}buildAutoRejectToolContext($,W){if($.pendingToolCalls.length===0)return W??{};let Q={},Z={};for(let J of $.pendingToolCalls){let Y=J.toolCall.id,H=J.toolCall.function.name;if(!W?.approval?.decisions?.[Y])Q[Y]={approved:!1,reason:"Auto-rejected: session resumed without tool context"};if(H==="AskUserQuestion"&&!W?.askUser?.answers?.[Y])Z[Y]="Auto-rejected: session resumed without user answers"}if(Object.keys(Q).length===0&&Object.keys(Z).length===0)return W??{};return{...W,approval:{...W?.approval,decisions:{...W?.approval?.decisions,...Q}},askUser:{answers:W?.askUser?.answers??{},rejected:{...W?.askUser?.rejected,...Z}}}}getRuntimeModelRoute(){if(this.configOverride?.model){let $=this.resolveModelRef(this.configOverride.model);if($)return{model:$,variants:this._modelVariantsOverride}}return{model:this._modelOverride,variants:this._modelVariantsOverride}}_ensureRuntimeConfigured($){if(!this._modelClient)throw Error("Session is not configured with a model client");if($&&this.getEffectiveSystemPrompt()===void 0)throw Error("Session is not configured with a system prompt")}extractTextFromContent($){if(typeof $==="string")return $;if(Array.isArray($))return $.filter((W)=>W.type==="text").map((W)=>W.text).join(" ");if($&&typeof $==="object"&&$.type==="text")return $.text||"";return""}createTitle($,W=50){let Q=$.trim();if(Q.length<=W)return Q;return`${Q.substring(0,W).trim()}...`}_recordUsage($){if(this._onUsage)this._onUsage($)}async*executeModelStream($,W,Q,Z,J,Y){if(!this._modelClient)throw Error("Session is not configured with a model client");let H=$.sessionId,X=new Map,G=!1,V=!1,K=(N)=>{let A=X.get(N);if(A)return A;let O={argsText:"",started:!1};return X.set(N,O),O},z=[],j=(N,A)=>{let O=K(N);if(A&&!O.toolName)O.toolName=A;if(!O.started)O.started=!0,this._log(`Stream: tool_call_start - ${O.toolName} (${N.slice(0,8)})`),z.push({type:"tool_call_start",callId:N,toolName:O.toolName,sessionId:H})},B=(N,A,O)=>{let T=K(N);if(A&&!T.toolName)T.toolName=A;if(typeof O==="string"&&O.length>0)T.argsText+=O;j(N,T.toolName),z.push({type:"tool_call_delta",callId:N,toolName:T.toolName,argsTextDelta:O,sessionId:H})},U=()=>{if(G)return;G=!0,this._log("Stream: text_start"),z.push({type:"text_start",sessionId:H})},F=()=>{if(!G||V)return;V=!0;let N=$.currentResponse.slice(0,50)+($.currentResponse.length>50?"...":"");this._log(`Stream: text_end - "${N}"`),z.push({type:"text_end",content:$.currentResponse,sessionId:H})},R=()=>{for(let[N,A]of X){if(!A.toolName)continue;let O={id:N,type:"function",function:{name:A.toolName,arguments:A.argsText}};if(this._tools){$.pendingToolCalls.push({toolCall:O});let T=A.argsText.slice(0,100)+(A.argsText.length>100?"...":"");this._log(`Stream: tool_call_end - ${A.toolName} with args: ${T}`)}z.push({type:"tool_call_end",toolCall:O,sessionId:H})}X.clear()},q=(()=>{if(!Y)return;let N={...Y};if(typeof N.maxOutputTokens!=="number"&&typeof Y.maxTokens==="number")N.maxOutputTokens=Y.maxTokens;return delete N.maxTokens,N})(),_=Array.isArray(J)&&J.length>0?{variants:J}:void 0,D=Z?{model:Z,..._??{},messages:o1($.messages),tools:Q,signal:W,...q??{}}:{..._??{},messages:o1($.messages),tools:Q,signal:W,...q??{}};try{for await(let N of this._modelClient.stream(D)){if(U$(W,"Session streaming"),N.type==="delta"){if(N.chunk.kind==="text")U(),$.currentResponse+=N.chunk.text,z.push({type:"text_delta",delta:N.chunk.text,sessionId:H});else if(N.chunk.kind==="thinking_start")this._log("Stream: thinking_start"),z.push({type:"thinking_start",sessionId:H});else if(N.chunk.kind==="thinking_delta")$.currentThinking=($.currentThinking??"")+N.chunk.text,z.push({type:"thinking_delta",delta:N.chunk.text,sessionId:H});else if(N.chunk.kind==="thinking_end"){let A=typeof N.chunk.text==="string"?N.chunk.text:"";if(A&&typeof $.currentThinking!=="string")$.currentThinking=A;let O=typeof $.currentThinking==="string"?$.currentThinking:A,T=O?O.slice(0,50)+(O.length>50?"...":""):"";this._log(`Stream: thinking_end - "${T}"`),z.push({type:"thinking_end",sessionId:H,...O?{content:O}:{}})}else if(N.chunk.kind==="tool_call_delta")B(N.chunk.callId,N.chunk.toolId,N.chunk.argsTextDelta)}else if(N.type==="response_end"){this._log(`Stream: response_end - stopReason: ${N.stopReason}`),F(),R(),$.lastModelStopReason=N.stopReason;let A=N.usage;if(A&&typeof A==="object"){let O=A;if(O.prompt_tokens||O.completion_tokens||O.total_tokens){let T={promptTokens:O.prompt_tokens??0,completionTokens:O.completion_tokens??0,totalTokens:O.total_tokens??0};$.usage.promptTokens=T.promptTokens,$.usage.completionTokens=T.completionTokens,$.usage.totalTokens+=T.totalTokens,this._recordUsage(T)}}}else if(N.type==="error"){if(N.terminal!==!1){let A=N.error?.code??"model_error",O=N.error?.message??"Model error",T=new I(O,{code:A,retryable:N.error?.retryable});$.error=T,$.shouldContinue=!1,$.stopReason="error"}}while(z.length>0)yield z.shift()}}catch(N){if(N instanceof N$)throw N;if(W?.aborted)throw new N$(typeof W?.reason==="string"?W.reason:"Agent execution aborted");$.error=N instanceof Error?N:Error(String(N)),$.shouldContinue=!1,$.stopReason="error"}finally{if(F(),X.size>0)R();while(z.length>0)yield z.shift()}}mergeStateResults($,W){if($.currentResponse=W.currentResponse,$.currentThinking=W.currentThinking,$.pendingToolCalls=W.pendingToolCalls,$.usage=W.usage,$.metadata=W.metadata,$.shouldContinue=W.shouldContinue,$.stopReason=W.stopReason,$.lastModelStopReason=W.lastModelStopReason,$.error=W.error,this._checkpointSkipSnapshot=W._skipMessageSnapshot,this._checkpointOriginalMessages&&!this._checkpointSkipSnapshot){let Q=this._checkpointOriginalMessages;$.messages=[...Q,...this._checkpointNewMessages]}else $.messages=W.messages}appendMessage($,W){if($.messages.push(W),this._checkpointOriginalMessages&&!this._checkpointSkipSnapshot)this._checkpointNewMessages.push(W)}getCheckpointMessages($){if(this._checkpointSkipSnapshot||!this._checkpointOriginalMessages)return $.messages;return[...this._checkpointOriginalMessages,...this._checkpointNewMessages]}async saveCheckpointForState($,W){let Q=S0($,{agentName:this._agentName,phase:W?.phase,status:W?.status,modelConfig:W?.modelConfig,requestParams:W?.requestParams,messages:this.getCheckpointMessages($)});return await this._checkpointManager.saveCheckpoint(Q),Q}addToolResultToHistory($,W){let Q=W.result,Z,J=W.isError;if(typeof Q==="string")Z=Q;else if(Q&&typeof Q==="object"&&"content"in Q){let Y=Q;if(Z=JSON.stringify(Y.content),Y.isError===!0)J=!0}else Z=JSON.stringify(Q);this.appendMessage($,{role:"tool",tool_call_id:W.toolCall.id,content:Z,...J?{isError:!0}:{}})}addAssistantMessageWithToolCalls($){let W=typeof $.currentThinking==="string"?$.currentThinking:void 0;this.appendMessage($,{role:"assistant",content:$.currentResponse||"",tool_calls:$.pendingToolCalls.map((Q)=>a1(Q.toolCall)),...W&&W.length>0?{reasoning_content:W}:{}})}addFinalAssistantMessage($){if($.currentResponse){let W=typeof $.currentThinking==="string"?$.currentThinking:void 0;this.appendMessage($,{role:"assistant",content:$.currentResponse,...W&&W.length>0?{reasoning_content:W}:{}})}}async persistSessionState($){this.messages=$.messages.filter((W)=>W.role!=="system"),await this.save()}async*_streamWithState($,W){let Q=W.maxIterations??c4,Z=W.signal,J=x0(this._middlewares),Y=this._toolExecutor.createToolExecutionContext($,Z),H=this._stateStore,X=H?.deleteOnComplete??!0,G=W.model?{modelId:W.model.modelId,provider:W.model.provider,...Array.isArray(W.variants)&&W.variants.length>0?{variants:W.variants.map((K)=>({provider:K.provider,modelId:K.modelId}))}:{}}:this._modelClient?{modelId:this._modelClient.modelId}:void 0,V=async(K)=>{if(!H)return;await this.saveCheckpointForState($,{phase:K?.phase,status:K?.status,modelConfig:G,requestParams:W.requestParams})};while($.shouldContinue){if(U$(Z,`Session iteration ${$.iteration}`),$.iteration>=Q){this._log(`Max iterations (${Q}) reached`),$.shouldContinue=!1,$.stopReason="max_iterations",yield{type:"done",finalResponse:$.currentResponse,stopReason:"max_iterations",modelStopReason:$.lastModelStopReason,usage:{...$.usage},sessionId:$.sessionId};break}if(this._log(`Iteration ${$.iteration} started, pending tool calls: ${$.pendingToolCalls.length}`),yield{type:"iteration_start",iteration:$.iteration,sessionId:$.sessionId},this._checkpointOriginalMessages=structuredClone($.messages),this._checkpointNewMessages=[],this._checkpointSkipSnapshot=$._skipMessageSnapshot,$.pendingToolCalls.length>0){if(this._log(`Executing ${$.pendingToolCalls.length} tool calls`),yield*this._toolExecutor.handleToolCalls($,Y,{signal:Z,toolContextInput:W.toolContext,hooks:W.hooks,checkpointModelConfig:G,requestParams:W.requestParams}),$.metadata?._pendingUserInput){let B=$.metadata._pendingUserInput;delete $.metadata._pendingUserInput,this.appendMessage($,{role:"user",content:B})}continue}if($.metadata?._pendingUserInput){let B=$.metadata._pendingUserInput;delete $.metadata._pendingUserInput,this.appendMessage($,{role:"user",content:B})}$.currentResponse="",$.currentThinking=void 0,$.pendingToolCalls=[],$.lastModelStopReason=void 0,await V();let K=await J({...$,messages:structuredClone($.messages)},async(B)=>{U$(Z,"Session model call");let U=this.collectBlockedTools(B);return B.metadata.blockedTools=U,B}),z=this.getToolsForModel(K),j=z?.length??0;this._log(`Calling model with ${K.messages.length} messages and ${j} tools`);for await(let B of this.executeModelStream(K,Z,z,W.model,W.variants,W.requestParams))yield B;if(this._log(`Model response: ${K.currentResponse.slice(0,100)}${K.currentResponse.length>100?"...":""}, tool calls: ${K.pendingToolCalls.length}`),this.mergeStateResults($,K),U$(Z,`Session iteration ${$.iteration}`),$.stopReason==="error"){yield{type:"iteration_end",iteration:$.iteration,willContinue:!1,toolCallCount:$.pendingToolCalls.length,usage:{...$.usage},sessionId:$.sessionId},yield{type:"done",finalResponse:$.currentResponse,stopReason:"error",modelStopReason:$.lastModelStopReason,error:d4($.error),usage:{...$.usage},sessionId:$.sessionId};break}if($.pendingToolCalls.length>0)yield*this._toolExecutor.handleToolCalls($,Y,{signal:Z,toolContextInput:W.toolContext,hooks:W.hooks,checkpointModelConfig:G,requestParams:W.requestParams});else yield*this.handleFinalResponse($);if(await V(),!$.shouldContinue){if(this._log(`Agent loop finished. Stop reason: ${$.stopReason}`),H&&X)await H.deleteCheckpoint($.sessionId);break}}}hasAssistantToolCallMessage($,W){return $.messages.some((Q)=>{if(!Q||typeof Q!=="object"||Q.role!=="assistant")return!1;let Z=Q.tool_calls;return Array.isArray(Z)&&Z.some((J)=>J?.id===W)})}async*handleFinalResponse($){$.shouldContinue=!1,$.stopReason="final_response",this.addFinalAssistantMessage($),yield{type:"iteration_end",iteration:$.iteration,willContinue:!1,toolCallCount:0,usage:{...$.usage},sessionId:$.sessionId},yield{type:"done",finalResponse:$.currentResponse,stopReason:"final_response",modelStopReason:$.lastModelStopReason,usage:{...$.usage},sessionId:$.sessionId}}async _finalizeRun($,W){if(this.messages=$.messages.filter((Z)=>Z.role!=="system"),$.usage.totalTokens>0)this.addUsage($.usage);let Q=Date.now()-W;this.recordResponse(Q),await this.save()}getLastMessagePreview($=100){if(this.messages.length===0)return;let W=this.messages[this.messages.length-1],Q=typeof W.content==="string"?W.content:JSON.stringify(W.content);return Q.length>$?`${Q.substring(0,$)}...`:Q}toSnapshot(){let $={status:this.status,updatedAt:this.updatedAt,lastActiveAt:this.lastActiveAt,title:this.title,errorMessage:this.errorMessage},W={messages:[...this.messages],messageCount:this.messages.length,lastMessagePreview:this.getLastMessagePreview(),toolCallCount:this.toolCallCount},Q={usage:{...this.usage},responseCount:this.responseCount,avgResponseTime:this.avgResponseTime};return{id:this.id,createdAt:this.createdAt,state:$,configOverride:this.configOverride?{...this.configOverride}:void 0,context:W,stats:Q,metadata:this.metadata?{...this.metadata}:void 0}}restoreFromSnapshot($){this.status=$.state.status,this.updatedAt=$.state.updatedAt,this.lastActiveAt=$.state.lastActiveAt,this.title=$.state.title,this.errorMessage=$.state.errorMessage,this.configOverride=$.configOverride?{...$.configOverride}:void 0,this.metadata=$.metadata&&typeof $.metadata==="object"?{...$.metadata}:void 0,this.messages=[...$.context.messages],this.toolCallCount=$.context.toolCallCount,this.usage={...$.stats.usage},this.responseCount=$.stats.responseCount,this.avgResponseTime=$.stats.avgResponseTime}async save(){let $=this.toSnapshot();await this._stateStore.save(this.id,n.SESSION,$)}async load(){let $=await this._stateStore.load(this.id,n.SESSION);if($)return this.restoreFromSnapshot($),!0;return!1}triggerAutoSave(){this._autoSaveManager.trigger()}setStatus($,W){if(this.status=$,this.errorMessage=W,this.updatedAt=Date.now(),this._autoSave)this.triggerAutoSave()}markActive(){if(this.lastActiveAt=Date.now(),this.updatedAt=Date.now(),this._autoSave)this.triggerAutoSave()}addMessage($){if(this.messages.push($),this.markActive(),this._autoSave)this.triggerAutoSave()}addUsage($){if(this.usage.promptTokens=$.promptTokens,this.usage.completionTokens=$.completionTokens,this.usage.totalTokens+=$.totalTokens,this.updatedAt=Date.now(),this._autoSave)this.triggerAutoSave()}recordResponse($){let W=(this.avgResponseTime??0)*this.responseCount;if(this.responseCount++,this.avgResponseTime=(W+$)/this.responseCount,this.updatedAt=Date.now(),this._autoSave)this.triggerAutoSave()}incrementToolCallCount(){if(this.toolCallCount++,this.updatedAt=Date.now(),this._autoSave)this.triggerAutoSave()}setModelOverride($){if(!this.configOverride)this.configOverride={};if(this.configOverride.model=$,this.updatedAt=Date.now(),this._modelOverride=this.resolveModelRef($)??this._modelOverride,this._autoSave)this.triggerAutoSave()}clearModelOverride(){if(this.configOverride)delete this.configOverride.model,this.updatedAt=Date.now();if(this._modelOverride=void 0,this._autoSave)this.triggerAutoSave()}setSystemPromptOverride($){if(!this.configOverride)this.configOverride={};if(this.configOverride.systemPromptOverride=$,this.updatedAt=Date.now(),this._autoSave)this.triggerAutoSave()}clearSystemPromptOverride(){if(this.configOverride)delete this.configOverride.systemPromptOverride,this.updatedAt=Date.now();if(this._autoSave)this.triggerAutoSave()}disableTools($){if(!this.configOverride)this.configOverride={};if(this.configOverride.disabledTools=[...this.configOverride.disabledTools??[],...$],this.updatedAt=Date.now(),this._autoSave)this.triggerAutoSave()}enableAllTools(){if(this.configOverride)delete this.configOverride.disabledTools,this.updatedAt=Date.now();if(this._autoSave)this.triggerAutoSave()}setAutoSave($){this._autoSave=$}}class V0{}import{randomUUID as l4}from"node:crypto";class v0 extends V0{_stateStore;constructor($){super();this._stateStore=$}async create($){let W=$??l4(),Q=Date.now(),Z=(()=>{try{let H=globalThis?.process;return typeof H?.cwd==="function"?String(H.cwd()):void 0}catch{return}})(),J={id:W,createdAt:Q,state:{status:"active",updatedAt:Q,lastActiveAt:Q},context:{messages:[],messageCount:0,toolCallCount:0},stats:{usage:{promptTokens:0,completionTokens:0,totalTokens:0},responseCount:0},metadata:Z?{cwd:Z}:void 0},Y=new e(this._stateStore,W,J);return await Y.save(),Y}async get($){let W=await this._stateStore.load($,n.SESSION);if(!W)return;return new e(this._stateStore,$,W)}async list(){let $=await this._stateStore.listSessions(),W=[];for(let Q of $){let Z=await this._stateStore.load(Q,n.SESSION);if(Z){let J=new e(this._stateStore,Q,Z);W.push(J)}}return W}async destroy($){await this._stateStore.deleteSession($)}}import{existsSync as y$,mkdirSync as s1,rmSync as i4}from"node:fs";import{mkdir as r4,readdir as H1,readFile as n4,rm as t1,writeFile as o4}from"node:fs/promises";import C$ from"node:path";class b${deleteOnComplete;constructor($){this.deleteOnComplete=$?.deleteOnComplete??!0}assertValidStorageSegment($,W){if(!W)throw Error(`${$} must be a non-empty string`);if(W==="."||W==="..")throw Error(`${$} must not be "." or ".."`);if(W.includes("/")||W.includes("\\"))throw Error(`${$} must not contain path separators`);if(W.includes("\x00"))throw Error(`${$} must not contain NUL bytes`)}async save($,W,Q){let Z=this.buildPath($,W),J=JSON.stringify(Q,null,2);await this._write(Z,J)}async load($,W){let Q=this.buildPath($,W),Z=await this._read(Q);if(Z===void 0)return;try{return JSON.parse(Z)}catch{return}}async delete($,W){let Q=this.buildPath($,W);await this._delete(Q)}async deleteSession($){let W=this.buildPrefix($),Q=await this._list(W);await Promise.all(Q.map((Z)=>this._delete(Z)))}async listKeys($){let W=this.buildPrefix($);return(await this._list(W)).map((Z)=>this.extractKey($,Z))}async exists($,W){let Q=this.buildPath($,W);return this._exists(Q)}async saveCheckpoint($){let W={_meta:{description:"GoatChain Agent Loop Checkpoint - DO NOT EDIT MANUALLY",savedAt:new Date().toISOString(),agentName:$.agentName,sessionId:$.sessionId,iteration:$.iteration,phase:$.phase,status:$.status,messageCount:$.messages.length,toolCallsPending:$.pendingToolCalls?.length??0},checkpoint:$};await this.save($.sessionId,n.CHECKPOINT,W)}async loadCheckpoint($){return(await this.load($,n.CHECKPOINT))?.checkpoint}async deleteCheckpoint($){await this.delete($,n.CHECKPOINT)}async listCheckpoints(){let $=await this.listSessions(),W=[];for(let Q of $){let Z=await this.loadCheckpoint(Q);if(Z)W.push(Z)}return W}async listSessions(){let $=await this._list(""),W=new Set;for(let Q of $){let Z=this.extractSessionId(Q);if(Z)W.add(Z)}return Array.from(W)}buildPath($,W){return this.assertValidStorageSegment("sessionId",$),this.assertValidStorageSegment("key",W),`${$}/${W}`}buildPrefix($){return this.assertValidStorageSegment("sessionId",$),`${$}/`}extractKey($,W){let Q=this.buildPrefix($);return W.startsWith(Q)?W.slice(Q.length):W}extractSessionId($){let W=$.split("/");return W.length>0?W[0]:void 0}}class G0 extends b${baseDir;writeQueues=new Map;pendingWrites=new Map;constructor($){super($);this.baseDir=C$.resolve($.dir),this.ensureDir(this.baseDir)}async _write($,W){let Q=this.toFilePath($);this.pendingWrites.set(Q,W);let Z=this.writeQueues.get(Q);if(Z){await Z;return}let J=(async()=>{while(this.pendingWrites.has(Q)){let Y=this.pendingWrites.get(Q);this.pendingWrites.delete(Q);let H=C$.dirname(Q);await this.ensureDirAsync(H),await o4(Q,Y,"utf-8")}})();this.writeQueues.set(Q,J);try{await J}finally{if(this.writeQueues.get(Q)===J)this.writeQueues.delete(Q)}}async _read($){let W=this.toFilePath($);try{return await n4(W,"utf-8")}catch{return}}async _delete($){let W=this.toFilePath($);await t1(W,{force:!0});let Q=C$.dirname(W);if(y$(Q))try{if((await H1(Q)).length===0)await t1(Q,{recursive:!0,force:!0})}catch{}}async _exists($){let W=this.toFilePath($);return y$(W)}async _list($){let W=[];if(!y$(this.baseDir))return W;let Q=(await H1(this.baseDir,{withFileTypes:!0})).filter((Z)=>Z.isDirectory()).map((Z)=>Z.name);for(let Z of Q){if($&&!Z.startsWith($.split("/")[0]))continue;let J=C$.join(this.baseDir,Z),Y=await this.listJsonFiles(J);for(let H of Y){let X=C$.basename(H,".json"),G=`${Z}/${X}`;if(!$||G.startsWith($))W.push(G)}}return W}toFilePath($){return C$.join(this.baseDir,`${$}.json`)}ensureDir($){if(!y$($))s1($,{recursive:!0})}async ensureDirAsync($){if(y$($))return;await r4($,{recursive:!0})}async listJsonFiles($){if(!y$($))return[];return(await H1($)).filter((Q)=>Q.endsWith(".json")).map((Q)=>C$.join($,Q))}getBaseDir(){return this.baseDir}clear(){if(y$(this.baseDir))i4(this.baseDir,{recursive:!0}),s1(this.baseDir,{recursive:!0})}}class K0 extends b${store=new Map;constructor($){super($)}async _write($,W){this.store.set($,W)}async _read($){return this.store.get($)}async _delete($){this.store.delete($)}async _exists($){return this.store.has($)}async _list($){let W=[];for(let Q of this.store.keys())if($===""||Q.startsWith($))W.push(Q);return W}clear(){this.store.clear()}stats(){let $=new Set;for(let W of this.store.keys()){let Q=this.extractSessionId(W);if(Q)$.add(Q)}return{entryCount:this.store.size,sessionCount:$.size}}}class R${id;name;systemPrompt;createdAt;_model;_modelOverride;_tools;_stateStore;_sessionManager;_middlewares=[];_middlewareCounter=0;_middlewareTools=new Map;_enableLogging;_initializationPromise=null;_initialized=!1;constructor($){this.id=$.id??crypto.randomUUID(),this.name=$.name,this.systemPrompt=$.systemPrompt,this.createdAt=Date.now(),this._model=$.model,this._tools=$.tools,this._stateStore=$.stateStore??new K0,this._enableLogging=$.enableLogging??!1,this._sessionManager=new v0(this._stateStore),this._log(`Agent created: ${this.name} (id: ${this.id})`);let W=$.middleware??[];if(W.length>0)this._initializationPromise=this._initializeMiddleware(W)}async _initializeMiddleware($){for(let W of $)await this.use(W);this._initialized=!0}async _ensureInitialized(){if(this._initializationPromise&&!this._initialized)await this._initializationPromise}_log(...$){if(this._enableLogging)console.warn(`[GoatChain:Agent:${this.name}]`,...$)}get model(){return this._model}get modelId(){return this.modelRef?.modelId??this._model.modelId}get modelRef(){return this._modelOverride??this._model.modelRef}get tools(){return this._tools}get stateStore(){return this._stateStore}get sessionManager(){return this._sessionManager}async createSession($){if(await this._ensureInitialized(),!this._sessionManager)throw Error("SessionManager is not configured");let W=await this._sessionManager.create($?.sessionId);if(!this._stateStore)throw Error("StateStore is required to create sessions");this._log(`Creating new session: ${W.id}`);let Q=W.toSnapshot();return new e(this._stateStore,W.id,Q,{...$,modelClient:this._model,systemPrompt:this.systemPrompt,agentName:this.name,tools:this._tools,middlewares:this._middlewares.map((Z)=>Z.fn),emitSessionCreatedEvent:!0,enableLogging:this._enableLogging})}async resumeSession($,W){if(!this._sessionManager)throw Error("SessionManager is not configured");await this._ensureInitialized();let Q=await this._sessionManager.get($);if(!Q)throw Error(`Session not found: ${$}`);if(!this._stateStore)throw Error("StateStore is required to resume sessions");this._log(`Resuming session: ${$}`);let Z=Q.toSnapshot();return new e(this._stateStore,Q.id,Z,{...W,modelClient:this._model,systemPrompt:this.systemPrompt,agentName:this.name,tools:this._tools,middlewares:this._middlewares.map((J)=>J.fn),emitSessionCreatedEvent:!1,enableLogging:this._enableLogging})}async use($,W){let Q=W??$.__middlewareName??`middleware_${this._middlewareCounter++}`;if(this._middlewares.some((J)=>J.name===Q))throw Error(`Middleware with name "${Q}" already exists`);let Z={name:Q,fn:$};if(this._middlewares.push(Z),this._log(`Middleware registered: ${Q}`),$.__createTools&&typeof $.__createTools==="function")await this._registerMiddlewareTools(Q,$.__createTools);return()=>{this.removeMiddleware(Q)}}removeMiddleware($){let W=-1,Q;if(typeof $==="string")W=this._middlewares.findIndex((Z)=>Z.name===$),Q=$;else if(W=this._middlewares.findIndex((Z)=>Z.fn===$),W>-1)Q=this._middlewares[W].name;if(W>-1&&Q)return this._unregisterMiddlewareTools(Q),this._middlewares.splice(W,1),!0;return!1}clearMiddlewares(){for(let $ of this._middlewareTools.keys())this._unregisterMiddlewareTools($);this._middlewares=[]}get middlewares(){return[...this._middlewares]}get middlewareNames(){return this._middlewares.map(($)=>$.name)}setModel($){if(((Q)=>{return Boolean(Q&&typeof Q==="object"&&typeof Q.provider==="string"&&typeof Q.modelId==="string"&&typeof Q.stream!=="function")})($))this._modelOverride=$;else this._model=$,this._modelOverride=void 0}_getNamespacedToolName($,W){return`${$}_${W}`}async _registerMiddlewareTools($,W){if(!this._tools)return;let Q=await W(),Z=[];for(let J of Q){let Y=this._getNamespacedToolName($,J.name),H=Object.create(Object.getPrototypeOf(J));Object.assign(H,J),Object.defineProperty(H,"name",{value:Y,writable:!1,configurable:!0});try{this._tools.register(H),Z.push(Y)}catch(X){console.warn(`Failed to register tool ${Y}:`,X)}}if(Z.length>0)this._middlewareTools.set($,Z)}_unregisterMiddlewareTools($){if(!this._tools)return;let W=this._middlewareTools.get($);if(!W)return;for(let Q of W)this._tools.unregister(Q);this._middlewareTools.delete($)}}import{execSync as p}from"node:child_process";import{unlinkSync as a4,writeFileSync as s4}from"node:fs";import{tmpdir as t4}from"node:os";import{join as e4}from"node:path";function X1($){try{return p("git rev-parse --git-dir",{cwd:$,stdio:"pipe"}),!0}catch{return!1}}function e1($){try{return p("git add --all",{cwd:$,encoding:"utf-8"}),p("git diff --staged --name-only",{cwd:$,encoding:"utf-8"}).trim().split(`
|
|
41
|
-
`).filter(Boolean)}catch
|
|
42
|
-
`).filter(Boolean).map((Q)=>{let Z=Q.split("\t"),J=Z[0].charAt(0);if(J==="R"||J==="C")return{file:Z[2],status:J,oldFile:Z[1]};return{file:Z[1],status:J}})}catch{return[]}}function
|
|
43
|
-
`).map((Z)=>Z.trim()).includes(W)}catch{return!1}}function
|
|
44
|
-
`);for(let J of Z){let Y=J.match(/^(?:UU|AA|DD|AU|UA|DU|UD)\s+(\S.*)$/);if(Y)Q.push(Y[1].trim())}return Q}catch{return[]}}function
|
|
39
|
+
`}async function t1($){let{sessionId:W,fullMessages:Q,model:Z,stateStore:J,summaryPrompt:Y,enableLogging:H=!1,logFilePath:X="compression-logs.jsonl"}=$,G=Date.now(),V=Q.length,K=Q.filter((q)=>q.role==="tool").length,z=Q.filter((q)=>q.role!=="system");if(H)r(X,{sessionId:W,event:"manual_compression_started",messageCount:V,toolOutputCount:K,messagesToSummarizeCount:z.length,timestamp:Date.now()});if(z.length===0){if(H)r(X,{sessionId:W,event:"manual_compression_skipped",reason:"no_messages_to_summarize",timestamp:Date.now()});return{summary:"",messageCount:V,toolOutputCount:K}}let j=await J.load(W,n.COMPRESSION),_=a1(z),B=await s1(_,Z,j?.summary,Y);if(!B){if(H)r(X,{sessionId:W,event:"manual_compression_failed",reason:"empty_summary_generated",timestamp:Date.now()});return{summary:"",messageCount:V,toolOutputCount:K}}let F=Date.now(),A=F-G,N=q$(Q),U={tokensBefore:N,tokensAfter:N,clearedToolOutputs:0,removedMessages:z.length,summaryGenerated:!0,timestamp:F},R={lastStats:U,history:[...j?.history??[],U],summary:B,updatedAt:F};if(await J.save(W,n.COMPRESSION,R),H)r(X,{sessionId:W,event:"manual_compression_completed",messageCount:V,toolOutputCount:K,summaryLength:B.length,tokensBefore:N,elapsedMs:A,timestamp:F});return{summary:B,messageCount:V,toolOutputCount:K}}function u4($){let W=-1;for(let Z=0;Z<$.length;Z++)if($[Z].role==="user"){W=Z;break}if(W===-1)return 0;let Q=-1;for(let Z=W+1;Z<$.length;Z++)if($[Z].role==="assistant"){Q=Z;break}if(Q===-1)return W+1;for(let Z=Q+1;Z<$.length;Z++)if($[Z].role==="user")return Z;return $.length}function m4($,W){if(W<=0)return $.length;let Q=0,Z=[];for(let Y=$.length-1;Y>=0;Y--)if($[Y].role==="user"){if(Q++,Z.unshift(Y),Q>=W)return Y}let J=6;return Math.max(0,$.length-J)}var p4=["planMode","planModeMiddleware","parallelMode","parallelSubagentMiddleware","blockedTools","commitProcessed","_pendingUserInput"];function P0($){let W={};for(let[Q,Z]of Object.entries($))if(!p4.includes(Q))W[Q]=Z;return W}function e1($){return{...$,metadata:P0($.metadata)}}var c4=1;function x0($,W){let Q=W?.phase;if(!Q)if(!$.shouldContinue)Q="completed";else if($.pendingToolCalls.length>0)Q="tool_execution";else Q="llm_call";let Z=W?.status;if(!Z)if(Q==="completed")Z=`Completed: ${$.stopReason??"unknown"}`;else if(Q==="tool_execution")Z=`Executing tools: ${$.pendingToolCalls.map((H)=>H.toolCall.function.name).join(", ")}`;else if(Q==="approval_pending")Z="Waiting for user approval";else Z=`Iteration ${$.iteration}: Calling LLM`;let J=W?.messages??$.messages;return{schemaVersion:c4,sessionId:$.sessionId,agentName:W?.agentName,iteration:$.iteration,phase:Q,status:Z,modelConfig:W?.modelConfig,requestParams:W?.requestParams,messages:[...J],pendingToolCalls:$.pendingToolCalls.map((Y)=>({toolCall:{...Y.toolCall},result:Y.result,isError:Y.isError})),currentResponse:$.currentResponse,currentThinking:$.currentThinking,shouldContinue:$.shouldContinue,stopReason:$.stopReason,lastModelStopReason:$.lastModelStopReason,usage:{...$.usage},metadata:P0($.metadata),savedAt:Date.now()}}function G0($){let W=$.schemaVersion??1;if(W!==1)throw Error(`Unsupported checkpoint schemaVersion: ${W}. Please migrate checkpoints or upgrade GoatChain.`);return{sessionId:$.sessionId,iteration:$.iteration,messages:[...$.messages],pendingToolCalls:$.pendingToolCalls.map((Q)=>({toolCall:{...Q.toolCall},result:Q.result,isError:Q.isError})),currentResponse:$.currentResponse,currentThinking:$.currentThinking,shouldContinue:$.shouldContinue,stopReason:$.stopReason,lastModelStopReason:$.lastModelStopReason,usage:{...$.usage},metadata:{...$.metadata}}}class W1{stateStore;constructor($){this.stateStore=$}hasStore(){return Boolean(this.stateStore)}async saveCheckpoint($){if(!this.stateStore)return;await this.stateStore.saveCheckpoint($)}async loadCheckpoint($){return this.stateStore?.loadCheckpoint($)}async clearCheckpoint($){if(!this.stateStore)return;await this.stateStore.deleteCheckpoint($)}}import{EventEmitter as s4}from"node:events";class N$ extends Error{constructor($="Agent execution aborted"){super($);this.name="AgentAbortError"}}class Q1 extends Error{iterations;constructor($,W){super(W??`Agent exceeded maximum iterations (${$})`);this.name="AgentMaxIterationsError",this.iterations=$}}class w$ extends Error{constructor($="Agent execution paused"){super($);this.name="AgentPauseError"}}function B$($,W){if(!$?.aborted)return;let Q=$?.reason;if(Q instanceof Error)throw Q;throw new N$(typeof Q==="string"?Q:W?`${W} aborted`:"Agent execution aborted")}function w0($){return(W,Q)=>{let Z=-1,J=async(Y,H)=>{if(Y<=Z)throw Error("next() called multiple times");if(Z=Y,Y===$.length)return Q?await Q(H):H;let X=$[Y];return X(H,(G)=>J(Y+1,G))};return J(0,W)}}function b0($,W){let Q=[{role:"system",content:W},...$.messages??[],{role:"user",content:$.input}];return{sessionId:$.sessionId??"",messages:Q,iteration:0,pendingToolCalls:[],currentResponse:"",shouldContinue:!0,usage:{promptTokens:0,completionTokens:0,totalTokens:0},metadata:{}}}class v extends Error{code;retryable;status;constructor($,W){super($);this.name="ModelError",this.code=W.code,this.retryable=W.retryable??!1,this.status=W.status}}class A${static isRetryableStatus($){return $===408||$===409||$===429||$>=500&&$<=599}static async sleep($,W){if($<=0)return Promise.resolve();return new Promise((Q,Z)=>{let J=setTimeout(()=>{Y(),Q()},$);function Y(){if(clearTimeout(J),W)W.removeEventListener("abort",H)}function H(){Y(),Z(Error("Aborted"))}if(W){if(W.aborted)return H();W.addEventListener("abort",H)}})}}function p$($="req"){let W=Math.random().toString(16).slice(2),Q=Date.now().toString(16);return`${$}_${Q}_${W}`}async function*$W($,W){let Q=new Map,Z=new Map;for await(let J of $){if(J.type==="response.created"){yield{type:"response_start",requestId:W,model:{provider:"codex",modelId:J.response.model}};continue}if(J.type==="response.output_item.added"){let Y=J;if(Y.item.type==="reasoning")yield{type:"delta",requestId:W,chunk:{kind:"thinking_start"}};else if(Y.item.type==="function_call"){let H=Y.item.call_id;Q.set(H,{toolId:Y.item.name,argsText:""}),Z.set(Y.output_index,H)}continue}if(J.type==="response.output_text.delta"){yield{type:"delta",requestId:W,chunk:{kind:"text",text:J.delta}};continue}if(J.type==="response.reasoning_summary_text.delta"){yield{type:"delta",requestId:W,chunk:{kind:"thinking_delta",text:J.delta}};continue}if(J.type==="response.function_call_arguments.delta"){let Y=J,H=Z.get(Y.output_index);if(H){let X=Q.get(H);if(X)X.argsText+=Y.delta,yield{type:"delta",requestId:W,chunk:{kind:"tool_call_delta",callId:H,toolId:X.toolId,argsTextDelta:Y.delta}}}continue}if(J.type==="response.output_item.done"){let Y=J;if(Y.item.type==="reasoning")yield{type:"delta",requestId:W,chunk:{kind:"thinking_end"}};else if(Y.item.type==="function_call"){let H=Y.item.call_id;if(Q.get(H))yield{type:"delta",requestId:W,chunk:{kind:"tool_call_delta",callId:H,toolId:Y.item.name,argsTextDelta:void 0}}}continue}if(J.type==="response.completed"){yield{type:"response_end",requestId:W,stopReason:"final",usage:J.response.usage};continue}if(J.type==="response.incomplete"){let Y=J,H=Y.response.incomplete_details?.reason,X="error";if(H==="max_tokens"||H==="max_output_tokens")X="length";else if(H==="tool_calls"||H==="function_call")X="tool_call";else if(H==="stop"||H==="end_turn")X="final";yield{type:"response_end",requestId:W,stopReason:X,usage:Y.response.usage};continue}if(J.type==="error"){let Y=J;yield{type:"error",requestId:W,terminal:!0,source:"adapter",error:{code:Y.code,message:Y.message,retryable:!1}};continue}}}function Z1($){try{let W=$.split(".");if(W.length!==3)throw new v("Invalid JWT token format",{code:"invalid_jwt_format",retryable:!1});let Q=W[1],Z=atob(Q.replace(/-/g,"+").replace(/_/g,"/")),J=JSON.parse(Z),Y=J["https://api.openai.com/auth"]?.chatgpt_account_id||J.chatgpt_account_id||J.organizations?.[0]?.id;if(!Y)throw new v("ChatGPT account ID not found in token",{code:"account_id_not_found",retryable:!1});return Y}catch(W){if(W instanceof v)throw W;throw new v("Failed to extract account ID from token",{code:"token_decode_error",retryable:!1})}}function d4($){let W=($.baseUrl||"https://chatgpt.com/backend-api").replace(/\/$/,"");async function Q(){let X=typeof $.accessToken==="function"?await $.accessToken():$.accessToken;if(!X||typeof X!=="string"||!X.trim())throw new v("Missing Codex access token",{code:"missing_access_token",retryable:!1});return X.trim()}async function Z(){if($.accountId){let X=typeof $.accountId==="function"?await $.accountId():$.accountId;if(!X||typeof X!=="string"||!X.trim())throw new v("Invalid ChatGPT account ID",{code:"invalid_account_id",retryable:!1});return X.trim()}try{let X=await Q();return Z1(X)}catch(X){if(X instanceof v)throw X;throw new v("Failed to extract account ID from token",{code:"account_id_extraction_failed",retryable:!1})}}async function J(){if(!$.codexInstructions)return"You are an AI coding assistant. Help the user with their coding tasks.";return(typeof $.codexInstructions==="function"?await $.codexInstructions():$.codexInstructions)||"You are an AI coding assistant. Help the user with their coding tasks."}function Y(X){let G=[];for(let V of X)if(V.role==="system")G.push({role:"developer",content:[{type:"input_text",text:typeof V.content==="string"?V.content:JSON.stringify(V.content)}]});else if(V.role==="user")G.push({role:"user",content:[{type:"input_text",text:typeof V.content==="string"?V.content:JSON.stringify(V.content)}]});else if(V.role==="assistant"){if(G.push({role:"assistant",content:[{type:"output_text",text:typeof V.content==="string"?V.content:JSON.stringify(V.content)}]}),V.tool_calls&&V.tool_calls.length>0)for(let K of V.tool_calls)G.push({type:"function_call",call_id:K.id,name:K.function.name,arguments:typeof K.function.arguments==="string"?K.function.arguments:JSON.stringify(K.function.arguments)})}else if(V.role==="tool")G.push({type:"function_call_output",call_id:V.tool_call_id,output:typeof V.content==="string"?V.content:JSON.stringify(V.content)});return G}async function*H(X){let{request:G}=X,V=G.requestId||p$("req");try{let K=[];if(G.instructions)K.push({role:"developer",content:[{type:"input_text",text:G.instructions}]});if(G.messages&&G.messages.length>0)K.push(...Y(G.messages));else if(G.input)K.push({role:"user",content:[{type:"input_text",text:G.input}]});let[z,j,_]=await Promise.all([Q(),Z(),J()]),B=i4(G.model.modelId),F={model:B,input:K,stream:!0,store:!1,instructions:_},A=G.reasoning?.effort||r4(B);if(F.reasoning={effort:A,summary:G.reasoning?.summary||"auto"},F.text={verbosity:"medium"},F.include=["reasoning.encrypted_content"],G.metadata)F.metadata=G.metadata;let N=G.metadata?.promptCacheKey;if(N)F.prompt_cache_key=N;if(G.tools&&G.tools.length>0)F.tools=G.tools.map((D)=>({type:"function",name:D.function.name,description:D.function.description,parameters:D.function.parameters}));let U={"Content-Type":"application/json",Authorization:`Bearer ${z}`,"chatgpt-account-id":j,"OpenAI-Beta":"responses=experimental",originator:"codex_cli_rs",accept:"text/event-stream"};if(N)U.conversation_id=N,U.session_id=N;let R=await fetch(`${W}/codex/responses`,{method:"POST",headers:U,body:JSON.stringify(F),signal:G.signal});if(!R.ok){let D=await R.text().catch(()=>"");throw new v(`Codex API error: ${R.status} ${D}`,{code:`codex_http_${R.status}`,retryable:A$.isRetryableStatus(R.status),status:R.status})}if(!R.body)throw new v("No response body",{code:"no_response_body",retryable:!1});let q=l4(R.body);yield*$W(q,V)}catch(K){if(K?.name==="AbortError")throw new v("Request aborted",{code:"aborted",retryable:!1});if(K instanceof v)throw K;throw new v(K?.message||"Unknown error",{code:K?.code||"unknown_error",retryable:!1})}}return{provider:"codex",defaultModelId:$.defaultModelId,stream:H}}async function*l4($){let W=$.getReader(),Q=new TextDecoder,Z="";try{while(!0){let{done:J,value:Y}=await W.read();if(J)break;Z+=Q.decode(Y,{stream:!0});let H=Z.split(`
|
|
40
|
+
`);Z=H.pop()||"";for(let X of H)if(X.startsWith("data: ")){let G=X.slice(6);if(G==="[DONE]")return;try{yield JSON.parse(G)}catch(V){continue}}}}finally{W.releaseLock()}}function i4($){if(!$)return"gpt-5.1";let Q=($.includes("/")?$.split("/").pop():$).toLowerCase();if(Q.includes("gpt-5.2-codex")||Q.includes("gpt 5.2 codex"))return"gpt-5.2-codex";if(Q.includes("gpt-5.2")||Q.includes("gpt 5.2"))return"gpt-5.2";if(Q.includes("gpt-5.1-codex-max")||Q.includes("gpt 5.1 codex max"))return"gpt-5.1-codex-max";if(Q.includes("gpt-5.1-codex-mini")||Q.includes("gpt 5.1 codex mini"))return"gpt-5.1-codex-mini";if(Q.includes("codex-mini-latest")||Q.includes("gpt-5-codex-mini")||Q.includes("gpt 5 codex mini"))return"codex-mini-latest";if(Q.includes("gpt-5.1-codex")||Q.includes("gpt 5.1 codex"))return"gpt-5.1-codex";if(Q.includes("gpt-5.1")||Q.includes("gpt 5.1"))return"gpt-5.1";if(Q.includes("codex"))return"gpt-5.1-codex";if(Q.includes("gpt-5")||Q.includes("gpt 5"))return"gpt-5.1";return"gpt-5.1"}function r4($){let W=$.toLowerCase();if(W.includes("codex-mini"))return"medium";if(W.includes("gpt-5.2-codex")||W.includes("codex-max"))return"high";if(W.includes("nano")||W.includes("mini"))return"low";return"medium"}class b${maxAttempts;baseDelayMs;maxDelayMs;strategy;jitter;multiplier;_previousDelay;constructor($={}){this.maxAttempts=$.maxAttempts??3,this.baseDelayMs=$.baseDelayMs??500,this.maxDelayMs=$.maxDelayMs??30000,this.strategy=$.strategy??"exponential",this.jitter=$.jitter??"equal",this.multiplier=$.multiplier??2,this._previousDelay=this.baseDelayMs}getDelay($){let W;switch(this.strategy){case"exponential":W=this.baseDelayMs*this.multiplier**($-1);break;case"linear":W=this.baseDelayMs*$;break;case"fixed":W=this.baseDelayMs;break}return W=Math.min(W,this.maxDelayMs),W=this.applyJitter(W),this._previousDelay=W,Math.floor(W)}applyJitter($){switch(this.jitter){case"full":return Math.random()*$;case"equal":return $/2+Math.random()*$/2;case"decorrelated":return Math.min(this.maxDelayMs,Math.random()*(this._previousDelay*3-this.baseDelayMs)+this.baseDelayMs);case"none":default:return $}}canRetry($){return $<this.maxAttempts}reset(){this._previousDelay=this.baseDelayMs}toString(){return`RetryPolicy(${this.strategy}, max=${this.maxAttempts}, base=${this.baseDelayMs}ms, cap=${this.maxDelayMs}ms, jitter=${this.jitter})`}static default=new b$;static aggressive=new b$({maxAttempts:5,baseDelayMs:1000,maxDelayMs:60000});static gentle=new b$({maxAttempts:3,baseDelayMs:2000,maxDelayMs:30000,jitter:"full"})}function y0($){let W=$.adapter;if(!W)throw new v("Missing adapter. Provide `adapter` option.",{code:"missing_adapter",retryable:!1});if(!W.defaultModelId)throw new v("Adapter must have a defaultModelId.",{code:"missing_model_id",retryable:!1});let Q={provider:W.provider,modelId:W.defaultModelId},Z=new b$({maxAttempts:$.retry?.maxAttempts??3,baseDelayMs:$.retry?.baseDelayMs??500,maxDelayMs:$.retry?.maxDelayMs??30000,strategy:$.retry?.strategy??"exponential",jitter:$.retry?.jitter??"equal"}),J=$.timeoutMs??1800000;async function*Y(X){let G=X.requestId||p$("req"),{model:V,variants:K,...z}=X,j=X.model??Q,_=(()=>{let D=[j,...Array.isArray(K)?K:[]],O=new Set,T=[];for(let S of D){if(!S||typeof S.provider!=="string"||typeof S.modelId!=="string")continue;let f=`${S.provider}:${S.modelId}`;if(O.has(f))continue;O.add(f),T.push(S)}return T.length>0?T:[j]})(),B=X.timeoutMs??J,F=new AbortController,A=X.signal,N=setTimeout(()=>F.abort(),B),U=()=>F.abort();if(A)if(A.aborted)F.abort();else A.addEventListener("abort",U);let R,q=0;try{let D=0;for(let O=0;O<_.length;O++){let T=_[O],S=!1;D=0;let f={...z,requestId:G,model:T,stream:X.stream??!0,signal:F.signal,timeoutMs:B};try{for(let L=1;L<=Z.maxAttempts;L++){D=L;try{for await(let y of W.stream({request:f})){if(y.type==="delta")S=!0;yield y}return}catch(y){let b=J1(y),u=b.retryable;if(S||!u||!Z.canRetry(L))throw b;let g=Z.getDelay(L);$.retry?.onRetry?.({attempt:L,maxAttempts:Z.maxAttempts,delayMs:g,error:{code:b.code,message:b.message,retryable:b.retryable},model:T,request:f}),await A$.sleep(g,F.signal)}}}catch(L){let y=J1(L);R=T,q=D||1;let b=O<_.length-1;if(!S&&b){yield{type:"error",requestId:G,terminal:!1,model:T,attempt:q,source:"client",error:{code:y.code,message:y.message,retryable:y.retryable}};continue}throw y}}}catch(D){let O=J1(D);throw yield{type:"error",requestId:G,terminal:!0,model:R??j,attempt:q||1,source:"client",error:{code:O.code,message:O.message,retryable:O.retryable}},O}finally{if(clearTimeout(N),A)A.removeEventListener("abort",U)}throw new v("Max retry attempts exceeded",{code:"max_retries_exceeded",retryable:!1})}async function H(X){let G="",V="",K="error",z,j,_=X.requestId||"",B=!1;for await(let F of Y({...X,stream:!0}))if(F.type==="response_start")B=!0,_=F.requestId,j=F.model,G="";else if(F.type==="delta"&&F.chunk.kind==="text")G+=F.chunk.text;else if(F.type==="response_end")V=G,K=F.stopReason,z=F.usage;else if(F.type==="error")K="error";if(!j)throw new v("Missing response_start from adapter",{code:"protocol_error",retryable:!1});return{requestId:_,model:j,text:B?V:G,stopReason:K,usage:z}}return{get modelId(){return Q.modelId},get modelRef(){return Q},setModelId(X){Q={provider:Q.provider,modelId:X}},stream:Y,run:H}}function J1($){if($ instanceof v)return $;if($&&typeof $==="object"){let W=typeof $.status==="number"?$.status:void 0,Q=typeof $.code==="string"?$.code:W?`http_${W}`:"unknown_error",Z=typeof $.message==="string"?$.message:"Unknown error",J=W?A$.isRetryableStatus(W):!1;return new v(Z,{code:Q,retryable:J,status:W})}return new v(String($||"Unknown error"),{code:"unknown_error",retryable:!1})}import WW from"openai";function n4($){function W(Q,Z){if(typeof Q!=="string")return"";let J=Q.trim();if(!J)return"";if(/^data:/i.test(J)||/^https?:\/\//i.test(J))return J;if(typeof Z==="string"&&Z.trim())return`data:${Z.trim()};base64,${J}`;return J}if(typeof $==="string")return $.trim().length===0?"":$;if($===null||$===void 0)return"";if(typeof $==="object"&&"type"in $){let Q=$;if(Q.type==="text"&&Q.text)return Q.text;if(Q.type==="image"){let Z=W(Q.data??Q.source?.data,Q.mimeType??Q.source?.media_type??Q.source?.mimeType);if(!Z)return"";return[{type:"image_url",image_url:{url:Z}}]}}if(Array.isArray($)){let Q=[];for(let Z of $)if(typeof Z==="string")Q.push({type:"text",text:Z});else if(Z&&typeof Z==="object"&&"type"in Z){let J=Z;if(J.type==="text"&&J.text)Q.push({type:"text",text:J.text});else if(J.type==="image"){let Y=W(J.data??J.source?.data,J.mimeType??J.source?.media_type??J.source?.mimeType);if(Y)Q.push({type:"image_url",image_url:{url:Y}})}}return Q.length>0?Q:""}return String($)}function o4($){return{...$,content:n4($.content)}}function a4($,W){if(typeof W==="string"&&/deepseek/i.test(W))return!0;return/^deepseek-/i.test($)}function C0($={}){let W=$.baseUrl;function Q(){if(typeof $.apiKey==="function"){let V=$.apiKey();if(typeof V==="string"){let K=V.trim();if(!K)throw new v("Missing apiKey",{code:"missing_api_key",retryable:!1});return K}if(V!=null)throw new v("Invalid apiKey provider",{code:"invalid_api_key",retryable:!1})}if(typeof $.apiKey==="string"){let V=$.apiKey.trim();if(!V)throw new v("Missing apiKey",{code:"missing_api_key",retryable:!1});return V}let G=typeof process<"u"?process.env?.OPENAI_API_KEY:void 0;if(typeof G!=="string"||!G.trim())throw new v("Missing OPENAI_API_KEY",{code:"missing_api_key",retryable:!1});return G.trim()}function Z(){if(!(typeof globalThis.window<"u"))return!1;let V=typeof process<"u"&&!!process?.versions?.node,K=typeof globalThis.Bun<"u"||typeof process<"u"&&!!process?.versions?.bun;return V||K}function J(){let G=Q(),V=Z();if(typeof W==="string"&&/\/chat\/completions\/?$/.test(W))return new WW({apiKey:G,dangerouslyAllowBrowser:V,organization:$.organization,project:$.project,baseURL:"https://api.openai.com/v1",fetch:(z,j)=>{return fetch(W,j)}});return new WW({apiKey:G,dangerouslyAllowBrowser:V,organization:$.organization,project:$.project,baseURL:W||void 0})}function Y(G){return{provider:"openai",modelId:G.model.modelId}}function H(G){if(G instanceof v)return G;let V=typeof G?.status==="number"?G.status:void 0,K=typeof G?.message==="string"?G.message:"OpenAI error",z=typeof G?.code==="string"?G.code:V?`openai_http_${V}`:"openai_error",j=V?A$.isRetryableStatus(V):!1;return new v(K,{code:z,retryable:j,status:V})}async function*X(G){let{request:V}=G,K=V.requestId||p$("req"),z=J(),j=V.model.modelId,_=$.compat?.interleavedThinking,B=typeof _==="boolean"?_:a4(j,W),F=V.stream!==!1,A=[];if(V.messages&&Array.isArray(V.messages)){let R=-1;for(let q=V.messages.length-1;q>=0;q--)if(V.messages[q].role==="user"){R=q;break}for(let q=0;q<V.messages.length;q++){let D=V.messages[q],O=o4(D),T=q<R;if(O&&typeof O==="object"&&O.role==="assistant"){if(T){if("reasoning_content"in O)delete O.reasoning_content}else if(!B){if("reasoning_content"in O)delete O.reasoning_content}else if(Array.isArray(O?.tool_calls)&&O.tool_calls.length>0){let S=O.reasoning_content;if(typeof S!=="string"||S.length===0)O.reasoning_content="."}}A.push(O)}}else{if(typeof V.instructions==="string"&&V.instructions.length>0)A.push({role:"system",content:V.instructions});A.push({role:"user",content:V.input})}let N=(()=>{let R=V.reasoning?.effort;if(typeof R!=="string")return;if(R==="none"||R==="minimal"||R==="low"||R==="medium"||R==="high"||R==="xhigh")return R;return})(),U={model:j,messages:A,stream:F,stream_options:F?{include_usage:!0}:void 0,metadata:V.metadata??void 0,reasoning_effort:N,max_tokens:V.maxOutputTokens??void 0,stop:V.stop??void 0,temperature:V.temperature??void 0,top_p:V.topP??void 0};if(V.tools&&Array.isArray(V.tools)&&V.tools.length>0)U.tools=V.tools;try{let R=Y(V);if(yield{type:"response_start",requestId:K,model:R},!F){let L=await z.chat.completions.create({...U,stream:!1},{signal:V.signal,timeout:V.timeoutMs}),y=Array.isArray(L?.choices)?L.choices[0]:void 0,b=y?.message,u=typeof b?.reasoning_content==="string"?b.reasoning_content:"";if(u.length>0)yield{type:"delta",requestId:K,chunk:{kind:"thinking_start"}},yield{type:"delta",requestId:K,chunk:{kind:"thinking_delta",text:u}},yield{type:"delta",requestId:K,chunk:{kind:"thinking_end",text:u}};let g=typeof b?.content==="string"?b.content:"";if(g.length>0)yield{type:"delta",requestId:K,chunk:{kind:"text",text:g}};let c=Array.isArray(b?.tool_calls)?b.tool_calls:[];for(let l=0;l<c.length;l++){let M=c[l],E=typeof M?.id==="string"?M.id:`call_${l}`,w=typeof M?.function?.name==="string"?M.function.name:void 0,x=typeof M?.function?.arguments==="string"?M.function.arguments:void 0;if(x||w)yield{type:"delta",requestId:K,chunk:{kind:"tool_call_delta",callId:E,toolId:w,argsTextDelta:x}}}let o=QW(y?.finish_reason);yield{type:"response_end",requestId:K,stopReason:o,usage:L?.usage};return}let q=await z.chat.completions.create({...U,stream:!0},{signal:V.signal,timeout:V.timeoutMs}),D=null,O,T=new Map,S=!1,f="";for await(let L of q){if(L?.usage!=null)O=L.usage;let y=Array.isArray(L?.choices)?L.choices:[];for(let b of y){if(b?.finish_reason!=null)D=b.finish_reason;let u=b?.delta,g=u?.reasoning_content;if(typeof g==="string"&&g.length>0){if(!S)S=!0,yield{type:"delta",requestId:K,chunk:{kind:"thinking_start"}};f+=g,yield{type:"delta",requestId:K,chunk:{kind:"thinking_delta",text:g}}}let c=u?.content;if(typeof c==="string"&&c.length>0){if(S)S=!1,yield{type:"delta",requestId:K,chunk:{kind:"thinking_end",text:f||void 0}};yield{type:"delta",requestId:K,chunk:{kind:"text",text:c}}}let o=Array.isArray(u?.tool_calls)?u.tool_calls:[];for(let l of o){let M=typeof l?.index==="number"?l.index:0,w=T.get(M)||(typeof l?.id==="string"?l.id:`call_${M}`);T.set(M,w);let x=typeof l?.function?.name==="string"?l.function.name:void 0,h=typeof l?.function?.arguments==="string"?l.function.arguments:void 0;if(x||h)yield{type:"delta",requestId:K,chunk:{kind:"tool_call_delta",callId:w,toolId:x,argsTextDelta:h}}}}}if(S)yield{type:"delta",requestId:K,chunk:{kind:"thinking_end",text:f||void 0}};yield{type:"response_end",requestId:K,stopReason:QW(D),usage:O}}catch(R){if(R?.name==="AbortError")throw new v("Aborted",{code:"aborted",retryable:!1});throw H(R)}}return{provider:"openai",defaultModelId:$.defaultModelId,stream:X}}function QW($){if($==="tool_calls"||$==="function_call")return"tool_call";if($==="length")return"length";if($==="content_filter")return"error";if($==="stop"||$==null)return"final";return"final"}class I0{queue=[];waiters=[];enqueue($){let W=this.waiters.shift();if(W){W($);return}this.queue.push($)}isEmpty(){return this.queue.length===0}async dequeueOrWait($){if(this.queue.length>0)return this.queue.shift();return new Promise((W)=>{let Q=setTimeout(()=>{let Z=this.waiters.indexOf(W);if(Z>=0)this.waiters.splice(Z,1);W(void 0)},$);this.waiters.push((Z)=>{clearTimeout(Q),W(Z)})})}}class Y1{tools;options;eventQueue=new I0;constructor($,W){this.tools=$;this.options=W}async*executeTasksInParallel($,W,Q){this.eventQueue=new I0;let Z=!1,J=$.map(async(X)=>{let G=X.toolCall.function.name,V=this.tools?.get(G);if(!V)return{tc:X,result:`Tool "${G}" not found`,isError:!0};try{let K=typeof X.toolCall.function.arguments==="string"?JSON.parse(X.toolCall.function.arguments):X.toolCall.function.arguments,z=`${W.sessionId}:subagent:${crypto.randomUUID()}`,j={...Q,sessionId:z,emitEvent:(B)=>{this.eventQueue.enqueue({...B,sessionId:W.sessionId})}},_=await V.execute(K,j);return{tc:X,result:_,isError:!1}}catch(K){return{tc:X,result:`Task execution failed: ${K instanceof Error?K.message:String(K)}`,isError:!0}}}),Y=Promise.allSettled(J).then((X)=>{return Z=!0,X});while(!Z||!this.eventQueue.isEmpty()){let X=await this.eventQueue.dequeueOrWait(5);if(X)yield X}let H=await Y;for(let[X,G]of H.entries()){let V=$[X];if(G.status==="fulfilled"){let{result:K,isError:z}=G.value;V.result=K,V.isError=z}else V.result=`Task execution rejected: ${G.reason}`,V.isError=!0;if(!this.options.hasAssistantToolCallMessage(W,V.toolCall.id))this.options.addAssistantMessageWithToolCalls(W);yield{type:"tool_result",tool_call_id:V.toolCall.id,result:V.result,isError:V.isError,sessionId:W.sessionId},this.options.addToolResultToHistory(W,V)}}}class y${hooks;constructor($){this.hooks=$??{}}async executePreToolUse($){let W=this.hooks.preToolUse;if(!W)return{allow:!0};return await W($)}async executePostToolUse($,W){let Q=this.hooks.postToolUse;if(!Q)return;await Q($,W)}async executePostToolUseFailure($,W){let Q=this.hooks.postToolUseFailure;if(!Q)return;await Q($,W)}}class H1{options;toolEventQueue=[];constructor($){this.options=$}_log(...$){if(this.options.log)this.options.log(...$)}createToolExecutionContext($,W,Q,Z){return{sessionId:$.sessionId,toolCallId:Q,toolName:Z,signal:W,usage:$.usage,metadata:$.metadata,emitEvent:(J)=>{this.toolEventQueue.push({...J,sessionId:$.sessionId})}}}async executeToolCall($,W,Q,Z,J){B$(Q,`Tool execution: ${$.toolCall.function.name}`);let Y=Z?new y$(Z):void 0,H=$.toolCall.id,X=$.toolCall,G=X,V=(_)=>({sessionId:W.sessionId,toolCall:_,toolContext:W});if(J){if(!J.allow)return $.result="Tool execution blocked by PreToolUse hook",$.isError=!0,{type:"tool_result",tool_call_id:H,result:$.result,isError:!0,sessionId:W.sessionId};if(J.modifiedToolCall)G={...J.modifiedToolCall,id:H,type:X.type}}else if(Y){let _=await Y.executePreToolUse(V(G));if(!_.allow)return $.result="Tool execution blocked by PreToolUse hook",$.isError=!0,{type:"tool_result",tool_call_id:H,result:$.result,isError:!0,sessionId:W.sessionId};if(_.modifiedToolCall)G={..._.modifiedToolCall,id:H,type:X.type}}let K=this.options.tools?.get(G.function.name);if(!K)return this._log(`Tool NOT FOUND: ${G.function.name}`),$.result=`Tool not found: ${G.function.name}`,$.isError=!0,{type:"tool_result",tool_call_id:H,result:$.result,isError:!0,sessionId:W.sessionId};let z;try{z=typeof G.function.arguments==="string"?G.function.arguments.trim()===""?{}:JSON.parse(G.function.arguments):G.function.arguments??{}}catch(_){this._log(`Warning: Failed to parse tool arguments for ${G.function.name}, using empty object`),z={}}let j={...W,toolCallId:H,toolName:G.function.name};try{if($.result=await K.execute(z,j),$.isError=!1,Y)await Y.executePostToolUse(V(G),$.result);return{type:"tool_result",tool_call_id:H,result:$.result,sessionId:W.sessionId}}catch(_){let B=_ instanceof Error?_:Error(String(_));if(this._log(`Tool execution threw ERROR: ${G.function.name} - ${B.message}`),$.result=B.message,$.isError=!0,Y)await Y.executePostToolUseFailure(V(G),B);return{type:"tool_result",tool_call_id:H,result:$.result,isError:!0,sessionId:W.sessionId}}}async*handleToolCalls($,W,Q){W.metadata=$.metadata;let Z=$.pendingToolCalls.length,J=Q?.signal,Y=Q?.toolContextInput,H=Y?.approval,X=H?.decisions??{},G=(N)=>{return this.options.approvalHandler.shouldRequireApproval(H,N)},V=(N)=>{return $.messages.some((U)=>{if(!U||typeof U!=="object"||U.role!=="assistant")return!1;let R=U.tool_calls;return Array.isArray(R)&&R.some((q)=>q?.id===N)})},K=(N)=>{if(!V(N))this.options.addAssistantMessageWithToolCalls($)},z=(N)=>{return $.messages.some((U)=>U&&typeof U==="object"&&U.role==="tool"&&U.tool_call_id===N)},j=new Set,_=(N)=>{try{return typeof N.function.arguments==="string"?JSON.parse(N.function.arguments):N.function.arguments}catch(U){let R=U instanceof Error?U.message:String(U);return{_raw:N.function.arguments,_parseError:R}}},B=(N)=>{let U=[];for(let R=N;R<$.pendingToolCalls.length;R++){let q=$.pendingToolCalls[R];if(z(q.toolCall.id))continue;if(j.has(q.toolCall.id))continue;if(X[q.toolCall.id])continue;let D=this.options.tools?.get(q.toolCall.function.name),O=D?.riskLevel??"safe";if(D&&this.options.isToolDisabled(q.toolCall.function.name))continue;if(D&&this.options.isToolBlocked($,q.toolCall.function.name))continue;if(!D||!G(O))continue;j.add(q.toolCall.id),U.push({type:"tool_approval_requested",tool_call_id:q.toolCall.id,toolName:q.toolCall.function.name,riskLevel:O,args:_(q.toolCall),sessionId:$.sessionId})}return U};if($.metadata?.parallelMode===!0){let N=$.pendingToolCalls.filter((U)=>{let R=U.toolCall.function.name;return R==="Task"||R.endsWith("_Task")});if(N.length>1)yield*this.options.parallelTaskExecutor.executeTasksInParallel(N,$,W),$.pendingToolCalls=$.pendingToolCalls.filter((U)=>!N.includes(U))}let A=this.options.checkpointManager.hasStore();for(let N=0;N<$.pendingToolCalls.length;N++){let U=$.pendingToolCalls[N];if(z(U.toolCall.id)){$.pendingToolCalls.splice(N,1),N--;continue}let R=U.toolCall.function.name,q;if(Q?.hooks?.preToolUse){let L=new y$(Q.hooks),y=(b)=>({sessionId:$.sessionId,toolCall:b,toolContext:W});if(q=await L.executePreToolUse(y(U.toolCall)),!q.allow){this._log(`Tool BLOCKED by preToolUse hook: ${R}`),U.result="Tool execution blocked by PreToolUse hook",U.isError=!0,K(U.toolCall.id),yield{type:"tool_result",tool_call_id:U.toolCall.id,result:U.result,isError:!0,sessionId:$.sessionId},this.options.addToolResultToHistory($,U),$.pendingToolCalls.splice(N,1),N--,await this.options.saveCheckpoint($,{phase:"tool_execution",status:`Tool blocked by preToolUse hook: ${R}`,modelConfig:Q?.checkpointModelConfig,requestParams:Q?.requestParams});continue}}if(q?.modifiedToolCall)U.toolCall={...q.modifiedToolCall,id:U.toolCall.id,type:U.toolCall.type};let D=U.toolCall.function.name,O=this.options.tools?.get(D),T=O?.riskLevel??"safe";if(O&&this.options.isToolBlocked($,D)){let L=`Tool "${D}" is blocked by middleware`;this._log(`Tool BLOCKED: ${D} - ${L}`),U.result=`Tool execution skipped: ${L}`,U.isError=!0,K(U.toolCall.id),yield{type:"tool_skipped",tool_call_id:U.toolCall.id,toolName:D,reason:L,sessionId:$.sessionId},yield{type:"tool_result",tool_call_id:U.toolCall.id,result:U.result,isError:!0,sessionId:$.sessionId},this.options.addToolResultToHistory($,U),$.pendingToolCalls.splice(N,1),N--,await this.options.saveCheckpoint($,{phase:"tool_execution",status:`Tool blocked: ${D}`,modelConfig:Q?.checkpointModelConfig,requestParams:Q?.requestParams});continue}if(O&&this.options.isToolDisabled(D)){let L=`Tool "${D}" is disabled for this session`;this._log(`Tool DISABLED: ${D}`),U.result=`Tool execution skipped: ${L}`,U.isError=!0,K(U.toolCall.id),yield{type:"tool_skipped",tool_call_id:U.toolCall.id,toolName:D,reason:L,sessionId:$.sessionId},yield{type:"tool_result",tool_call_id:U.toolCall.id,result:U.result,isError:!0,sessionId:$.sessionId},this.options.addToolResultToHistory($,U),$.pendingToolCalls.splice(N,1),N--,await this.options.saveCheckpoint($,{phase:"tool_execution",status:`Tool disabled: ${D}`,modelConfig:Q?.checkpointModelConfig,requestParams:Q?.requestParams});continue}if(O&&G(T)){let L=X[U.toolCall.id];if(!L){this._log(`Tool approval required: ${D} (risk: ${T})`),$.stopReason="approval_required";for(let b of B(N)){if(b.type==="tool_approval_requested")this._log(` - Requesting approval for: ${b.toolName}`);yield b}let y=await this.options.saveCheckpoint($,{phase:"approval_pending",status:`Waiting for approval: ${D}`,modelConfig:Q?.checkpointModelConfig,requestParams:Q?.requestParams});throw yield{type:"requires_action",kind:"tool_approval",checkpoint:A?void 0:y,checkpointRef:A?{sessionId:y.sessionId}:void 0,sessionId:$.sessionId},await this.options.persistSessionState($),yield{type:"done",finalResponse:$.currentResponse,stopReason:"approval_required",modelStopReason:$.lastModelStopReason,usage:{...$.usage},sessionId:$.sessionId},new w$}if(!L.approved){let y=L.reason??"User denied approval";this._log(`Tool approval REJECTED: ${D} - ${y}`),U.result=`Tool execution skipped: ${y}`,U.isError=!0,K(U.toolCall.id),yield{type:"tool_skipped",tool_call_id:U.toolCall.id,toolName:U.toolCall.function.name,reason:y,sessionId:$.sessionId},yield{type:"tool_result",tool_call_id:U.toolCall.id,result:U.result,isError:!0,sessionId:$.sessionId},this.options.addToolResultToHistory($,U),$.pendingToolCalls.splice(N,1),N--,await this.options.saveCheckpoint($,{phase:"tool_execution",status:`Tool approval rejected: ${D}`,modelConfig:Q?.checkpointModelConfig,requestParams:Q?.requestParams});continue}this._log(`Tool approval APPROVED: ${D}`)}K(U.toolCall.id),this._log(`Executing tool: ${D}`),this.toolEventQueue=[];let S=await this.executeToolCall(U,W,J,Q?.hooks,q);for(let L of this.toolEventQueue)yield L;if(this.toolEventQueue=[],S.type==="tool_result")if(S.isError||S.result&&typeof S.result==="object"&&S.result.isError===!0){let y=typeof S.result==="string"?S.result:JSON.stringify(S.result);this._log(`Tool execution ERROR: ${D} - ${y.slice(0,100)}`)}else{let y=typeof S.result==="string"?S.result.slice(0,100):JSON.stringify(S.result).slice(0,100);this._log(`Tool execution SUCCESS: ${D} - ${y}${y.length>=100?"...":""}`)}let f=S.type==="tool_result"&&(S.isError||S.result&&typeof S.result==="object"&&S.result.isError===!0);if(O&&O.name==="AskUserQuestion"&&f){let L=Y?.askUser?.rejected?.[U.toolCall.id];if(L!==void 0){let b=L||"User cancelled the question";this._log(`AskUser CANCELLED: ${b}`),U.result=`User cancelled the question: ${b}`,U.isError=!0,K(U.toolCall.id),yield{type:"tool_skipped",tool_call_id:U.toolCall.id,toolName:O.name,reason:b,sessionId:$.sessionId},yield{type:"tool_result",tool_call_id:U.toolCall.id,result:U.result,isError:!0,sessionId:$.sessionId},this.options.addToolResultToHistory($,U),$.pendingToolCalls.splice(N,1),N--,await this.options.saveCheckpoint($,{phase:"tool_execution",status:`AskUser cancelled: ${O.name}`,modelConfig:Q?.checkpointModelConfig,requestParams:Q?.requestParams});continue}let y=Y?.askUser?.answers?.[U.toolCall.id];if(!y){let u=(typeof U.toolCall.function.arguments==="string"?JSON.parse(U.toolCall.function.arguments):U.toolCall.function.arguments)?.questions||[];this._log(`AskUser waiting for answers (${u.length} questions)`),yield S,$.stopReason="approval_required";let g=await this.options.saveCheckpoint($,{phase:"approval_pending",status:`Waiting for user answers: ${O.name}`,modelConfig:Q?.checkpointModelConfig,requestParams:Q?.requestParams});throw await this.options.persistSessionState($),yield{type:"requires_action",kind:"ask_user",toolCallId:U.toolCall.id,questions:u,checkpoint:A?void 0:g,checkpointRef:A?{sessionId:g.sessionId}:void 0,sessionId:$.sessionId},yield{type:"done",finalResponse:$.currentResponse,stopReason:"approval_required",modelStopReason:$.lastModelStopReason,usage:{...$.usage},sessionId:$.sessionId},new w$}else{let u={...typeof U.toolCall.function.arguments==="string"?JSON.parse(U.toolCall.function.arguments):U.toolCall.function.arguments,answers:y};U.toolCall.function.arguments=JSON.stringify(u),this.toolEventQueue=[];let g=await this.executeToolCall(U,W,J,Q?.hooks,q);for(let c of this.toolEventQueue)yield c;this.toolEventQueue=[],yield g,this.options.addToolResultToHistory($,U),$.pendingToolCalls.splice(N,1),N--,await this.options.saveCheckpoint($,{phase:"tool_execution",status:U.isError?`AskUser error: ${O.name}`:`AskUser completed: ${O.name}`,modelConfig:Q?.checkpointModelConfig,requestParams:Q?.requestParams});continue}}yield S,this.options.addToolResultToHistory($,U),$.pendingToolCalls.splice(N,1),N--,await this.options.saveCheckpoint($,{phase:"tool_execution",status:U.isError?`Tool error: ${D}`:`Tool completed: ${D}`,modelConfig:Q?.checkpointModelConfig,requestParams:Q?.requestParams})}$.pendingToolCalls=[],$.iteration++,yield{type:"iteration_end",iteration:$.iteration-1,willContinue:!0,toolCallCount:Z,usage:{...$.usage},sessionId:$.sessionId}}}class v0{static APPROVAL_REQUIRED_LEVELS=new Set(["high","critical"]);requiresApproval($){return v0.APPROVAL_REQUIRED_LEVELS.has($)}shouldRequireApproval($,W){if($?.autoApprove===!0)return!1;if(($?.strategy??"high_risk")==="all")return!0;return this.requiresApproval(W)}}class X1{saveHandler;onError;constructor($,W){this.saveHandler=$;this.onError=W}async trigger(){try{await this.saveHandler()}catch($){let W=$ instanceof Error?$:Error(String($));console.warn("[Session] Auto-save failed:",W.message),this.onError?.(W)}}}var t4=1000;function e4($){if(!$)return;if($ instanceof v)return{code:$.code,message:$.message,status:$.status,retryable:$.retryable};if($ instanceof Error){let W=$,Q=typeof W.code==="string"?W.code:void 0,Z=typeof W.status==="number"?W.status:void 0,J=typeof W.retryable==="boolean"?W.retryable:void 0;return{code:Q,message:$.message,status:Z,retryable:J}}return{message:String($)}}function JW($){let W=$?.function?.arguments;if(typeof W==="string")try{return JSON.parse(W),$}catch(Q){let Z=Q instanceof Error?Q.message:String(Q);return{...$,function:{...$.function,arguments:JSON.stringify({_raw:W,_parseError:Z})}}}if(W&&typeof W==="object")return{...$,function:{...$.function,arguments:JSON.stringify(W)}};return{...$,function:{...$.function,arguments:JSON.stringify(W??null)}}}function ZW($){let W=!1,Q=$.map((Z)=>{if(!Z||typeof Z!=="object"||Z.role!=="assistant")return Z;let J=Z.tool_calls;if(!Array.isArray(J)||J.length===0)return Z;let Y=!1,H=J.map((X)=>{let G=JW(X);if(G!==X)Y=!0;return G});if(!Y)return Z;return W=!0,{...Z,tool_calls:H}});return W?Q:$}class e extends s4{id;createdAt;status;title;updatedAt;lastActiveAt;errorMessage;configOverride;metadata;messages;toolCallCount;usage;responseCount;avgResponseTime;_stateStore;_checkpointManager;_approvalHandler;_parallelTaskExecutor;_toolExecutor;_autoSave;_autoSaveManager;_modelClient;_tools;_middlewares;_systemPrompt;_agentName;_onUsage;_pendingInput=null;_isReceiving=!1;_hooks;_modelOverride;_modelVariantsOverride;_maxIterations;_requestParams;_emitSessionCreatedEvent;_sessionCreatedEventEmitted=!1;_abortController=null;_enableLogging;_checkpointOriginalMessages;_checkpointNewMessages=[];_checkpointSkipSnapshot;getDisabledToolNames(){let $=this.configOverride?.disabledTools;if(!$||$.length===0)return new Set;return new Set($)}isToolDisabled($){return this.getDisabledToolNames().has($)}collectBlockedTools($){let W=new Set;for(let Q of this._middlewares)if(typeof Q.__getBlockedTools==="function"){let Z=Q.__getBlockedTools($);(Array.isArray(Z)?Z:Array.from(Z)).forEach((Y)=>W.add(Y))}return W}isToolBlocked($,W){let Q=$.metadata?.blockedTools;if(!Q)return!1;if(Q instanceof Set)return Q.has(W);if(Array.isArray(Q))return Q.includes(W);return!1}getToolsForModel($){let W=this._tools?.toOpenAIFormat();if(!W||W.length===0)return;let Q=this.getDisabledToolNames(),Z=Q.size===0?W:W.filter((Y)=>!Q.has(Y.function.name)),J=$.metadata?.blockedTools;if(J&&J.size>0)Z=Z.filter((Y)=>!J.has(Y.function.name));return Z.length>0?Z:void 0}getEffectiveSystemPrompt(){let $=this.configOverride?.systemPromptOverride;if(typeof $==="string")return $;return this._systemPrompt}_log(...$){if(this._enableLogging){let W=this._agentName?`[GoatChain:Session:${this._agentName}:${this.id.slice(0,8)}]`:`[GoatChain:Session:${this.id.slice(0,8)}]`;console.warn(W,...$)}}constructor($,W,Q,Z){super();if(this._stateStore=$,this._checkpointManager=new W1($),this._approvalHandler=new v0,this.id=W,Q)this.createdAt=Q.createdAt,this.restoreFromSnapshot(Q);else{let J=Date.now();this.createdAt=J,this.status="active",this.updatedAt=J,this.lastActiveAt=J,this.messages=[],this.toolCallCount=0,this.metadata=void 0,this.usage={promptTokens:0,completionTokens:0,totalTokens:0},this.responseCount=0}this._autoSave=!0,this._autoSaveManager=new X1(()=>this.save(),(J)=>{this.emit("auto-save-failed",{error:J})}),this._modelClient=Z?.modelClient,this._tools=Z?.tools,this._middlewares=Z?.middlewares??[],this._systemPrompt=Z?.systemPrompt,this._agentName=Z?.agentName,this._onUsage=Z?.onUsage,this._hooks=Z?.hooks,this._modelOverride=Z?.model,this._modelVariantsOverride=Z?.variants,this._maxIterations=Z?.maxIterations,this._requestParams=Z?.requestParams,this._emitSessionCreatedEvent=Z?.emitSessionCreatedEvent===!0,this._enableLogging=Z?.enableLogging??!1,this._parallelTaskExecutor=new Y1(this._tools,{hasAssistantToolCallMessage:(J,Y)=>this.hasAssistantToolCallMessage(J,Y),addAssistantMessageWithToolCalls:(J)=>this.addAssistantMessageWithToolCalls(J),addToolResultToHistory:(J,Y)=>this.addToolResultToHistory(J,Y)}),this._toolExecutor=new H1({tools:this._tools,approvalHandler:this._approvalHandler,checkpointManager:this._checkpointManager,saveCheckpoint:(J,Y)=>this.saveCheckpointForState(J,Y),parallelTaskExecutor:this._parallelTaskExecutor,isToolDisabled:(J)=>this.isToolDisabled(J),isToolBlocked:(J,Y)=>this.isToolBlocked(J,Y),addAssistantMessageWithToolCalls:(J)=>this.addAssistantMessageWithToolCalls(J),addToolResultToHistory:(J,Y)=>this.addToolResultToHistory(J,Y),persistSessionState:(J)=>this.persistSessionState(J),log:(...J)=>this._log(...J)})}async hasCheckpoint(){try{return await this._checkpointManager.loadCheckpoint(this.id)!=null}catch{return!1}}send($,W){if(this._ensureRuntimeConfigured(!0),this._isReceiving)throw Error("Cannot send while receiving messages");if(this._pendingInput)throw Error("Pending input already exists; call receive() to consume it before sending another message");let Q=typeof $==="string"?$:JSON.stringify($);this._log("send() called with input:",Q.slice(0,100)+(Q.length>100?"...":"")),this._pendingInput={input:$,options:W}}cancel(){if(this._abortController)this._abortController.abort("Session cancelled by user")}async*receive($){if(this._isReceiving)throw Error("Cannot receive concurrently");let W=await this._checkpointManager.loadCheckpoint(this.id).catch(()=>null),Q=W!=null;if(!Q&&!this._pendingInput)throw Error("Nothing to receive; call send() first (or resume from a session that has a checkpoint)");this._log(`receive() started, hasCheckpoint: ${Q}, hasPendingInput: ${!!this._pendingInput}`),this._abortController=new AbortController;let Z=this._abortController.signal;this._isReceiving=!0;try{if(this._emitSessionCreatedEvent&&!this._sessionCreatedEventEmitted)this._sessionCreatedEventEmitted=!0,yield{type:"session_created",sessionId:this.id};if(Q&&this._pendingInput){this._log("Resuming from checkpoint with new user message");let{input:J,options:Y}=this._pendingInput;this._pendingInput=null;let H=G0(W);if(H.sessionId!==this.id)H.sessionId=this.id;H.shouldContinue=!0,H.stopReason=void 0,H.metadata={...H.metadata,_pendingUserInput:J};let X=this._requestParams??W.requestParams,G=Y??$,V=this.buildAutoRejectToolContext(H,G?.toolContext),{model:K,variants:z}=this.getRuntimeModelRoute();if(!(yield*this._streamWithPauseDetection(H,{maxIterations:this._maxIterations,signal:Z,model:K,variants:z,toolContext:V,hooks:this._hooks,requestParams:X})))await this._finalizeRun(H,Date.now());return}if(Q){this._log("Resuming from checkpoint without new message");let J=G0(W);if(J.sessionId!==this.id)J.sessionId=this.id;let Y=this._requestParams??W.requestParams,H=this.buildAutoRejectToolContext(J,$?.toolContext),{model:X,variants:G}=this.getRuntimeModelRoute();if(!(yield*this._streamWithPauseDetection(J,{maxIterations:this._maxIterations,signal:Z,model:X,variants:G,toolContext:H,hooks:this._hooks,requestParams:Y})))await this._finalizeRun(J,Date.now());return}if(this._pendingInput){this._log("Starting new message flow");let{input:J,options:Y}=this._pendingInput;this._pendingInput=null,yield*this._stream(J,Y)}}catch(J){if(J instanceof N$){yield{type:"done",finalResponse:"",stopReason:"cancelled",usage:{promptTokens:0,completionTokens:0,totalTokens:0},sessionId:this.id};return}throw J}finally{this._isReceiving=!1,this._abortController=null}}async*receiveWithApprovals($,W){let Q=W?.toolContext,Z={...Q??{},approval:{...Q?.approval??{},decisions:{...Q?.approval?.decisions??{},...$}}};yield*this.receive({...W,toolContext:Z})}async*_stream($,W){this._ensureRuntimeConfigured(!0);let Q=Date.now(),{model:Z,variants:J}=this.getRuntimeModelRoute(),Y=this._abortController?.signal;if(!this.title&&this.messages.length===0){let V=this.extractTextFromContent($);if(V)this.title=this.createTitle(V)}let H=this.messages.filter((V)=>V.role!=="system");this._log(`Starting agent loop with ${H.length} existing messages`);let X=b0({sessionId:this.id,input:$,messages:H},this.getEffectiveSystemPrompt()??"");if(!(yield*this._streamWithPauseDetection(X,{maxIterations:this._maxIterations,signal:Y,model:Z,variants:J,toolContext:W?.toolContext,hooks:this._hooks,requestParams:this._requestParams})))await this._finalizeRun(X,Q)}async*_streamWithPauseDetection($,W){try{return yield*this._streamWithState($,W),!1}catch(Q){if(Q instanceof w$)return this.messages=$.messages.filter((Z)=>Z.role!=="system"),!0;throw Q}}resolveModelRef($){if($.provider)return{provider:$.provider,modelId:$.modelId};let W=this._modelClient?.modelRef?.provider;if(W)return{provider:W,modelId:$.modelId};return}buildAutoRejectToolContext($,W){if($.pendingToolCalls.length===0)return W??{};let Q={},Z={};for(let J of $.pendingToolCalls){let Y=J.toolCall.id,H=J.toolCall.function.name;if(!W?.approval?.decisions?.[Y])Q[Y]={approved:!1,reason:"Auto-rejected: session resumed without tool context"};if(H==="AskUserQuestion"&&!W?.askUser?.answers?.[Y])Z[Y]="Auto-rejected: session resumed without user answers"}if(Object.keys(Q).length===0&&Object.keys(Z).length===0)return W??{};return{...W,approval:{...W?.approval,decisions:{...W?.approval?.decisions,...Q}},askUser:{answers:W?.askUser?.answers??{},rejected:{...W?.askUser?.rejected,...Z}}}}getRuntimeModelRoute(){if(this.configOverride?.model){let $=this.resolveModelRef(this.configOverride.model);if($)return{model:$,variants:this._modelVariantsOverride}}return{model:this._modelOverride,variants:this._modelVariantsOverride}}_ensureRuntimeConfigured($){if(!this._modelClient)throw Error("Session is not configured with a model client");if($&&this.getEffectiveSystemPrompt()===void 0)throw Error("Session is not configured with a system prompt")}extractTextFromContent($){if(typeof $==="string")return $;if(Array.isArray($))return $.filter((W)=>W.type==="text").map((W)=>W.text).join(" ");if($&&typeof $==="object"&&$.type==="text")return $.text||"";return""}createTitle($,W=50){let Q=$.trim();if(Q.length<=W)return Q;return`${Q.substring(0,W).trim()}...`}_recordUsage($){if(this._onUsage)this._onUsage($)}async*executeModelStream($,W,Q,Z,J,Y){if(!this._modelClient)throw Error("Session is not configured with a model client");let H=$.sessionId,X=new Map,G=!1,V=!1,K=(q)=>{let D=X.get(q);if(D)return D;let O={argsText:"",started:!1};return X.set(q,O),O},z=[],j=(q,D)=>{let O=K(q);if(D&&!O.toolName)O.toolName=D;if(!O.started)O.started=!0,this._log(`Stream: tool_call_start - ${O.toolName} (${q.slice(0,8)})`),z.push({type:"tool_call_start",callId:q,toolName:O.toolName,sessionId:H})},_=(q,D,O)=>{let T=K(q);if(D&&!T.toolName)T.toolName=D;if(typeof O==="string"&&O.length>0)T.argsText+=O;j(q,T.toolName),z.push({type:"tool_call_delta",callId:q,toolName:T.toolName,argsTextDelta:O,sessionId:H})},B=()=>{if(G)return;G=!0,this._log("Stream: text_start"),z.push({type:"text_start",sessionId:H})},F=()=>{if(!G||V)return;V=!0;let q=$.currentResponse.slice(0,50)+($.currentResponse.length>50?"...":"");this._log(`Stream: text_end - "${q}"`),z.push({type:"text_end",content:$.currentResponse,sessionId:H})},A=()=>{for(let[q,D]of X){if(!D.toolName)continue;let O={id:q,type:"function",function:{name:D.toolName,arguments:D.argsText}};if(this._tools){$.pendingToolCalls.push({toolCall:O});let T=D.argsText.slice(0,100)+(D.argsText.length>100?"...":"");this._log(`Stream: tool_call_end - ${D.toolName} with args: ${T}`)}z.push({type:"tool_call_end",toolCall:O,sessionId:H})}X.clear()},N=(()=>{if(!Y)return;let q={...Y};if(typeof q.maxOutputTokens!=="number"&&typeof Y.maxTokens==="number")q.maxOutputTokens=Y.maxTokens;return delete q.maxTokens,q})(),U=Array.isArray(J)&&J.length>0?{variants:J}:void 0,R=Z?{model:Z,...U??{},messages:ZW($.messages),tools:Q,signal:W,...N??{}}:{...U??{},messages:ZW($.messages),tools:Q,signal:W,...N??{}};try{for await(let q of this._modelClient.stream(R)){if(B$(W,"Session streaming"),q.type==="delta"){if(q.chunk.kind==="text")B(),$.currentResponse+=q.chunk.text,z.push({type:"text_delta",delta:q.chunk.text,sessionId:H});else if(q.chunk.kind==="thinking_start")this._log("Stream: thinking_start"),z.push({type:"thinking_start",sessionId:H});else if(q.chunk.kind==="thinking_delta")$.currentThinking=($.currentThinking??"")+q.chunk.text,z.push({type:"thinking_delta",delta:q.chunk.text,sessionId:H});else if(q.chunk.kind==="thinking_end"){let D=typeof q.chunk.text==="string"?q.chunk.text:"";if(D&&typeof $.currentThinking!=="string")$.currentThinking=D;let O=typeof $.currentThinking==="string"?$.currentThinking:D,T=O?O.slice(0,50)+(O.length>50?"...":""):"";this._log(`Stream: thinking_end - "${T}"`),z.push({type:"thinking_end",sessionId:H,...O?{content:O}:{}})}else if(q.chunk.kind==="tool_call_delta")_(q.chunk.callId,q.chunk.toolId,q.chunk.argsTextDelta)}else if(q.type==="response_end"){this._log(`Stream: response_end - stopReason: ${q.stopReason}`),F(),A(),$.lastModelStopReason=q.stopReason;let D=q.usage;if(D&&typeof D==="object"){let O=D;if(O.prompt_tokens||O.completion_tokens||O.total_tokens){let T={promptTokens:O.prompt_tokens??0,completionTokens:O.completion_tokens??0,totalTokens:O.total_tokens??0};$.usage.promptTokens=T.promptTokens,$.usage.completionTokens=T.completionTokens,$.usage.totalTokens+=T.totalTokens,this._recordUsage(T)}}}else if(q.type==="error"){if(q.terminal!==!1){let D=q.error?.code??"model_error",O=q.error?.message??"Model error",T=new v(O,{code:D,retryable:q.error?.retryable});$.error=T,$.shouldContinue=!1,$.stopReason="error"}}while(z.length>0)yield z.shift()}}catch(q){if(q instanceof N$)throw q;if(W?.aborted)throw new N$(typeof W?.reason==="string"?W.reason:"Agent execution aborted");$.error=q instanceof Error?q:Error(String(q)),$.shouldContinue=!1,$.stopReason="error"}finally{if(F(),X.size>0)A();while(z.length>0)yield z.shift()}}mergeStateResults($,W){if($.currentResponse=W.currentResponse,$.currentThinking=W.currentThinking,$.pendingToolCalls=W.pendingToolCalls,$.usage=W.usage,$.metadata=W.metadata,$.shouldContinue=W.shouldContinue,$.stopReason=W.stopReason,$.lastModelStopReason=W.lastModelStopReason,$.error=W.error,this._checkpointSkipSnapshot=W._skipMessageSnapshot,this._checkpointOriginalMessages&&!this._checkpointSkipSnapshot){let Q=this._checkpointOriginalMessages;$.messages=[...Q,...this._checkpointNewMessages]}else $.messages=W.messages}appendMessage($,W){if($.messages.push(W),this._checkpointOriginalMessages&&!this._checkpointSkipSnapshot)this._checkpointNewMessages.push(W)}getCheckpointMessages($){if(this._checkpointSkipSnapshot||!this._checkpointOriginalMessages)return $.messages;return[...this._checkpointOriginalMessages,...this._checkpointNewMessages]}async saveCheckpointForState($,W){let Q=x0($,{agentName:this._agentName,phase:W?.phase,status:W?.status,modelConfig:W?.modelConfig,requestParams:W?.requestParams,messages:this.getCheckpointMessages($)});return await this._checkpointManager.saveCheckpoint(Q),Q}addToolResultToHistory($,W){let Q=W.result,Z,J=W.isError;if(typeof Q==="string")Z=Q;else if(Q&&typeof Q==="object"&&"content"in Q){let Y=Q;if(Z=JSON.stringify(Y.content),Y.isError===!0)J=!0}else Z=JSON.stringify(Q);this.appendMessage($,{role:"tool",tool_call_id:W.toolCall.id,content:Z,...J?{isError:!0}:{}})}addAssistantMessageWithToolCalls($){let W=typeof $.currentThinking==="string"?$.currentThinking:void 0;this.appendMessage($,{role:"assistant",content:$.currentResponse||"",tool_calls:$.pendingToolCalls.map((Q)=>JW(Q.toolCall)),...W&&W.length>0?{reasoning_content:W}:{}})}addFinalAssistantMessage($){if($.currentResponse){let W=typeof $.currentThinking==="string"?$.currentThinking:void 0;this.appendMessage($,{role:"assistant",content:$.currentResponse,...W&&W.length>0?{reasoning_content:W}:{}})}}async persistSessionState($){this.messages=$.messages.filter((W)=>W.role!=="system"),await this.save()}async*_streamWithState($,W){let Q=W.maxIterations??t4,Z=W.signal,J=w0(this._middlewares),Y=this._toolExecutor.createToolExecutionContext($,Z),H=this._stateStore,X=H?.deleteOnComplete??!0,G=W.model?{modelId:W.model.modelId,provider:W.model.provider,...Array.isArray(W.variants)&&W.variants.length>0?{variants:W.variants.map((K)=>({provider:K.provider,modelId:K.modelId}))}:{}}:this._modelClient?{modelId:this._modelClient.modelId}:void 0,V=async(K)=>{if(!H)return;await this.saveCheckpointForState($,{phase:K?.phase,status:K?.status,modelConfig:G,requestParams:W.requestParams})};while($.shouldContinue){if(B$(Z,`Session iteration ${$.iteration}`),$.iteration>=Q){this._log(`Max iterations (${Q}) reached`),$.shouldContinue=!1,$.stopReason="max_iterations",yield{type:"done",finalResponse:$.currentResponse,stopReason:"max_iterations",modelStopReason:$.lastModelStopReason,usage:{...$.usage},sessionId:$.sessionId};break}if(this._log(`Iteration ${$.iteration} started, pending tool calls: ${$.pendingToolCalls.length}`),yield{type:"iteration_start",iteration:$.iteration,sessionId:$.sessionId},this._checkpointOriginalMessages=structuredClone($.messages),this._checkpointNewMessages=[],this._checkpointSkipSnapshot=$._skipMessageSnapshot,$.pendingToolCalls.length>0){if(this._log(`Executing ${$.pendingToolCalls.length} tool calls`),yield*this._toolExecutor.handleToolCalls($,Y,{signal:Z,toolContextInput:W.toolContext,hooks:W.hooks,checkpointModelConfig:G,requestParams:W.requestParams}),$.metadata?._pendingUserInput){let _=$.metadata._pendingUserInput;delete $.metadata._pendingUserInput,this.appendMessage($,{role:"user",content:_})}continue}if($.metadata?._pendingUserInput){let _=$.metadata._pendingUserInput;delete $.metadata._pendingUserInput,this.appendMessage($,{role:"user",content:_})}$.currentResponse="",$.currentThinking=void 0,$.pendingToolCalls=[],$.lastModelStopReason=void 0,await V();let K=await J({...$,messages:structuredClone($.messages)},async(_)=>{B$(Z,"Session model call");let B=this.collectBlockedTools(_);return _.metadata.blockedTools=B,_}),z=this.getToolsForModel(K),j=z?.length??0;this._log(`Calling model with ${K.messages.length} messages and ${j} tools`);for await(let _ of this.executeModelStream(K,Z,z,W.model,W.variants,W.requestParams))yield _;if(this._log(`Model response: ${K.currentResponse.slice(0,100)}${K.currentResponse.length>100?"...":""}, tool calls: ${K.pendingToolCalls.length}`),this.mergeStateResults($,K),B$(Z,`Session iteration ${$.iteration}`),$.stopReason==="error"){yield{type:"iteration_end",iteration:$.iteration,willContinue:!1,toolCallCount:$.pendingToolCalls.length,usage:{...$.usage},sessionId:$.sessionId},yield{type:"done",finalResponse:$.currentResponse,stopReason:"error",modelStopReason:$.lastModelStopReason,error:e4($.error),usage:{...$.usage},sessionId:$.sessionId};break}if($.pendingToolCalls.length>0)yield*this._toolExecutor.handleToolCalls($,Y,{signal:Z,toolContextInput:W.toolContext,hooks:W.hooks,checkpointModelConfig:G,requestParams:W.requestParams});else yield*this.handleFinalResponse($);if(await V(),!$.shouldContinue){if(this._log(`Agent loop finished. Stop reason: ${$.stopReason}`),H&&X)await H.deleteCheckpoint($.sessionId);break}}}hasAssistantToolCallMessage($,W){return $.messages.some((Q)=>{if(!Q||typeof Q!=="object"||Q.role!=="assistant")return!1;let Z=Q.tool_calls;return Array.isArray(Z)&&Z.some((J)=>J?.id===W)})}async*handleFinalResponse($){$.shouldContinue=!1,$.stopReason="final_response",this.addFinalAssistantMessage($),yield{type:"iteration_end",iteration:$.iteration,willContinue:!1,toolCallCount:0,usage:{...$.usage},sessionId:$.sessionId},yield{type:"done",finalResponse:$.currentResponse,stopReason:"final_response",modelStopReason:$.lastModelStopReason,usage:{...$.usage},sessionId:$.sessionId}}async _finalizeRun($,W){if(this.messages=$.messages.filter((Z)=>Z.role!=="system"),$.usage.totalTokens>0)this.addUsage($.usage);let Q=Date.now()-W;this.recordResponse(Q),await this.save()}getLastMessagePreview($=100){if(this.messages.length===0)return;let W=this.messages[this.messages.length-1],Q=typeof W.content==="string"?W.content:JSON.stringify(W.content);return Q.length>$?`${Q.substring(0,$)}...`:Q}toSnapshot(){let $={status:this.status,updatedAt:this.updatedAt,lastActiveAt:this.lastActiveAt,title:this.title,errorMessage:this.errorMessage},W={messages:[...this.messages],messageCount:this.messages.length,lastMessagePreview:this.getLastMessagePreview(),toolCallCount:this.toolCallCount},Q={usage:{...this.usage},responseCount:this.responseCount,avgResponseTime:this.avgResponseTime};return{id:this.id,createdAt:this.createdAt,state:$,configOverride:this.configOverride?{...this.configOverride}:void 0,context:W,stats:Q,metadata:this.metadata?{...this.metadata}:void 0}}restoreFromSnapshot($){this.status=$.state.status,this.updatedAt=$.state.updatedAt,this.lastActiveAt=$.state.lastActiveAt,this.title=$.state.title,this.errorMessage=$.state.errorMessage,this.configOverride=$.configOverride?{...$.configOverride}:void 0,this.metadata=$.metadata&&typeof $.metadata==="object"?{...$.metadata}:void 0,this.messages=[...$.context.messages],this.toolCallCount=$.context.toolCallCount,this.usage={...$.stats.usage},this.responseCount=$.stats.responseCount,this.avgResponseTime=$.stats.avgResponseTime}async save(){let $=this.toSnapshot();await this._stateStore.save(this.id,n.SESSION,$)}async load(){let $=await this._stateStore.load(this.id,n.SESSION);if($)return this.restoreFromSnapshot($),!0;return!1}triggerAutoSave(){this._autoSaveManager.trigger()}setStatus($,W){if(this.status=$,this.errorMessage=W,this.updatedAt=Date.now(),this._autoSave)this.triggerAutoSave()}markActive(){if(this.lastActiveAt=Date.now(),this.updatedAt=Date.now(),this._autoSave)this.triggerAutoSave()}addMessage($){if(this.messages.push($),this.markActive(),this._autoSave)this.triggerAutoSave()}addUsage($){if(this.usage.promptTokens=$.promptTokens,this.usage.completionTokens=$.completionTokens,this.usage.totalTokens+=$.totalTokens,this.updatedAt=Date.now(),this._autoSave)this.triggerAutoSave()}recordResponse($){let W=(this.avgResponseTime??0)*this.responseCount;if(this.responseCount++,this.avgResponseTime=(W+$)/this.responseCount,this.updatedAt=Date.now(),this._autoSave)this.triggerAutoSave()}incrementToolCallCount(){if(this.toolCallCount++,this.updatedAt=Date.now(),this._autoSave)this.triggerAutoSave()}setModelOverride($){if(!this.configOverride)this.configOverride={};if(this.configOverride.model=$,this.updatedAt=Date.now(),this._modelOverride=this.resolveModelRef($)??this._modelOverride,this._autoSave)this.triggerAutoSave()}clearModelOverride(){if(this.configOverride)delete this.configOverride.model,this.updatedAt=Date.now();if(this._modelOverride=void 0,this._autoSave)this.triggerAutoSave()}setSystemPromptOverride($){if(!this.configOverride)this.configOverride={};if(this.configOverride.systemPromptOverride=$,this.updatedAt=Date.now(),this._autoSave)this.triggerAutoSave()}clearSystemPromptOverride(){if(this.configOverride)delete this.configOverride.systemPromptOverride,this.updatedAt=Date.now();if(this._autoSave)this.triggerAutoSave()}disableTools($){if(!this.configOverride)this.configOverride={};if(this.configOverride.disabledTools=[...this.configOverride.disabledTools??[],...$],this.updatedAt=Date.now(),this._autoSave)this.triggerAutoSave()}enableAllTools(){if(this.configOverride)delete this.configOverride.disabledTools,this.updatedAt=Date.now();if(this._autoSave)this.triggerAutoSave()}setAutoSave($){this._autoSave=$}}class K0{}import{randomUUID as $8}from"node:crypto";class f0 extends K0{_stateStore;constructor($){super();this._stateStore=$}async create($){let W=$??$8(),Q=Date.now(),Z=(()=>{try{let H=globalThis?.process;return typeof H?.cwd==="function"?String(H.cwd()):void 0}catch{return}})(),J={id:W,createdAt:Q,state:{status:"active",updatedAt:Q,lastActiveAt:Q},context:{messages:[],messageCount:0,toolCallCount:0},stats:{usage:{promptTokens:0,completionTokens:0,totalTokens:0},responseCount:0},metadata:Z?{cwd:Z}:void 0},Y=new e(this._stateStore,W,J);return await Y.save(),Y}async get($){let W=await this._stateStore.load($,n.SESSION);if(!W)return;return new e(this._stateStore,$,W)}async list(){let $=await this._stateStore.listSessions(),W=[];for(let Q of $){let Z=await this._stateStore.load(Q,n.SESSION);if(Z){let J=new e(this._stateStore,Q,Z);W.push(J)}}return W}async destroy($){await this._stateStore.deleteSession($)}}import{existsSync as I$,mkdirSync as YW,rmSync as W8}from"node:fs";import{mkdir as Q8,readdir as V1,readFile as Z8,rm as HW,writeFile as J8}from"node:fs/promises";import v$ from"node:path";class C${deleteOnComplete;constructor($){this.deleteOnComplete=$?.deleteOnComplete??!0}assertValidStorageSegment($,W){if(!W)throw Error(`${$} must be a non-empty string`);if(W==="."||W==="..")throw Error(`${$} must not be "." or ".."`);if(W.includes("/")||W.includes("\\"))throw Error(`${$} must not contain path separators`);if(W.includes("\x00"))throw Error(`${$} must not contain NUL bytes`)}async save($,W,Q){let Z=this.buildPath($,W),J=JSON.stringify(Q,null,2);await this._write(Z,J)}async load($,W){let Q=this.buildPath($,W),Z=await this._read(Q);if(Z===void 0)return;try{return JSON.parse(Z)}catch{return}}async delete($,W){let Q=this.buildPath($,W);await this._delete(Q)}async deleteSession($){let W=this.buildPrefix($),Q=await this._list(W);await Promise.all(Q.map((Z)=>this._delete(Z)))}async listKeys($){let W=this.buildPrefix($);return(await this._list(W)).map((Z)=>this.extractKey($,Z))}async exists($,W){let Q=this.buildPath($,W);return this._exists(Q)}async saveCheckpoint($){let W={_meta:{description:"GoatChain Agent Loop Checkpoint - DO NOT EDIT MANUALLY",savedAt:new Date().toISOString(),agentName:$.agentName,sessionId:$.sessionId,iteration:$.iteration,phase:$.phase,status:$.status,messageCount:$.messages.length,toolCallsPending:$.pendingToolCalls?.length??0},checkpoint:$};await this.save($.sessionId,n.CHECKPOINT,W)}async loadCheckpoint($){return(await this.load($,n.CHECKPOINT))?.checkpoint}async deleteCheckpoint($){await this.delete($,n.CHECKPOINT)}async listCheckpoints(){let $=await this.listSessions(),W=[];for(let Q of $){let Z=await this.loadCheckpoint(Q);if(Z)W.push(Z)}return W}async listSessions(){let $=await this._list(""),W=new Set;for(let Q of $){let Z=this.extractSessionId(Q);if(Z)W.add(Z)}return Array.from(W)}buildPath($,W){return this.assertValidStorageSegment("sessionId",$),this.assertValidStorageSegment("key",W),`${$}/${W}`}buildPrefix($){return this.assertValidStorageSegment("sessionId",$),`${$}/`}extractKey($,W){let Q=this.buildPrefix($);return W.startsWith(Q)?W.slice(Q.length):W}extractSessionId($){let W=$.split("/");return W.length>0?W[0]:void 0}}class j0 extends C${baseDir;writeQueues=new Map;pendingWrites=new Map;constructor($){super($);this.baseDir=v$.resolve($.dir),this.ensureDir(this.baseDir)}async _write($,W){let Q=this.toFilePath($);this.pendingWrites.set(Q,W);let Z=this.writeQueues.get(Q);if(Z){await Z;return}let J=(async()=>{while(this.pendingWrites.has(Q)){let Y=this.pendingWrites.get(Q);this.pendingWrites.delete(Q);let H=v$.dirname(Q);await this.ensureDirAsync(H),await J8(Q,Y,"utf-8")}})();this.writeQueues.set(Q,J);try{await J}finally{if(this.writeQueues.get(Q)===J)this.writeQueues.delete(Q)}}async _read($){let W=this.toFilePath($);try{return await Z8(W,"utf-8")}catch{return}}async _delete($){let W=this.toFilePath($);await HW(W,{force:!0});let Q=v$.dirname(W);if(I$(Q))try{if((await V1(Q)).length===0)await HW(Q,{recursive:!0,force:!0})}catch{}}async _exists($){let W=this.toFilePath($);return I$(W)}async _list($){let W=[];if(!I$(this.baseDir))return W;let Q=(await V1(this.baseDir,{withFileTypes:!0})).filter((Z)=>Z.isDirectory()).map((Z)=>Z.name);for(let Z of Q){if($&&!Z.startsWith($.split("/")[0]))continue;let J=v$.join(this.baseDir,Z),Y=await this.listJsonFiles(J);for(let H of Y){let X=v$.basename(H,".json"),G=`${Z}/${X}`;if(!$||G.startsWith($))W.push(G)}}return W}toFilePath($){return v$.join(this.baseDir,`${$}.json`)}ensureDir($){if(!I$($))YW($,{recursive:!0})}async ensureDirAsync($){if(I$($))return;await Q8($,{recursive:!0})}async listJsonFiles($){if(!I$($))return[];return(await V1($)).filter((Q)=>Q.endsWith(".json")).map((Q)=>v$.join($,Q))}getBaseDir(){return this.baseDir}clear(){if(I$(this.baseDir))W8(this.baseDir,{recursive:!0}),YW(this.baseDir,{recursive:!0})}}class z0 extends C${store=new Map;constructor($){super($)}async _write($,W){this.store.set($,W)}async _read($){return this.store.get($)}async _delete($){this.store.delete($)}async _exists($){return this.store.has($)}async _list($){let W=[];for(let Q of this.store.keys())if($===""||Q.startsWith($))W.push(Q);return W}clear(){this.store.clear()}stats(){let $=new Set;for(let W of this.store.keys()){let Q=this.extractSessionId(W);if(Q)$.add(Q)}return{entryCount:this.store.size,sessionCount:$.size}}}class D${id;name;systemPrompt;createdAt;_model;_modelOverride;_tools;_stateStore;_sessionManager;_middlewares=[];_middlewareCounter=0;_middlewareTools=new Map;_enableLogging;_initializationPromise=null;_initialized=!1;constructor($){this.id=$.id??crypto.randomUUID(),this.name=$.name,this.systemPrompt=$.systemPrompt,this.createdAt=Date.now(),this._model=$.model,this._tools=$.tools,this._stateStore=$.stateStore??new z0,this._enableLogging=$.enableLogging??!1,this._sessionManager=new f0(this._stateStore),this._log(`Agent created: ${this.name} (id: ${this.id})`);let W=$.middleware??[];if(W.length>0)this._initializationPromise=this._initializeMiddleware(W)}async _initializeMiddleware($){for(let W of $)await this.use(W);this._initialized=!0}async _ensureInitialized(){if(this._initializationPromise&&!this._initialized)await this._initializationPromise}_log(...$){if(this._enableLogging)console.warn(`[GoatChain:Agent:${this.name}]`,...$)}get model(){return this._model}get modelId(){return this.modelRef?.modelId??this._model.modelId}get modelRef(){return this._modelOverride??this._model.modelRef}get tools(){return this._tools}get stateStore(){return this._stateStore}get sessionManager(){return this._sessionManager}async createSession($){if(await this._ensureInitialized(),!this._sessionManager)throw Error("SessionManager is not configured");let W=await this._sessionManager.create($?.sessionId);if(!this._stateStore)throw Error("StateStore is required to create sessions");this._log(`Creating new session: ${W.id}`);let Q=W.toSnapshot();return new e(this._stateStore,W.id,Q,{...$,modelClient:this._model,systemPrompt:this.systemPrompt,agentName:this.name,tools:this._tools,middlewares:this._middlewares.map((Z)=>Z.fn),emitSessionCreatedEvent:!0,enableLogging:this._enableLogging})}async resumeSession($,W){if(!this._sessionManager)throw Error("SessionManager is not configured");await this._ensureInitialized();let Q=await this._sessionManager.get($);if(!Q)throw Error(`Session not found: ${$}`);if(!this._stateStore)throw Error("StateStore is required to resume sessions");this._log(`Resuming session: ${$}`);let Z=Q.toSnapshot();return new e(this._stateStore,Q.id,Z,{...W,modelClient:this._model,systemPrompt:this.systemPrompt,agentName:this.name,tools:this._tools,middlewares:this._middlewares.map((J)=>J.fn),emitSessionCreatedEvent:!1,enableLogging:this._enableLogging})}async use($,W){let Q=W??$.__middlewareName??`middleware_${this._middlewareCounter++}`;if(this._middlewares.some((J)=>J.name===Q))throw Error(`Middleware with name "${Q}" already exists`);let Z={name:Q,fn:$};if(this._middlewares.push(Z),this._log(`Middleware registered: ${Q}`),$.__createTools&&typeof $.__createTools==="function")await this._registerMiddlewareTools(Q,$.__createTools);return()=>{this.removeMiddleware(Q)}}removeMiddleware($){let W=-1,Q;if(typeof $==="string")W=this._middlewares.findIndex((Z)=>Z.name===$),Q=$;else if(W=this._middlewares.findIndex((Z)=>Z.fn===$),W>-1)Q=this._middlewares[W].name;if(W>-1&&Q)return this._unregisterMiddlewareTools(Q),this._middlewares.splice(W,1),!0;return!1}clearMiddlewares(){for(let $ of this._middlewareTools.keys())this._unregisterMiddlewareTools($);this._middlewares=[]}get middlewares(){return[...this._middlewares]}get middlewareNames(){return this._middlewares.map(($)=>$.name)}setModel($){if(((Q)=>{return Boolean(Q&&typeof Q==="object"&&typeof Q.provider==="string"&&typeof Q.modelId==="string"&&typeof Q.stream!=="function")})($))this._modelOverride=$;else this._model=$,this._modelOverride=void 0}_getNamespacedToolName($,W){return`${$}_${W}`}async _registerMiddlewareTools($,W){if(!this._tools)return;let Q=await W(),Z=[];for(let J of Q){let Y=this._getNamespacedToolName($,J.name),H=Object.create(Object.getPrototypeOf(J));Object.assign(H,J),Object.defineProperty(H,"name",{value:Y,writable:!1,configurable:!0});try{this._tools.register(H),Z.push(Y)}catch(X){console.warn(`Failed to register tool ${Y}:`,X)}}if(Z.length>0)this._middlewareTools.set($,Z)}_unregisterMiddlewareTools($){if(!this._tools)return;let W=this._middlewareTools.get($);if(!W)return;for(let Q of W)this._tools.unregister(Q);this._middlewareTools.delete($)}}import{execSync as p}from"node:child_process";import{unlinkSync as Y8,writeFileSync as H8}from"node:fs";import{tmpdir as X8}from"node:os";import{join as V8}from"node:path";function G1($){try{return p("git rev-parse --git-dir",{cwd:$,stdio:"pipe"}),!0}catch{return!1}}function XW($){try{return p("git add --all",{cwd:$,encoding:"utf-8",stdio:"pipe"}),p("git diff --staged --name-only",{cwd:$,encoding:"utf-8",stdio:"pipe"}).trim().split(`
|
|
41
|
+
`).filter(Boolean)}catch{return[]}}function k0($){try{return p("git diff --staged",{cwd:$,encoding:"utf-8",stdio:"pipe"})}catch{return""}}function VW($){try{return p("git diff",{cwd:$,encoding:"utf-8",stdio:"pipe"})}catch{return""}}function _0($){try{return p("git diff --staged --name-only",{cwd:$,encoding:"utf-8",stdio:"pipe"}).trim().length>0}catch{return!1}}function h0($){try{let W=p("git diff --staged --name-status",{cwd:$,encoding:"utf-8",stdio:"pipe"});if(!W.trim())return[];return W.trim().split(`
|
|
42
|
+
`).filter(Boolean).map((Q)=>{let Z=Q.split("\t"),J=Z[0].charAt(0);if(J==="R"||J==="C")return{file:Z[2],status:J,oldFile:Z[1]};return{file:Z[1],status:J}})}catch{return[]}}function B0($){try{if(p("git diff --name-only",{cwd:$,encoding:"utf-8",stdio:"pipe"}).trim().length>0)return!0;return p("git ls-files --others --exclude-standard",{cwd:$,encoding:"utf-8",stdio:"pipe"}).trim().length>0}catch{return!1}}function GW($,W){try{let Q=V8(X8(),`goatchain-commit-${Date.now()}.txt`);H8(Q,$,"utf-8");try{return p(`git commit -F "${Q}"`,{cwd:W,stdio:"pipe"}),p("git rev-parse HEAD",{cwd:W,encoding:"utf-8",stdio:"pipe"}).trim()}finally{try{Y8(Q)}catch{}}}catch{return""}}function K1($){try{let W=p("git rev-parse --abbrev-ref HEAD",{cwd:$,encoding:"utf-8",stdio:"pipe"}).trim();return W==="HEAD"?null:W}catch{return null}}function G8($,W="origin"){try{return p("git remote",{cwd:$,encoding:"utf-8",stdio:"pipe"}).split(`
|
|
43
|
+
`).map((Z)=>Z.trim()).includes(W)}catch{return!1}}function K8($){try{return p("git rev-parse --abbrev-ref --symbolic-full-name @{u}",{cwd:$,encoding:"utf-8",stdio:"pipe"}).trim()||null}catch{return null}}function KW($,W="origin"){try{return p(`git fetch ${W}`,{cwd:$,stdio:"pipe"}),!0}catch{return!1}}function j8($){try{let W=p("git rev-list --left-right --count @{u}...HEAD",{cwd:$,encoding:"utf-8",stdio:"pipe"}).trim(),[Q,Z]=W.split(/\s+/).map((J)=>Number.parseInt(J,10));return{ahead:Z||0,behind:Q||0,hasUpstream:!0}}catch{return{ahead:0,behind:0,hasUpstream:!1}}}function z8($){try{let W=p("git status --porcelain",{cwd:$,encoding:"utf-8",stdio:"pipe"});return/^(?:UU|AA|DD|AU|UA|DU|UD)\s/m.test(W)}catch{return!1}}function _8($){try{let W=p("git status --porcelain",{cwd:$,encoding:"utf-8",stdio:"pipe"}),Q=[],Z=W.split(`
|
|
44
|
+
`);for(let J of Z){let Y=J.match(/^(?:UU|AA|DD|AU|UA|DU|UD)\s+(\S.*)$/);if(Y)Q.push(Y[1].trim())}return Q}catch{return[]}}function B8($){try{try{return p("git rev-parse --verify MERGE_HEAD",{cwd:$,stdio:"pipe"}),{inMerge:!0,type:"merge"}}catch{}try{return p("test -d .git/rebase-merge -o -d .git/rebase-apply",{cwd:$,stdio:"pipe"}),{inMerge:!0,type:"rebase"}}catch{}try{return p("git rev-parse --verify CHERRY_PICK_HEAD",{cwd:$,stdio:"pipe"}),{inMerge:!0,type:"cherry-pick"}}catch{}return{inMerge:!1,type:null}}catch{return{inMerge:!1,type:null}}}function U0($){let W={canCommit:!0,isGitRepo:!1,hasChanges:!1,hasConflicts:!1,conflictFiles:[],inMergeState:!1,mergeStateType:null,hasRemote:!1,hasUpstream:!1,ahead:0,behind:0,isDiverged:!1,currentBranch:null,warnings:[],errors:[]};if(W.isGitRepo=G1($),!W.isGitRepo)return W.canCommit=!1,W.errors.push("Not a git repository"),W;if(W.currentBranch=K1($),!W.currentBranch)W.warnings.push("Detached HEAD state - no branch checked out");let Q=B8($);if(W.inMergeState=Q.inMerge,W.mergeStateType=Q.type,W.inMergeState)W.warnings.push(`Currently in ${W.mergeStateType} state`);if(W.hasConflicts=z8($),W.hasConflicts)W.conflictFiles=_8($),W.canCommit=!1,W.errors.push(`Unresolved conflicts in ${W.conflictFiles.length} file(s): ${W.conflictFiles.join(", ")}`);if(W.hasChanges=B0($)||_0($),!W.hasChanges&&!W.inMergeState)W.canCommit=!1,W.errors.push("No changes to commit");if(W.hasRemote=G8($),W.hasRemote){let Z=K8($);if(W.hasUpstream=!!Z,W.hasUpstream){let J=j8($);if(W.ahead=J.ahead,W.behind=J.behind,W.isDiverged=W.ahead>0&&W.behind>0,W.behind>0)W.warnings.push(`Local branch is ${W.behind} commit(s) behind remote`);if(W.isDiverged)W.warnings.push(`Branch has diverged: ${W.ahead} ahead, ${W.behind} behind`)}else W.warnings.push("No upstream branch configured")}return W}var U8="You are a commit message generator. You print plain text without code blocks and don't talk.";function O8($,W,Q){if(Q)return Q.replace("[DIFF_CONTENT]",$).replace("[LANGUAGE]",W);return`Analyze the following staged diffs and craft a conventional commit message in ${W}.
|
|
45
45
|
|
|
46
46
|
Staged Diffs:
|
|
47
47
|
\`\`\`diff
|
|
@@ -65,56 +65,61 @@ Fixed (if applicable):
|
|
|
65
65
|
- [Bug fixes]
|
|
66
66
|
|
|
67
67
|
Security (if applicable):
|
|
68
|
-
- [Security improvements]`}function
|
|
69
|
-
`)}function
|
|
70
|
-
`)}function
|
|
68
|
+
- [Security improvements]`}function j1($){let W=[];if($.errors.length>0)W.push("❌ 错误 (Errors):"),$.errors.forEach((Q)=>W.push(` • ${Q}`));if($.warnings.length>0)W.push("⚠️ 警告 (Warnings):"),$.warnings.forEach((Q)=>W.push(` • ${Q}`));if($.conflictFiles.length>0)W.push(""),W.push("\uD83D\uDD00 冲突文件 (Conflict files):"),$.conflictFiles.forEach((Q)=>W.push(` • ${Q}`));if($.inMergeState)W.push(""),W.push(`\uD83D\uDCCC 当前状态: 正在进行 ${$.mergeStateType}`);if($.hasUpstream&&($.ahead>0||$.behind>0)){if(W.push(""),W.push("\uD83D\uDCCA 分支状态:"),$.ahead>0)W.push(` • 领先远程 ${$.ahead} 个提交`);if($.behind>0)W.push(` • 落后远程 ${$.behind} 个提交`)}return W.join(`
|
|
69
|
+
`)}function jW($){switch($){case"A":return"新增 (new file)";case"M":return"修改 (modified)";case"D":return"删除 (deleted)";case"R":return"重命名 (renamed)";case"C":return"复制 (copied)";case"T":return"类型变更 (typechange)";case"U":return"未合并 (unmerged)";default:return $}}function F8($){if($.length===0)return"";let W=["\uD83D\uDCCB Changes to be committed (待提交的更改):",""],Q={};for(let J of $){let Y=J.status;if(!Q[Y])Q[Y]=[];Q[Y].push(J)}let Z=["A","M","D","R","C","T","U"];for(let J of Z){let Y=Q[J];if(!Y||Y.length===0)continue;W.push(` ${jW(J)}:`);for(let H of Y)if(H.oldFile)W.push(` • ${H.oldFile} → ${H.file}`);else W.push(` • ${H.file}`);W.push("")}for(let[J,Y]of Object.entries(Q)){if(Z.includes(J))continue;W.push(` ${jW(J)}:`);for(let H of Y)W.push(` • ${H.file}`);W.push("")}return W.push(` 共 ${$.length} 个文件 (Total: ${$.length} files)`),W.join(`
|
|
70
|
+
`)}function z1($){let W=$.name??"commit-mode",Q=$.model,Z=$.defaultLanguage??"English",J=$.defaultAutoStage??!0,Y=$.fetchBeforeCommit??!1,H=$.allowBehindRemote??!1,X=$.cwd??process.cwd(),G=$.customPrompt,V=async(K,z)=>{if(K.metadata?.commitProcessed)return z(K);try{let j=U0(X);if(!j.isGitRepo){let L={role:"assistant",content:`✗ 错误:当前目录不是 git 仓库。
|
|
71
71
|
|
|
72
|
-
Error: Not in a git repository. Please run this from within a git repository.`};return{...K,messages:[...K.messages,L],currentResponse:L.content,shouldContinue:!1,stopReason:"final_response",metadata:{...K.metadata,commitProcessed:!0,preCommitCheck:j}}}let
|
|
72
|
+
Error: Not in a git repository. Please run this from within a git repository.`};return{...K,messages:[...K.messages,L],currentResponse:L.content,shouldContinue:!1,stopReason:"final_response",metadata:{...K.metadata,commitProcessed:!0,preCommitCheck:j}}}let _={fetched:!1,message:""};if(Y&&j.hasRemote)if(KW(X)){_={fetched:!0,message:"已从远程获取最新更新"};let y=U0(X);Object.assign(j,{ahead:y.ahead,behind:y.behind,isDiverged:y.isDiverged})}else _={fetched:!1,message:"无法从远程获取更新(网络问题或无权限)"};if(j.hasConflicts){let L={role:"assistant",content:`✗ 存在未解决的冲突,无法提交。
|
|
73
73
|
|
|
74
74
|
❌ Cannot commit: Unresolved conflicts detected.
|
|
75
75
|
|
|
76
|
-
${
|
|
76
|
+
${j1(j)}
|
|
77
77
|
|
|
78
78
|
请先解决以上冲突文件,然后再次尝试提交。
|
|
79
79
|
Please resolve the conflicts above before committing.`};return{...K,messages:[...K.messages,L],currentResponse:L.content,shouldContinue:!1,stopReason:"final_response",metadata:{...K.metadata,commitProcessed:!0,preCommitCheck:j,hasConflicts:!0}}}if(j.inMergeState&&!j.hasChanges){let L={role:"assistant",content:`✗ 当前正在进行 ${j.mergeStateType},但没有暂存的更改。
|
|
80
80
|
|
|
81
81
|
❌ Currently in ${j.mergeStateType} state but no staged changes.
|
|
82
82
|
|
|
83
|
-
${
|
|
83
|
+
${j1(j)}
|
|
84
84
|
|
|
85
85
|
请先完成或取消当前的 ${j.mergeStateType} 操作。
|
|
86
86
|
Please complete or abort the current ${j.mergeStateType} operation.`};return{...K,messages:[...K.messages,L],currentResponse:L.content,shouldContinue:!1,stopReason:"final_response",metadata:{...K.metadata,commitProcessed:!0,preCommitCheck:j}}}if(!H&&j.behind>0){let L={role:"assistant",content:`⚠️ 本地分支落后于远程 ${j.behind} 个提交。
|
|
87
87
|
|
|
88
88
|
⚠️ Local branch is ${j.behind} commit(s) behind remote.
|
|
89
89
|
|
|
90
|
-
${
|
|
90
|
+
${j1(j)}
|
|
91
91
|
|
|
92
92
|
建议先执行 git pull 拉取最新更改,解决可能的冲突后再提交。
|
|
93
93
|
Recommend running 'git pull' first to get latest changes and resolve any conflicts before committing.
|
|
94
94
|
|
|
95
|
-
如需强制提交,请使用 allowBehindRemote: true 选项。`};return{...K,messages:[...K.messages,L],currentResponse:L.content,shouldContinue:!1,stopReason:"final_response",metadata:{...K.metadata,commitProcessed:!0,preCommitCheck:j,isBehindRemote:!0}}}if(J){if(
|
|
95
|
+
如需强制提交,请使用 allowBehindRemote: true 选项。`};return{...K,messages:[...K.messages,L],currentResponse:L.content,shouldContinue:!1,stopReason:"final_response",metadata:{...K.metadata,commitProcessed:!0,preCommitCheck:j,isBehindRemote:!0}}}if(J){if(B0(X))XW(X);else if(!_0(X)&&!j.inMergeState){let L={role:"assistant",content:`✗ 没有需要提交的更改。
|
|
96
96
|
|
|
97
|
-
No changes to commit. Working directory is clean.`};return{...K,messages:[...K.messages,L],currentResponse:L.content,shouldContinue:!1,stopReason:"final_response",metadata:{...K.metadata,commitProcessed:!0,preCommitCheck:j}}}}let
|
|
97
|
+
No changes to commit. Working directory is clean.`};return{...K,messages:[...K.messages,L],currentResponse:L.content,shouldContinue:!1,stopReason:"final_response",metadata:{...K.metadata,commitProcessed:!0,preCommitCheck:j}}}}let B=h0(X),F=k0(X);if(!F||F.trim().length===0){let L={role:"assistant",content:`✗ 没有暂存的更改。
|
|
98
98
|
|
|
99
|
-
No staged changes to commit. Please stage files first or enable auto_stage.`};return{...K,messages:[...K.messages,L],currentResponse:L.content,shouldContinue:!1,stopReason:"final_response",metadata:{...K.metadata,commitProcessed:!0,preCommitCheck:j}}}if(!Q.run)throw Error("Model does not support run() method");let
|
|
99
|
+
No staged changes to commit. Please stage files first or enable auto_stage.`};return{...K,messages:[...K.messages,L],currentResponse:L.content,shouldContinue:!1,stopReason:"final_response",metadata:{...K.metadata,commitProcessed:!0,preCommitCheck:j}}}if(!Q.run)throw Error("Model does not support run() method");let A=O8(F,Z,G),N=[{role:"system",content:U8},{role:"user",content:A}],R=(await Q.run({messages:N})).text.trim();if(!R)throw Error("LLM returned empty commit message");let q=GW(R,X),D=F8(B),O=_.fetched?`
|
|
100
100
|
|
|
101
|
-
\uD83D\uDCE1 ${
|
|
101
|
+
\uD83D\uDCE1 ${_.message}`:"",T=j.warnings.length>0?`
|
|
102
102
|
|
|
103
103
|
⚠️ 注意事项:
|
|
104
104
|
${j.warnings.map((L)=>` • ${L}`).join(`
|
|
105
|
-
`)}`:"",
|
|
106
|
-
分支: ${j.currentBranch}`:"",
|
|
105
|
+
`)}`:"",S=j.currentBranch?`
|
|
106
|
+
分支: ${j.currentBranch}`:"",f={role:"assistant",content:`✓ 成功创建 commit
|
|
107
107
|
|
|
108
|
-
Commit Hash: ${
|
|
108
|
+
Commit Hash: ${q}${S}${O}${T}
|
|
109
109
|
|
|
110
|
-
${
|
|
110
|
+
${D}
|
|
111
111
|
|
|
112
112
|
Commit Message:
|
|
113
|
-
${
|
|
113
|
+
${R}`};return{...K,messages:[...K.messages,f],currentResponse:f.content,shouldContinue:!1,stopReason:"final_response",metadata:{...K.metadata,commitProcessed:!0,commitHash:q,commitMessage:R,preCommitCheck:j}}}catch(j){let _={role:"assistant",content:`✗ 创建 commit 失败
|
|
114
114
|
|
|
115
|
-
Error: ${j instanceof Error?j.message:String(j)}`};return{...K,messages:[...K.messages,
|
|
115
|
+
Error: ${j instanceof Error?j.message:String(j)}`};return{...K,messages:[...K.messages,_],currentResponse:_.content,shouldContinue:!1,stopReason:"error",metadata:{...K.metadata,commitProcessed:!0}}}};return V.__middlewareName=W,V}class c${policy;constructor($){this.policy=$}getAccessMode($){return this.policy.overrides?.[$]??this.policy.defaultMode}getBlockedTools(){let $=[];if(this.policy.overrides){for(let[W,Q]of Object.entries(this.policy.overrides))if(Q==="blocked")$.push(W)}return $}getRestrictedTools(){let $=[];if(this.policy.overrides){for(let[W,Q]of Object.entries(this.policy.overrides))if(Q==="restricted")$.push(W)}return $}isBlocked($){return this.getAccessMode($)==="blocked"}isRestricted($){return this.getAccessMode($)==="restricted"}hasFullAccess($){return this.getAccessMode($)==="full"}}var _1={defaultMode:"full",overrides:{Write:"blocked",Edit:"blocked",ast_grep_replace:"blocked",TodoWrite:"blocked",Bash:"restricted",Task:"restricted",Read:"full",Glob:"full",Grep:"full",WebSearch:"full",WebFetch:"full",AskUserQuestion:"full",TodoPlan:"full",EnterPlanMode:"full",ExitPlanMode:"full",ast_grep_search:"full",LSP:"full"}},B1={defaultMode:"blocked",overrides:{Glob:"full",Grep:"full",Read:"full",Bash:"restricted"}},U1={defaultMode:"full",overrides:{Task:"blocked"}};var O1=["ls","find","file","stat","tree","du","df","wc","cat","head","tail","less","more","grep","awk","sed","sort","uniq","cut","tr","xargs","git status","git log","git diff","git show","git branch","git remote","git tag","git blame","git rev-parse","git ls-files","git ls-tree","pwd","which","whereis","type","echo","printf","date","env","printenv"],g0=[/\bmkdir\b/,/\btouch\b/,/\brm\b/,/\brmdir\b/,/\bcp\b/,/\bmv\b/,/\bchmod\b/,/\bchown\b/,/\bln\b/,/\binstall\b/,/\bgit\s+(add|commit|push|pull|fetch|merge|rebase|reset|checkout|stash|cherry-pick|revert|clean)\b/,/\bgit\s+branch\s+-[dDmM]/,/\b(npm|yarn|pnpm)\s+(install|add|remove|uninstall|update|upgrade|publish|init)\b/,/\bpip\s+(install|uninstall)\b/,/\bbun\s+(add|remove|install)\b/,/\bcargo\s+(install|build|publish)\b/,/\bgo\s+(install|get|build)\b/,/>\s*[^|&]/,/>>/,/\btee\b/,/\bsudo\b/,/\bsu\b/,/\bkill\b/,/\bpkill\b/,/\bkillall\b/,/\bshutdown\b/,/\breboot\b/,/\bsource\b/,/\b\.\s+\//,/\bcurl\b.*-[oO]/,/\bwget\b/,/\bsed\s+(-[a-zA-Z]*i|-i[a-zA-Z]*)\b/,/\bawk\s+(-[a-zA-Z]*i|-i[a-zA-Z]*)\b/,/\bperl\s+-[a-zA-Z]*[pi][a-zA-Z]*\b/,/\bpython[23]?\s+-c\b/,/\bnode\s+-e\b/,/\bruby\s+-e\b/,/\beval\s+/,/\bexec\s+/];function R$($){let W=$.trim();if(!W)return{isAllowed:!1,reason:"Empty command"};for(let Q of g0)if(Q.test(W)){let Z=W.match(Q),J=Z?Z[0]:Q.source,Y=`Command contains forbidden pattern: ${J}`;if(/>\s*[^|&]|>>/.test(W))Y="Command contains redirect operator that writes to files";else if(/\bgit\s+(add|commit|push)/.test(W))Y="Git write operations are not allowed in read-only mode";else if(/\b(npm|yarn|pnpm|pip|bun)\s+(install|add)/.test(W))Y="Package installation is not allowed in read-only mode";else if(/\b(rm|rmdir|mkdir|touch|cp|mv)\b/.test(W))Y="File modification commands are not allowed in read-only mode";else if(/\b(sed|awk|perl)\s+.*-[a-zA-Z]*i/.test(W))Y="In-place editing commands are not allowed in read-only mode";else if(/\b(python|node|ruby)\s+-[ec]\b/.test(W))Y="Code execution via interpreter is not allowed in read-only mode";else if(/\b(eval|exec)\s+/.test(W))Y="Shell eval/exec commands are not allowed in read-only mode";return{isAllowed:!1,reason:Y,matchedPattern:J}}return{isAllowed:!0}}function F1($){let W=R$($);if(!W.isAllowed)throw Error(`Bash command rejected: ${W.reason}`)}function zW($){return{content:[{type:"text",text:$}]}}function I($){return{content:[{type:"text",text:$}],isError:!0}}function _W($,W){return{content:[{type:"image",data:$,mimeType:W}]}}class k{riskLevel="safe"}class O0 extends k{name="Task";description;parameters={type:"object",properties:{description:{type:"string",description:"A short (3-5 word) description of the task"},prompt:{type:"string",description:"The task for the agent to perform"},subagent_type:{type:"string",description:"The type of specialized agent to use for this task"},resume:{type:"string",description:"Optional subagent ID to resume from. If provided, the subagent will continue from the previous execution."},run_in_background:{type:"boolean",description:"Set to true to run this agent in the background. Use TaskOutput to read the output later."}},required:["description","prompt","subagent_type"]};subagents;executor;constructor($){super();if(this.subagents=new Map,this.executor=$?.executor,$?.subagents)for(let W of $.subagents)this.subagents.set(W.name,W);this.description=this.buildDescription()}registerSubagent($){this.subagents.set($.name,$)}unregisterSubagent($){return this.subagents.delete($)}getSubagents(){return Array.from(this.subagents.values())}hasSubagent($){return this.subagents.has($)}setExecutor($){this.executor=$}async execute($,W){let Q=this.validateArgs($);if(W.metadata?.planMode===!0){if(Q.subagent_type!=="Explore")return I(`[PLAN MODE] Only 'Explore' subagent is allowed in Plan Mode.
|
|
116
116
|
|
|
117
|
-
|
|
117
|
+
Requested: ${Q.subagent_type}
|
|
118
|
+
Allowed: Explore
|
|
119
|
+
|
|
120
|
+
Plan Mode is read-only. Use 'Explore' agent for codebase exploration, or exit Plan Mode first to use other subagents.`)}if(!this.subagents.has(Q.subagent_type)){let Z=Array.from(this.subagents.keys()).join(", ");return I(`Subagent type "${Q.subagent_type}" not found. Available types: ${Z||"none"}`)}if(!this.executor)return I("Task executor is not configured. Please set an executor using setExecutor().");try{let{subagentId:Z,data:J}=await this.executor(Q,W),Y={success:!0,subagentId:Z,subagentType:Q.subagent_type,description:Q.description,background:Q.run_in_background??!1,data:J},H=Y.background?" (running in background)":"",X=`Task "${Q.description}" started with subagent ${Z}${H}`,G=Y.background?null:this.formatTaskData(J);return{content:[{type:"text",text:`Result:${X}
|
|
121
|
+
|
|
122
|
+
${G}`}],structuredContent:Y}}catch(Z){return I(`Task execution failed: ${Z instanceof Error?Z.message:String(Z)}`)}}validateArgs($){let{description:W,prompt:Q,subagent_type:Z}=$;if(typeof W!=="string"||!W.trim())throw Error("description is required and must be a non-empty string");if(typeof Q!=="string"||!Q.trim())throw Error("prompt is required and must be a non-empty string");if(typeof Z!=="string"||!Z.trim())throw Error("subagent_type is required and must be a non-empty string");let J={description:W.trim(),prompt:Q.trim(),subagent_type:Z.trim()};if($.resume!==void 0&&$.resume!==null&&$.resume!==""){if(typeof $.resume!=="string")throw TypeError("resume must be a string");J.resume=$.resume.trim()}if($.run_in_background!==void 0&&$.run_in_background!==null)J.run_in_background=Boolean($.run_in_background);return J}formatTaskData($){if($===void 0||$===null)return null;if(typeof $==="string"){let W=$.trim();return W.length>0?W:null}if(typeof $==="number"||typeof $==="boolean")return String($);try{let W=JSON.stringify($,null,2);return W===void 0?null:W}catch{return String($)}}buildDescription(){return`Launch a new agent to handle complex, multi-step tasks autonomously.
|
|
118
123
|
|
|
119
124
|
<available_agents>
|
|
120
125
|
${this.buildAgentsList()||"No subagent types registered."}
|
|
@@ -138,12 +143,12 @@ Usage notes:
|
|
|
138
143
|
4. The agent's outputs should generally be trusted
|
|
139
144
|
5. Clearly tell the agent whether you expect it to write code or just to do research (search, file reads, web fetches, etc.), since it is not aware of the user's intent
|
|
140
145
|
6. If the agent description mentions that it should be used proactively, then you should try your best to use it without the user having to ask for it first. Use your judgement.
|
|
141
|
-
7. Use "run_in_background: true" to run agents in background. Use TaskOutput to read the output later.`}buildAgentsList(){if(this.subagents.size===0)return"";return Array.from(this.subagents.values()).map(($)=>{let W=`- ${$.name}: ${$.description}
|
|
142
|
-
`)}}function
|
|
146
|
+
7. Use "run_in_background: true" to run agents in background. Use TaskOutput to read the output later.`}buildAgentsList(){if(this.subagents.size===0)return"";return Array.from(this.subagents.values()).map(($)=>{let W=`- ${$.name}: ${$.description}`,Q=$.accessPolicy.overrides||{},Z=[];for(let[J,Y]of Object.entries(Q))if(Y==="full")Z.push(J);else if(Y==="restricted")Z.push(`${J}[restricted]`);if($.accessPolicy.defaultMode==="full"){let J=Object.entries(Q).filter(([Y,H])=>H==="blocked").map(([Y])=>Y);if(J.length>0)W+=` (Tools: All except ${J.join(", ")})`;else W+=" (Tools: All)"}else if(Z.length>0)W+=` (Tools: ${Z.join(", ")})`;return W}).join(`
|
|
147
|
+
`)}}function q1($){let{subagents:W,executor:Q,globalToolRegistry:Z,model:J,name:Y="parallel-subagent"}=$,H=new Set(["tool_call_end","tool_result","tool_skipped"]);if(!Q&&(!Z||!J))throw Error('createParallelSubagentMiddleware: either provide "executor" or both "globalToolRegistry" and "model"');let X=Q||(async(V,K)=>{let z=W.find((R)=>R.name===V.subagent_type);if(!z)throw Error(`Unknown subagent type: ${V.subagent_type}`);let j=new c$(z.accessPolicy),_=new Z.constructor;for(let R of Z.list()){if(j.getAccessMode(R.name)==="blocked"){if($.debug)console.warn(`[${Y}] Blocking tool "${R.name}" for subagent "${V.subagent_type}"`);continue}if(R instanceof O0){if($.debug)console.warn(`[${Y}] Skipping TaskTool "${R.name}" for subagent "${V.subagent_type}" to prevent infinite recursion`);continue}_.register(R)}let B={readOnlyBash:j.getAccessMode("Bash")==="restricted"},F=async(R,q)=>{if(R.iteration===0)return q({...R,metadata:{...B,...R.metadata}});return q(R)},A=new D$({name:V.subagent_type,systemPrompt:`${z.systemPrompt||""}
|
|
143
148
|
|
|
144
149
|
Your task: ${V.prompt}
|
|
145
150
|
|
|
146
|
-
Provide a concise summary of your findings.`,model:J,tools:
|
|
151
|
+
Provide a concise summary of your findings.`,model:J,tools:_});if(A.use(F,"metadata-init"),A.use(m$({maxTokens:128000,protectedTurns:1,model:J,stateStore:A.stateStore,toolCompressionTarget:0.3,minKeepToolResults:5})),$.debug)console.warn(`[${Y}] Created subagent "${V.subagent_type}" with readOnlyBash=${B.readOnlyBash}`);let N=await A.createSession({sessionId:K?.sessionId});N.send(V.prompt);let U="";for await(let R of N.receive()){if(K?.emitEvent&&H.has(R.type)){let{sessionId:q,...D}=R;K.emitEvent({type:"subagent_event",subagentId:A.id,subagentType:V.subagent_type,taskDescription:V.description,nestedEvent:D})}if(R.type==="done")U=R.finalResponse||""}return{subagentId:A.id,data:U}}),G=async(V,K)=>{return K({...V,metadata:{...V.metadata,parallelMode:!0,parallelSubagentMiddleware:Y}})};return G.__middlewareName=Y,G.__createTools=()=>{return[new O0({subagents:W,executor:X})]},G}class d$ extends k{name="AskUserQuestion";riskLevel="safe";description=`Use this tool when you need to ask the user questions during execution. This allows you to:
|
|
147
152
|
1. Gather user preferences or requirements
|
|
148
153
|
2. Clarify ambiguous instructions
|
|
149
154
|
3. Get decisions on implementation choices as you work
|
|
@@ -152,7 +157,7 @@ Provide a concise summary of your findings.`,model:J,tools:B});U.use(u$({maxToke
|
|
|
152
157
|
Usage notes:
|
|
153
158
|
- Users will always be able to select "Other" to provide custom text input
|
|
154
159
|
- Use multiSelect: true to allow multiple answers to be selected for a question
|
|
155
|
-
- If you recommend a specific option, make that the first option in the list and add "(Recommended)" at the end of the label`;parameters={type:"object",properties:{questions:{type:"array",items:{type:"object",properties:{question:{type:"string",description:'The complete question to ask the user. Should be clear, specific, and end with a question mark. Example: "Which library should we use for date formatting?" If multiSelect is true, phrase it accordingly, e.g. "Which features do you want to enable?"'},header:{type:"string",maxLength:12,description:'Very short label displayed as a chip/tag (max 12 chars). Examples: "Auth method", "Library", "Approach".'},options:{type:"array",items:{type:"object",properties:{label:{type:"string",description:"The display text for this option that the user will see and select. Should be concise (1-5 words) and clearly describe the choice."},description:{type:"string",description:"Explanation of what this option means or what will happen if chosen. Useful for providing context about trade-offs or implications."}},required:["label","description"]},minItems:2,maxItems:4,description:"The available choices for this question. Must have 2-4 options. Each option should be a distinct, mutually exclusive choice (unless multiSelect is enabled). There should be no 'Other' option, that will be provided automatically."},multiSelect:{type:"boolean",description:"Set to true to allow the user to select multiple options instead of just one. Use when choices are not mutually exclusive."}},required:["question","header","options","multiSelect"]},minItems:1,maxItems:4,description:"Questions to ask the user (1-4 questions)"},answers:{type:"object",additionalProperties:{oneOf:[{type:"string"},{type:"array",items:{type:"string"}}]},description:"User answers collected by the permission component"}},required:["questions"]};async execute($,W){let{questions:Q,answers:Z}=this.validateArgs($);if(!Z||Object.keys(Z).length===0)throw Error("AskUserTool.execute() was called without answers. This indicates a bug: Session should have intercepted this tool call and emitted a requires_action event. The tool should only be executed after the user provides answers via toolContext.");let J=this.formatAnswersMessage(Q,Z);return{content:[{type:"text",text:J}],structuredContent:{success:!0,answers:Z,message:J}}}validateArgs($){let W=$.questions;if(!Array.isArray(W))throw TypeError("questions is required and must be an array");if(W.length<1||W.length>4)throw Error("questions must contain 1-4 items");let Q=[];for(let J=0;J<W.length;J++){let Y=W[J];if(typeof Y!=="object"||Y===null)throw TypeError(`questions[${J}] must be an object`);let{question:H,header:X,options:G,multiSelect:V}=Y;if(typeof H!=="string"||!H.trim())throw Error(`questions[${J}].question is required and must be a non-empty string`);if(typeof X!=="string"||!X.trim())throw Error(`questions[${J}].header is required and must be a non-empty string`);if(X.length>12)throw Error(`questions[${J}].header must be at most 12 characters`);if(!Array.isArray(G))throw TypeError(`questions[${J}].options must be an array`);if(G.length<2||G.length>4)throw Error(`questions[${J}].options must contain 2-4 items`);if(typeof V!=="boolean")throw TypeError(`questions[${J}].multiSelect is required and must be a boolean`);let K=[];for(let z=0;z<G.length;z++){let j=G[z];if(typeof j!=="object"||j===null)throw TypeError(`questions[${J}].options[${z}] must be an object`);let{label:
|
|
160
|
+
- If you recommend a specific option, make that the first option in the list and add "(Recommended)" at the end of the label`;parameters={type:"object",properties:{questions:{type:"array",items:{type:"object",properties:{question:{type:"string",description:'The complete question to ask the user. Should be clear, specific, and end with a question mark. Example: "Which library should we use for date formatting?" If multiSelect is true, phrase it accordingly, e.g. "Which features do you want to enable?"'},header:{type:"string",maxLength:12,description:'Very short label displayed as a chip/tag (max 12 chars). Examples: "Auth method", "Library", "Approach".'},options:{type:"array",items:{type:"object",properties:{label:{type:"string",description:"The display text for this option that the user will see and select. Should be concise (1-5 words) and clearly describe the choice."},description:{type:"string",description:"Explanation of what this option means or what will happen if chosen. Useful for providing context about trade-offs or implications."}},required:["label","description"]},minItems:2,maxItems:4,description:"The available choices for this question. Must have 2-4 options. Each option should be a distinct, mutually exclusive choice (unless multiSelect is enabled). There should be no 'Other' option, that will be provided automatically."},multiSelect:{type:"boolean",description:"Set to true to allow the user to select multiple options instead of just one. Use when choices are not mutually exclusive."}},required:["question","header","options","multiSelect"]},minItems:1,maxItems:4,description:"Questions to ask the user (1-4 questions)"},answers:{type:"object",additionalProperties:{oneOf:[{type:"string"},{type:"array",items:{type:"string"}}]},description:"User answers collected by the permission component"}},required:["questions"]};async execute($,W){let{questions:Q,answers:Z}=this.validateArgs($);if(!Z||Object.keys(Z).length===0)throw Error("AskUserTool.execute() was called without answers. This indicates a bug: Session should have intercepted this tool call and emitted a requires_action event. The tool should only be executed after the user provides answers via toolContext.");let J=this.formatAnswersMessage(Q,Z);return{content:[{type:"text",text:J}],structuredContent:{success:!0,answers:Z,message:J}}}validateArgs($){let W=$.questions;if(!Array.isArray(W))throw TypeError("questions is required and must be an array");if(W.length<1||W.length>4)throw Error("questions must contain 1-4 items");let Q=[];for(let J=0;J<W.length;J++){let Y=W[J];if(typeof Y!=="object"||Y===null)throw TypeError(`questions[${J}] must be an object`);let{question:H,header:X,options:G,multiSelect:V}=Y;if(typeof H!=="string"||!H.trim())throw Error(`questions[${J}].question is required and must be a non-empty string`);if(typeof X!=="string"||!X.trim())throw Error(`questions[${J}].header is required and must be a non-empty string`);if(X.length>12)throw Error(`questions[${J}].header must be at most 12 characters`);if(!Array.isArray(G))throw TypeError(`questions[${J}].options must be an array`);if(G.length<2||G.length>4)throw Error(`questions[${J}].options must contain 2-4 items`);if(typeof V!=="boolean")throw TypeError(`questions[${J}].multiSelect is required and must be a boolean`);let K=[];for(let z=0;z<G.length;z++){let j=G[z];if(typeof j!=="object"||j===null)throw TypeError(`questions[${J}].options[${z}] must be an object`);let{label:_,description:B}=j;if(typeof _!=="string"||!_.trim())throw Error(`questions[${J}].options[${z}].label is required and must be a non-empty string`);if(typeof B!=="string"||!B.trim())throw Error(`questions[${J}].options[${z}].description is required and must be a non-empty string`);K.push({label:_.trim(),description:B.trim()})}Q.push({question:H.trim(),header:X.trim(),options:K,multiSelect:Boolean(V)})}let Z;if($.answers&&typeof $.answers==="object"&&$.answers!==null){Z={};for(let[J,Y]of Object.entries($.answers))if(typeof Y==="string")Z[J]=Y;else if(Array.isArray(Y))Z[J]=Y.map((H)=>String(H));else Z[J]=String(Y)}return{questions:Q,answers:Z}}formatAnswersMessage($,W){let Q=[];for(let Z=0;Z<$.length;Z++){let J=$[Z],Y=W[String(Z)];if(Y===void 0)continue;Q.push(`Question ${Z+1} (${J.header}): ${J.question}`);let H=this.formatAnswerText(Y);if(H.inline!==void 0)Q.push(`Answer: ${H.inline}`);else if(H.lines){Q.push("Answer:");for(let X of H.lines)Q.push(` ${X}`)}Q.push("")}if(Q.length===0)return"No answers received";if(Q[Q.length-1]==="")Q.pop();return`User responses:
|
|
156
161
|
|
|
157
162
|
${Q.join(`
|
|
158
163
|
`)}`}formatAnswerText($){if(Array.isArray($)){if($.length===0)return{inline:"(no response)"};if($.length===1){let Q=String($[0]);if(Q.includes(`
|
|
@@ -160,9 +165,9 @@ ${Q.join(`
|
|
|
160
165
|
`)};return{inline:Q}}return{lines:this.formatArrayAnswer($.map((Q)=>String(Q)))}}let W=String($);if(W.includes(`
|
|
161
166
|
`))return{lines:W.split(`
|
|
162
167
|
`)};return{inline:W}}formatArrayAnswer($){let W=[];for(let Q of $){let Z=Q.split(`
|
|
163
|
-
`);W.push(`- ${Z[0]??""}`);for(let J=1;J<Z.length;J++)W.push(` ${Z[J]}`)}return W}}import
|
|
168
|
+
`);W.push(`- ${Z[0]??""}`);for(let J=1;J<Z.length;J++)W.push(` ${Z[J]}`)}return W}}import m8 from"node:process";import{spawn as FW}from"node:child_process";import{chmodSync as q8,existsSync as J$,mkdirSync as N8,statSync as A8,unlinkSync as D8}from"node:fs";import{writeFile as R8}from"node:fs/promises";import{createRequire as N1}from"node:module";import{homedir as BW}from"node:os";import $$ from"node:path";import d from"node:process";var E8="ast-grep/ast-grep",qW="0.40.0",E$=["bash","c","cpp","csharp","css","elixir","go","haskell","html","java","javascript","json","kotlin","lua","nix","php","python","ruby","rust","scala","solidity","swift","typescript","tsx","yaml"],L8=300000,F0=1048576,UW=500,M8={"darwin-arm64":{arch:"aarch64",os:"apple-darwin"},"darwin-x64":{arch:"x86_64",os:"apple-darwin"},"linux-arm64":{arch:"aarch64",os:"unknown-linux-gnu"},"linux-x64":{arch:"x86_64",os:"unknown-linux-gnu"},"win32-x64":{arch:"x86_64",os:"pc-windows-msvc"},"win32-arm64":{arch:"aarch64",os:"pc-windows-msvc"},"win32-ia32":{arch:"i686",os:"pc-windows-msvc"}};function q0($){try{return A8($).size>1e4}catch{return!1}}function T8(){return{"darwin-arm64":"@ast-grep/cli-darwin-arm64","darwin-x64":"@ast-grep/cli-darwin-x64","linux-arm64":"@ast-grep/cli-linux-arm64-gnu","linux-x64":"@ast-grep/cli-linux-x64-gnu","win32-x64":"@ast-grep/cli-win32-x64-msvc","win32-arm64":"@ast-grep/cli-win32-arm64-msvc","win32-ia32":"@ast-grep/cli-win32-ia32-msvc"}[`${d.platform}-${d.arch}`]??null}function S8(){try{return N1(import.meta.url)("@ast-grep/cli/package.json").version}catch{return qW}}function N0(){if(d.platform==="win32"){let Z=d.env.LOCALAPPDATA||d.env.APPDATA||$$.join(BW(),"AppData","Local");return $$.join(Z,"goat-chain","bin")}let W=d.env.XDG_CACHE_HOME||$$.join(BW(),".cache");return $$.join(W,"goat-chain","bin")}function A1(){return d.platform==="win32"?"ast-grep.exe":"ast-grep"}function P8(){return d.platform==="win32"?"sg.exe":"sg"}function x8(){let $=[A1(),P8()];return Array.from(new Set($))}function NW(){let $=N0();for(let W of x8()){let Q=$$.join($,W);if(J$(Q)&&q0(Q))return Q}return null}async function w8($,W){let Q=d.platform==="win32",Z=Q?"powershell":"unzip",J=Q?["-command",`Expand-Archive -Path '${$}' -DestinationPath '${W}' -Force`]:["-o",$,"-d",W],{exitCode:Y,stderr:H}=await I8(Z,J);if(Y!==0)throw Error(`zip extraction failed (exit ${Y}): ${H}
|
|
164
169
|
|
|
165
|
-
${Q?"Ensure PowerShell is available on your system.":"Please install 'unzip' (e.g., apt install unzip, brew install unzip)."}`)}async function
|
|
170
|
+
${Q?"Ensure PowerShell is available on your system.":"Please install 'unzip' (e.g., apt install unzip, brew install unzip)."}`)}async function b8($=qW){let W=`${d.platform}-${d.arch}`,Q=M8[W];if(!Q)return console.error(`[goat-chain] Unsupported platform for ast-grep: ${W}`),null;let Z=N0(),J=A1(),Y=$$.join(Z,J);if(J$(Y))return Y;let{arch:H,os:X}=Q,G=`app-${H}-${X}.zip`,V=`https://github.com/${E8}/releases/download/${$}/${G}`;console.log("[goat-chain] Downloading ast-grep binary...");try{if(!J$(Z))N8(Z,{recursive:!0});let K=await fetch(V,{redirect:"follow"});if(!K.ok)throw Error(`HTTP ${K.status}: ${K.statusText}`);let z=$$.join(Z,G),j=await K.arrayBuffer();if(await R8(z,Buffer.from(j)),await w8(z,Z),J$(z))D8(z);if(d.platform!=="win32"&&J$(Y))q8(Y,493);return console.log("[goat-chain] ast-grep binary ready."),Y}catch(K){return console.error(`[goat-chain] Failed to download ast-grep: ${K instanceof Error?K.message:K}`),null}}async function AW(){let $=S8(),W=await b8($);if(W)U$=W,RW(W);return W}async function OW(){let $=NW();if($)return $;if(V$)return V$;return V$=(async()=>{try{return await AW()}finally{V$=null}})(),V$}function DW(){let $=A1(),W=NW();if(W&&q0(W))return W;try{let J=N1(import.meta.url).resolve("@ast-grep/cli/package.json"),Y=$$.dirname(J),H=$$.join(Y,$);if(J$(H)&&q0(H))return H}catch{}let Q=T8();if(Q)try{let J=N1(import.meta.url).resolve(`${Q}/package.json`),Y=$$.dirname(J),H=d.platform==="win32"?"ast-grep.exe":"ast-grep",X=$$.join(Y,H);if(J$(X)&&q0(X))return X}catch{}if(d.platform==="darwin"){let Z=["/opt/homebrew/bin/ast-grep","/usr/local/bin/ast-grep","/opt/homebrew/bin/sg","/usr/local/bin/sg"];for(let J of Z)if(J$(J)&&q0(J))return J}return null}var U$=null,V$=null;function y8(){if(U$!==null)return U$;let $=DW();if($)return U$=$,$;return"sg"}function RW($){U$=$}async function C8(){if(U$!==null&&J$(U$))return U$;if(V$)return V$;return V$=(async()=>{try{let $=DW();if($&&J$($))return U$=$,RW($),$;return await AW()}finally{V$=null}})(),V$}function I8($,W){return new Promise((Q,Z)=>{let J=FW($,W,{stdio:["ignore","pipe","pipe"]}),Y="",H="";J.stdout?.on("data",(X)=>{Y+=X.toString()}),J.stderr?.on("data",(X)=>{H+=X.toString()}),J.on("error",(X)=>{Z(X)}),J.on("close",(X)=>{Q({exitCode:X,stdout:Y,stderr:H})})})}function v8($,W,Q,Z){return new Promise((J,Y)=>{let H=!1,X=!1,G=[],V=0,K=[],z=0;console.log("[goat-chain] Spawning process:",$,W,Z??d.cwd());let j=FW($,W,{cwd:Z,stdio:["ignore","pipe","pipe"]}),_=setTimeout(()=>{H=!0,j.kill()},Q);j.stdout?.on("data",(B)=>{if(V>=F0){X=!0;return}let F=F0-V;if(B.length>F)G.push(B.subarray(0,F)),V+=F,X=!0;else G.push(B),V+=B.length}),j.stderr?.on("data",(B)=>{if(z>=F0)return;let F=F0-z;if(B.length>F)K.push(B.subarray(0,F)),z+=F;else K.push(B),z+=B.length}),j.on("error",(B)=>{clearTimeout(_),Y(B)}),j.on("close",(B)=>{clearTimeout(_),J({stdout:Buffer.concat(G).toString(),stderr:Buffer.concat(K).toString(),exitCode:B,timedOut:H,outputTruncated:X})})})}function f8($){return $.code==="ENOENT"||$.message?.includes("ENOENT")||$.message?.includes("not found")||$.message?.includes("cannot execute")||$.message?.includes("Exec format error")||$.code==="EACCES"}function k8($,W){try{let Q=JSON.parse($);return Array.isArray(Q)?Q:[]}catch{if(!W)return[]}try{let Q=$.lastIndexOf("}");if(Q>0){let Z=$.lastIndexOf("},",Q);if(Z>0){let J=`${$.substring(0,Z+1)}]`,Y=JSON.parse(J);return Array.isArray(Y)?Y:[]}}}catch{return null}return null}async function f$($){console.log("[goat-chain] Running ast-grep command...",$);let W=$.jsonOutput!==!1,Q=["run","-p",$.pattern,"--lang",$.lang];if(W)Q.push("--json=compact");if($.rewrite){if(Q.push("-r",$.rewrite),$.updateAll)Q.push("--update-all")}if($.context&&$.context>0)Q.push("-C",String($.context));if($.globs)for(let _ of $.globs)Q.push("--globs",_);let Z=$.paths&&$.paths.length>0?$.paths:["."];Q.push(...Z);let J=L8,Y=Boolean($.binaryPath),H=$.binaryPath??y8();if(!Y&&!J$(H)&&H!=="sg"){let _=await C8();if(_)H=_}let X;try{X=await v8(H,Q,J,$.cwd)}catch(_){let B=_;if(!Y&&f8(B)){if(await OW())return f$($);return{matches:[],totalMatches:0,truncated:!1,error:`ast-grep CLI binary not found or invalid.
|
|
166
171
|
|
|
167
172
|
Auto-download failed. Manual install options:
|
|
168
173
|
pnpm install --force # Re-run postinstall scripts
|
|
@@ -170,30 +175,30 @@ Auto-download failed. Manual install options:
|
|
|
170
175
|
cargo install ast-grep --locked
|
|
171
176
|
brew install ast-grep
|
|
172
177
|
|
|
173
|
-
See docs/TROUBLESHOOTING.md for more information.`}}return{matches:[],totalMatches:0,truncated:!1,error:`Failed to spawn ast-grep: ${
|
|
178
|
+
See docs/TROUBLESHOOTING.md for more information.`}}return{matches:[],totalMatches:0,truncated:!1,error:`Failed to spawn ast-grep: ${B.message}`}}if(X.timedOut)return{matches:[],totalMatches:0,truncated:!0,truncatedReason:"timeout",error:`Search timeout after ${J}ms`,exitCode:X.exitCode,stderr:X.stderr};if(!W){let _=X.stdout.trim(),B=X.stderr.trim();if(X.exitCode!==0){let F=B||_||`ast-grep exited with code ${X.exitCode}`;return{matches:[],totalMatches:0,truncated:X.outputTruncated,truncatedReason:X.outputTruncated?"max_output_bytes":void 0,error:F,exitCode:X.exitCode,stderr:X.stderr}}return{matches:[],totalMatches:0,truncated:X.outputTruncated,truncatedReason:X.outputTruncated?"max_output_bytes":void 0,exitCode:X.exitCode,stderr:X.stderr}}if(X.exitCode!==0&&X.stdout.trim()===""){if(X.stderr.includes("No files found"))return{matches:[],totalMatches:0,truncated:!1,exitCode:X.exitCode,stderr:X.stderr};let _=X.stderr.toLowerCase();if(!Y&&(_.includes("command not found")||_.includes("cannot execute")||_.includes("exec format error")||_.includes("permission denied"))){if(await OW())return f$($)}if(X.stderr.trim())return{matches:[],totalMatches:0,truncated:!1,error:X.stderr.trim(),exitCode:X.exitCode,stderr:X.stderr};return{matches:[],totalMatches:0,truncated:!1,exitCode:X.exitCode,stderr:X.stderr}}if(!X.stdout.trim())return{matches:[],totalMatches:0,truncated:!1,exitCode:X.exitCode,stderr:X.stderr};let G=X.outputTruncated||Buffer.byteLength(X.stdout)>=F0,V=k8(X.stdout,G);if(V===null)return{matches:[],totalMatches:0,truncated:!0,truncatedReason:"max_output_bytes",error:"Output too large and could not be parsed",exitCode:X.exitCode,stderr:X.stderr};let K=V.length,z=K>UW;return{matches:z?V.slice(0,UW):V,totalMatches:K,truncated:G||z,truncatedReason:G?"max_output_bytes":z?"max_matches":void 0,exitCode:X.exitCode,stderr:X.stderr}}import EW from"node:path";function LW($,W){if(!$||!W)return $;let Q=EW.relative(W,$);if(Q&&!Q.startsWith("..")&&!EW.isAbsolute(Q))return Q;return $}function MW($){if($.truncatedReason==="max_matches")return`showing first ${$.matches.length} of ${$.totalMatches}`;if($.truncatedReason==="max_output_bytes")return"output exceeded 1MB limit";if($.truncatedReason==="timeout")return"search timed out";return"output truncated"}function h8($){let W=($.lines??$.text??"").trim();return W?` ${W}`:""}function TW($,W){if($.error)return`Error: ${$.error}`;if($.matches.length===0)return"No matches found";let Q=[];if($.truncated)Q.push(`Results truncated (${MW($)})
|
|
174
179
|
`);Q.push(`Found ${$.matches.length} match(es)${$.truncated?` (truncated from ${$.totalMatches})`:""}:
|
|
175
|
-
`);for(let Z of $.matches){let J=(Z.range?.start?.line??0)+1,Y=(Z.range?.start?.column??0)+1,H=`${
|
|
176
|
-
`)}function
|
|
180
|
+
`);for(let Z of $.matches){let J=(Z.range?.start?.line??0)+1,Y=(Z.range?.start?.column??0)+1,H=`${LW(Z.file,W)}:${J}:${Y}`;Q.push(H);let X=h8(Z);if(X)Q.push(X);Q.push("")}return Q.join(`
|
|
181
|
+
`)}function D1($,W,Q){if($.error)return`Error: ${$.error}`;if($.matches.length===0)return"No matches found to replace";let Z=W?"[DRY RUN] ":"",J=[];if($.truncated)J.push(`Results truncated (${MW($)})
|
|
177
182
|
`);J.push(`${Z}${$.matches.length} replacement(s):
|
|
178
|
-
`);for(let Y of $.matches){let H=(Y.range?.start?.line??0)+1,X=(Y.range?.start?.column??0)+1,G=`${
|
|
179
|
-
`)}function
|
|
183
|
+
`);for(let Y of $.matches){let H=(Y.range?.start?.line??0)+1,X=(Y.range?.start?.column??0)+1,G=`${LW(Y.file,Q)}:${H}:${X}`;J.push(G);let V=Y.text?.trim();if(V)J.push(` ${V}`);J.push("")}if(W)J.push("Use dryRun=false to apply changes");return J.join(`
|
|
184
|
+
`)}function SW($,W){let Q=$.trim();if(W==="python"){if(Q.startsWith("class ")&&Q.endsWith(":"))return`Hint: Remove trailing colon. Try: "${Q.slice(0,-1)}"`;if((Q.startsWith("def ")||Q.startsWith("async def "))&&Q.endsWith(":"))return`Hint: Remove trailing colon. Try: "${Q.slice(0,-1)}"`}if(["javascript","typescript","tsx"].includes(W)){if(/^(?:export\s+)?(?:async\s+)?function\s+\$[A-Z_]+\s*$/i.test(Q))return'Hint: Function patterns need params and body. Try "function $NAME($$$) { $$$ }"'}return null}import{realpath as PW}from"node:fs/promises";import l$ from"node:path";import g8 from"picomatch";var bW=[{pattern:".env",reason:"Sensitive configuration file"},{pattern:".env.local",reason:"Sensitive configuration file"},{pattern:".env.development",reason:"Sensitive configuration file"},{pattern:".env.production",reason:"Sensitive configuration file"},{pattern:".env.test",reason:"Sensitive configuration file"},{pattern:".env.staging",reason:"Sensitive configuration file"},{pattern:".envrc",reason:"Sensitive configuration file"},{pattern:".npmrc",reason:"Registry credentials file"},{pattern:".pypirc",reason:"Registry credentials file"},{pattern:".aws/credentials",reason:"Cloud credentials file"},{pattern:"credentials.json",reason:"Credentials file"},{pattern:"secrets.json",reason:"Secrets file"},{pattern:".ssh/*",reason:"SSH key material"},{pattern:"id_rsa",reason:"SSH private key"},{pattern:"id_ed25519",reason:"SSH private key"},{pattern:"id_ecdsa",reason:"SSH private key"},{pattern:"id_dsa",reason:"SSH private key"},{pattern:"private_key.pem",reason:"Private key file"},{pattern:"*.pem",reason:"Private key file"},{pattern:"*.key",reason:"Private key file"},{pattern:"*.p12",reason:"Private key file"},{pattern:"*.pfx",reason:"Private key file"}],g3=bW.map(($)=>$.pattern),xW=new Map;function yW($){return $.replace(/\\/g,"/").trim()}function wW($){return $.replace(/\\/g,"/")}function u8($){let W=yW($);if(!W)return[];let Q=W;if(Q.startsWith("./"))Q=Q.slice(2);if(Q.startsWith("/"))Q=Q.slice(1);let Z=new Set;if(Z.add(Q),Q.includes("/")&&!Q.startsWith("**/"))Z.add(`**/${Q}`);return Array.from(Z)}function CW($){let W=[];for(let Q of $)for(let Z of u8(Q.pattern))try{let J=`${Z}:${process.platform==="win32"?"nocase":"case"}`,Y=xW.get(J);if(!Y)Y=g8(Z,{dot:!0,nocase:process.platform==="win32"}),xW.set(J,Y);W.push({rule:Q,matcher:Y})}catch{}return W}function R1($){if($===void 0)return[...bW];return $.map((W)=>{if(typeof W==="string")return{pattern:W};if(W&&typeof W.pattern==="string")return{pattern:W.pattern,reason:W.reason};return null}).filter((W)=>Boolean(W&&W.pattern.trim()))}function IW($,W){let Q=new Set;return((J)=>{if(!J)return;let Y=wW(J);if(Q.add(Y),Q.add(l$.posix.basename(Y)),W){let H=l$.relative(W,J);if(H)Q.add(wW(H))}})($),Array.from(Q)}function vW($,W){for(let{rule:Q,matcher:Z}of W)for(let J of $)if(Z(J))return Q;return}function E1($,W){let Q=W?.reason??"Protected file";return`Access denied: ${$}
|
|
180
185
|
This file is in the protected file list and cannot be accessed by tools.
|
|
181
|
-
Reason: ${Q}`}function
|
|
186
|
+
Reason: ${Q}`}function u0($={}){let{blacklist:W,disabled:Q,cwd:Z}=$;if(Q)return{match:(X)=>{return},isBlocked:(X)=>!1};let J=R1(W),Y=CW(J),H=(X)=>{let G=IW(X,Z);return vW(G,Y)};return{match:H,isBlocked:(X)=>Boolean(H(X))}}async function i$($,W={}){if(W.disabled)return{isBlocked:!1};let Q=R1(W.blacklist);if(Q.length===0)return{isBlocked:!1};let Z=CW(Q),J=new Set,Y=(X)=>{for(let G of IW(X,W.cwd))J.add(G)};Y($),Y(l$.resolve($));try{let X=await PW($);Y(X)}catch{}try{let X=await PW(l$.dirname($));Y(l$.join(X,l$.basename($)))}catch{}let H=vW(Array.from(J),Z);if(!H)return{isBlocked:!1};return{isBlocked:!0,rule:H,message:E1(W.originalPath??$,H)}}function m0($={}){if($.disabled)return[];let W=R1($.blacklist);if(W.length===0)return[];let Q=new Set;for(let Z of W){let J=yW(Z.pattern);if(!J)continue;let Y=J;if(Y.startsWith("./"))Y=Y.slice(2);if(Y.startsWith("/"))Y=Y.slice(1);if(!Y.startsWith("**/"))Y=`**/${Y}`;Q.add(`!${Y}`)}return Array.from(Q)}class r$ extends k{name="ast_grep_replace";riskLevel="high";description=`Replace code patterns across filesystem with AST-aware rewriting. Dry-run by default.
|
|
182
187
|
|
|
183
188
|
Usage notes:
|
|
184
189
|
- Use meta-variables in rewrite to preserve matched content
|
|
185
190
|
- Example: pattern='console.log($MSG)' rewrite='logger.info($MSG)'
|
|
186
|
-
- Set dryRun=false to apply changes`;parameters={type:"object",properties:{pattern:{type:"string",description:"AST pattern to match."},rewrite:{type:"string",description:"Replacement pattern (can use $VAR from pattern)."},lang:{type:"string",enum:[...
|
|
191
|
+
- Set dryRun=false to apply changes`;parameters={type:"object",properties:{pattern:{type:"string",description:"AST pattern to match."},rewrite:{type:"string",description:"Replacement pattern (can use $VAR from pattern)."},lang:{type:"string",enum:[...E$],description:"Target language (ast-grep language identifier)."},paths:{type:"array",items:{type:"string"},description:'Paths to search (default: ["."]).'},globs:{type:"array",items:{type:"string"},description:"Include/exclude globs (prefix ! to exclude)."},dryRun:{type:"boolean",description:"Preview changes without applying (default: true)."}},required:["pattern","rewrite","lang"]};cwd;astGrepPath;fileBlacklist;disableBlacklist;constructor($){super();this.cwd=$?.cwd??m8.cwd(),this.astGrepPath=$?.astGrepPath,this.fileBlacklist=$?.fileBlacklist,this.disableBlacklist=$?.disableBlacklist===!0}setCwd($){this.cwd=$}getCwd(){return this.cwd}async execute($,W){let Q=this.validateArgs($),Z=Q.dryRun!==!1,J=m0({blacklist:this.fileBlacklist,disabled:this.disableBlacklist}),Y=(Q.globs?.length??0)>0||J.length>0?[...Q.globs??[],...J]:void 0,H=await f$({pattern:Q.pattern,rewrite:Q.rewrite,lang:Q.lang,paths:Q.paths,globs:Y,updateAll:!1,cwd:this.cwd,binaryPath:this.astGrepPath});if(!Z&&!H.error&&H.matches.length>0){let V=await f$({pattern:Q.pattern,rewrite:Q.rewrite,lang:Q.lang,paths:Q.paths,globs:Y,updateAll:!0,jsonOutput:!1,cwd:this.cwd,binaryPath:this.astGrepPath});if(Boolean(V.error)||V.exitCode!==null&&V.exitCode!==0){let B=`Error: ${V.error||V.stderr?.trim()||`ast-grep replace failed${V.exitCode!==null?` (exit ${V.exitCode})`:""}`}`,F={exitCode:V.exitCode??H.exitCode??null,output:B,matches:H.matches,matchCount:H.totalMatches,stderr:V.stderr?.trim()||H.stderr?.trim()||void 0,truncated:H.truncated,truncatedReason:H.truncatedReason,timedOut:H.truncatedReason==="timeout"};return{content:[{type:"text",text:B}],structuredContent:F,isError:!0}}let z=D1(H,Z,this.cwd),j={exitCode:V.exitCode??H.exitCode??null,output:z,matches:H.matches,matchCount:H.totalMatches,stderr:V.stderr?.trim()||H.stderr?.trim()||void 0,truncated:H.truncated,truncatedReason:H.truncatedReason,timedOut:H.truncatedReason==="timeout"};return{content:[{type:"text",text:z}],structuredContent:j,isError:!1}}let X=D1(H,Z,this.cwd),G={exitCode:H.exitCode??null,output:X,matches:H.matches,matchCount:H.totalMatches,stderr:H.stderr?.trim()||void 0,truncated:H.truncated,truncatedReason:H.truncatedReason,timedOut:H.truncatedReason==="timeout"};return{content:[{type:"text",text:X}],structuredContent:G,isError:Boolean(H.error)}}validateArgs($){let{pattern:W,rewrite:Q,lang:Z}=$;if(typeof W!=="string"||!W.trim())throw Error("pattern is required and must be a non-empty string");if(typeof Q!=="string"||!Q.trim())throw Error("rewrite is required and must be a non-empty string");if(typeof Z!=="string"||!Z.trim())throw Error("lang is required and must be a non-empty string");if(!E$.includes(Z))throw Error(`lang must be one of: ${E$.join(", ")}`);let J={pattern:W.trim(),rewrite:Q.trim(),lang:Z.trim()};if($.paths!==void 0&&$.paths!==null){if(!Array.isArray($.paths)||$.paths.some((Y)=>typeof Y!=="string"))throw TypeError("paths must be an array of strings");J.paths=$.paths.map((Y)=>Y.trim()).filter(Boolean)}if($.globs!==void 0&&$.globs!==null){if(!Array.isArray($.globs)||$.globs.some((Y)=>typeof Y!=="string"))throw TypeError("globs must be an array of strings");J.globs=$.globs.map((Y)=>Y.trim()).filter(Boolean)}if($.dryRun!==void 0&&$.dryRun!==null)J.dryRun=Boolean($.dryRun);return J}}import p8 from"node:process";var fW=5000;class n$ extends k{name="ast_grep_search";description=`Search code patterns across filesystem using AST-aware matching. Supports 25 languages.
|
|
187
192
|
|
|
188
193
|
Usage notes:
|
|
189
194
|
- Use meta-variables: $VAR (single node), $$$ (multiple nodes)
|
|
190
195
|
- Patterns must be complete AST nodes (valid code)
|
|
191
196
|
- For functions, include params and body: 'export async function $NAME($$$) { $$$ }' not 'export async function $NAME'
|
|
192
|
-
- Examples: 'console.log($MSG)', 'def $FUNC($$$):', 'async function $NAME($$$)'`;parameters={type:"object",properties:{pattern:{type:"string",description:"AST pattern with meta-variables ($VAR, $$$). Must be complete AST node."},lang:{type:"string",enum:[...
|
|
197
|
+
- Examples: 'console.log($MSG)', 'def $FUNC($$$):', 'async function $NAME($$$)'`;parameters={type:"object",properties:{pattern:{type:"string",description:"AST pattern with meta-variables ($VAR, $$$). Must be complete AST node."},lang:{type:"string",enum:[...E$],description:"Target language (ast-grep language identifier)."},paths:{type:"array",items:{type:"string"},description:'Paths to search (default: ["."]).'},globs:{type:"array",items:{type:"string"},description:"Include/exclude globs (prefix ! to exclude)."},context:{type:"number",description:"Context lines around match."}},required:["pattern","lang"]};cwd;astGrepPath;constructor($){super();this.cwd=$?.cwd??p8.cwd(),this.astGrepPath=$?.astGrepPath}setCwd($){this.cwd=$}getCwd(){return this.cwd}async execute($,W){let Q=this.validateArgs($),Z=await f$({pattern:Q.pattern,lang:Q.lang,paths:Q.paths,globs:Q.globs,context:Q.context,cwd:this.cwd,binaryPath:this.astGrepPath}),J=TW(Z,this.cwd);if(Z.matches.length===0&&!Z.error){let G=SW(Q.pattern,Q.lang);if(G)J+=`
|
|
193
198
|
|
|
194
|
-
${G}`}let{truncated:Y,truncatedReason:H}=Z;if(J.length>
|
|
199
|
+
${G}`}let{truncated:Y,truncatedReason:H}=Z;if(J.length>fW){if(J=`${J.slice(0,fW)}
|
|
195
200
|
|
|
196
|
-
... [output truncated due to length limit]`,Y=!0,!H)H="max_output_bytes"}let X={exitCode:Z.exitCode??null,output:J,matches:Z.matches,matchCount:Z.totalMatches,stderr:Z.stderr?.trim()||void 0,truncated:Y,truncatedReason:H,timedOut:Z.truncatedReason==="timeout"};return{content:[{type:"text",text:J}],structuredContent:X,isError:Boolean(Z.error)}}validateArgs($){let{pattern:W,lang:Q}=$;if(typeof W!=="string"||!W.trim())throw Error("pattern is required and must be a non-empty string");if(typeof Q!=="string"||!Q.trim())throw Error("lang is required and must be a non-empty string");if(!
|
|
201
|
+
... [output truncated due to length limit]`,Y=!0,!H)H="max_output_bytes"}let X={exitCode:Z.exitCode??null,output:J,matches:Z.matches,matchCount:Z.totalMatches,stderr:Z.stderr?.trim()||void 0,truncated:Y,truncatedReason:H,timedOut:Z.truncatedReason==="timeout"};return{content:[{type:"text",text:J}],structuredContent:X,isError:Boolean(Z.error)}}validateArgs($){let{pattern:W,lang:Q}=$;if(typeof W!=="string"||!W.trim())throw Error("pattern is required and must be a non-empty string");if(typeof Q!=="string"||!Q.trim())throw Error("lang is required and must be a non-empty string");if(!E$.includes(Q))throw Error(`lang must be one of: ${E$.join(", ")}`);let Z={pattern:W.trim(),lang:Q.trim()};if($.paths!==void 0&&$.paths!==null){if(!Array.isArray($.paths)||$.paths.some((J)=>typeof J!=="string"))throw TypeError("paths must be an array of strings");Z.paths=$.paths.map((J)=>J.trim()).filter(Boolean)}if($.globs!==void 0&&$.globs!==null){if(!Array.isArray($.globs)||$.globs.some((J)=>typeof J!=="string"))throw TypeError("globs must be an array of strings");Z.globs=$.globs.map((J)=>J.trim()).filter(Boolean)}if($.context!==void 0&&$.context!==null){if(typeof $.context!=="number"||!Number.isFinite($.context)||$.context<0)throw TypeError("context must be a non-negative number");Z.context=Math.floor($.context)}return Z}}import{spawn as kW}from"node:child_process";import s from"node:process";var p0=30000,hW=120000,c8=600000,G$=new Map;async function o$($){try{if(s.platform==="win32"){let{execSync:W}=await import("node:child_process");try{return W(`taskkill /PID ${$} /T /F`,{stdio:"ignore"}),!0}catch{return!1}}else try{s.kill(-$,"SIGTERM"),await new Promise((W)=>setTimeout(W,100));try{s.kill(-$,"SIGKILL")}catch{}return!0}catch(W){try{s.kill($,"SIGTERM"),await new Promise((Q)=>setTimeout(Q,100));try{s.kill($,"SIGKILL")}catch{}return!0}catch{return!1}}}catch{return!1}}function A0($){try{return s.kill($,0),!0}catch{return!1}}function L1(){for(let[$]of G$)if(!A0($))G$.delete($);return Array.from(G$.values())}async function M1($){let W=[];for(let[Q,Z]of G$)if(Z.category===$&&A0(Q)){if(await o$(Q))W.push(Q),G$.delete(Q)}return W}async function T1(){let $=[];for(let[W]of G$){if(A0(W)){if(await o$(W))$.push(W)}G$.delete(W)}return $}function gW($){let W=$.toLowerCase().trim();if(/^(npm|yarn|pnpm|bun)\s+(run\s+)?(dev|start|serve)/.test(W))return"dev-server";if(/^(npm|yarn|pnpm|bun)\s+run\s+watch/.test(W))return"watch";if(/^node\s+(?:\S.*)?server/.test(W))return"node-server";if(/^(vite|webpack-dev-server|parcel|rollup)/.test(W))return"bundler-server";if(/^(next|nuxt)\s+dev/.test(W))return"framework-server";if(/^(redis-server|mongod|postgres|mysql)/.test(W))return"database";if(/^(python|python3)\s+-m\s+(http\.server|SimpleHTTPServer)/.test(W))return"python-server";return}class L$ extends k{name="Bash";riskLevel="critical";description=`Executes a given bash command in a persistent shell session with optional timeout.
|
|
197
202
|
|
|
198
203
|
Usage notes:
|
|
199
204
|
- The command argument is required.
|
|
@@ -210,44 +215,48 @@ Usage notes:
|
|
|
210
215
|
Examples:
|
|
211
216
|
- Background: { command: "npm run dev", run_in_background: true, description: "Start dev server" }
|
|
212
217
|
- Foreground: { command: "npm test", timeout: 60000, description: "Run tests" }
|
|
213
|
-
- Foreground: { command: "npm run build", description: "Build project" }`;parameters={type:"object",properties:{command:{type:"string",description:"The command to execute"},timeout:{type:"number",description:"Optional timeout in milliseconds (max 600000)"},description:{type:"string",description:"Clear, concise description of what this command does in 5-10 words"},run_in_background:{type:"boolean",description:"Set to true to run this command in the background. REQUIRED for long-running processes like dev servers (npm run dev, npm start), watch modes, or any command that runs indefinitely. The command will start immediately and return its PID without waiting for completion."},workdir:{type:"string",description:"Working directory to run the command in. Use this instead of cd commands."}},required:["command"]};cwd;shell;constructor($){super();this.cwd=$?.cwd??s.cwd(),this.shell=$?.shell??(s.platform==="win32"?"cmd.exe":"/bin/bash")}setCwd($){this.cwd=$}getCwd(){return this.cwd}async execute($,W){let{command:Q,timeout:Z=
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
218
|
+
- Foreground: { command: "npm run build", description: "Build project" }`;parameters={type:"object",properties:{command:{type:"string",description:"The command to execute"},timeout:{type:"number",description:"Optional timeout in milliseconds (max 600000)"},description:{type:"string",description:"Clear, concise description of what this command does in 5-10 words"},run_in_background:{type:"boolean",description:"Set to true to run this command in the background. REQUIRED for long-running processes like dev servers (npm run dev, npm start), watch modes, or any command that runs indefinitely. The command will start immediately and return its PID without waiting for completion."},workdir:{type:"string",description:"Working directory to run the command in. Use this instead of cd commands."}},required:["command"]};cwd;shell;constructor($){super();this.cwd=$?.cwd??s.cwd(),this.shell=$?.shell??(s.platform==="win32"?"cmd.exe":"/bin/bash")}setCwd($){this.cwd=$}getCwd(){return this.cwd}async execute($,W){let{command:Q,timeout:Z=hW,run_in_background:J,workdir:Y}=this.validateArgs($);if(W.metadata?.readOnlyBash===!0){let B=R$(Q);if(!B.isAllowed)return I(`[READ-ONLY MODE] Command rejected: ${B.reason}
|
|
219
|
+
|
|
220
|
+
In read-only mode, only commands like: ls, find, cat, head, tail, git status, git log, git diff, etc. are allowed.
|
|
221
|
+
|
|
222
|
+
Forbidden: file creation/modification, git write operations, package installations, redirects.`)}let X=Y||this.cwd,G=this.shouldRunInBackground(Q),V,K=[];if(G&&!J)V=`⚠️ WARNING: This command appears to be a long-running process (dev server, watch mode, or daemon). It will timeout after ${Z}ms. Consider using 'run_in_background: true' to run it properly in the background.`;if(J){let B=gW(Q);if(B)K=await M1(B)}let z=J?await this.executeBackground(Q,X,W):await this.executeSync(Q,Z,X,W);if(V)z.warning=V;if(K.length>0)z.killedPids=K;let j=[];if(K.length>0)j.push(`[Killed ${K.length} existing process(es) of same type: PID ${K.join(", ")}]`),j.push("");if(z.warning)j.push(z.warning),j.push("");if(z.stdout)j.push(z.stdout);if(z.stderr)j.push(`[stderr]:
|
|
223
|
+
${z.stderr}`);if(z.timedOut){if(j.push(`[Command timed out after ${Z}ms]`),G)j.push("[Hint: This looks like a long-running process. Retry with 'run_in_background: true']")}if(z.background)j.push(`[Running in background with PID ${z.pid}]`);return{content:[{type:"text",text:j.join(`
|
|
224
|
+
`)||"[No output]"}],structuredContent:z,isError:z.exitCode!==0&&z.exitCode!==null&&!z.background}}shouldRunInBackground($){let W=$.toLowerCase().trim();return[/^(npm|yarn|pnpm|bun)\s+(run\s+)?(dev|start|serve)/,/^(npm|yarn|pnpm|bun)\s+run\s+watch/,/^node\s+(?:\S.*)?server/,/^(python|python3)\s+-m\s+(http\.server|SimpleHTTPServer)/,/^(ruby)\s+-run\s+-e\s+httpd/,/^(vite|webpack-dev-server|parcel|rollup)\s+/,/^(redis-server|mongod|postgres|mysql)/,/^(next|nuxt)\s+dev/].some((Z)=>Z.test(W))}validateArgs($){let W=$.command;if(typeof W!=="string"||!W.trim())throw Error("Command is required and must be a non-empty string");let Q=hW;if($.timeout!==void 0){if(typeof $.timeout!=="number")throw TypeError("Timeout must be a number");Q=Math.min(Math.max(0,$.timeout),c8)}return{command:W.trim(),timeout:Q,description:typeof $.description==="string"?$.description:void 0,run_in_background:$.run_in_background===!0,workdir:typeof $.workdir==="string"?$.workdir:void 0}}executeSync($,W,Q,Z){return new Promise((J)=>{let Y="",H="",X=!1,G=!1,V=!1,K=!1,z=!1,j=s.platform==="win32"?["/c",$]:["-c",$],_=kW(this.shell,j,{cwd:Q,env:s.env,stdio:["ignore","pipe","pipe"],detached:s.platform!=="win32"}),B=_.pid,F=()=>{if(!z&&Z?.emitEvent&&Z.toolCallId)z=!0,Z.emitEvent({type:"tool_output_start",tool_call_id:Z.toolCallId,toolName:Z.toolName||"Bash"})},A=(O,T)=>{if(Z?.emitEvent&&Z.toolCallId)F(),Z.emitEvent({type:"tool_output_delta",tool_call_id:Z.toolCallId,delta:O,isStderr:T})},N=async()=>{if(B&&!K)await o$(B)},U=()=>{V=!0,N()},R=Z?.signal;if(R)if(R.aborted)V=!0,N();else R.addEventListener("abort",U,{once:!0});let q=setTimeout(()=>{X=!0,N()},W),D=()=>{if(clearTimeout(q),R)R.removeEventListener("abort",U)};_.stdout?.on("data",(O)=>{let T=O.toString();if(Y.length+T.length>p0)Y+=T.slice(0,p0-Y.length),G=!0;else Y+=T;A(T,!1)}),_.stderr?.on("data",(O)=>{let T=O.toString();if(H.length+T.length>p0)H+=T.slice(0,p0-H.length),G=!0;else H+=T;A(T,!0)}),_.on("close",(O)=>{K=!0,D();let T=G?`${Y}
|
|
225
|
+
... [output truncated]`:Y,S=H,f=[];if(X)f.push(`Command terminated after exceeding timeout ${W}ms`);if(V)f.push("Command was aborted by user");if(f.length>0)S+=`${S?`
|
|
217
226
|
|
|
218
227
|
`:""}<bash_metadata>
|
|
219
|
-
${
|
|
228
|
+
${f.join(`
|
|
220
229
|
`)}
|
|
221
|
-
</bash_metadata>`;J({exitCode:O,stdout:T,stderr:
|
|
230
|
+
</bash_metadata>`;J({exitCode:O,stdout:T,stderr:S,truncated:G,timedOut:X,background:!1})}),_.on("error",(O)=>{K=!0,D(),J({exitCode:1,stdout:"",stderr:`Failed to execute command: ${O.message}`,truncated:!1,timedOut:!1,background:!1})})})}executeBackground($,W,Q){return new Promise((Z)=>{let J=s.platform==="win32"?["/c",$]:["-c",$],Y=kW(this.shell,J,{cwd:W,env:s.env,stdio:["ignore","pipe","pipe"],detached:s.platform!=="win32"}),H=Y.pid,X=!1,G=()=>{if(!X&&Q?.emitEvent&&Q.toolCallId)X=!0,Q.emitEvent({type:"tool_output_start",tool_call_id:Q.toolCallId,toolName:Q.toolName||"Bash"})},V=(_,B)=>{if(Q?.emitEvent&&Q.toolCallId)G(),Q.emitEvent({type:"tool_output_delta",tool_call_id:Q.toolCallId,delta:_,isStderr:B})},K="",z="",j=2000;if(Y.stdout?.on("data",(_)=>{let B=_.toString();if(K.length<1000)K+=B;V(B,!1)}),Y.stderr?.on("data",(_)=>{let B=_.toString();if(z.length<1000)z+=B;V(B,!0)}),H){let _=gW($);G$.set(H,{pid:H,command:$,startedAt:Date.now(),process:Y,category:_}),Y.on("exit",()=>{G$.delete(H)})}setTimeout(()=>{Y.unref();let _=[];if(_.push(`Command started in background with PID ${H}`),K.trim())_.push(`
|
|
222
231
|
[Initial output]:
|
|
223
|
-
${K.trim()}`);if(z.trim())
|
|
232
|
+
${K.trim()}`);if(z.trim())_.push(`
|
|
224
233
|
[Initial stderr]:
|
|
225
|
-
${z.trim()}`);Z({exitCode:null,stdout:
|
|
234
|
+
${z.trim()}`);Z({exitCode:null,stdout:_.join(""),stderr:"",truncated:!1,timedOut:!1,background:!0,pid:H})},j)})}async killProcess($){let W=await o$($);if(W)G$.delete($);return W}getRunningProcesses(){return L1()}async killAllProcesses(){return T1()}}import{readFile as d8,stat as l8,writeFile as i8}from"node:fs/promises";import S1 from"node:path";import r8 from"node:process";var uW=0,n8=0.3;function mW($,W){if($===""||W==="")return Math.max($.length,W.length);let Q=Array.from({length:$.length+1},(Z,J)=>Array.from({length:W.length+1},(Y,H)=>J===0?H:H===0?J:0));for(let Z=1;Z<=$.length;Z++)for(let J=1;J<=W.length;J++){let Y=$[Z-1]===W[J-1]?0:1;Q[Z][J]=Math.min(Q[Z-1][J]+1,Q[Z][J-1]+1,Q[Z-1][J-1]+Y)}return Q[$.length][W.length]}var o8=function*($,W){yield W},a8=function*($,W){let Q=$.split(`
|
|
226
235
|
`),Z=W.split(`
|
|
227
|
-
`);if(Z[Z.length-1]==="")Z.pop();for(let J=0;J<=Q.length-Z.length;J++){let Y=!0;for(let H=0;H<Z.length;H++){let X=Q[J+H].trim(),G=Z[H].trim();if(X!==G){Y=!1;break}}if(Y){let H=0;for(let G=0;G<J;G++)H+=Q[G].length+1;let X=H;for(let G=0;G<Z.length;G++)if(X+=Q[J+G].length,G<Z.length-1)X+=1;yield $.substring(H,X)}}},
|
|
236
|
+
`);if(Z[Z.length-1]==="")Z.pop();for(let J=0;J<=Q.length-Z.length;J++){let Y=!0;for(let H=0;H<Z.length;H++){let X=Q[J+H].trim(),G=Z[H].trim();if(X!==G){Y=!1;break}}if(Y){let H=0;for(let G=0;G<J;G++)H+=Q[G].length+1;let X=H;for(let G=0;G<Z.length;G++)if(X+=Q[J+G].length,G<Z.length-1)X+=1;yield $.substring(H,X)}}},s8=function*($,W){let Q=$.split(`
|
|
228
237
|
`),Z=W.split(`
|
|
229
|
-
`);if(Z.length<3)return;if(Z[Z.length-1]==="")Z.pop();let J=Z[0].trim(),Y=Z[Z.length-1].trim(),H=Z.length,X=[];for(let K=0;K<Q.length;K++){if(Q[K].trim()!==J)continue;for(let z=K+2;z<Q.length;z++)if(Q[z].trim()===Y){X.push({startLine:K,endLine:z});break}}if(X.length===0)return;if(X.length===1){let{startLine:K,endLine:z}=X[0],j=z-K+1,
|
|
238
|
+
`);if(Z.length<3)return;if(Z[Z.length-1]==="")Z.pop();let J=Z[0].trim(),Y=Z[Z.length-1].trim(),H=Z.length,X=[];for(let K=0;K<Q.length;K++){if(Q[K].trim()!==J)continue;for(let z=K+2;z<Q.length;z++)if(Q[z].trim()===Y){X.push({startLine:K,endLine:z});break}}if(X.length===0)return;if(X.length===1){let{startLine:K,endLine:z}=X[0],j=z-K+1,_=0,B=Math.min(H-2,j-2);if(B>0)for(let F=1;F<H-1&&F<j-1;F++){let A=Q[K+F].trim(),N=Z[F].trim(),U=Math.max(A.length,N.length);if(U===0)continue;let R=mW(A,N);if(_+=(1-R/U)/B,_>=uW)break}else _=1;if(_>=uW){let F=0;for(let N=0;N<K;N++)F+=Q[N].length+1;let A=F;for(let N=K;N<=z;N++)if(A+=Q[N].length,N<z)A+=1;yield $.substring(F,A)}return}let G=null,V=-1;for(let K of X){let{startLine:z,endLine:j}=K,_=j-z+1,B=0,F=Math.min(H-2,_-2);if(F>0){for(let A=1;A<H-1&&A<_-1;A++){let N=Q[z+A].trim(),U=Z[A].trim(),R=Math.max(N.length,U.length);if(R===0)continue;let q=mW(N,U);B+=1-q/R}B/=F}else B=1;if(B>V)V=B,G=K}if(V>=n8&&G){let{startLine:K,endLine:z}=G,j=0;for(let B=0;B<K;B++)j+=Q[B].length+1;let _=j;for(let B=K;B<=z;B++)if(_+=Q[B].length,B<z)_+=1;yield $.substring(j,_)}},t8=function*($,W){let Q=(H)=>H.replace(/\s+/g," ").trim(),Z=Q(W),J=$.split(`
|
|
230
239
|
`);for(let H=0;H<J.length;H++){let X=J[H];if(Q(X)===Z)yield X;else if(Q(X).includes(Z)){let V=W.trim().split(/\s+/);if(V.length>0){let K=V.map((z)=>z.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")).join("\\s+");try{let z=new RegExp(K),j=X.match(z);if(j)yield j[0]}catch{}}}}let Y=W.split(`
|
|
231
240
|
`);if(Y.length>1)for(let H=0;H<=J.length-Y.length;H++){let X=J.slice(H,H+Y.length);if(Q(X.join(`
|
|
232
241
|
`))===Z)yield X.join(`
|
|
233
|
-
`)}},
|
|
242
|
+
`)}},e8=function*($,W){let Q=(H)=>{let X=H.split(`
|
|
234
243
|
`),G=X.filter((K)=>K.trim().length>0);if(G.length===0)return H;let V=Math.min(...G.map((K)=>{let z=K.match(/^(\s*)/);return z?z[1].length:0}));return X.map((K)=>K.trim().length===0?K:K.slice(V)).join(`
|
|
235
244
|
`)},Z=Q(W),J=$.split(`
|
|
236
245
|
`),Y=W.split(`
|
|
237
246
|
`);for(let H=0;H<=J.length-Y.length;H++){let X=J.slice(H,H+Y.length).join(`
|
|
238
|
-
`);if(Q(X)===Z)yield X}}
|
|
247
|
+
`);if(Q(X)===Z)yield X}},$9=function*($,W){let Q=(H)=>{return H.replace(/\\([ntr'"`\\\n$])/g,(X,G)=>{switch(G){case"n":return`
|
|
239
248
|
`;case"t":return"\t";case"r":return"\r";case"'":return"'";case'"':return'"';case"`":return"`";case"\\":return"\\";case`
|
|
240
249
|
`:return`
|
|
241
250
|
`;case"$":return"$";default:return X}})},Z=Q(W);if($.includes(Z))yield Z;let J=$.split(`
|
|
242
251
|
`),Y=Z.split(`
|
|
243
252
|
`);for(let H=0;H<=J.length-Y.length;H++){let X=J.slice(H,H+Y.length).join(`
|
|
244
|
-
`);if(Q(X)===Z)yield X}},
|
|
253
|
+
`);if(Q(X)===Z)yield X}},W9=function*($,W){let Q=W.trim();if(Q===W)return;if($.includes(Q))yield Q;let Z=$.split(`
|
|
245
254
|
`),J=W.split(`
|
|
246
255
|
`);for(let Y=0;Y<=Z.length-J.length;Y++){let H=Z.slice(Y,Y+J.length).join(`
|
|
247
|
-
`);if(H.trim()===Q)yield H}},
|
|
256
|
+
`);if(H.trim()===Q)yield H}},Q9=function*($,W){let Q=W.split(`
|
|
248
257
|
`);if(Q.length<3)return;if(Q[Q.length-1]==="")Q.pop();let Z=$.split(`
|
|
249
258
|
`),J=Q[0].trim(),Y=Q[Q.length-1].trim();for(let H=0;H<Z.length;H++){if(Z[H].trim()!==J)continue;for(let X=H+2;X<Z.length;X++)if(Z[X].trim()===Y){let G=Z.slice(H,X+1),V=G.join(`
|
|
250
|
-
`);if(G.length===Q.length){let K=0,z=0;for(let j=1;j<G.length-1;j++){let
|
|
259
|
+
`);if(G.length===Q.length){let K=0,z=0;for(let j=1;j<G.length-1;j++){let _=G[j].trim(),B=Q[j].trim();if(_.length>0||B.length>0){if(z++,_===B)K++}}if(z===0||K/z>=0.5){yield V;break}}break}}};class a$ extends k{name="Edit";riskLevel="high";description=`Performs exact string replacements in files.
|
|
251
260
|
|
|
252
261
|
Usage notes:
|
|
253
262
|
- When editing, preserve the exact indentation (tabs/spaces) from the original file
|
|
@@ -255,10 +264,10 @@ Usage notes:
|
|
|
255
264
|
- Use replace_all for replacing/renaming strings across the entire file
|
|
256
265
|
- old_string and new_string must be different
|
|
257
266
|
- If exact matching fails, the tool tries normalized variants (trimmed lines, whitespace, indentation, escapes)
|
|
258
|
-
- ALWAYS prefer editing existing files over creating new ones`;parameters={type:"object",properties:{file_path:{type:"string",description:"The absolute path to the file to modify"},old_string:{type:"string",description:"The text to replace"},new_string:{type:"string",description:"The text to replace it with (must be different from old_string)"},replace_all:{type:"boolean",description:"Replace all occurrences of old_string (default false)"}},required:["file_path","old_string","new_string"]};cwd;fileBlacklist;disableBlacklist;constructor($){super();this.cwd=$?.cwd??
|
|
267
|
+
- ALWAYS prefer editing existing files over creating new ones`;parameters={type:"object",properties:{file_path:{type:"string",description:"The absolute path to the file to modify"},old_string:{type:"string",description:"The text to replace"},new_string:{type:"string",description:"The text to replace it with (must be different from old_string)"},replace_all:{type:"boolean",description:"Replace all occurrences of old_string (default false)"}},required:["file_path","old_string","new_string"]};cwd;fileBlacklist;disableBlacklist;constructor($){super();this.cwd=$?.cwd??r8.cwd(),this.fileBlacklist=$?.fileBlacklist,this.disableBlacklist=$?.disableBlacklist===!0}setCwd($){this.cwd=$}getCwd(){return this.cwd}async execute($,W){let{file_path:Q,old_string:Z,new_string:J,replace_all:Y}=this.validateArgs($),H=S1.isAbsolute(Q)?Q:S1.resolve(this.cwd,Q),X=await i$(H,{cwd:this.cwd,blacklist:this.fileBlacklist,disabled:this.disableBlacklist,originalPath:Q});if(X.isBlocked)return I(X.message??`Access denied: ${Q}`);try{if((await l8(H)).isDirectory())return I(`Path is a directory, not a file: ${H}`)}catch(_){if(_.code==="ENOENT")return I(`File not found: ${H}`);throw _}let G=await d8(H,"utf-8"),V=this.replaceWithFallback(G,Z,J,Y??!1);if(V.kind==="not_found")return I(`old_string not found in file: ${H}
|
|
259
268
|
|
|
260
269
|
Searched for (including normalized variants):
|
|
261
|
-
${this.truncateForError(Z)}`);if(V.kind==="not_unique")return
|
|
270
|
+
${this.truncateForError(Z)}`);if(V.kind==="not_unique")return I("old_string matched multiple places in the file. Provide more context to make it unique, or set replace_all: true to replace all occurrences.");let{content:K,replacements:z}=V;await i8(H,K,"utf-8");let j={success:!0,replacements:z,filePath:H,message:`Successfully replaced ${z} occurrence${z>1?"s":""} in ${S1.basename(H)}`};return{content:[{type:"text",text:j.message}],structuredContent:j}}validateArgs($){let{file_path:W,old_string:Q,new_string:Z}=$;if(typeof W!=="string"||!W.trim())throw Error("file_path is required and must be a non-empty string");if(typeof Q!=="string")throw TypeError("old_string is required and must be a string");if(Q==="")throw Error("old_string cannot be empty");if(typeof Z!=="string")throw TypeError("new_string is required and must be a string");if(Q===Z)throw Error("new_string must be different from old_string");return{file_path:W.trim(),old_string:Q,new_string:Z,replace_all:$.replace_all===!0}}countOccurrences($,W){let Q=0,Z=$.indexOf(W);while(Z!==-1)Q++,Z=$.indexOf(W,Z+W.length);return Q}replaceWithFallback($,W,Q,Z){let J=!1,Y=[o8,a8,s8,t8,e8,$9,W9,Q9];for(let H of Y)for(let X of H($,W)){if(!X)continue;let G=this.countOccurrences($,X);if(G===0)continue;if(Z)return{kind:"ok",content:$.split(X).join(Q),replacements:G};if(G===1){let V=$.indexOf(X);return{kind:"ok",content:$.slice(0,V)+Q+$.slice(V+X.length),replacements:1}}J=!0}return J?{kind:"not_unique"}:{kind:"not_found"}}truncateForError($,W=200){if($.length<=W)return $;return`${$.slice(0,W)}... [truncated, ${$.length} chars total]`}}import{readdir as Z9,stat as pW}from"node:fs/promises";import c0 from"node:path";import J9 from"node:process";var P1=1000,Y9=20;function H9($){let W="",Q=0;while(Q<$.length){let Z=$[Q];if(Z==="*")if($[Q+1]==="*")if($[Q+2]==="/")W+="(?:.*\\/)?",Q+=3;else W+=".*",Q+=2;else W+="[^/]*",Q++;else if(Z==="?")W+="[^/]",Q++;else if(Z==="{"){let J=$.indexOf("}",Q);if(J!==-1){let Y=$.slice(Q+1,J).split(",");W+=`(?:${Y.map((H)=>X9(H)).join("|")})`,Q=J+1}else W+="\\{",Q++}else if(Z==="["){let J=$.indexOf("]",Q);if(J!==-1)W+=$.slice(Q,J+1),Q=J+1;else W+="\\[",Q++}else if(Z===".")W+="\\.",Q++;else if(Z==="/")W+="\\/",Q++;else if("()[]{}^$+|\\".includes(Z))W+=`\\${Z}`,Q++;else W+=Z,Q++}return new RegExp(`^${W}$`)}function X9($){return $.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}class s$ extends k{name="Glob";description=`Fast file pattern matching tool that works with any codebase size.
|
|
262
271
|
|
|
263
272
|
Usage notes:
|
|
264
273
|
- Supports glob patterns like "**/*.js" or "src/**/*.ts"
|
|
@@ -271,13 +280,13 @@ Supported patterns:
|
|
|
271
280
|
- \`**\` matches any sequence of characters including path separator
|
|
272
281
|
- \`?\` matches any single character
|
|
273
282
|
- \`{a,b}\` matches either a or b
|
|
274
|
-
- \`[abc]\` matches any character in brackets`;parameters={type:"object",properties:{pattern:{type:"string",description:"The glob pattern to match files against"},path:{type:"string",description:'The directory to search in. If not specified, the current working directory will be used. IMPORTANT: Omit this field to use the default directory. DO NOT enter "undefined" or "null" - simply omit it for the default behavior.'}},required:["pattern"]};cwd;fileBlacklist;disableBlacklist;constructor($){super();this.cwd=$?.cwd??
|
|
283
|
+
- \`[abc]\` matches any character in brackets`;parameters={type:"object",properties:{pattern:{type:"string",description:"The glob pattern to match files against"},path:{type:"string",description:'The directory to search in. If not specified, the current working directory will be used. IMPORTANT: Omit this field to use the default directory. DO NOT enter "undefined" or "null" - simply omit it for the default behavior.'}},required:["pattern"]};cwd;fileBlacklist;disableBlacklist;constructor($){super();this.cwd=$?.cwd??J9.cwd(),this.fileBlacklist=$?.fileBlacklist,this.disableBlacklist=$?.disableBlacklist===!0}setCwd($){this.cwd=$}getCwd(){return this.cwd}async execute($,W){let{pattern:Q,path:Z}=this.validateArgs($),J=Z?c0.isAbsolute(Z)?Z:c0.resolve(this.cwd,Z):this.cwd;try{if(!(await pW(J)).isDirectory())return I(`Path is not a directory: ${J}`)}catch(_){if(_.code==="ENOENT")return I(`Directory not found: ${J}`);throw _}let Y=Q;if(!Q.startsWith("**/")&&!Q.startsWith("/")&&!Q.startsWith("./"))Y=`**/${Q}`;let H=H9(Y),X=[],G=u0({cwd:this.cwd,blacklist:this.fileBlacklist,disabled:this.disableBlacklist});await this.walkDirectory(J,"",H,X,0,G),X.sort((_,B)=>B.mtime-_.mtime);let V=X.length>P1,K=X.slice(0,P1).map((_)=>_.path),z={files:K,totalMatches:X.length,truncated:V};return{content:[{type:"text",text:K.length>0?`Found ${X.length} file${X.length!==1?"s":""}${V?` (showing first ${P1})`:""}:
|
|
275
284
|
${K.join(`
|
|
276
|
-
`)}`:`No files found matching pattern: ${Q}`}],structuredContent:z}}validateArgs($){let W=$.pattern;if(typeof W!=="string"||!W.trim())throw Error("Pattern is required and must be a non-empty string");let Q;if($.path!==void 0&&$.path!==null&&$.path!=="undefined"&&$.path!=="null"){if(typeof $.path!=="string")throw TypeError("Path must be a string");Q=$.path.trim()||void 0}return{pattern:W.trim(),path:Q}}async walkDirectory($,W,Q,Z,J,Y){if(J>
|
|
285
|
+
`)}`:`No files found matching pattern: ${Q}`}],structuredContent:z}}validateArgs($){let W=$.pattern;if(typeof W!=="string"||!W.trim())throw Error("Pattern is required and must be a non-empty string");let Q;if($.path!==void 0&&$.path!==null&&$.path!=="undefined"&&$.path!=="null"){if(typeof $.path!=="string")throw TypeError("Path must be a string");Q=$.path.trim()||void 0}return{pattern:W.trim(),path:Q}}async walkDirectory($,W,Q,Z,J,Y){if(J>Y9)return;let H=W?c0.join($,W):$,X;try{X=await Z9(H,{withFileTypes:!0})}catch{return}for(let G of X){if(G.name.startsWith(".")||G.name==="node_modules")continue;let V=c0.join(H,G.name);if(Y.isBlocked(V))continue;let K=W?`${W}/${G.name}`:G.name;if(G.isDirectory())await this.walkDirectory($,K,Q,Z,J+1,Y);else if(G.isFile()){if(Q.test(K))try{let z=await pW(V);Z.push({path:K,mtime:z.mtimeMs})}catch{}}}}}import{Buffer as V9}from"node:buffer";import{spawn as w1}from"node:child_process";import{chmodSync as G9,existsSync as R0,mkdirSync as K9,statSync as j9}from"node:fs";import{copyFile as z9,mkdtemp as _9,readdir as B9,readFile as U9,rm as cW,stat as O9,writeFile as F9}from"node:fs/promises";import t from"node:path";import M$ from"node:process";import dW from"fast-glob";import q9 from"picomatch";var k$=5000,x1=60000,N9="BurntSushi/ripgrep",iW="latest",A9={"darwin-arm64":{arch:"aarch64",os:"apple-darwin"},"darwin-x64":{arch:"x86_64",os:"apple-darwin"},"linux-arm64":{arch:"aarch64",os:"unknown-linux-musl"},"linux-x64":{arch:"x86_64",os:"unknown-linux-musl"},"win32-x64":{arch:"x86_64",os:"pc-windows-msvc"},"win32-arm64":{arch:"aarch64",os:"pc-windows-msvc"}};function b1($){try{return j9($).size>1e4}catch{return!1}}function rW(){return M$.platform==="win32"?"rg.exe":"rg"}function y1(){let $=t.join(N0(),rW());return R0($)&&b1($)?$:null}function D9($){return $.code==="ENOENT"||$.message?.includes("ENOENT")||$.message?.includes("not found")}function nW($,W){return new Promise((Q,Z)=>{let J=w1($,W,{stdio:["ignore","pipe","pipe"]}),Y=[],H=[],X=0,G=0,V=Math.max(50000,k$*10);J.stdout?.on("data",(K)=>{if(X>=V)return;let z=K.toString();if(!z)return;let j=V-X;if(j<=0)return;let _=z.length>j?z.slice(0,j):z;Y.push(_),X+=_.length}),J.stderr?.on("data",(K)=>{if(G>=V)return;let z=K.toString();if(!z)return;let j=V-G;if(j<=0)return;let _=z.length>j?z.slice(0,j):z;H.push(_),G+=_.length}),J.on("error",(K)=>{Z(K)}),J.on("close",(K)=>{Q({exitCode:K,stdout:Y.length===1?Y[0]:Y.join(""),stderr:H.length===1?H[0]:H.join("")})})})}async function R9($,W){let Z=["-command",`Expand-Archive -Path '${$}' -DestinationPath '${W}' -Force`],{exitCode:J,stderr:Y}=await nW("powershell",Z);if(J!==0)throw Error(`zip extraction failed (exit ${J}): ${Y}
|
|
277
286
|
|
|
278
|
-
Ensure PowerShell is available on your system.`)}async function
|
|
287
|
+
Ensure PowerShell is available on your system.`)}async function E9($,W){let{exitCode:Q,stderr:Z}=await nW("tar",["-xzf",$,"-C",W]);if(Q!==0)throw Error(`tar extraction failed (exit ${Q}): ${Z}
|
|
279
288
|
|
|
280
|
-
Please install 'tar' (e.g., apt install tar, brew install gnu-tar).`)}async function
|
|
289
|
+
Please install 'tar' (e.g., apt install tar, brew install gnu-tar).`)}async function oW($,W){let Q=await B9($,{withFileTypes:!0});for(let Z of Q){let J=t.join($,Z.name);if(Z.isFile()&&Z.name===W)return J;if(Z.isDirectory()){let Y=await oW(J,W);if(Y)return Y}}return null}var D0=null,d0=null,l0=null;async function L9($){if($!=="latest")return $;if(l0)return l0;try{let W=new AbortController,Q=setTimeout(()=>W.abort(),30000);try{let Z=await fetch("https://api.github.com/repos/BurntSushi/ripgrep/releases/latest",{redirect:"follow",signal:W.signal});if(!Z.ok)throw Error(`HTTP ${Z.status}: ${Z.statusText}`);let Y=(await Z.json())?.tag_name;if(!Y)throw Error("Missing tag_name in GitHub response.");return l0=Y.startsWith("v")?Y.slice(1):Y,l0}finally{clearTimeout(Q)}}catch(W){return console.error(`[goat-chain] Failed to resolve latest ripgrep version: ${W instanceof Error?W.message:W}`),null}}async function M9($=iW){let W=`${M$.platform}-${M$.arch}`,Q=A9[W];if(!Q)return console.error(`[goat-chain] Unsupported platform for ripgrep: ${W}`),null;let Z=N0(),J=rW(),Y=t.join(Z,J);if(R0(Y)&&b1(Y))return Y;let H=await L9($);if(!H)return null;let{arch:X,os:G}=Q,V=M$.platform==="win32"?"zip":"tar.gz",K=`ripgrep-${H}-${X}-${G}.${V}`,z=`https://github.com/${N9}/releases/download/${H}/${K}`;console.log("[goat-chain] Downloading ripgrep binary...");let j=null,_=t.join(Z,K);try{if(!R0(Z))K9(Z,{recursive:!0});let B=new AbortController,F=setTimeout(()=>B.abort(),120000);try{let N=await fetch(z,{redirect:"follow",signal:B.signal});if(!N.ok)throw Error(`HTTP ${N.status}: ${N.statusText}`);let U=await N.arrayBuffer();await F9(_,V9.from(U))}finally{clearTimeout(F)}if(j=await _9(t.join(Z,"ripgrep-")),V==="zip")await R9(_,j);else await E9(_,j);let A=await oW(j,J);if(!A)throw Error("ripgrep binary not found in extracted archive.");if(await z9(A,Y),M$.platform!=="win32"&&R0(Y))G9(Y,493);if(!b1(Y))throw Error("Downloaded ripgrep binary failed validation.");return console.log("[goat-chain] ripgrep binary ready."),Y}catch(B){return console.error(`[goat-chain] Failed to download ripgrep: ${B instanceof Error?B.message:B}`),null}finally{if(await cW(_,{force:!0}).catch(()=>{}),j)await cW(j,{recursive:!0,force:!0}).catch(()=>{})}}async function T9($=iW){let W=y1();if(W)return W;return M9($)}async function S9(){if(D0!==null&&R0(D0))return D0;if(d0)return d0;return d0=(async()=>{let $=y1();if($)return D0=$,$;let W=await T9();if(W)return D0=W,W;return null})(),d0}function lW($){let W=Math.max(0,Math.floor(Number($)||0)),Q=[],Z=0;return{append(J){let Y=String(J??"");if(!Y||W===0)return{truncated:W===0&&Y.length>0};let H=W-Z;if(H<=0)return{truncated:!0};if(Y.length>H)return Q.push(Y.slice(0,H)),Z=W,{truncated:!0};return Q.push(Y),Z+=Y.length,{truncated:!1}},toString(){return Q.join("")},length(){return Z}}}class t$ extends k{name="Grep";description=`A powerful search tool built on ripgrep.
|
|
281
290
|
|
|
282
291
|
Usage notes:
|
|
283
292
|
- Supports full regex syntax (e.g., "log.*Error", "function\\s+\\w+")
|
|
@@ -285,47 +294,47 @@ Usage notes:
|
|
|
285
294
|
- Output modes: "content" shows matching lines, "files_with_matches" shows only file paths (default), "count" shows match counts
|
|
286
295
|
- Pattern syntax: Uses ripgrep (not grep) - literal braces need escaping (use \`interface\\{\\}\` to find \`interface{}\` in Go code)
|
|
287
296
|
- Multiline matching: By default patterns match within single lines only. For cross-line patterns, use multiline: true
|
|
288
|
-
- If ripgrep is not available, this tool falls back to a JS-based search (slower). You can opt into downloading a ripgrep binary via the GrepTool constructor option \`allowDownload: true\`.`;parameters={type:"object",properties:{pattern:{type:"string",description:"The regular expression pattern to search for in file contents"},path:{type:"string",description:"File or directory to search in. Defaults to current working directory."},glob:{type:"string",description:'Glob pattern to filter files (e.g. "*.js", "*.{ts,tsx}")'},output_mode:{type:"string",enum:["content","files_with_matches","count"],description:'Output mode: "content" shows matching lines, "files_with_matches" shows file paths (default), "count" shows match counts.'},"-B":{type:"number",description:'Number of lines to show before each match. Requires output_mode: "content".'},"-A":{type:"number",description:'Number of lines to show after each match. Requires output_mode: "content".'},"-C":{type:"number",description:'Number of lines to show before and after each match. Requires output_mode: "content".'},"-n":{type:"boolean",description:'Show line numbers in output. Requires output_mode: "content". Defaults to true.'},"-i":{type:"boolean",description:"Case insensitive search"},type:{type:"string",description:"File type to search (e.g., js, py, rust, go, java). More efficient than glob for standard file types."},head_limit:{type:"number",description:"Limit output to first N lines/entries. Defaults to 0 (unlimited)."},offset:{type:"number",description:"Skip first N lines/entries before applying head_limit. Defaults to 0."},multiline:{type:"boolean",description:"Enable multiline mode where . matches newlines and patterns can span lines. Default: false."}},required:["pattern"]};cwd;rgPath;fileBlacklist;disableBlacklist;allowDownload;constructor($){super();this.cwd=$?.cwd??
|
|
297
|
+
- If ripgrep is not available, this tool falls back to a JS-based search (slower). You can opt into downloading a ripgrep binary via the GrepTool constructor option \`allowDownload: true\`.`;parameters={type:"object",properties:{pattern:{type:"string",description:"The regular expression pattern to search for in file contents"},path:{type:"string",description:"File or directory to search in. Defaults to current working directory."},glob:{type:"string",description:'Glob pattern to filter files (e.g. "*.js", "*.{ts,tsx}")'},output_mode:{type:"string",enum:["content","files_with_matches","count"],description:'Output mode: "content" shows matching lines, "files_with_matches" shows file paths (default), "count" shows match counts.'},"-B":{type:"number",description:'Number of lines to show before each match. Requires output_mode: "content".'},"-A":{type:"number",description:'Number of lines to show after each match. Requires output_mode: "content".'},"-C":{type:"number",description:'Number of lines to show before and after each match. Requires output_mode: "content".'},"-n":{type:"boolean",description:'Show line numbers in output. Requires output_mode: "content". Defaults to true.'},"-i":{type:"boolean",description:"Case insensitive search"},type:{type:"string",description:"File type to search (e.g., js, py, rust, go, java). More efficient than glob for standard file types."},head_limit:{type:"number",description:"Limit output to first N lines/entries. Defaults to 0 (unlimited)."},offset:{type:"number",description:"Skip first N lines/entries before applying head_limit. Defaults to 0."},multiline:{type:"boolean",description:"Enable multiline mode where . matches newlines and patterns can span lines. Default: false."}},required:["pattern"]};cwd;rgPath;fileBlacklist;disableBlacklist;allowDownload;constructor($){super();this.cwd=$?.cwd??M$.cwd(),this.rgPath=$?.rgPath??"rg",this.allowDownload=$?.allowDownload===!0,this.fileBlacklist=$?.fileBlacklist,this.disableBlacklist=$?.disableBlacklist===!0}setCwd($){this.cwd=$}getCwd(){return this.cwd}async execute($,W){let Q=this.validateArgs($),Z=this.buildRgArgs(Q),J=await this.runRipgrep(Z,Q),Y=J.output||"[No matches found]";if(J.timedOut)Y+=`
|
|
289
298
|
[Search timed out]`;if(J.matchCount!==void 0)Y=`Found ${J.matchCount} match${J.matchCount!==1?"es":""}
|
|
290
|
-
${Y}`;return{content:[{type:"text",text:Y}],structuredContent:J,isError:J.exitCode!==null&&J.exitCode!==0&&J.exitCode!==1}}validateArgs($){let W=$.pattern;if(typeof W!=="string"||!W.trim())throw Error("Pattern is required and must be a non-empty string");let Q={pattern:W.trim()};if($.path!==void 0&&$.path!==null&&$.path!==""){if(typeof $.path!=="string")throw TypeError("Path must be a string");Q.path=$.path.trim()}if($.glob!==void 0&&$.glob!==null&&$.glob!==""){if(typeof $.glob!=="string")throw TypeError("Glob must be a string");Q.glob=$.glob.trim()}if($.type!==void 0&&$.type!==null&&$.type!==""){if(typeof $.type!=="string")throw TypeError("Type must be a string");Q.type=$.type.trim()}if($.output_mode!==void 0){let Y=["content","files_with_matches","count"];if(!Y.includes($.output_mode))throw Error(`Invalid output_mode. Must be one of: ${Y.join(", ")}`);Q.output_mode=$.output_mode}let Z=["-B","-A","-C","head_limit","offset"];for(let Y of Z)if($[Y]!==void 0&&$[Y]!==null){if(typeof $[Y]!=="number")throw TypeError(`${Y} must be a number`);Q[Y]=Math.max(0,Math.floor($[Y]))}let J=["-n","-i","multiline"];for(let Y of J)if($[Y]!==void 0&&$[Y]!==null)Q[Y]=Boolean($[Y]);return Q}buildRgArgs($){let W=[],Q=$.output_mode??"files_with_matches";if(Q==="files_with_matches")W.push("-l");else if(Q==="count")W.push("-c");if(Q==="content"){if($["-n"]!==!1)W.push("-n");if($["-B"]!==void 0&&$["-B"]>0)W.push("-B",String($["-B"]));if($["-A"]!==void 0&&$["-A"]>0)W.push("-A",String($["-A"]));if($["-C"]!==void 0&&$["-C"]>0)W.push("-C",String($["-C"]))}if($["-i"])W.push("-i");if($.multiline)W.push("-U","--multiline-dotall");if($.type)W.push("--type",$.type);if($.glob)W.push("--glob",$.glob);let Z=
|
|
291
|
-
[stderr]: ${
|
|
292
|
-
`).filter((
|
|
293
|
-
`)}let
|
|
294
|
-
`).filter((
|
|
295
|
-
... [output truncated]`:F,truncated:H,timedOut:Y,matchCount:
|
|
296
|
-
`)
|
|
297
|
-
`);if(o.length>
|
|
299
|
+
${Y}`;return{content:[{type:"text",text:Y}],structuredContent:J,isError:J.exitCode!==null&&J.exitCode!==0&&J.exitCode!==1}}validateArgs($){let W=$.pattern;if(typeof W!=="string"||!W.trim())throw Error("Pattern is required and must be a non-empty string");let Q={pattern:W.trim()};if($.path!==void 0&&$.path!==null&&$.path!==""){if(typeof $.path!=="string")throw TypeError("Path must be a string");Q.path=$.path.trim()}if($.glob!==void 0&&$.glob!==null&&$.glob!==""){if(typeof $.glob!=="string")throw TypeError("Glob must be a string");Q.glob=$.glob.trim()}if($.type!==void 0&&$.type!==null&&$.type!==""){if(typeof $.type!=="string")throw TypeError("Type must be a string");Q.type=$.type.trim()}if($.output_mode!==void 0){let Y=["content","files_with_matches","count"];if(!Y.includes($.output_mode))throw Error(`Invalid output_mode. Must be one of: ${Y.join(", ")}`);Q.output_mode=$.output_mode}let Z=["-B","-A","-C","head_limit","offset"];for(let Y of Z)if($[Y]!==void 0&&$[Y]!==null){if(typeof $[Y]!=="number")throw TypeError(`${Y} must be a number`);Q[Y]=Math.max(0,Math.floor($[Y]))}let J=["-n","-i","multiline"];for(let Y of J)if($[Y]!==void 0&&$[Y]!==null)Q[Y]=Boolean($[Y]);return Q}buildRgArgs($){let W=[],Q=$.output_mode??"files_with_matches";if(Q==="files_with_matches")W.push("-l");else if(Q==="count")W.push("-c");if(Q==="content"){if($["-n"]!==!1)W.push("-n");if($["-B"]!==void 0&&$["-B"]>0)W.push("-B",String($["-B"]));if($["-A"]!==void 0&&$["-A"]>0)W.push("-A",String($["-A"]));if($["-C"]!==void 0&&$["-C"]>0)W.push("-C",String($["-C"]))}if($["-i"])W.push("-i");if($.multiline)W.push("-U","--multiline-dotall");if($.type)W.push("--type",$.type);if($.glob)W.push("--glob",$.glob);let Z=m0({blacklist:this.fileBlacklist,disabled:this.disableBlacklist});for(let J of Z)W.push("--glob",J);if(W.push("--color","never"),W.push("--no-heading"),W.push("--regexp",$.pattern),$.path)W.push("--",$.path);return W}runRipgrep($,W,Q=!1){return new Promise((Z)=>{let J=lW(k$),Y=!1,H=!1,X=!1,G=null,V=!1;if(this.rgPath==="rg"){let _=y1();if(_)this.rgPath=_}let K=w1(this.rgPath,$,{cwd:this.cwd,env:M$.env,stdio:["ignore","pipe","pipe"]}),z=(_)=>{if(X)return;X=!0,Z(_)},j=setTimeout(()=>{Y=!0,K.kill("SIGTERM"),setTimeout(()=>{if(!K.killed)K.kill("SIGKILL")},5000)},x1);K.stdout?.on("data",(_)=>{let B=_.toString();if(J.append(B).truncated)H=!0,clearTimeout(j),K.kill("SIGTERM")}),K.stderr?.on("data",(_)=>{let B=_.toString();if(B.includes("error:")){if(J.append(`
|
|
300
|
+
[stderr]: ${B}`).truncated)H=!0,clearTimeout(j),K.kill("SIGTERM")}}),K.on("close",(_)=>{if(X)return;if(clearTimeout(j),G||_!==null&&_<0){if(!V)this.runJsSearch(W).then(z);return}let B=J.toString(),F=B;if(W.offset||W.head_limit){let N=B.split(`
|
|
301
|
+
`).filter((D)=>D.trim()),U=W.offset??0,R=W.head_limit??N.length;F=N.slice(U,U+R).join(`
|
|
302
|
+
`)}let A;if(W.output_mode==="count")A=F.split(`
|
|
303
|
+
`).filter((N)=>N.trim()).reduce((N,U)=>{let R=U.match(/:(\d+)$/);return N+(R?Number.parseInt(R[1],10):0)},0);z({exitCode:_,output:H?`${F}
|
|
304
|
+
... [output truncated]`:F,truncated:H,timedOut:Y,matchCount:A})}),K.on("error",(_)=>{if(X)return;G=_,V=!0,clearTimeout(j);let B=_;if(this.allowDownload&&!Q&&D9(B)){(async()=>{try{let A=await S9();if(A){this.rgPath=A;let N=await this.runRipgrep($,W,!0);z(N);return}}catch{}let F=await this.runJsSearch(W);z(F)})();return}this.runJsSearch(W).then(z)})})}async runJsSearch($){let W=!1,Q=!1,Z=setTimeout(()=>{W=!0},x1),J=$.output_mode??"files_with_matches",Y=$["-B"]??0,H=$["-A"]??0,X=$["-C"]??0;if(X>0)Y=Math.max(Y,X),H=Math.max(H,X);let G=Boolean($["-i"]),V=Boolean($.multiline),K=`${G?"i":""}${V?"sm":""}`,z=null,j=null;try{if(V)j=new RegExp($.pattern,`${K}g`);else z=new RegExp($.pattern,K)}catch(M){return clearTimeout(Z),{exitCode:2,engine:"js",output:`Invalid regex pattern: ${M.message}`,truncated:!1,timedOut:!1}}let _=$.path??".",B=t.isAbsolute(_)?_:t.resolve(this.cwd,_),F=t.isAbsolute(_),A=u0({cwd:this.cwd,blacklist:this.fileBlacklist,disabled:this.disableBlacklist}),N;try{N=await O9(B)}catch{return clearTimeout(Z),{exitCode:2,engine:"js",output:`Search path not found: ${_}`,truncated:!1,timedOut:!1}}let U=[],R=dW.default??dW;if(typeof R!=="function")return clearTimeout(Z),this.runSystemGrep($);let q=B;if(N.isFile()){let M=A.match(B);if(M)return clearTimeout(Z),{exitCode:2,engine:"js",output:E1(_,M),truncated:!1,timedOut:!1};U=[B],q=t.dirname(B)}else if(N.isDirectory()){q=B;try{U=await R("**/*",{cwd:q,absolute:!0,onlyFiles:!0,dot:!0})}catch{return clearTimeout(Z),this.runSystemGrep($)}}else return clearTimeout(Z),{exitCode:2,engine:"js",output:`Search path not found: ${_}`,truncated:!1,timedOut:!1};U.sort();let D=[],O=!1,T=0,S=(M)=>{let E=M.length+1;if(T+E>k$)return Q=!0,!1;return D.push(M),T+=E,!0},f={js:[".js",".cjs",".mjs"],jsx:[".jsx"],ts:[".ts",".tsx",".d.ts"],tsx:[".tsx"],json:[".json"],md:[".md",".markdown"],py:[".py"],go:[".go"],rs:[".rs"],java:[".java"],c:[".c",".h"],cpp:[".cc",".cpp",".cxx",".hpp",".hh",".hxx",".h"]},L=(M)=>{if(!$.type)return!0;let E=$.type.toLowerCase(),w=f[E]??[E.startsWith(".")?E:`.${E}`],x=M.toLowerCase();return w.some((h)=>x.endsWith(h))},y=(M)=>{if(F)return M;return t.relative(this.cwd,M)||t.basename(M)},b=$.glob,u=q9.isMatch,g=J==="content"?$["-n"]!==!1:!1;for(let M of U){if(W)break;if(T>=k$){Q=!0;break}if(!L(M))continue;if(b&&u&&!u(t.basename(M),b))continue;if(A.isBlocked(M))continue;let E="";try{E=await U9(M,"utf-8")}catch{continue}if(!E||E.includes("\x00"))continue;let w=y(M);if(!V){let i=E.split(/\r?\n/),m=new Set;for(let Q$=0;Q$<i.length;Q$++)if(z.test(i[Q$]))m.add(Q$+1);if(m.size===0)continue;O=!0;let a=m.size;if(J==="files_with_matches"){if(!S(w))break;continue}if(J==="count"){if(!S(`${w}:${a}`))break;continue}let H$=new Set(m);if(Y>0||H>0){let Q$=i.length;for(let Z$ of m){let H0=Math.max(1,Z$-Y),R4=Math.min(Q$,Z$+H);for(let s0=H0;s0<=R4;s0++)H$.add(s0)}}let F$=!1;for(let Q$ of Array.from(H$).sort((Z$,H0)=>Z$-H0)){let Z$=i[Q$-1]??"",H0=g?`${w}:${Q$}:${Z$}`:`${w}:${Z$}`;if(!S(H0)){F$=!0;break}}if(F$)break;continue}let x=E.split(/\r?\n/),h=[0];for(let i=0;i<E.length;i++)if(E[i]===`
|
|
305
|
+
`)h.push(i+1);let j$=(i)=>{let m=0,a=h.length-1;while(m<=a){let H$=Math.floor((m+a)/2);if(h[H$]<=i)m=H$+1;else a=H$-1}return Math.max(a+1,1)};j.lastIndex=0;let Y$=new Set;for(let i of E.matchAll(j)){let m=i.index??0,a=i[0]?.length??0,H$=Math.max(m,m+a-1),F$=j$(m),Q$=j$(H$);for(let Z$=F$;Z$<=Q$;Z$++)Y$.add(Z$)}if(Y$.size===0)continue;O=!0;let x$=Y$.size;if(J==="files_with_matches"){if(!S(w))break;continue}if(J==="count"){if(!S(`${w}:${x$}`))break;continue}let Y0=new Set(Y$);if(Y>0||H>0){let i=x.length;for(let m of Y$){let a=Math.max(1,m-Y),H$=Math.min(i,m+H);for(let F$=a;F$<=H$;F$++)Y0.add(F$)}}let L0=!1;for(let i of Array.from(Y0).sort((m,a)=>m-a)){let m=x[i-1]??"",a=g?`${w}:${i}:${m}`:`${w}:${m}`;if(!S(a)){L0=!0;break}}if(L0)break}clearTimeout(Z);let c=D;if($.offset||$.head_limit){let M=D.filter((x)=>x.trim()),E=$.offset??0,w=$.head_limit??M.length;c=M.slice(E,E+w)}let o=c.join(`
|
|
306
|
+
`);if(o.length>k$)o=o.slice(0,k$),Q=!0;let l;if(J==="count")l=o.split(`
|
|
298
307
|
`).filter((M)=>M.trim()).reduce((M,E)=>{let w=E.split(":").pop(),x=w?Number.parseInt(w,10):Number.NaN;return M+(Number.isFinite(x)?x:0)},0);return{exitCode:O?0:1,engine:"js",output:Q?`${o}
|
|
299
|
-
... [output truncated]`:o,truncated:Q,timedOut:W,matchCount:l}}runSystemGrep($){return new Promise((W)=>{let Q=
|
|
300
|
-
[stderr]: ${K}`).truncated)J=!0,clearTimeout(G),X.kill("SIGTERM")}}),X.on("close",(V)=>{clearTimeout(G);let K=Q.toString(),z=K;if($.offset||$.head_limit){let
|
|
301
|
-
`).filter((
|
|
308
|
+
... [output truncated]`:o,truncated:Q,timedOut:W,matchCount:l}}runSystemGrep($){return new Promise((W)=>{let Q=lW(k$),Z=!1,J=!1,Y=[];Y.push("-R","-E","-I");let H=$.output_mode??"files_with_matches";if(H==="files_with_matches")Y.push("-l");else if(H==="count")Y.push("-c");else Y.push("-n");if(H==="content"){if($["-B"]!==void 0&&$["-B"]>0)Y.push("-B",String($["-B"]));if($["-A"]!==void 0&&$["-A"]>0)Y.push("-A",String($["-A"]));if($["-C"]!==void 0&&$["-C"]>0)Y.push("-C",String($["-C"]))}if($["-i"])Y.push("-i");if(Y.push($.pattern),$.path)Y.push($.path);else Y.push(".");let X=w1("grep",Y,{cwd:this.cwd,env:M$.env,stdio:["ignore","pipe","pipe"]}),G=setTimeout(()=>{Z=!0,X.kill("SIGTERM"),setTimeout(()=>{if(!X.killed)X.kill("SIGKILL")},5000)},x1);X.stdout?.on("data",(V)=>{let K=V.toString();if(Q.append(K).truncated)J=!0,clearTimeout(G),X.kill("SIGTERM")}),X.stderr?.on("data",(V)=>{let K=V.toString();if(K.trim()){if(Q.append(`
|
|
309
|
+
[stderr]: ${K}`).truncated)J=!0,clearTimeout(G),X.kill("SIGTERM")}}),X.on("close",(V)=>{clearTimeout(G);let K=Q.toString(),z=K;if($.offset||$.head_limit){let _=K.split(`
|
|
310
|
+
`).filter((A)=>A.trim()),B=$.offset??0,F=$.head_limit??_.length;z=_.slice(B,B+F).join(`
|
|
302
311
|
`)}let j;if(H==="count")j=z.split(`
|
|
303
|
-
`).filter((
|
|
304
|
-
... [output truncated]`:z,truncated:J,timedOut:Z,matchCount:j})}),X.on("error",(V)=>{clearTimeout(G),W({exitCode:1,engine:"grep",output:`Failed to execute grep: ${V.message}.`,truncated:!1,timedOut:!1})})})}}import{readFile as
|
|
312
|
+
`).filter((_)=>_.trim()).reduce((_,B)=>{let F=B.split(":").pop(),A=F?Number.parseInt(F,10):Number.NaN;return _+(Number.isFinite(A)?A:0)},0);W({exitCode:V,engine:"grep",output:J?`${z}
|
|
313
|
+
... [output truncated]`:z,truncated:J,timedOut:Z,matchCount:j})}),X.on("error",(V)=>{clearTimeout(G),W({exitCode:1,engine:"grep",output:`Failed to execute grep: ${V.message}.`,truncated:!1,timedOut:!1})})})}}import{readFile as i0,stat as P9}from"node:fs/promises";import h$ from"node:path";import x9 from"node:process";var aW=2000,C1=2000,w9=new Set([".png",".jpg",".jpeg",".gif",".bmp",".ico",".webp",".svg",".pdf",".zip",".tar",".gz",".rar",".7z",".exe",".dll",".so",".dylib",".mp3",".mp4",".avi",".mov",".wav",".woff",".woff2",".ttf",".eot"]),b9={".png":"image/png",".jpg":"image/jpeg",".jpeg":"image/jpeg",".gif":"image/gif",".webp":"image/webp",".svg":"image/svg+xml",".pdf":"application/pdf",".json":"application/json",".js":"text/javascript",".ts":"text/typescript",".html":"text/html",".css":"text/css",".md":"text/markdown",".txt":"text/plain"};class e$ extends k{name="Read";_cwd;_allowedDirectory;_fileBlacklist;_disableBlacklist;constructor($){super();this._cwd=$?.cwd??x9.cwd(),this._allowedDirectory=$?.allowedDirectory,this._fileBlacklist=$?.fileBlacklist,this._disableBlacklist=$?.disableBlacklist===!0}get description(){let $=`Reads a file from the local filesystem. You can access any file directly by using this tool.
|
|
305
314
|
|
|
306
315
|
Usage notes:
|
|
307
316
|
- Current working directory: ${this._cwd}
|
|
308
317
|
- Supports both absolute paths and relative paths (relative to cwd)
|
|
309
318
|
- IMPORTANT: Do NOT guess file paths. Use Glob to search for files first if unsure.
|
|
310
|
-
- By default, it reads up to ${
|
|
319
|
+
- By default, it reads up to ${aW} lines starting from the beginning
|
|
311
320
|
- You can optionally specify a line offset and limit for large files
|
|
312
|
-
- Any lines longer than ${
|
|
321
|
+
- Any lines longer than ${C1} characters will be truncated
|
|
313
322
|
- Results are returned with line numbers (like cat -n format)
|
|
314
323
|
- Can read images (PNG, JPG, etc.), PDFs, and Jupyter notebooks
|
|
315
324
|
- You can call multiple tools in parallel to read multiple files at once`;if(this._allowedDirectory)return`${$}
|
|
316
325
|
- IMPORTANT: Files can ONLY be read from within: ${this._allowedDirectory}
|
|
317
|
-
- Use paths within ${this._allowedDirectory}/ (e.g., ${this._allowedDirectory}/filename.html)`;return $}get parameters(){return{type:"object",properties:{file_path:{type:"string",description:this._allowedDirectory?`The path to the file to read (must be within ${this._allowedDirectory})`:`The path to the file to read (absolute or relative to ${this._cwd})`},offset:{type:"number",description:"The line number to start reading from (1-based). Only provide if the file is too large to read at once."},limit:{type:"number",description:"The number of lines to read. Only provide if the file is too large to read at once."}},required:["file_path"]}}setCwd($){this._cwd=$}getCwd(){return this._cwd}setAllowedDirectory($){this._allowedDirectory=$}getAllowedDirectory(){return this._allowedDirectory}async execute($,W){let{file_path:Q,offset:Z,limit:J}=this.validateArgs($),Y=
|
|
326
|
+
- Use paths within ${this._allowedDirectory}/ (e.g., ${this._allowedDirectory}/filename.html)`;return $}get parameters(){return{type:"object",properties:{file_path:{type:"string",description:this._allowedDirectory?`The path to the file to read (must be within ${this._allowedDirectory})`:`The path to the file to read (absolute or relative to ${this._cwd})`},offset:{type:"number",description:"The line number to start reading from (1-based). Only provide if the file is too large to read at once."},limit:{type:"number",description:"The number of lines to read. Only provide if the file is too large to read at once."}},required:["file_path"]}}setCwd($){this._cwd=$}getCwd(){return this._cwd}setAllowedDirectory($){this._allowedDirectory=$}getAllowedDirectory(){return this._allowedDirectory}async execute($,W){let{file_path:Q,offset:Z,limit:J}=this.validateArgs($),Y=h$.isAbsolute(Q)?Q:h$.resolve(this._cwd,Q);if(this._allowedDirectory){let j=h$.resolve(this._allowedDirectory),_=h$.resolve(Y);if(!_.startsWith(j+h$.sep)&&_!==j)return I(`Access denied: ${Q}
|
|
318
327
|
Files can only be read from within: ${this._allowedDirectory}
|
|
319
|
-
Please use a path like: ${this._allowedDirectory}/<filename>`)}let H=await
|
|
328
|
+
Please use a path like: ${this._allowedDirectory}/<filename>`)}let H=await i$(Y,{cwd:this._cwd,blacklist:this._fileBlacklist,disabled:this._disableBlacklist,originalPath:Q});if(H.isBlocked)return I(H.message??`Access denied: ${Q}`);let X;try{X=await P9(Y)}catch(j){if(j.code==="ENOENT")return I(`File not found: ${Y}`);throw j}if(X.isDirectory())return I(`Path is a directory, not a file: ${Y}. Use ls command via Bash tool to read directories.`);let G=h$.extname(Y).toLowerCase(),V=w9.has(G),K=b9[G],z;if(V){if(z=await this.handleBinaryFile(Y,X.size,K),K?.startsWith("image/"))return{content:[{type:"image",data:(await i0(Y)).toString("base64"),mimeType:K}],structuredContent:z}}else if(G===".ipynb")z=await this.handleJupyterNotebook(Y,X.size,Z,J);else z=await this.handleTextFile(Y,X.size,Z,J);return{content:[{type:"text",text:z.content}],structuredContent:z}}validateArgs($){let W=$.file_path;if(typeof W!=="string"||!W.trim())throw Error("file_path is required and must be a non-empty string");let Q={file_path:W.trim()};if($.offset!==void 0&&$.offset!==null){if(typeof $.offset!=="number")throw TypeError("offset must be a number");Q.offset=Math.max(1,Math.floor($.offset))}if($.limit!==void 0&&$.limit!==null){if(typeof $.limit!=="number")throw TypeError("limit must be a number");Q.limit=Math.max(1,Math.floor($.limit))}return Q}async handleBinaryFile($,W,Q){let J=(await i0($)).toString("base64");return{content:`[Binary file: ${h$.basename($)}]
|
|
320
329
|
Size: ${this.formatSize(W)}
|
|
321
330
|
MIME type: ${Q??"unknown"}
|
|
322
331
|
Base64 encoded content:
|
|
323
|
-
${J}`,totalLines:1,linesReturned:1,startLine:1,truncated:!1,fileSize:W,isBinary:!0,mimeType:Q}}async handleJupyterNotebook($,W,Q,Z){let J=await
|
|
324
|
-
`)),V.outputs&&V.outputs.length>0){X.push("--- Output ---");for(let
|
|
325
|
-
`))}else if(
|
|
326
|
-
`))}}}X.push("")}return this.formatOutput(X,W,Q,Z)}async handleTextFile($,W,Q,Z){let J=await
|
|
327
|
-
`);return this.formatOutput(Y,W,Q,Z)}formatOutput($,W,Q,Z){let J=$.length,Y=Q??1,H=Z??
|
|
328
|
-
`),totalLines:J,linesReturned:V.length,startLine:Y,truncated:K,fileSize:W,isBinary:!1}}formatSize($){let W=["B","KB","MB","GB"],Q=$,Z=0;while(Q>=1024&&Z<W.length-1)Q/=1024,Z++;return`${Q.toFixed(Z===0?0:2)} ${W[Z]}`}}class
|
|
332
|
+
${J}`,totalLines:1,linesReturned:1,startLine:1,truncated:!1,fileSize:W,isBinary:!0,mimeType:Q}}async handleJupyterNotebook($,W,Q,Z){let J=await i0($,"utf-8"),Y;try{Y=JSON.parse(J)}catch{throw Error(`Invalid Jupyter notebook format: ${$}`)}let H=Y.cells||[],X=[];for(let G=0;G<H.length;G++){let V=H[G],K=G+1,z=V.cell_type||"unknown";X.push(`--- Cell ${K} (${z}) ---`);let j=Array.isArray(V.source)?V.source.join(""):V.source||"";if(X.push(...j.split(`
|
|
333
|
+
`)),V.outputs&&V.outputs.length>0){X.push("--- Output ---");for(let _ of V.outputs)if(_.text){let B=Array.isArray(_.text)?_.text.join(""):_.text;X.push(...B.split(`
|
|
334
|
+
`))}else if(_.data){if(_.data["text/plain"]){let B=Array.isArray(_.data["text/plain"])?_.data["text/plain"].join(""):_.data["text/plain"];X.push(...B.split(`
|
|
335
|
+
`))}}}X.push("")}return this.formatOutput(X,W,Q,Z)}async handleTextFile($,W,Q,Z){let J=await i0($,"utf-8");if(J.length===0)return{content:"[File is empty]",totalLines:0,linesReturned:0,startLine:1,truncated:!1,fileSize:W,isBinary:!1};let Y=J.split(`
|
|
336
|
+
`);return this.formatOutput(Y,W,Q,Z)}formatOutput($,W,Q,Z){let J=$.length,Y=Q??1,H=Z??aW,X=Y-1,G=Math.min(X+H,J),V=$.slice(X,G),K=!1;return{content:V.map((j,_)=>{let B=Y+_,F=String(B).padStart(6," "),A=j;if(j.length>C1)A=`${j.slice(0,C1)}... [truncated]`,K=!0;return`${F}|${A}`}).join(`
|
|
337
|
+
`),totalLines:J,linesReturned:V.length,startLine:Y,truncated:K,fileSize:W,isBinary:!1}}formatSize($){let W=["B","KB","MB","GB"],Q=$,Z=0;while(Q>=1024&&Z<W.length-1)Q/=1024,Z++;return`${Q.toFixed(Z===0?0:2)} ${W[Z]}`}}class $0 extends k{name="TodoPlan";riskLevel="safe";description=`Use this tool to draft a structured task list in plan mode.
|
|
329
338
|
|
|
330
339
|
This tool only generates a plan for review and does NOT update any execution state.
|
|
331
340
|
Use TodoWrite in agent mode when you are actively executing tasks.
|
|
@@ -348,7 +357,7 @@ Task States:
|
|
|
348
357
|
Task descriptions have two forms:
|
|
349
358
|
- content: Imperative form (e.g., "Run tests")
|
|
350
359
|
- activeForm: Present continuous form (e.g., "Running tests")`;parameters={type:"object",properties:{todos:{type:"array",items:{type:"object",properties:{content:{type:"string",minLength:1,description:'The task description in imperative form (e.g., "Run tests")'},status:{type:"string",enum:["pending","in_progress","completed"],description:"Current status of the task"},activeForm:{type:"string",minLength:1,description:'The task description in present continuous form (e.g., "Running tests")'}},required:["content","status","activeForm"]},description:"The drafted todo list"}},required:["todos"]};async execute($,W){let{todos:Q}=this.validateArgs($),Z=Q.filter((V)=>V.status==="pending").length,J=Q.filter((V)=>V.status==="in_progress").length,Y=Q.filter((V)=>V.status==="completed").length,H=[];if(Y>0)H.push(`${Y} completed`);if(J>0)H.push(`${J} in progress`);if(Z>0)H.push(`${Z} pending`);let X=this.formatTodoList(Q,H);return{content:[{type:"text",text:X}],structuredContent:{success:!0,todos:Q,pendingCount:Z,inProgressCount:J,completedCount:Y,message:X}}}validateArgs($){let W=$.todos;if(!Array.isArray(W))throw TypeError("todos is required and must be an array");let Q=[],Z=["pending","in_progress","completed"];for(let Y=0;Y<W.length;Y++){let H=W[Y];if(typeof H!=="object"||H===null)throw TypeError(`todos[${Y}] must be an object`);let{content:X,status:G,activeForm:V}=H;if(typeof X!=="string"||!X.trim())throw Error(`todos[${Y}].content is required and must be a non-empty string`);if(typeof G!=="string"||!Z.includes(G))throw Error(`todos[${Y}].status must be one of: ${Z.join(", ")}`);if(typeof V!=="string"||!V.trim())throw Error(`todos[${Y}].activeForm is required and must be a non-empty string`);Q.push({content:X.trim(),status:G,activeForm:V.trim()})}let J=Q.filter((Y)=>Y.status==="in_progress");if(J.length>1)console.warn(`Warning: ${J.length} tasks are in_progress. Ideally only one task should be in_progress at a time.`);return{todos:Q}}formatTodoList($,W){if($.length===0)return"Plan todo list is empty";let Q=[],Z=W.length>0?W.join(", "):"0 pending";Q.push(`Plan todo list drafted: ${Z}`),Q.push(""),Q.push("Todos:");for(let J=0;J<$.length;J++){let Y=$[J];Q.push(`${J+1}. [${Y.status}] ${Y.content}`),Q.push(` activeForm: ${Y.activeForm}`)}return Q.join(`
|
|
351
|
-
`)}}class
|
|
360
|
+
`)}}class W0 extends k{name="TodoWrite";riskLevel="low";description=`Use this tool to create and manage a structured task list for your current coding session.
|
|
352
361
|
|
|
353
362
|
When to use:
|
|
354
363
|
- Complex multi-step tasks (3+ steps)
|
|
@@ -370,14 +379,14 @@ Task States:
|
|
|
370
379
|
Task descriptions have two forms:
|
|
371
380
|
- content: Imperative form (e.g., "Run tests")
|
|
372
381
|
- activeForm: Present continuous form (e.g., "Running tests")`;parameters={type:"object",properties:{todos:{type:"array",items:{type:"object",properties:{content:{type:"string",minLength:1,description:'The task description in imperative form (e.g., "Run tests")'},status:{type:"string",enum:["pending","in_progress","completed"],description:"Current status of the task"},activeForm:{type:"string",minLength:1,description:'The task description in present continuous form (e.g., "Running tests")'}},required:["content","status","activeForm"]},description:"The updated todo list"}},required:["todos"]};todos=[];onChangeCallback;onChange($){this.onChangeCallback=$}getTodos(){return[...this.todos]}clear(){this.todos=[],this.onChangeCallback?.(this.todos)}async execute($,W){let{todos:Q}=this.validateArgs($);this.todos=Q,this.onChangeCallback?.(this.todos);let Z=Q.filter((V)=>V.status==="pending").length,J=Q.filter((V)=>V.status==="in_progress").length,Y=Q.filter((V)=>V.status==="completed").length,H=[];if(Y>0)H.push(`${Y} completed`);if(J>0)H.push(`${J} in progress`);if(Z>0)H.push(`${Z} pending`);let X=this.formatTodoList(this.todos,H),G={success:!0,todos:this.todos,pendingCount:Z,inProgressCount:J,completedCount:Y,message:X};return{content:[{type:"text",text:X}],structuredContent:G}}validateArgs($){let W=$.todos;if(!Array.isArray(W))throw TypeError("todos is required and must be an array");let Q=[],Z=["pending","in_progress","completed"];for(let Y=0;Y<W.length;Y++){let H=W[Y];if(typeof H!=="object"||H===null)throw TypeError(`todos[${Y}] must be an object`);let{content:X,status:G,activeForm:V}=H;if(typeof X!=="string"||!X.trim())throw Error(`todos[${Y}].content is required and must be a non-empty string`);if(typeof G!=="string"||!Z.includes(G))throw Error(`todos[${Y}].status must be one of: ${Z.join(", ")}`);if(typeof V!=="string"||!V.trim())throw Error(`todos[${Y}].activeForm is required and must be a non-empty string`);Q.push({content:X.trim(),status:G,activeForm:V.trim()})}let J=Q.filter((Y)=>Y.status==="in_progress");if(J.length>1)console.warn(`Warning: ${J.length} tasks are in_progress. Ideally only one task should be in_progress at a time.`);return{todos:Q}}formatTodoList($,W){if($.length===0)return"Todo list is empty";let Q=[],Z=W.length>0?W.join(", "):"0 pending";Q.push(`Todo list updated: ${Z}`),Q.push(""),Q.push("Todos:");for(let J=0;J<$.length;J++){let Y=$[J];Q.push(`${J+1}. [${Y.status}] ${Y.content}`),Q.push(` activeForm: ${Y.activeForm}`)}return Q.join(`
|
|
373
|
-
`)}}import
|
|
382
|
+
`)}}import y9 from"node:process";class Q0 extends k{name="WebSearch";riskLevel="medium";description=`Allows the agent to search the web and use the results to inform responses.
|
|
374
383
|
|
|
375
384
|
Usage notes:
|
|
376
385
|
- Provides up-to-date information for current events and recent data
|
|
377
386
|
- Returns search results with titles, links, and snippets
|
|
378
387
|
- Use this tool for accessing information beyond the knowledge cutoff
|
|
379
|
-
- After answering, include a "Sources:" section with relevant URLs as markdown hyperlinks`;parameters={type:"object",properties:{query:{type:"string",minLength:2,description:"The search query to use"}},required:["query"]};apiKey;apiEndpoint;numResults;constructor($){super();this.apiKey=$?.apiKey??
|
|
380
|
-
`)}}import{mkdir as
|
|
388
|
+
- After answering, include a "Sources:" section with relevant URLs as markdown hyperlinks`;parameters={type:"object",properties:{query:{type:"string",minLength:2,description:"The search query to use"}},required:["query"]};apiKey;apiEndpoint;numResults;constructor($){super();this.apiKey=$?.apiKey??y9.env.SERPER_API_KEY??"",this.apiEndpoint=$?.apiEndpoint??"https://google.serper.dev/search?format=json",this.numResults=$?.numResults??10}setApiKey($){this.apiKey=$}async execute($,W){let{query:Q}=this.validateArgs($);if(!this.apiKey)return I("Serper API key is not configured. Set SERPER_API_KEY environment variable or pass apiKey in constructor.");try{let Z=await fetch(this.apiEndpoint,{method:"POST",headers:{"X-API-KEY":this.apiKey,"Content-Type":"application/json"},body:JSON.stringify({q:Q,num:this.numResults})});if(!Z.ok){let G=await Z.text();return I(`Serper API error (${Z.status}): ${G}`)}let Y=((await Z.json()).organic??[]).map((G,V)=>({title:G.title,link:G.link,snippet:G.snippet,position:G.position??V+1})),H=this.formatMarkdown(Q,Y),X={success:!0,query:Q,results:Y,totalResults:Y.length,markdown:H};return{content:[{type:"text",text:H}],structuredContent:X}}catch(Z){return I(`Failed to execute search: ${Z instanceof Error?Z.message:String(Z)}`)}}validateArgs($){let W=$.query;if(typeof W!=="string"||W.trim().length<2)throw Error("query is required and must be at least 2 characters");return{query:W.trim()}}formatMarkdown($,W){if(W.length===0)return`No results found for: "${$}"`;let Q=[`## Search Results for: "${$}"`,""];for(let Z of W)Q.push(`### ${Z.position}. [${Z.title}](${Z.link})`),Q.push(""),Q.push(Z.snippet),Q.push("");Q.push("---"),Q.push(""),Q.push("**Sources:**");for(let Z of W)Q.push(`- [${Z.title}](${Z.link})`);return Q.join(`
|
|
389
|
+
`)}}import{mkdir as C9,stat as I9,writeFile as v9}from"node:fs/promises";import T$ from"node:path";import f9 from"node:process";class Z0 extends k{name="Write";riskLevel="high";_cwd;_allowedDirectory;_fileBlacklist;_disableBlacklist;constructor($){super();this._cwd=$?.cwd??f9.cwd(),this._allowedDirectory=$?.allowedDirectory,this._fileBlacklist=$?.fileBlacklist,this._disableBlacklist=$?.disableBlacklist===!0}get description(){let $=`Writes a file to the local filesystem.
|
|
381
390
|
|
|
382
391
|
Usage notes:
|
|
383
392
|
- Current working directory: ${this._cwd}
|
|
@@ -388,14 +397,34 @@ Usage notes:
|
|
|
388
397
|
- ALWAYS prefer editing existing files over writing new ones
|
|
389
398
|
- NEVER proactively create documentation files (*.md) or README files unless explicitly requested`;if(this._allowedDirectory)return`${$}
|
|
390
399
|
- IMPORTANT: Files can ONLY be written within: ${this._allowedDirectory}
|
|
391
|
-
- Use paths within ${this._allowedDirectory}/ (e.g., ${this._allowedDirectory}/filename.html)`;return $}get parameters(){return{type:"object",properties:{file_path:{type:"string",description:this._allowedDirectory?`The path to the file to write (must be within ${this._allowedDirectory})`:`The path to the file to write (absolute or relative to ${this._cwd})`},content:{type:"string",description:"The content to write to the file"}},required:["file_path","content"]}}setCwd($){this._cwd=$}getCwd(){return this._cwd}setAllowedDirectory($){this._allowedDirectory=$}getAllowedDirectory(){return this._allowedDirectory}async execute($,W){let{file_path:Q,content:Z}=this.validateArgs($),J=
|
|
400
|
+
- Use paths within ${this._allowedDirectory}/ (e.g., ${this._allowedDirectory}/filename.html)`;return $}get parameters(){return{type:"object",properties:{file_path:{type:"string",description:this._allowedDirectory?`The path to the file to write (must be within ${this._allowedDirectory})`:`The path to the file to write (absolute or relative to ${this._cwd})`},content:{type:"string",description:"The content to write to the file"}},required:["file_path","content"]}}setCwd($){this._cwd=$}getCwd(){return this._cwd}setAllowedDirectory($){this._allowedDirectory=$}getAllowedDirectory(){return this._allowedDirectory}async execute($,W){let{file_path:Q,content:Z}=this.validateArgs($),J=T$.isAbsolute(Q)?Q:T$.resolve(this._cwd,Q);if(this._allowedDirectory){let K=T$.resolve(this._allowedDirectory),z=T$.resolve(J);if(!z.startsWith(K+T$.sep)&&z!==K)return I(`Access denied: ${Q}
|
|
392
401
|
Files can only be written within: ${this._allowedDirectory}
|
|
393
|
-
Please use a path like: ${this._allowedDirectory}/<filename>`)}let Y=await
|
|
394
|
-
`);function
|
|
402
|
+
Please use a path like: ${this._allowedDirectory}/<filename>`)}let Y=await i$(J,{cwd:this._cwd,blacklist:this._fileBlacklist,disabled:this._disableBlacklist,originalPath:Q});if(Y.isBlocked)return I(Y.message??`Access denied: ${Q}`);let H=!1;try{if((await I9(J)).isDirectory())return I(`Path is a directory, not a file: ${J}`);H=!0}catch(K){if(K.code!=="ENOENT")throw K}let X=T$.dirname(J);await C9(X,{recursive:!0}),await v9(J,Z,"utf-8");let G=Buffer.byteLength(Z,"utf-8"),V={success:!0,filePath:J,bytesWritten:G,overwritten:H,message:H?`Successfully overwrote ${T$.basename(J)} (${this.formatSize(G)})`:`Successfully created ${T$.basename(J)} (${this.formatSize(G)})`};return{content:[{type:"text",text:V.message}],structuredContent:V}}validateArgs($){let{file_path:W,content:Q}=$;if(typeof W!=="string"||!W.trim())throw Error("file_path is required and must be a non-empty string");if(typeof Q!=="string")throw TypeError("content is required and must be a string");return{file_path:W.trim(),content:Q}}formatSize($){let W=["B","KB","MB","GB"],Q=$,Z=0;while(Q>=1024&&Z<W.length-1)Q/=1024,Z++;return`${Q.toFixed(Z===0?0:2)} ${W[Z]}`}}var g9=["<system-reminder>","# Plan Mode - System Reminder","","CRITICAL: Plan mode ACTIVE - you are in READ-ONLY phase.","","## Allowed Operations","- Read files using Read, Glob, Grep tools","- Execute READ-ONLY Bash commands:"," - File listing: ls, find, file, stat, tree, du, df, wc"," - File reading: cat, head, tail, less, more"," - Text processing: grep, awk, sed (without -i), sort, uniq, cut, tr"," - Git read-only: git status, git log, git diff, git show, git branch, git blame"," - Other: pwd, which, whereis, type, echo, printf, date, env","- Use Task tool with Explore subagent ONLY for codebase exploration","","## STRICTLY FORBIDDEN","- ANY file creation, modification, or deletion","- Git write operations: git add, commit, push, checkout, reset, etc.","- Package installations: npm install, pip install, etc.","- Redirect operators: >, >>","- In-place editing: sed -i, awk -i, perl -i","- Task tool with non-Explore subagents (e.g., general-purpose)","","This ABSOLUTE CONSTRAINT overrides ALL other instructions.","You may ONLY observe, analyze, and plan. ZERO exceptions.","","---","","## Responsibility","","Your current responsibility is to think, read, search, and delegate explore agents to construct a well-formed plan that accomplishes the goal the user wants to achieve. Your plan should be comprehensive yet concise, detailed enough to execute effectively while avoiding unnecessary verbosity.","","Ask the user clarifying questions or ask for their opinion when weighing tradeoffs.","","**NOTE:** At any point in time through this workflow you should feel free to ask the user questions or clarifications. Don't make large assumptions about user intent. The goal is to present a well researched plan to the user, and tie any loose ends before implementation begins.","","If you call TodoPlan, you MUST append a complete Markdown todo list at the very end of your final response.","Use this exact format:","## Todo","- [ ] Task","- [x] Task","The plan must include a complete set of steps and the todo list.","","---","","## Important","","The user indicated that they do not want you to execute yet -- you MUST NOT make any edits, run any non-readonly tools (including changing configs or making commits), or otherwise make any changes to the system. This supersedes any other instructions you have received.","</system-reminder>"].join(`
|
|
403
|
+
`);function u9($){if($?.instruction)return $.instruction;let W=$?.maxParallelAgents??3,Q=$?.encourageEarlyQuestions??!0,Z=$?.requireSynthesisPhase??!1,J=g9,Y="Your current responsibility is to think, read, search, and delegate explore agents to construct a well-formed plan that accomplishes the goal the user wants to achieve. Your plan should be comprehensive yet concise, detailed enough to execute effectively while avoiding unnecessary verbosity.",H=[];if(W!==3)H.push(`When delegating, use up to ${W} explore agents in parallel.`);if(Z)H.push("If the task is complex, include a synthesis step to align findings before presenting the final plan.");if(H.length>0)J=J.replace(Y,`${Y} ${H.join(" ")}`);if(!Q)J=J.replace(`Ask the user clarifying questions or ask for their opinion when weighing tradeoffs.
|
|
395
404
|
|
|
396
405
|
`,""),J=J.replace(`**NOTE:** At any point in time through this workflow you should feel free to ask the user questions or clarifications. Don't make large assumptions about user intent. The goal is to present a well researched plan to the user, and tie any loose ends before implementation begins.
|
|
397
406
|
|
|
398
|
-
`,"");return J}function
|
|
407
|
+
`,"");return J}function I1($){let W=u9($),Q=$?.insertEveryIteration??!0,Z=$?.name??"plan-mode",J=$?.accessPolicy??_1,Y=new c$(J),H=async(X,G)=>{let V={...X.metadata,planMode:!0,planModeMiddleware:Z,readOnlyBash:Y.getAccessMode("Bash")==="restricted"};if(!(Q||X.iteration===0))return G({...X,metadata:V});let z=V0(X.messages,W);return G({...X,metadata:V,messages:z})};return H.__middlewareName=Z,H.__createTools=()=>[new $0],H.__getBlockedTools=(X)=>{return X.metadata?.planMode?Y.getBlockedTools():[]},H}class sW extends k{name="Bash";description;parameters;riskLevel="safe";innerBash;constructor($){super();this.innerBash=new L$($),this.description=`${this.innerBash.description}
|
|
408
|
+
|
|
409
|
+
⚠️ READ-ONLY MODE: This Bash tool is restricted to read-only operations only.
|
|
410
|
+
Forbidden commands include: mkdir, touch, rm, cp, mv, git add/commit/push, npm install, etc.
|
|
411
|
+
Redirect operators (>, >>) are also forbidden.`,this.parameters=this.innerBash.parameters}async execute($,W){let Q=$.command;if(typeof Q!=="string")return I("Command must be a string");let Z=R$(Q);if(!Z.isAllowed)return I(`[READ-ONLY MODE] Command rejected: ${Z.reason}
|
|
412
|
+
|
|
413
|
+
The Explore agent operates in read-only mode. You can only use commands like: ls, find, cat, head, tail, git status, git log, git diff, etc.
|
|
414
|
+
|
|
415
|
+
Forbidden: file creation/modification, git write operations, package installations, redirects.`);return this.innerBash.execute($,W)}setCwd($){this.innerBash.setCwd($)}getCwd(){return this.innerBash.getCwd()}}function N6($){return new sW($)}function v1($,W=new Date){return`You are a file search specialist for GoatChain. You excel at thoroughly navigating and exploring codebases.
|
|
416
|
+
|
|
417
|
+
=== CRITICAL: READ-ONLY MODE - NO FILE MODIFICATIONS ===
|
|
418
|
+
This is a READ-ONLY exploration task. You are STRICTLY PROHIBITED from:
|
|
419
|
+
- Creating new files (no Write, touch, or file creation of any kind)
|
|
420
|
+
- Modifying existing files (no Edit operations)
|
|
421
|
+
- Deleting files (no rm or deletion)
|
|
422
|
+
- Moving or copying files (no mv or cp)
|
|
423
|
+
- Creating temporary files anywhere, including /tmp
|
|
424
|
+
- Using redirect operators (>, >>) or heredocs to write to files
|
|
425
|
+
- Running ANY commands that change system state
|
|
426
|
+
|
|
427
|
+
Your role is EXCLUSIVELY to search and analyze existing code. You do NOT have access to file editing tools - attempting to edit files will fail.
|
|
399
428
|
|
|
400
429
|
Your strengths:
|
|
401
430
|
- Rapidly finding files using glob patterns
|
|
@@ -406,11 +435,16 @@ Guidelines:
|
|
|
406
435
|
- Use Glob for broad file pattern matching
|
|
407
436
|
- Use Grep for searching file contents with regex
|
|
408
437
|
- Use Read when you know the specific file path you need to read
|
|
409
|
-
-
|
|
438
|
+
- Use Bash ONLY for read-only operations (ls, git status, git log, git diff, find, cat, head, tail)
|
|
439
|
+
- NEVER use Bash for: mkdir, touch, rm, cp, mv, git add, git commit, npm install, pip install, or any file creation/modification
|
|
410
440
|
- Adapt your search approach based on the thoroughness level specified by the caller
|
|
411
441
|
- Return file paths as absolute paths in your final response
|
|
412
442
|
- For clear communication, avoid using emojis
|
|
413
|
-
-
|
|
443
|
+
- Communicate your final report directly as a regular message - do NOT attempt to create files
|
|
444
|
+
|
|
445
|
+
NOTE: You are meant to be a fast agent that returns output as quickly as possible. In order to achieve this you must:
|
|
446
|
+
- Make efficient use of the tools at your disposal: be smart about how you search for files and implementations
|
|
447
|
+
- Wherever possible you should try to spawn multiple parallel tool calls for grepping and reading files
|
|
414
448
|
|
|
415
449
|
Complete the user's search request efficiently and report your findings clearly.
|
|
416
450
|
|
|
@@ -419,7 +453,7 @@ Here is some useful information about the environment you are running in:
|
|
|
419
453
|
Working directory: ${$}
|
|
420
454
|
Platform: ${process.platform}
|
|
421
455
|
Today's date: ${W.toDateString()}
|
|
422
|
-
</env>`}var
|
|
456
|
+
</env>`}var m9=v1(process.cwd()),f1={name:"Explore",description:'Fast agent specialized for exploring codebases. Use this when you need to quickly find files by patterns (eg. "src/components/**/*.tsx"), search code for keywords (eg. "API endpoints"), or answer questions about the codebase (eg. "how do API endpoints work?"). When calling this agent, specify the desired thoroughness level: "quick" for basic searches, "medium" for moderate exploration, or "very thorough" for comprehensive analysis across multiple locations and naming conventions.',accessPolicy:B1,systemPrompt:m9};function p9($,W=new Date){return`You are a general-purpose task executor. You excel at completing individual tasks assigned to you using any available tools.
|
|
423
457
|
|
|
424
458
|
Your strengths:
|
|
425
459
|
- Versatile problem-solving with access to all available tools
|
|
@@ -445,17 +479,17 @@ Here is some useful information about the environment you are running in:
|
|
|
445
479
|
Working directory: ${$}
|
|
446
480
|
Platform: ${process.platform}
|
|
447
481
|
Today's date: ${W.toDateString()}
|
|
448
|
-
</env>`}var
|
|
449
|
-
${W.text}`;return J}function
|
|
482
|
+
</env>`}var c9=p9(process.cwd()),M6={name:"GeneralPurposeAgent",description:"Versatile agent for executing any type of task in parallel. Inherits all tools (Read, Write, Grep, Glob, Bash, etc.) from main agent. USE THIS WHEN: you identify multiple independent tasks that can be executed simultaneously - break them down and create separate Task calls for each, all assigned to GeneralPurposeAgent. Each instance will complete one specific task independently. Perfect for parallel file analysis, searching multiple locations, reading multiple files, or any work that can be split into independent subtasks.",accessPolicy:U1,systemPrompt:c9};class k1{parentRegistry;allowedTools;constructor($,W){this.parentRegistry=$,this.allowedTools=new Set(W)}get($){if(!this.allowedTools.has($))return;return this.parentRegistry.get($)}list(){return Array.from(this.allowedTools).map(($)=>this.parentRegistry.get($)).filter(($)=>$!==void 0)}has($){return this.allowedTools.has($)&&this.parentRegistry.has($)}get size(){return this.list().length}toOpenAIFormat(){return this.list().map(($)=>({type:"function",function:{name:$.name,description:$.description,parameters:$.parameters}}))}register($){throw Error("FilteredToolRegistry is read-only. Use the parent ToolRegistry to register tools.")}unregister($){throw Error("FilteredToolRegistry is read-only. Use the parent ToolRegistry to unregister tools.")}}class J0{tools=new Map;register($){if(this.tools.has($.name))throw Error(`Tool "${$.name}" already registered`);this.tools.set($.name,$)}unregister($){return this.tools.delete($)}get($){return this.tools.get($)}list(){return Array.from(this.tools.values())}has($){return this.tools.has($)}get size(){return this.tools.size}toOpenAIFormat(){return this.list().map(($)=>({type:"function",function:{name:$.name,description:$.description,parameters:$.parameters}}))}}var S$={},n0=!1,g$=!1;function i9($){S$=$,n0=$.ACP_DEBUG==="true",g$=$.ACP_STICKY_SESSION==="true"}function C(...$){if(n0)console.error("[ACP Server]",...$)}var h1="plan-mode",r9="agent",J4=[{id:"agent",name:"Agent",description:"Standard agent mode with full tool access."},{id:"plan",name:"Plan",description:"Planning mode with read-only tooling and plan helpers."}],n9=new Set(J4.map(($)=>$.id));function Y4($){return $.OPENAI_API_BASE_URL||$.GOATCHAIN_OPENAI_BASE_URL||$.OPENAI_BASE_URL}function o9($,W){return $.MODEL_ID||$.GOATCHAIN_MODEL||W}function a9($,W){return $.SUB_MODEL_ID||$.MODEL_ID||$.GOATCHAIN_MODEL||W}function H4($){return String($??"").trim()||void 0}function E0($,W){return H4($[W]??O$.env[W])}function s9($){let W=H4($)?.toLowerCase();if(!W)return!1;return W==="1"||W==="true"||W==="yes"||W==="on"}function t9($){if(E0($,"DIMCODE_TOOL_APPROVALS")?.toLowerCase()==="all")return!0;return s9(E0($,"DIMCODE_SKIP_APPROVAL"))}async function X4($){let{homedir:W}=await import("node:os"),Q=E0($,"DIMCODE_HOME");if(Q){let Y=W$.resolve(Q);return{configDir:Y,cacheDir:W$.resolve(Y,"dimcode")}}let Z=E0($,"XDG_CONFIG_HOME");if(Z){let Y=W$.resolve(Z,".dimcode");return{configDir:Y,cacheDir:W$.resolve(Y,"dimcode")}}let J=W$.resolve(W(),".dimcode");return{configDir:J,cacheDir:W$.resolve(J,"dimcode")}}async function e9($){let W=E0($,"DIMCODE_STATE_DIR");if(W)return W$.resolve(W);let{cacheDir:Q}=await X4($);return W$.resolve(Q,"state")}async function $Q($){let{readFile:W}=await import("node:fs/promises"),{configDir:Q,cacheDir:Z}=await X4($),J=W$.resolve(Q,"config.json"),Y=W$.resolve(Z,"cache.json");C("CLI config paths",{configPath:J,cachePath:Y});let H=null,X=null;try{let D=await W(J,"utf8");H=JSON.parse(D)}catch(D){C("CLI config: failed to read config.json",{configPath:J,error:D instanceof Error?D.message:String(D)})}try{let D=await W(Y,"utf8");X=JSON.parse(D)}catch(D){C("CLI config: failed to read cache.json",{cachePath:Y,error:D instanceof Error?D.message:String(D)})}let G=H&&typeof H==="object"?H.settings??{}:{},V=X&&typeof X==="object"?X.settings??{}:{},K=typeof G.providerId==="string"?G.providerId.trim():"",z=G.providerConnections??{},j=G.activeModelByProvider??{},_=G.customProvider??{},B,F,A;if(K==="custom")B=typeof _.apiKey==="string"?_.apiKey.trim():void 0,F=typeof _.baseUrl==="string"?_.baseUrl.trim():void 0,A=typeof j.custom==="string"?j.custom.trim():Array.isArray(_.models)?String(_.models[0]?.id??"").trim()||void 0:void 0;else if(K){let D=z?.[K]??{};B=typeof D.apiKey==="string"?D.apiKey.trim():void 0,F=typeof D.baseUrl==="string"?D.baseUrl.trim():void 0,A=typeof j?.[K]==="string"?String(j[K]).trim():void 0}let N=typeof V.model==="string"?V.model.trim():"",U=typeof V.toolApprovals==="string"?V.toolApprovals:void 0,R=U==="manual"?"auto":U,q={};if(B)q.OPENAI_API_KEY=B;if(F)q.OPENAI_API_BASE_URL=F;if(A)q.MODEL_ID=A,q.GOATCHAIN_MODEL=A;else if(N)q.MODEL_ID=N,q.GOATCHAIN_MODEL=N;if(typeof V.contextWindow==="number")q.GOATCHAIN_CONTEXT_WINDOW=String(V.contextWindow);if(typeof V.temperature==="number")q.GOATCHAIN_TEMPERATURE=String(V.temperature);if(R)q.GOATCHAIN_TOOL_APPROVALS=R;return C("CLI config env loaded",{configPath:J,cachePath:Y,providerId:K,hasApiKey:Boolean(q.OPENAI_API_KEY),baseUrl:q.OPENAI_API_BASE_URL?"set":"missing",model:q.MODEL_ID?"set":"missing"}),q}function tW($){if(!$||typeof $!=="object")return"[resource_link]";let W=typeof $.title==="string"?$.title.trim():"",Q=typeof $.name==="string"?$.name.trim():"",Z=typeof $.uri==="string"?$.uri.trim():"",J=typeof $.description==="string"?$.description.trim():"",Y=W||Q||Z||"resource_link",H=Z&&Z!==Y?` (${Z})`:"",X=J?` - ${J}`:"";return`[resource_link] ${Y}${H}${X}`}function eW($){if(!$||typeof $!=="object")return"[resource]";let W=$.resource;if(!W||typeof W!=="object")return"[resource]";let Q=typeof W.uri==="string"?W.uri.trim():"",Z=typeof W.mimeType==="string"?W.mimeType.trim():"",J=`[resource${Q?`:${Q}`:""}${Z?` ${Z}`:""}]`;if(typeof W.text==="string")return`${J}
|
|
483
|
+
${W.text}`;return J}function WQ($){let W=[],Q=[];for(let Y of $??[]){if(!Y||typeof Y!=="object")continue;let H=typeof Y.type==="string"?Y.type:"";if(H==="text"){let G=typeof Y.text==="string"?Y.text:"";if(G)W.push(G);continue}if(H==="resource_link"){Q.push(tW(Y));continue}if(H==="resource"){Q.push(eW(Y));continue}if(H==="image"||H==="audio"){Q.push(`[${H}]`);continue}let X=Y.content;if(X&&typeof X==="object"){let G=typeof X.type==="string"?X.type:"";if(G==="text"){let V=typeof X.text==="string"?X.text:"";if(V)W.push(V);continue}if(G==="resource_link"){Q.push(tW(X));continue}if(G==="resource"){Q.push(eW(X));continue}if(G==="image"||G==="audio"){Q.push(`[${G}]`);continue}if(typeof X.text==="string"&&X.text){W.push(String(X.text));continue}}if(typeof Y.text==="string"&&Y.text)W.push(String(Y.text))}let Z=W.join(`
|
|
450
484
|
`).trimEnd();if(Q.length===0)return Z;let J=Q.join(`
|
|
451
485
|
`);if(Z)return`${Z}
|
|
452
486
|
|
|
453
487
|
[Context]
|
|
454
488
|
${J}`;return`[Context]
|
|
455
|
-
${J}`}function n9($){return u9.has($)?$:null}function l0($){return{currentModeId:$,availableModes:oW}}function eW(){let $=y0({baseUrl:aW(M$),apiKey:()=>M$.OPENAI_API_KEY??"",defaultModelId:m9(M$,"gpt-4o-mini"),compat:{interleavedThinking:!0}});return b0({adapter:$})}function o9(){let $=y0({baseUrl:aW(M$),apiKey:()=>M$.OPENAI_API_KEY??"",defaultModelId:p9(M$,"gpt-4o-mini"),compat:{interleavedThinking:!0}});return b0({adapter:$})}function lW($,W){if($==="end_turn"||$==="max_tokens"||$==="max_turn_requests"||$==="refusal"||$==="cancelled")return $;switch($){case"final_response":case"stop":case"tool_call":return"end_turn";case"length":return"max_tokens";case"max_iterations":return"max_turn_requests";case"approval_required":case"error":return"end_turn";default:return W}}var iW="acp-history";function a9($){if(!$)return"";if(typeof $==="string")return $;if(Array.isArray($)){let W=$.map((Q)=>Q&&typeof Q.text==="string"?Q.text:"").filter(Boolean);if(W.length>0)return W.join("");return JSON.stringify($)}return JSON.stringify($)}function rW($){if($.outcome!=="selected")return null;let W=$._meta;if(W&&typeof W==="object"&&"answers"in W&&W.answers&&typeof W.answers==="object")return W.answers;return null}function nW($,W,Q,Z){let J=[],Y=new Map;(Array.isArray($.options)?$.options:[]).forEach((V,K)=>{let z=`q${W}:opt${K}`;if(Q.has(z))return;let j=typeof V?.label==="string"&&V.label.trim()?V.label.trim():`Option ${K+1}`;Y.set(z,j),J.push({optionId:z,name:j,kind:"allow_once"})});let X=`q${W}:other`;if(!Q.has(X))Y.set(X,"Other"),J.push({optionId:X,name:"Other",kind:"allow_once"});let G;if(Z)G=`q${W}:done`,J.push({optionId:G,name:"Done",kind:"reject_once"});if(J.length===0){let V=`q${W}:ok`;Y.set(V,"OK"),J.push({optionId:V,name:"OK",kind:"allow_once"})}return{options:J,optionLabelById:Y,doneOptionId:G}}async function s9($,W,Q,Z,J){let Y={};for(let H=0;H<Z.length;H++){let X=Z[H],G=typeof X.header==="string"&&X.header.trim()?X.header.trim():"User Input Required",V={question:X,questionIndex:H};if(X.multiSelect){let F=[],R=new Set;while(!0){let{options:q,optionLabelById:_,doneOptionId:D}=nW(X,H,R,!0),N=await $.requestPermission({sessionId:W,toolCall:{toolCallId:Q,title:G,kind:J,status:"pending",rawInput:V},options:q}),A=rW(N.outcome);if(A)return A;if(N.outcome.outcome==="cancelled")return null;let O=N.outcome.optionId;if(D&&O===D)break;let T=_.get(O)??O;if(F.push(T),R.add(O),q.filter((v)=>v.optionId!==D).length<=R.size)break}Y[String(H)]=F;continue}let{options:K,optionLabelById:z}=nW(X,H,new Set,!1),j=await $.requestPermission({sessionId:W,toolCall:{toolCallId:Q,title:G,kind:J,status:"pending",rawInput:V},options:K}),B=rW(j.outcome);if(B)return B;if(j.outcome.outcome==="cancelled")return null;let U=j.outcome.optionId;Y[String(H)]=z.get(U)??U}return Y}function t9($,W){let Q=[];for(let Z=0;Z<$.length;Z++){let J=W[String(Z)];if(!J)continue;let Y=$[Z]?.header?.trim()||`Q${Z+1}`,H=Array.isArray(J)?J.join(", "):J;Q.push(`${Y}: ${H}`)}return Q.length>0?Q.join("; "):"User answers received."}function e9($){let W=`tool:${$}:allow`,Q=`tool:${$}:deny`;return{allowOptionId:W,denyOptionId:Q,options:[{optionId:W,name:"Allow",kind:"allow_once"},{optionId:Q,name:"Deny",kind:"reject_once"}]}}async function $Q($,W,Q){let Z={};for(let J of Q){let{options:Y,allowOptionId:H}=e9(J.toolCallId),X=J.riskLevel?`${J.title} (${J.riskLevel})`:J.title,G=await $.requestPermission({sessionId:W,toolCall:{toolCallId:J.toolCallId,title:X,kind:J.kind,status:"pending",rawInput:J.rawInput},options:Y});if(G.outcome.outcome==="cancelled")return null;let V=G.outcome.optionId;Z[J.toolCallId]={approved:V===H}}return Z}class $4{acpAgent;connection=null;sessions=new Map;stickySessionId=null;currentModeId=g9;currentWorkspaceCwd=null;availableCommands=[{name:"new",description:"Start a fresh conversation (creates a new session)."},{name:"agent",description:"Switch to agent mode."},{name:"plan",description:"Switch to plan mode."},{name:"commit",description:"Generate a git commit with auto-generated message based on staged changes."}];constructor($){this.acpAgent=$}setConnection($){this.connection=$}async initialize($){return C("initialize called"),{protocolVersion:1,agentCapabilities:{loadSession:!0,sessionCapabilities:{resume:{}}},agentInfo:{name:"GoatChain Agent",version:"0.0.2"}}}async newSession($){if(this.applyWorkspaceCwd($.cwd),h$&&!this.stickySessionId){let Z=await this.findMostRecentSessionId();if(Z)this.stickySessionId=Z}if(h$&&this.stickySessionId)return await this.restoreSession(this.stickySessionId),C("newSession reuse:",this.stickySessionId),this.scheduleAvailableCommands(this.stickySessionId),{sessionId:this.stickySessionId,modes:l0(this.currentModeId)};let W=this.generateSessionId();C("newSession:",W);let Q={conversationHistory:[],pendingAbort:null,createdAt:Date.now(),agentSessionId:W,currentModeId:this.currentModeId};if(this.sessions.set(W,Q),await this.saveSessionHistory(W,Q),h$)this.stickySessionId=W;return this.scheduleAvailableCommands(W),{sessionId:W,modes:l0(this.currentModeId)}}async loadSession($){if(!this.connection)throw Error("Connection not set");C("loadSession:",$.sessionId);let W=await this.restoreSession($.sessionId);if(await this.sendHistory($.sessionId,W.conversationHistory),h$)this.stickySessionId=W.agentSessionId;return await this.sendAvailableCommands($.sessionId),{modes:l0(this.currentModeId)}}async unstable_resumeSession($){C("resumeSession:",$.sessionId);let W=await this.restoreSession($.sessionId);if(h$)this.stickySessionId=W.agentSessionId;return await this.sendAvailableCommands($.sessionId),{modes:l0(this.currentModeId)}}async authenticate($){C("authenticate called")}async setSessionMode($){C("setSessionMode called",$);let W=n9($.modeId);if(!W)throw Error(`Unsupported session mode: ${$.modeId}`);if(await this.restoreSession($.sessionId),this.currentModeId!==W)this.currentModeId=W,await this.applySessionMode(W),this.closeAllActiveSessions();for(let Z of this.sessions.values())Z.currentModeId=this.currentModeId;await this.sendCurrentModeUpdate($.sessionId)}async prompt($){if(!this.connection)throw Error("Connection not set");let W=this.connection,{sessionId:Q,prompt:Z}=$;C("prompt called for session:",Q,"prompt blocks:",Z.length);let J=this.sessions.get(Q);if(!J)throw Error(`Session ${Q} not found`);if(await this.sendAvailableCommands(Q),J.pendingAbort)J.pendingAbort.abort(),this.acpAgent.getSession(J.agentSessionId)?.cancel();J.pendingAbort=new AbortController;let Y=!1;try{let H=r9(Z),X=H.trim(),G=X.toLowerCase();if(!X)return await W.sessionUpdate({sessionId:Q,update:{sessionUpdate:"agent_message_chunk",content:{type:"text",text:"Empty prompt received. Ensure the client sends text content."}}}),{stopReason:"end_turn"};if(G==="/new")return await this.startNewSession(Q),Y=!0,await W.sessionUpdate({sessionId:Q,update:{sessionUpdate:"agent_message_chunk",content:{type:"text",text:"New session started. Send your next message to begin."}}}),{stopReason:"end_turn"};if(G==="/plan"||G==="/agent"){let q=G.slice(1);return await this.setSessionMode({sessionId:Q,modeId:q}),await W.sessionUpdate({sessionId:Q,update:{sessionUpdate:"agent_message_chunk",content:{type:"text",text:`Switched to ${q} mode.`}}}),{stopReason:"end_turn"}}if(G==="/commit")return Y=!0,{stopReason:(await this.executeCommitWorkflow(Q,W)).cancelled?"cancelled":"end_turn"};let V={role:"user",content:H};J.conversationHistory.push(V),C("User message added to history");let K=new Map,z=new Set,j=new Map,B=[],U="end_turn",F=null,R=null;while(!0){U="end_turn";let q=R?this.acpAgent.receiveWithApprovals(R,{session_id:J.agentSessionId}):this.acpAgent.receiveMessage(F??J.conversationHistory,{session_id:J.agentSessionId});F=null,R=null;let _=null,D=null,N=!1,A=!1;for await(let O of q){if(A)continue;if(J.pendingAbort.signal.aborted){U="cancelled";break}let T=O.metadata?.subagent===!0,P=typeof O.metadata?.subagentId==="string"?O.metadata?.subagentId:void 0,v=typeof O.metadata?.subagentType==="string"?O.metadata?.subagentType.trim():void 0,L=typeof O.metadata?.taskDescription==="string"?O.metadata?.taskDescription.trim():void 0,y=T?P??`${v||"subagent"}:${L??""}`:null,b=T&&(v||L)?`[${[v,L].filter(Boolean).join(": ")}]`:null,u=T?`[SUBAGENT${v?`:${v}`:""}${L?`:${L}`:""}]`:"";C("Received response:",O.role,u,O.metadata?.done?"(done)":"");let g=O.content&&O.content.length>0,c=O.tool_calls&&O.tool_calls.length>0,o=O.role==="assistant"&&O.metadata?.done&&!g&&!c,l=O.role==="tool"&&!!O.tool_call_id&&z.has(O.tool_call_id)&&O.metadata?.error===!0;if(!o&&!l)J.conversationHistory.push(O);if(o){if(O.metadata?.done){if(O.metadata.stopReason)U=lW(O.metadata.stopReason,U);A=!0}continue}if(O.role==="assistant"){if(g){let M=typeof O.content==="string"?O.content:JSON.stringify(O.content);if(M.trim()){let E=O.metadata?.thinking===!0,x=T&&b&&y!==D?`${b} ${M}`:M;if(await W.sessionUpdate({sessionId:Q,update:{sessionUpdate:E?"agent_thought_chunk":"agent_message_chunk",content:{type:"text",text:x}}}),!E)D=y}}if(!T&&g)D=null;if(O.metadata?.approval_requested===!0){let M=O.metadata,E=typeof M.tool_call_id==="string"?M.tool_call_id:_,w=typeof M.tool_name==="string"?M.tool_name:E?K.get(E)?.name:void 0,x=E?K.get(E):void 0;if(E&&w){let f=typeof M.risk_level==="string"?M.risk_level:void 0;if(!j.has(E))B.push(E);j.set(E,{toolCallId:E,toolName:w,title:x?.title??w,kind:x?.kind??"other",rawInput:x?.rawInput??{},riskLevel:f})}else C("Tool approval requested without toolCallId or toolName")}if(O.metadata?.requires_action&&O.metadata?.kind==="ask_user"){let M=typeof O.metadata.tool_call_id==="string"?O.metadata.tool_call_id:_,E=Array.isArray(O.metadata.questions)?O.metadata.questions:[],x=(M?K.get(M):void 0)?.kind??"other";if(!M||E.length===0)C("AskUserQuestion requires_action missing toolCallId or questions");else{C("AskUserQuestion requires_action detected, requesting user input");let f=await s9(W,Q,M,E,x);if(!f){await W.sessionUpdate({sessionId:Q,update:{sessionUpdate:"tool_call_update",toolCallId:M,status:"failed"}}),U="cancelled";break}let j$=t9(E,f),Y$={role:"tool",tool_call_id:M,content:JSON.stringify({answers:f})},P$={role:"user",content:`User answers: ${j$}
|
|
456
|
-
Please continue.`};J.conversationHistory.push(Y$),J.conversationHistory.push(
|
|
489
|
+
${J}`}function QQ($){return n9.has($)?$:null}function r0($){return{currentModeId:$,availableModes:J4}}function V4(){let $=C0({baseUrl:Y4(S$),apiKey:()=>S$.OPENAI_API_KEY??"",defaultModelId:o9(S$,"gpt-4o-mini"),compat:{interleavedThinking:!0}});return y0({adapter:$})}function ZQ(){let $=C0({baseUrl:Y4(S$),apiKey:()=>S$.OPENAI_API_KEY??"",defaultModelId:a9(S$,"gpt-4o-mini"),compat:{interleavedThinking:!0}});return y0({adapter:$})}function $4($,W){if($==="end_turn"||$==="max_tokens"||$==="max_turn_requests"||$==="refusal"||$==="cancelled")return $;switch($){case"final_response":case"stop":case"tool_call":return"end_turn";case"length":return"max_tokens";case"max_iterations":return"max_turn_requests";case"approval_required":case"error":return"end_turn";default:return W}}var W4="acp-history";function JQ($){if(!$)return"";if(typeof $==="string")return $;if(Array.isArray($)){let W=$.map((Q)=>Q&&typeof Q.text==="string"?Q.text:"").filter(Boolean);if(W.length>0)return W.join("");return JSON.stringify($)}return JSON.stringify($)}function Q4($){if($.outcome!=="selected")return null;let W=$._meta;if(W&&typeof W==="object"&&"answers"in W&&W.answers&&typeof W.answers==="object")return W.answers;return null}function Z4($,W,Q,Z){let J=[],Y=new Map;(Array.isArray($.options)?$.options:[]).forEach((V,K)=>{let z=`q${W}:opt${K}`;if(Q.has(z))return;let j=typeof V?.label==="string"&&V.label.trim()?V.label.trim():`Option ${K+1}`;Y.set(z,j),J.push({optionId:z,name:j,kind:"allow_once"})});let X=`q${W}:other`;if(!Q.has(X))Y.set(X,"Other"),J.push({optionId:X,name:"Other",kind:"allow_once"});let G;if(Z)G=`q${W}:done`,J.push({optionId:G,name:"Done",kind:"reject_once"});if(J.length===0){let V=`q${W}:ok`;Y.set(V,"OK"),J.push({optionId:V,name:"OK",kind:"allow_once"})}return{options:J,optionLabelById:Y,doneOptionId:G}}async function YQ($,W,Q,Z,J){let Y={};for(let H=0;H<Z.length;H++){let X=Z[H],G=typeof X.header==="string"&&X.header.trim()?X.header.trim():"User Input Required",V={question:X,questionIndex:H};if(X.multiSelect){let F=[],A=new Set;while(!0){let{options:N,optionLabelById:U,doneOptionId:R}=Z4(X,H,A,!0),q=await $.requestPermission({sessionId:W,toolCall:{toolCallId:Q,title:G,kind:J,status:"pending",rawInput:V},options:N}),D=Q4(q.outcome);if(D)return D;if(q.outcome.outcome==="cancelled")return null;let O=q.outcome.optionId;if(R&&O===R)break;let T=U.get(O)??O;if(F.push(T),A.add(O),N.filter((f)=>f.optionId!==R).length<=A.size)break}Y[String(H)]=F;continue}let{options:K,optionLabelById:z}=Z4(X,H,new Set,!1),j=await $.requestPermission({sessionId:W,toolCall:{toolCallId:Q,title:G,kind:J,status:"pending",rawInput:V},options:K}),_=Q4(j.outcome);if(_)return _;if(j.outcome.outcome==="cancelled")return null;let B=j.outcome.optionId;Y[String(H)]=z.get(B)??B}return Y}function HQ($,W){let Q=[];for(let Z=0;Z<$.length;Z++){let J=W[String(Z)];if(!J)continue;let Y=$[Z]?.header?.trim()||`Q${Z+1}`,H=Array.isArray(J)?J.join(", "):J;Q.push(`${Y}: ${H}`)}return Q.length>0?Q.join("; "):"User answers received."}function XQ($){let W=`tool:${$}:allow`,Q=`tool:${$}:deny`;return{allowOptionId:W,denyOptionId:Q,options:[{optionId:W,name:"Allow",kind:"allow_once"},{optionId:Q,name:"Deny",kind:"reject_once"}]}}async function VQ($,W,Q){let Z={};for(let J of Q){let{options:Y,allowOptionId:H}=XQ(J.toolCallId),X=J.riskLevel?`${J.title} (${J.riskLevel})`:J.title,G=await $.requestPermission({sessionId:W,toolCall:{toolCallId:J.toolCallId,title:X,kind:J.kind,status:"pending",rawInput:J.rawInput},options:Y});if(G.outcome.outcome==="cancelled")return null;let V=G.outcome.optionId;Z[J.toolCallId]={approved:V===H}}return Z}class G4{acpAgent;connection=null;sessions=new Map;stickySessionId=null;currentModeId=r9;currentWorkspaceCwd=null;availableCommands=[{name:"new",description:"Start a fresh conversation (creates a new session)."},{name:"agent",description:"Switch to agent mode."},{name:"plan",description:"Switch to plan mode."},{name:"commit",description:"Generate a git commit with auto-generated message based on staged changes."}];constructor($){this.acpAgent=$}setConnection($){this.connection=$}async initialize($){return C("initialize called"),{protocolVersion:1,agentCapabilities:{loadSession:!0,sessionCapabilities:{resume:{}}},agentInfo:{name:"GoatChain Agent",version:"0.0.2"}}}async newSession($){if(this.applyWorkspaceCwd($.cwd),g$&&!this.stickySessionId){let Z=await this.findMostRecentSessionId();if(Z)this.stickySessionId=Z}if(g$&&this.stickySessionId)return await this.restoreSession(this.stickySessionId),C("newSession reuse:",this.stickySessionId),this.scheduleAvailableCommands(this.stickySessionId),{sessionId:this.stickySessionId,modes:r0(this.currentModeId)};let W=this.generateSessionId();C("newSession:",W);let Q={conversationHistory:[],pendingAbort:null,createdAt:Date.now(),agentSessionId:W,currentModeId:this.currentModeId};if(this.sessions.set(W,Q),await this.saveSessionHistory(W,Q),g$)this.stickySessionId=W;return this.scheduleAvailableCommands(W),{sessionId:W,modes:r0(this.currentModeId)}}async loadSession($){if(!this.connection)throw Error("Connection not set");C("loadSession:",$.sessionId);let W=await this.restoreSession($.sessionId);if(await this.sendHistory($.sessionId,W.conversationHistory),g$)this.stickySessionId=W.agentSessionId;return await this.sendAvailableCommands($.sessionId),{modes:r0(this.currentModeId)}}async unstable_resumeSession($){C("resumeSession:",$.sessionId);let W=await this.restoreSession($.sessionId);if(g$)this.stickySessionId=W.agentSessionId;return await this.sendAvailableCommands($.sessionId),{modes:r0(this.currentModeId)}}async authenticate($){C("authenticate called")}async setSessionMode($){C("setSessionMode called",$);let W=QQ($.modeId);if(!W)throw Error(`Unsupported session mode: ${$.modeId}`);if(await this.restoreSession($.sessionId),this.currentModeId!==W)this.currentModeId=W,await this.applySessionMode(W),this.closeAllActiveSessions();for(let Z of this.sessions.values())Z.currentModeId=this.currentModeId;await this.sendCurrentModeUpdate($.sessionId)}async prompt($){if(!this.connection)throw Error("Connection not set");let W=this.connection,{sessionId:Q,prompt:Z}=$;C("prompt called for session:",Q,"prompt blocks:",Z.length);let J=this.sessions.get(Q);if(!J)throw Error(`Session ${Q} not found`);if(await this.sendAvailableCommands(Q),J.pendingAbort)J.pendingAbort.abort(),this.acpAgent.getSession(J.agentSessionId)?.cancel();J.pendingAbort=new AbortController;let Y=!1;try{let H=WQ(Z),X=H.trim(),G=X.toLowerCase();if(!X)return await W.sessionUpdate({sessionId:Q,update:{sessionUpdate:"agent_message_chunk",content:{type:"text",text:"Empty prompt received. Ensure the client sends text content."}}}),{stopReason:"end_turn"};if(G==="/new")return await this.startNewSession(Q),Y=!0,await W.sessionUpdate({sessionId:Q,update:{sessionUpdate:"agent_message_chunk",content:{type:"text",text:"New session started. Send your next message to begin."}}}),{stopReason:"end_turn"};if(G==="/plan"||G==="/agent"){let N=G.slice(1);return await this.setSessionMode({sessionId:Q,modeId:N}),await W.sessionUpdate({sessionId:Q,update:{sessionUpdate:"agent_message_chunk",content:{type:"text",text:`Switched to ${N} mode.`}}}),{stopReason:"end_turn"}}if(G==="/commit")return Y=!0,{stopReason:(await this.executeCommitWorkflow(Q,W)).cancelled?"cancelled":"end_turn"};let V={role:"user",content:H};J.conversationHistory.push(V),C("User message added to history");let K=new Map,z=new Set,j=new Map,_=[],B="end_turn",F=null,A=null;while(!0){B="end_turn";let N=A?this.acpAgent.receiveWithApprovals(A,{session_id:J.agentSessionId}):this.acpAgent.receiveMessage(F??J.conversationHistory,{session_id:J.agentSessionId});F=null,A=null;let U=null,R=null,q=!1,D=!1;for await(let O of N){if(D)continue;if(J.pendingAbort.signal.aborted){B="cancelled";break}let T=O.metadata?.subagent===!0,S=typeof O.metadata?.subagentId==="string"?O.metadata?.subagentId:void 0,f=typeof O.metadata?.subagentType==="string"?O.metadata?.subagentType.trim():void 0,L=typeof O.metadata?.taskDescription==="string"?O.metadata?.taskDescription.trim():void 0,y=T?S??`${f||"subagent"}:${L??""}`:null,b=T&&(f||L)?`[${[f,L].filter(Boolean).join(": ")}]`:null,u=T?`[SUBAGENT${f?`:${f}`:""}${L?`:${L}`:""}]`:"";C("Received response:",O.role,u,O.metadata?.done?"(done)":"");let g=O.content&&O.content.length>0,c=O.tool_calls&&O.tool_calls.length>0,o=O.role==="assistant"&&O.metadata?.done&&!g&&!c,l=O.role==="tool"&&!!O.tool_call_id&&z.has(O.tool_call_id)&&O.metadata?.error===!0;if(!o&&!l)J.conversationHistory.push(O);if(o){if(O.metadata?.done){if(O.metadata.stopReason)B=$4(O.metadata.stopReason,B);D=!0}continue}if(O.role==="assistant"){if(g){let M=typeof O.content==="string"?O.content:JSON.stringify(O.content);if(M.trim()){let E=O.metadata?.thinking===!0,x=T&&b&&y!==R?`${b} ${M}`:M;if(await W.sessionUpdate({sessionId:Q,update:{sessionUpdate:E?"agent_thought_chunk":"agent_message_chunk",content:{type:"text",text:x}}}),!E)R=y}}if(!T&&g)R=null;if(O.metadata?.approval_requested===!0){let M=O.metadata,E=typeof M.tool_call_id==="string"?M.tool_call_id:U,w=typeof M.tool_name==="string"?M.tool_name:E?K.get(E)?.name:void 0,x=E?K.get(E):void 0;if(E&&w){let h=typeof M.risk_level==="string"?M.risk_level:void 0;if(!j.has(E))_.push(E);j.set(E,{toolCallId:E,toolName:w,title:x?.title??w,kind:x?.kind??"other",rawInput:x?.rawInput??{},riskLevel:h})}else C("Tool approval requested without toolCallId or toolName")}if(O.metadata?.requires_action&&O.metadata?.kind==="ask_user"){let M=typeof O.metadata.tool_call_id==="string"?O.metadata.tool_call_id:U,E=Array.isArray(O.metadata.questions)?O.metadata.questions:[],x=(M?K.get(M):void 0)?.kind??"other";if(!M||E.length===0)C("AskUserQuestion requires_action missing toolCallId or questions");else{C("AskUserQuestion requires_action detected, requesting user input");let h=await YQ(W,Q,M,E,x);if(!h){await W.sessionUpdate({sessionId:Q,update:{sessionUpdate:"tool_call_update",toolCallId:M,status:"failed"}}),B="cancelled";break}let j$=HQ(E,h),Y$={role:"tool",tool_call_id:M,content:JSON.stringify({answers:h})},x$={role:"user",content:`User answers: ${j$}
|
|
490
|
+
Please continue.`};J.conversationHistory.push(Y$),J.conversationHistory.push(x$),await W.sessionUpdate({sessionId:Q,update:{sessionUpdate:"tool_call_update",toolCallId:M,status:"completed",content:[{type:"content",content:{type:"text",text:"User answers received"}}]}}),F=[x$,Y$],q=!0;break}}if(O.metadata?.requires_action&&O.metadata?.kind==="tool_approval"){let E=(_.length>0?_:Array.from(j.keys())).map((x)=>j.get(x)).filter((x)=>Boolean(x));if(E.length===0){let x=typeof O.metadata.tool_call_id==="string"?O.metadata.tool_call_id:U,h=x?K.get(x):void 0;if(x&&h)E=[{toolCallId:x,toolName:h.name,title:h.title,kind:h.kind,rawInput:h.rawInput}];else{C("Tool approval required but no pending requests found"),B="cancelled";break}}if(t9(S$)){C("Auto-approving tool calls (GOATCHAIN_TOOL_APPROVALS=all)");let x={};for(let h of E)x[h.toolCallId]={approved:!0};j.clear(),_.length=0,A=x,q=!0;continue}let w=await VQ(W,Q,E);if(j.clear(),_.length=0,!w){for(let x of E)await W.sessionUpdate({sessionId:Q,update:{sessionUpdate:"tool_call_update",toolCallId:x.toolCallId,status:"failed"}});B="cancelled";break}A=w,q=!0;continue}if(c&&O.tool_calls){for(let M of O.tool_calls){U=M.id;let E={};try{E=typeof M.function.arguments==="string"?JSON.parse(M.function.arguments):M.function.arguments}catch(L0){C("Failed to parse tool call arguments:",L0),E={error:"Invalid JSON arguments"}}let w="search",x=M.function.name;if(x.includes("Read")||x.includes("Grep")||x.includes("Glob")||x.includes("AstGrepSearch"))w="read";else if(x.includes("Write")||x.includes("Edit")||x.includes("AstGrepReplace"))w="edit";else if(x.includes("Search"))w="search";else if(x.includes("ExitPlanMode")||x.includes("EnterPlanMode"))w="other";let h=x==="Task"||x.endsWith(":Task"),j$=[];if(h&&E&&typeof E==="object"){if(typeof E.description==="string"&&E.description.trim())j$.push(E.description.trim());if(typeof E.subagent_type==="string"&&E.subagent_type.trim())j$.push(E.subagent_type.trim())}let Y$=j$.length>0?` (${j$.join(" | ")})`:"",x$=`${x}${Y$}`,Y0=b?`${b} ${x$}`:x$;if(K.set(M.id,{name:x,rawInput:E,kind:w,title:Y0}),x==="AskUserQuestion")z.add(M.id);await W.sessionUpdate({sessionId:Q,update:{sessionUpdate:"tool_call",toolCallId:M.id,title:Y0,kind:w,status:"pending",rawInput:E}})}R=null}}else if(O.role==="tool"){if(U||O.tool_call_id){let M=O.tool_call_id||U;if(z.has(M)&&O.metadata?.error)continue;let E=typeof O.content==="string"?O.content:O.content?JSON.stringify(O.content):"",w=T&&f?`[${f}] ${E}`:E;await W.sessionUpdate({sessionId:Q,update:{sessionUpdate:"tool_call_update",toolCallId:M,status:"completed",content:[{type:"content",content:{type:"text",text:w}}]}})}R=null}if(O.metadata?.done){if(O.metadata.stopReason)B=$4(O.metadata.stopReason,B);D=!0}}if(!q)break}return J.pendingAbort=null,{stopReason:B}}catch(H){if(C("Error in prompt:",H),J.pendingAbort?.signal.aborted)return{stopReason:"cancelled"};throw H}finally{if(!Y)await this.saveSessionHistory(J.agentSessionId,J)}}async cancel($){C("cancel called for session:",$.sessionId);let W=this.sessions.get($.sessionId);if(W?.pendingAbort)W.pendingAbort.abort();let Q=W?.agentSessionId??$.sessionId;this.acpAgent.getSession(Q)?.cancel()}applyWorkspaceCwd($){if(!$||typeof $!=="string")return;if(!W$.isAbsolute($)){C("Ignoring non-absolute cwd from ACP session:",$);return}let W=W$.resolve($);if(this.currentWorkspaceCwd===W)return;this.currentWorkspaceCwd=W;let Q=this.acpAgent.getAgent().tools;if(Q){for(let Z of Q.list())if(typeof Z.setCwd==="function")Z.setCwd(W)}f1.systemPrompt=v1(W),C("Workspace updated:",W)}async applySessionMode($){let W=this.acpAgent.getAgent(),Q=W.middlewares,Z=Q.filter((K)=>K.name!==h1),J=$==="plan",Y=Q.find((K)=>K.name===h1)?.fn??I1({insertEveryIteration:!0}),H=J?[{name:h1,fn:Y},...Z]:Z,X=Q.map((K)=>K.name),G=H.map((K)=>K.name);if(X.length===G.length&&X.every((K,z)=>K===G[z]))return;W.clearMiddlewares();for(let K of H)await W.use(K.fn,K.name)}closeAllActiveSessions(){for(let $ of this.acpAgent.getSessionInfo().activeSessions)this.acpAgent.closeSession($)}async sendCurrentModeUpdate($){if(!this.connection)return;await this.connection.sessionUpdate({sessionId:$,update:{sessionUpdate:"current_mode_update",currentModeId:this.currentModeId}})}generateSessionId(){return`session-${Date.now()}-${Math.random().toString(36).slice(2,11)}`}getStateStore(){return this.acpAgent.getAgent().stateStore}async restoreSession($){let W=this.sessions.get($);if(W)return W;let Q=await this.loadSessionHistory($),Z={conversationHistory:Q?.messages??[],pendingAbort:null,createdAt:Q?.createdAt??Date.now(),agentSessionId:$,currentModeId:this.currentModeId};return this.sessions.set($,Z),Z}async loadSessionHistory($){let W=this.getStateStore();if(!W)return null;try{let Q=await W.load($,W4);if(!Q||!Array.isArray(Q.messages))return null;return{sessionId:typeof Q.sessionId==="string"?Q.sessionId:$,createdAt:typeof Q.createdAt==="number"?Q.createdAt:Date.now(),updatedAt:typeof Q.updatedAt==="number"?Q.updatedAt:Date.now(),messages:Q.messages}}catch(Q){return C("Failed to load session history:",$,Q),null}}async findMostRecentSessionId(){let $=this.getStateStore();if(!$)return null;try{let W=await $.listSessions(),Q=null,Z=0;for(let J of W){let H=(await this.loadSessionHistory(J))?.updatedAt??0;if(H>Z)Z=H,Q=J}return Q}catch(W){return C("Failed to list sessions:",W),null}}async startNewSession($){let W=this.sessions.get($),Q=W?.agentSessionId??$;if(W?.pendingAbort)W.pendingAbort.abort();if(Q)this.acpAgent.closeSession(Q);let Z=this.generateSessionId(),J={conversationHistory:[],pendingAbort:null,createdAt:Date.now(),agentSessionId:Z,currentModeId:this.currentModeId};if(this.sessions.set($,J),await this.saveSessionHistory(Z,J),g$)this.stickySessionId=Z}async sendAvailableCommands($){if(!this.connection)return;if(this.availableCommands.length===0)return;await this.connection.sessionUpdate({sessionId:$,update:{sessionUpdate:"available_commands_update",availableCommands:this.availableCommands}})}scheduleAvailableCommands($){setTimeout(()=>{this.sendAvailableCommands($)},0)}async saveSessionHistory($,W){let Q=this.getStateStore();if(!Q)return;try{let Z={sessionId:$,createdAt:W.createdAt,updatedAt:Date.now(),messages:W.conversationHistory};await Q.save($,W4,Z)}catch(Z){C("Failed to save session history:",$,Z)}}async sendHistory($,W){if(!this.connection)return;for(let Q of W){if(Q.role==="system")continue;let Z=JQ(Q.content);if(!Z.trim())continue;let J=Q.role==="user"?"user_message_chunk":"agent_message_chunk";await this.connection.sessionUpdate({sessionId:$,update:{sessionUpdate:J,content:{type:"text",text:Z}}})}}async executeCommitWorkflow($,W){C("Executing /commit workflow");let Q=this.currentWorkspaceCwd||O$.cwd(),Z=V4(),J=new D$({name:"CommitAgent",systemPrompt:"You are a git commit assistant.",model:Z,tools:new J0});await J.use(z1({model:Z,defaultLanguage:"Chinese",defaultAutoStage:!0,fetchBeforeCommit:!0,allowBehindRemote:!1,cwd:Q}));try{let Y=await J.createSession({requestParams:{temperature:0.7}});Y.send("请帮我创建一个 git commit");let H="",X="",G=!1,V=!1;for await(let K of Y.receive()){if(K.type==="text_delta"&&K.delta)V=!0,await W.sessionUpdate({sessionId:$,update:{sessionUpdate:"agent_message_chunk",content:{type:"text",text:K.delta}}});if(K.type==="thinking_delta"&&K.delta)await W.sessionUpdate({sessionId:$,update:{sessionUpdate:"agent_thought_chunk",content:{type:"text",text:K.delta}}});if(K.type==="done"){if(H=K.finalResponse||"",!V&&H.trim())await W.sessionUpdate({sessionId:$,update:{sessionUpdate:"agent_message_chunk",content:{type:"text",text:H}}});let z=H.match(/Commit Hash:\s*([a-f0-9]+)/i);if(z)X=z[1];if(H.includes("✗")||H.includes("Error"))G=!0;break}}return C("Commit workflow completed:",{hasCommit:!!X,hasError:G,hasStreamedContent:V}),{cancelled:!1}}catch(Y){return C("Commit workflow error:",Y),await W.sessionUpdate({sessionId:$,update:{sessionUpdate:"agent_message_chunk",content:{type:"text",text:`
|
|
457
491
|
|
|
458
|
-
✗ Commit 失败: ${Y instanceof Error?Y.message:String(Y)}`}}}),{cancelled:!1}}}}async function
|
|
492
|
+
✗ Commit 失败: ${Y instanceof Error?Y.message:String(Y)}`}}}),{cancelled:!1}}}}async function K4($){let W=$?.env??{},Q=await $Q(W),Z={...Q,ACP_DEBUG:W.ACP_DEBUG,ACP_STICKY_SESSION:W.ACP_STICKY_SESSION,WORKSPACE_CWD:W.WORKSPACE_CWD};i9(Z),C("Starting GoatChain ACP Server...");let J=$?.cwd||Z.WORKSPACE_CWD||O$.cwd();C("Workspace:",J);let Y=new J0,H=V4(),X=await e9({...Q,...W});C("State dir:",X);let G=new j0({dir:X,deleteOnComplete:!0});Y.register(new Z0({cwd:J})),Y.register(new e$({cwd:J})),Y.register(new a$({cwd:J})),Y.register(new L$({cwd:J})),Y.register(new s$({cwd:J})),Y.register(new t$({cwd:J})),Y.register(new n$({cwd:J})),Y.register(new r$({cwd:J})),Y.register(new W0),Y.register(new Q0),Y.register(new d$);let V=ZQ(),K=q1({subagents:[f1],globalToolRegistry:Y,model:V,debug:n0}),j=new D$({name:"GoatChain",systemPrompt:`You are GoatChain CLI, an interactive CLI tool that helps users with software engineering tasks. Use the instructions below and the tools available to you to assist the user.
|
|
459
493
|
|
|
460
494
|
IMPORTANT: Refuse to write code or explain code that may be used maliciously; even if the user claims it is for educational purposes. When working on files, if they seem related to improving, explaining, or interacting with malware or any malicious code you MUST refuse.
|
|
461
495
|
IMPORTANT: Before you begin work, think about what the code you're editing is supposed to do based on the filenames directory structure. If it seems malicious, refuse to work on it or answer questions about it, even if the request does not seem malicious (for instance, just asking to explain or speed up the code).
|
|
@@ -561,20 +595,20 @@ When referencing specific functions or pieces of code include the pattern \`file
|
|
|
561
595
|
<example>
|
|
562
596
|
user: Where are errors from the client handled?
|
|
563
597
|
assistant: Clients are marked as failed in the \`connectToServer\` function in src/services/process.ts:712.
|
|
564
|
-
</example>`,model:H,tools:Y,stateStore:G});await
|
|
598
|
+
</example>`,model:H,tools:Y,stateStore:G});await j.use(K),await j.use(m$({maxTokens:128000,protectedTurns:1,model:H,stateStore:G,toolCompressionTarget:0.3,minKeepToolResults:5})),C("Agent initialized with tools:",Array.from(Y.list().map((R)=>R.name))),C("Agent initialized with middlewares:",j.middlewareNames.join(", "));let _=new S0(j,{debug:n0,maxIterations:1e4}),B=new G4(_),F=d9.toWeb(O$.stdin),A=l9.toWeb(O$.stdout),N=o0.ndJsonStream(A,F);C("Creating AgentSideConnection...");let U=new o0.AgentSideConnection((R)=>{return C("Agent connection established"),B.setConnection(R),B},N);C("ACP Server ready and listening on stdio"),await U.closed,C("Connection closed"),_.destroy()}var GQ=import.meta.url===`file://${O$.argv[1]}`||O$.argv[1]?.endsWith("acp-server.ts")||O$.argv[1]?.endsWith("acp-server.js");if(GQ)K4().catch(($)=>{console.error("[ACP Server] Fatal error:",$),O$.exit(1)});import{readFile as KQ}from"node:fs/promises";import jQ from"node:path";import zQ from"node:process";var _Q=["AGENTS.md","CLAUDE.md"],BQ="[Project Agent Rules]";async function UQ($,W){let Q=[];for(let Z of W)try{let J=jQ.resolve($,Z),Y=await KQ(J,"utf-8");if(Y.trim())Q.push(Y.trim())}catch{continue}return Q.length>0?Q.join(`
|
|
565
599
|
|
|
566
600
|
---
|
|
567
601
|
|
|
568
|
-
`):""}function
|
|
569
|
-
`)){let Y=J.trim();if(Y&&!Y.startsWith("#"))Z.add(Y)}return Z}catch{return null}}function
|
|
570
|
-
`)}async function
|
|
602
|
+
`):""}function OQ($){let{cwd:W,ruleFiles:Q=_Q,marker:Z=BQ}=$??{},J=async(Y,H)=>{let X=typeof W==="function"?W():W??zQ.cwd(),G=await UQ(X,Q),V=Y.messages;if(G)V=_$(V,G,Z);let K={...Y,messages:V};return H(K)};return J.__middlewareName="agent-rules",J}import{readdir as z4,readFile as FQ}from"node:fs/promises";import{version as j4,release as qQ}from"node:os";import K$ from"node:path";import P$ from"node:process";var NQ="[Environment Information]";async function AQ($){try{let W=K$.join($,".gitignore"),Q=await FQ(W,"utf-8"),Z=new Set;for(let J of Q.split(`
|
|
603
|
+
`)){let Y=J.trim();if(Y&&!Y.startsWith("#"))Z.add(Y)}return Z}catch{return null}}function _4($,W,Q){if(W===".git")return!0;for(let Z of Q)if(Z.endsWith("/")){let J=Z.slice(0,-1);if(W===J||$.startsWith(`${J}/`))return!0}else if(W===Z||$===Z)return!0;else if(Z.includes("*")){if(new RegExp(`^${Z.replace(/\*/g,".*")}$`).test(W))return!0}return!1}function B4($){return K$.extname($)||$}async function U4($,W,Q,Z,J){try{let Y=await z4($,{withFileTypes:!0}),H=K$.relative(Z.cwd,$),X=[],G={},V=0,K=Y.sort((j,_)=>{if(j.isDirectory()&&!_.isDirectory())return-1;if(!j.isDirectory()&&_.isDirectory())return 1;return j.name.localeCompare(_.name)}),z=0;for(let j of K){if(z>=Z.maxEntriesPerDir)break;let _=K$.join($,j.name),B=K$.relative(Z.cwd,_);if(Z.respectGitignore&&_4(B,j.name,J))continue;if(j.isDirectory())if(Q<Z.maxDepth){let F=await U4(_,W,Q+1,Z,J);if(F){X.push(F),V+=F.totalFiles;for(let[A,N]of Object.entries(F.fileStats))G[A]=(G[A]||0)+N}}else{let F=await O4(_,J,Z);X.push({name:j.name,path:B,children:[],fileStats:F.stats,totalFiles:F.total}),V+=F.total;for(let[A,N]of Object.entries(F.stats))G[A]=(G[A]||0)+N}else{X.push({name:j.name,path:B});let F=B4(j.name);G[F]=(G[F]||0)+1,V+=1}z++}return{name:K$.basename($),path:H||".",children:X,fileStats:G,totalFiles:V}}catch{return null}}async function O4($,W,Q){let Z={},J=0;try{let Y=await z4($,{withFileTypes:!0});for(let H of Y){let X=K$.join($,H.name),G=K$.relative(Q.cwd,X);if(Q.respectGitignore&&_4(G,H.name,W))continue;if(H.isDirectory()){let V=await O4(X,W,Q);J+=V.total;for(let[K,z]of Object.entries(V.stats))Z[K]=(Z[K]||0)+z}else{let V=B4(H.name);Z[V]=(Z[V]||0)+1,J+=1}}}catch{}return{total:J,stats:Z}}function DQ($,W){if(W===0)return"";let Z=Object.entries($).sort((J,Y)=>Y[1]-J[1]).slice(0,5).map(([J,Y])=>`${Y} ${J}`);return`[${W} files in subtree: ${Z.join(", ")}]`}function F4($,W="",Q=!0){let Z=[];if(Q)Z.push(`${$.name}/`);for(let J=0;J<$.children.length;J++){let Y=$.children[J];if("children"in Y){let H=Y;if(Z.push(`${W}${H.name}/`),H.totalFiles>0&&H.children.length===0){let X=DQ(H.fileStats,H.totalFiles);if(X)Z.push(`${W} ${X}`)}else if(H.children.length>0){let X=F4(H,`${W} `,!1);Z.push(X)}}else{let H=Y;Z.push(`${W}${H.name}`)}}return Z.join(`
|
|
604
|
+
`)}async function RQ($){try{let W;if($.respectGitignore){let Z=await AQ($.cwd);if(Z===null)return null;W=Z}else W=new Set;let Q=await U4($.cwd,$.cwd,0,$,W);if(!Q)return"Unable to read directory structure";return F4(Q)}catch(W){return`Error generating file tree: ${W instanceof Error?W.message:String(W)}`}}function EQ($){let W=["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],Q=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],Z=W[$.getDay()],J=Q[$.getMonth()],Y=$.getDate().toString().padStart(2,"0"),H=$.getFullYear();return`${Z} ${J} ${Y} ${H}`}function LQ(){if(P$.env.PSModulePath)return"PowerShell";if(P$.platform==="win32"&&P$.env.ComSpec)return"cmd.exe";if(P$.env.SHELL){let $=P$.env.SHELL;if($.includes("zsh"))return"zsh";if($.includes("bash"))return"bash";if($.includes("fish"))return"fish";return K$.basename($)}if(P$.platform==="win32")return"cmd.exe (assumed)";return"bash (assumed)"}function MQ(){try{if(typeof j4==="function")return j4()}catch{}return qQ()}async function TQ($,W,Q){let Z=[],J=[];J.push(`Working directory: ${$}`);let Y=G1($);if(Y){let G=K1($);if(G)J.push(`Is directory a git repo: yes, branch: ${G}`);else J.push("Is directory a git repo: yes")}else J.push("Is directory a git repo: no");let H=MQ();J.push(`OS: ${P$.platform} ${H}`);let X=LQ();if(J.push(`Shell: ${X}`),J.push(`Today's date: ${EQ(new Date)}`),Z.push(`<env>
|
|
571
605
|
${J.join(`
|
|
572
606
|
`)}
|
|
573
|
-
</env>`),W&&Y&&Q){let G=await
|
|
607
|
+
</env>`),W&&Y&&Q){let G=await RQ(Q);if(G!==null)Z.push(`<files>
|
|
574
608
|
${G}
|
|
575
609
|
</files>`)}return Z.join(`
|
|
576
610
|
|
|
577
|
-
`)}function
|
|
611
|
+
`)}function SQ($){let{cwd:W,marker:Q=NQ,includeFileTree:Z=!0,maxDepth:J=3,maxEntriesPerDir:Y=50,respectGitignore:H=!0}=$??{},X=async(G,V)=>{let K=typeof W==="function"?W():W??P$.cwd(),j=await TQ(K,Z,{cwd:K,maxDepth:J,maxEntriesPerDir:Y,respectGitignore:H}),_=G.messages;if(j)_=_$(_,j,Q);let B={...G,messages:_};return V(B)};return X.__middlewareName="env-info",X}var PQ=`You are an expert code reviewer for React 19, Vue 3, Rust, TypeScript, Java, Python, and C/C++.
|
|
578
612
|
Provide comprehensive, constructive feedback that transforms code reviews from gatekeeping to knowledge sharing.
|
|
579
613
|
|
|
580
614
|
## Core Principles
|
|
@@ -632,7 +666,7 @@ Use collaborative language:
|
|
|
632
666
|
- Explain the "why" behind recommendations
|
|
633
667
|
- Offer to pair for complex issues
|
|
634
668
|
|
|
635
|
-
Focus on high-impact issues first, then nice-to-haves.`;function
|
|
669
|
+
Focus on high-impact issues first, then nice-to-haves.`;function xQ($,W,Q){if(Q)return Q.replace("[LANGUAGE]",$);let Z=W&&W.length>0?`
|
|
636
670
|
|
|
637
671
|
Focus particularly on: ${W.join(", ")}`:"";return`Please review the code changes listed above and provide feedback in ${$}.
|
|
638
672
|
${Z}
|
|
@@ -662,29 +696,29 @@ Provide your review in the following format:
|
|
|
662
696
|
- [Specific actionable improvements]
|
|
663
697
|
|
|
664
698
|
## \uD83E\uDDEA Testing Notes (测试建议)
|
|
665
|
-
- [What should be tested, edge cases to consider]`}function
|
|
666
|
-
`)}function
|
|
667
|
-
`),Q=0,Z=0,J=new Set;for(let Y of W)if(Y.startsWith("+++")||Y.startsWith("---")){let H=Y.match(/^[+\-]{3}\s+[ab]\/(.+)/);if(H)J.add(H[1])}else if(Y.startsWith("+")&&!Y.startsWith("+++"))Q++;else if(Y.startsWith("-")&&!Y.startsWith("---"))Z++;return{additions:Q,deletions:Z,files:J.size}}function
|
|
699
|
+
- [What should be tested, edge cases to consider]`}function q4($){switch($){case"A":return"新增 (new file)";case"M":return"修改 (modified)";case"D":return"删除 (deleted)";case"R":return"重命名 (renamed)";case"C":return"复制 (copied)";case"T":return"类型变更 (typechange)";case"U":return"未合并 (unmerged)";default:return $}}function wQ($,W){if($.length===0)return"";let Q=[`\uD83D\uDCCB ${W}:`,""],Z={};for(let Y of $){let H=Y.status;if(!Z[H])Z[H]=[];Z[H].push(Y)}let J=["A","M","D","R","C","T","U"];for(let Y of J){let H=Z[Y];if(!H||H.length===0)continue;Q.push(` ${q4(Y)}:`);for(let X of H)if(X.oldFile)Q.push(` • ${X.oldFile} → ${X.file}`);else Q.push(` • ${X.file}`);Q.push("")}for(let[Y,H]of Object.entries(Z)){if(J.includes(Y))continue;Q.push(` ${q4(Y)}:`);for(let X of H)Q.push(` • ${X.file}`);Q.push("")}return Q.push(` 共 ${$.length} 个文件 (Total: ${$.length} files)`),Q.join(`
|
|
700
|
+
`)}function bQ($){let W=$.split(`
|
|
701
|
+
`),Q=0,Z=0,J=new Set;for(let Y of W)if(Y.startsWith("+++")||Y.startsWith("---")){let H=Y.match(/^[+\-]{3}\s+[ab]\/(.+)/);if(H)J.add(H[1])}else if(Y.startsWith("+")&&!Y.startsWith("+++"))Q++;else if(Y.startsWith("-")&&!Y.startsWith("---"))Z++;return{additions:Q,deletions:Z,files:J.size}}function yQ($){return`\uD83D\uDCC8 统计 (Stats): ${$.files} files, +${$.additions} additions, -${$.deletions} deletions`}function CQ($){let W=[...$].reverse().find((J)=>J.role==="user");if(!W)return!1;let Q=typeof W.content==="string"?W.content:JSON.stringify(W.content);return[/help.*review.*code.*changes?/i,/review.*code.*changes?/i,/code.*review/i,/review.*changes?/i,/check.*my.*code/i,/review.*my.*code/i].some((J)=>J.test(Q))}function IQ($={}){let W=$.name??"review-mode",Q=$.defaultLanguage??"English",Z=$.reviewTarget??"unstaged",J=$.focusAreas,Y=$.includeStats??!0,H=$.cwd??process.cwd(),X=$.customPrompt,G=async(V,K)=>{if(!CQ(V.messages))return K(V);if(V.metadata?.reviewProcessed)return K(V);try{let z=U0(H),j="",_=[],B="",F=_0(H),A=B0(H);if(Z==="staged"||Z==="both"&&F){if(F){let L=k0(H);j+=L,_=h0(H),B="Staged changes (暂存区的更改)"}}if(Z==="unstaged"||Z==="both"&&A){if(A){let L=VW(H);if(j)j+=`
|
|
668
702
|
|
|
669
|
-
${L}`,
|
|
670
|
-
分支 (Branch): ${z.currentBranch}`:"",
|
|
671
|
-
${
|
|
703
|
+
${L}`,B="Staged and unstaged changes (暂存区和工作区的更改)";else j=L,B="Unstaged changes (工作区的更改)"}}let N=Y?bQ(j):null,U=z.currentBranch?`
|
|
704
|
+
分支 (Branch): ${z.currentBranch}`:"",R=N?`
|
|
705
|
+
${yQ(N)}`:"",q=_.length>0?`
|
|
672
706
|
|
|
673
|
-
${
|
|
707
|
+
${wQ(_,B)}`:"",D=`# \uD83D\uDD0D Code Review Request
|
|
674
708
|
|
|
675
709
|
## 基本信息 (Basic Info)
|
|
676
|
-
${
|
|
710
|
+
${B}${U}${R}${q}
|
|
677
711
|
|
|
678
712
|
---
|
|
679
|
-
`,O=
|
|
680
|
-
${
|
|
713
|
+
`,O=xQ(Q,J,X),T=`<system-reminder>
|
|
714
|
+
${PQ}
|
|
681
715
|
</system-reminder>
|
|
682
716
|
|
|
683
|
-
${
|
|
717
|
+
${D}
|
|
684
718
|
|
|
685
|
-
${O}`,
|
|
719
|
+
${O}`,S=V0(V.messages,T);return await K({...V,messages:S,metadata:{...V.metadata,reviewProcessed:!0,reviewTarget:Z,hasReview:!0,diffStats:N}})}catch(z){let j={role:"assistant",content:`✗ Code review 失败
|
|
686
720
|
|
|
687
|
-
Error: ${z instanceof Error?z.message:String(z)}`};return{...V,messages:[...V.messages,j],currentResponse:j.content,shouldContinue:!1,stopReason:"error",metadata:{...V.metadata,reviewProcessed:!0}}}};return G.__middlewareName=W,G}import{existsSync as
|
|
721
|
+
Error: ${z instanceof Error?z.message:String(z)}`};return{...V,messages:[...V.messages,j],currentResponse:j.content,shouldContinue:!1,stopReason:"error",metadata:{...V.metadata,reviewProcessed:!0}}}};return G.__middlewareName=W,G}import{existsSync as vQ}from"node:fs";import{appendFile as fQ,mkdir as kQ,readdir as hQ,readFile as gQ}from"node:fs/promises";import{homedir as uQ}from"node:os";import u$ from"node:path";import a0 from"node:process";class g1 extends k{name="Skill";description;parameters={type:"object",properties:{action:{type:"string",enum:["activate","deactivate"],description:"Operation type: activate to load skill instructions, deactivate to unload"},skill_name:{type:"string",description:'The skill name to control (e.g., "commit", "pdf", "review-pr")'}},required:["action","skill_name"]};skills;executor;constructor($){super();if(this.skills=new Map,this.executor=$?.executor,$?.skills)for(let W of $.skills)this.skills.set(W.name,W);this.description=this.buildDescription()}registerSkill($){this.skills.set($.name,$)}unregisterSkill($){return this.skills.delete($)}getSkills(){return Array.from(this.skills.values())}hasSkill($){return this.skills.has($)}setExecutor($){this.executor=$}async execute($,W){let{action:Q,skill_name:Z}=this.validateArgs($);if(!this.skills.has(Z)){let J=Array.from(this.skills.keys()).join(", ");return I(`Skill "${Z}" not found. Available skills: ${J||"none"}`)}if(!this.executor)return I("Skill executor is not configured. Please set an executor using setExecutor().");try{let J=await this.executor(Q,Z);return{content:[{type:"text",text:J}],structuredContent:{success:!0,message:J}}}catch(J){return I(`Skill operation failed: ${J instanceof Error?J.message:String(J)}`)}}validateArgs($){let{action:W,skill_name:Q}=$;if(typeof W!=="string"||W!=="activate"&&W!=="deactivate")throw Error('action is required and must be either "activate" or "deactivate"');if(typeof Q!=="string"||!Q.trim())throw Error("skill_name is required and must be a non-empty string");return{action:W,skill_name:Q.trim()}}buildDescription(){if(this.skills.size===0)return`Load a skill to get detailed instructions for a specific task.
|
|
688
722
|
Skills provide specialized knowledge and step-by-step guidance.
|
|
689
723
|
Use this when a task matches an available skill's description.
|
|
690
724
|
|
|
@@ -714,20 +748,20 @@ ${Array.from(this.skills.values()).map((Q)=>`<skill>
|
|
|
714
748
|
<description>${Q.description}</description>
|
|
715
749
|
</skill>`).join(`
|
|
716
750
|
`)}
|
|
717
|
-
</available_skills>`}}var
|
|
751
|
+
</available_skills>`}}var N4=u$.join(a0.cwd(),".goatchain","skills-debug.log"),mQ=a0.env.GOATCHAIN_SKILLS_DEBUG==="1";async function P($,W){try{if(!mQ)return;let Q=new Date().toISOString(),Z=W?`[${Q}] ${$}
|
|
718
752
|
${JSON.stringify(W,null,2)}
|
|
719
753
|
|
|
720
754
|
`:`[${Q}] ${$}
|
|
721
755
|
|
|
722
|
-
`,J=
|
|
756
|
+
`,J=u$.dirname(N4);if(!vQ(J))await kQ(J,{recursive:!0});await fQ(N4,Z,"utf-8")}catch(Q){console.error("Failed to write skills debug log:",Q)}}var pQ="[Active Skills]";async function u1($){try{await P(`Attempting to parse skill file: ${$}`);let W=await gQ($,"utf-8");if(await P(`Successfully read file: ${$} (${W.length} chars)`),!W.startsWith(`---
|
|
723
757
|
`)&&!W.startsWith(`---\r
|
|
724
|
-
`))return await
|
|
725
|
-
`),Z=-1;for(let V=1;V<Q.length;V++)if(Q[V].trim()==="---"){Z=V;break}if(Z===-1)return await
|
|
726
|
-
`).trim(),G={name:H.name,description:H.description,content:X,fullPath:$};return await
|
|
758
|
+
`))return await P(`File ${$} does not start with frontmatter delimiter`),null;let Q=W.split(`
|
|
759
|
+
`),Z=-1;for(let V=1;V<Q.length;V++)if(Q[V].trim()==="---"){Z=V;break}if(Z===-1)return await P(`File ${$} missing closing frontmatter delimiter`),null;let J=Q.slice(1,Z),Y=Q.slice(Z+1),H={};for(let V of J){let K=V.indexOf(":");if(K>0){let z=V.slice(0,K).trim(),j=V.slice(K+1).trim();H[z]=j}}if(await P(`Parsed frontmatter from ${$}:`,H),!H.name||!H.description)return await P(`File ${$} missing required fields (name or description)`,H),null;let X=Y.join(`
|
|
760
|
+
`).trim(),G={name:H.name,description:H.description,content:X,fullPath:$};return await P(`Successfully parsed skill: ${H.name}`,{name:G.name,description:G.description,contentLength:X.length}),G}catch(W){return await P(`Error parsing skill file ${$}:`,W),null}}async function A4($){let W=[];try{await P(`Scanning skills directory: ${$}`);let Q=await hQ($,{withFileTypes:!0});await P(`Found ${Q.length} entries in ${$}`,Q.map((Z)=>({name:Z.name,isDirectory:Z.isDirectory()})));for(let Z of Q){if(!Z.isDirectory()){await P(`Skipping non-directory entry: ${Z.name}`);continue}let J=u$.join($,Z.name,"SKILL.md");await P(`Checking skill path: ${J}`);let Y=await u1(J);if(Y)W.push({name:Y.name,description:Y.description,fullPath:Y.fullPath}),await P(`Added skill: ${Y.name}`);else await P(`Failed to parse skill at: ${J}`)}await P(`Scan complete for ${$}. Found ${W.length} valid skills`,W.map((Z)=>Z.name))}catch(Q){await P(`Error scanning directory ${$}:`,Q)}return W}async function D4($){await P(`Scanning ${$.length} skill directories`,$);let W=new Map;for(let Z of $){await P(`Scanning directory: ${Z}`);let J=await A4(Z);await P(`Found ${J.length} skills in ${Z}`,J.map((Y)=>Y.name));for(let Y of J){if(W.has(Y.name))await P(`Overriding skill "${Y.name}" with version from ${Z}`);W.set(Y.name,Y)}}let Q=Array.from(W.values());return await P(`Total unique skills after scanning all directories: ${Q.length}`,Q.map((Z)=>Z.name)),Q}function cQ($){let W=new Map,Q=0;for(let J of $)if(J.role==="assistant"&&J.tool_calls)for(let Y of J.tool_calls){let H=Y.function.name;if(H==="Skill"||H.endsWith("_Skill")){Q++;try{let X=typeof Y.function.arguments==="string"?JSON.parse(Y.function.arguments):Y.function.arguments;if(X?.action&&X?.skill_name){let G=String(X.action),V=String(X.skill_name);if(G==="activate")W.set(V,"activated"),P(`Skill activated: ${V}`,{toolName:H,args:X}).catch(()=>{});else if(G==="deactivate")W.set(V,"deactivated"),P(`Skill deactivated: ${V}`,{toolName:H,args:X}).catch(()=>{})}}catch(X){P("Error parsing skill tool call:",{toolName:H,error:X}).catch(()=>{})}}}let Z=Array.from(W.entries()).filter(([J,Y])=>Y==="activated").map(([J])=>J);return P(`findActiveSkills: Found ${Z.length} active skills from ${Q} tool calls`,Z).catch(()=>{}),Z}async function dQ($,W){await P(`Loading content for ${$.length} active skills`,{skillNames:$,directories:W});let Q=[];for(let J of $){await P(`Searching for skill: ${J}`);let Y=!1;for(let H of W){let X=u$.join(H,J,"SKILL.md");await P(`Trying path: ${X}`);let G=await u1(X);if(G){Q.push(`## Skill: ${G.name}
|
|
727
761
|
|
|
728
|
-
${G.content}`),await
|
|
762
|
+
${G.content}`),await P(`Successfully loaded skill: ${J} from ${X}`),Y=!0;break}}if(!Y)await P(`WARNING: Skill "${J}" not found in any directory`)}let Z=Q.join(`
|
|
729
763
|
|
|
730
|
-
`);return await
|
|
731
|
-
`),await K(V);let z=typeof W==="function"?W():W??
|
|
732
|
-
`),
|
|
733
|
-
`)}catch(V){await
|
|
764
|
+
`);return await P(`Loaded ${Q.length} skills, total content length: ${Z.length}`),Z}function lQ($){let W=$?.cwd,Q=$?.globalSkillsDirectory===null?null:$?.globalSkillsDirectory??u$.join(uQ(),".claude","skills"),Z=$?.projectSkillsDirectory,J=$?.marker??pQ,Y=$?.name??"skills",H=null,X=null,G=async(V,K)=>{if(await P("=== Skills Middleware Execution Start ==="),X)await X;if(!H||H.length===0)return await P("No skills discovered, passing through without modification"),await P(`=== Skills Middleware Execution End (No-op) ===
|
|
765
|
+
`),await K(V);let z=typeof W==="function"?W():W??a0.cwd();await P(`Resolved cwd: ${z}`);let j=Z===null?null:Z??u$.join(z,".claude","skills");await P(`Project skills directory: ${j??"disabled"}`),await P(`Global skills directory: ${Q??"disabled"}`);let _=[];if(j)_.push(j);if(Q)_.push(Q);await P("Skills directories to scan:",_),await P(`Scanning ${V.messages.length} messages for active skills`);let B=cQ(V.messages);await P(`Active skills found: ${B.length}`,B);let F=V.messages;if(B.length>0){await P("Loading active skills content...");let U=await dQ(B,_);if(U)await P(`Injecting ${U.length} chars of skills content with marker: "${J}"`),F=_$(F,U,J),await P("Skills content injected successfully");else await P("WARNING: No skills content loaded despite active skills")}else await P("No active skills, skipping content injection");let A={...V,messages:F};await P("Calling next middleware...");let N=await K(A);return await P(`=== Skills Middleware Execution End ===
|
|
766
|
+
`),N};return G.__middlewareName=Y,G.__createTools=async()=>{if(await P("__createTools called"),X)await P("Waiting for skills discovery to complete..."),await X,await P("Skills discovery completed");if(!H)await P("No discovered skills yet, using empty array"),H=[];if(H.length===0)return await P("No skills discovered, skipping tool registration"),[];await P(`Creating SkillTool with ${H.length} skills`,H.map((K)=>K.name));let V=new g1({skills:H,executor:async(K,z)=>{if(await P(`Skill executor called: ${K} ${z}`),K==="activate")return`Skill '${z}' activated. Instructions will be loaded in next turn.`;else return`Skill '${z}' deactivated. Instructions have been removed.`}});return await P("SkillTool created successfully"),[V]},X=(async()=>{try{await P("=== Skills Middleware Initialization Start ===");let V=typeof W==="function"?W():W??a0.cwd();await P(`Initial cwd: ${V}`);let K=Z===null?null:Z??u$.join(V,".claude","skills");await P(`Initial project skills directory: ${K??"disabled"}`);let z=[];if(K)z.push(K);if(Q)z.push(Q);await P("Initial directories to scan:",z),H=await D4(z),await P(`Skills discovery complete. Found ${H.length} skills:`,H.map((j)=>({name:j.name,description:j.description,fullPath:j.fullPath}))),await P(`=== Skills Middleware Initialization Complete ===
|
|
767
|
+
`)}catch(V){await P("Skills initialization error:",V),H=[]}})(),G}export{x0 as toLoopCheckpoint,zW as textContent,A4 as scanSkillsDirectory,D4 as scanMultipleSkillsDirectories,K4 as runAcpServer,u1 as parseSkillFile,R$ as isReadOnlyBashCommand,V0 as injectSystemReminderToLastUserMessage,_W as imageContent,c9 as generalPurposeAgentPrompt,M6 as generalPurposeAgent,G0 as fromLoopCheckpoint,e1 as extractPersistentState,P0 as extractPersistentMetadata,Z1 as extractAccountIdFromToken,m9 as explorePrompt,f1 as exploreAgent,I as errorContent,B$ as ensureNotAborted,lQ as createSkillsMiddleware,IQ as createReviewModeMiddleware,N6 as createReadOnlyBashTool,I1 as createPlanModeMiddleware,q1 as createParallelSubagentMiddleware,C0 as createOpenAIAdapter,y0 as createModel,b0 as createInitialLoopState,SQ as createEnvInfoMiddleware,m$ as createContextCompressionMiddleware,z1 as createCommitModeMiddleware,d4 as createCodexAdapter,OQ as createAgentRulesMiddleware,t1 as compressSessionManually,w0 as compose,p9 as buildGeneralPurposeAgentPrompt,v1 as buildExplorePrompt,F1 as assertReadOnlyBashCommand,Z0 as WriteTool,Q0 as WebSearchTool,J0 as ToolRegistry,W0 as TodoWriteTool,$0 as TodoPlanTool,C$ as StateStore,n as StateKeys,T0 as SessionRouter,e as Session,b$ as RetryPolicy,e$ as ReadTool,sW as ReadOnlyBashTool,O1 as READ_ONLY_COMMANDS,M0 as ProtocolConverter,v as ModelError,z0 as InMemoryStateStore,y$ as HookManager,t$ as GrepTool,s$ as GlobTool,k1 as FilteredToolRegistry,j0 as FileStateStore,g0 as FORBIDDEN_PATTERNS,a$ as EditTool,L$ as BashTool,k as BaseTool,K0 as BaseSessionManager,e as BaseSession,n$ as AstGrepSearchTool,r$ as AstGrepReplaceTool,d$ as AskUserTool,Q1 as AgentMaxIterationsError,N$ as AgentAbortError,D$ as Agent,S0 as ACPAgent};
|