goatchain 0.0.10 → 0.0.11
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 +156 -128
- package/dist/subagent/index.d.ts +1 -0
- package/dist/subagent/parallel-task-coordinator.d.ts +19 -0
- package/dist/tool/builtin/astGrepReplace.d.ts +6 -0
- package/dist/tool/builtin/edit.d.ts +6 -0
- package/dist/tool/builtin/fileBlacklist.d.ts +25 -0
- package/dist/tool/builtin/glob.d.ts +6 -0
- package/dist/tool/builtin/grep.d.ts +6 -0
- package/dist/tool/builtin/read.d.ts +8 -0
- package/dist/tool/builtin/write.d.ts +8 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import{createRequire as
|
|
2
|
-
`);let Z;while((Z=
|
|
3
|
-
`),Y=Y.replace(/\\r/g,"\r");W[J]=Y}return W}function
|
|
1
|
+
import{createRequire as N2}from"node:module";var O2=Object.create;var{getPrototypeOf:_2,defineProperty:C1,getOwnPropertyNames:F2}=Object;var q2=Object.prototype.hasOwnProperty;var v1=($,W,Q)=>{Q=$!=null?O2(_2($)):{};let Z=W||!$||!$.__esModule?C1(Q,"default",{value:$,enumerable:!0}):Q;for(let J of F2($))if(!q2.call(Z,J))C1(Z,J,{get:()=>$[J],enumerable:!0});return Z};var J0=($,W)=>()=>(W||$((W={exports:{}}).exports,W),W.exports);var Y0=N2(import.meta.url);var nW=J0((bZ,J9)=>{J9.exports={name:"dotenv",version:"17.2.3",description:"Loads environment variables from .env file",main:"lib/main.js",types:"lib/main.d.ts",exports:{".":{types:"./lib/main.d.ts",require:"./lib/main.js",default:"./lib/main.js"},"./config":"./config.js","./config.js":"./config.js","./lib/env-options":"./lib/env-options.js","./lib/env-options.js":"./lib/env-options.js","./lib/cli-options":"./lib/cli-options.js","./lib/cli-options.js":"./lib/cli-options.js","./package.json":"./package.json"},scripts:{"dts-check":"tsc --project tests/types/tsconfig.json",lint:"standard",pretest:"npm run lint && npm run dts-check",test:"tap run tests/**/*.js --allow-empty-coverage --disable-coverage --timeout=60000","test:coverage":"tap run tests/**/*.js --show-full-coverage --timeout=60000 --coverage-report=text --coverage-report=lcov",prerelease:"npm test",release:"standard-version"},repository:{type:"git",url:"git://github.com/motdotla/dotenv.git"},homepage:"https://github.com/motdotla/dotenv#readme",funding:"https://dotenvx.com",keywords:["dotenv","env",".env","environment","variables","config","settings"],readmeFilename:"README.md",license:"BSD-2-Clause",devDependencies:{"@types/node":"^18.11.3",decache:"^4.6.2",sinon:"^14.0.1",standard:"^17.0.0","standard-version":"^9.5.0",tap:"^19.2.0",typescript:"^4.8.4"},engines:{node:">=12"},browser:{fs:!1}}});var $2=J0((CZ,O$)=>{var P1=Y0("fs"),m0=Y0("path"),Y9=Y0("os"),V9=Y0("crypto"),G9=nW(),S1=G9.version,oW=["\uD83D\uDD10 encrypt with Dotenvx: https://dotenvx.com","\uD83D\uDD10 prevent committing .env to code: https://dotenvx.com/precommit","\uD83D\uDD10 prevent building .env in docker: https://dotenvx.com/prebuild","\uD83D\uDCE1 add observability to secrets: https://dotenvx.com/ops","\uD83D\uDC65 sync secrets across teammates & machines: https://dotenvx.com/ops","\uD83D\uDDC2️ backup and recover secrets: https://dotenvx.com/ops","✅ audit secrets and track compliance: https://dotenvx.com/ops","\uD83D\uDD04 add secrets lifecycle management: https://dotenvx.com/ops","\uD83D\uDD11 add access controls to secrets: https://dotenvx.com/ops","\uD83D\uDEE0️ run anywhere with `dotenvx run -- yourcommand`","⚙️ specify custom .env file path with { path: '/custom/path/.env' }","⚙️ enable debug logging with { debug: true }","⚙️ override existing env vars with { override: true }","⚙️ suppress all logs with { quiet: true }","⚙️ write to custom object with { processEnv: myObject }","⚙️ load multiple .env files with { path: ['.env.local', '.env'] }"];function H9(){return oW[Math.floor(Math.random()*oW.length)]}function $0($){if(typeof $==="string")return!["false","0","no","off",""].includes($.toLowerCase());return Boolean($)}function X9(){return process.stdout.isTTY}function K9($){return X9()?`\x1B[2m${$}\x1B[0m`:$}var j9=/(?:^|^)\s*(?:export\s+)?([\w.-]+)(?:\s*=\s*?|:\s+?)(\s*'(?:\\'|[^'])*'|\s*"(?:\\"|[^"])*"|\s*`(?:\\`|[^`])*`|[^#\r\n]+)?\s*(?:#.*)?(?:$|$)/mg;function z9($){let W={},Q=$.toString();Q=Q.replace(/\r\n?/mg,`
|
|
2
|
+
`);let Z;while((Z=j9.exec(Q))!=null){let J=Z[1],Y=Z[2]||"";Y=Y.trim();let V=Y[0];if(Y=Y.replace(/^(['"`])([\s\S]*)\1$/mg,"$2"),V==='"')Y=Y.replace(/\\n/g,`
|
|
3
|
+
`),Y=Y.replace(/\\r/g,"\r");W[J]=Y}return W}function B9($){$=$||{};let W=eW($);$.path=W;let Q=d.configDotenv($);if(!Q.parsed){let V=Error(`MISSING_DATA: Cannot parse ${W} for an unknown reason`);throw V.code="MISSING_DATA",V}let Z=tW($).split(","),J=Z.length,Y;for(let V=0;V<J;V++)try{let G=Z[V].trim(),X=O9(Q,G);Y=d.decrypt(X.ciphertext,X.key);break}catch(G){if(V+1>=J)throw G}return d.parse(Y)}function U9($){console.error(`[dotenv@${S1}][WARN] ${$}`)}function q0($){console.log(`[dotenv@${S1}][DEBUG] ${$}`)}function sW($){console.log(`[dotenv@${S1}] ${$}`)}function tW($){if($&&$.DOTENV_KEY&&$.DOTENV_KEY.length>0)return $.DOTENV_KEY;if(process.env.DOTENV_KEY&&process.env.DOTENV_KEY.length>0)return process.env.DOTENV_KEY;return""}function O9($,W){let Q;try{Q=new URL(W)}catch(G){if(G.code==="ERR_INVALID_URL"){let X=Error("INVALID_DOTENV_KEY: Wrong format. Must be in valid uri format like dotenv://:key_1234@dotenvx.com/vault/.env.vault?environment=development");throw X.code="INVALID_DOTENV_KEY",X}throw G}let Z=Q.password;if(!Z){let G=Error("INVALID_DOTENV_KEY: Missing key part");throw G.code="INVALID_DOTENV_KEY",G}let J=Q.searchParams.get("environment");if(!J){let G=Error("INVALID_DOTENV_KEY: Missing environment part");throw G.code="INVALID_DOTENV_KEY",G}let Y=`DOTENV_VAULT_${J.toUpperCase()}`,V=$.parsed[Y];if(!V){let G=Error(`NOT_FOUND_DOTENV_ENVIRONMENT: Cannot locate environment ${Y} in your .env.vault file.`);throw G.code="NOT_FOUND_DOTENV_ENVIRONMENT",G}return{ciphertext:V,key:Z}}function eW($){let W=null;if($&&$.path&&$.path.length>0)if(Array.isArray($.path)){for(let Q of $.path)if(P1.existsSync(Q))W=Q.endsWith(".vault")?Q:`${Q}.vault`}else W=$.path.endsWith(".vault")?$.path:`${$.path}.vault`;else W=m0.resolve(process.cwd(),".env.vault");if(P1.existsSync(W))return W;return null}function aW($){return $[0]==="~"?m0.join(Y9.homedir(),$.slice(1)):$}function _9($){let W=$0(process.env.DOTENV_CONFIG_DEBUG||$&&$.debug),Q=$0(process.env.DOTENV_CONFIG_QUIET||$&&$.quiet);if(W||!Q)sW("Loading env from encrypted .env.vault");let Z=d._parseVault($),J=process.env;if($&&$.processEnv!=null)J=$.processEnv;return d.populate(J,Z,$),{parsed:Z}}function F9($){let W=m0.resolve(process.cwd(),".env"),Q="utf8",Z=process.env;if($&&$.processEnv!=null)Z=$.processEnv;let J=$0(Z.DOTENV_CONFIG_DEBUG||$&&$.debug),Y=$0(Z.DOTENV_CONFIG_QUIET||$&&$.quiet);if($&&$.encoding)Q=$.encoding;else if(J)q0("No encoding is specified. UTF-8 is used by default");let V=[W];if($&&$.path)if(!Array.isArray($.path))V=[aW($.path)];else{V=[];for(let K of $.path)V.push(aW(K))}let G,X={};for(let K of V)try{let B=d.parse(P1.readFileSync(K,{encoding:Q}));d.populate(X,B,$)}catch(B){if(J)q0(`Failed to load ${K} ${B.message}`);G=B}let H=d.populate(Z,X,$);if(J=$0(Z.DOTENV_CONFIG_DEBUG||J),Y=$0(Z.DOTENV_CONFIG_QUIET||Y),J||!Y){let K=Object.keys(H).length,B=[];for(let j of V)try{let z=m0.relative(process.cwd(),j);B.push(z)}catch(z){if(J)q0(`Failed to load ${j} ${z.message}`);G=z}sW(`injecting env (${K}) from ${B.join(",")} ${K9(`-- tip: ${H9()}`)}`)}if(G)return{parsed:X,error:G};else return{parsed:X}}function q9($){if(tW($).length===0)return d.configDotenv($);let W=eW($);if(!W)return U9(`You set DOTENV_KEY but you are missing a .env.vault file at ${W}. Did you forget to build it?`),d.configDotenv($);return d._configVault($)}function N9($,W){let Q=Buffer.from(W.slice(-64),"hex"),Z=Buffer.from($,"base64"),J=Z.subarray(0,12),Y=Z.subarray(-16);Z=Z.subarray(12,-16);try{let V=V9.createDecipheriv("aes-256-gcm",Q,J);return V.setAuthTag(Y),`${V.update(Z)}${V.final()}`}catch(V){let G=V instanceof RangeError,X=V.message==="Invalid key length",H=V.message==="Unsupported state or unable to authenticate data";if(G||X){let K=Error("INVALID_DOTENV_KEY: It must be 64 characters long (or more)");throw K.code="INVALID_DOTENV_KEY",K}else if(H){let K=Error("DECRYPTION_FAILED: Please check your DOTENV_KEY");throw K.code="DECRYPTION_FAILED",K}else throw V}}function A9($,W,Q={}){let Z=Boolean(Q&&Q.debug),J=Boolean(Q&&Q.override),Y={};if(typeof W!=="object"){let V=Error("OBJECT_REQUIRED: Please check the processEnv argument being passed to populate");throw V.code="OBJECT_REQUIRED",V}for(let V of Object.keys(W))if(Object.prototype.hasOwnProperty.call($,V)){if(J===!0)$[V]=W[V],Y[V]=W[V];if(Z)if(J===!0)q0(`"${V}" is already defined and WAS overwritten`);else q0(`"${V}" is already defined and was NOT overwritten`)}else $[V]=W[V],Y[V]=W[V];return Y}var d={configDotenv:F9,_configVault:_9,_parseVault:B9,config:q9,decrypt:N9,parse:z9,populate:A9};CZ.configDotenv=d.configDotenv;CZ._configVault=d._configVault;CZ._parseVault=d._parseVault;CZ.config=d.config;CZ.decrypt=d.decrypt;CZ.parse=d.parse;CZ.populate=d.populate;O$.exports=d});var Q2=J0((vZ,W2)=>{var I$={};if(process.env.DOTENV_CONFIG_ENCODING!=null)I$.encoding=process.env.DOTENV_CONFIG_ENCODING;if(process.env.DOTENV_CONFIG_PATH!=null)I$.path=process.env.DOTENV_CONFIG_PATH;if(process.env.DOTENV_CONFIG_QUIET!=null)I$.quiet=process.env.DOTENV_CONFIG_QUIET;if(process.env.DOTENV_CONFIG_DEBUG!=null)I$.debug=process.env.DOTENV_CONFIG_DEBUG;if(process.env.DOTENV_CONFIG_OVERRIDE!=null)I$.override=process.env.DOTENV_CONFIG_OVERRIDE;if(process.env.DOTENV_CONFIG_DOTENV_KEY!=null)I$.DOTENV_KEY=process.env.DOTENV_CONFIG_DOTENV_KEY;W2.exports=I$});var J2=J0((fZ,Z2)=>{var S9=/^dotenv_config_(encoding|path|quiet|debug|override|DOTENV_KEY)=(.+)$/;Z2.exports=function(W){let Q=W.reduce(function(Z,J){let Y=J.match(S9);if(Y)Z[Y[1]]=Y[2];return Z},{});if(!("quiet"in Q))Q.quiet="true";return Q}});var Y2=J0(()=>{(function(){$2().config(Object.assign({},Q2(),J2()(process.argv)))})()});import{encoding_for_model as A2,get_encoding as E2}from"tiktoken";var R2="gpt-4o";function K$($,W){if(!$)return 0;let Q=null;try{return Q=A2(W??R2),Q.encode($).length}catch(Z){console.error("Error encoding text:",Z);try{return Q=E2("cl100k_base"),Q.encode($).length}catch{return Math.ceil($.length/4)}}finally{Q?.free()}}function f1($,W){if(typeof $==="string")return K$($,W);if(Array.isArray($))return $.reduce((Q,Z)=>{if(typeof Z==="object"&&Z!==null&&"text"in Z)return Q+K$(String(Z.text),W);return Q},0);return 0}function y1($,W){try{let Q=JSON.stringify($);return K$(Q,W)}catch{return D2($,W)}}function D2($,W){let Z=4;if(Z+=f1($.content,W),$.role==="assistant"&&$.tool_calls)for(let J of $.tool_calls){Z+=K$(J.function.name,W);let Y=typeof J.function.arguments==="string"?J.function.arguments:JSON.stringify(J.function.arguments);Z+=K$(Y,W),Z+=10}if($.role==="tool"&&$.name)Z+=K$($.name,W);if($.role==="assistant"&&$.reasoning_content)Z+=K$($.reasoning_content,W);return Z}function T$($,W){if(!$||$.length===0)return 0;try{let Q=JSON.stringify($);return K$(Q,W)}catch{return $.reduce((Z,J)=>Z+y1(J,W),3)}}var r={CHECKPOINT:"checkpoint",COMPRESSION:"compression",SESSION:"session",COMPRESSION_SNAPSHOT:"compression-snapshot"};function j$($,W,Q="[Previous conversation context]"){let Z=[...$],J=Z.findIndex((j)=>j.role==="system");if(J===-1)return Z;let Y=Z[J],V=Y.content;if(!W||W.trim().length===0)return Z;let X={type:"text",text:`${Q}
|
|
4
4
|
|
|
5
|
-
${W}`},
|
|
5
|
+
${W}`},K=[...L2(V,Q),X],B={...Y,content:K};return Z[J]=B,Z}function L2($,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 V=typeof Y.text==="string"?Y.text:"",G=Q(V);if(G.trim().length>0)Z.push({...Y,text:G});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 d0($,W){let Q=[...$],Z=-1;for(let H=Q.length-1;H>=0;H--)if(Q[H].role==="user"){Z=H;break}if(Z===-1){let H={role:"user",content:W};return[...Q,H]}let J=Q[Z],Y=J.content,V,G={type:"text",text:W};if(typeof Y==="string")V=[{type:"text",text:Y},G];else if(Array.isArray(Y))V=[...Y,G];else V=[Y,G];let X={...J,content:V};return Q[Z]=X,Q}var I1="[Old tool result content cleared]",M2=`
|
|
6
6
|
Summarize the conversation context for future continuation.
|
|
7
7
|
|
|
8
8
|
Rules:
|
|
@@ -18,30 +18,30 @@ Existing summary (if any):
|
|
|
18
18
|
|
|
19
19
|
Content to summarize:
|
|
20
20
|
{{content}}
|
|
21
|
-
`;function
|
|
21
|
+
`;function k$($){let{maxTokens:W,protectedTurns:Q=0,model:Z,stateStore:J,toolCompressionTarget:Y=0.45,minKeepToolResults:V=5}=$,G=Math.floor(W*0.5),X=Math.floor(W*0.8),H=async(K,B)=>{let j=await J.load(K.sessionId,r.COMPRESSION),z=K.messages;if(j?.summary)z=j$(z,j.summary);let O=T$(z),F=0,E=0,_=j?.summary,U=!1;if(O>X){let y=x2(z),L=w2(z,Q),C=await P2(z,Z,j?.summary,y,L);if(C.summaryApplied)z=C.compressedMessages,_=C.newSummary,E=C.removedCount,U=!0,z=j$(z,_)}if((U?T$(z):O)>G){let y=Math.floor(W*Y),L=T2(z,y,V);z=L.compressedMessages,F=L.clearedCount}let A=U||F>0,R=A?T$(z):O,q=A?Date.now():0;if(U){let y={tokensBefore:O,tokensAfter:R,clearedToolOutputs:F,removedMessages:E,summaryGenerated:!0,timestamp:q},L={lastStats:y,history:[...j?.history??[],y],summary:_,updatedAt:q};await J.save(K.sessionId,r.COMPRESSION,L)}let S={...K,messages:z,metadata:A?{...K.metadata,lastCompression:{tokensBefore:O,tokensAfter:R,clearedToolOutputs:F,removedMessages:E,summaryGenerated:U,timestamp:q}}:K.metadata};return B(S)};return H.__middlewareName="context-compression",H}function T2($,W,Q){let Z=[];if($.forEach((X,H)=>{if(X.role==="tool")Z.push(H)}),Z.length===0)return{compressedMessages:$,clearedCount:0};let J=Math.min(Q,Z.length),Y=Z.slice(0,Z.length-J),V=$,G=0;for(let X of Y){let H=V[X];if(typeof H.content==="string"&&H.content===I1)continue;if(V=V.map((B,j)=>{if(j===X)return{...H,content:I1};return B}),G++,T$(V)<=W)break}return{compressedMessages:V,clearedCount:G}}async function P2($,W,Q,Z,J){let Y=$.slice(Z,J);if(Y.length===0)return{compressedMessages:$,newSummary:Q??"",removedCount:0,summaryApplied:!1};let V=k1(Y),G=await h1(V,W,Q);if(!G)return{compressedMessages:$,newSummary:Q??"",removedCount:0,summaryApplied:!1};return{compressedMessages:[...$.slice(0,Z),...$.slice(J)],newSummary:G,removedCount:Y.length,summaryApplied:!0}}function k1($){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
|
|
22
22
|
${Z}`)}else if(Q.role==="assistant"){let Z=typeof Q.content==="string"?Q.content:JSON.stringify(Q.content);W.push(`## Assistant
|
|
23
23
|
${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"}
|
|
24
24
|
${Y}`)}return W.join(`
|
|
25
25
|
|
|
26
26
|
---
|
|
27
27
|
|
|
28
|
-
`)}async function
|
|
28
|
+
`)}async function h1($,W,Q,Z){let J=S2(Z??M2,Q,$),Y=[{role:"system",content:"You are a helpful assistant that creates concise rolling summaries."},{role:"user",content:J}],V="";for await(let G of W.stream({messages:Y,maxOutputTokens:500}))if(G.type==="delta"&&G.chunk.kind==="text")V+=G.chunk.text;else if(G.type==="response_end")break;return V.trim()}function S2($,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 V=[];if(!Z)V.push(`Existing summary (if any):
|
|
29
29
|
${W??"(none)"}`);if(!J)V.push(`Content to summarize:
|
|
30
30
|
${Q}`);return`${Y.trim()}
|
|
31
31
|
|
|
32
32
|
${V.join(`
|
|
33
33
|
|
|
34
34
|
`)}
|
|
35
|
-
`}async function C1($){let{sessionId:W,fullMessages:Q,model:Z,stateStore:J,summaryPrompt:Y}=$,V=Q.length,G=Q.filter((R)=>R.role==="tool").length,K=Q.filter((R)=>R.role!=="system");if(K.length===0)return{summary:"",messageCount:V,toolOutputCount:G};let H=await J.load(W,n.COMPRESSION),X=w1(K),B=await x1(X,Z,H?.summary,Y);if(!B)return{summary:"",messageCount:V,toolOutputCount:G};let j=Date.now(),z=M$(Q),F={tokensBefore:z,tokensAfter:z,clearedToolOutputs:0,removedMessages:K.length,summaryGenerated:!0,timestamp:j},O={lastStats:F,history:[...H?.history??[],F],summary:B,updatedAt:j};return await J.save(W,n.COMPRESSION,O),{summary:B,messageCount:V,toolOutputCount:G}}function U2($){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 F2($,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 _2=["planMode","planModeMiddleware","parallelMode","parallelSubagentMiddleware","blockedTools","commitProcessed","_pendingUserInput"];function O0($){let W={};for(let[Q,Z]of Object.entries($))if(!_2.includes(Q))W[Q]=Z;return W}function f1($){return{...$,metadata:O0($.metadata)}}var O2=1;function q0($,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((V)=>V.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:O2,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:O0($.metadata),savedAt:Date.now()}}function Z0($){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 m0{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 M2}from"node:events";class O$ extends Error{constructor($="Agent execution aborted"){super($);this.name="AgentAbortError"}}class u0 extends Error{iterations;constructor($,W){super(W??`Agent exceeded maximum iterations (${$})`);this.name="AgentMaxIterationsError",this.iterations=$}}class T$ extends Error{constructor($="Agent execution paused"){super($);this.name="AgentPauseError"}}function j$($,W){if(!$?.aborted)return;let Q=$?.reason;if(Q instanceof Error)throw Q;throw new O$(typeof Q==="string"?Q:W?`${W} aborted`:"Agent execution aborted")}function N0($){return(W,Q)=>{let Z=-1,J=async(Y,V)=>{if(Y<=Z)throw Error("next() called multiple times");if(Z=Y,Y===$.length)return Q?await Q(V):V;let G=$[Y];return G(V,(K)=>J(Y+1,K))};return J(0,W)}}function A0($,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:{}}}async function*v1($,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 V=Y.item.call_id;Q.set(V,{toolId:Y.item.name,argsText:""}),Z.set(Y.output_index,V)}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,V=Z.get(Y.output_index);if(V){let G=Q.get(V);if(G)G.argsText+=Y.delta,yield{type:"delta",requestId:W,chunk:{kind:"tool_call_delta",callId:V,toolId:G.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 V=Y.item.call_id;if(Q.get(V))yield{type:"delta",requestId:W,chunk:{kind:"tool_call_delta",callId:V,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,V=Y.response.incomplete_details?.reason,G="error";if(V==="max_tokens"||V==="max_output_tokens")G="length";else if(V==="tool_calls"||V==="function_call")G="tool_call";else if(V==="stop"||V==="end_turn")G="final";yield{type:"response_end",requestId:W,stopReason:G,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}}}class x 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 q${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",V)}function V(){Y(),Z(Error("Aborted"))}if(W){if(W.aborted)return V();W.addEventListener("abort",V)}})}}function k$($="req"){let W=Math.random().toString(16).slice(2),Q=Date.now().toString(16);return`${$}_${Q}_${W}`}function p0($){try{let W=$.split(".");if(W.length!==3)throw new x("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 x("ChatGPT account ID not found in token",{code:"account_id_not_found",retryable:!1});return Y}catch(W){if(W instanceof x)throw W;throw new x("Failed to extract account ID from token",{code:"token_decode_error",retryable:!1})}}function q2($){let W=($.baseUrl||"https://chatgpt.com/backend-api").replace(/\/$/,"");async function Q(){let G=typeof $.accessToken==="function"?await $.accessToken():$.accessToken;if(!G||typeof G!=="string"||!G.trim())throw new x("Missing Codex access token",{code:"missing_access_token",retryable:!1});return G.trim()}async function Z(){if($.accountId){let G=typeof $.accountId==="function"?await $.accountId():$.accountId;if(!G||typeof G!=="string"||!G.trim())throw new x("Invalid ChatGPT account ID",{code:"invalid_account_id",retryable:!1});return G.trim()}try{let G=await Q();return p0(G)}catch(G){if(G instanceof x)throw G;throw new x("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(G){let K=[];for(let H of G)if(H.role==="system")K.push({role:"developer",content:[{type:"input_text",text:typeof H.content==="string"?H.content:JSON.stringify(H.content)}]});else if(H.role==="user")K.push({role:"user",content:[{type:"input_text",text:typeof H.content==="string"?H.content:JSON.stringify(H.content)}]});else if(H.role==="assistant"){if(K.push({role:"assistant",content:[{type:"output_text",text:typeof H.content==="string"?H.content:JSON.stringify(H.content)}]}),H.tool_calls&&H.tool_calls.length>0)for(let X of H.tool_calls)K.push({type:"function_call",call_id:X.id,name:X.function.name,arguments:typeof X.function.arguments==="string"?X.function.arguments:JSON.stringify(X.function.arguments)})}else if(H.role==="tool")K.push({type:"function_call_output",call_id:H.tool_call_id,output:typeof H.content==="string"?H.content:JSON.stringify(H.content)});return K}async function*V(G){let{request:K}=G,H=K.requestId||k$("req");try{let X=[];if(K.instructions)X.push({role:"developer",content:[{type:"input_text",text:K.instructions}]});if(K.messages&&K.messages.length>0)X.push(...Y(K.messages));else if(K.input)X.push({role:"user",content:[{type:"input_text",text:K.input}]});let[B,j,z]=await Promise.all([Q(),Z(),J()]),F=A2(K.model.modelId),O={model:F,input:X,stream:!0,store:!1,instructions:z},R=K.reasoning?.effort||R2(F);if(O.reasoning={effort:R,summary:K.reasoning?.summary||"auto"},O.text={verbosity:"medium"},O.include=["reasoning.encrypted_content"],K.metadata)O.metadata=K.metadata;let _=K.metadata?.promptCacheKey;if(_)O.prompt_cache_key=_;if(K.tools&&K.tools.length>0)O.tools=K.tools.map((E)=>({type:"function",name:E.function.name,description:E.function.description,parameters:E.function.parameters}));let U={"Content-Type":"application/json",Authorization:`Bearer ${B}`,"chatgpt-account-id":j,"OpenAI-Beta":"responses=experimental",originator:"codex_cli_rs",accept:"text/event-stream"};if(_)U.conversation_id=_,U.session_id=_;let N=await fetch(`${W}/codex/responses`,{method:"POST",headers:U,body:JSON.stringify(O),signal:K.signal});if(!N.ok){let E=await N.text().catch(()=>"");throw new x(`Codex API error: ${N.status} ${E}`,{code:`codex_http_${N.status}`,retryable:q$.isRetryableStatus(N.status),status:N.status})}if(!N.body)throw new x("No response body",{code:"no_response_body",retryable:!1});let A=N2(N.body);yield*v1(A,H)}catch(X){if(X?.name==="AbortError")throw new x("Request aborted",{code:"aborted",retryable:!1});if(X instanceof x)throw X;throw new x(X?.message||"Unknown error",{code:X?.code||"unknown_error",retryable:!1})}}return{provider:"codex",defaultModelId:$.defaultModelId,stream:V}}async function*N2($){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 V=Z.split(`
|
|
36
|
-
`);Z=V.pop()||"";for(let G of V)if(G.startsWith("data: ")){let K=G.slice(6);if(K==="[DONE]")return;try{yield JSON.parse(K)}catch(H){continue}}}}finally{W.releaseLock()}}function A2($){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 R2($){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 P${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 P$;static aggressive=new P$({maxAttempts:5,baseDelayMs:1000,maxDelayMs:60000});static gentle=new P$({maxAttempts:3,baseDelayMs:2000,maxDelayMs:30000,jitter:"full"})}function R0($){let W=$.adapter;if(!W)throw new x("Missing adapter. Provide `adapter` option.",{code:"missing_adapter",retryable:!1});if(!W.defaultModelId)throw new x("Adapter must have a defaultModelId.",{code:"missing_model_id",retryable:!1});let Q={provider:W.provider,modelId:W.defaultModelId},Z=new P$({maxAttempts:$.retry?.maxAttempts??3,baseDelayMs:$.retry?.baseDelayMs??500,maxDelayMs:$.retry?.maxDelayMs??30000,strategy:$.retry?.strategy??"exponential",jitter:$.retry?.jitter??"equal"}),J=$.timeoutMs??60000;async function*Y(G){let K=G.requestId||k$("req"),{model:H,...X}=G,B=G.model??Q,j=G.timeoutMs??J,z=!1,F=0,O=new AbortController,R=G.signal,_=setTimeout(()=>O.abort(),j),U=()=>O.abort();if(R)if(R.aborted)O.abort();else R.addEventListener("abort",U);let N={...X,requestId:K,model:B,stream:G.stream??!0,signal:O.signal,timeoutMs:j};try{for(let A=1;A<=Z.maxAttempts;A++){F=A;try{for await(let E of W.stream({request:N})){if(E.type==="delta")z=!0;yield E}return}catch(E){let q=y1(E),S=q.retryable;if(z||!S||!Z.canRetry(A))throw q;let b=Z.getDelay(A);$.retry?.onRetry?.({attempt:A,maxAttempts:Z.maxAttempts,delayMs:b,error:{code:q.code,message:q.message,retryable:q.retryable},model:B,request:N}),await q$.sleep(b,O.signal)}}}catch(A){let E=y1(A);throw yield{type:"error",requestId:K,terminal:!0,model:B,attempt:F||1,source:"client",error:{code:E.code,message:E.message,retryable:E.retryable}},E}finally{if(clearTimeout(_),R)R.removeEventListener("abort",U)}throw new x("Max retry attempts exceeded",{code:"max_retries_exceeded",retryable:!1})}async function V(G){let K="",H="",X="error",B,j,z=G.requestId||"",F=!1;for await(let O of Y({...G,stream:!0}))if(O.type==="response_start")F=!0,z=O.requestId,j=O.model,K="";else if(O.type==="delta"&&O.chunk.kind==="text")K+=O.chunk.text;else if(O.type==="response_end")H=K,X=O.stopReason,B=O.usage;else if(O.type==="error")X="error";if(!j)throw new x("Missing response_start from adapter",{code:"protocol_error",retryable:!1});return{requestId:z,model:j,text:F?H:K,stopReason:X,usage:B}}return{get modelId(){return Q.modelId},get modelRef(){return Q},setModelId(G){Q={provider:Q.provider,modelId:G}},stream:Y,run:V}}function y1($){if($ instanceof x)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?q$.isRetryableStatus(W):!1;return new x(Z,{code:Q,retryable:J,status:W})}return new x(String($||"Unknown error"),{code:"unknown_error",retryable:!1})}import I1 from"openai";function E2($){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 D2($){return{...$,content:E2($.content)}}function L2($,W){if(typeof W==="string"&&/deepseek/i.test(W))return!0;return/^deepseek-/i.test($)}function E0($={}){let W=$.baseUrl;function Q(){if(typeof $.apiKey==="function"){let H=$.apiKey();if(typeof H==="string"){let X=H.trim();if(!X)throw new x("Missing apiKey",{code:"missing_api_key",retryable:!1});return X}if(H!=null)throw new x("Invalid apiKey provider",{code:"invalid_api_key",retryable:!1})}if(typeof $.apiKey==="string"){let H=$.apiKey.trim();if(!H)throw new x("Missing apiKey",{code:"missing_api_key",retryable:!1});return H}let K=typeof process<"u"?process.env?.OPENAI_API_KEY:void 0;if(typeof K!=="string"||!K.trim())throw new x("Missing OPENAI_API_KEY",{code:"missing_api_key",retryable:!1});return K.trim()}function Z(){if(!(typeof globalThis.window<"u"))return!1;let H=typeof process<"u"&&!!process?.versions?.node,X=typeof globalThis.Bun<"u"||typeof process<"u"&&!!process?.versions?.bun;return H||X}function J(){let K=Q(),H=Z();if(typeof W==="string"&&/\/chat\/completions\/?$/.test(W))return new I1({apiKey:K,dangerouslyAllowBrowser:H,organization:$.organization,project:$.project,baseURL:"https://api.openai.com/v1",fetch:(B,j)=>{return fetch(W,j)}});return new I1({apiKey:K,dangerouslyAllowBrowser:H,organization:$.organization,project:$.project,baseURL:W||void 0})}function Y(K){return{provider:"openai",modelId:K.model.modelId}}function V(K){if(K instanceof x)return K;let H=typeof K?.status==="number"?K.status:void 0,X=typeof K?.message==="string"?K.message:"OpenAI error",B=typeof K?.code==="string"?K.code:H?`openai_http_${H}`:"openai_error",j=H?q$.isRetryableStatus(H):!1;return new x(X,{code:B,retryable:j,status:H})}async function*G(K){let{request:H}=K,X=H.requestId||k$("req"),B=J(),j=H.model.modelId,z=$.compat?.interleavedThinking,F=typeof z==="boolean"?z:L2(j,W),O=H.stream!==!1,R=[];if(H.messages&&Array.isArray(H.messages)){let N=-1;for(let A=H.messages.length-1;A>=0;A--)if(H.messages[A].role==="user"){N=A;break}for(let A=0;A<H.messages.length;A++){let E=H.messages[A],q=D2(E),S=A<N;if(q&&typeof q==="object"&&q.role==="assistant"){if(S){if("reasoning_content"in q)delete q.reasoning_content}else if(!F){if("reasoning_content"in q)delete q.reasoning_content}else if(Array.isArray(q?.tool_calls)&&q.tool_calls.length>0){let b=q.reasoning_content;if(typeof b!=="string"||b.length===0)q.reasoning_content="."}}R.push(q)}}else{if(typeof H.instructions==="string"&&H.instructions.length>0)R.push({role:"system",content:H.instructions});R.push({role:"user",content:H.input})}let _=(()=>{let N=H.reasoning?.effort;if(typeof N!=="string")return;if(N==="none"||N==="minimal"||N==="low"||N==="medium"||N==="high"||N==="xhigh")return N;return})(),U={model:j,messages:R,stream:O,stream_options:O?{include_usage:!0}:void 0,metadata:H.metadata??void 0,reasoning_effort:_,max_completion_tokens:H.maxOutputTokens??void 0,stop:H.stop??void 0,temperature:H.temperature??void 0,top_p:H.topP??void 0};if(H.tools&&Array.isArray(H.tools)&&H.tools.length>0)U.tools=H.tools;try{let N=Y(H);if(yield{type:"response_start",requestId:X,model:N},!O){let L=await B.chat.completions.create({...U,stream:!1},{signal:H.signal,timeout:H.timeoutMs}),C=Array.isArray(L?.choices)?L.choices[0]:void 0,k=C?.message,i=typeof k?.reasoning_content==="string"?k.reasoning_content:"";if(i.length>0)yield{type:"delta",requestId:X,chunk:{kind:"thinking_start"}},yield{type:"delta",requestId:X,chunk:{kind:"thinking_delta",text:i}},yield{type:"delta",requestId:X,chunk:{kind:"thinking_end",text:i}};let c=typeof k?.content==="string"?k.content:"";if(c.length>0)yield{type:"delta",requestId:X,chunk:{kind:"text",text:c}};let r=Array.isArray(k?.tool_calls)?k.tool_calls:[];for(let w=0;w<r.length;w++){let D=r[w],T=typeof D?.id==="string"?D.id:`call_${w}`,f=typeof D?.function?.name==="string"?D.function.name:void 0,P=typeof D?.function?.arguments==="string"?D.function.arguments:void 0;if(P||f)yield{type:"delta",requestId:X,chunk:{kind:"tool_call_delta",callId:T,toolId:f,argsTextDelta:P}}}let H$=k1(C?.finish_reason);yield{type:"response_end",requestId:X,stopReason:H$,usage:L?.usage};return}let A=await B.chat.completions.create({...U,stream:!0},{signal:H.signal,timeout:H.timeoutMs}),E=null,q,S=new Map,b=!1,I="";for await(let L of A){if(L?.usage!=null)q=L.usage;let C=Array.isArray(L?.choices)?L.choices:[];for(let k of C){if(k?.finish_reason!=null)E=k.finish_reason;let i=k?.delta,c=i?.reasoning_content;if(typeof c==="string"&&c.length>0){if(!b)b=!0,yield{type:"delta",requestId:X,chunk:{kind:"thinking_start"}};I+=c,yield{type:"delta",requestId:X,chunk:{kind:"thinking_delta",text:c}}}let r=i?.content;if(typeof r==="string"&&r.length>0){if(b)b=!1,yield{type:"delta",requestId:X,chunk:{kind:"thinking_end",text:I||void 0}};yield{type:"delta",requestId:X,chunk:{kind:"text",text:r}}}let H$=Array.isArray(i?.tool_calls)?i.tool_calls:[];for(let w of H$){let D=typeof w?.index==="number"?w.index:0,f=S.get(D)||(typeof w?.id==="string"?w.id:`call_${D}`);S.set(D,f);let P=typeof w?.function?.name==="string"?w.function.name:void 0,d=typeof w?.function?.arguments==="string"?w.function.arguments:void 0;if(P||d)yield{type:"delta",requestId:X,chunk:{kind:"tool_call_delta",callId:f,toolId:P,argsTextDelta:d}}}}}if(b)yield{type:"delta",requestId:X,chunk:{kind:"thinking_end",text:I||void 0}};yield{type:"response_end",requestId:X,stopReason:k1(E),usage:q}}catch(N){if(N?.name==="AbortError")throw new x("Aborted",{code:"aborted",retryable:!1});throw V(N)}}return{provider:"openai",defaultModelId:$.defaultModelId,stream:G}}function k1($){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 D0{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 c0{tools;options;eventQueue=new D0;constructor($,W){this.tools=$;this.options=W}async*executeTasksInParallel($,W,Q){this.eventQueue=new D0;let Z=!1,J=$.map(async(G)=>{let K=G.toolCall.function.name,H=this.tools?.get(K);if(!H)return{tc:G,result:`Tool "${K}" not found`,isError:!0};try{let X=typeof G.toolCall.function.arguments==="string"?JSON.parse(G.toolCall.function.arguments):G.toolCall.function.arguments,B=`${W.sessionId}:subagent:${crypto.randomUUID()}`,j={...Q,sessionId:B,emitEvent:(F)=>{this.eventQueue.enqueue({...F,sessionId:W.sessionId})}},z=await H.execute(X,j);return{tc:G,result:z,isError:!1}}catch(X){return{tc:G,result:`Task execution failed: ${X instanceof Error?X.message:String(X)}`,isError:!0}}}),Y=Promise.allSettled(J).then((G)=>{return Z=!0,G});while(!Z||!this.eventQueue.isEmpty()){let G=await this.eventQueue.dequeueOrWait(5);if(G)yield G}let V=await Y;for(let[G,K]of V.entries()){let H=$[G];if(K.status==="fulfilled"){let{result:X,isError:B}=K.value;H.result=X,H.isError=B}else H.result=`Task execution rejected: ${K.reason}`,H.isError=!0;if(!this.options.hasAssistantToolCallMessage(W,H.toolCall.id))this.options.addAssistantMessageWithToolCalls(W);yield{type:"tool_result",tool_call_id:H.toolCall.id,result:H.result,isError:H.isError,sessionId:W.sessionId},this.options.addToolResultToHistory(W,H)}}}class b${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 d0{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){j$(Q,`Tool execution: ${$.toolCall.function.name}`);let Y=Z?new b$(Z):void 0,V=$.toolCall.id,G=$.toolCall,K=G,H=(z)=>({sessionId:W.sessionId,toolCall:z,toolContext:W});if(J){if(!J.allow)return $.result="Tool execution blocked by PreToolUse hook",$.isError=!0,{type:"tool_result",tool_call_id:V,result:$.result,isError:!0,sessionId:W.sessionId};if(J.modifiedToolCall)K={...J.modifiedToolCall,id:V,type:G.type}}else if(Y){let z=await Y.executePreToolUse(H(K));if(!z.allow)return $.result="Tool execution blocked by PreToolUse hook",$.isError=!0,{type:"tool_result",tool_call_id:V,result:$.result,isError:!0,sessionId:W.sessionId};if(z.modifiedToolCall)K={...z.modifiedToolCall,id:V,type:G.type}}let X=this.options.tools?.get(K.function.name);if(!X)return this._log(`Tool NOT FOUND: ${K.function.name}`),$.result=`Tool not found: ${K.function.name}`,$.isError=!0,{type:"tool_result",tool_call_id:V,result:$.result,isError:!0,sessionId:W.sessionId};let B;try{B=typeof K.function.arguments==="string"?K.function.arguments.trim()===""?{}:JSON.parse(K.function.arguments):K.function.arguments??{}}catch(z){this._log(`Warning: Failed to parse tool arguments for ${K.function.name}, using empty object`),B={}}let j={...W,toolCallId:V,toolName:K.function.name};try{if($.result=await X.execute(B,j),$.isError=!1,Y)await Y.executePostToolUse(H(K),$.result);return{type:"tool_result",tool_call_id:V,result:$.result,sessionId:W.sessionId}}catch(z){let F=z instanceof Error?z:Error(String(z));if(this._log(`Tool execution threw ERROR: ${K.function.name} - ${F.message}`),$.result=F.message,$.isError=!0,Y)await Y.executePostToolUseFailure(H(K),F);return{type:"tool_result",tool_call_id:V,result:$.result,isError:!0,sessionId:W.sessionId}}}async*handleToolCalls($,W,Q){let Z=$.pendingToolCalls.length,J=Q?.signal,Y=Q?.toolContextInput,V=Y?.approval,G=V?.decisions??{},K=(_)=>{return this.options.approvalHandler.shouldRequireApproval(V,_)},H=(_)=>{return $.messages.some((U)=>{if(!U||typeof U!=="object"||U.role!=="assistant")return!1;let N=U.tool_calls;return Array.isArray(N)&&N.some((A)=>A?.id===_)})},X=(_)=>{if(!H(_))this.options.addAssistantMessageWithToolCalls($)},B=(_)=>{return $.messages.some((U)=>U&&typeof U==="object"&&U.role==="tool"&&U.tool_call_id===_)},j=new Set,z=(_)=>{try{return typeof _.function.arguments==="string"?JSON.parse(_.function.arguments):_.function.arguments}catch(U){let N=U instanceof Error?U.message:String(U);return{_raw:_.function.arguments,_parseError:N}}},F=(_)=>{let U=[];for(let N=_;N<$.pendingToolCalls.length;N++){let A=$.pendingToolCalls[N];if(B(A.toolCall.id))continue;if(j.has(A.toolCall.id))continue;if(G[A.toolCall.id])continue;let E=this.options.tools?.get(A.toolCall.function.name),q=E?.riskLevel??"safe";if(E&&this.options.isToolDisabled(A.toolCall.function.name))continue;if(E&&this.options.isToolBlocked($,A.toolCall.function.name))continue;if(!E||!K(q))continue;j.add(A.toolCall.id),U.push({type:"tool_approval_requested",tool_call_id:A.toolCall.id,toolName:A.toolCall.function.name,riskLevel:q,args:z(A.toolCall),sessionId:$.sessionId})}return U};if($.metadata?.parallelMode===!0){let _=$.pendingToolCalls.filter((U)=>{let N=U.toolCall.function.name;return N==="Task"||N.endsWith("_Task")});if(_.length>1)yield*this.options.parallelTaskExecutor.executeTasksInParallel(_,$,W),$.pendingToolCalls=$.pendingToolCalls.filter((U)=>!_.includes(U))}let R=this.options.checkpointManager.hasStore();for(let _=0;_<$.pendingToolCalls.length;_++){let U=$.pendingToolCalls[_];if(B(U.toolCall.id)){$.pendingToolCalls.splice(_,1),_--;continue}let N=U.toolCall.function.name,A;if(Q?.hooks?.preToolUse){let L=new b$(Q.hooks),C=(k)=>({sessionId:$.sessionId,toolCall:k,toolContext:W});if(A=await L.executePreToolUse(C(U.toolCall)),!A.allow){this._log(`Tool BLOCKED by preToolUse hook: ${N}`),U.result="Tool execution blocked by PreToolUse hook",U.isError=!0,X(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(_,1),_--,await this.options.saveCheckpoint($,{phase:"tool_execution",status:`Tool blocked by preToolUse hook: ${N}`,modelConfig:Q?.checkpointModelConfig,requestParams:Q?.requestParams});continue}}if(A?.modifiedToolCall)U.toolCall={...A.modifiedToolCall,id:U.toolCall.id,type:U.toolCall.type};let E=U.toolCall.function.name,q=this.options.tools?.get(E),S=q?.riskLevel??"safe";if(q&&this.options.isToolBlocked($,E)){let L=`Tool "${E}" is blocked by middleware`;this._log(`Tool BLOCKED: ${E} - ${L}`),U.result=`Tool execution skipped: ${L}`,U.isError=!0,X(U.toolCall.id),yield{type:"tool_skipped",tool_call_id:U.toolCall.id,toolName:E,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(_,1),_--,await this.options.saveCheckpoint($,{phase:"tool_execution",status:`Tool blocked: ${E}`,modelConfig:Q?.checkpointModelConfig,requestParams:Q?.requestParams});continue}if(q&&this.options.isToolDisabled(E)){let L=`Tool "${E}" is disabled for this session`;this._log(`Tool DISABLED: ${E}`),U.result=`Tool execution skipped: ${L}`,U.isError=!0,X(U.toolCall.id),yield{type:"tool_skipped",tool_call_id:U.toolCall.id,toolName:E,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(_,1),_--,await this.options.saveCheckpoint($,{phase:"tool_execution",status:`Tool disabled: ${E}`,modelConfig:Q?.checkpointModelConfig,requestParams:Q?.requestParams});continue}if(q&&K(S)){let L=G[U.toolCall.id];if(!L){this._log(`Tool approval required: ${E} (risk: ${S})`),$.stopReason="approval_required";for(let k of F(_)){if(k.type==="tool_approval_requested")this._log(` - Requesting approval for: ${k.toolName}`);yield k}let C=await this.options.saveCheckpoint($,{phase:"approval_pending",status:`Waiting for approval: ${E}`,modelConfig:Q?.checkpointModelConfig,requestParams:Q?.requestParams});throw yield{type:"requires_action",kind:"tool_approval",checkpoint:R?void 0:C,checkpointRef:R?{sessionId:C.sessionId}:void 0,sessionId:$.sessionId},await this.options.persistSessionState($),yield{type:"done",finalResponse:$.currentResponse,stopReason:"approval_required",modelStopReason:$.lastModelStopReason,usage:{...$.usage},sessionId:$.sessionId},new T$}if(!L.approved){let C=L.reason??"User denied approval";this._log(`Tool approval REJECTED: ${E} - ${C}`),U.result=`Tool execution skipped: ${C}`,U.isError=!0,X(U.toolCall.id),yield{type:"tool_skipped",tool_call_id:U.toolCall.id,toolName:U.toolCall.function.name,reason:C,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(_,1),_--,await this.options.saveCheckpoint($,{phase:"tool_execution",status:`Tool approval rejected: ${E}`,modelConfig:Q?.checkpointModelConfig,requestParams:Q?.requestParams});continue}this._log(`Tool approval APPROVED: ${E}`)}X(U.toolCall.id),this._log(`Executing tool: ${E}`),this.toolEventQueue=[];let b=await this.executeToolCall(U,W,J,Q?.hooks,A);for(let L of this.toolEventQueue)yield L;if(this.toolEventQueue=[],b.type==="tool_result")if(b.isError||b.result&&typeof b.result==="object"&&b.result.isError===!0){let C=typeof b.result==="string"?b.result:JSON.stringify(b.result);this._log(`Tool execution ERROR: ${E} - ${C.slice(0,100)}`)}else{let C=typeof b.result==="string"?b.result.slice(0,100):JSON.stringify(b.result).slice(0,100);this._log(`Tool execution SUCCESS: ${E} - ${C}${C.length>=100?"...":""}`)}let I=b.type==="tool_result"&&(b.isError||b.result&&typeof b.result==="object"&&b.result.isError===!0);if(q&&q.name==="AskUserQuestion"&&I){let L=Y?.askUser?.rejected?.[U.toolCall.id];if(L!==void 0){let k=L||"User cancelled the question";this._log(`AskUser CANCELLED: ${k}`),U.result=`User cancelled the question: ${k}`,U.isError=!0,X(U.toolCall.id),yield{type:"tool_skipped",tool_call_id:U.toolCall.id,toolName:q.name,reason:k,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(_,1),_--,await this.options.saveCheckpoint($,{phase:"tool_execution",status:`AskUser cancelled: ${q.name}`,modelConfig:Q?.checkpointModelConfig,requestParams:Q?.requestParams});continue}let C=Y?.askUser?.answers?.[U.toolCall.id];if(!C){let i=(typeof U.toolCall.function.arguments==="string"?JSON.parse(U.toolCall.function.arguments):U.toolCall.function.arguments)?.questions||[];this._log(`AskUser waiting for answers (${i.length} questions)`),yield b,$.stopReason="approval_required";let c=await this.options.saveCheckpoint($,{phase:"approval_pending",status:`Waiting for user answers: ${q.name}`,modelConfig:Q?.checkpointModelConfig,requestParams:Q?.requestParams});throw await this.options.persistSessionState($),yield{type:"requires_action",kind:"ask_user",toolCallId:U.toolCall.id,questions:i,checkpoint:R?void 0:c,checkpointRef:R?{sessionId:c.sessionId}:void 0,sessionId:$.sessionId},yield{type:"done",finalResponse:$.currentResponse,stopReason:"approval_required",modelStopReason:$.lastModelStopReason,usage:{...$.usage},sessionId:$.sessionId},new T$}else{let i={...typeof U.toolCall.function.arguments==="string"?JSON.parse(U.toolCall.function.arguments):U.toolCall.function.arguments,answers:C};U.toolCall.function.arguments=JSON.stringify(i),this.toolEventQueue=[];let c=await this.executeToolCall(U,W,J,Q?.hooks,A);for(let r of this.toolEventQueue)yield r;this.toolEventQueue=[],yield c,this.options.addToolResultToHistory($,U),$.pendingToolCalls.splice(_,1),_--,await this.options.saveCheckpoint($,{phase:"tool_execution",status:U.isError?`AskUser error: ${q.name}`:`AskUser completed: ${q.name}`,modelConfig:Q?.checkpointModelConfig,requestParams:Q?.requestParams});continue}}yield b,this.options.addToolResultToHistory($,U),$.pendingToolCalls.splice(_,1),_--,await this.options.saveCheckpoint($,{phase:"tool_execution",status:U.isError?`Tool error: ${E}`:`Tool completed: ${E}`,modelConfig:Q?.checkpointModelConfig,requestParams:Q?.requestParams})}$.pendingToolCalls=[],$.iteration++,yield{type:"iteration_end",iteration:$.iteration-1,willContinue:!0,toolCallCount:Z,usage:{...$.usage},sessionId:$.sessionId}}}class L0{static APPROVAL_REQUIRED_LEVELS=new Set(["high","critical"]);requiresApproval($){return L0.APPROVAL_REQUIRED_LEVELS.has($)}shouldRequireApproval($,W){if($?.autoApprove===!0)return!1;if(($?.strategy??"high_risk")==="all")return!0;return this.requiresApproval(W)}}class l0{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 T2=1000;function P2($){if(!$)return;if($ instanceof x)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 g1($){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 h1($){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,V=J.map((G)=>{let K=g1(G);if(K!==G)Y=!0;return K});if(!Y)return Z;return W=!0,{...Z,tool_calls:V}});return W?Q:$}class e extends M2{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;_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 m0($),this._approvalHandler=new L0,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 l0(()=>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._maxIterations=Z?.maxIterations,this._requestParams=Z?.requestParams,this._emitSessionCreatedEvent=Z?.emitSessionCreatedEvent===!0,this._enableLogging=Z?.enableLogging??!1,this._parallelTaskExecutor=new c0(this._tools,{hasAssistantToolCallMessage:(J,Y)=>this.hasAssistantToolCallMessage(J,Y),addAssistantMessageWithToolCalls:(J)=>this.addAssistantMessageWithToolCalls(J),addToolResultToHistory:(J,Y)=>this.addToolResultToHistory(J,Y)}),this._toolExecutor=new d0({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 V=Z0(W);if(V.sessionId!==this.id)V.sessionId=this.id;V.shouldContinue=!0,V.stopReason=void 0,V.metadata={...V.metadata,_pendingUserInput:J};let G=this._requestParams??W.requestParams,K=Y??$,H=this.buildAutoRejectToolContext(V,K?.toolContext);if(!(yield*this._streamWithPauseDetection(V,{maxIterations:this._maxIterations,signal:Z,model:this.getRuntimeModelOverride(),toolContext:H,hooks:this._hooks,requestParams:G})))await this._finalizeRun(V,Date.now());return}if(Q){this._log("Resuming from checkpoint without new message");let J=Z0(W);if(J.sessionId!==this.id)J.sessionId=this.id;let Y=this._requestParams??W.requestParams,V=this.buildAutoRejectToolContext(J,$?.toolContext);if(!(yield*this._streamWithPauseDetection(J,{maxIterations:this._maxIterations,signal:Z,model:this.getRuntimeModelOverride(),toolContext:V,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 O$){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(),Z=this.getRuntimeModelOverride(),J=this._abortController?.signal;if(!this.title&&this.messages.length===0){let K=this.extractTextFromContent($);if(K)this.title=this.createTitle(K)}let Y=this.messages.filter((K)=>K.role!=="system");this._log(`Starting agent loop with ${Y.length} existing messages`);let V=A0({sessionId:this.id,input:$,messages:Y},this.getEffectiveSystemPrompt()??"");if(!(yield*this._streamWithPauseDetection(V,{maxIterations:this._maxIterations,signal:J,model:Z,toolContext:W?.toolContext,hooks:this._hooks,requestParams:this._requestParams})))await this._finalizeRun(V,Q)}async*_streamWithPauseDetection($,W){try{return yield*this._streamWithState($,W),!1}catch(Q){if(Q instanceof T$)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,V=J.toolCall.function.name;if(!W?.approval?.decisions?.[Y])Q[Y]={approved:!1,reason:"Auto-rejected: session resumed without tool context"};if(V==="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}}}}getRuntimeModelOverride(){if(this.configOverride?.model){let $=this.resolveModelRef(this.configOverride.model);if($)return $}return this._modelOverride}_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){if(!this._modelClient)throw Error("Session is not configured with a model client");let Y=[],V=$.sessionId,G=new Map,K=!1,H=!1,X=(U)=>{let N=G.get(U);if(N)return N;let A={argsText:"",started:!1};return G.set(U,A),A},B=(U,N)=>{let A=X(U);if(N&&!A.toolName)A.toolName=N;if(!A.started)A.started=!0,this._log(`Stream: tool_call_start - ${A.toolName} (${U.slice(0,8)})`),Y.push({type:"tool_call_start",callId:U,toolName:A.toolName,sessionId:V})},j=(U,N,A)=>{let E=X(U);if(N&&!E.toolName)E.toolName=N;if(typeof A==="string"&&A.length>0)E.argsText+=A;B(U,E.toolName),Y.push({type:"tool_call_delta",callId:U,toolName:E.toolName,argsTextDelta:A,sessionId:V})},z=()=>{if(K)return;K=!0,this._log("Stream: text_start"),Y.push({type:"text_start",sessionId:V})},F=()=>{if(!K||H)return;H=!0;let U=$.currentResponse.slice(0,50)+($.currentResponse.length>50?"...":"");this._log(`Stream: text_end - "${U}"`),Y.push({type:"text_end",content:$.currentResponse,sessionId:V})},O=()=>{for(let[U,N]of G){if(!N.toolName)continue;let A={id:U,type:"function",function:{name:N.toolName,arguments:N.argsText}};if(this._tools){$.pendingToolCalls.push({toolCall:A});let E=N.argsText.slice(0,100)+(N.argsText.length>100?"...":"");this._log(`Stream: tool_call_end - ${N.toolName} with args: ${E}`)}Y.push({type:"tool_call_end",toolCall:A,sessionId:V})}G.clear()},R=(()=>{if(!J)return;let U={...J};if(typeof U.maxOutputTokens!=="number"&&typeof J.maxTokens==="number")U.maxOutputTokens=J.maxTokens;return delete U.maxTokens,U})(),_=Z?{model:Z,messages:h1($.messages),tools:Q,signal:W,...R??{}}:{messages:h1($.messages),tools:Q,signal:W,...R??{}};try{for await(let U of this._modelClient.stream(_))if(j$(W,"Session streaming"),U.type==="delta"){if(U.chunk.kind==="text")z(),$.currentResponse+=U.chunk.text,Y.push({type:"text_delta",delta:U.chunk.text,sessionId:V});else if(U.chunk.kind==="thinking_start")this._log("Stream: thinking_start"),Y.push({type:"thinking_start",sessionId:V});else if(U.chunk.kind==="thinking_delta")$.currentThinking=($.currentThinking??"")+U.chunk.text,Y.push({type:"thinking_delta",delta:U.chunk.text,sessionId:V});else if(U.chunk.kind==="thinking_end"){let N=typeof U.chunk.text==="string"?U.chunk.text:"";if(N&&typeof $.currentThinking!=="string")$.currentThinking=N;let A=typeof $.currentThinking==="string"?$.currentThinking:N,E=A?A.slice(0,50)+(A.length>50?"...":""):"";this._log(`Stream: thinking_end - "${E}"`),Y.push({type:"thinking_end",sessionId:V,...A?{content:A}:{}})}else if(U.chunk.kind==="tool_call_delta")j(U.chunk.callId,U.chunk.toolId,U.chunk.argsTextDelta)}else if(U.type==="response_end"){this._log(`Stream: response_end - stopReason: ${U.stopReason}`),F(),O(),$.lastModelStopReason=U.stopReason;let N=U.usage;if(N&&typeof N==="object"){let A=N;if(A.prompt_tokens||A.completion_tokens||A.total_tokens){let E={promptTokens:A.prompt_tokens??0,completionTokens:A.completion_tokens??0,totalTokens:A.total_tokens??0};$.usage.promptTokens=E.promptTokens,$.usage.completionTokens=E.completionTokens,$.usage.totalTokens+=E.totalTokens,this._recordUsage(E)}}}else if(U.type==="error"){if(U.terminal!==!1){let N=U.error?.code??"model_error",A=U.error?.message??"Model error",E=new x(A,{code:N,retryable:U.error?.retryable});$.error=E,$.shouldContinue=!1,$.stopReason="error"}}}catch(U){if(U instanceof O$)throw U;if(W?.aborted)throw new O$(typeof W?.reason==="string"?W.reason:"Agent execution aborted");$.error=U instanceof Error?U:Error(String(U)),$.shouldContinue=!1,$.stopReason="error"}finally{if(F(),G.size>0)O()}return Y}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=q0($,{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)=>g1(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??T2,Z=W.signal,J=N0(this._middlewares),Y=this._toolExecutor.createToolExecutionContext($,Z),V=this._stateStore,G=V?.deleteOnComplete??!0,K=W.model?{modelId:W.model.modelId,provider:W.model.provider}:this._modelClient?{modelId:this._modelClient.modelId}:void 0,H=async(X)=>{if(!V)return;await this.saveCheckpointForState($,{phase:X?.phase,status:X?.status,modelConfig:K,requestParams:W.requestParams})};while($.shouldContinue){if(j$(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:K,requestParams:W.requestParams}),$.metadata?._pendingUserInput){let j=$.metadata._pendingUserInput;delete $.metadata._pendingUserInput,this.appendMessage($,{role:"user",content:j})}continue}if($.metadata?._pendingUserInput){let j=$.metadata._pendingUserInput;delete $.metadata._pendingUserInput,this.appendMessage($,{role:"user",content:j})}$.currentResponse="",$.currentThinking=void 0,$.pendingToolCalls=[],$.lastModelStopReason=void 0,await H();let X=[],B=await J({...$,messages:structuredClone($.messages)},async(j)=>{j$(Z,"Session model call");let z=this.collectBlockedTools(j);j.metadata.blockedTools=z;let F=this.getToolsForModel(j),O=F?.length??0;return this._log(`Calling model with ${j.messages.length} messages and ${O} tools`),X=await this.executeModelStream(j,Z,F,W.model,W.requestParams),this._log(`Model response: ${j.currentResponse.slice(0,100)}${j.currentResponse.length>100?"...":""}, tool calls: ${j.pendingToolCalls.length}`),j});this.mergeStateResults($,B);for(let j of X)yield j;if(j$(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:P2($.error),usage:{...$.usage},sessionId:$.sessionId};break}if($.pendingToolCalls.length>0)yield*this._toolExecutor.handleToolCalls($,Y,{signal:Z,toolContextInput:W.toolContext,hooks:W.hooks,checkpointModelConfig:K,requestParams:W.requestParams});else yield*this.handleFinalResponse($);if(await H(),!$.shouldContinue){if(this._log(`Agent loop finished. Stop reason: ${$.stopReason}`),V&&G)await V.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 J0{}import{randomUUID as b2}from"node:crypto";class M0 extends J0{_stateStore;constructor($){super();this._stateStore=$}async create($){let W=$??b2(),Q=Date.now(),Z=(()=>{try{let V=globalThis?.process;return typeof V?.cwd==="function"?String(V.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 N$,mkdirSync as m1,readdirSync as i0,readFileSync as S2,rmSync as r0,writeFileSync as w2}from"node:fs";import w$ from"node:path";class S${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 Y0 extends S${baseDir;constructor($){super($);this.baseDir=w$.resolve($.dir),this.ensureDir(this.baseDir)}async _write($,W){let Q=this.toFilePath($);this.ensureDir(w$.dirname(Q)),w2(Q,W,"utf-8")}async _read($){let W=this.toFilePath($);try{if(!N$(W))return;return S2(W,"utf-8")}catch{return}}async _delete($){let W=this.toFilePath($);if(N$(W))r0(W);let Q=w$.dirname(W);if(N$(Q))try{if(i0(Q).length===0)r0(Q,{recursive:!0})}catch{}}async _exists($){let W=this.toFilePath($);return N$(W)}async _list($){let W=[];if(!N$(this.baseDir))return W;let Q=i0(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=w$.join(this.baseDir,Z),Y=this.listJsonFiles(J);for(let V of Y){let G=w$.basename(V,".json"),K=`${Z}/${G}`;if(!$||K.startsWith($))W.push(K)}}return W}toFilePath($){return w$.join(this.baseDir,`${$}.json`)}ensureDir($){if(!N$($))m1($,{recursive:!0})}listJsonFiles($){if(!N$($))return[];return i0($).filter((W)=>W.endsWith(".json")).map((W)=>w$.join($,W))}getBaseDir(){return this.baseDir}clear(){if(N$(this.baseDir))r0(this.baseDir,{recursive:!0}),m1(this.baseDir,{recursive:!0})}}class V0 extends S${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 A${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 V0,this._enableLogging=$.enableLogging??!1,this._sessionManager=new M0(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");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),V=Object.create(Object.getPrototypeOf(J));Object.assign(V,J),Object.defineProperty(V,"name",{value:Y,writable:!1,configurable:!0});try{this._tools.register(V),Z.push(Y)}catch(G){console.warn(`Failed to register tool ${Y}:`,G)}}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{readFile as x2}from"node:fs/promises";import C2 from"node:path";import f2 from"node:process";var v2=["AGENTS.md","CLAUDE.md"],y2="[Project Agent Rules]";async function I2($,W){let Q=[];for(let Z of W)try{let J=C2.resolve($,Z),Y=await x2(J,"utf-8");if(Y.trim())Q.push(Y.trim())}catch{continue}return Q.length>0?Q.join(`
|
|
35
|
+
`}async function g1($){let{sessionId:W,fullMessages:Q,model:Z,stateStore:J,summaryPrompt:Y}=$,V=Q.length,G=Q.filter((E)=>E.role==="tool").length,X=Q.filter((E)=>E.role!=="system");if(X.length===0)return{summary:"",messageCount:V,toolOutputCount:G};let H=await J.load(W,r.COMPRESSION),K=k1(X),B=await h1(K,Z,H?.summary,Y);if(!B)return{summary:"",messageCount:V,toolOutputCount:G};let j=Date.now(),z=T$(Q),O={tokensBefore:z,tokensAfter:z,clearedToolOutputs:0,removedMessages:X.length,summaryGenerated:!0,timestamp:j},F={lastStats:O,history:[...H?.history??[],O],summary:B,updatedAt:j};return await J.save(W,r.COMPRESSION,F),{summary:B,messageCount:V,toolOutputCount:G}}function x2($){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 w2($,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 b2=["planMode","planModeMiddleware","parallelMode","parallelSubagentMiddleware","blockedTools","commitProcessed","_pendingUserInput"];function A0($){let W={};for(let[Q,Z]of Object.entries($))if(!b2.includes(Q))W[Q]=Z;return W}function m1($){return{...$,metadata:A0($.metadata)}}var C2=1;function E0($,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((V)=>V.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:C2,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:A0($.metadata),savedAt:Date.now()}}function V0($){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 l0{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 m2}from"node:events";class F$ extends Error{constructor($="Agent execution aborted"){super($);this.name="AgentAbortError"}}class i0 extends Error{iterations;constructor($,W){super(W??`Agent exceeded maximum iterations (${$})`);this.name="AgentMaxIterationsError",this.iterations=$}}class P$ extends Error{constructor($="Agent execution paused"){super($);this.name="AgentPauseError"}}function z$($,W){if(!$?.aborted)return;let Q=$?.reason;if(Q instanceof Error)throw Q;throw new F$(typeof Q==="string"?Q:W?`${W} aborted`:"Agent execution aborted")}function R0($){return(W,Q)=>{let Z=-1,J=async(Y,V)=>{if(Y<=Z)throw Error("next() called multiple times");if(Z=Y,Y===$.length)return Q?await Q(V):V;let G=$[Y];return G(V,(X)=>J(Y+1,X))};return J(0,W)}}function D0($,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:{}}}async function*u1($,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 V=Y.item.call_id;Q.set(V,{toolId:Y.item.name,argsText:""}),Z.set(Y.output_index,V)}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,V=Z.get(Y.output_index);if(V){let G=Q.get(V);if(G)G.argsText+=Y.delta,yield{type:"delta",requestId:W,chunk:{kind:"tool_call_delta",callId:V,toolId:G.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 V=Y.item.call_id;if(Q.get(V))yield{type:"delta",requestId:W,chunk:{kind:"tool_call_delta",callId:V,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,V=Y.response.incomplete_details?.reason,G="error";if(V==="max_tokens"||V==="max_output_tokens")G="length";else if(V==="tool_calls"||V==="function_call")G="tool_call";else if(V==="stop"||V==="end_turn")G="final";yield{type:"response_end",requestId:W,stopReason:G,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}}}class b 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 q${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",V)}function V(){Y(),Z(Error("Aborted"))}if(W){if(W.aborted)return V();W.addEventListener("abort",V)}})}}function h$($="req"){let W=Math.random().toString(16).slice(2),Q=Date.now().toString(16);return`${$}_${Q}_${W}`}function r0($){try{let W=$.split(".");if(W.length!==3)throw new b("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 b("ChatGPT account ID not found in token",{code:"account_id_not_found",retryable:!1});return Y}catch(W){if(W instanceof b)throw W;throw new b("Failed to extract account ID from token",{code:"token_decode_error",retryable:!1})}}function v2($){let W=($.baseUrl||"https://chatgpt.com/backend-api").replace(/\/$/,"");async function Q(){let G=typeof $.accessToken==="function"?await $.accessToken():$.accessToken;if(!G||typeof G!=="string"||!G.trim())throw new b("Missing Codex access token",{code:"missing_access_token",retryable:!1});return G.trim()}async function Z(){if($.accountId){let G=typeof $.accountId==="function"?await $.accountId():$.accountId;if(!G||typeof G!=="string"||!G.trim())throw new b("Invalid ChatGPT account ID",{code:"invalid_account_id",retryable:!1});return G.trim()}try{let G=await Q();return r0(G)}catch(G){if(G instanceof b)throw G;throw new b("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(G){let X=[];for(let H of G)if(H.role==="system")X.push({role:"developer",content:[{type:"input_text",text:typeof H.content==="string"?H.content:JSON.stringify(H.content)}]});else if(H.role==="user")X.push({role:"user",content:[{type:"input_text",text:typeof H.content==="string"?H.content:JSON.stringify(H.content)}]});else if(H.role==="assistant"){if(X.push({role:"assistant",content:[{type:"output_text",text:typeof H.content==="string"?H.content:JSON.stringify(H.content)}]}),H.tool_calls&&H.tool_calls.length>0)for(let K of H.tool_calls)X.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(H.role==="tool")X.push({type:"function_call_output",call_id:H.tool_call_id,output:typeof H.content==="string"?H.content:JSON.stringify(H.content)});return X}async function*V(G){let{request:X}=G,H=X.requestId||h$("req");try{let K=[];if(X.instructions)K.push({role:"developer",content:[{type:"input_text",text:X.instructions}]});if(X.messages&&X.messages.length>0)K.push(...Y(X.messages));else if(X.input)K.push({role:"user",content:[{type:"input_text",text:X.input}]});let[B,j,z]=await Promise.all([Q(),Z(),J()]),O=y2(X.model.modelId),F={model:O,input:K,stream:!0,store:!1,instructions:z},E=X.reasoning?.effort||I2(O);if(F.reasoning={effort:E,summary:X.reasoning?.summary||"auto"},F.text={verbosity:"medium"},F.include=["reasoning.encrypted_content"],X.metadata)F.metadata=X.metadata;let _=X.metadata?.promptCacheKey;if(_)F.prompt_cache_key=_;if(X.tools&&X.tools.length>0)F.tools=X.tools.map((R)=>({type:"function",name:R.function.name,description:R.function.description,parameters:R.function.parameters}));let U={"Content-Type":"application/json",Authorization:`Bearer ${B}`,"chatgpt-account-id":j,"OpenAI-Beta":"responses=experimental",originator:"codex_cli_rs",accept:"text/event-stream"};if(_)U.conversation_id=_,U.session_id=_;let N=await fetch(`${W}/codex/responses`,{method:"POST",headers:U,body:JSON.stringify(F),signal:X.signal});if(!N.ok){let R=await N.text().catch(()=>"");throw new b(`Codex API error: ${N.status} ${R}`,{code:`codex_http_${N.status}`,retryable:q$.isRetryableStatus(N.status),status:N.status})}if(!N.body)throw new b("No response body",{code:"no_response_body",retryable:!1});let A=f2(N.body);yield*u1(A,H)}catch(K){if(K?.name==="AbortError")throw new b("Request aborted",{code:"aborted",retryable:!1});if(K instanceof b)throw K;throw new b(K?.message||"Unknown error",{code:K?.code||"unknown_error",retryable:!1})}}return{provider:"codex",defaultModelId:$.defaultModelId,stream:V}}async function*f2($){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 V=Z.split(`
|
|
36
|
+
`);Z=V.pop()||"";for(let G of V)if(G.startsWith("data: ")){let X=G.slice(6);if(X==="[DONE]")return;try{yield JSON.parse(X)}catch(H){continue}}}}finally{W.releaseLock()}}function y2($){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 I2($){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 S${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 S$;static aggressive=new S$({maxAttempts:5,baseDelayMs:1000,maxDelayMs:60000});static gentle=new S$({maxAttempts:3,baseDelayMs:2000,maxDelayMs:30000,jitter:"full"})}function L0($){let W=$.adapter;if(!W)throw new b("Missing adapter. Provide `adapter` option.",{code:"missing_adapter",retryable:!1});if(!W.defaultModelId)throw new b("Adapter must have a defaultModelId.",{code:"missing_model_id",retryable:!1});let Q={provider:W.provider,modelId:W.defaultModelId},Z=new S$({maxAttempts:$.retry?.maxAttempts??3,baseDelayMs:$.retry?.baseDelayMs??500,maxDelayMs:$.retry?.maxDelayMs??30000,strategy:$.retry?.strategy??"exponential",jitter:$.retry?.jitter??"equal"}),J=$.timeoutMs??60000;async function*Y(G){let X=G.requestId||h$("req"),{model:H,...K}=G,B=G.model??Q,j=G.timeoutMs??J,z=!1,O=0,F=new AbortController,E=G.signal,_=setTimeout(()=>F.abort(),j),U=()=>F.abort();if(E)if(E.aborted)F.abort();else E.addEventListener("abort",U);let N={...K,requestId:X,model:B,stream:G.stream??!0,signal:F.signal,timeoutMs:j};try{for(let A=1;A<=Z.maxAttempts;A++){O=A;try{for await(let R of W.stream({request:N})){if(R.type==="delta")z=!0;yield R}return}catch(R){let q=p1(R),x=q.retryable;if(z||!x||!Z.canRetry(A))throw q;let S=Z.getDelay(A);$.retry?.onRetry?.({attempt:A,maxAttempts:Z.maxAttempts,delayMs:S,error:{code:q.code,message:q.message,retryable:q.retryable},model:B,request:N}),await q$.sleep(S,F.signal)}}}catch(A){let R=p1(A);throw yield{type:"error",requestId:X,terminal:!0,model:B,attempt:O||1,source:"client",error:{code:R.code,message:R.message,retryable:R.retryable}},R}finally{if(clearTimeout(_),E)E.removeEventListener("abort",U)}throw new b("Max retry attempts exceeded",{code:"max_retries_exceeded",retryable:!1})}async function V(G){let X="",H="",K="error",B,j,z=G.requestId||"",O=!1;for await(let F of Y({...G,stream:!0}))if(F.type==="response_start")O=!0,z=F.requestId,j=F.model,X="";else if(F.type==="delta"&&F.chunk.kind==="text")X+=F.chunk.text;else if(F.type==="response_end")H=X,K=F.stopReason,B=F.usage;else if(F.type==="error")K="error";if(!j)throw new b("Missing response_start from adapter",{code:"protocol_error",retryable:!1});return{requestId:z,model:j,text:O?H:X,stopReason:K,usage:B}}return{get modelId(){return Q.modelId},get modelRef(){return Q},setModelId(G){Q={provider:Q.provider,modelId:G}},stream:Y,run:V}}function p1($){if($ instanceof b)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?q$.isRetryableStatus(W):!1;return new b(Z,{code:Q,retryable:J,status:W})}return new b(String($||"Unknown error"),{code:"unknown_error",retryable:!1})}import c1 from"openai";function k2($){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 h2($){return{...$,content:k2($.content)}}function g2($,W){if(typeof W==="string"&&/deepseek/i.test(W))return!0;return/^deepseek-/i.test($)}function M0($={}){let W=$.baseUrl;function Q(){if(typeof $.apiKey==="function"){let H=$.apiKey();if(typeof H==="string"){let K=H.trim();if(!K)throw new b("Missing apiKey",{code:"missing_api_key",retryable:!1});return K}if(H!=null)throw new b("Invalid apiKey provider",{code:"invalid_api_key",retryable:!1})}if(typeof $.apiKey==="string"){let H=$.apiKey.trim();if(!H)throw new b("Missing apiKey",{code:"missing_api_key",retryable:!1});return H}let X=typeof process<"u"?process.env?.OPENAI_API_KEY:void 0;if(typeof X!=="string"||!X.trim())throw new b("Missing OPENAI_API_KEY",{code:"missing_api_key",retryable:!1});return X.trim()}function Z(){if(!(typeof globalThis.window<"u"))return!1;let H=typeof process<"u"&&!!process?.versions?.node,K=typeof globalThis.Bun<"u"||typeof process<"u"&&!!process?.versions?.bun;return H||K}function J(){let X=Q(),H=Z();if(typeof W==="string"&&/\/chat\/completions\/?$/.test(W))return new c1({apiKey:X,dangerouslyAllowBrowser:H,organization:$.organization,project:$.project,baseURL:"https://api.openai.com/v1",fetch:(B,j)=>{return fetch(W,j)}});return new c1({apiKey:X,dangerouslyAllowBrowser:H,organization:$.organization,project:$.project,baseURL:W||void 0})}function Y(X){return{provider:"openai",modelId:X.model.modelId}}function V(X){if(X instanceof b)return X;let H=typeof X?.status==="number"?X.status:void 0,K=typeof X?.message==="string"?X.message:"OpenAI error",B=typeof X?.code==="string"?X.code:H?`openai_http_${H}`:"openai_error",j=H?q$.isRetryableStatus(H):!1;return new b(K,{code:B,retryable:j,status:H})}async function*G(X){let{request:H}=X,K=H.requestId||h$("req"),B=J(),j=H.model.modelId,z=$.compat?.interleavedThinking,O=typeof z==="boolean"?z:g2(j,W),F=H.stream!==!1,E=[];if(H.messages&&Array.isArray(H.messages)){let N=-1;for(let A=H.messages.length-1;A>=0;A--)if(H.messages[A].role==="user"){N=A;break}for(let A=0;A<H.messages.length;A++){let R=H.messages[A],q=h2(R),x=A<N;if(q&&typeof q==="object"&&q.role==="assistant"){if(x){if("reasoning_content"in q)delete q.reasoning_content}else if(!O){if("reasoning_content"in q)delete q.reasoning_content}else if(Array.isArray(q?.tool_calls)&&q.tool_calls.length>0){let S=q.reasoning_content;if(typeof S!=="string"||S.length===0)q.reasoning_content="."}}E.push(q)}}else{if(typeof H.instructions==="string"&&H.instructions.length>0)E.push({role:"system",content:H.instructions});E.push({role:"user",content:H.input})}let _=(()=>{let N=H.reasoning?.effort;if(typeof N!=="string")return;if(N==="none"||N==="minimal"||N==="low"||N==="medium"||N==="high"||N==="xhigh")return N;return})(),U={model:j,messages:E,stream:F,stream_options:F?{include_usage:!0}:void 0,metadata:H.metadata??void 0,reasoning_effort:_,max_completion_tokens:H.maxOutputTokens??void 0,stop:H.stop??void 0,temperature:H.temperature??void 0,top_p:H.topP??void 0};if(H.tools&&Array.isArray(H.tools)&&H.tools.length>0)U.tools=H.tools;try{let N=Y(H);if(yield{type:"response_start",requestId:K,model:N},!F){let L=await B.chat.completions.create({...U,stream:!1},{signal:H.signal,timeout:H.timeoutMs}),C=Array.isArray(L?.choices)?L.choices[0]:void 0,k=C?.message,l=typeof k?.reasoning_content==="string"?k.reasoning_content:"";if(l.length>0)yield{type:"delta",requestId:K,chunk:{kind:"thinking_start"}},yield{type:"delta",requestId:K,chunk:{kind:"thinking_delta",text:l}},yield{type:"delta",requestId:K,chunk:{kind:"thinking_end",text:l}};let p=typeof k?.content==="string"?k.content:"";if(p.length>0)yield{type:"delta",requestId:K,chunk:{kind:"text",text:p}};let o=Array.isArray(k?.tool_calls)?k.tool_calls:[];for(let i=0;i<o.length;i++){let D=o[i],M=typeof D?.id==="string"?D.id:`call_${i}`,w=typeof D?.function?.name==="string"?D.function.name:void 0,P=typeof D?.function?.arguments==="string"?D.function.arguments:void 0;if(P||w)yield{type:"delta",requestId:K,chunk:{kind:"tool_call_delta",callId:M,toolId:w,argsTextDelta:P}}}let e=d1(C?.finish_reason);yield{type:"response_end",requestId:K,stopReason:e,usage:L?.usage};return}let A=await B.chat.completions.create({...U,stream:!0},{signal:H.signal,timeout:H.timeoutMs}),R=null,q,x=new Map,S=!1,y="";for await(let L of A){if(L?.usage!=null)q=L.usage;let C=Array.isArray(L?.choices)?L.choices:[];for(let k of C){if(k?.finish_reason!=null)R=k.finish_reason;let l=k?.delta,p=l?.reasoning_content;if(typeof p==="string"&&p.length>0){if(!S)S=!0,yield{type:"delta",requestId:K,chunk:{kind:"thinking_start"}};y+=p,yield{type:"delta",requestId:K,chunk:{kind:"thinking_delta",text:p}}}let o=l?.content;if(typeof o==="string"&&o.length>0){if(S)S=!1,yield{type:"delta",requestId:K,chunk:{kind:"thinking_end",text:y||void 0}};yield{type:"delta",requestId:K,chunk:{kind:"text",text:o}}}let e=Array.isArray(l?.tool_calls)?l.tool_calls:[];for(let i of e){let D=typeof i?.index==="number"?i.index:0,w=x.get(D)||(typeof i?.id==="string"?i.id:`call_${D}`);x.set(D,w);let P=typeof i?.function?.name==="string"?i.function.name:void 0,h=typeof i?.function?.arguments==="string"?i.function.arguments:void 0;if(P||h)yield{type:"delta",requestId:K,chunk:{kind:"tool_call_delta",callId:w,toolId:P,argsTextDelta:h}}}}}if(S)yield{type:"delta",requestId:K,chunk:{kind:"thinking_end",text:y||void 0}};yield{type:"response_end",requestId:K,stopReason:d1(R),usage:q}}catch(N){if(N?.name==="AbortError")throw new b("Aborted",{code:"aborted",retryable:!1});throw V(N)}}return{provider:"openai",defaultModelId:$.defaultModelId,stream:G}}function d1($){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 T0{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 n0{tools;options;eventQueue=new T0;constructor($,W){this.tools=$;this.options=W}async*executeTasksInParallel($,W,Q){this.eventQueue=new T0;let Z=!1,J=$.map(async(G)=>{let X=G.toolCall.function.name,H=this.tools?.get(X);if(!H)return{tc:G,result:`Tool "${X}" not found`,isError:!0};try{let K=typeof G.toolCall.function.arguments==="string"?JSON.parse(G.toolCall.function.arguments):G.toolCall.function.arguments,B=`${W.sessionId}:subagent:${crypto.randomUUID()}`,j={...Q,sessionId:B,emitEvent:(O)=>{this.eventQueue.enqueue({...O,sessionId:W.sessionId})}},z=await H.execute(K,j);return{tc:G,result:z,isError:!1}}catch(K){return{tc:G,result:`Task execution failed: ${K instanceof Error?K.message:String(K)}`,isError:!0}}}),Y=Promise.allSettled(J).then((G)=>{return Z=!0,G});while(!Z||!this.eventQueue.isEmpty()){let G=await this.eventQueue.dequeueOrWait(5);if(G)yield G}let V=await Y;for(let[G,X]of V.entries()){let H=$[G];if(X.status==="fulfilled"){let{result:K,isError:B}=X.value;H.result=K,H.isError=B}else H.result=`Task execution rejected: ${X.reason}`,H.isError=!0;if(!this.options.hasAssistantToolCallMessage(W,H.toolCall.id))this.options.addAssistantMessageWithToolCalls(W);yield{type:"tool_result",tool_call_id:H.toolCall.id,result:H.result,isError:H.isError,sessionId:W.sessionId},this.options.addToolResultToHistory(W,H)}}}class x${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 o0{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){z$(Q,`Tool execution: ${$.toolCall.function.name}`);let Y=Z?new x$(Z):void 0,V=$.toolCall.id,G=$.toolCall,X=G,H=(z)=>({sessionId:W.sessionId,toolCall:z,toolContext:W});if(J){if(!J.allow)return $.result="Tool execution blocked by PreToolUse hook",$.isError=!0,{type:"tool_result",tool_call_id:V,result:$.result,isError:!0,sessionId:W.sessionId};if(J.modifiedToolCall)X={...J.modifiedToolCall,id:V,type:G.type}}else if(Y){let z=await Y.executePreToolUse(H(X));if(!z.allow)return $.result="Tool execution blocked by PreToolUse hook",$.isError=!0,{type:"tool_result",tool_call_id:V,result:$.result,isError:!0,sessionId:W.sessionId};if(z.modifiedToolCall)X={...z.modifiedToolCall,id:V,type:G.type}}let K=this.options.tools?.get(X.function.name);if(!K)return this._log(`Tool NOT FOUND: ${X.function.name}`),$.result=`Tool not found: ${X.function.name}`,$.isError=!0,{type:"tool_result",tool_call_id:V,result:$.result,isError:!0,sessionId:W.sessionId};let B;try{B=typeof X.function.arguments==="string"?X.function.arguments.trim()===""?{}:JSON.parse(X.function.arguments):X.function.arguments??{}}catch(z){this._log(`Warning: Failed to parse tool arguments for ${X.function.name}, using empty object`),B={}}let j={...W,toolCallId:V,toolName:X.function.name};try{if($.result=await K.execute(B,j),$.isError=!1,Y)await Y.executePostToolUse(H(X),$.result);return{type:"tool_result",tool_call_id:V,result:$.result,sessionId:W.sessionId}}catch(z){let O=z instanceof Error?z:Error(String(z));if(this._log(`Tool execution threw ERROR: ${X.function.name} - ${O.message}`),$.result=O.message,$.isError=!0,Y)await Y.executePostToolUseFailure(H(X),O);return{type:"tool_result",tool_call_id:V,result:$.result,isError:!0,sessionId:W.sessionId}}}async*handleToolCalls($,W,Q){let Z=$.pendingToolCalls.length,J=Q?.signal,Y=Q?.toolContextInput,V=Y?.approval,G=V?.decisions??{},X=(_)=>{return this.options.approvalHandler.shouldRequireApproval(V,_)},H=(_)=>{return $.messages.some((U)=>{if(!U||typeof U!=="object"||U.role!=="assistant")return!1;let N=U.tool_calls;return Array.isArray(N)&&N.some((A)=>A?.id===_)})},K=(_)=>{if(!H(_))this.options.addAssistantMessageWithToolCalls($)},B=(_)=>{return $.messages.some((U)=>U&&typeof U==="object"&&U.role==="tool"&&U.tool_call_id===_)},j=new Set,z=(_)=>{try{return typeof _.function.arguments==="string"?JSON.parse(_.function.arguments):_.function.arguments}catch(U){let N=U instanceof Error?U.message:String(U);return{_raw:_.function.arguments,_parseError:N}}},O=(_)=>{let U=[];for(let N=_;N<$.pendingToolCalls.length;N++){let A=$.pendingToolCalls[N];if(B(A.toolCall.id))continue;if(j.has(A.toolCall.id))continue;if(G[A.toolCall.id])continue;let R=this.options.tools?.get(A.toolCall.function.name),q=R?.riskLevel??"safe";if(R&&this.options.isToolDisabled(A.toolCall.function.name))continue;if(R&&this.options.isToolBlocked($,A.toolCall.function.name))continue;if(!R||!X(q))continue;j.add(A.toolCall.id),U.push({type:"tool_approval_requested",tool_call_id:A.toolCall.id,toolName:A.toolCall.function.name,riskLevel:q,args:z(A.toolCall),sessionId:$.sessionId})}return U};if($.metadata?.parallelMode===!0){let _=$.pendingToolCalls.filter((U)=>{let N=U.toolCall.function.name;return N==="Task"||N.endsWith("_Task")});if(_.length>1)yield*this.options.parallelTaskExecutor.executeTasksInParallel(_,$,W),$.pendingToolCalls=$.pendingToolCalls.filter((U)=>!_.includes(U))}let E=this.options.checkpointManager.hasStore();for(let _=0;_<$.pendingToolCalls.length;_++){let U=$.pendingToolCalls[_];if(B(U.toolCall.id)){$.pendingToolCalls.splice(_,1),_--;continue}let N=U.toolCall.function.name,A;if(Q?.hooks?.preToolUse){let L=new x$(Q.hooks),C=(k)=>({sessionId:$.sessionId,toolCall:k,toolContext:W});if(A=await L.executePreToolUse(C(U.toolCall)),!A.allow){this._log(`Tool BLOCKED by preToolUse hook: ${N}`),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(_,1),_--,await this.options.saveCheckpoint($,{phase:"tool_execution",status:`Tool blocked by preToolUse hook: ${N}`,modelConfig:Q?.checkpointModelConfig,requestParams:Q?.requestParams});continue}}if(A?.modifiedToolCall)U.toolCall={...A.modifiedToolCall,id:U.toolCall.id,type:U.toolCall.type};let R=U.toolCall.function.name,q=this.options.tools?.get(R),x=q?.riskLevel??"safe";if(q&&this.options.isToolBlocked($,R)){let L=`Tool "${R}" is blocked by middleware`;this._log(`Tool BLOCKED: ${R} - ${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:R,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(_,1),_--,await this.options.saveCheckpoint($,{phase:"tool_execution",status:`Tool blocked: ${R}`,modelConfig:Q?.checkpointModelConfig,requestParams:Q?.requestParams});continue}if(q&&this.options.isToolDisabled(R)){let L=`Tool "${R}" is disabled for this session`;this._log(`Tool DISABLED: ${R}`),U.result=`Tool execution skipped: ${L}`,U.isError=!0,K(U.toolCall.id),yield{type:"tool_skipped",tool_call_id:U.toolCall.id,toolName:R,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(_,1),_--,await this.options.saveCheckpoint($,{phase:"tool_execution",status:`Tool disabled: ${R}`,modelConfig:Q?.checkpointModelConfig,requestParams:Q?.requestParams});continue}if(q&&X(x)){let L=G[U.toolCall.id];if(!L){this._log(`Tool approval required: ${R} (risk: ${x})`),$.stopReason="approval_required";for(let k of O(_)){if(k.type==="tool_approval_requested")this._log(` - Requesting approval for: ${k.toolName}`);yield k}let C=await this.options.saveCheckpoint($,{phase:"approval_pending",status:`Waiting for approval: ${R}`,modelConfig:Q?.checkpointModelConfig,requestParams:Q?.requestParams});throw yield{type:"requires_action",kind:"tool_approval",checkpoint:E?void 0:C,checkpointRef:E?{sessionId:C.sessionId}:void 0,sessionId:$.sessionId},await this.options.persistSessionState($),yield{type:"done",finalResponse:$.currentResponse,stopReason:"approval_required",modelStopReason:$.lastModelStopReason,usage:{...$.usage},sessionId:$.sessionId},new P$}if(!L.approved){let C=L.reason??"User denied approval";this._log(`Tool approval REJECTED: ${R} - ${C}`),U.result=`Tool execution skipped: ${C}`,U.isError=!0,K(U.toolCall.id),yield{type:"tool_skipped",tool_call_id:U.toolCall.id,toolName:U.toolCall.function.name,reason:C,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(_,1),_--,await this.options.saveCheckpoint($,{phase:"tool_execution",status:`Tool approval rejected: ${R}`,modelConfig:Q?.checkpointModelConfig,requestParams:Q?.requestParams});continue}this._log(`Tool approval APPROVED: ${R}`)}K(U.toolCall.id),this._log(`Executing tool: ${R}`),this.toolEventQueue=[];let S=await this.executeToolCall(U,W,J,Q?.hooks,A);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 C=typeof S.result==="string"?S.result:JSON.stringify(S.result);this._log(`Tool execution ERROR: ${R} - ${C.slice(0,100)}`)}else{let C=typeof S.result==="string"?S.result.slice(0,100):JSON.stringify(S.result).slice(0,100);this._log(`Tool execution SUCCESS: ${R} - ${C}${C.length>=100?"...":""}`)}let y=S.type==="tool_result"&&(S.isError||S.result&&typeof S.result==="object"&&S.result.isError===!0);if(q&&q.name==="AskUserQuestion"&&y){let L=Y?.askUser?.rejected?.[U.toolCall.id];if(L!==void 0){let k=L||"User cancelled the question";this._log(`AskUser CANCELLED: ${k}`),U.result=`User cancelled the question: ${k}`,U.isError=!0,K(U.toolCall.id),yield{type:"tool_skipped",tool_call_id:U.toolCall.id,toolName:q.name,reason:k,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(_,1),_--,await this.options.saveCheckpoint($,{phase:"tool_execution",status:`AskUser cancelled: ${q.name}`,modelConfig:Q?.checkpointModelConfig,requestParams:Q?.requestParams});continue}let C=Y?.askUser?.answers?.[U.toolCall.id];if(!C){let l=(typeof U.toolCall.function.arguments==="string"?JSON.parse(U.toolCall.function.arguments):U.toolCall.function.arguments)?.questions||[];this._log(`AskUser waiting for answers (${l.length} questions)`),yield S,$.stopReason="approval_required";let p=await this.options.saveCheckpoint($,{phase:"approval_pending",status:`Waiting for user answers: ${q.name}`,modelConfig:Q?.checkpointModelConfig,requestParams:Q?.requestParams});throw await this.options.persistSessionState($),yield{type:"requires_action",kind:"ask_user",toolCallId:U.toolCall.id,questions:l,checkpoint:E?void 0:p,checkpointRef:E?{sessionId:p.sessionId}:void 0,sessionId:$.sessionId},yield{type:"done",finalResponse:$.currentResponse,stopReason:"approval_required",modelStopReason:$.lastModelStopReason,usage:{...$.usage},sessionId:$.sessionId},new P$}else{let l={...typeof U.toolCall.function.arguments==="string"?JSON.parse(U.toolCall.function.arguments):U.toolCall.function.arguments,answers:C};U.toolCall.function.arguments=JSON.stringify(l),this.toolEventQueue=[];let p=await this.executeToolCall(U,W,J,Q?.hooks,A);for(let o of this.toolEventQueue)yield o;this.toolEventQueue=[],yield p,this.options.addToolResultToHistory($,U),$.pendingToolCalls.splice(_,1),_--,await this.options.saveCheckpoint($,{phase:"tool_execution",status:U.isError?`AskUser error: ${q.name}`:`AskUser completed: ${q.name}`,modelConfig:Q?.checkpointModelConfig,requestParams:Q?.requestParams});continue}}yield S,this.options.addToolResultToHistory($,U),$.pendingToolCalls.splice(_,1),_--,await this.options.saveCheckpoint($,{phase:"tool_execution",status:U.isError?`Tool error: ${R}`:`Tool completed: ${R}`,modelConfig:Q?.checkpointModelConfig,requestParams:Q?.requestParams})}$.pendingToolCalls=[],$.iteration++,yield{type:"iteration_end",iteration:$.iteration-1,willContinue:!0,toolCallCount:Z,usage:{...$.usage},sessionId:$.sessionId}}}class P0{static APPROVAL_REQUIRED_LEVELS=new Set(["high","critical"]);requiresApproval($){return P0.APPROVAL_REQUIRED_LEVELS.has($)}shouldRequireApproval($,W){if($?.autoApprove===!0)return!1;if(($?.strategy??"high_risk")==="all")return!0;return this.requiresApproval(W)}}class a0{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 u2=1000;function p2($){if(!$)return;if($ instanceof b)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 i1($){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 l1($){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,V=J.map((G)=>{let X=i1(G);if(X!==G)Y=!0;return X});if(!Y)return Z;return W=!0,{...Z,tool_calls:V}});return W?Q:$}class $$ extends m2{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;_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 l0($),this._approvalHandler=new P0,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 a0(()=>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._maxIterations=Z?.maxIterations,this._requestParams=Z?.requestParams,this._emitSessionCreatedEvent=Z?.emitSessionCreatedEvent===!0,this._enableLogging=Z?.enableLogging??!1,this._parallelTaskExecutor=new n0(this._tools,{hasAssistantToolCallMessage:(J,Y)=>this.hasAssistantToolCallMessage(J,Y),addAssistantMessageWithToolCalls:(J)=>this.addAssistantMessageWithToolCalls(J),addToolResultToHistory:(J,Y)=>this.addToolResultToHistory(J,Y)}),this._toolExecutor=new o0({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 V=V0(W);if(V.sessionId!==this.id)V.sessionId=this.id;V.shouldContinue=!0,V.stopReason=void 0,V.metadata={...V.metadata,_pendingUserInput:J};let G=this._requestParams??W.requestParams,X=Y??$,H=this.buildAutoRejectToolContext(V,X?.toolContext);if(!(yield*this._streamWithPauseDetection(V,{maxIterations:this._maxIterations,signal:Z,model:this.getRuntimeModelOverride(),toolContext:H,hooks:this._hooks,requestParams:G})))await this._finalizeRun(V,Date.now());return}if(Q){this._log("Resuming from checkpoint without new message");let J=V0(W);if(J.sessionId!==this.id)J.sessionId=this.id;let Y=this._requestParams??W.requestParams,V=this.buildAutoRejectToolContext(J,$?.toolContext);if(!(yield*this._streamWithPauseDetection(J,{maxIterations:this._maxIterations,signal:Z,model:this.getRuntimeModelOverride(),toolContext:V,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 F$){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(),Z=this.getRuntimeModelOverride(),J=this._abortController?.signal;if(!this.title&&this.messages.length===0){let X=this.extractTextFromContent($);if(X)this.title=this.createTitle(X)}let Y=this.messages.filter((X)=>X.role!=="system");this._log(`Starting agent loop with ${Y.length} existing messages`);let V=D0({sessionId:this.id,input:$,messages:Y},this.getEffectiveSystemPrompt()??"");if(!(yield*this._streamWithPauseDetection(V,{maxIterations:this._maxIterations,signal:J,model:Z,toolContext:W?.toolContext,hooks:this._hooks,requestParams:this._requestParams})))await this._finalizeRun(V,Q)}async*_streamWithPauseDetection($,W){try{return yield*this._streamWithState($,W),!1}catch(Q){if(Q instanceof P$)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,V=J.toolCall.function.name;if(!W?.approval?.decisions?.[Y])Q[Y]={approved:!1,reason:"Auto-rejected: session resumed without tool context"};if(V==="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}}}}getRuntimeModelOverride(){if(this.configOverride?.model){let $=this.resolveModelRef(this.configOverride.model);if($)return $}return this._modelOverride}_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){if(!this._modelClient)throw Error("Session is not configured with a model client");let Y=[],V=$.sessionId,G=new Map,X=!1,H=!1,K=(U)=>{let N=G.get(U);if(N)return N;let A={argsText:"",started:!1};return G.set(U,A),A},B=(U,N)=>{let A=K(U);if(N&&!A.toolName)A.toolName=N;if(!A.started)A.started=!0,this._log(`Stream: tool_call_start - ${A.toolName} (${U.slice(0,8)})`),Y.push({type:"tool_call_start",callId:U,toolName:A.toolName,sessionId:V})},j=(U,N,A)=>{let R=K(U);if(N&&!R.toolName)R.toolName=N;if(typeof A==="string"&&A.length>0)R.argsText+=A;B(U,R.toolName),Y.push({type:"tool_call_delta",callId:U,toolName:R.toolName,argsTextDelta:A,sessionId:V})},z=()=>{if(X)return;X=!0,this._log("Stream: text_start"),Y.push({type:"text_start",sessionId:V})},O=()=>{if(!X||H)return;H=!0;let U=$.currentResponse.slice(0,50)+($.currentResponse.length>50?"...":"");this._log(`Stream: text_end - "${U}"`),Y.push({type:"text_end",content:$.currentResponse,sessionId:V})},F=()=>{for(let[U,N]of G){if(!N.toolName)continue;let A={id:U,type:"function",function:{name:N.toolName,arguments:N.argsText}};if(this._tools){$.pendingToolCalls.push({toolCall:A});let R=N.argsText.slice(0,100)+(N.argsText.length>100?"...":"");this._log(`Stream: tool_call_end - ${N.toolName} with args: ${R}`)}Y.push({type:"tool_call_end",toolCall:A,sessionId:V})}G.clear()},E=(()=>{if(!J)return;let U={...J};if(typeof U.maxOutputTokens!=="number"&&typeof J.maxTokens==="number")U.maxOutputTokens=J.maxTokens;return delete U.maxTokens,U})(),_=Z?{model:Z,messages:l1($.messages),tools:Q,signal:W,...E??{}}:{messages:l1($.messages),tools:Q,signal:W,...E??{}};try{for await(let U of this._modelClient.stream(_))if(z$(W,"Session streaming"),U.type==="delta"){if(U.chunk.kind==="text")z(),$.currentResponse+=U.chunk.text,Y.push({type:"text_delta",delta:U.chunk.text,sessionId:V});else if(U.chunk.kind==="thinking_start")this._log("Stream: thinking_start"),Y.push({type:"thinking_start",sessionId:V});else if(U.chunk.kind==="thinking_delta")$.currentThinking=($.currentThinking??"")+U.chunk.text,Y.push({type:"thinking_delta",delta:U.chunk.text,sessionId:V});else if(U.chunk.kind==="thinking_end"){let N=typeof U.chunk.text==="string"?U.chunk.text:"";if(N&&typeof $.currentThinking!=="string")$.currentThinking=N;let A=typeof $.currentThinking==="string"?$.currentThinking:N,R=A?A.slice(0,50)+(A.length>50?"...":""):"";this._log(`Stream: thinking_end - "${R}"`),Y.push({type:"thinking_end",sessionId:V,...A?{content:A}:{}})}else if(U.chunk.kind==="tool_call_delta")j(U.chunk.callId,U.chunk.toolId,U.chunk.argsTextDelta)}else if(U.type==="response_end"){this._log(`Stream: response_end - stopReason: ${U.stopReason}`),O(),F(),$.lastModelStopReason=U.stopReason;let N=U.usage;if(N&&typeof N==="object"){let A=N;if(A.prompt_tokens||A.completion_tokens||A.total_tokens){let R={promptTokens:A.prompt_tokens??0,completionTokens:A.completion_tokens??0,totalTokens:A.total_tokens??0};$.usage.promptTokens=R.promptTokens,$.usage.completionTokens=R.completionTokens,$.usage.totalTokens+=R.totalTokens,this._recordUsage(R)}}}else if(U.type==="error"){if(U.terminal!==!1){let N=U.error?.code??"model_error",A=U.error?.message??"Model error",R=new b(A,{code:N,retryable:U.error?.retryable});$.error=R,$.shouldContinue=!1,$.stopReason="error"}}}catch(U){if(U instanceof F$)throw U;if(W?.aborted)throw new F$(typeof W?.reason==="string"?W.reason:"Agent execution aborted");$.error=U instanceof Error?U:Error(String(U)),$.shouldContinue=!1,$.stopReason="error"}finally{if(O(),G.size>0)F()}return Y}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=E0($,{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)=>i1(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??u2,Z=W.signal,J=R0(this._middlewares),Y=this._toolExecutor.createToolExecutionContext($,Z),V=this._stateStore,G=V?.deleteOnComplete??!0,X=W.model?{modelId:W.model.modelId,provider:W.model.provider}:this._modelClient?{modelId:this._modelClient.modelId}:void 0,H=async(K)=>{if(!V)return;await this.saveCheckpointForState($,{phase:K?.phase,status:K?.status,modelConfig:X,requestParams:W.requestParams})};while($.shouldContinue){if(z$(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:X,requestParams:W.requestParams}),$.metadata?._pendingUserInput){let j=$.metadata._pendingUserInput;delete $.metadata._pendingUserInput,this.appendMessage($,{role:"user",content:j})}continue}if($.metadata?._pendingUserInput){let j=$.metadata._pendingUserInput;delete $.metadata._pendingUserInput,this.appendMessage($,{role:"user",content:j})}$.currentResponse="",$.currentThinking=void 0,$.pendingToolCalls=[],$.lastModelStopReason=void 0,await H();let K=[],B=await J({...$,messages:structuredClone($.messages)},async(j)=>{z$(Z,"Session model call");let z=this.collectBlockedTools(j);j.metadata.blockedTools=z;let O=this.getToolsForModel(j),F=O?.length??0;return this._log(`Calling model with ${j.messages.length} messages and ${F} tools`),K=await this.executeModelStream(j,Z,O,W.model,W.requestParams),this._log(`Model response: ${j.currentResponse.slice(0,100)}${j.currentResponse.length>100?"...":""}, tool calls: ${j.pendingToolCalls.length}`),j});this.mergeStateResults($,B);for(let j of K)yield j;if(z$(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:p2($.error),usage:{...$.usage},sessionId:$.sessionId};break}if($.pendingToolCalls.length>0)yield*this._toolExecutor.handleToolCalls($,Y,{signal:Z,toolContextInput:W.toolContext,hooks:W.hooks,checkpointModelConfig:X,requestParams:W.requestParams});else yield*this.handleFinalResponse($);if(await H(),!$.shouldContinue){if(this._log(`Agent loop finished. Stop reason: ${$.stopReason}`),V&&G)await V.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,r.SESSION,$)}async load(){let $=await this._stateStore.load(this.id,r.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 G0{}import{randomUUID as c2}from"node:crypto";class S0 extends G0{_stateStore;constructor($){super();this._stateStore=$}async create($){let W=$??c2(),Q=Date.now(),Z=(()=>{try{let V=globalThis?.process;return typeof V?.cwd==="function"?String(V.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 $$(this._stateStore,W,J);return await Y.save(),Y}async get($){let W=await this._stateStore.load($,r.SESSION);if(!W)return;return new $$(this._stateStore,$,W)}async list(){let $=await this._stateStore.listSessions(),W=[];for(let Q of $){let Z=await this._stateStore.load(Q,r.SESSION);if(Z){let J=new $$(this._stateStore,Q,Z);W.push(J)}}return W}async destroy($){await this._stateStore.deleteSession($)}}import{existsSync as N$,mkdirSync as r1,readdirSync as s0,readFileSync as d2,rmSync as t0,writeFileSync as l2}from"node:fs";import b$ from"node:path";class w${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,r.CHECKPOINT,W)}async loadCheckpoint($){return(await this.load($,r.CHECKPOINT))?.checkpoint}async deleteCheckpoint($){await this.delete($,r.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 H0 extends w${baseDir;constructor($){super($);this.baseDir=b$.resolve($.dir),this.ensureDir(this.baseDir)}async _write($,W){let Q=this.toFilePath($);this.ensureDir(b$.dirname(Q)),l2(Q,W,"utf-8")}async _read($){let W=this.toFilePath($);try{if(!N$(W))return;return d2(W,"utf-8")}catch{return}}async _delete($){let W=this.toFilePath($);if(N$(W))t0(W);let Q=b$.dirname(W);if(N$(Q))try{if(s0(Q).length===0)t0(Q,{recursive:!0})}catch{}}async _exists($){let W=this.toFilePath($);return N$(W)}async _list($){let W=[];if(!N$(this.baseDir))return W;let Q=s0(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=b$.join(this.baseDir,Z),Y=this.listJsonFiles(J);for(let V of Y){let G=b$.basename(V,".json"),X=`${Z}/${G}`;if(!$||X.startsWith($))W.push(X)}}return W}toFilePath($){return b$.join(this.baseDir,`${$}.json`)}ensureDir($){if(!N$($))r1($,{recursive:!0})}listJsonFiles($){if(!N$($))return[];return s0($).filter((W)=>W.endsWith(".json")).map((W)=>b$.join($,W))}getBaseDir(){return this.baseDir}clear(){if(N$(this.baseDir))t0(this.baseDir,{recursive:!0}),r1(this.baseDir,{recursive:!0})}}class X0 extends w${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 A${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 X0,this._enableLogging=$.enableLogging??!1,this._sessionManager=new S0(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 $$(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");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 $$(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),V=Object.create(Object.getPrototypeOf(J));Object.assign(V,J),Object.defineProperty(V,"name",{value:Y,writable:!1,configurable:!0});try{this._tools.register(V),Z.push(Y)}catch(G){console.warn(`Failed to register tool ${Y}:`,G)}}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{readFile as i2}from"node:fs/promises";import r2 from"node:path";import n2 from"node:process";var o2=["AGENTS.md","CLAUDE.md"],a2="[Project Agent Rules]";async function s2($,W){let Q=[];for(let Z of W)try{let J=r2.resolve($,Z),Y=await i2(J,"utf-8");if(Y.trim())Q.push(Y.trim())}catch{continue}return Q.length>0?Q.join(`
|
|
37
37
|
|
|
38
38
|
---
|
|
39
39
|
|
|
40
|
-
`):""}function
|
|
41
|
-
`).filter(Boolean)}catch(W){throw Error(`Failed to stage files: ${W instanceof Error?W.message:String(W)}`)}}function
|
|
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
|
|
40
|
+
`):""}function t2($){let{cwd:W,ruleFiles:Q=o2,marker:Z=a2}=$??{},J=async(Y,V)=>{let G=typeof W==="function"?W():W??n2.cwd(),X=await s2(G,Q),H=Y.messages;if(X)H=j$(H,X,Z);let K={...Y,messages:H};return V(K)};return J.__middlewareName="agent-rules",J}import{execSync as m}from"node:child_process";import{unlinkSync as e2,writeFileSync as $4}from"node:fs";import{tmpdir as W4}from"node:os";import{join as Q4}from"node:path";function e0($){try{return m("git rev-parse --git-dir",{cwd:$,stdio:"pipe"}),!0}catch{return!1}}function n1($){try{return m("git add --all",{cwd:$,encoding:"utf-8"}),m("git diff --staged --name-only",{cwd:$,encoding:"utf-8"}).trim().split(`
|
|
41
|
+
`).filter(Boolean)}catch(W){throw Error(`Failed to stage files: ${W instanceof Error?W.message:String(W)}`)}}function o1($){try{return m("git diff --staged",{cwd:$,encoding:"utf-8"})}catch(W){throw Error(`Failed to get diff: ${W instanceof Error?W.message:String(W)}`)}}function $1($){try{return m("git diff --staged --name-only",{cwd:$,encoding:"utf-8"}).trim().length>0}catch{return!1}}function a1($){try{let W=m("git diff --staged --name-status",{cwd:$,encoding:"utf-8"});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 W1($){try{if(m("git diff --name-only",{cwd:$,encoding:"utf-8"}).trim().length>0)return!0;return m("git ls-files --others --exclude-standard",{cwd:$,encoding:"utf-8"}).trim().length>0}catch{return!1}}function s1($,W){try{let Q=Q4(W4(),`goatchain-commit-${Date.now()}.txt`);$4(Q,$,"utf-8");try{return m(`git commit -F "${Q}"`,{cwd:W,stdio:"pipe"}),m("git rev-parse HEAD",{cwd:W,encoding:"utf-8"}).trim()}finally{try{e2(Q)}catch{}}}catch(Q){throw Error(`Failed to create commit: ${Q instanceof Error?Q.message:String(Q)}`)}}function Q1($){try{let W=m("git rev-parse --abbrev-ref HEAD",{cwd:$,encoding:"utf-8"}).trim();return W==="HEAD"?null:W}catch{return null}}function Z4($,W="origin"){try{return m("git remote",{cwd:$,encoding:"utf-8"}).split(`
|
|
43
|
+
`).map((Z)=>Z.trim()).includes(W)}catch{return!1}}function J4($){try{return m("git rev-parse --abbrev-ref --symbolic-full-name @{u}",{cwd:$,encoding:"utf-8"}).trim()||null}catch{return null}}function t1($,W="origin"){try{return m(`git fetch ${W}`,{cwd:$,stdio:"pipe"}),!0}catch{return!1}}function Y4($){try{let W=m("git rev-list --left-right --count @{u}...HEAD",{cwd:$,encoding:"utf-8"}).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 V4($){try{let W=m("git status --porcelain",{cwd:$,encoding:"utf-8"});return/^(?:UU|AA|DD|AU|UA|DU|UD)\s/m.test(W)}catch{return!1}}function G4($){try{let W=m("git status --porcelain",{cwd:$,encoding:"utf-8"}),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 H4($){try{try{return m("git rev-parse --verify MERGE_HEAD",{cwd:$,stdio:"pipe"}),{inMerge:!0,type:"merge"}}catch{}try{return m("test -d .git/rebase-merge -o -d .git/rebase-apply",{cwd:$,stdio:"pipe"}),{inMerge:!0,type:"rebase"}}catch{}try{return m("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 Z1($){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=e0($),!W.isGitRepo)return W.canCommit=!1,W.errors.push("Not a git repository"),W;if(W.currentBranch=Q1($),!W.currentBranch)W.warnings.push("Detached HEAD state - no branch checked out");let Q=H4($);if(W.inMergeState=Q.inMerge,W.mergeStateType=Q.type,W.inMergeState)W.warnings.push(`Currently in ${W.mergeStateType} state`);if(W.hasConflicts=V4($),W.hasConflicts)W.conflictFiles=G4($),W.canCommit=!1,W.errors.push(`Unresolved conflicts in ${W.conflictFiles.length} file(s): ${W.conflictFiles.join(", ")}`);if(W.hasChanges=W1($)||$1($),!W.hasChanges&&!W.inMergeState)W.canCommit=!1,W.errors.push("No changes to commit");if(W.hasRemote=Z4($),W.hasRemote){let Z=J4($);if(W.hasUpstream=!!Z,W.hasUpstream){let J=Y4($);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 X4="You are a commit message generator. You print plain text without code blocks and don't talk.";function K4($,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,63 +65,63 @@ 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 e1($){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 j4($){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(` ${e1(J)}:`);for(let V of Y)if(V.oldFile)W.push(` • ${V.oldFile} → ${V.file}`);else W.push(` • ${V.file}`);W.push("")}for(let[J,Y]of Object.entries(Q)){if(Z.includes(J))continue;W.push(` ${e1(J)}:`);for(let V of Y)W.push(` • ${V.file}`);W.push("")}return W.push(` 共 ${$.length} 个文件 (Total: ${$.length} files)`),W.join(`
|
|
70
|
+
`)}function Y1($){let W=$.name??"commit-mode",Q=$.model,Z=$.defaultLanguage??"English",J=$.defaultAutoStage??!0,Y=$.fetchBeforeCommit??!1,V=$.allowBehindRemote??!1,G=$.cwd??process.cwd(),X=$.customPrompt,H=async(K,B)=>{if(K.metadata?.commitProcessed)return B(K);try{let j=Z1(G);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{...
|
|
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 z={fetched:!1,message:""};if(Y&&j.hasRemote)if(t1(G)){z={fetched:!0,message:"已从远程获取最新更新"};let C=Z1(G);Object.assign(j,{ahead:C.ahead,behind:C.behind,isDiverged:C.isDiverged})}else z={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
|
-
Please resolve the conflicts above before committing.`};return{...
|
|
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
|
-
Please complete or abort the current ${j.mergeStateType} operation.`};return{...
|
|
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(!V&&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{...
|
|
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(W1(G))n1(G);else if(!$1(G)&&!j.inMergeState){let L={role:"assistant",content:`✗ 没有需要提交的更改。
|
|
96
96
|
|
|
97
|
-
No changes to commit. Working directory is clean.`};return{...
|
|
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 O=a1(G),F=o1(G);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{...
|
|
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 E=K4(F,Z,X),_=[{role:"system",content:X4},{role:"user",content:E}],N=(await Q.run({messages:_})).text.trim();if(!N)throw Error("LLM returned empty commit message");let A=s1(N,G),R=j4(O),q=z.fetched?`
|
|
100
100
|
|
|
101
|
-
\uD83D\uDCE1 ${z.message}`:"",
|
|
101
|
+
\uD83D\uDCE1 ${z.message}`:"",x=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}`:"",y={role:"assistant",content:`✓ 成功创建 commit
|
|
107
107
|
|
|
108
|
-
Commit Hash: ${A}${
|
|
108
|
+
Commit Hash: ${A}${S}${q}${x}
|
|
109
109
|
|
|
110
|
-
${
|
|
110
|
+
${R}
|
|
111
111
|
|
|
112
112
|
Commit Message:
|
|
113
|
-
${N}`};return{...
|
|
113
|
+
${N}`};return{...K,messages:[...K.messages,y],currentResponse:y.content,shouldContinue:!1,stopReason:"final_response",metadata:{...K.metadata,commitProcessed:!0,commitHash:A,commitMessage:N,preCommitCheck:j}}}catch(j){let z={role:"assistant",content:`✗ 创建 commit 失败
|
|
114
114
|
|
|
115
|
-
Error: ${j instanceof Error?j.message:String(j)}`};return{...
|
|
116
|
-
`)){let Y=J.trim();if(Y&&!Y.startsWith("#"))Z.add(Y)}return Z}catch{return
|
|
117
|
-
`)}async function
|
|
115
|
+
Error: ${j instanceof Error?j.message:String(j)}`};return{...K,messages:[...K.messages,z],currentResponse:z.content,shouldContinue:!1,stopReason:"error",metadata:{...K.metadata,commitProcessed:!0}}}};return H.__middlewareName=W,H}import{readdir as $W,readFile as z4}from"node:fs/promises";import B$ from"node:path";import WW from"node:process";var B4="[Environment Information]";async function U4($){try{let W=B$.join($,".gitignore"),Q=await z4(W,"utf-8"),Z=new Set;for(let J of Q.split(`
|
|
116
|
+
`)){let Y=J.trim();if(Y&&!Y.startsWith("#"))Z.add(Y)}return Z}catch{return null}}function QW($,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 ZW($){return B$.extname($)||$}async function JW($,W,Q,Z,J){try{let Y=await $W($,{withFileTypes:!0}),V=B$.relative(Z.cwd,$),G=[],X={},H=0,K=Y.sort((j,z)=>{if(j.isDirectory()&&!z.isDirectory())return-1;if(!j.isDirectory()&&z.isDirectory())return 1;return j.name.localeCompare(z.name)}),B=0;for(let j of K){if(B>=Z.maxEntriesPerDir)break;let z=B$.join($,j.name),O=B$.relative(Z.cwd,z);if(Z.respectGitignore&&QW(O,j.name,J))continue;if(j.isDirectory())if(Q<Z.maxDepth){let F=await JW(z,W,Q+1,Z,J);if(F){G.push(F),H+=F.totalFiles;for(let[E,_]of Object.entries(F.fileStats))X[E]=(X[E]||0)+_}}else{let F=await YW(z,J,Z);G.push({name:j.name,path:O,children:[],fileStats:F.stats,totalFiles:F.total}),H+=F.total;for(let[E,_]of Object.entries(F.stats))X[E]=(X[E]||0)+_}else{G.push({name:j.name,path:O});let F=ZW(j.name);X[F]=(X[F]||0)+1,H+=1}B++}return{name:B$.basename($),path:V||".",children:G,fileStats:X,totalFiles:H}}catch{return null}}async function YW($,W,Q){let Z={},J=0;try{let Y=await $W($,{withFileTypes:!0});for(let V of Y){let G=B$.join($,V.name),X=B$.relative(Q.cwd,G);if(Q.respectGitignore&&QW(X,V.name,W))continue;if(V.isDirectory()){let H=await YW(G,W,Q);J+=H.total;for(let[K,B]of Object.entries(H.stats))Z[K]=(Z[K]||0)+B}else{let H=ZW(V.name);Z[H]=(Z[H]||0)+1,J+=1}}}catch{}return{total:J,stats:Z}}function O4($,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 VW($,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 V=Y;if(Z.push(`${W}${V.name}/`),V.totalFiles>0&&V.children.length===0){let G=O4(V.fileStats,V.totalFiles);if(G)Z.push(`${W} ${G}`)}else if(V.children.length>0){let G=VW(V,`${W} `,!1);Z.push(G)}}else{let V=Y;Z.push(`${W}${V.name}`)}}return Z.join(`
|
|
117
|
+
`)}async function _4($){try{let W;if($.respectGitignore){let Z=await U4($.cwd);if(Z===null)return null;W=Z}else W=new Set;let Q=await JW($.cwd,$.cwd,0,$,W);if(!Q)return"Unable to read directory structure";return VW(Q)}catch(W){return`Error generating file tree: ${W instanceof Error?W.message:String(W)}`}}function F4($){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"),V=$.getFullYear();return`${Z} ${J} ${Y} ${V}`}async function q4($,W,Q){let Z=[],J=[];J.push(`Working directory: ${$}`);let Y=e0($);if(Y){let V=Q1($);if(V)J.push(`Is directory a git repo: yes, branch: ${V}`);else J.push("Is directory a git repo: yes")}else J.push("Is directory a git repo: no");if(J.push(`Platform: ${WW.platform}`),J.push(`Today's date: ${F4(new Date)}`),Z.push(`<env>
|
|
118
118
|
${J.join(`
|
|
119
119
|
`)}
|
|
120
|
-
</env>`),W&&Y&&Q){let V=await
|
|
120
|
+
</env>`),W&&Y&&Q){let V=await _4(Q);if(V!==null)Z.push(`<files>
|
|
121
121
|
${V}
|
|
122
122
|
</files>`)}return Z.join(`
|
|
123
123
|
|
|
124
|
-
`)}function
|
|
124
|
+
`)}function N4($){let{cwd:W,marker:Q=B4,includeFileTree:Z=!0,maxDepth:J=3,maxEntriesPerDir:Y=50,respectGitignore:V=!0}=$??{},G=async(X,H)=>{let K=typeof W==="function"?W():W??WW.cwd(),j=await q4(K,Z,{cwd:K,maxDepth:J,maxEntriesPerDir:Y,respectGitignore:V}),z=X.messages;if(j)z=j$(z,j,Q);let O={...X,messages:z};return H(O)};return G.__middlewareName="env-info",G}function GW($){return{content:[{type:"text",text:$}]}}function I($){return{content:[{type:"text",text:$}],isError:!0}}function HW($,W){return{content:[{type:"image",data:$,mimeType:W}]}}class v{riskLevel="safe"}class g$ extends v{name="AskUserQuestion";riskLevel="safe";description=`Use this tool when you need to ask the user questions during execution. This allows you to:
|
|
125
125
|
1. Gather user preferences or requirements
|
|
126
126
|
2. Clarify ambiguous instructions
|
|
127
127
|
3. Get decisions on implementation choices as you work
|
|
@@ -130,7 +130,7 @@ ${V}
|
|
|
130
130
|
Usage notes:
|
|
131
131
|
- Users will always be able to select "Other" to provide custom text input
|
|
132
132
|
- Use multiSelect: true to allow multiple answers to be selected for a question
|
|
133
|
-
- 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:V,header:G,options:
|
|
133
|
+
- 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:V,header:G,options:X,multiSelect:H}=Y;if(typeof V!=="string"||!V.trim())throw Error(`questions[${J}].question is required and must be a non-empty string`);if(typeof G!=="string"||!G.trim())throw Error(`questions[${J}].header is required and must be a non-empty string`);if(G.length>12)throw Error(`questions[${J}].header must be at most 12 characters`);if(!Array.isArray(X))throw TypeError(`questions[${J}].options must be an array`);if(X.length<2||X.length>4)throw Error(`questions[${J}].options must contain 2-4 items`);if(typeof H!=="boolean")throw TypeError(`questions[${J}].multiSelect is required and must be a boolean`);let K=[];for(let B=0;B<X.length;B++){let j=X[B];if(typeof j!=="object"||j===null)throw TypeError(`questions[${J}].options[${B}] must be an object`);let{label:z,description:O}=j;if(typeof z!=="string"||!z.trim())throw Error(`questions[${J}].options[${B}].label is required and must be a non-empty string`);if(typeof O!=="string"||!O.trim())throw Error(`questions[${J}].options[${B}].description is required and must be a non-empty string`);K.push({label:z.trim(),description:O.trim()})}Q.push({question:V.trim(),header:G.trim(),options:K,multiSelect:Boolean(H)})}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((V)=>String(V));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 V=this.formatAnswerText(Y);if(V.inline!==void 0)Q.push(`Answer: ${V.inline}`);else if(V.lines){Q.push("Answer:");for(let G of V.lines)Q.push(` ${G}`)}Q.push("")}if(Q.length===0)return"No answers received";if(Q[Q.length-1]==="")Q.pop();return`User responses:
|
|
134
134
|
|
|
135
135
|
${Q.join(`
|
|
136
136
|
`)}`}formatAnswerText($){if(Array.isArray($)){if($.length===0)return{inline:"(no response)"};if($.length===1){let Q=String($[0]);if(Q.includes(`
|
|
@@ -138,9 +138,9 @@ ${Q.join(`
|
|
|
138
138
|
`)};return{inline:Q}}return{lines:this.formatArrayAnswer($.map((Q)=>String(Q)))}}let W=String($);if(W.includes(`
|
|
139
139
|
`))return{lines:W.split(`
|
|
140
140
|
`)};return{inline:W}}formatArrayAnswer($){let W=[];for(let Q of $){let Z=Q.split(`
|
|
141
|
-
`);W.push(`- ${Z[0]??""}`);for(let J=1;J<Z.length;J++)W.push(` ${Z[J]}`)}return W}}import
|
|
141
|
+
`);W.push(`- ${Z[0]??""}`);for(let J=1;J<Z.length;J++)W.push(` ${Z[J]}`)}return W}}import c4 from"node:process";import{spawn as zW}from"node:child_process";import{chmodSync as A4,existsSync as J$,mkdirSync as E4,statSync as R4,unlinkSync as D4}from"node:fs";import{writeFile as L4}from"node:fs/promises";import{createRequire as V1}from"node:module";import{homedir as XW}from"node:os";import W$ from"node:path";import u from"node:process";var M4="ast-grep/ast-grep",BW="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"],T4=300000,K0=1048576,KW=500,P4={"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 j0($){try{return R4($).size>1e4}catch{return!1}}function S4(){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"}[`${u.platform}-${u.arch}`]??null}function x4(){try{return V1(import.meta.url)("@ast-grep/cli/package.json").version}catch{return BW}}function z0(){if(u.platform==="win32"){let Z=u.env.LOCALAPPDATA||u.env.APPDATA||W$.join(XW(),"AppData","Local");return W$.join(Z,"goat-chain","bin")}let W=u.env.XDG_CACHE_HOME||W$.join(XW(),".cache");return W$.join(W,"goat-chain","bin")}function G1(){return u.platform==="win32"?"ast-grep.exe":"ast-grep"}function w4(){return u.platform==="win32"?"sg.exe":"sg"}function b4(){let $=[G1(),w4()];return Array.from(new Set($))}function UW(){let $=z0();for(let W of b4()){let Q=W$.join($,W);if(J$(Q)&&j0(Q))return Q}return null}async function C4($,W){let Q=u.platform==="win32",Z=Q?"powershell":"unzip",J=Q?["-command",`Expand-Archive -Path '${$}' -DestinationPath '${W}' -Force`]:["-o",$,"-d",W],{exitCode:Y,stderr:V}=await I4(Z,J);if(Y!==0)throw Error(`zip extraction failed (exit ${Y}): ${V}
|
|
142
142
|
|
|
143
|
-
${Q?"Ensure PowerShell is available on your system.":"Please install 'unzip' (e.g., apt install unzip, brew install unzip)."}`)}async function
|
|
143
|
+
${Q?"Ensure PowerShell is available on your system.":"Please install 'unzip' (e.g., apt install unzip, brew install unzip)."}`)}async function v4($=BW){let W=`${u.platform}-${u.arch}`,Q=P4[W];if(!Q)return console.error(`[goat-chain] Unsupported platform for ast-grep: ${W}`),null;let Z=z0(),J=G1(),Y=W$.join(Z,J);if(J$(Y))return Y;let{arch:V,os:G}=Q,X=`app-${V}-${G}.zip`,H=`https://github.com/${M4}/releases/download/${$}/${X}`;console.log("[goat-chain] Downloading ast-grep binary...");try{if(!J$(Z))E4(Z,{recursive:!0});let K=await fetch(H,{redirect:"follow"});if(!K.ok)throw Error(`HTTP ${K.status}: ${K.statusText}`);let B=W$.join(Z,X),j=await K.arrayBuffer();if(await L4(B,Buffer.from(j)),await C4(B,Z),J$(B))D4(B);if(u.platform!=="win32"&&J$(Y))A4(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 OW(){let $=x4(),W=await v4($);if(W)U$=W,FW(W);return W}async function jW(){let $=UW();if($)return $;if(G$)return G$;return G$=(async()=>{try{return await OW()}finally{G$=null}})(),G$}function _W(){let $=G1(),W=UW();if(W&&j0(W))return W;try{let J=V1(import.meta.url).resolve("@ast-grep/cli/package.json"),Y=W$.dirname(J),V=W$.join(Y,$);if(J$(V)&&j0(V))return V}catch{}let Q=S4();if(Q)try{let J=V1(import.meta.url).resolve(`${Q}/package.json`),Y=W$.dirname(J),V=u.platform==="win32"?"ast-grep.exe":"ast-grep",G=W$.join(Y,V);if(J$(G)&&j0(G))return G}catch{}if(u.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)&&j0(J))return J}return null}var U$=null,G$=null;function f4(){if(U$!==null)return U$;let $=_W();if($)return U$=$,$;return"sg"}function FW($){U$=$}async function y4(){if(U$!==null&&J$(U$))return U$;if(G$)return G$;return G$=(async()=>{try{let $=_W();if($&&J$($))return U$=$,FW($),$;return await OW()}finally{G$=null}})(),G$}function I4($,W){return new Promise((Q,Z)=>{let J=zW($,W,{stdio:["ignore","pipe","pipe"]}),Y="",V="";J.stdout?.on("data",(G)=>{Y+=G.toString()}),J.stderr?.on("data",(G)=>{V+=G.toString()}),J.on("error",(G)=>{Z(G)}),J.on("close",(G)=>{Q({exitCode:G,stdout:Y,stderr:V})})})}function k4($,W,Q,Z){return new Promise((J,Y)=>{let V=!1,G=!1,X=[],H=0,K=[],B=0;console.log("[goat-chain] Spawning process:",$,W,Z??u.cwd());let j=zW($,W,{cwd:Z,stdio:["ignore","pipe","pipe"]}),z=setTimeout(()=>{V=!0,j.kill()},Q);j.stdout?.on("data",(O)=>{if(H>=K0){G=!0;return}let F=K0-H;if(O.length>F)X.push(O.subarray(0,F)),H+=F,G=!0;else X.push(O),H+=O.length}),j.stderr?.on("data",(O)=>{if(B>=K0)return;let F=K0-B;if(O.length>F)K.push(O.subarray(0,F)),B+=F;else K.push(O),B+=O.length}),j.on("error",(O)=>{clearTimeout(z),Y(O)}),j.on("close",(O)=>{clearTimeout(z),J({stdout:Buffer.concat(X).toString(),stderr:Buffer.concat(K).toString(),exitCode:O,timedOut:V,outputTruncated:G})})})}function h4($){return $.code==="ENOENT"||$.message?.includes("ENOENT")||$.message?.includes("not found")||$.message?.includes("cannot execute")||$.message?.includes("Exec format error")||$.code==="EACCES"}function g4($,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 C$($){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 z of $.globs)Q.push("--globs",z);let Z=$.paths&&$.paths.length>0?$.paths:["."];Q.push(...Z);let J=T4,Y=Boolean($.binaryPath),V=$.binaryPath??f4();if(!Y&&!J$(V)&&V!=="sg"){let z=await y4();if(z)V=z}let G;try{G=await k4(V,Q,J,$.cwd)}catch(z){let O=z;if(!Y&&h4(O)){if(await jW())return C$($);return{matches:[],totalMatches:0,truncated:!1,error:`ast-grep CLI binary not found or invalid.
|
|
144
144
|
|
|
145
145
|
Auto-download failed. Manual install options:
|
|
146
146
|
pnpm install --force # Re-run postinstall scripts
|
|
@@ -148,28 +148,30 @@ Auto-download failed. Manual install options:
|
|
|
148
148
|
cargo install ast-grep --locked
|
|
149
149
|
brew install ast-grep
|
|
150
150
|
|
|
151
|
-
See docs/TROUBLESHOOTING.md for more information.`}}return{matches:[],totalMatches:0,truncated:!1,error:`Failed to spawn ast-grep: ${
|
|
151
|
+
See docs/TROUBLESHOOTING.md for more information.`}}return{matches:[],totalMatches:0,truncated:!1,error:`Failed to spawn ast-grep: ${O.message}`}}if(G.timedOut)return{matches:[],totalMatches:0,truncated:!0,truncatedReason:"timeout",error:`Search timeout after ${J}ms`,exitCode:G.exitCode,stderr:G.stderr};if(!W){let z=G.stdout.trim(),O=G.stderr.trim();if(G.exitCode!==0){let F=O||z||`ast-grep exited with code ${G.exitCode}`;return{matches:[],totalMatches:0,truncated:G.outputTruncated,truncatedReason:G.outputTruncated?"max_output_bytes":void 0,error:F,exitCode:G.exitCode,stderr:G.stderr}}return{matches:[],totalMatches:0,truncated:G.outputTruncated,truncatedReason:G.outputTruncated?"max_output_bytes":void 0,exitCode:G.exitCode,stderr:G.stderr}}if(G.exitCode!==0&&G.stdout.trim()===""){if(G.stderr.includes("No files found"))return{matches:[],totalMatches:0,truncated:!1,exitCode:G.exitCode,stderr:G.stderr};let z=G.stderr.toLowerCase();if(!Y&&(z.includes("command not found")||z.includes("cannot execute")||z.includes("exec format error")||z.includes("permission denied"))){if(await jW())return C$($)}if(G.stderr.trim())return{matches:[],totalMatches:0,truncated:!1,error:G.stderr.trim(),exitCode:G.exitCode,stderr:G.stderr};return{matches:[],totalMatches:0,truncated:!1,exitCode:G.exitCode,stderr:G.stderr}}if(!G.stdout.trim())return{matches:[],totalMatches:0,truncated:!1,exitCode:G.exitCode,stderr:G.stderr};let X=G.outputTruncated||Buffer.byteLength(G.stdout)>=K0,H=g4(G.stdout,X);if(H===null)return{matches:[],totalMatches:0,truncated:!0,truncatedReason:"max_output_bytes",error:"Output too large and could not be parsed",exitCode:G.exitCode,stderr:G.stderr};let K=H.length,B=K>KW;return{matches:B?H.slice(0,KW):H,totalMatches:K,truncated:X||B,truncatedReason:X?"max_output_bytes":B?"max_matches":void 0,exitCode:G.exitCode,stderr:G.stderr}}import qW from"node:path";function NW($,W){if(!$||!W)return $;let Q=qW.relative(W,$);if(Q&&!Q.startsWith("..")&&!qW.isAbsolute(Q))return Q;return $}function AW($){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 m4($){let W=($.lines??$.text??"").trim();return W?` ${W}`:""}function EW($,W){if($.error)return`Error: ${$.error}`;if($.matches.length===0)return"No matches found";let Q=[];if($.truncated)Q.push(`Results truncated (${AW($)})
|
|
152
152
|
`);Q.push(`Found ${$.matches.length} match(es)${$.truncated?` (truncated from ${$.totalMatches})`:""}:
|
|
153
|
-
`);for(let Z of $.matches){let J=(Z.range?.start?.line??0)+1,Y=(Z.range?.start?.column??0)+1,V=`${
|
|
154
|
-
`)}function
|
|
153
|
+
`);for(let Z of $.matches){let J=(Z.range?.start?.line??0)+1,Y=(Z.range?.start?.column??0)+1,V=`${NW(Z.file,W)}:${J}:${Y}`;Q.push(V);let G=m4(Z);if(G)Q.push(G);Q.push("")}return Q.join(`
|
|
154
|
+
`)}function H1($,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 (${AW($)})
|
|
155
155
|
`);J.push(`${Z}${$.matches.length} replacement(s):
|
|
156
|
-
`);for(let Y of $.matches){let V=(Y.range?.start?.line??0)+1,G=(Y.range?.start?.column??0)+1,
|
|
157
|
-
`)}function
|
|
156
|
+
`);for(let Y of $.matches){let V=(Y.range?.start?.line??0)+1,G=(Y.range?.start?.column??0)+1,X=`${NW(Y.file,Q)}:${V}:${G}`;J.push(X);let H=Y.text?.trim();if(H)J.push(` ${H}`);J.push("")}if(W)J.push("Use dryRun=false to apply changes");return J.join(`
|
|
157
|
+
`)}function RW($,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 DW}from"node:fs/promises";import m$ from"node:path";import u4 from"picomatch";var TW=[{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"}],N3=TW.map(($)=>$.pattern),LW=new Map;function PW($){return $.replace(/\\/g,"/").trim()}function MW($){return $.replace(/\\/g,"/")}function p4($){let W=PW($);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 SW($){let W=[];for(let Q of $)for(let Z of p4(Q.pattern))try{let J=`${Z}:${process.platform==="win32"?"nocase":"case"}`,Y=LW.get(J);if(!Y)Y=u4(Z,{dot:!0,nocase:process.platform==="win32"}),LW.set(J,Y);W.push({rule:Q,matcher:Y})}catch{}return W}function X1($){if($===void 0)return[...TW];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 xW($,W){let Q=new Set;return((J)=>{if(!J)return;let Y=MW(J);if(Q.add(Y),Q.add(m$.posix.basename(Y)),W){let V=m$.relative(W,J);if(V)Q.add(MW(V))}})($),Array.from(Q)}function wW($,W){for(let{rule:Q,matcher:Z}of W)for(let J of $)if(Z(J))return Q;return}function K1($,W){let Q=W?.reason??"Protected file";return`Access denied: ${$}
|
|
158
|
+
This file is in the protected file list and cannot be accessed by tools.
|
|
159
|
+
Reason: ${Q}`}function x0($={}){let{blacklist:W,disabled:Q,cwd:Z}=$;if(Q)return{match:(G)=>{return},isBlocked:(G)=>!1};let J=X1(W),Y=SW(J),V=(G)=>{let X=xW(G,Z);return wW(X,Y)};return{match:V,isBlocked:(G)=>Boolean(V(G))}}async function u$($,W={}){if(W.disabled)return{isBlocked:!1};let Q=X1(W.blacklist);if(Q.length===0)return{isBlocked:!1};let Z=SW(Q),J=new Set,Y=(G)=>{for(let X of xW(G,W.cwd))J.add(X)};Y($),Y(m$.resolve($));try{let G=await DW($);Y(G)}catch{}try{let G=await DW(m$.dirname($));Y(m$.join(G,m$.basename($)))}catch{}let V=wW(Array.from(J),Z);if(!V)return{isBlocked:!1};return{isBlocked:!0,rule:V,message:K1(W.originalPath??$,V)}}function w0($={}){if($.disabled)return[];let W=X1($.blacklist);if(W.length===0)return[];let Q=new Set;for(let Z of W){let J=PW(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 p$ extends v{name="ast_grep_replace";riskLevel="high";description=`Replace code patterns across filesystem with AST-aware rewriting. Dry-run by default.
|
|
158
160
|
|
|
159
161
|
Usage notes:
|
|
160
162
|
- Use meta-variables in rewrite to preserve matched content
|
|
161
163
|
- Example: pattern='console.log($MSG)' rewrite='logger.info($MSG)'
|
|
162
|
-
- 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:[...
|
|
164
|
+
- 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??c4.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=w0({blacklist:this.fileBlacklist,disabled:this.disableBlacklist}),Y=(Q.globs?.length??0)>0||J.length>0?[...Q.globs??[],...J]:void 0,V=await C$({pattern:Q.pattern,rewrite:Q.rewrite,lang:Q.lang,paths:Q.paths,globs:Y,updateAll:!1,cwd:this.cwd,binaryPath:this.astGrepPath});if(!Z&&!V.error&&V.matches.length>0){let H=await C$({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(H.error)||H.exitCode!==null&&H.exitCode!==0){let O=`Error: ${H.error||H.stderr?.trim()||`ast-grep replace failed${H.exitCode!==null?` (exit ${H.exitCode})`:""}`}`,F={exitCode:H.exitCode??V.exitCode??null,output:O,matches:V.matches,matchCount:V.totalMatches,stderr:H.stderr?.trim()||V.stderr?.trim()||void 0,truncated:V.truncated,truncatedReason:V.truncatedReason,timedOut:V.truncatedReason==="timeout"};return{content:[{type:"text",text:O}],structuredContent:F,isError:!0}}let B=H1(V,Z,this.cwd),j={exitCode:H.exitCode??V.exitCode??null,output:B,matches:V.matches,matchCount:V.totalMatches,stderr:H.stderr?.trim()||V.stderr?.trim()||void 0,truncated:V.truncated,truncatedReason:V.truncatedReason,timedOut:V.truncatedReason==="timeout"};return{content:[{type:"text",text:B}],structuredContent:j,isError:!1}}let G=H1(V,Z,this.cwd),X={exitCode:V.exitCode??null,output:G,matches:V.matches,matchCount:V.totalMatches,stderr:V.stderr?.trim()||void 0,truncated:V.truncated,truncatedReason:V.truncatedReason,timedOut:V.truncatedReason==="timeout"};return{content:[{type:"text",text:G}],structuredContent:X,isError:Boolean(V.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 d4 from"node:process";var bW=5000;class c$ extends v{name="ast_grep_search";description=`Search code patterns across filesystem using AST-aware matching. Supports 25 languages.
|
|
163
165
|
|
|
164
166
|
Usage notes:
|
|
165
167
|
- Use meta-variables: $VAR (single node), $$$ (multiple nodes)
|
|
166
168
|
- Patterns must be complete AST nodes (valid code)
|
|
167
169
|
- For functions, include params and body: 'export async function $NAME($$$) { $$$ }' not 'export async function $NAME'
|
|
168
|
-
- 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:[...
|
|
170
|
+
- 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??d4.cwd(),this.astGrepPath=$?.astGrepPath}setCwd($){this.cwd=$}getCwd(){return this.cwd}async execute($,W){let Q=this.validateArgs($),Z=await C$({pattern:Q.pattern,lang:Q.lang,paths:Q.paths,globs:Q.globs,context:Q.context,cwd:this.cwd,binaryPath:this.astGrepPath}),J=EW(Z,this.cwd);if(Z.matches.length===0&&!Z.error){let X=RW(Q.pattern,Q.lang);if(X)J+=`
|
|
169
171
|
|
|
170
|
-
${
|
|
172
|
+
${X}`}let{truncated:Y,truncatedReason:V}=Z;if(J.length>bW){if(J=J.slice(0,bW)+`
|
|
171
173
|
|
|
172
|
-
... [output truncated due to length limit]`,Y=!0,!V)V="max_output_bytes"}let G={exitCode:Z.exitCode??null,output:J,matches:Z.matches,matchCount:Z.totalMatches,stderr:Z.stderr?.trim()||void 0,truncated:Y,truncatedReason:V,timedOut:Z.truncatedReason==="timeout"};return{content:[{type:"text",text:J}],structuredContent:G,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(!
|
|
174
|
+
... [output truncated due to length limit]`,Y=!0,!V)V="max_output_bytes"}let G={exitCode:Z.exitCode??null,output:J,matches:Z.matches,matchCount:Z.totalMatches,stderr:Z.stderr?.trim()||void 0,truncated:Y,truncatedReason:V,timedOut:Z.truncatedReason==="timeout"};return{content:[{type:"text",text:J}],structuredContent:G,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 CW}from"node:child_process";import s from"node:process";var b0=30000,vW=120000,l4=600000,H$=new Map;async function d$($){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 B0($){try{return s.kill($,0),!0}catch{return!1}}function j1(){for(let[$]of H$)if(!B0($))H$.delete($);return Array.from(H$.values())}async function z1($){let W=[];for(let[Q,Z]of H$)if(Z.category===$&&B0(Q)){if(await d$(Q))W.push(Q),H$.delete(Q)}return W}async function B1(){let $=[];for(let[W]of H$){if(B0(W)){if(await d$(W))$.push(W)}H$.delete(W)}return $}function fW($){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+.*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 v{name="Bash";riskLevel="critical";description=`Executes a given bash command in a persistent shell session with optional timeout.
|
|
173
175
|
|
|
174
176
|
Usage notes:
|
|
175
177
|
- The command argument is required.
|
|
@@ -186,44 +188,44 @@ Usage notes:
|
|
|
186
188
|
Examples:
|
|
187
189
|
- Background: { command: "npm run dev", run_in_background: true, description: "Start dev server" }
|
|
188
190
|
- Foreground: { command: "npm test", timeout: 60000, description: "Run tests" }
|
|
189
|
-
- 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=
|
|
190
|
-
${
|
|
191
|
-
`)||"[No output]"}],structuredContent:
|
|
192
|
-
... [output truncated]`:Y,
|
|
191
|
+
- 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=vW,run_in_background:J,workdir:Y}=this.validateArgs($),V=Y||this.cwd,G=this.shouldRunInBackground(Q),X,H=[];if(G&&!J)X=`⚠️ 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 z=fW(Q);if(z)H=await z1(z)}let K=J?await this.executeBackground(Q,V,W):await this.executeSync(Q,Z,V,W);if(X)K.warning=X;if(H.length>0)K.killedPids=H;let B=[];if(H.length>0)B.push(`[Killed ${H.length} existing process(es) of same type: PID ${H.join(", ")}]`),B.push("");if(K.warning)B.push(K.warning),B.push("");if(K.stdout)B.push(K.stdout);if(K.stderr)B.push(`[stderr]:
|
|
192
|
+
${K.stderr}`);if(K.timedOut){if(B.push(`[Command timed out after ${Z}ms]`),G)B.push("[Hint: This looks like a long-running process. Retry with 'run_in_background: true']")}if(K.background)B.push(`[Running in background with PID ${K.pid}]`);return{content:[{type:"text",text:B.join(`
|
|
193
|
+
`)||"[No output]"}],structuredContent:K,isError:K.exitCode!==0&&K.exitCode!==null&&!K.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+.*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=vW;if($.timeout!==void 0){if(typeof $.timeout!=="number")throw TypeError("Timeout must be a number");Q=Math.min(Math.max(0,$.timeout),l4)}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="",V="",G=!1,X=!1,H=!1,K=!1,B=!1,j=s.platform==="win32"?["/c",$]:["-c",$],z=CW(this.shell,j,{cwd:Q,env:s.env,stdio:["ignore","pipe","pipe"],detached:s.platform!=="win32"}),O=z.pid,F=()=>{if(!B&&Z?.emitEvent&&Z.toolCallId)B=!0,Z.emitEvent({type:"tool_output_start",tool_call_id:Z.toolCallId,toolName:Z.toolName||"Bash"})},E=(q,x)=>{if(Z?.emitEvent&&Z.toolCallId)F(),Z.emitEvent({type:"tool_output_delta",tool_call_id:Z.toolCallId,delta:q,isStderr:x})},_=async()=>{if(O&&!K)await d$(O)},U=()=>{H=!0,_()},N=Z?.signal;if(N)if(N.aborted)H=!0,_();else N.addEventListener("abort",U,{once:!0});let A=setTimeout(()=>{G=!0,_()},W),R=()=>{if(clearTimeout(A),N)N.removeEventListener("abort",U)};z.stdout?.on("data",(q)=>{let x=q.toString();if(Y.length+x.length>b0)Y+=x.slice(0,b0-Y.length),X=!0;else Y+=x;E(x,!1)}),z.stderr?.on("data",(q)=>{let x=q.toString();if(V.length+x.length>b0)V+=x.slice(0,b0-V.length),X=!0;else V+=x;E(x,!0)}),z.on("close",(q)=>{K=!0,R();let x=X?`${Y}
|
|
194
|
+
... [output truncated]`:Y,S=V,y=[];if(G)y.push(`Command terminated after exceeding timeout ${W}ms`);if(H)y.push("Command was aborted by user");if(y.length>0)S+=(S?`
|
|
193
195
|
|
|
194
196
|
`:"")+`<bash_metadata>
|
|
195
|
-
`+
|
|
197
|
+
`+y.join(`
|
|
196
198
|
`)+`
|
|
197
|
-
</bash_metadata>`;J({exitCode:q,stdout:
|
|
199
|
+
</bash_metadata>`;J({exitCode:q,stdout:x,stderr:S,truncated:X,timedOut:G,background:!1})}),z.on("error",(q)=>{K=!0,R(),J({exitCode:1,stdout:"",stderr:`Failed to execute command: ${q.message}`,truncated:!1,timedOut:!1,background:!1})})})}executeBackground($,W,Q){return new Promise((Z)=>{let J=s.platform==="win32"?["/c",$]:["-c",$],Y=CW(this.shell,J,{cwd:W,env:s.env,stdio:["ignore","pipe","pipe"],detached:s.platform!=="win32"}),V=Y.pid,G=!1,X=()=>{if(!G&&Q?.emitEvent&&Q.toolCallId)G=!0,Q.emitEvent({type:"tool_output_start",tool_call_id:Q.toolCallId,toolName:Q.toolName||"Bash"})},H=(z,O)=>{if(Q?.emitEvent&&Q.toolCallId)X(),Q.emitEvent({type:"tool_output_delta",tool_call_id:Q.toolCallId,delta:z,isStderr:O})},K="",B="",j=2000;if(Y.stdout?.on("data",(z)=>{let O=z.toString();if(K.length<1000)K+=O;H(O,!1)}),Y.stderr?.on("data",(z)=>{let O=z.toString();if(B.length<1000)B+=O;H(O,!0)}),V){let z=fW($);H$.set(V,{pid:V,command:$,startedAt:Date.now(),process:Y,category:z}),Y.on("exit",()=>{H$.delete(V)})}setTimeout(()=>{Y.unref();let z=[];if(z.push(`Command started in background with PID ${V}`),K.trim())z.push(`
|
|
198
200
|
[Initial output]:
|
|
199
|
-
${
|
|
201
|
+
${K.trim()}`);if(B.trim())z.push(`
|
|
200
202
|
[Initial stderr]:
|
|
201
|
-
${B.trim()}`);Z({exitCode:null,stdout:z.join(""),stderr:"",truncated:!1,timedOut:!1,background:!0,pid:V})},j)})}async killProcess($){let W=await
|
|
203
|
+
${B.trim()}`);Z({exitCode:null,stdout:z.join(""),stderr:"",truncated:!1,timedOut:!1,background:!0,pid:V})},j)})}async killProcess($){let W=await d$($);if(W)H$.delete($);return W}getRunningProcesses(){return j1()}async killAllProcesses(){return B1()}}import{readFile as i4,stat as r4,writeFile as n4}from"node:fs/promises";import U1 from"node:path";import o4 from"node:process";var yW=0,a4=0.3;function IW($,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,V)=>J===0?V:V===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 s4=function*($,W){yield W},t4=function*($,W){let Q=$.split(`
|
|
202
204
|
`),Z=W.split(`
|
|
203
|
-
`);if(Z[Z.length-1]==="")Z.pop();for(let J=0;J<=Q.length-Z.length;J++){let Y=!0;for(let V=0;V<Z.length;V++){let G=Q[J+V].trim(),
|
|
205
|
+
`);if(Z[Z.length-1]==="")Z.pop();for(let J=0;J<=Q.length-Z.length;J++){let Y=!0;for(let V=0;V<Z.length;V++){let G=Q[J+V].trim(),X=Z[V].trim();if(G!==X){Y=!1;break}}if(Y){let V=0;for(let X=0;X<J;X++)V+=Q[X].length+1;let G=V;for(let X=0;X<Z.length;X++)if(G+=Q[J+X].length,X<Z.length-1)G+=1;yield $.substring(V,G)}}},e4=function*($,W){let Q=$.split(`
|
|
204
206
|
`),Z=W.split(`
|
|
205
|
-
`);if(Z.length<3)return;if(Z[Z.length-1]==="")Z.pop();let J=Z[0].trim(),Y=Z[Z.length-1].trim(),V=Z.length,G=[];for(let
|
|
206
|
-
`);for(let V=0;V<J.length;V++){let G=J[V];if(Q(G)===Z)yield G;else if(Q(G).includes(Z)){let H=W.trim().split(/\s+/);if(H.length>0){let
|
|
207
|
+
`);if(Z.length<3)return;if(Z[Z.length-1]==="")Z.pop();let J=Z[0].trim(),Y=Z[Z.length-1].trim(),V=Z.length,G=[];for(let K=0;K<Q.length;K++){if(Q[K].trim()!==J)continue;for(let B=K+2;B<Q.length;B++)if(Q[B].trim()===Y){G.push({startLine:K,endLine:B});break}}if(G.length===0)return;if(G.length===1){let{startLine:K,endLine:B}=G[0],j=B-K+1,z=0,O=Math.min(V-2,j-2);if(O>0)for(let F=1;F<V-1&&F<j-1;F++){let E=Q[K+F].trim(),_=Z[F].trim(),U=Math.max(E.length,_.length);if(U===0)continue;let N=IW(E,_);if(z+=(1-N/U)/O,z>=yW)break}else z=1;if(z>=yW){let F=0;for(let _=0;_<K;_++)F+=Q[_].length+1;let E=F;for(let _=K;_<=B;_++)if(E+=Q[_].length,_<B)E+=1;yield $.substring(F,E)}return}let X=null,H=-1;for(let K of G){let{startLine:B,endLine:j}=K,z=j-B+1,O=0,F=Math.min(V-2,z-2);if(F>0){for(let E=1;E<V-1&&E<z-1;E++){let _=Q[B+E].trim(),U=Z[E].trim(),N=Math.max(_.length,U.length);if(N===0)continue;let A=IW(_,U);O+=1-A/N}O/=F}else O=1;if(O>H)H=O,X=K}if(H>=a4&&X){let{startLine:K,endLine:B}=X,j=0;for(let O=0;O<K;O++)j+=Q[O].length+1;let z=j;for(let O=K;O<=B;O++)if(z+=Q[O].length,O<B)z+=1;yield $.substring(j,z)}},$8=function*($,W){let Q=(V)=>V.replace(/\s+/g," ").trim(),Z=Q(W),J=$.split(`
|
|
208
|
+
`);for(let V=0;V<J.length;V++){let G=J[V];if(Q(G)===Z)yield G;else if(Q(G).includes(Z)){let H=W.trim().split(/\s+/);if(H.length>0){let K=H.map((B)=>B.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")).join("\\s+");try{let B=new RegExp(K),j=G.match(B);if(j)yield j[0]}catch{}}}}let Y=W.split(`
|
|
207
209
|
`);if(Y.length>1)for(let V=0;V<=J.length-Y.length;V++){let G=J.slice(V,V+Y.length);if(Q(G.join(`
|
|
208
210
|
`))===Z)yield G.join(`
|
|
209
|
-
`)}},
|
|
210
|
-
`),
|
|
211
|
+
`)}},W8=function*($,W){let Q=(V)=>{let G=V.split(`
|
|
212
|
+
`),X=G.filter((K)=>K.trim().length>0);if(X.length===0)return V;let H=Math.min(...X.map((K)=>{let B=K.match(/^(\s*)/);return B?B[1].length:0}));return G.map((K)=>K.trim().length===0?K:K.slice(H)).join(`
|
|
211
213
|
`)},Z=Q(W),J=$.split(`
|
|
212
214
|
`),Y=W.split(`
|
|
213
215
|
`);for(let V=0;V<=J.length-Y.length;V++){let G=J.slice(V,V+Y.length).join(`
|
|
214
|
-
`);if(Q(G)===Z)yield G}},
|
|
216
|
+
`);if(Q(G)===Z)yield G}},Q8=function*($,W){let Q=(V)=>{return V.replace(/\\([ntr'"`\\\n$])/g,(G,X)=>{switch(X){case"n":return`
|
|
215
217
|
`;case"t":return"\t";case"r":return"\r";case"'":return"'";case'"':return'"';case"`":return"`";case"\\":return"\\";case`
|
|
216
218
|
`:return`
|
|
217
219
|
`;case"$":return"$";default:return G}})},Z=Q(W);if($.includes(Z))yield Z;let J=$.split(`
|
|
218
220
|
`),Y=Z.split(`
|
|
219
221
|
`);for(let V=0;V<=J.length-Y.length;V++){let G=J.slice(V,V+Y.length).join(`
|
|
220
|
-
`);if(Q(G)===Z)yield G}},
|
|
222
|
+
`);if(Q(G)===Z)yield G}},Z8=function*($,W){let Q=W.trim();if(Q===W)return;if($.includes(Q))yield Q;let Z=$.split(`
|
|
221
223
|
`),J=W.split(`
|
|
222
224
|
`);for(let Y=0;Y<=Z.length-J.length;Y++){let V=Z.slice(Y,Y+J.length).join(`
|
|
223
|
-
`);if(V.trim()===Q)yield V}},
|
|
225
|
+
`);if(V.trim()===Q)yield V}},J8=function*($,W){let Q=W.split(`
|
|
224
226
|
`);if(Q.length<3)return;if(Q[Q.length-1]==="")Q.pop();let Z=$.split(`
|
|
225
|
-
`),J=Q[0].trim(),Y=Q[Q.length-1].trim();for(let V=0;V<Z.length;V++){if(Z[V].trim()!==J)continue;for(let G=V+2;G<Z.length;G++)if(Z[G].trim()===Y){let
|
|
226
|
-
`);if(
|
|
227
|
+
`),J=Q[0].trim(),Y=Q[Q.length-1].trim();for(let V=0;V<Z.length;V++){if(Z[V].trim()!==J)continue;for(let G=V+2;G<Z.length;G++)if(Z[G].trim()===Y){let X=Z.slice(V,G+1),H=X.join(`
|
|
228
|
+
`);if(X.length===Q.length){let K=0,B=0;for(let j=1;j<X.length-1;j++){let z=X[j].trim(),O=Q[j].trim();if(z.length>0||O.length>0){if(B++,z===O)K++}}if(B===0||K/B>=0.5){yield H;break}}break}}};class i$ extends v{name="Edit";riskLevel="high";description=`Performs exact string replacements in files.
|
|
227
229
|
|
|
228
230
|
Usage notes:
|
|
229
231
|
- When editing, preserve the exact indentation (tabs/spaces) from the original file
|
|
@@ -231,10 +233,10 @@ Usage notes:
|
|
|
231
233
|
- Use replace_all for replacing/renaming strings across the entire file
|
|
232
234
|
- old_string and new_string must be different
|
|
233
235
|
- If exact matching fails, the tool tries normalized variants (trimmed lines, whitespace, indentation, escapes)
|
|
234
|
-
- 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;constructor($){super();this.cwd=$?.cwd??
|
|
236
|
+
- 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??o4.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($),V=U1.isAbsolute(Q)?Q:U1.resolve(this.cwd,Q),G=await u$(V,{cwd:this.cwd,blacklist:this.fileBlacklist,disabled:this.disableBlacklist,originalPath:Q});if(G.isBlocked)return I(G.message??`Access denied: ${Q}`);try{if((await r4(V)).isDirectory())return I(`Path is a directory, not a file: ${V}`)}catch(z){if(z.code==="ENOENT")return I(`File not found: ${V}`);throw z}let X=await i4(V,"utf-8"),H=this.replaceWithFallback(X,Z,J,Y??!1);if(H.kind==="not_found")return I(`old_string not found in file: ${V}
|
|
235
237
|
|
|
236
238
|
Searched for (including normalized variants):
|
|
237
|
-
${this.truncateForError(Z)}`);if(
|
|
239
|
+
${this.truncateForError(Z)}`);if(H.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:B}=H;await n4(V,K,"utf-8");let j={success:!0,replacements:B,filePath:V,message:`Successfully replaced ${B} occurrence${B>1?"s":""} in ${U1.basename(V)}`};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=[s4,t4,e4,$8,W8,Q8,Z8,J8];for(let V of Y)for(let G of V($,W)){if(!G)continue;let X=this.countOccurrences($,G);if(X===0)continue;if(Z)return{kind:"ok",content:$.split(G).join(Q),replacements:X};if(X===1){let H=$.indexOf(G);return{kind:"ok",content:$.slice(0,H)+Q+$.slice(H+G.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 Y8,stat as kW}from"node:fs/promises";import C0 from"node:path";import V8 from"node:process";var O1=1000,G8=20;function H8($){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((V)=>X8(V)).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 X8($){return $.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}class r$ extends v{name="Glob";description=`Fast file pattern matching tool that works with any codebase size.
|
|
238
240
|
|
|
239
241
|
Usage notes:
|
|
240
242
|
- Supports glob patterns like "**/*.js" or "src/**/*.ts"
|
|
@@ -247,13 +249,13 @@ Supported patterns:
|
|
|
247
249
|
- \`**\` matches any sequence of characters including path separator
|
|
248
250
|
- \`?\` matches any single character
|
|
249
251
|
- \`{a,b}\` matches either a or b
|
|
250
|
-
- \`[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;constructor($){super();this.cwd=$?.cwd??
|
|
251
|
-
${
|
|
252
|
-
`)}`:`No files found matching pattern: ${Q}`}],structuredContent:
|
|
252
|
+
- \`[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??V8.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 kW(J)).isDirectory())return I(`Path is not a directory: ${J}`)}catch(z){if(z.code==="ENOENT")return I(`Directory not found: ${J}`);throw z}let Y=Q;if(!Q.startsWith("**/")&&!Q.startsWith("/")&&!Q.startsWith("./"))Y=`**/${Q}`;let V=H8(Y),G=[],X=x0({cwd:this.cwd,blacklist:this.fileBlacklist,disabled:this.disableBlacklist});await this.walkDirectory(J,"",V,G,0,X),G.sort((z,O)=>O.mtime-z.mtime);let H=G.length>O1,K=G.slice(0,O1).map((z)=>z.path),B={files:K,totalMatches:G.length,truncated:H};return{content:[{type:"text",text:K.length>0?`Found ${G.length} file${G.length!==1?"s":""}${H?` (showing first ${O1})`:""}:
|
|
253
|
+
${K.join(`
|
|
254
|
+
`)}`:`No files found matching pattern: ${Q}`}],structuredContent:B}}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>G8)return;let V=W?C0.join($,W):$,G;try{G=await Y8(V,{withFileTypes:!0})}catch{return}for(let X of G){if(X.name.startsWith(".")||X.name==="node_modules")continue;let H=C0.join(V,X.name);if(Y.isBlocked(H))continue;let K=W?`${W}/${X.name}`:X.name;if(X.isDirectory())await this.walkDirectory($,K,Q,Z,J+1,Y);else if(X.isFile()){if(Q.test(K))try{let B=await kW(H);Z.push({path:K,mtime:B.mtimeMs})}catch{}}}}}import{Buffer as K8}from"node:buffer";import{spawn as F1}from"node:child_process";import{chmodSync as j8,existsSync as O0,mkdirSync as z8,statSync as B8}from"node:fs";import{copyFile as U8,mkdtemp as O8,readdir as _8,readFile as F8,rm as hW,stat as q8,writeFile as N8}from"node:fs/promises";import t from"node:path";import D$ from"node:process";import gW from"fast-glob";import A8 from"picomatch";var R$=5000,_1=60000,E8="BurntSushi/ripgrep",mW="latest",R8={"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 q1($){try{return B8($).size>1e4}catch{return!1}}function uW(){return D$.platform==="win32"?"rg.exe":"rg"}function N1(){let $=t.join(z0(),uW());return O0($)&&q1($)?$:null}function D8($){return $.code==="ENOENT"||$.message?.includes("ENOENT")||$.message?.includes("not found")}function pW($,W){return new Promise((Q,Z)=>{let J=F1($,W,{stdio:["ignore","pipe","pipe"]}),Y="",V="";J.stdout?.on("data",(G)=>{Y+=G.toString()}),J.stderr?.on("data",(G)=>{V+=G.toString()}),J.on("error",(G)=>{Z(G)}),J.on("close",(G)=>{Q({exitCode:G,stdout:Y,stderr:V})})})}async function L8($,W){let Z=["-command",`Expand-Archive -Path '${$}' -DestinationPath '${W}' -Force`],{exitCode:J,stderr:Y}=await pW("powershell",Z);if(J!==0)throw Error(`zip extraction failed (exit ${J}): ${Y}
|
|
253
255
|
|
|
254
|
-
Ensure PowerShell is available on your system.`)}async function
|
|
256
|
+
Ensure PowerShell is available on your system.`)}async function M8($,W){let{exitCode:Q,stderr:Z}=await pW("tar",["-xzf",$,"-C",W]);if(Q!==0)throw Error(`tar extraction failed (exit ${Q}): ${Z}
|
|
255
257
|
|
|
256
|
-
Please install 'tar' (e.g., apt install tar, brew install gnu-tar).`)}async function
|
|
258
|
+
Please install 'tar' (e.g., apt install tar, brew install gnu-tar).`)}async function cW($,W){let Q=await _8($,{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 cW(J,W);if(Y)return Y}}return null}var U0=null,v0=null,f0=null;async function T8($){if($!=="latest")return $;if(f0)return f0;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 f0=Y.startsWith("v")?Y.slice(1):Y,f0}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 P8($=mW){let W=`${D$.platform}-${D$.arch}`,Q=R8[W];if(!Q)return console.error(`[goat-chain] Unsupported platform for ripgrep: ${W}`),null;let Z=z0(),J=uW(),Y=t.join(Z,J);if(O0(Y)&&q1(Y))return Y;let V=await T8($);if(!V)return null;let{arch:G,os:X}=Q,H=D$.platform==="win32"?"zip":"tar.gz",K=`ripgrep-${V}-${G}-${X}.${H}`,B=`https://github.com/${E8}/releases/download/${V}/${K}`;console.log("[goat-chain] Downloading ripgrep binary...");let j=null,z=t.join(Z,K);try{if(!O0(Z))z8(Z,{recursive:!0});let O=new AbortController,F=setTimeout(()=>O.abort(),120000);try{let _=await fetch(B,{redirect:"follow",signal:O.signal});if(!_.ok)throw Error(`HTTP ${_.status}: ${_.statusText}`);let U=await _.arrayBuffer();await N8(z,K8.from(U))}finally{clearTimeout(F)}if(j=await O8(t.join(Z,"ripgrep-")),H==="zip")await L8(z,j);else await M8(z,j);let E=await cW(j,J);if(!E)throw Error("ripgrep binary not found in extracted archive.");if(await U8(E,Y),D$.platform!=="win32"&&O0(Y))j8(Y,493);if(!q1(Y))throw Error("Downloaded ripgrep binary failed validation.");return console.log("[goat-chain] ripgrep binary ready."),Y}catch(O){return console.error(`[goat-chain] Failed to download ripgrep: ${O instanceof Error?O.message:O}`),null}finally{if(await hW(z,{force:!0}).catch(()=>{}),j)await hW(j,{recursive:!0,force:!0}).catch(()=>{})}}async function S8($=mW){let W=N1();if(W)return W;return P8($)}async function x8(){if(U0!==null&&O0(U0))return U0;if(v0)return v0;return v0=(async()=>{let $=N1();if($)return U0=$,$;let W=await S8();if(W)return U0=W,W;return null})(),v0}class n$ extends v{name="Grep";description=`A powerful search tool built on ripgrep.
|
|
257
259
|
|
|
258
260
|
Usage notes:
|
|
259
261
|
- Supports full regex syntax (e.g., "log.*Error", "function\\s+\\w+")
|
|
@@ -261,49 +263,49 @@ Usage notes:
|
|
|
261
263
|
- Output modes: "content" shows matching lines, "files_with_matches" shows only file paths (default), "count" shows match counts
|
|
262
264
|
- Pattern syntax: Uses ripgrep (not grep) - literal braces need escaping (use \`interface\\{\\}\` to find \`interface{}\` in Go code)
|
|
263
265
|
- Multiline matching: By default patterns match within single lines only. For cross-line patterns, use multiline: true
|
|
264
|
-
- 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;allowDownload;constructor($){super();this.cwd=$?.cwd??D$.cwd(),this.rgPath=$?.rgPath??"rg",this.allowDownload=$?.allowDownload===!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+=`
|
|
266
|
+
- 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??D$.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+=`
|
|
265
267
|
[Search timed out]`;if(J.matchCount!==void 0)Y=`Found ${J.matchCount} match${J.matchCount!==1?"es":""}
|
|
266
|
-
${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);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="",Y=!1,V=!1,G=!1,
|
|
267
|
-
[stderr]: ${
|
|
268
|
-
`).filter((A)=>A.trim()),_=W.offset??0,U=W.head_limit??
|
|
269
|
-
`)}let
|
|
270
|
-
`).filter((
|
|
271
|
-
... [output truncated]`:
|
|
272
|
-
`)
|
|
273
|
-
`);if(
|
|
274
|
-
`).filter((
|
|
275
|
-
... [output truncated]`:
|
|
276
|
-
[stderr]: ${
|
|
277
|
-
`).filter((
|
|
278
|
-
`)}let B;if(V==="count")B=
|
|
279
|
-
`).filter((j)=>j.trim()).reduce((j,z)=>{let
|
|
280
|
-
... [output truncated]`:
|
|
268
|
+
${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=w0({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="",Y=!1,V=!1,G=!1,X=null,H=!1;if(this.rgPath==="rg"){let z=N1();if(z)this.rgPath=z}let K=F1(this.rgPath,$,{cwd:this.cwd,env:D$.env,stdio:["ignore","pipe","pipe"]}),B=(z)=>{if(G)return;G=!0,Z(z)},j=setTimeout(()=>{Y=!0,K.kill("SIGTERM"),setTimeout(()=>{if(!K.killed)K.kill("SIGKILL")},5000)},_1);K.stdout?.on("data",(z)=>{let O=z.toString();if(J.length+O.length>R$)J+=O.slice(0,R$-J.length),V=!0,clearTimeout(j),K.kill("SIGTERM");else J+=O}),K.stderr?.on("data",(z)=>{let O=z.toString();if(O.includes("error:"))J+=`
|
|
269
|
+
[stderr]: ${O}`}),K.on("close",(z)=>{if(G)return;if(clearTimeout(j),X||z!==null&&z<0){if(!H)this.runJsSearch(W).then(B);return}let O=J;if(W.offset||W.head_limit){let E=J.split(`
|
|
270
|
+
`).filter((A)=>A.trim()),_=W.offset??0,U=W.head_limit??E.length;O=E.slice(_,_+U).join(`
|
|
271
|
+
`)}let F;if(W.output_mode==="count")F=O.split(`
|
|
272
|
+
`).filter((E)=>E.trim()).reduce((E,_)=>{let U=_.match(/:(\d+)$/);return E+(U?Number.parseInt(U[1],10):0)},0);B({exitCode:z,output:V?`${O}
|
|
273
|
+
... [output truncated]`:O,truncated:V,timedOut:Y,matchCount:F})}),K.on("error",(z)=>{if(G)return;X=z,H=!0,clearTimeout(j);let O=z;if(this.allowDownload&&!Q&&D8(O)){(async()=>{try{let E=await x8();if(E){this.rgPath=E;let _=await this.runRipgrep($,W,!0);B(_);return}}catch{}let F=await this.runJsSearch(W);B(F)})();return}this.runJsSearch(W).then(B)})})}async runJsSearch($){let W=!1,Q=!1,Z=setTimeout(()=>{W=!0},_1),J=$.output_mode??"files_with_matches",Y=$["-B"]??0,V=$["-A"]??0,G=$["-C"]??0;if(G>0)Y=Math.max(Y,G),V=Math.max(V,G);let X=Boolean($["-i"]),H=Boolean($.multiline),K=`${X?"i":""}${H?"sm":""}`,B=null,j=null;try{if(H)j=new RegExp($.pattern,`${K}g`);else B=new RegExp($.pattern,K)}catch(D){return clearTimeout(Z),{exitCode:2,engine:"js",output:`Invalid regex pattern: ${D.message}`,truncated:!1,timedOut:!1}}let z=$.path??".",O=t.isAbsolute(z)?z:t.resolve(this.cwd,z),F=t.isAbsolute(z),E=x0({cwd:this.cwd,blacklist:this.fileBlacklist,disabled:this.disableBlacklist}),_;try{_=await q8(O)}catch{return clearTimeout(Z),{exitCode:2,engine:"js",output:`Search path not found: ${z}`,truncated:!1,timedOut:!1}}let U=[],N=gW.default??gW;if(typeof N!=="function")return clearTimeout(Z),this.runSystemGrep($);let A=O;if(_.isFile()){let D=E.match(O);if(D)return clearTimeout(Z),{exitCode:2,engine:"js",output:K1(z,D),truncated:!1,timedOut:!1};U=[O],A=t.dirname(O)}else if(_.isDirectory()){A=O;try{U=await N("**/*",{cwd:A,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: ${z}`,truncated:!1,timedOut:!1};U.sort();let R=[],q=!1,x=0,S=(D)=>{let M=D.length+1;if(x+M>R$)return Q=!0,!1;return R.push(D),x+=M,!0},y={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=(D)=>{if(!$.type)return!0;let M=$.type.toLowerCase(),w=y[M]??[M.startsWith(".")?M:`.${M}`],P=D.toLowerCase();return w.some((h)=>P.endsWith(h))},C=(D)=>{if(F)return D;return t.relative(this.cwd,D)||t.basename(D)},k=$.glob,l=A8.isMatch,p=J==="content"?$["-n"]!==!1:!1;for(let D of U){if(W)break;if(x>=R$){Q=!0;break}if(!L(D))continue;if(k&&l&&!l(t.basename(D),k))continue;if(E.isBlocked(D))continue;let M="";try{M=await F8(D,"utf-8")}catch{continue}if(!M||M.includes("\x00"))continue;let w=C(D);if(!H){let c=M.split(/\r?\n/),g=new Set;for(let Q$=0;Q$<c.length;Q$++)if(B.test(c[Q$]))g.add(Q$+1);if(g.size===0)continue;q=!0;let a=g.size;if(J==="files_with_matches"){if(!S(w))break;continue}if(J==="count"){if(!S(`${w}:${a}`))break;continue}let V$=new Set(g);if(Y>0||V>0){let Q$=c.length;for(let Z$ of g){let Z0=Math.max(1,Z$-Y),U2=Math.min(Q$,Z$+V);for(let c0=Z0;c0<=U2;c0++)V$.add(c0)}}let _$=!1;for(let Q$ of Array.from(V$).sort((Z$,Z0)=>Z$-Z0)){let Z$=c[Q$-1]??"",Z0=p?`${w}:${Q$}:${Z$}`:`${w}:${Z$}`;if(!S(Z0)){_$=!0;break}}if(_$)break;continue}let P=M.split(/\r?\n/),h=[0];for(let c=0;c<M.length;c++)if(M[c]===`
|
|
274
|
+
`)h.push(c+1);let X$=(c)=>{let g=0,a=h.length-1;while(g<=a){let V$=Math.floor((g+a)/2);if(h[V$]<=c)g=V$+1;else a=V$-1}return Math.max(a+1,1)};j.lastIndex=0;let Y$=new Set;for(let c of M.matchAll(j)){let g=c.index??0,a=c[0]?.length??0,V$=Math.max(g,g+a-1),_$=X$(g),Q$=X$(V$);for(let Z$=_$;Z$<=Q$;Z$++)Y$.add(Z$)}if(Y$.size===0)continue;q=!0;let M$=Y$.size;if(J==="files_with_matches"){if(!S(w))break;continue}if(J==="count"){if(!S(`${w}:${M$}`))break;continue}let Q0=new Set(Y$);if(Y>0||V>0){let c=P.length;for(let g of Y$){let a=Math.max(1,g-Y),V$=Math.min(c,g+V);for(let _$=a;_$<=V$;_$++)Q0.add(_$)}}let N0=!1;for(let c of Array.from(Q0).sort((g,a)=>g-a)){let g=P[c-1]??"",a=p?`${w}:${c}:${g}`:`${w}:${g}`;if(!S(a)){N0=!0;break}}if(N0)break}clearTimeout(Z);let o=R;if($.offset||$.head_limit){let D=R.filter((P)=>P.trim()),M=$.offset??0,w=$.head_limit??D.length;o=D.slice(M,M+w)}let e=o.join(`
|
|
275
|
+
`);if(e.length>R$)e=e.slice(0,R$),Q=!0;let i;if(J==="count")i=e.split(`
|
|
276
|
+
`).filter((D)=>D.trim()).reduce((D,M)=>{let w=M.split(":").pop(),P=w?Number.parseInt(w,10):Number.NaN;return D+(Number.isFinite(P)?P:0)},0);return{exitCode:q?0:1,engine:"js",output:Q?`${e}
|
|
277
|
+
... [output truncated]`:e,truncated:Q,timedOut:W,matchCount:i}}runSystemGrep($){return new Promise((W)=>{let Q="",Z=!1,J=!1,Y=[];Y.push("-R","-E","-I");let V=$.output_mode??"files_with_matches";if(V==="files_with_matches")Y.push("-l");else if(V==="count")Y.push("-c");else Y.push("-n");if(V==="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 G=F1("grep",Y,{cwd:this.cwd,env:D$.env,stdio:["ignore","pipe","pipe"]}),X=setTimeout(()=>{Z=!0,G.kill("SIGTERM"),setTimeout(()=>{if(!G.killed)G.kill("SIGKILL")},5000)},_1);G.stdout?.on("data",(H)=>{let K=H.toString();if(Q.length+K.length>R$)Q+=K.slice(0,R$-Q.length),J=!0,clearTimeout(X),G.kill("SIGTERM");else Q+=K}),G.stderr?.on("data",(H)=>{let K=H.toString();if(K.trim())Q+=`
|
|
278
|
+
[stderr]: ${K}`}),G.on("close",(H)=>{clearTimeout(X);let K=Q;if($.offset||$.head_limit){let j=Q.split(`
|
|
279
|
+
`).filter((F)=>F.trim()),z=$.offset??0,O=$.head_limit??j.length;K=j.slice(z,z+O).join(`
|
|
280
|
+
`)}let B;if(V==="count")B=K.split(`
|
|
281
|
+
`).filter((j)=>j.trim()).reduce((j,z)=>{let O=z.split(":").pop(),F=O?Number.parseInt(O,10):Number.NaN;return j+(Number.isFinite(F)?F:0)},0);W({exitCode:H,engine:"grep",output:J?`${K}
|
|
282
|
+
... [output truncated]`:K,truncated:J,timedOut:Z,matchCount:B})}),G.on("error",(H)=>{clearTimeout(X),W({exitCode:1,engine:"grep",output:`Failed to execute grep: ${H.message}.`,truncated:!1,timedOut:!1})})})}}import{readFile as y0,stat as w8}from"node:fs/promises";import v$ from"node:path";import b8 from"node:process";var dW=2000,A1=2000,C8=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"]),v8={".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 o$ extends v{name="Read";_cwd;_allowedDirectory;_fileBlacklist;_disableBlacklist;constructor($){super();this._cwd=$?.cwd??b8.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.
|
|
281
283
|
|
|
282
284
|
Usage notes:
|
|
283
285
|
- Current working directory: ${this._cwd}
|
|
284
286
|
- Supports both absolute paths and relative paths (relative to cwd)
|
|
285
287
|
- IMPORTANT: Do NOT guess file paths. Use Glob to search for files first if unsure.
|
|
286
|
-
- By default, it reads up to ${
|
|
288
|
+
- By default, it reads up to ${dW} lines starting from the beginning
|
|
287
289
|
- You can optionally specify a line offset and limit for large files
|
|
288
|
-
- Any lines longer than ${
|
|
290
|
+
- Any lines longer than ${A1} characters will be truncated
|
|
289
291
|
- Results are returned with line numbers (like cat -n format)
|
|
290
292
|
- Can read images (PNG, JPG, etc.), PDFs, and Jupyter notebooks
|
|
291
293
|
- You can call multiple tools in parallel to read multiple files at once`;if(this._allowedDirectory)return`${$}
|
|
292
294
|
- IMPORTANT: Files can ONLY be read from within: ${this._allowedDirectory}
|
|
293
|
-
- 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=
|
|
295
|
+
- 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=v$.isAbsolute(Q)?Q:v$.resolve(this._cwd,Q);if(this._allowedDirectory){let j=v$.resolve(this._allowedDirectory),z=v$.resolve(Y);if(!z.startsWith(j+v$.sep)&&z!==j)return I(`Access denied: ${Q}
|
|
294
296
|
Files can only be read from within: ${this._allowedDirectory}
|
|
295
|
-
Please use a path like: ${this._allowedDirectory}/<filename>`)}let V;try{
|
|
297
|
+
Please use a path like: ${this._allowedDirectory}/<filename>`)}let V=await u$(Y,{cwd:this._cwd,blacklist:this._fileBlacklist,disabled:this._disableBlacklist,originalPath:Q});if(V.isBlocked)return I(V.message??`Access denied: ${Q}`);let G;try{G=await w8(Y)}catch(j){if(j.code==="ENOENT")return I(`File not found: ${Y}`);throw j}if(G.isDirectory())return I(`Path is a directory, not a file: ${Y}. Use ls command via Bash tool to read directories.`);let X=v$.extname(Y).toLowerCase(),H=C8.has(X),K=v8[X],B;if(H){if(B=await this.handleBinaryFile(Y,G.size,K),K?.startsWith("image/"))return{content:[{type:"image",data:(await y0(Y)).toString("base64"),mimeType:K}],structuredContent:B}}else if(X===".ipynb")B=await this.handleJupyterNotebook(Y,G.size,Z,J);else B=await this.handleTextFile(Y,G.size,Z,J);return{content:[{type:"text",text:B.content}],structuredContent:B}}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 y0($)).toString("base64");return{content:`[Binary file: ${v$.basename($)}]
|
|
296
298
|
Size: ${this.formatSize(W)}
|
|
297
299
|
MIME type: ${Q??"unknown"}
|
|
298
300
|
Base64 encoded content:
|
|
299
|
-
${J}`,totalLines:1,linesReturned:1,startLine:1,truncated:!1,fileSize:W,isBinary:!0,mimeType:Q}}async handleJupyterNotebook($,W,Q,Z){let J=await
|
|
300
|
-
`)),H.outputs&&H.outputs.length>0){G.push("--- Output ---");for(let z of H.outputs)if(z.text){let
|
|
301
|
-
`))}else if(z.data){if(z.data["text/plain"]){let
|
|
302
|
-
`))}}}G.push("")}return this.formatOutput(G,W,Q,Z)}async handleTextFile($,W,Q,Z){let J=await
|
|
303
|
-
`);return this.formatOutput(Y,W,Q,Z)}formatOutput($,W,Q,Z){let J=$.length,Y=Q??1,V=Z??
|
|
304
|
-
`),totalLines:J,linesReturned:H.length,startLine:Y,truncated:
|
|
301
|
+
${J}`,totalLines:1,linesReturned:1,startLine:1,truncated:!1,fileSize:W,isBinary:!0,mimeType:Q}}async handleJupyterNotebook($,W,Q,Z){let J=await y0($,"utf-8"),Y;try{Y=JSON.parse(J)}catch{throw Error(`Invalid Jupyter notebook format: ${$}`)}let V=Y.cells||[],G=[];for(let X=0;X<V.length;X++){let H=V[X],K=X+1,B=H.cell_type||"unknown";G.push(`--- Cell ${K} (${B}) ---`);let j=Array.isArray(H.source)?H.source.join(""):H.source||"";if(G.push(...j.split(`
|
|
302
|
+
`)),H.outputs&&H.outputs.length>0){G.push("--- Output ---");for(let z of H.outputs)if(z.text){let O=Array.isArray(z.text)?z.text.join(""):z.text;G.push(...O.split(`
|
|
303
|
+
`))}else if(z.data){if(z.data["text/plain"]){let O=Array.isArray(z.data["text/plain"])?z.data["text/plain"].join(""):z.data["text/plain"];G.push(...O.split(`
|
|
304
|
+
`))}}}G.push("")}return this.formatOutput(G,W,Q,Z)}async handleTextFile($,W,Q,Z){let J=await y0($,"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(`
|
|
305
|
+
`);return this.formatOutput(Y,W,Q,Z)}formatOutput($,W,Q,Z){let J=$.length,Y=Q??1,V=Z??dW,G=Y-1,X=Math.min(G+V,J),H=$.slice(G,X),K=!1;return{content:H.map((j,z)=>{let O=Y+z,F=String(O).padStart(6," "),E=j;if(j.length>A1)E=`${j.slice(0,A1)}... [truncated]`,K=!0;return`${F}|${E}`}).join(`
|
|
306
|
+
`),totalLines:J,linesReturned:H.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 v{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(!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},V=Y.background?" (running in background)":"",G=`Task "${Q.description}" started with subagent ${Z}${V}`,X=Y.background?null:this.formatTaskData(J);return{content:[{type:"text",text:`Result:${G}
|
|
305
307
|
|
|
306
|
-
${
|
|
308
|
+
${X}`}],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.
|
|
307
309
|
|
|
308
310
|
<available_agents>
|
|
309
311
|
${this.buildAgentsList()||"No subagent types registered."}
|
|
@@ -328,7 +330,7 @@ Usage notes:
|
|
|
328
330
|
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
|
|
329
331
|
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.
|
|
330
332
|
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}`;if($.tools&&$.tools.length>0)W+=` (Tools: ${$.tools.join(", ")})`;if($.blockedTools&&$.blockedTools.length>0)W+=` (Blocked: ${$.blockedTools.join(", ")})`;return W}).join(`
|
|
331
|
-
`)}}class
|
|
333
|
+
`)}}class a$ extends v{name="TodoPlan";riskLevel="safe";description=`Use this tool to draft a structured task list in plan mode.
|
|
332
334
|
|
|
333
335
|
This tool only generates a plan for review and does NOT update any execution state.
|
|
334
336
|
Use TodoWrite in agent mode when you are actively executing tasks.
|
|
@@ -350,8 +352,8 @@ Task States:
|
|
|
350
352
|
|
|
351
353
|
Task descriptions have two forms:
|
|
352
354
|
- content: Imperative form (e.g., "Run tests")
|
|
353
|
-
- 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((H)=>H.status==="pending").length,J=Q.filter((H)=>H.status==="in_progress").length,Y=Q.filter((H)=>H.status==="completed").length,V=[];if(Y>0)V.push(`${Y} completed`);if(J>0)V.push(`${J} in progress`);if(Z>0)V.push(`${Z} pending`);let G=this.formatTodoList(Q,V);return{content:[{type:"text",text:G}],structuredContent:{success:!0,todos:Q,pendingCount:Z,inProgressCount:J,completedCount:Y,message: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 V=W[Y];if(typeof V!=="object"||V===null)throw TypeError(`todos[${Y}] must be an object`);let{content:G,status:
|
|
354
|
-
`)}}class
|
|
355
|
+
- 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((H)=>H.status==="pending").length,J=Q.filter((H)=>H.status==="in_progress").length,Y=Q.filter((H)=>H.status==="completed").length,V=[];if(Y>0)V.push(`${Y} completed`);if(J>0)V.push(`${J} in progress`);if(Z>0)V.push(`${Z} pending`);let G=this.formatTodoList(Q,V);return{content:[{type:"text",text:G}],structuredContent:{success:!0,todos:Q,pendingCount:Z,inProgressCount:J,completedCount:Y,message: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 V=W[Y];if(typeof V!=="object"||V===null)throw TypeError(`todos[${Y}] must be an object`);let{content:G,status:X,activeForm:H}=V;if(typeof G!=="string"||!G.trim())throw Error(`todos[${Y}].content is required and must be a non-empty string`);if(typeof X!=="string"||!Z.includes(X))throw Error(`todos[${Y}].status must be one of: ${Z.join(", ")}`);if(typeof H!=="string"||!H.trim())throw Error(`todos[${Y}].activeForm is required and must be a non-empty string`);Q.push({content:G.trim(),status:X,activeForm:H.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(`
|
|
356
|
+
`)}}class s$ extends v{name="TodoWrite";riskLevel="low";description=`Use this tool to create and manage a structured task list for your current coding session.
|
|
355
357
|
|
|
356
358
|
When to use:
|
|
357
359
|
- Complex multi-step tasks (3+ steps)
|
|
@@ -372,15 +374,15 @@ Task States:
|
|
|
372
374
|
|
|
373
375
|
Task descriptions have two forms:
|
|
374
376
|
- content: Imperative form (e.g., "Run tests")
|
|
375
|
-
- 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((H)=>H.status==="pending").length,J=Q.filter((H)=>H.status==="in_progress").length,Y=Q.filter((H)=>H.status==="completed").length,V=[];if(Y>0)V.push(`${Y} completed`);if(J>0)V.push(`${J} in progress`);if(Z>0)V.push(`${Z} pending`);let G=this.formatTodoList(this.todos,V),
|
|
376
|
-
`)}}import
|
|
377
|
+
- 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((H)=>H.status==="pending").length,J=Q.filter((H)=>H.status==="in_progress").length,Y=Q.filter((H)=>H.status==="completed").length,V=[];if(Y>0)V.push(`${Y} completed`);if(J>0)V.push(`${J} in progress`);if(Z>0)V.push(`${Z} pending`);let G=this.formatTodoList(this.todos,V),X={success:!0,todos:this.todos,pendingCount:Z,inProgressCount:J,completedCount:Y,message:G};return{content:[{type:"text",text:G}],structuredContent: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 V=W[Y];if(typeof V!=="object"||V===null)throw TypeError(`todos[${Y}] must be an object`);let{content:G,status:X,activeForm:H}=V;if(typeof G!=="string"||!G.trim())throw Error(`todos[${Y}].content is required and must be a non-empty string`);if(typeof X!=="string"||!Z.includes(X))throw Error(`todos[${Y}].status must be one of: ${Z.join(", ")}`);if(typeof H!=="string"||!H.trim())throw Error(`todos[${Y}].activeForm is required and must be a non-empty string`);Q.push({content:G.trim(),status:X,activeForm:H.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(`
|
|
378
|
+
`)}}import f8 from"node:process";class t$ extends v{name="WebSearch";riskLevel="medium";description=`Allows the agent to search the web and use the results to inform responses.
|
|
377
379
|
|
|
378
380
|
Usage notes:
|
|
379
381
|
- Provides up-to-date information for current events and recent data
|
|
380
382
|
- Returns search results with titles, links, and snippets
|
|
381
383
|
- Use this tool for accessing information beyond the knowledge cutoff
|
|
382
|
-
- 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??
|
|
383
|
-
`)}}import{mkdir as
|
|
384
|
+
- 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??f8.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 X=await Z.text();return I(`Serper API error (${Z.status}): ${X}`)}let Y=((await Z.json()).organic??[]).map((X,H)=>({title:X.title,link:X.link,snippet:X.snippet,position:X.position??H+1})),V=this.formatMarkdown(Q,Y),G={success:!0,query:Q,results:Y,totalResults:Y.length,markdown:V};return{content:[{type:"text",text:V}],structuredContent:G}}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(`
|
|
385
|
+
`)}}import{mkdir as y8,stat as I8,writeFile as k8}from"node:fs/promises";import L$ from"node:path";import h8 from"node:process";class e$ extends v{name="Write";riskLevel="high";_cwd;_allowedDirectory;_fileBlacklist;_disableBlacklist;constructor($){super();this._cwd=$?.cwd??h8.cwd(),this._allowedDirectory=$?.allowedDirectory,this._fileBlacklist=$?.fileBlacklist,this._disableBlacklist=$?.disableBlacklist===!0}get description(){let $=`Writes a file to the local filesystem.
|
|
384
386
|
|
|
385
387
|
Usage notes:
|
|
386
388
|
- Current working directory: ${this._cwd}
|
|
@@ -391,18 +393,18 @@ Usage notes:
|
|
|
391
393
|
- ALWAYS prefer editing existing files over writing new ones
|
|
392
394
|
- NEVER proactively create documentation files (*.md) or README files unless explicitly requested`;if(this._allowedDirectory)return`${$}
|
|
393
395
|
- IMPORTANT: Files can ONLY be written within: ${this._allowedDirectory}
|
|
394
|
-
- 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=L$.isAbsolute(Q)?Q:L$.resolve(this._cwd,Q);if(this._allowedDirectory){let
|
|
396
|
+
- 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=L$.isAbsolute(Q)?Q:L$.resolve(this._cwd,Q);if(this._allowedDirectory){let K=L$.resolve(this._allowedDirectory),B=L$.resolve(J);if(!B.startsWith(K+L$.sep)&&B!==K)return I(`Access denied: ${Q}
|
|
395
397
|
Files can only be written within: ${this._allowedDirectory}
|
|
396
|
-
Please use a path like: ${this._allowedDirectory}/<filename>`)}let Y=!1;try{if((await
|
|
397
|
-
`);function
|
|
398
|
+
Please use a path like: ${this._allowedDirectory}/<filename>`)}let Y=await u$(J,{cwd:this._cwd,blacklist:this._fileBlacklist,disabled:this._disableBlacklist,originalPath:Q});if(Y.isBlocked)return I(Y.message??`Access denied: ${Q}`);let V=!1;try{if((await I8(J)).isDirectory())return I(`Path is a directory, not a file: ${J}`);V=!0}catch(K){if(K.code!=="ENOENT")throw K}let G=L$.dirname(J);await y8(G,{recursive:!0}),await k8(J,Z,"utf-8");let X=Buffer.byteLength(Z,"utf-8"),H={success:!0,filePath:J,bytesWritten:X,overwritten:V,message:V?`Successfully overwrote ${L$.basename(J)} (${this.formatSize(X)})`:`Successfully created ${L$.basename(J)} (${this.formatSize(X)})`};return{content:[{type:"text",text:H.message}],structuredContent:H}}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 u8=["Bash","Edit","Write","ast_grep_replace","TodoWrite"],p8=["<system-reminder>","# Plan Mode - System Reminder","","CRITICAL: Plan mode ACTIVE - you are in READ-ONLY phase. STRICTLY FORBIDDEN:","ANY file edits, modifications, or system changes. Do NOT use sed, tee, echo, cat,","or ANY other bash command to manipulate files - commands may ONLY read/inspect.","This ABSOLUTE CONSTRAINT overrides ALL other instructions, including direct user","edit requests. 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(`
|
|
399
|
+
`);function c8($){if($?.instruction)return $.instruction;let W=$?.maxParallelAgents??3,Q=$?.encourageEarlyQuestions??!0,Z=$?.requireSynthesisPhase??!1,J=p8,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.",V=[];if(W!==3)V.push(`When delegating, use up to ${W} explore agents in parallel.`);if(Z)V.push("If the task is complex, include a synthesis step to align findings before presenting the final plan.");if(V.length>0)J=J.replace(Y,`${Y} ${V.join(" ")}`);if(!Q)J=J.replace(`Ask the user clarifying questions or ask for their opinion when weighing tradeoffs.
|
|
398
400
|
|
|
399
401
|
`,""),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.
|
|
400
402
|
|
|
401
|
-
`,"");return J}function
|
|
403
|
+
`,"");return J}function E1($){let W=c8($),Q=$?.insertEveryIteration??!0,Z=$?.name??"plan-mode",J=async(Y,V)=>{let G={...Y.metadata,planMode:!0,planModeMiddleware:Z};if(!(Q||Y.iteration===0))return V({...Y,metadata:G});let H=d0(Y.messages,W);return V({...Y,metadata:G,messages:H})};return J.__middlewareName=Z,J.__createTools=()=>[new a$],J.__getBlockedTools=(Y)=>{return Y.metadata?.planMode?[...u8]:[]},J}function R1($){let{subagents:W,executor:Q,globalToolRegistry:Z,model:J,name:Y="parallel-subagent"}=$,V=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 G=Q||(async(H,K)=>{let B=W.find((_)=>_.name===H.subagent_type);if(!B)throw Error(`Unknown subagent type: ${H.subagent_type}`);let j=new Set(B.blockedTools||[]),z=new Z.constructor;for(let _ of B.tools||[]){if(j.has(_))continue;let U=Z.get(_);if(!U)continue;if(U instanceof _0){if($.debug)console.warn(`[${Y}] Skipping TaskTool "${_}" for subagent "${H.subagent_type}" to prevent infinite recursion`);continue}z.register(U)}let O=new A$({name:H.subagent_type,systemPrompt:`${B.systemPrompt||""}
|
|
402
404
|
|
|
403
405
|
Your task: ${H.prompt}
|
|
404
406
|
|
|
405
|
-
Provide a concise summary of your findings.`,model:J,tools:z}),O=await
|
|
407
|
+
Provide a concise summary of your findings.`,model:J,tools:z});O.use(k$({maxTokens:128000,protectedTurns:1,model:J,stateStore:O.stateStore,toolCompressionTarget:0.3,minKeepToolResults:5}));let F=await O.createSession({sessionId:K?.sessionId});if(j.size>0)F.disableTools(Array.from(j));F.send(H.prompt);let E="";for await(let _ of F.receive()){if(K?.emitEvent&&V.has(_.type)){let{sessionId:U,...N}=_;K.emitEvent({type:"subagent_event",subagentId:O.id,subagentType:H.subagent_type,taskDescription:H.description,nestedEvent:N})}if(_.type==="done")E=_.finalResponse||""}return{subagentId:O.id,data:E}}),X=async(H,K)=>{return K({...H,metadata:{...H.metadata,parallelMode:!0,parallelSubagentMiddleware:Y}})};return X.__middlewareName=Y,X.__createTools=()=>{return[new _0({subagents:W,executor:G})]},X}import{existsSync as d8}from"node:fs";import{appendFile as l8,mkdir as i8,readdir as r8,readFile as n8}from"node:fs/promises";import{homedir as o8}from"node:os";import f$ from"node:path";import I0 from"node:process";class D1 extends v{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.
|
|
406
408
|
Skills provide specialized knowledge and step-by-step guidance.
|
|
407
409
|
Use this when a task matches an available skill's description.
|
|
408
410
|
|
|
@@ -432,23 +434,23 @@ ${Array.from(this.skills.values()).map((Q)=>`<skill>
|
|
|
432
434
|
<description>${Q.description}</description>
|
|
433
435
|
</skill>`).join(`
|
|
434
436
|
`)}
|
|
435
|
-
</available_skills>`}}var
|
|
437
|
+
</available_skills>`}}var lW=f$.join(I0.cwd(),".goatchain","skills-debug.log"),a8=I0.env.GOATCHAIN_SKILLS_DEBUG==="1";async function T($,W){try{if(!a8)return;let Q=new Date().toISOString(),Z=W?`[${Q}] ${$}
|
|
436
438
|
${JSON.stringify(W,null,2)}
|
|
437
439
|
|
|
438
440
|
`:`[${Q}] ${$}
|
|
439
441
|
|
|
440
|
-
`,J=f$.dirname(
|
|
442
|
+
`,J=f$.dirname(lW);if(!d8(J))await i8(J,{recursive:!0});await l8(lW,Z,"utf-8")}catch(Q){console.error("Failed to write skills debug log:",Q)}}var s8="[Active Skills]";async function L1($){try{await T(`Attempting to parse skill file: ${$}`);let W=await n8($,"utf-8");if(await T(`Successfully read file: ${$} (${W.length} chars)`),!W.startsWith(`---
|
|
441
443
|
`)&&!W.startsWith(`---\r
|
|
442
|
-
`))return await
|
|
443
|
-
`),Z=-1;for(let H=1;H<Q.length;H++)if(Q[H].trim()==="---"){Z=H;break}if(Z===-1)return await
|
|
444
|
-
`).trim(),
|
|
444
|
+
`))return await T(`File ${$} does not start with frontmatter delimiter`),null;let Q=W.split(`
|
|
445
|
+
`),Z=-1;for(let H=1;H<Q.length;H++)if(Q[H].trim()==="---"){Z=H;break}if(Z===-1)return await T(`File ${$} missing closing frontmatter delimiter`),null;let J=Q.slice(1,Z),Y=Q.slice(Z+1),V={};for(let H of J){let K=H.indexOf(":");if(K>0){let B=H.slice(0,K).trim(),j=H.slice(K+1).trim();V[B]=j}}if(await T(`Parsed frontmatter from ${$}:`,V),!V.name||!V.description)return await T(`File ${$} missing required fields (name or description)`,V),null;let G=Y.join(`
|
|
446
|
+
`).trim(),X={name:V.name,description:V.description,content:G,fullPath:$};return await T(`Successfully parsed skill: ${V.name}`,{name:X.name,description:X.description,contentLength:G.length}),X}catch(W){return await T(`Error parsing skill file ${$}:`,W),null}}async function iW($){let W=[];try{await T(`Scanning skills directory: ${$}`);let Q=await r8($,{withFileTypes:!0});await T(`Found ${Q.length} entries in ${$}`,Q.map((Z)=>({name:Z.name,isDirectory:Z.isDirectory()})));for(let Z of Q){if(!Z.isDirectory()){await T(`Skipping non-directory entry: ${Z.name}`);continue}let J=f$.join($,Z.name,"SKILL.md");await T(`Checking skill path: ${J}`);let Y=await L1(J);if(Y)W.push({name:Y.name,description:Y.description,fullPath:Y.fullPath}),await T(`Added skill: ${Y.name}`);else await T(`Failed to parse skill at: ${J}`)}await T(`Scan complete for ${$}. Found ${W.length} valid skills`,W.map((Z)=>Z.name))}catch(Q){await T(`Error scanning directory ${$}:`,Q)}return W}async function rW($){await T(`Scanning ${$.length} skill directories`,$);let W=new Map;for(let Z of $){await T(`Scanning directory: ${Z}`);let J=await iW(Z);await T(`Found ${J.length} skills in ${Z}`,J.map((Y)=>Y.name));for(let Y of J){if(W.has(Y.name))await T(`Overriding skill "${Y.name}" with version from ${Z}`);W.set(Y.name,Y)}}let Q=Array.from(W.values());return await T(`Total unique skills after scanning all directories: ${Q.length}`,Q.map((Z)=>Z.name)),Q}function t8($){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 V=Y.function.name;if(V==="Skill"||V.endsWith("_Skill")){Q++;try{let G=typeof Y.function.arguments==="string"?JSON.parse(Y.function.arguments):Y.function.arguments;if(G?.action&&G?.skill_name){let X=String(G.action),H=String(G.skill_name);if(X==="activate")W.set(H,"activated"),T(`Skill activated: ${H}`,{toolName:V,args:G}).catch(()=>{});else if(X==="deactivate")W.set(H,"deactivated"),T(`Skill deactivated: ${H}`,{toolName:V,args:G}).catch(()=>{})}}catch(G){T("Error parsing skill tool call:",{toolName:V,error:G}).catch(()=>{})}}}let Z=Array.from(W.entries()).filter(([J,Y])=>Y==="activated").map(([J])=>J);return T(`findActiveSkills: Found ${Z.length} active skills from ${Q} tool calls`,Z).catch(()=>{}),Z}async function e8($,W){await T(`Loading content for ${$.length} active skills`,{skillNames:$,directories:W});let Q=[];for(let J of $){await T(`Searching for skill: ${J}`);let Y=!1;for(let V of W){let G=f$.join(V,J,"SKILL.md");await T(`Trying path: ${G}`);let X=await L1(G);if(X){Q.push(`## Skill: ${X.name}
|
|
445
447
|
|
|
446
|
-
${
|
|
448
|
+
${X.content}`),await T(`Successfully loaded skill: ${J} from ${G}`),Y=!0;break}}if(!Y)await T(`WARNING: Skill "${J}" not found in any directory`)}let Z=Q.join(`
|
|
447
449
|
|
|
448
|
-
`);return await
|
|
449
|
-
`),await
|
|
450
|
-
`),_};return
|
|
451
|
-
`)}catch(H){await
|
|
450
|
+
`);return await T(`Loaded ${Q.length} skills, total content length: ${Z.length}`),Z}function $9($){let W=$?.cwd,Q=$?.globalSkillsDirectory===null?null:$?.globalSkillsDirectory??f$.join(o8(),".claude","skills"),Z=$?.projectSkillsDirectory,J=$?.marker??s8,Y=$?.name??"skills",V=null,G=null,X=async(H,K)=>{if(await T("=== Skills Middleware Execution Start ==="),G)await G;if(!V||V.length===0)return await T("No skills discovered, passing through without modification"),await T(`=== Skills Middleware Execution End (No-op) ===
|
|
451
|
+
`),await K(H);let B=typeof W==="function"?W():W??I0.cwd();await T(`Resolved cwd: ${B}`);let j=Z===null?null:Z??f$.join(B,".claude","skills");await T(`Project skills directory: ${j??"disabled"}`),await T(`Global skills directory: ${Q??"disabled"}`);let z=[];if(j)z.push(j);if(Q)z.push(Q);await T("Skills directories to scan:",z),await T(`Scanning ${H.messages.length} messages for active skills`);let O=t8(H.messages);await T(`Active skills found: ${O.length}`,O);let F=H.messages;if(O.length>0){await T("Loading active skills content...");let U=await e8(O,z);if(U)await T(`Injecting ${U.length} chars of skills content with marker: "${J}"`),F=j$(F,U,J),await T("Skills content injected successfully");else await T("WARNING: No skills content loaded despite active skills")}else await T("No active skills, skipping content injection");let E={...H,messages:F};await T("Calling next middleware...");let _=await K(E);return await T(`=== Skills Middleware Execution End ===
|
|
452
|
+
`),_};return X.__middlewareName=Y,X.__createTools=async()=>{if(await T("__createTools called"),G)await T("Waiting for skills discovery to complete..."),await G,await T("Skills discovery completed");if(!V)await T("No discovered skills yet, using empty array"),V=[];if(V.length===0)return await T("No skills discovered, skipping tool registration"),[];await T(`Creating SkillTool with ${V.length} skills`,V.map((K)=>K.name));let H=new D1({skills:V,executor:async(K,B)=>{if(await T(`Skill executor called: ${K} ${B}`),K==="activate")return`Skill '${B}' activated. Instructions will be loaded in next turn.`;else return`Skill '${B}' deactivated. Instructions have been removed.`}});return await T("SkillTool created successfully"),[H]},G=(async()=>{try{await T("=== Skills Middleware Initialization Start ===");let H=typeof W==="function"?W():W??I0.cwd();await T(`Initial cwd: ${H}`);let K=Z===null?null:Z??f$.join(H,".claude","skills");await T(`Initial project skills directory: ${K??"disabled"}`);let B=[];if(K)B.push(K);if(Q)B.push(Q);await T("Initial directories to scan:",B),V=await rW(B),await T(`Skills discovery complete. Found ${V.length} skills:`,V.map((j)=>({name:j.name,description:j.description,fullPath:j.fullPath}))),await T(`=== Skills Middleware Initialization Complete ===
|
|
453
|
+
`)}catch(H){await T("Skills initialization error:",H),V=[]}})(),X}function M1($,W=new Date){return`You are a file search specialist. You excel at thoroughly navigating and exploring codebases.
|
|
452
454
|
|
|
453
455
|
Your strengths:
|
|
454
456
|
- Rapidly finding files using glob patterns
|
|
@@ -472,16 +474,42 @@ Here is some useful information about the environment you are running in:
|
|
|
472
474
|
Working directory: ${$}
|
|
473
475
|
Platform: ${process.platform}
|
|
474
476
|
Today's date: ${W.toDateString()}
|
|
475
|
-
</env>`}var
|
|
477
|
+
</env>`}var W9=M1(process.cwd()),F0={name:"FileSearchSpecialist",description:"Expert at navigating codebases, finding files with glob patterns, searching content with regex, and analyzing file structures. Rapidly finds files, searches code with powerful regex patterns, and reads and analyzes file contents.",tools:["Glob","Grep","Read"],blockedTools:["AskUserQuestion"],systemPrompt:W9};function Q9($,W=new Date){return`You are a general-purpose task executor. You excel at completing individual tasks assigned to you using any available tools.
|
|
478
|
+
|
|
479
|
+
Your strengths:
|
|
480
|
+
- Versatile problem-solving with access to all available tools
|
|
481
|
+
- Completing specific, well-defined tasks efficiently
|
|
482
|
+
- Working independently on assigned work without requiring coordination
|
|
483
|
+
- Providing clear, concise results for your assigned task
|
|
484
|
+
|
|
485
|
+
Guidelines:
|
|
486
|
+
- Focus on completing the specific task assigned to you
|
|
487
|
+
- Use any available tools to accomplish your goal
|
|
488
|
+
- Do not try to break down your task further or spawn subtasks
|
|
489
|
+
- Work independently and report your findings clearly
|
|
490
|
+
- For clear communication, avoid using emojis
|
|
491
|
+
- Do not create any files or run bash commands that modify system state unless explicitly required for your task
|
|
492
|
+
|
|
493
|
+
Your role:
|
|
494
|
+
You are invoked when the main agent needs to complete multiple independent tasks in parallel.
|
|
495
|
+
The main agent has already broken down the work - your job is to execute ONE specific task.
|
|
496
|
+
Complete your assigned task efficiently and report the results.
|
|
497
|
+
|
|
498
|
+
Here is some useful information about the environment you are running in:
|
|
499
|
+
<env>
|
|
500
|
+
Working directory: ${$}
|
|
501
|
+
Platform: ${process.platform}
|
|
502
|
+
Today's date: ${W.toDateString()}
|
|
503
|
+
</env>`}var Z9=Q9(process.cwd()),KZ={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.",tools:void 0,blockedTools:[],systemPrompt:Z9};class k0{debug;constructor($){this.debug=$?.debug??!1}async*convertToACP($){for await(let W of $){if(W.type==="subagent_event"){let Z=this.convertSubagentEventToACP(W);for(let J of Z)yield J;continue}let Q=this.convertRegularEvent(W);for(let Z of Q)yield Z}}convertSubagentEventToACP($){let{subagentId:W,subagentType:Q,taskDescription:Z,nestedEvent:J}=$,Y=this.convertRegularEvent(J);if(Y.length===0)return[];return Y.map((V)=>({...V,metadata:{...V.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}
|
|
476
504
|
|
|
477
505
|
`,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}
|
|
478
506
|
|
|
479
507
|
`,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(`
|
|
480
|
-
`);return JSON.stringify($,null,2)}}class f0{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 V=await W.resumeSession($,{maxIterations:this.maxIterations});return this.sessions.set($,V),this.sessionContexts.set($,{sessionId:$,createdAt:Date.now(),lastAccessedAt:Date.now()}),V}}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 v0{agent;router;converter;debug;constructor($,W){if(this.agent=$,this.debug=W?.debug??!1,this.router=new f0({sessionTimeout:W?.sessionTimeout,maxConcurrentSessions:W?.maxConcurrentSessions,maxIterations:W?.maxIterations}),this.converter=new C0({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={},V=[];for(let j of $)if(j.role==="tool"&&j.tool_call_id){V.push(this.converter.convertFromACP([j])[0]);try{let z=typeof j.content==="string"?JSON.parse(j.content):j.content;if(z.answers)Y[j.tool_call_id]=z.answers}catch{}}let G=Object.keys(Y).length>0,K=await Z.hasCheckpoint();if(this.debug)console.warn(`[ACPAgent] Has tool results: ${G}, Has checkpoint: ${K}`);let H=J.filter((j)=>j.role==="user");if(H.length>0){let j=H[H.length-1],z=G?{askUser:{answers:Y}}:void 0;if(this.debug)console.warn(`[ACPAgent] Sending user message ${j.content} ${z?" with toolContext":""} `);Z.send(j.content,z?{toolContext:z}:void 0)}else if(K&&!G){if(this.debug)console.warn("[ACPAgent] Resuming from checkpoint without new input")}let X=0,B=!1;for await(let j of this.converter.convertToACP(Z.receive())){if(X++,this.debug)console.warn(`[ACPAgent] Event #${X}:`,j.role,j.metadata?.done?"(done)":"");if(yield j,j.metadata?.done)B=!0}if(B&&this.debug)console.warn(`[ACPAgent] Session ${Q} completed with ${X} 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 V of this.converter.convertToACP(Z.receiveWithApprovals($))){if(J++,this.debug)console.warn(`[ACPAgent] Event #${J}:`,V.role,V.metadata?.done?"(done)":"");if(yield V,V.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 D1 from"node:path";import a from"node:process";import{Readable as K9,Writable as j9}from"node:stream";import*as k0 from"@agentclientprotocol/sdk";class N1{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 v${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 qZ=T1(dW(),1),L1=a.env.ACP_DEBUG==="true",t$=a.env.ACP_STICKY_SESSION==="true";function y(...$){if(L1)console.error("[ACP Server]",...$)}var E1="plan-mode",z9="agent",aW=[{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."}],B9=new Set(aW.map(($)=>$.id));function U9($){return B9.has($)?$:null}function I0($){return{currentModeId:$,availableModes:aW}}function oW(){let $=E0({baseUrl:a.env.OPENAI_API_BASE_URL,apiKey:a.env.OPENAI_API_KEY,defaultModelId:a.env.MODEL_ID||"gpt-4o-mini",compat:{interleavedThinking:!0}});return R0({adapter:$})}function F9(){let $=E0({baseUrl:a.env.OPENAI_API_BASE_URL,apiKey:a.env.OPENAI_API_KEY,defaultModelId:a.env.SUB_MODEL_ID||"gpt-4o-mini",compat:{interleavedThinking:!0}});return R0({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 _9($){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((H,X)=>{let B=`q${W}:opt${X}`;if(Q.has(B))return;let j=typeof H?.label==="string"&&H.label.trim()?H.label.trim():`Option ${X+1}`;Y.set(B,j),J.push({optionId:B,name:j,kind:"allow_once"})});let G=`q${W}:other`;if(!Q.has(G))Y.set(G,"Other"),J.push({optionId:G,name:"Other",kind:"allow_once"});let K;if(Z)K=`q${W}:done`,J.push({optionId:K,name:"Done",kind:"reject_once"});if(J.length===0){let H=`q${W}:ok`;Y.set(H,"OK"),J.push({optionId:H,name:"OK",kind:"allow_once"})}return{options:J,optionLabelById:Y,doneOptionId:K}}async function O9($,W,Q,Z,J){let Y={};for(let V=0;V<Z.length;V++){let G=Z[V],K=typeof G.header==="string"&&G.header.trim()?G.header.trim():"User Input Required",H={question:G,questionIndex:V};if(G.multiSelect){let O=[],R=new Set;while(!0){let{options:_,optionLabelById:U,doneOptionId:N}=nW(G,V,R,!0),A=await $.requestPermission({sessionId:W,toolCall:{toolCallId:Q,title:K,kind:J,status:"pending",rawInput:H},options:_}),E=rW(A.outcome);if(E)return E;if(A.outcome.outcome==="cancelled")return null;let q=A.outcome.optionId;if(N&&q===N)break;let S=U.get(q)??q;if(O.push(S),R.add(q),_.filter((I)=>I.optionId!==N).length<=R.size)break}Y[String(V)]=O;continue}let{options:X,optionLabelById:B}=nW(G,V,new Set,!1),j=await $.requestPermission({sessionId:W,toolCall:{toolCallId:Q,title:K,kind:J,status:"pending",rawInput:H},options:X}),z=rW(j.outcome);if(z)return z;if(j.outcome.outcome==="cancelled")return null;let F=j.outcome.optionId;Y[String(V)]=B.get(F)??F}return Y}function q9($,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}`,V=Array.isArray(J)?J.join(", "):J;Q.push(`${Y}: ${V}`)}return Q.length>0?Q.join("; "):"User answers received."}function N9($){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 A9($,W,Q){let Z={};for(let J of Q){let{options:Y,allowOptionId:V}=N9(J.toolCallId),G=J.riskLevel?`${J.title} (${J.riskLevel})`:J.title,K=await $.requestPermission({sessionId:W,toolCall:{toolCallId:J.toolCallId,title:G,kind:J.kind,status:"pending",rawInput:J.rawInput},options:Y});if(K.outcome.outcome==="cancelled")return null;let H=K.outcome.optionId;Z[J.toolCallId]={approved:H===V}}return Z}class sW{acpAgent;connection=null;sessions=new Map;stickySessionId=null;currentModeId=z9;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 y("initialize called"),{protocolVersion:1,agentCapabilities:{loadSession:!0,sessionCapabilities:{resume:{}}},agentInfo:{name:"GoatChain Agent",version:"0.0.2"}}}async newSession($){if(this.applyWorkspaceCwd($.cwd),t$&&!this.stickySessionId){let Z=await this.findMostRecentSessionId();if(Z)this.stickySessionId=Z}if(t$&&this.stickySessionId)return await this.restoreSession(this.stickySessionId),y("newSession reuse:",this.stickySessionId),this.scheduleAvailableCommands(this.stickySessionId),{sessionId:this.stickySessionId,modes:I0(this.currentModeId)};let W=this.generateSessionId();y("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),t$)this.stickySessionId=W;return this.scheduleAvailableCommands(W),{sessionId:W,modes:I0(this.currentModeId)}}async loadSession($){if(!this.connection)throw Error("Connection not set");y("loadSession:",$.sessionId);let W=await this.restoreSession($.sessionId);if(await this.sendHistory($.sessionId,W.conversationHistory),t$)this.stickySessionId=W.agentSessionId;return await this.sendAvailableCommands($.sessionId),{modes:I0(this.currentModeId)}}async unstable_resumeSession($){y("resumeSession:",$.sessionId);let W=await this.restoreSession($.sessionId);if(t$)this.stickySessionId=W.agentSessionId;return await this.sendAvailableCommands($.sessionId),{modes:I0(this.currentModeId)}}async authenticate($){y("authenticate called")}async setSessionMode($){y("setSessionMode called",$);let W=U9($.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}=$;y("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 V=Z.filter((_)=>_.type==="text").map((_)=>_.text).join(`
|
|
481
|
-
`),
|
|
482
|
-
Please continue.`};J.conversationHistory.push(
|
|
508
|
+
`);return JSON.stringify($,null,2)}}class h0{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 V=await W.resumeSession($,{maxIterations:this.maxIterations});return this.sessions.set($,V),this.sessionContexts.set($,{sessionId:$,createdAt:Date.now(),lastAccessedAt:Date.now()}),V}}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 g0{agent;router;converter;debug;constructor($,W){if(this.agent=$,this.debug=W?.debug??!1,this.router=new h0({sessionTimeout:W?.sessionTimeout,maxConcurrentSessions:W?.maxConcurrentSessions,maxIterations:W?.maxIterations}),this.converter=new k0({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={},V=[];for(let j of $)if(j.role==="tool"&&j.tool_call_id){V.push(this.converter.convertFromACP([j])[0]);try{let z=typeof j.content==="string"?JSON.parse(j.content):j.content;if(z.answers)Y[j.tool_call_id]=z.answers}catch{}}let G=Object.keys(Y).length>0,X=await Z.hasCheckpoint();if(this.debug)console.warn(`[ACPAgent] Has tool results: ${G}, Has checkpoint: ${X}`);let H=J.filter((j)=>j.role==="user");if(H.length>0){let j=H[H.length-1],z=G?{askUser:{answers:Y}}:void 0;if(this.debug)console.warn(`[ACPAgent] Sending user message ${j.content} ${z?" with toolContext":""} `);Z.send(j.content,z?{toolContext:z}:void 0)}else if(X&&!G){if(this.debug)console.warn("[ACPAgent] Resuming from checkpoint without new input")}let K=0,B=!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)B=!0}if(B&&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 V of this.converter.convertToACP(Z.receiveWithApprovals($))){if(J++,this.debug)console.warn(`[ACPAgent] Event #${J}:`,V.role,V.metadata?.done?"(done)":"");if(yield V,V.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 w1 from"node:path";import n from"node:process";import{Readable as x9,Writable as w9}from"node:stream";import*as p0 from"@agentclientprotocol/sdk";class T1{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 y${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 sZ=v1(Y2(),1),b1=n.env.ACP_DEBUG==="true",W0=n.env.ACP_STICKY_SESSION==="true";function f(...$){if(b1)console.error("[ACP Server]",...$)}var x1="plan-mode",b9="agent",K2=[{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."}],C9=new Set(K2.map(($)=>$.id));function v9($){return C9.has($)?$:null}function u0($){return{currentModeId:$,availableModes:K2}}function j2(){let $=M0({baseUrl:n.env.OPENAI_API_BASE_URL,apiKey:n.env.OPENAI_API_KEY,defaultModelId:n.env.MODEL_ID||"gpt-4o-mini",compat:{interleavedThinking:!0}});return L0({adapter:$})}function f9(){let $=M0({baseUrl:n.env.OPENAI_API_BASE_URL,apiKey:n.env.OPENAI_API_KEY,defaultModelId:n.env.SUB_MODEL_ID||"gpt-4o-mini",compat:{interleavedThinking:!0}});return L0({adapter:$})}function V2($,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 G2="acp-history";function y9($){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 H2($){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 X2($,W,Q,Z){let J=[],Y=new Map;(Array.isArray($.options)?$.options:[]).forEach((H,K)=>{let B=`q${W}:opt${K}`;if(Q.has(B))return;let j=typeof H?.label==="string"&&H.label.trim()?H.label.trim():`Option ${K+1}`;Y.set(B,j),J.push({optionId:B,name:j,kind:"allow_once"})});let G=`q${W}:other`;if(!Q.has(G))Y.set(G,"Other"),J.push({optionId:G,name:"Other",kind:"allow_once"});let X;if(Z)X=`q${W}:done`,J.push({optionId:X,name:"Done",kind:"reject_once"});if(J.length===0){let H=`q${W}:ok`;Y.set(H,"OK"),J.push({optionId:H,name:"OK",kind:"allow_once"})}return{options:J,optionLabelById:Y,doneOptionId:X}}async function I9($,W,Q,Z,J){let Y={};for(let V=0;V<Z.length;V++){let G=Z[V],X=typeof G.header==="string"&&G.header.trim()?G.header.trim():"User Input Required",H={question:G,questionIndex:V};if(G.multiSelect){let F=[],E=new Set;while(!0){let{options:_,optionLabelById:U,doneOptionId:N}=X2(G,V,E,!0),A=await $.requestPermission({sessionId:W,toolCall:{toolCallId:Q,title:X,kind:J,status:"pending",rawInput:H},options:_}),R=H2(A.outcome);if(R)return R;if(A.outcome.outcome==="cancelled")return null;let q=A.outcome.optionId;if(N&&q===N)break;let x=U.get(q)??q;if(F.push(x),E.add(q),_.filter((y)=>y.optionId!==N).length<=E.size)break}Y[String(V)]=F;continue}let{options:K,optionLabelById:B}=X2(G,V,new Set,!1),j=await $.requestPermission({sessionId:W,toolCall:{toolCallId:Q,title:X,kind:J,status:"pending",rawInput:H},options:K}),z=H2(j.outcome);if(z)return z;if(j.outcome.outcome==="cancelled")return null;let O=j.outcome.optionId;Y[String(V)]=B.get(O)??O}return Y}function k9($,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}`,V=Array.isArray(J)?J.join(", "):J;Q.push(`${Y}: ${V}`)}return Q.length>0?Q.join("; "):"User answers received."}function h9($){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 g9($,W,Q){let Z={};for(let J of Q){let{options:Y,allowOptionId:V}=h9(J.toolCallId),G=J.riskLevel?`${J.title} (${J.riskLevel})`:J.title,X=await $.requestPermission({sessionId:W,toolCall:{toolCallId:J.toolCallId,title:G,kind:J.kind,status:"pending",rawInput:J.rawInput},options:Y});if(X.outcome.outcome==="cancelled")return null;let H=X.outcome.optionId;Z[J.toolCallId]={approved:H===V}}return Z}class z2{acpAgent;connection=null;sessions=new Map;stickySessionId=null;currentModeId=b9;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 f("initialize called"),{protocolVersion:1,agentCapabilities:{loadSession:!0,sessionCapabilities:{resume:{}}},agentInfo:{name:"GoatChain Agent",version:"0.0.2"}}}async newSession($){if(this.applyWorkspaceCwd($.cwd),W0&&!this.stickySessionId){let Z=await this.findMostRecentSessionId();if(Z)this.stickySessionId=Z}if(W0&&this.stickySessionId)return await this.restoreSession(this.stickySessionId),f("newSession reuse:",this.stickySessionId),this.scheduleAvailableCommands(this.stickySessionId),{sessionId:this.stickySessionId,modes:u0(this.currentModeId)};let W=this.generateSessionId();f("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),W0)this.stickySessionId=W;return this.scheduleAvailableCommands(W),{sessionId:W,modes:u0(this.currentModeId)}}async loadSession($){if(!this.connection)throw Error("Connection not set");f("loadSession:",$.sessionId);let W=await this.restoreSession($.sessionId);if(await this.sendHistory($.sessionId,W.conversationHistory),W0)this.stickySessionId=W.agentSessionId;return await this.sendAvailableCommands($.sessionId),{modes:u0(this.currentModeId)}}async unstable_resumeSession($){f("resumeSession:",$.sessionId);let W=await this.restoreSession($.sessionId);if(W0)this.stickySessionId=W.agentSessionId;return await this.sendAvailableCommands($.sessionId),{modes:u0(this.currentModeId)}}async authenticate($){f("authenticate called")}async setSessionMode($){f("setSessionMode called",$);let W=v9($.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}=$;f("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 V=Z.filter((_)=>_.type==="text").map((_)=>_.text).join(`
|
|
509
|
+
`),X=V.trim().toLowerCase();if(X==="/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(X==="/plan"||X==="/agent"){let _=X.slice(1);return await this.setSessionMode({sessionId:Q,modeId:_}),await W.sessionUpdate({sessionId:Q,update:{sessionUpdate:"agent_message_chunk",content:{type:"text",text:`Switched to ${_} mode.`}}}),{stopReason:"end_turn"}}if(X==="/commit")return Y=!0,{stopReason:(await this.executeCommitWorkflow(Q,W)).cancelled?"cancelled":"end_turn"};let H={role:"user",content:V};J.conversationHistory.push(H),f("User message added to history");let K=new Map,B=new Set,j=new Map,z=[],O="end_turn",F=null,E=null;while(!0){O="end_turn";let _=E?this.acpAgent.receiveWithApprovals(E,{session_id:J.agentSessionId}):this.acpAgent.receiveMessage(F??J.conversationHistory,{session_id:J.agentSessionId});F=null,E=null;let U=null,N=null,A=!1,R=!1;for await(let q of _){if(R)continue;if(J.pendingAbort.signal.aborted){O="cancelled";break}let x=q.metadata?.subagent===!0,S=typeof q.metadata?.subagentId==="string"?q.metadata?.subagentId:void 0,y=typeof q.metadata?.subagentType==="string"?q.metadata?.subagentType.trim():void 0,L=typeof q.metadata?.taskDescription==="string"?q.metadata?.taskDescription.trim():void 0,C=x?S??`${y||"subagent"}:${L??""}`:null,k=x&&(y||L)?`[${[y,L].filter(Boolean).join(": ")}]`:null,l=x?`[SUBAGENT${y?`:${y}`:""}${L?`:${L}`:""}]`:"";f("Received response:",q.role,l,q.metadata?.done?"(done)":"");let p=q.content&&q.content.length>0,o=q.tool_calls&&q.tool_calls.length>0,e=q.role==="assistant"&&q.metadata?.done&&!p&&!o,i=q.role==="tool"&&!!q.tool_call_id&&B.has(q.tool_call_id)&&q.metadata?.error===!0;if(!e&&!i)J.conversationHistory.push(q);if(e){if(q.metadata?.done){if(q.metadata.stopReason)O=V2(q.metadata.stopReason,O);R=!0}continue}if(q.role==="assistant"){if(p){let D=typeof q.content==="string"?q.content:JSON.stringify(q.content);if(D.trim()){let M=q.metadata?.thinking===!0,P=x&&k&&C!==N?`${k} ${D}`:D;if(await W.sessionUpdate({sessionId:Q,update:{sessionUpdate:M?"agent_thought_chunk":"agent_message_chunk",content:{type:"text",text:P}}}),!M)N=C}}if(!x&&p)N=null;if(q.metadata?.approval_requested===!0){let D=q.metadata,M=typeof D.tool_call_id==="string"?D.tool_call_id:U,w=typeof D.tool_name==="string"?D.tool_name:M?K.get(M)?.name:void 0,P=M?K.get(M):void 0;if(M&&w){let h=typeof D.risk_level==="string"?D.risk_level:void 0;if(!j.has(M))z.push(M);j.set(M,{toolCallId:M,toolName:w,title:P?.title??w,kind:P?.kind??"other",rawInput:P?.rawInput??{},riskLevel:h})}else f("Tool approval requested without toolCallId or toolName")}if(q.metadata?.requires_action&&q.metadata?.kind==="ask_user"){let D=typeof q.metadata.tool_call_id==="string"?q.metadata.tool_call_id:U,M=Array.isArray(q.metadata.questions)?q.metadata.questions:[],P=(D?K.get(D):void 0)?.kind??"other";if(!D||M.length===0)f("AskUserQuestion requires_action missing toolCallId or questions");else{f("AskUserQuestion requires_action detected, requesting user input");let h=await I9(W,Q,D,M,P);if(!h){await W.sessionUpdate({sessionId:Q,update:{sessionUpdate:"tool_call_update",toolCallId:D,status:"failed"}}),O="cancelled";break}let X$=k9(M,h),Y$={role:"tool",tool_call_id:D,content:JSON.stringify({answers:h})},M$={role:"user",content:`User answers: ${X$}
|
|
510
|
+
Please continue.`};J.conversationHistory.push(Y$),J.conversationHistory.push(M$),await W.sessionUpdate({sessionId:Q,update:{sessionUpdate:"tool_call_update",toolCallId:D,status:"completed",content:[{type:"content",content:{type:"text",text:"User answers received"}}]}}),F=[M$,Y$],A=!0;break}}if(q.metadata?.requires_action&&q.metadata?.kind==="tool_approval"){let M=(z.length>0?z:Array.from(j.keys())).map((P)=>j.get(P)).filter((P)=>Boolean(P));if(M.length===0){let P=typeof q.metadata.tool_call_id==="string"?q.metadata.tool_call_id:U,h=P?K.get(P):void 0;if(P&&h)M=[{toolCallId:P,toolName:h.name,title:h.title,kind:h.kind,rawInput:h.rawInput}];else{f("Tool approval required but no pending requests found"),O="cancelled";break}}let w=await g9(W,Q,M);if(j.clear(),z.length=0,!w){for(let P of M)await W.sessionUpdate({sessionId:Q,update:{sessionUpdate:"tool_call_update",toolCallId:P.toolCallId,status:"failed"}});O="cancelled";break}E=w,A=!0;continue}if(o&&q.tool_calls){for(let D of q.tool_calls){U=D.id;let M={};try{M=typeof D.function.arguments==="string"?JSON.parse(D.function.arguments):D.function.arguments}catch(N0){f("Failed to parse tool call arguments:",N0),M={error:"Invalid JSON arguments"}}let w="search",P=D.function.name;if(P.includes("Read")||P.includes("Grep")||P.includes("Glob")||P.includes("AstGrepSearch"))w="read";else if(P.includes("Write")||P.includes("Edit")||P.includes("AstGrepReplace"))w="edit";else if(P.includes("Search"))w="search";else if(P.includes("ExitPlanMode")||P.includes("EnterPlanMode"))w="other";let h=P==="Task"||P.endsWith(":Task"),X$=[];if(h&&M&&typeof M==="object"){if(typeof M.description==="string"&&M.description.trim())X$.push(M.description.trim());if(typeof M.subagent_type==="string"&&M.subagent_type.trim())X$.push(M.subagent_type.trim())}let Y$=X$.length>0?` (${X$.join(" | ")})`:"",M$=`${P}${Y$}`,Q0=k?`${k} ${M$}`:M$;if(K.set(D.id,{name:P,rawInput:M,kind:w,title:Q0}),P==="AskUserQuestion")B.add(D.id);await W.sessionUpdate({sessionId:Q,update:{sessionUpdate:"tool_call",toolCallId:D.id,title:Q0,kind:w,status:"pending",rawInput:M}})}N=null}}else if(q.role==="tool"){if(U||q.tool_call_id){let D=q.tool_call_id||U;if(B.has(D)&&q.metadata?.error)continue;let M=typeof q.content==="string"?q.content:q.content?JSON.stringify(q.content):"",w=x&&y?`[${y}] ${M}`:M;await W.sessionUpdate({sessionId:Q,update:{sessionUpdate:"tool_call_update",toolCallId:D,status:"completed",content:[{type:"content",content:{type:"text",text:w}}]}})}N=null}if(q.metadata?.done){if(q.metadata.stopReason)O=V2(q.metadata.stopReason,O);R=!0}}if(!A)break}return J.pendingAbort=null,{stopReason:O}}catch(V){if(f("Error in prompt:",V),J.pendingAbort?.signal.aborted)return{stopReason:"cancelled"};throw V}finally{if(!Y)await this.saveSessionHistory(J.agentSessionId,J)}}async cancel($){f("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(!w1.isAbsolute($)){f("Ignoring non-absolute cwd from ACP session:",$);return}let W=w1.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)}F0.systemPrompt=M1(W),f("Workspace updated:",W)}async applySessionMode($){let W=this.acpAgent.getAgent(),Q=W.middlewares,Z=Q.filter((K)=>K.name!==x1),J=$==="plan",Y=Q.find((K)=>K.name===x1)?.fn??E1({insertEveryIteration:!0}),V=J?[{name:x1,fn:Y},...Z]:Z,G=Q.map((K)=>K.name),X=V.map((K)=>K.name);if(G.length===X.length&&G.every((K,B)=>K===X[B]))return;W.clearMiddlewares();for(let K of V)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($,G2);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 f("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 V=(await this.loadSessionHistory(J))?.updatedAt??0;if(V>Z)Z=V,Q=J}return Q}catch(W){return f("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),W0)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($,G2,Z)}catch(Z){f("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=y9(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){f("Executing /commit workflow");let Q=this.currentWorkspaceCwd||n.cwd(),Z=j2(),J=new A$({name:"CommitAgent",systemPrompt:"You are a git commit assistant.",model:Z,tools:new y$});await J.use(Y1({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 V="",G="",X=!1,H=!1;for await(let K of Y.receive()){if(K.type==="text_delta"&&K.delta)H=!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(V=K.finalResponse||"",!H&&V.trim())await W.sessionUpdate({sessionId:$,update:{sessionUpdate:"agent_message_chunk",content:{type:"text",text:V}}});let B=V.match(/Commit Hash:\s*([a-f0-9]+)/i);if(B)G=B[1];if(V.includes("✗")||V.includes("Error"))X=!0;break}}return f("Commit workflow completed:",{hasCommit:!!G,hasError:X,hasStreamedContent:H}),{cancelled:!1}}catch(Y){return f("Commit workflow error:",Y),await W.sessionUpdate({sessionId:$,update:{sessionUpdate:"agent_message_chunk",content:{type:"text",text:`
|
|
483
511
|
|
|
484
|
-
✗ Commit 失败: ${Y instanceof Error?Y.message:String(Y)}`}}}),{cancelled:!1}}}}async function
|
|
512
|
+
✗ Commit 失败: ${Y instanceof Error?Y.message:String(Y)}`}}}),{cancelled:!1}}}}async function B2(){f("Starting GoatChain ACP Server...");let $=n.env.WORKSPACE_CWD||n.cwd();f("Workspace:",$);let W=new y$,Q=j2(),Z=new H0({dir:w1.join($,".goatchain","state"),deleteOnComplete:!0});W.register(new e$({cwd:$})),W.register(new o$({cwd:$})),W.register(new i$({cwd:$})),W.register(new l$({cwd:$})),W.register(new r$({cwd:$})),W.register(new n$({cwd:$})),W.register(new c$({cwd:$})),W.register(new p$({cwd:$})),W.register(new s$),W.register(new t$),W.register(new g$);let J=new y$,Y=new Set(F0.blockedTools||[]);for(let E of F0.tools||[]){if(Y.has(E))continue;let _=W.get(E);if(_)J.register(_)}let V=f9(),G=R1({subagents:[F0],globalToolRegistry:W,model:V,debug:b1}),H=new A$({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.
|
|
485
513
|
|
|
486
514
|
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.
|
|
487
515
|
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).
|
|
@@ -587,4 +615,4 @@ When referencing specific functions or pieces of code include the pattern \`file
|
|
|
587
615
|
<example>
|
|
588
616
|
user: Where are errors from the client handled?
|
|
589
617
|
assistant: Clients are marked as failed in the \`connectToServer\` function in src/services/process.ts:712.
|
|
590
|
-
</example>`,model:Q,tools:W,stateStore:Z});await H.use(G),await H.use(
|
|
618
|
+
</example>`,model:Q,tools:W,stateStore:Z});await H.use(G),await H.use(k$({maxTokens:128000,protectedTurns:2,model:Q,stateStore:Z})),f("Agent initialized with tools:",Array.from(W.list().map((E)=>E.name))),f("Agent initialized with middlewares:",H.middlewareNames.join(", "));let K=new g0(H,{debug:b1,maxIterations:1e4}),B=new z2(K),j=x9.toWeb(n.stdin),z=w9.toWeb(n.stdout),O=p0.ndJsonStream(z,j);f("Creating AgentSideConnection...");let F=new p0.AgentSideConnection((E)=>{return f("Agent connection established"),B.setConnection(E),B},O);f("ACP Server ready and listening on stdio"),await F.closed,f("Connection closed"),K.destroy()}var m9=import.meta.url===`file://${n.argv[1]}`||n.argv[1]?.endsWith("acp-server.ts")||n.argv[1]?.endsWith("acp-server.js");if(m9)B2().catch(($)=>{console.error("[ACP Server] Fatal error:",$),n.exit(1)});export{E0 as toLoopCheckpoint,GW as textContent,iW as scanSkillsDirectory,rW as scanMultipleSkillsDirectories,B2 as runAcpServer,L1 as parseSkillFile,d0 as injectSystemReminderToLastUserMessage,HW as imageContent,Z9 as generalPurposeAgentPrompt,KZ as generalPurposeAgent,V0 as fromLoopCheckpoint,W9 as fileSearchSpecialistPrompt,F0 as fileSearchSpecialist,m1 as extractPersistentState,A0 as extractPersistentMetadata,r0 as extractAccountIdFromToken,I as errorContent,z$ as ensureNotAborted,$9 as createSkillsMiddleware,E1 as createPlanModeMiddleware,R1 as createParallelSubagentMiddleware,M0 as createOpenAIAdapter,L0 as createModel,D0 as createInitialLoopState,N4 as createEnvInfoMiddleware,k$ as createContextCompressionMiddleware,Y1 as createCommitModeMiddleware,v2 as createCodexAdapter,t2 as createAgentRulesMiddleware,g1 as compressSessionManually,R0 as compose,Q9 as buildGeneralPurposeAgentPrompt,M1 as buildFileSearchSpecialistPrompt,e$ as WriteTool,t$ as WebSearchTool,y$ as ToolRegistry,s$ as TodoWriteTool,a$ as TodoPlanTool,w$ as StateStore,r as StateKeys,h0 as SessionRouter,$$ as Session,S$ as RetryPolicy,o$ as ReadTool,k0 as ProtocolConverter,b as ModelError,X0 as InMemoryStateStore,x$ as HookManager,n$ as GrepTool,r$ as GlobTool,T1 as FilteredToolRegistry,H0 as FileStateStore,i$ as EditTool,l$ as BashTool,v as BaseTool,G0 as BaseSessionManager,$$ as BaseSession,c$ as AstGrepSearchTool,p$ as AstGrepReplaceTool,g$ as AskUserTool,i0 as AgentMaxIterationsError,F$ as AgentAbortError,A$ as Agent,g0 as ACPAgent};
|