@code-yeongyu/senpi 2026.9.28-4 → 2026.9.28-5

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.
Files changed (164) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/dist/bundle/chunks/{anthropic-messages-W2XLZZ35.js → anthropic-messages-GG4ZKS6A.js} +2 -2
  3. package/dist/bundle/chunks/{app-server-command-7LBMB34E.js → app-server-command-3AJWPHKJ.js} +1 -1
  4. package/dist/bundle/chunks/{azure-openai-responses-WNELC744.js → azure-openai-responses-ZAJSIEAV.js} +1 -1
  5. package/dist/bundle/chunks/{chunk-UTGOAXS6.js → chunk-4BDFNRBE.js} +1 -1
  6. package/dist/bundle/chunks/{chunk-OLQI7DUR.js → chunk-7SFG425F.js} +1 -1
  7. package/dist/bundle/chunks/chunk-7X4ZMME4.js +2 -0
  8. package/dist/bundle/chunks/chunk-BQGVC47Y.js +3 -0
  9. package/dist/bundle/chunks/chunk-C5I2LUOI.js +2 -0
  10. package/dist/bundle/chunks/{chunk-3JX3X45G.js → chunk-CXVI2YV7.js} +1 -1
  11. package/dist/bundle/chunks/{chunk-RKIAHDIB.js → chunk-EXUI5D5V.js} +14 -13
  12. package/dist/bundle/chunks/chunk-J5TMX734.js +2 -0
  13. package/dist/bundle/chunks/{chunk-TYN6XEJL.js → chunk-JCMOKXWG.js} +1 -1
  14. package/dist/bundle/chunks/{chunk-WQO75X37.js → chunk-JGRPPPHS.js} +1 -1
  15. package/dist/bundle/chunks/{chunk-YHT3LLIA.js → chunk-K3SEG6TJ.js} +1 -1
  16. package/dist/bundle/chunks/{chunk-ZORNIKXN.js → chunk-KDZAVHA7.js} +1 -1
  17. package/dist/bundle/chunks/{chunk-HVFSRIJI.js → chunk-KR2TJOGO.js} +1 -1
  18. package/dist/bundle/chunks/chunk-KRNXUTZJ.js +2 -0
  19. package/dist/bundle/chunks/{chunk-OH4ONX6R.js → chunk-LEAJXPT2.js} +4 -4
  20. package/dist/bundle/chunks/{chunk-7FIDRH2I.js → chunk-MMHQLGF2.js} +1 -1
  21. package/dist/bundle/chunks/{chunk-O3D7S64D.js → chunk-OHJLQ7BY.js} +1 -1
  22. package/dist/bundle/chunks/chunk-TJV2LFKM.js +2 -0
  23. package/dist/bundle/chunks/{chunk-6WDC7AEV.js → chunk-UDTWLXSQ.js} +1 -1
  24. package/dist/bundle/chunks/chunk-XNIX26QC.js +8 -0
  25. package/dist/bundle/chunks/{chunk-5LYDQMQY.js → chunk-XPJLBOWV.js} +1 -1
  26. package/dist/bundle/chunks/{chunk-C5FRNOUP.js → chunk-XYGXUFMG.js} +1 -1
  27. package/dist/bundle/chunks/{chunk-3JR7GC6P.js → chunk-YEMM3LPR.js} +1 -1
  28. package/dist/bundle/chunks/{chunk-KAFTHZWC.js → chunk-YLIS5N3W.js} +1 -1
  29. package/dist/bundle/chunks/{chunk-4BK43Q6Z.js → chunk-Z5NVK72W.js} +1 -1
  30. package/dist/bundle/chunks/cli-main-NUSBF3HE.js +3 -0
  31. package/dist/bundle/chunks/github-copilot.js +1 -1
  32. package/dist/bundle/chunks/{google-generative-ai-FUULH4UE.js → google-generative-ai-C4YRAMFN.js} +1 -1
  33. package/dist/bundle/chunks/{google-vertex-PLXS45T4.js → google-vertex-4ZM6HGYI.js} +1 -1
  34. package/dist/bundle/chunks/help-fast-path-A4S4KOQ6.js +2 -0
  35. package/dist/bundle/chunks/host-command-D2CHSATG.js +2 -0
  36. package/dist/bundle/chunks/host-lifecycle-S7O5K62Z.js +3 -0
  37. package/dist/bundle/chunks/interactive-host-runtime-AAK47HIV.js +4 -0
  38. package/dist/bundle/chunks/interactive-mode-LSTD6EUQ.js +2 -0
  39. package/dist/bundle/chunks/{mistral-conversations-G5CGRCMV.js → mistral-conversations-7SROSYOE.js} +1 -1
  40. package/dist/bundle/chunks/{multi-session-host-GJCSLVES.js → multi-session-host-5WNZ7XRV.js} +1 -1
  41. package/dist/bundle/chunks/{openai-codex-responses-4JOIWFJF.js → openai-codex-responses-2ZNOPGE4.js} +1 -1
  42. package/dist/bundle/chunks/{openai-completions-XDHNDF3Z.js → openai-completions-DVEOAQK4.js} +1 -1
  43. package/dist/bundle/chunks/{openai-images-I7DR7ERP.js → openai-images-AEFVNUTL.js} +1 -1
  44. package/dist/bundle/chunks/openai-responses-7H2ADNW4.js +2 -0
  45. package/dist/bundle/chunks/{openrouter-images-IPNDRK6C.js → openrouter-images-N4NZJKSF.js} +1 -1
  46. package/dist/bundle/chunks/{package-manager-cli-E2SGFMXL.js → package-manager-cli-3HZYQYVX.js} +1 -1
  47. package/dist/bundle/chunks/rotation-stream-F36RJ6VP.js +2 -0
  48. package/dist/bundle/chunks/rpc-mode-GMPBEVSL.js +2 -0
  49. package/dist/bundle/chunks/{schedule-command-UKBZQK3Y.js → schedule-command-BYWZGYOJ.js} +1 -1
  50. package/dist/bundle/chunks/session-picker-6VU2F5VF.js +2 -0
  51. package/dist/bundle/chunks/session-worker.js +175 -173
  52. package/dist/bundle/cli.js +1 -1
  53. package/dist/bundle/index.js +1 -1
  54. package/dist/bundle/rpc-entry.js +1 -1
  55. package/dist/core/credential-pool/rejected-token-retry.d.ts +24 -0
  56. package/dist/core/credential-pool/rejected-token-retry.d.ts.map +1 -0
  57. package/dist/core/credential-pool/rejected-token-retry.js +76 -0
  58. package/dist/core/credential-pool/rejected-token-retry.js.map +1 -0
  59. package/dist/core/credential-pool/rotation-events.d.ts +1 -0
  60. package/dist/core/credential-pool/rotation-events.d.ts.map +1 -1
  61. package/dist/core/credential-pool/rotation-events.js +4 -2
  62. package/dist/core/credential-pool/rotation-events.js.map +1 -1
  63. package/dist/core/extensions/builtin/goal/agent-end-continuation.d.ts.map +1 -1
  64. package/dist/core/extensions/builtin/goal/agent-end-continuation.js +13 -1
  65. package/dist/core/extensions/builtin/goal/agent-end-continuation.js.map +1 -1
  66. package/dist/core/extensions/builtin/goal/continuation-recovery.d.ts +8 -0
  67. package/dist/core/extensions/builtin/goal/continuation-recovery.d.ts.map +1 -1
  68. package/dist/core/extensions/builtin/goal/continuation-recovery.js +22 -0
  69. package/dist/core/extensions/builtin/goal/continuation-recovery.js.map +1 -1
  70. package/dist/core/extensions/builtin/goal/terminal-provider-error.d.ts +11 -0
  71. package/dist/core/extensions/builtin/goal/terminal-provider-error.d.ts.map +1 -1
  72. package/dist/core/extensions/builtin/goal/terminal-provider-error.js +31 -0
  73. package/dist/core/extensions/builtin/goal/terminal-provider-error.js.map +1 -1
  74. package/dist/core/model-resolver.js +1 -1
  75. package/dist/core/model-resolver.js.map +1 -1
  76. package/dist/core/model-runtime.d.ts +7 -0
  77. package/dist/core/model-runtime.d.ts.map +1 -1
  78. package/dist/core/model-runtime.js +34 -19
  79. package/dist/core/model-runtime.js.map +1 -1
  80. package/dist/core/retry-fallback/cooldown.d.ts.map +1 -1
  81. package/dist/core/retry-fallback/cooldown.js +2 -1
  82. package/dist/core/retry-fallback/cooldown.js.map +1 -1
  83. package/dist/modes/interactive/interactive-mode.d.ts +1 -0
  84. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  85. package/dist/modes/interactive/interactive-mode.js +13 -0
  86. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  87. package/node_modules/@code-yeongyu/senpi-codemode/CHANGELOG.md +12 -0
  88. package/node_modules/@code-yeongyu/senpi-codemode/package.json +4 -4
  89. package/node_modules/@earendil-works/pi-agent-core/package.json +3 -3
  90. package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.d.ts.map +1 -1
  91. package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.js +8 -1
  92. package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.js.map +1 -1
  93. package/node_modules/@earendil-works/pi-ai/dist/api/github-copilot-errors.d.ts +9 -0
  94. package/node_modules/@earendil-works/pi-ai/dist/api/github-copilot-errors.d.ts.map +1 -0
  95. package/node_modules/@earendil-works/pi-ai/dist/api/github-copilot-errors.js +75 -0
  96. package/node_modules/@earendil-works/pi-ai/dist/api/github-copilot-errors.js.map +1 -0
  97. package/node_modules/@earendil-works/pi-ai/dist/api/github-copilot-headers.d.ts +1 -0
  98. package/node_modules/@earendil-works/pi-ai/dist/api/github-copilot-headers.d.ts.map +1 -1
  99. package/node_modules/@earendil-works/pi-ai/dist/api/github-copilot-headers.js +3 -0
  100. package/node_modules/@earendil-works/pi-ai/dist/api/github-copilot-headers.js.map +1 -1
  101. package/node_modules/@earendil-works/pi-ai/dist/api/openai-completions.d.ts.map +1 -1
  102. package/node_modules/@earendil-works/pi-ai/dist/api/openai-completions.js +8 -1
  103. package/node_modules/@earendil-works/pi-ai/dist/api/openai-completions.js.map +1 -1
  104. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.d.ts.map +1 -1
  105. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.js +21 -2
  106. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.js.map +1 -1
  107. package/node_modules/@earendil-works/pi-ai/dist/auth/helpers.d.ts +1 -0
  108. package/node_modules/@earendil-works/pi-ai/dist/auth/helpers.d.ts.map +1 -1
  109. package/node_modules/@earendil-works/pi-ai/dist/auth/helpers.js +1 -0
  110. package/node_modules/@earendil-works/pi-ai/dist/auth/helpers.js.map +1 -1
  111. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/github-copilot-model-catalog.d.ts +7 -0
  112. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/github-copilot-model-catalog.d.ts.map +1 -0
  113. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/github-copilot-model-catalog.js +46 -0
  114. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/github-copilot-model-catalog.js.map +1 -0
  115. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/github-copilot.d.ts.map +1 -1
  116. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/github-copilot.js +6 -41
  117. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/github-copilot.js.map +1 -1
  118. package/node_modules/@earendil-works/pi-ai/dist/auth/resolve.d.ts +6 -0
  119. package/node_modules/@earendil-works/pi-ai/dist/auth/resolve.d.ts.map +1 -1
  120. package/node_modules/@earendil-works/pi-ai/dist/auth/resolve.js +6 -5
  121. package/node_modules/@earendil-works/pi-ai/dist/auth/resolve.js.map +1 -1
  122. package/node_modules/@earendil-works/pi-ai/dist/auth/types.d.ts +7 -0
  123. package/node_modules/@earendil-works/pi-ai/dist/auth/types.d.ts.map +1 -1
  124. package/node_modules/@earendil-works/pi-ai/dist/auth/types.js.map +1 -1
  125. package/node_modules/@earendil-works/pi-ai/dist/providers/data/.manifest.json +1 -1
  126. package/node_modules/@earendil-works/pi-ai/dist/providers/data/openrouter.json +1 -1
  127. package/node_modules/@earendil-works/pi-ai/dist/providers/github-copilot-limits.d.ts +11 -0
  128. package/node_modules/@earendil-works/pi-ai/dist/providers/github-copilot-limits.d.ts.map +1 -0
  129. package/node_modules/@earendil-works/pi-ai/dist/providers/github-copilot-limits.js +65 -0
  130. package/node_modules/@earendil-works/pi-ai/dist/providers/github-copilot-limits.js.map +1 -0
  131. package/node_modules/@earendil-works/pi-ai/dist/providers/github-copilot.d.ts.map +1 -1
  132. package/node_modules/@earendil-works/pi-ai/dist/providers/github-copilot.js +9 -2
  133. package/node_modules/@earendil-works/pi-ai/dist/providers/github-copilot.js.map +1 -1
  134. package/node_modules/@earendil-works/pi-ai/dist/utils/github-copilot-tool-limit.d.ts +10 -0
  135. package/node_modules/@earendil-works/pi-ai/dist/utils/github-copilot-tool-limit.d.ts.map +1 -0
  136. package/node_modules/@earendil-works/pi-ai/dist/utils/github-copilot-tool-limit.js +75 -0
  137. package/node_modules/@earendil-works/pi-ai/dist/utils/github-copilot-tool-limit.js.map +1 -0
  138. package/node_modules/@earendil-works/pi-ai/dist/utils/overflow.js +1 -1
  139. package/node_modules/@earendil-works/pi-ai/dist/utils/overflow.js.map +1 -1
  140. package/node_modules/@earendil-works/pi-ai/dist/utils/retry.d.ts +3 -0
  141. package/node_modules/@earendil-works/pi-ai/dist/utils/retry.d.ts.map +1 -1
  142. package/node_modules/@earendil-works/pi-ai/dist/utils/retry.js +15 -3
  143. package/node_modules/@earendil-works/pi-ai/dist/utils/retry.js.map +1 -1
  144. package/node_modules/@earendil-works/pi-ai/package.json +2 -2
  145. package/node_modules/@earendil-works/pi-pty/package.json +1 -1
  146. package/node_modules/@earendil-works/pi-telemetry/package.json +1 -1
  147. package/node_modules/@earendil-works/pi-tui/package.json +1 -1
  148. package/package.json +7 -7
  149. package/dist/bundle/chunks/chunk-2E2FN2VJ.js +0 -2
  150. package/dist/bundle/chunks/chunk-DM3AVOKA.js +0 -2
  151. package/dist/bundle/chunks/chunk-EDU27GXU.js +0 -2
  152. package/dist/bundle/chunks/chunk-NAIMNKNG.js +0 -2
  153. package/dist/bundle/chunks/chunk-PUWVIQW6.js +0 -2
  154. package/dist/bundle/chunks/chunk-S5Q3WPVR.js +0 -8
  155. package/dist/bundle/chunks/cli-main-LVTTAX7I.js +0 -3
  156. package/dist/bundle/chunks/help-fast-path-PCN7D4UN.js +0 -2
  157. package/dist/bundle/chunks/host-command-FETBGITW.js +0 -2
  158. package/dist/bundle/chunks/host-lifecycle-FW6LQ6SW.js +0 -3
  159. package/dist/bundle/chunks/interactive-host-runtime-7RUBGCMP.js +0 -4
  160. package/dist/bundle/chunks/interactive-mode-FDQ4N3JQ.js +0 -2
  161. package/dist/bundle/chunks/openai-responses-MQUMRQVY.js +0 -2
  162. package/dist/bundle/chunks/rotation-stream-3KJLEXQQ.js +0 -2
  163. package/dist/bundle/chunks/rpc-mode-435L7DOL.js +0 -2
  164. package/dist/bundle/chunks/session-picker-JHFPLMON.js +0 -2
@@ -1,3 +1,3 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire as __piCreateRequire } from "node:module"; const require = __piCreateRequire(import.meta.url); { const __piWorkerThreads = require("node:worker_threads"); if (typeof __piWorkerThreads.markAsUncloneable !== "function") { __piWorkerThreads.markAsUncloneable = () => {}; } }
3
- import{enableStartupCompileCache}from"./chunks/chunk-F73COJ7R.js";import{getLatestPiRelease,hasInheritedInspectorOption,isNewerPackageVersion,processBunRuntimeOptions,releaseInheritedInspectorForChild,resolveBunReexec}from"./chunks/chunk-4LVZQRDG.js";import"./chunks/chunk-ZOFZRJSL.js";import"./chunks/chunk-2SOVDETB.js";import{APP_NAME,DISPLAY_VERSION,PACKAGE_NAME,VERSION,brandProfile,getAgentDir,getPackageDir,getSelfUpdateCommand,getSelfUpdateUnavailableInstruction,isBundledNode}from"./chunks/chunk-PBWQK23Z.js";import"./chunks/chunk-ATQFN5HI.js";import"./chunks/chunk-IKOFCODM.js";import{spawn as spawn2,spawnSync}from"node:child_process";import{existsSync,realpathSync}from"node:fs";import{join as join2}from"node:path";import{fileURLToPath}from"node:url";import{spawn}from"node:child_process";import{readFileSync}from"node:fs";import{join}from"node:path";function parseBootstrapSelfUpdateArgs(args2){let[command,...rest]=args2;if(command!=="update")return;let force=!1,selfFlag=!1,extensionsFlag=!1,extensionFlag=!1,source;for(let index=0;index<rest.length;index++){let arg=rest[index];if(arg==="-h"||arg==="--help")return;if(arg==="--force"){force=!0;continue}if(arg==="--self"){selfFlag=!0;continue}if(arg==="--extensions"){extensionsFlag=!0;continue}if(arg==="--extension"){extensionFlag=!0,index++;continue}if(arg.startsWith("-")||source)return;source=arg}if(extensionFlag)return;let sourceIsSelf=source==="self"||source==="pi"||source===APP_NAME;if(!(source&&!sourceIsSelf)&&!(!selfFlag&&!sourceIsSelf&&extensionsFlag))return{force}}function getObjectProperty(value,key){if(!(!value||typeof value!="object"))return Object.getOwnPropertyDescriptor(value,key)?.value}function readConfiguredNpmCommand(){try{let parsed=JSON.parse(readFileSync(join(getAgentDir(),"settings.json"),"utf-8")),npmCommand=getObjectProperty(parsed,"npmCommand");return!Array.isArray(npmCommand)||npmCommand.some(part=>typeof part!="string")?void 0:npmCommand.length>0?npmCommand:void 0}catch{return}}async function runCommand(step){await new Promise((resolve,reject)=>{let child=spawn(step.command,step.args,{stdio:"inherit"});child.on("error",error=>{reject(error)}),child.on("close",(code,signal)=>{code===0?resolve():reject(signal?new Error(`${step.display} terminated by signal ${signal}`):new Error(`${step.display} exited with code ${code??"unknown"}`))})})}async function handleBootstrapSelfUpdate(args2,dependencies={}){let parsed=parseBootstrapSelfUpdateArgs(args2);if(!parsed)return!1;let writeStdout=dependencies.writeStdout??(line=>console.log(line)),writeStderr=dependencies.writeStderr??(line=>console.error(line)),readNpmCommand=dependencies.readNpmCommand??readConfiguredNpmCommand,resolveSelfUpdateCommand=dependencies.getSelfUpdateCommand??getSelfUpdateCommand,resolveUnavailableInstruction=dependencies.getUnavailableInstruction??getSelfUpdateUnavailableInstruction,executeCommand=dependencies.runCommand??runCommand,brandUpdate=brandProfile()?.update;if(brandUpdate)return writeStdout(`${APP_NAME} ships inside ${brandUpdate.packageName}. Update it with: ${brandUpdate.command}`),!0;let loadLatestRelease=dependencies.getLatestRelease??getLatestPiRelease,latestRelease;if(!parsed.force)try{latestRelease=await loadLatestRelease(VERSION)}catch{latestRelease=void 0}let updatePackageName=latestRelease?.packageName??PACKAGE_NAME;if(!(parsed.force||!latestRelease||updatePackageName!==PACKAGE_NAME||isNewerPackageVersion(latestRelease.version,VERSION)))return writeStdout(`${APP_NAME} is already up to date (v${VERSION})`),!0;let npmCommand=readNpmCommand(),selfUpdateCommand=resolveSelfUpdateCommand(PACKAGE_NAME,npmCommand,updatePackageName);if(!selfUpdateCommand)return writeStderr(`error: ${APP_NAME} cannot self-update this installation.`),writeStderr(resolveUnavailableInstruction(PACKAGE_NAME,npmCommand,updatePackageName)),process.argv[1]&&(writeStderr(""),writeStderr(`Location of ${APP_NAME} executable: ${process.argv[1]}`)),process.exitCode=1,!0;latestRelease?.note?.trim()&&(writeStdout(""),writeStdout("Update note"),writeStdout(latestRelease.note.trim()),writeStdout("")),writeStdout(`Updating ${APP_NAME} with ${selfUpdateCommand.display}...`);for(let step of selfUpdateCommand.steps??[selfUpdateCommand])try{await executeCommand(step)}catch(error){let message=error instanceof Error?error.message:"Unknown package command error";return writeStderr(`Error: ${message}`),writeStderr(`If this keeps failing, run this command yourself: ${selfUpdateCommand.display}`),process.exitCode=1,!0}return writeStdout(`Updated ${APP_NAME}`),!0}function reexecUnderBunIfNeeded(){let options=processBunRuntimeOptions(existsSync,realpathSync),scriptRealPath=process.argv[1]??fileURLToPath(import.meta.url);try{scriptRealPath=realpathSync(scriptRealPath)}catch{}let decision=resolveBunReexec({scriptRealPath,versions:process.versions,hasInheritedInspectorOption:hasInheritedInspectorOption(),options});if(decision.action==="stay")return!1;let result=spawnSync(decision.bunPath,[scriptRealPath,...process.argv.slice(2)],{stdio:"inherit",windowsHide:!0});return result.signal?(process.kill(process.pid,result.signal),!0):(process.exitCode=result.status??1,!0)}reexecUnderBunIfNeeded()&&process.exit();enableStartupCompileCache();process.title=APP_NAME;process.env.PI_CODING_AGENT="true";process.env.AI_AGENT=APP_NAME;process.emitWarning=(()=>{});var args=process.argv.slice(2),PACKAGE_COMMANDS=new Set(["install","remove","uninstall","update","list","config"]);function isRootCommand(args2){let firstArg=args2[0];return firstArg===void 0||!PACKAGE_COMMANDS.has(firstArg)}function isPackageManagerInstall(packageDir){return packageDir.replace(/\\/g,"/").includes("/node_modules/@code-yeongyu/senpi")}function isMissingBundledWorkspaceDependencies(packageDir){return isPackageManagerInstall(packageDir)?["pi-agent-core","pi-ai","pi-tui"].some(name=>!existsSync(join2(packageDir,"node_modules","@earendil-works",name,"dist","index.js"))):!1}var ISOLATED_CHILD_ENV="SENPI_CLI_ISOLATED_CHILD";function requiresIsolatedProcess(){return process.env[ISOLATED_CHILD_ENV]==="1"?!1:process.execArgv.length>0||hasInheritedInspectorOption()}async function spawnFullCli(){let extension=import.meta.url.endsWith(".ts")?".ts":".js",fullCliPath=isBundledNode?fileURLToPath(import.meta.url):fileURLToPath(new URL(`./cli-main${extension}`,import.meta.url));releaseInheritedInspectorForChild();let childEnvironment=isBundledNode?{...process.env,[ISOLATED_CHILD_ENV]:"1"}:process.env;return await new Promise((resolve,reject)=>{let child=spawn2(process.execPath,[...process.execArgv,fullCliPath,...args],{env:childEnvironment,stdio:"inherit"});child.on("error",error=>{reject(error)}),child.on("close",(code,signal)=>{if(signal){process.kill(process.pid,signal),resolve(1);return}resolve(code??1)})})}isRootCommand(args)&&(args.includes("--version")||args.includes("-v"))&&(console.log(DISPLAY_VERSION),process.exit());if(isRootCommand(args)&&args.some(arg=>arg==="--help"||arg==="-h")){let{tryPrintHelpWithoutEngine}=await import("./chunks/help-fast-path-PCN7D4UN.js");tryPrintHelpWithoutEngine(args)&&process.exit()}isMissingBundledWorkspaceDependencies(getPackageDir())&&await handleBootstrapSelfUpdate(args)&&process.exit();requiresIsolatedProcess()?process.exitCode=await spawnFullCli():await import("./chunks/cli-main-LVTTAX7I.js");
3
+ import{enableStartupCompileCache}from"./chunks/chunk-F73COJ7R.js";import{getLatestPiRelease,hasInheritedInspectorOption,isNewerPackageVersion,processBunRuntimeOptions,releaseInheritedInspectorForChild,resolveBunReexec}from"./chunks/chunk-4LVZQRDG.js";import"./chunks/chunk-ZOFZRJSL.js";import"./chunks/chunk-2SOVDETB.js";import{APP_NAME,DISPLAY_VERSION,PACKAGE_NAME,VERSION,brandProfile,getAgentDir,getPackageDir,getSelfUpdateCommand,getSelfUpdateUnavailableInstruction,isBundledNode}from"./chunks/chunk-PBWQK23Z.js";import"./chunks/chunk-ATQFN5HI.js";import"./chunks/chunk-IKOFCODM.js";import{spawn as spawn2,spawnSync}from"node:child_process";import{existsSync,realpathSync}from"node:fs";import{join as join2}from"node:path";import{fileURLToPath}from"node:url";import{spawn}from"node:child_process";import{readFileSync}from"node:fs";import{join}from"node:path";function parseBootstrapSelfUpdateArgs(args2){let[command,...rest]=args2;if(command!=="update")return;let force=!1,selfFlag=!1,extensionsFlag=!1,extensionFlag=!1,source;for(let index=0;index<rest.length;index++){let arg=rest[index];if(arg==="-h"||arg==="--help")return;if(arg==="--force"){force=!0;continue}if(arg==="--self"){selfFlag=!0;continue}if(arg==="--extensions"){extensionsFlag=!0;continue}if(arg==="--extension"){extensionFlag=!0,index++;continue}if(arg.startsWith("-")||source)return;source=arg}if(extensionFlag)return;let sourceIsSelf=source==="self"||source==="pi"||source===APP_NAME;if(!(source&&!sourceIsSelf)&&!(!selfFlag&&!sourceIsSelf&&extensionsFlag))return{force}}function getObjectProperty(value,key){if(!(!value||typeof value!="object"))return Object.getOwnPropertyDescriptor(value,key)?.value}function readConfiguredNpmCommand(){try{let parsed=JSON.parse(readFileSync(join(getAgentDir(),"settings.json"),"utf-8")),npmCommand=getObjectProperty(parsed,"npmCommand");return!Array.isArray(npmCommand)||npmCommand.some(part=>typeof part!="string")?void 0:npmCommand.length>0?npmCommand:void 0}catch{return}}async function runCommand(step){await new Promise((resolve,reject)=>{let child=spawn(step.command,step.args,{stdio:"inherit"});child.on("error",error=>{reject(error)}),child.on("close",(code,signal)=>{code===0?resolve():reject(signal?new Error(`${step.display} terminated by signal ${signal}`):new Error(`${step.display} exited with code ${code??"unknown"}`))})})}async function handleBootstrapSelfUpdate(args2,dependencies={}){let parsed=parseBootstrapSelfUpdateArgs(args2);if(!parsed)return!1;let writeStdout=dependencies.writeStdout??(line=>console.log(line)),writeStderr=dependencies.writeStderr??(line=>console.error(line)),readNpmCommand=dependencies.readNpmCommand??readConfiguredNpmCommand,resolveSelfUpdateCommand=dependencies.getSelfUpdateCommand??getSelfUpdateCommand,resolveUnavailableInstruction=dependencies.getUnavailableInstruction??getSelfUpdateUnavailableInstruction,executeCommand=dependencies.runCommand??runCommand,brandUpdate=brandProfile()?.update;if(brandUpdate)return writeStdout(`${APP_NAME} ships inside ${brandUpdate.packageName}. Update it with: ${brandUpdate.command}`),!0;let loadLatestRelease=dependencies.getLatestRelease??getLatestPiRelease,latestRelease;if(!parsed.force)try{latestRelease=await loadLatestRelease(VERSION)}catch{latestRelease=void 0}let updatePackageName=latestRelease?.packageName??PACKAGE_NAME;if(!(parsed.force||!latestRelease||updatePackageName!==PACKAGE_NAME||isNewerPackageVersion(latestRelease.version,VERSION)))return writeStdout(`${APP_NAME} is already up to date (v${VERSION})`),!0;let npmCommand=readNpmCommand(),selfUpdateCommand=resolveSelfUpdateCommand(PACKAGE_NAME,npmCommand,updatePackageName);if(!selfUpdateCommand)return writeStderr(`error: ${APP_NAME} cannot self-update this installation.`),writeStderr(resolveUnavailableInstruction(PACKAGE_NAME,npmCommand,updatePackageName)),process.argv[1]&&(writeStderr(""),writeStderr(`Location of ${APP_NAME} executable: ${process.argv[1]}`)),process.exitCode=1,!0;latestRelease?.note?.trim()&&(writeStdout(""),writeStdout("Update note"),writeStdout(latestRelease.note.trim()),writeStdout("")),writeStdout(`Updating ${APP_NAME} with ${selfUpdateCommand.display}...`);for(let step of selfUpdateCommand.steps??[selfUpdateCommand])try{await executeCommand(step)}catch(error){let message=error instanceof Error?error.message:"Unknown package command error";return writeStderr(`Error: ${message}`),writeStderr(`If this keeps failing, run this command yourself: ${selfUpdateCommand.display}`),process.exitCode=1,!0}return writeStdout(`Updated ${APP_NAME}`),!0}function reexecUnderBunIfNeeded(){let options=processBunRuntimeOptions(existsSync,realpathSync),scriptRealPath=process.argv[1]??fileURLToPath(import.meta.url);try{scriptRealPath=realpathSync(scriptRealPath)}catch{}let decision=resolveBunReexec({scriptRealPath,versions:process.versions,hasInheritedInspectorOption:hasInheritedInspectorOption(),options});if(decision.action==="stay")return!1;let result=spawnSync(decision.bunPath,[scriptRealPath,...process.argv.slice(2)],{stdio:"inherit",windowsHide:!0});return result.signal?(process.kill(process.pid,result.signal),!0):(process.exitCode=result.status??1,!0)}reexecUnderBunIfNeeded()&&process.exit();enableStartupCompileCache();process.title=APP_NAME;process.env.PI_CODING_AGENT="true";process.env.AI_AGENT=APP_NAME;process.emitWarning=(()=>{});var args=process.argv.slice(2),PACKAGE_COMMANDS=new Set(["install","remove","uninstall","update","list","config"]);function isRootCommand(args2){let firstArg=args2[0];return firstArg===void 0||!PACKAGE_COMMANDS.has(firstArg)}function isPackageManagerInstall(packageDir){return packageDir.replace(/\\/g,"/").includes("/node_modules/@code-yeongyu/senpi")}function isMissingBundledWorkspaceDependencies(packageDir){return isPackageManagerInstall(packageDir)?["pi-agent-core","pi-ai","pi-tui"].some(name=>!existsSync(join2(packageDir,"node_modules","@earendil-works",name,"dist","index.js"))):!1}var ISOLATED_CHILD_ENV="SENPI_CLI_ISOLATED_CHILD";function requiresIsolatedProcess(){return process.env[ISOLATED_CHILD_ENV]==="1"?!1:process.execArgv.length>0||hasInheritedInspectorOption()}async function spawnFullCli(){let extension=import.meta.url.endsWith(".ts")?".ts":".js",fullCliPath=isBundledNode?fileURLToPath(import.meta.url):fileURLToPath(new URL(`./cli-main${extension}`,import.meta.url));releaseInheritedInspectorForChild();let childEnvironment=isBundledNode?{...process.env,[ISOLATED_CHILD_ENV]:"1"}:process.env;return await new Promise((resolve,reject)=>{let child=spawn2(process.execPath,[...process.execArgv,fullCliPath,...args],{env:childEnvironment,stdio:"inherit"});child.on("error",error=>{reject(error)}),child.on("close",(code,signal)=>{if(signal){process.kill(process.pid,signal),resolve(1);return}resolve(code??1)})})}isRootCommand(args)&&(args.includes("--version")||args.includes("-v"))&&(console.log(DISPLAY_VERSION),process.exit());if(isRootCommand(args)&&args.some(arg=>arg==="--help"||arg==="-h")){let{tryPrintHelpWithoutEngine}=await import("./chunks/help-fast-path-A4S4KOQ6.js");tryPrintHelpWithoutEngine(args)&&process.exit()}isMissingBundledWorkspaceDependencies(getPackageDir())&&await handleBootstrapSelfUpdate(args)&&process.exit();requiresIsolatedProcess()?process.exitCode=await spawnFullCli():await import("./chunks/cli-main-NUSBF3HE.js");
@@ -1,2 +1,2 @@
1
1
  import { createRequire as __piCreateRequire } from "node:module"; const require = __piCreateRequire(import.meta.url); { const __piWorkerThreads = require("node:worker_threads"); if (typeof __piWorkerThreads.markAsUncloneable !== "function") { __piWorkerThreads.markAsUncloneable = () => {}; } }
2
- import{AgentSession,AgentSessionRuntime,ArminComponent,AssistantMessageComponent,BashExecutionComponent,BorderedLoader,BranchSummaryMessageComponent,CompactionSummaryMessageComponent,CredentialSynchronizationError,CustomEditor,CustomMessageComponent,DEFAULT_COMPACTION_SETTINGS,DefaultResourceLoader,ExtensionEditorComponent,ExtensionRunner,FooterComponent,InteractiveMode,LoginDialogComponent,ModelRegistry,ModelRuntime,ModelSelectorComponent,OAuthSelectorComponent,SettingsSelectorComponent,ShowImagesSelectorComponent,SkillInvocationMessageComponent,ThemeSelectorComponent,ThinkingSelectorComponent,ToolExecutionComponent,TreeSelectorComponent,UserMessageComponent,UserMessageSelectorComponent,buildNoticeBox,calculateContextTokens,classifyRead,collectEntriesForBranchSummary,collectOrphanedChildren,compact,connectWebViewService,convertToPng,copyToClipboard,createAgentSession,createAgentSessionFromServices,createAgentSessionRuntime,createAgentSessionServices,createBashTool,createBashToolDefinition,createCodingTools,createEditTool,createEditToolDefinition,createEventBus,createExtensionRuntime,createFindTool,createFindToolDefinition,createGrepTool,createGrepToolDefinition,createLocalBashOperations,createLsTool,createLsToolDefinition,createPowerShellTool,createReadOnlyTools,createReadTool,createReadToolDefinition,createSyntheticSourceInfo,createWriteTool,createWriteToolDefinition,defineTool,detectSupportedImageMimeTypeFromFile,discoverAndLoadExtensions,estimateTokens,findCutPoint,findTurnStartIndex,formatDimensionNote,formatSkillsForPrompt,generateBranchSummary,generateDiffString,generateSummary,generateSummaryWithUsage,generateUnifiedPatch,getLastAssistantUsage,isBashToolResult,isEditToolResult,isFindToolResult,isGrepToolResult,isLsToolResult,isPowerShellToolResult,isReadToolResult,isToolCallEventType,isWriteToolResult,kernelToolsStorage,loadProjectContextFiles,loadSkills,loadSkillsFromDir,main,noticeEntryRenderer,noticeMessageRenderer,parseFrontmatter,parseSkillBlock,prepareBranchEntries,readOwnFootprint,readProcessFootprint,readStoredCredential,registerReadClassifier,renderDiff,resizeImage,resolveCliModel,resolveModelScopeWithDiagnostics,runPrintMode,serializeConversation,shouldCompact,stripFrontmatter,truncateToVisualLines,withFileMutationQueue,wrapRegisteredTool,wrapRegisteredTools}from"./chunks/chunk-RKIAHDIB.js";import"./chunks/chunk-FAV4DX74.js";import{DefaultPackageManager,DynamicBorder,ExtensionInputComponent,ExtensionSelectorComponent,SessionSelectorComponent,keyHint,keyText,rawKeyHint}from"./chunks/chunk-3JR7GC6P.js";import"./chunks/chunk-A4UMPXQF.js";import"./chunks/chunk-TFA3YAJK.js";import{CURRENT_SESSION_VERSION,DEFAULT_MAX_BYTES,DEFAULT_MAX_LINES,RpcClient,RpcClientOpenInFlightError,RpcTransportGoneError,SessionManager,buildContextEntries,buildSessionContext,convertToLlm,formatSize,getLatestCompactionEntry,isTransportGoneError,migrateSessionEntries,parseSessionEntries,sessionEntryToContextMessages,truncateHead,truncateLine,truncateTail}from"./chunks/chunk-O3D7S64D.js";import"./chunks/chunk-NZRVAZL2.js";import"./chunks/chunk-U5KVIAHJ.js";import{runRpcMode}from"./chunks/chunk-S5Q3WPVR.js";import{Theme,getLanguageFromPath,getMarkdownTheme,getSelectListTheme,getSettingsListTheme,highlightCode,initTheme}from"./chunks/chunk-C5FRNOUP.js";import{sanitizeTerminalLabel}from"./chunks/chunk-6BWCPOCV.js";import"./chunks/chunk-7FIDRH2I.js";import{SettingsManager}from"./chunks/chunk-3JX3X45G.js";import"./chunks/chunk-YU2P3CAR.js";import"./chunks/chunk-BMX2U22F.js";import{DEFAULT_HOST_LAUNCH_SPEC,HOST_EXIT_ERROR,HOST_EXIT_FALLBACK,HOST_EXIT_OK,HOST_EXIT_REFUSED,HOST_EXIT_USAGE,HostLaunchSpecError,loadHostLaunchSpec,parseHostLaunchSpec,readHostStatus,runHostCommand,runHostRequest}from"./chunks/chunk-WQO75X37.js";import{GENERATION_HANDOFF_CAPABILITY,HOST_PROTOCOL_VERSION,HostEnsureRefusedError,PINNED_HOST_CLIENT_CAPABILITIES,REQUIRED_HOST_CAPABILITIES,decideHostAction,ensureHost,handoffHost,parseHostProtocolInfo,probeHost,stopHost}from"./chunks/chunk-4BK43Q6Z.js";import"./chunks/chunk-HH3KJDWA.js";import{createHostDaemonPaths,daemonDirectoryName,shardKey,shardSocketPath,shardSocketPathForKey}from"./chunks/chunk-OLQI7DUR.js";import{compareEngineOrdinal,engineBuildIdentity,engineBuildIdentityFrom}from"./chunks/chunk-5LYDQMQY.js";import"./chunks/chunk-DA4W77J7.js";import"./chunks/chunk-H4QOEVS5.js";import"./chunks/chunk-HB35RBP4.js";import"./chunks/chunk-2E2FN2VJ.js";import"./chunks/chunk-KAFTHZWC.js";import{getPowerShellConfig,getShellConfig}from"./chunks/chunk-ASAQQ6VM.js";import"./chunks/chunk-36ACNYQR.js";import"./chunks/chunk-7X72IACK.js";import"./chunks/chunk-KUPQO7MC.js";import"./chunks/chunk-UTGOAXS6.js";import{ProjectTrustStore,hasTrustRequiringProjectResources}from"./chunks/chunk-Y5A6TKBN.js";import{parseArgs}from"./chunks/chunk-ZORNIKXN.js";import"./chunks/chunk-26UBFF6N.js";import"./chunks/chunk-OH4ONX6R.js";import"./chunks/chunk-GZVCRV7I.js";import"./chunks/chunk-U3VOXCGP.js";import"./chunks/chunk-RFB5CBW7.js";import"./chunks/chunk-2VZJTDUX.js";import"./chunks/chunk-6WDC7AEV.js";import"./chunks/chunk-BBK6SSYT.js";import"./chunks/chunk-4LVZQRDG.js";import"./chunks/chunk-ZOFZRJSL.js";import"./chunks/chunk-2SOVDETB.js";import{CONFIG_DIR_NAME,VERSION,getAgentDir,getDocsPath,getExamplesPath,getPackageDir,getReadmePath}from"./chunks/chunk-PBWQK23Z.js";import"./chunks/chunk-ATQFN5HI.js";import"./chunks/chunk-RBCQOIAD.js";import"./chunks/chunk-WASCMT6Y.js";import"./chunks/chunk-X4Q5YSTE.js";import"./chunks/chunk-IXAUDPOK.js";import"./chunks/chunk-NAIMNKNG.js";import"./chunks/chunk-LHYG7TK7.js";import"./chunks/chunk-45SZOLCU.js";import"./chunks/chunk-WVGCQOLJ.js";import"./chunks/chunk-BPX6QWPD.js";import"./chunks/chunk-EDU27GXU.js";import"./chunks/chunk-WDTJ6JKE.js";import"./chunks/chunk-5ROMKDLK.js";import"./chunks/chunk-3W47LTXQ.js";import"./chunks/chunk-DMI55M2N.js";import"./chunks/chunk-BQVVQ2LQ.js";import"./chunks/chunk-IKOFCODM.js";export{AgentSession,AgentSessionRuntime,ArminComponent,AssistantMessageComponent,BashExecutionComponent,BorderedLoader,BranchSummaryMessageComponent,CONFIG_DIR_NAME,CURRENT_SESSION_VERSION,CompactionSummaryMessageComponent,CredentialSynchronizationError,CustomEditor,CustomMessageComponent,DEFAULT_COMPACTION_SETTINGS,DEFAULT_HOST_LAUNCH_SPEC,DEFAULT_MAX_BYTES,DEFAULT_MAX_LINES,DefaultPackageManager,DefaultResourceLoader,DynamicBorder,ExtensionEditorComponent,ExtensionInputComponent,ExtensionRunner,ExtensionSelectorComponent,FooterComponent,GENERATION_HANDOFF_CAPABILITY,HOST_EXIT_ERROR,HOST_EXIT_FALLBACK,HOST_EXIT_OK,HOST_EXIT_REFUSED,HOST_EXIT_USAGE,HOST_PROTOCOL_VERSION,HostEnsureRefusedError,HostLaunchSpecError,InteractiveMode,LoginDialogComponent,ModelRegistry,ModelRuntime,ModelSelectorComponent,OAuthSelectorComponent,PINNED_HOST_CLIENT_CAPABILITIES,ProjectTrustStore,REQUIRED_HOST_CAPABILITIES,RpcClient,RpcClientOpenInFlightError,RpcTransportGoneError,SessionManager,SessionSelectorComponent,SettingsManager,SettingsSelectorComponent,ShowImagesSelectorComponent,SkillInvocationMessageComponent,Theme,ThemeSelectorComponent,ThinkingSelectorComponent,ToolExecutionComponent,TreeSelectorComponent,UserMessageComponent,UserMessageSelectorComponent,VERSION,buildContextEntries,buildNoticeBox,buildSessionContext,calculateContextTokens,classifyRead,collectEntriesForBranchSummary,collectOrphanedChildren,compact,compareEngineOrdinal,connectWebViewService,convertToLlm,convertToPng,copyToClipboard,createAgentSession,createAgentSessionFromServices,createAgentSessionRuntime,createAgentSessionServices,createBashTool,createBashToolDefinition,createCodingTools,createEditTool,createEditToolDefinition,createEventBus,createExtensionRuntime,createFindTool,createFindToolDefinition,createGrepTool,createGrepToolDefinition,createHostDaemonPaths,createLocalBashOperations,createLsTool,createLsToolDefinition,createPowerShellTool,createReadOnlyTools,createReadTool,createReadToolDefinition,createSyntheticSourceInfo,createWriteTool,createWriteToolDefinition,daemonDirectoryName,decideHostAction,defineTool,detectSupportedImageMimeTypeFromFile,discoverAndLoadExtensions,engineBuildIdentity,engineBuildIdentityFrom,ensureHost,estimateTokens,findCutPoint,findTurnStartIndex,formatDimensionNote,formatSize,formatSkillsForPrompt,generateBranchSummary,generateDiffString,generateSummary,generateSummaryWithUsage,generateUnifiedPatch,getAgentDir,getDocsPath,getExamplesPath,getLanguageFromPath,getLastAssistantUsage,getLatestCompactionEntry,getMarkdownTheme,getPackageDir,getPowerShellConfig,getReadmePath,getSelectListTheme,getSettingsListTheme,getShellConfig,handoffHost,hasTrustRequiringProjectResources,highlightCode,initTheme,isBashToolResult,isEditToolResult,isFindToolResult,isGrepToolResult,isLsToolResult,isPowerShellToolResult,isReadToolResult,isToolCallEventType,isTransportGoneError,isWriteToolResult,kernelToolsStorage,keyHint,keyText,loadHostLaunchSpec,loadProjectContextFiles,loadSkills,loadSkillsFromDir,main,migrateSessionEntries,noticeEntryRenderer,noticeMessageRenderer,parseArgs,parseFrontmatter,parseHostLaunchSpec,parseHostProtocolInfo,parseSessionEntries,parseSkillBlock,prepareBranchEntries,probeHost,rawKeyHint,readHostStatus,readOwnFootprint,readProcessFootprint,readStoredCredential,registerReadClassifier,renderDiff,resizeImage,resolveCliModel,resolveModelScopeWithDiagnostics,runHostCommand,runHostRequest,runPrintMode,runRpcMode,sanitizeTerminalLabel,serializeConversation,sessionEntryToContextMessages,shardKey,shardSocketPath,shardSocketPathForKey,shouldCompact,stopHost,stripFrontmatter,truncateHead,truncateLine,truncateTail,truncateToVisualLines,withFileMutationQueue,wrapRegisteredTool,wrapRegisteredTools};
2
+ import{AgentSession,AgentSessionRuntime,ArminComponent,AssistantMessageComponent,BashExecutionComponent,BorderedLoader,BranchSummaryMessageComponent,CompactionSummaryMessageComponent,CredentialSynchronizationError,CustomEditor,CustomMessageComponent,DEFAULT_COMPACTION_SETTINGS,DefaultResourceLoader,ExtensionEditorComponent,ExtensionRunner,FooterComponent,InteractiveMode,LoginDialogComponent,ModelRegistry,ModelRuntime,ModelSelectorComponent,OAuthSelectorComponent,SettingsSelectorComponent,ShowImagesSelectorComponent,SkillInvocationMessageComponent,ThemeSelectorComponent,ThinkingSelectorComponent,ToolExecutionComponent,TreeSelectorComponent,UserMessageComponent,UserMessageSelectorComponent,buildNoticeBox,calculateContextTokens,classifyRead,collectEntriesForBranchSummary,collectOrphanedChildren,compact,connectWebViewService,convertToPng,copyToClipboard,createAgentSession,createAgentSessionFromServices,createAgentSessionRuntime,createAgentSessionServices,createBashTool,createBashToolDefinition,createCodingTools,createEditTool,createEditToolDefinition,createEventBus,createExtensionRuntime,createFindTool,createFindToolDefinition,createGrepTool,createGrepToolDefinition,createLocalBashOperations,createLsTool,createLsToolDefinition,createPowerShellTool,createReadOnlyTools,createReadTool,createReadToolDefinition,createSyntheticSourceInfo,createWriteTool,createWriteToolDefinition,defineTool,detectSupportedImageMimeTypeFromFile,discoverAndLoadExtensions,estimateTokens,findCutPoint,findTurnStartIndex,formatDimensionNote,formatSkillsForPrompt,generateBranchSummary,generateDiffString,generateSummary,generateSummaryWithUsage,generateUnifiedPatch,getLastAssistantUsage,isBashToolResult,isEditToolResult,isFindToolResult,isGrepToolResult,isLsToolResult,isPowerShellToolResult,isReadToolResult,isToolCallEventType,isWriteToolResult,kernelToolsStorage,loadProjectContextFiles,loadSkills,loadSkillsFromDir,main,noticeEntryRenderer,noticeMessageRenderer,parseFrontmatter,parseSkillBlock,prepareBranchEntries,readOwnFootprint,readProcessFootprint,readStoredCredential,registerReadClassifier,renderDiff,resizeImage,resolveCliModel,resolveModelScopeWithDiagnostics,runPrintMode,serializeConversation,shouldCompact,stripFrontmatter,truncateToVisualLines,withFileMutationQueue,wrapRegisteredTool,wrapRegisteredTools}from"./chunks/chunk-EXUI5D5V.js";import"./chunks/chunk-FAV4DX74.js";import{DefaultPackageManager,DynamicBorder,ExtensionInputComponent,ExtensionSelectorComponent,SessionSelectorComponent,keyHint,keyText,rawKeyHint}from"./chunks/chunk-YEMM3LPR.js";import"./chunks/chunk-A4UMPXQF.js";import"./chunks/chunk-TFA3YAJK.js";import{CURRENT_SESSION_VERSION,DEFAULT_MAX_BYTES,DEFAULT_MAX_LINES,RpcClient,RpcClientOpenInFlightError,RpcTransportGoneError,SessionManager,buildContextEntries,buildSessionContext,convertToLlm,formatSize,getLatestCompactionEntry,isTransportGoneError,migrateSessionEntries,parseSessionEntries,sessionEntryToContextMessages,truncateHead,truncateLine,truncateTail}from"./chunks/chunk-OHJLQ7BY.js";import"./chunks/chunk-NZRVAZL2.js";import"./chunks/chunk-U5KVIAHJ.js";import{runRpcMode}from"./chunks/chunk-XNIX26QC.js";import{Theme,getLanguageFromPath,getMarkdownTheme,getSelectListTheme,getSettingsListTheme,highlightCode,initTheme}from"./chunks/chunk-XYGXUFMG.js";import{sanitizeTerminalLabel}from"./chunks/chunk-6BWCPOCV.js";import"./chunks/chunk-MMHQLGF2.js";import{SettingsManager}from"./chunks/chunk-CXVI2YV7.js";import"./chunks/chunk-YU2P3CAR.js";import"./chunks/chunk-BMX2U22F.js";import{DEFAULT_HOST_LAUNCH_SPEC,HOST_EXIT_ERROR,HOST_EXIT_FALLBACK,HOST_EXIT_OK,HOST_EXIT_REFUSED,HOST_EXIT_USAGE,HostLaunchSpecError,loadHostLaunchSpec,parseHostLaunchSpec,readHostStatus,runHostCommand,runHostRequest}from"./chunks/chunk-JGRPPPHS.js";import{GENERATION_HANDOFF_CAPABILITY,HOST_PROTOCOL_VERSION,HostEnsureRefusedError,PINNED_HOST_CLIENT_CAPABILITIES,REQUIRED_HOST_CAPABILITIES,decideHostAction,ensureHost,handoffHost,parseHostProtocolInfo,probeHost,stopHost}from"./chunks/chunk-Z5NVK72W.js";import"./chunks/chunk-HH3KJDWA.js";import{createHostDaemonPaths,daemonDirectoryName,shardKey,shardSocketPath,shardSocketPathForKey}from"./chunks/chunk-7SFG425F.js";import{compareEngineOrdinal,engineBuildIdentity,engineBuildIdentityFrom}from"./chunks/chunk-XPJLBOWV.js";import"./chunks/chunk-DA4W77J7.js";import"./chunks/chunk-H4QOEVS5.js";import"./chunks/chunk-HB35RBP4.js";import"./chunks/chunk-C5I2LUOI.js";import"./chunks/chunk-YLIS5N3W.js";import{getPowerShellConfig,getShellConfig}from"./chunks/chunk-ASAQQ6VM.js";import"./chunks/chunk-36ACNYQR.js";import"./chunks/chunk-7X72IACK.js";import"./chunks/chunk-KUPQO7MC.js";import"./chunks/chunk-4BDFNRBE.js";import{ProjectTrustStore,hasTrustRequiringProjectResources}from"./chunks/chunk-Y5A6TKBN.js";import{parseArgs}from"./chunks/chunk-KDZAVHA7.js";import"./chunks/chunk-26UBFF6N.js";import"./chunks/chunk-LEAJXPT2.js";import"./chunks/chunk-GZVCRV7I.js";import"./chunks/chunk-U3VOXCGP.js";import"./chunks/chunk-RFB5CBW7.js";import"./chunks/chunk-2VZJTDUX.js";import"./chunks/chunk-UDTWLXSQ.js";import"./chunks/chunk-4LVZQRDG.js";import"./chunks/chunk-ZOFZRJSL.js";import"./chunks/chunk-2SOVDETB.js";import{CONFIG_DIR_NAME,VERSION,getAgentDir,getDocsPath,getExamplesPath,getPackageDir,getReadmePath}from"./chunks/chunk-PBWQK23Z.js";import"./chunks/chunk-ATQFN5HI.js";import"./chunks/chunk-RBCQOIAD.js";import"./chunks/chunk-WASCMT6Y.js";import"./chunks/chunk-X4Q5YSTE.js";import"./chunks/chunk-IXAUDPOK.js";import"./chunks/chunk-J5TMX734.js";import"./chunks/chunk-LHYG7TK7.js";import"./chunks/chunk-KRNXUTZJ.js";import"./chunks/chunk-TJV2LFKM.js";import"./chunks/chunk-45SZOLCU.js";import"./chunks/chunk-WVGCQOLJ.js";import"./chunks/chunk-BBK6SSYT.js";import"./chunks/chunk-BPX6QWPD.js";import"./chunks/chunk-7X4ZMME4.js";import"./chunks/chunk-WDTJ6JKE.js";import"./chunks/chunk-5ROMKDLK.js";import"./chunks/chunk-3W47LTXQ.js";import"./chunks/chunk-DMI55M2N.js";import"./chunks/chunk-BQVVQ2LQ.js";import"./chunks/chunk-IKOFCODM.js";export{AgentSession,AgentSessionRuntime,ArminComponent,AssistantMessageComponent,BashExecutionComponent,BorderedLoader,BranchSummaryMessageComponent,CONFIG_DIR_NAME,CURRENT_SESSION_VERSION,CompactionSummaryMessageComponent,CredentialSynchronizationError,CustomEditor,CustomMessageComponent,DEFAULT_COMPACTION_SETTINGS,DEFAULT_HOST_LAUNCH_SPEC,DEFAULT_MAX_BYTES,DEFAULT_MAX_LINES,DefaultPackageManager,DefaultResourceLoader,DynamicBorder,ExtensionEditorComponent,ExtensionInputComponent,ExtensionRunner,ExtensionSelectorComponent,FooterComponent,GENERATION_HANDOFF_CAPABILITY,HOST_EXIT_ERROR,HOST_EXIT_FALLBACK,HOST_EXIT_OK,HOST_EXIT_REFUSED,HOST_EXIT_USAGE,HOST_PROTOCOL_VERSION,HostEnsureRefusedError,HostLaunchSpecError,InteractiveMode,LoginDialogComponent,ModelRegistry,ModelRuntime,ModelSelectorComponent,OAuthSelectorComponent,PINNED_HOST_CLIENT_CAPABILITIES,ProjectTrustStore,REQUIRED_HOST_CAPABILITIES,RpcClient,RpcClientOpenInFlightError,RpcTransportGoneError,SessionManager,SessionSelectorComponent,SettingsManager,SettingsSelectorComponent,ShowImagesSelectorComponent,SkillInvocationMessageComponent,Theme,ThemeSelectorComponent,ThinkingSelectorComponent,ToolExecutionComponent,TreeSelectorComponent,UserMessageComponent,UserMessageSelectorComponent,VERSION,buildContextEntries,buildNoticeBox,buildSessionContext,calculateContextTokens,classifyRead,collectEntriesForBranchSummary,collectOrphanedChildren,compact,compareEngineOrdinal,connectWebViewService,convertToLlm,convertToPng,copyToClipboard,createAgentSession,createAgentSessionFromServices,createAgentSessionRuntime,createAgentSessionServices,createBashTool,createBashToolDefinition,createCodingTools,createEditTool,createEditToolDefinition,createEventBus,createExtensionRuntime,createFindTool,createFindToolDefinition,createGrepTool,createGrepToolDefinition,createHostDaemonPaths,createLocalBashOperations,createLsTool,createLsToolDefinition,createPowerShellTool,createReadOnlyTools,createReadTool,createReadToolDefinition,createSyntheticSourceInfo,createWriteTool,createWriteToolDefinition,daemonDirectoryName,decideHostAction,defineTool,detectSupportedImageMimeTypeFromFile,discoverAndLoadExtensions,engineBuildIdentity,engineBuildIdentityFrom,ensureHost,estimateTokens,findCutPoint,findTurnStartIndex,formatDimensionNote,formatSize,formatSkillsForPrompt,generateBranchSummary,generateDiffString,generateSummary,generateSummaryWithUsage,generateUnifiedPatch,getAgentDir,getDocsPath,getExamplesPath,getLanguageFromPath,getLastAssistantUsage,getLatestCompactionEntry,getMarkdownTheme,getPackageDir,getPowerShellConfig,getReadmePath,getSelectListTheme,getSettingsListTheme,getShellConfig,handoffHost,hasTrustRequiringProjectResources,highlightCode,initTheme,isBashToolResult,isEditToolResult,isFindToolResult,isGrepToolResult,isLsToolResult,isPowerShellToolResult,isReadToolResult,isToolCallEventType,isTransportGoneError,isWriteToolResult,kernelToolsStorage,keyHint,keyText,loadHostLaunchSpec,loadProjectContextFiles,loadSkills,loadSkillsFromDir,main,migrateSessionEntries,noticeEntryRenderer,noticeMessageRenderer,parseArgs,parseFrontmatter,parseHostLaunchSpec,parseHostProtocolInfo,parseSessionEntries,parseSkillBlock,prepareBranchEntries,probeHost,rawKeyHint,readHostStatus,readOwnFootprint,readProcessFootprint,readStoredCredential,registerReadClassifier,renderDiff,resizeImage,resolveCliModel,resolveModelScopeWithDiagnostics,runHostCommand,runHostRequest,runPrintMode,runRpcMode,sanitizeTerminalLabel,serializeConversation,sessionEntryToContextMessages,shardKey,shardSocketPath,shardSocketPathForKey,shouldCompact,stopHost,stripFrontmatter,truncateHead,truncateLine,truncateTail,truncateToVisualLines,withFileMutationQueue,wrapRegisteredTool,wrapRegisteredTools};
@@ -1,3 +1,3 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire as __piCreateRequire } from "node:module"; const require = __piCreateRequire(import.meta.url); { const __piWorkerThreads = require("node:worker_threads"); if (typeof __piWorkerThreads.markAsUncloneable !== "function") { __piWorkerThreads.markAsUncloneable = () => {}; } }
3
- import{main}from"./chunks/chunk-RKIAHDIB.js";import"./chunks/chunk-FAV4DX74.js";import"./chunks/chunk-3JR7GC6P.js";import"./chunks/chunk-A4UMPXQF.js";import"./chunks/chunk-TFA3YAJK.js";import"./chunks/chunk-O3D7S64D.js";import"./chunks/chunk-NZRVAZL2.js";import"./chunks/chunk-U5KVIAHJ.js";import"./chunks/chunk-S5Q3WPVR.js";import"./chunks/chunk-C5FRNOUP.js";import"./chunks/chunk-6BWCPOCV.js";import"./chunks/chunk-7FIDRH2I.js";import{configureHttpDispatcher}from"./chunks/chunk-3JX3X45G.js";import"./chunks/chunk-YU2P3CAR.js";import"./chunks/chunk-BMX2U22F.js";import"./chunks/chunk-WQO75X37.js";import"./chunks/chunk-4BK43Q6Z.js";import"./chunks/chunk-HH3KJDWA.js";import"./chunks/chunk-OLQI7DUR.js";import"./chunks/chunk-5LYDQMQY.js";import"./chunks/chunk-DA4W77J7.js";import"./chunks/chunk-H4QOEVS5.js";import"./chunks/chunk-HB35RBP4.js";import"./chunks/chunk-2E2FN2VJ.js";import"./chunks/chunk-KAFTHZWC.js";import"./chunks/chunk-ASAQQ6VM.js";import"./chunks/chunk-36ACNYQR.js";import"./chunks/chunk-7X72IACK.js";import"./chunks/chunk-KUPQO7MC.js";import"./chunks/chunk-UTGOAXS6.js";import"./chunks/chunk-Y5A6TKBN.js";import"./chunks/chunk-ZORNIKXN.js";import"./chunks/chunk-26UBFF6N.js";import"./chunks/chunk-OH4ONX6R.js";import"./chunks/chunk-GZVCRV7I.js";import"./chunks/chunk-U3VOXCGP.js";import"./chunks/chunk-RFB5CBW7.js";import"./chunks/chunk-2VZJTDUX.js";import"./chunks/chunk-6WDC7AEV.js";import"./chunks/chunk-BBK6SSYT.js";import"./chunks/chunk-4LVZQRDG.js";import"./chunks/chunk-ZOFZRJSL.js";import"./chunks/chunk-2SOVDETB.js";import{APP_NAME,scrubBrandFromEnvironment}from"./chunks/chunk-PBWQK23Z.js";import"./chunks/chunk-ATQFN5HI.js";import"./chunks/chunk-RBCQOIAD.js";import"./chunks/chunk-WASCMT6Y.js";import"./chunks/chunk-X4Q5YSTE.js";import"./chunks/chunk-IXAUDPOK.js";import"./chunks/chunk-NAIMNKNG.js";import"./chunks/chunk-LHYG7TK7.js";import"./chunks/chunk-45SZOLCU.js";import"./chunks/chunk-WVGCQOLJ.js";import"./chunks/chunk-BPX6QWPD.js";import"./chunks/chunk-EDU27GXU.js";import"./chunks/chunk-WDTJ6JKE.js";import"./chunks/chunk-5ROMKDLK.js";import"./chunks/chunk-3W47LTXQ.js";import"./chunks/chunk-DMI55M2N.js";import"./chunks/chunk-BQVVQ2LQ.js";import"./chunks/chunk-IKOFCODM.js";process.title=`${APP_NAME}-rpc`;scrubBrandFromEnvironment();process.env.PI_CODING_AGENT="true";process.env.AI_AGENT=APP_NAME;process.emitWarning=(()=>{});configureHttpDispatcher();main(["--mode","rpc",...process.argv.slice(2)]);
3
+ import{main}from"./chunks/chunk-EXUI5D5V.js";import"./chunks/chunk-FAV4DX74.js";import"./chunks/chunk-YEMM3LPR.js";import"./chunks/chunk-A4UMPXQF.js";import"./chunks/chunk-TFA3YAJK.js";import"./chunks/chunk-OHJLQ7BY.js";import"./chunks/chunk-NZRVAZL2.js";import"./chunks/chunk-U5KVIAHJ.js";import"./chunks/chunk-XNIX26QC.js";import"./chunks/chunk-XYGXUFMG.js";import"./chunks/chunk-6BWCPOCV.js";import"./chunks/chunk-MMHQLGF2.js";import{configureHttpDispatcher}from"./chunks/chunk-CXVI2YV7.js";import"./chunks/chunk-YU2P3CAR.js";import"./chunks/chunk-BMX2U22F.js";import"./chunks/chunk-JGRPPPHS.js";import"./chunks/chunk-Z5NVK72W.js";import"./chunks/chunk-HH3KJDWA.js";import"./chunks/chunk-7SFG425F.js";import"./chunks/chunk-XPJLBOWV.js";import"./chunks/chunk-DA4W77J7.js";import"./chunks/chunk-H4QOEVS5.js";import"./chunks/chunk-HB35RBP4.js";import"./chunks/chunk-C5I2LUOI.js";import"./chunks/chunk-YLIS5N3W.js";import"./chunks/chunk-ASAQQ6VM.js";import"./chunks/chunk-36ACNYQR.js";import"./chunks/chunk-7X72IACK.js";import"./chunks/chunk-KUPQO7MC.js";import"./chunks/chunk-4BDFNRBE.js";import"./chunks/chunk-Y5A6TKBN.js";import"./chunks/chunk-KDZAVHA7.js";import"./chunks/chunk-26UBFF6N.js";import"./chunks/chunk-LEAJXPT2.js";import"./chunks/chunk-GZVCRV7I.js";import"./chunks/chunk-U3VOXCGP.js";import"./chunks/chunk-RFB5CBW7.js";import"./chunks/chunk-2VZJTDUX.js";import"./chunks/chunk-UDTWLXSQ.js";import"./chunks/chunk-4LVZQRDG.js";import"./chunks/chunk-ZOFZRJSL.js";import"./chunks/chunk-2SOVDETB.js";import{APP_NAME,scrubBrandFromEnvironment}from"./chunks/chunk-PBWQK23Z.js";import"./chunks/chunk-ATQFN5HI.js";import"./chunks/chunk-RBCQOIAD.js";import"./chunks/chunk-WASCMT6Y.js";import"./chunks/chunk-X4Q5YSTE.js";import"./chunks/chunk-IXAUDPOK.js";import"./chunks/chunk-J5TMX734.js";import"./chunks/chunk-LHYG7TK7.js";import"./chunks/chunk-KRNXUTZJ.js";import"./chunks/chunk-TJV2LFKM.js";import"./chunks/chunk-45SZOLCU.js";import"./chunks/chunk-WVGCQOLJ.js";import"./chunks/chunk-BBK6SSYT.js";import"./chunks/chunk-BPX6QWPD.js";import"./chunks/chunk-7X4ZMME4.js";import"./chunks/chunk-WDTJ6JKE.js";import"./chunks/chunk-5ROMKDLK.js";import"./chunks/chunk-3W47LTXQ.js";import"./chunks/chunk-DMI55M2N.js";import"./chunks/chunk-BQVVQ2LQ.js";import"./chunks/chunk-IKOFCODM.js";process.title=`${APP_NAME}-rpc`;scrubBrandFromEnvironment();process.env.PI_CODING_AGENT="true";process.env.AI_AGENT=APP_NAME;process.emitWarning=(()=>{});configureHttpDispatcher();main(["--mode","rpc",...process.argv.slice(2)]);
@@ -0,0 +1,24 @@
1
+ import type { AssistantMessage, AssistantMessageEvent } from "@earendil-works/pi-ai";
2
+ type EventSource = AsyncIterable<AssistantMessageEvent> & {
3
+ result?: () => Promise<AssistantMessage>;
4
+ };
5
+ export type RejectableAttempt = {
6
+ stream: EventSource;
7
+ /** The stored OAuth access token this attempt authenticated with, when the provider can refuse it. */
8
+ rejectableAccess?: string;
9
+ /** HTTP statuses that prove `rejectableAccess` was refused (`OAuthAuth.rejectedTokenStatuses`). */
10
+ rejectedTokenStatuses?: readonly number[];
11
+ };
12
+ /**
13
+ * Runs one request attempt and, when the provider refuses the stored OAuth token
14
+ * before any output reached the caller, runs it exactly once more with that token
15
+ * named as rejected so auth resolution re-exchanges it. GitHub Copilot revokes its
16
+ * short-lived tokens server-side while they still look valid (#2297); VS Code does
17
+ * the same drop-and-refetch on 401/403. Pre-commit frames are held back so the
18
+ * caller sees one stream, never a start from an attempt that was replaced. A
19
+ * provider that declares no refusal statuses gets its own stream back untouched,
20
+ * and `result()` always follows the attempt that ended the request.
21
+ */
22
+ export declare function retryOnceOnRejectedToken(attempt: (rejectedAccess: string | undefined) => Promise<RejectableAttempt>): Promise<EventSource>;
23
+ export {};
24
+ //# sourceMappingURL=rejected-token-retry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rejected-token-retry.d.ts","sourceRoot":"","sources":["../../../src/core/credential-pool/rejected-token-retry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAGrF,KAAK,WAAW,GAAG,aAAa,CAAC,qBAAqB,CAAC,GAAG;IAAE,MAAM,CAAC,EAAE,MAAM,OAAO,CAAC,gBAAgB,CAAC,CAAA;CAAE,CAAC;AAEvG,MAAM,MAAM,iBAAiB,GAAG;IAC/B,MAAM,EAAE,WAAW,CAAC;IACpB,sGAAsG;IACtG,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,mGAAmG;IACnG,qBAAqB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC1C,CAAC;AA4BF;;;;;;;;;GASG;AACH,wBAAsB,wBAAwB,CAC7C,OAAO,EAAE,CAAC,cAAc,EAAE,MAAM,GAAG,SAAS,KAAK,OAAO,CAAC,iBAAiB,CAAC,GACzE,OAAO,CAAC,WAAW,CAAC,CA0CtB"}
@@ -0,0 +1,76 @@
1
+ import { isCommittedRotationOutput } from "./rotation-events.js";
2
+ // Account-scoped wording: the credential pool reads it as a per-account 403, blocks
3
+ // the slot until a new login, and fails over to a healthy sibling account.
4
+ const REFUSED_AFTER_REEXCHANGE = "A freshly re-exchanged token for this account was refused as well; log in to this account again or switch accounts.";
5
+ function refusesToken(event, statuses) {
6
+ if (event.type !== "error" || event.reason !== "error")
7
+ return false;
8
+ const status = event.error.providerDiagnostic?.httpStatus;
9
+ return status !== undefined && statuses.includes(status);
10
+ }
11
+ async function* markRefusalAfterReexchange(stream, statuses) {
12
+ let committed = false;
13
+ for await (const event of stream) {
14
+ if (!committed && event.type === "error" && refusesToken(event, statuses)) {
15
+ // The event and the stream's `result()` share this message, so both carry the note.
16
+ event.error.errorMessage = `${event.error.errorMessage ?? "provider stream error"}\n${REFUSED_AFTER_REEXCHANGE}`;
17
+ }
18
+ committed ||= isCommittedRotationOutput(event);
19
+ yield event;
20
+ }
21
+ }
22
+ /**
23
+ * Runs one request attempt and, when the provider refuses the stored OAuth token
24
+ * before any output reached the caller, runs it exactly once more with that token
25
+ * named as rejected so auth resolution re-exchanges it. GitHub Copilot revokes its
26
+ * short-lived tokens server-side while they still look valid (#2297); VS Code does
27
+ * the same drop-and-refetch on 401/403. Pre-commit frames are held back so the
28
+ * caller sees one stream, never a start from an attempt that was replaced. A
29
+ * provider that declares no refusal statuses gets its own stream back untouched,
30
+ * and `result()` always follows the attempt that ended the request.
31
+ */
32
+ export async function retryOnceOnRejectedToken(attempt) {
33
+ const first = await attempt(undefined);
34
+ const statuses = first.rejectedTokenStatuses ?? [];
35
+ const rejectedAccess = first.rejectableAccess;
36
+ if (rejectedAccess === undefined || statuses.length === 0)
37
+ return first.stream;
38
+ let final = first.stream;
39
+ async function* events() {
40
+ const iterator = first.stream[Symbol.asyncIterator]();
41
+ const held = [];
42
+ try {
43
+ while (true) {
44
+ const next = await iterator.next();
45
+ if (next.done) {
46
+ yield* held;
47
+ return;
48
+ }
49
+ const event = next.value;
50
+ if (refusesToken(event, statuses)) {
51
+ await iterator.return?.(undefined);
52
+ const retried = await attempt(rejectedAccess);
53
+ final = retried.stream;
54
+ yield* markRefusalAfterReexchange(retried.stream, statuses);
55
+ return;
56
+ }
57
+ if (isCommittedRotationOutput(event)) {
58
+ yield* held;
59
+ yield event;
60
+ break;
61
+ }
62
+ held.push(event);
63
+ }
64
+ yield* { [Symbol.asyncIterator]: () => iterator };
65
+ }
66
+ finally {
67
+ await iterator.return?.(undefined);
68
+ }
69
+ }
70
+ const source = events();
71
+ if (typeof first.stream.result === "function") {
72
+ source.result = () => final.result?.() ?? Promise.reject(new Error("provider stream has no result"));
73
+ }
74
+ return source;
75
+ }
76
+ //# sourceMappingURL=rejected-token-retry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rejected-token-retry.js","sourceRoot":"","sources":["../../../src/core/credential-pool/rejected-token-retry.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AssistantMessage, AssistantMessageEvent } from \"@earendil-works/pi-ai\";\nimport { isCommittedRotationOutput } from \"./rotation-events.ts\";\n\ntype EventSource = AsyncIterable<AssistantMessageEvent> & { result?: () => Promise<AssistantMessage> };\n\nexport type RejectableAttempt = {\n\tstream: EventSource;\n\t/** The stored OAuth access token this attempt authenticated with, when the provider can refuse it. */\n\trejectableAccess?: string;\n\t/** HTTP statuses that prove `rejectableAccess` was refused (`OAuthAuth.rejectedTokenStatuses`). */\n\trejectedTokenStatuses?: readonly number[];\n};\n\n// Account-scoped wording: the credential pool reads it as a per-account 403, blocks\n// the slot until a new login, and fails over to a healthy sibling account.\nconst REFUSED_AFTER_REEXCHANGE =\n\t\"A freshly re-exchanged token for this account was refused as well; log in to this account again or switch accounts.\";\n\nfunction refusesToken(event: AssistantMessageEvent, statuses: readonly number[]): boolean {\n\tif (event.type !== \"error\" || event.reason !== \"error\") return false;\n\tconst status = event.error.providerDiagnostic?.httpStatus;\n\treturn status !== undefined && statuses.includes(status);\n}\n\nasync function* markRefusalAfterReexchange(\n\tstream: AsyncIterable<AssistantMessageEvent>,\n\tstatuses: readonly number[],\n): AsyncGenerator<AssistantMessageEvent> {\n\tlet committed = false;\n\tfor await (const event of stream) {\n\t\tif (!committed && event.type === \"error\" && refusesToken(event, statuses)) {\n\t\t\t// The event and the stream's `result()` share this message, so both carry the note.\n\t\t\tevent.error.errorMessage = `${event.error.errorMessage ?? \"provider stream error\"}\\n${REFUSED_AFTER_REEXCHANGE}`;\n\t\t}\n\t\tcommitted ||= isCommittedRotationOutput(event);\n\t\tyield event;\n\t}\n}\n\n/**\n * Runs one request attempt and, when the provider refuses the stored OAuth token\n * before any output reached the caller, runs it exactly once more with that token\n * named as rejected so auth resolution re-exchanges it. GitHub Copilot revokes its\n * short-lived tokens server-side while they still look valid (#2297); VS Code does\n * the same drop-and-refetch on 401/403. Pre-commit frames are held back so the\n * caller sees one stream, never a start from an attempt that was replaced. A\n * provider that declares no refusal statuses gets its own stream back untouched,\n * and `result()` always follows the attempt that ended the request.\n */\nexport async function retryOnceOnRejectedToken(\n\tattempt: (rejectedAccess: string | undefined) => Promise<RejectableAttempt>,\n): Promise<EventSource> {\n\tconst first = await attempt(undefined);\n\tconst statuses = first.rejectedTokenStatuses ?? [];\n\tconst rejectedAccess = first.rejectableAccess;\n\tif (rejectedAccess === undefined || statuses.length === 0) return first.stream;\n\n\tlet final: EventSource = first.stream;\n\tasync function* events(): AsyncGenerator<AssistantMessageEvent> {\n\t\tconst iterator = first.stream[Symbol.asyncIterator]();\n\t\tconst held: AssistantMessageEvent[] = [];\n\t\ttry {\n\t\t\twhile (true) {\n\t\t\t\tconst next = await iterator.next();\n\t\t\t\tif (next.done) {\n\t\t\t\t\tyield* held;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst event = next.value;\n\t\t\t\tif (refusesToken(event, statuses)) {\n\t\t\t\t\tawait iterator.return?.(undefined);\n\t\t\t\t\tconst retried = await attempt(rejectedAccess);\n\t\t\t\t\tfinal = retried.stream;\n\t\t\t\t\tyield* markRefusalAfterReexchange(retried.stream, statuses);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (isCommittedRotationOutput(event)) {\n\t\t\t\t\tyield* held;\n\t\t\t\t\tyield event;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\theld.push(event);\n\t\t\t}\n\t\t\tyield* { [Symbol.asyncIterator]: () => iterator };\n\t\t} finally {\n\t\t\tawait iterator.return?.(undefined);\n\t\t}\n\t}\n\tconst source: EventSource = events();\n\tif (typeof first.stream.result === \"function\") {\n\t\tsource.result = () => final.result?.() ?? Promise.reject(new Error(\"provider stream has no result\"));\n\t}\n\treturn source;\n}\n"]}
@@ -1,5 +1,6 @@
1
1
  import type { AssistantMessageEvent } from "@earendil-works/pi-ai";
2
2
  export declare function isCommittedRotationOutput(event: AssistantMessageEvent): boolean;
3
3
  export declare function isRotationStreamStart(event: AssistantMessageEvent): boolean;
4
+ /** The failure a terminal error event carries, with the adapter's structured HTTP status for classification. */
4
5
  export declare function rotationErrorFromEvent(event: AssistantMessageEvent): unknown;
5
6
  //# sourceMappingURL=rotation-events.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"rotation-events.d.ts","sourceRoot":"","sources":["../../../src/core/credential-pool/rotation-events.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAenE,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,qBAAqB,GAAG,OAAO,CAE/E;AAED,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,qBAAqB,GAAG,OAAO,CAE3E;AAED,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,qBAAqB,GAAG,OAAO,CAI5E"}
1
+ {"version":3,"file":"rotation-events.d.ts","sourceRoot":"","sources":["../../../src/core/credential-pool/rotation-events.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAenE,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,qBAAqB,GAAG,OAAO,CAE/E;AAED,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,qBAAqB,GAAG,OAAO,CAE3E;AAED,gHAAgH;AAChH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,qBAAqB,GAAG,OAAO,CAK5E"}
@@ -16,10 +16,12 @@ export function isCommittedRotationOutput(event) {
16
16
  export function isRotationStreamStart(event) {
17
17
  return event.type === "start";
18
18
  }
19
+ /** The failure a terminal error event carries, with the adapter's structured HTTP status for classification. */
19
20
  export function rotationErrorFromEvent(event) {
20
21
  if (event.type !== "error")
21
22
  return undefined;
22
- const message = event.error.errorMessage ?? "provider stream error";
23
- return new Error(message);
23
+ const failure = new Error(event.error.errorMessage ?? "provider stream error");
24
+ const status = event.error.providerDiagnostic?.httpStatus;
25
+ return status === undefined ? failure : Object.assign(failure, { status });
24
26
  }
25
27
  //# sourceMappingURL=rotation-events.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"rotation-events.js","sourceRoot":"","sources":["../../../src/core/credential-pool/rotation-events.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,MAAM,sBAAsB,GAA+C,IAAI,GAAG,CAAgC;IACjH,OAAO;IACP,YAAY;IACZ,gBAAgB;IAChB,gBAAgB;CAChB,CAAC,CAAC;AAEH,MAAM,UAAU,yBAAyB,CAAC,KAA4B;IACrE,OAAO,CAAC,sBAAsB,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;AAChD,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,KAA4B;IACjE,OAAO,KAAK,CAAC,IAAI,KAAK,OAAO,CAAC;AAC/B,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,KAA4B;IAClE,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO;QAAE,OAAO,SAAS,CAAC;IAC7C,MAAM,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC,YAAY,IAAI,uBAAuB,CAAC;IACpE,OAAO,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC;AAC3B,CAAC","sourcesContent":["import type { AssistantMessageEvent } from \"@earendil-works/pi-ai\";\n\n/**\n * Frames that announce the message or open a block without delivering any of\n * its content. Nothing the user can read has been committed after them, so a\n * replacement attempt may still take over the stream (default-DENY: every other\n * event type, known or unknown, counts as committed).\n */\nconst PRE_COMMIT_EVENT_TYPES: ReadonlySet<AssistantMessageEvent[\"type\"]> = new Set<AssistantMessageEvent[\"type\"]>([\n\t\"start\",\n\t\"text_start\",\n\t\"thinking_start\",\n\t\"toolcall_start\",\n]);\n\nexport function isCommittedRotationOutput(event: AssistantMessageEvent): boolean {\n\treturn !PRE_COMMIT_EVENT_TYPES.has(event.type);\n}\n\nexport function isRotationStreamStart(event: AssistantMessageEvent): boolean {\n\treturn event.type === \"start\";\n}\n\nexport function rotationErrorFromEvent(event: AssistantMessageEvent): unknown {\n\tif (event.type !== \"error\") return undefined;\n\tconst message = event.error.errorMessage ?? \"provider stream error\";\n\treturn new Error(message);\n}\n"]}
1
+ {"version":3,"file":"rotation-events.js","sourceRoot":"","sources":["../../../src/core/credential-pool/rotation-events.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,MAAM,sBAAsB,GAA+C,IAAI,GAAG,CAAgC;IACjH,OAAO;IACP,YAAY;IACZ,gBAAgB;IAChB,gBAAgB;CAChB,CAAC,CAAC;AAEH,MAAM,UAAU,yBAAyB,CAAC,KAA4B;IACrE,OAAO,CAAC,sBAAsB,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;AAChD,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,KAA4B;IACjE,OAAO,KAAK,CAAC,IAAI,KAAK,OAAO,CAAC;AAC/B,CAAC;AAED,gHAAgH;AAChH,MAAM,UAAU,sBAAsB,CAAC,KAA4B;IAClE,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO;QAAE,OAAO,SAAS,CAAC;IAC7C,MAAM,OAAO,GAAG,IAAI,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,YAAY,IAAI,uBAAuB,CAAC,CAAC;IAC/E,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,kBAAkB,EAAE,UAAU,CAAC;IAC1D,OAAO,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;AAC5E,CAAC","sourcesContent":["import type { AssistantMessageEvent } from \"@earendil-works/pi-ai\";\n\n/**\n * Frames that announce the message or open a block without delivering any of\n * its content. Nothing the user can read has been committed after them, so a\n * replacement attempt may still take over the stream (default-DENY: every other\n * event type, known or unknown, counts as committed).\n */\nconst PRE_COMMIT_EVENT_TYPES: ReadonlySet<AssistantMessageEvent[\"type\"]> = new Set<AssistantMessageEvent[\"type\"]>([\n\t\"start\",\n\t\"text_start\",\n\t\"thinking_start\",\n\t\"toolcall_start\",\n]);\n\nexport function isCommittedRotationOutput(event: AssistantMessageEvent): boolean {\n\treturn !PRE_COMMIT_EVENT_TYPES.has(event.type);\n}\n\nexport function isRotationStreamStart(event: AssistantMessageEvent): boolean {\n\treturn event.type === \"start\";\n}\n\n/** The failure a terminal error event carries, with the adapter's structured HTTP status for classification. */\nexport function rotationErrorFromEvent(event: AssistantMessageEvent): unknown {\n\tif (event.type !== \"error\") return undefined;\n\tconst failure = new Error(event.error.errorMessage ?? \"provider stream error\");\n\tconst status = event.error.providerDiagnostic?.httpStatus;\n\treturn status === undefined ? failure : Object.assign(failure, { status });\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"agent-end-continuation.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/goal/agent-end-continuation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAEtE,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,2BAA2B,CAAC;AAI9E,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAEvC,UAAU,mBAAmB;IAC5B,QAAQ,CAAC,GAAG,EAAE,gBAAgB,CAAC;IAC/B,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC;IAC9B,QAAQ,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,CAAC;CAC3B;AAED,wBAAsB,yBAAyB,CAC9C,OAAO,EAAE,4BAA4B,EACrC,OAAO,EAAE,mBAAmB,GAC1B,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC,CAwCtB"}
1
+ {"version":3,"file":"agent-end-continuation.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/goal/agent-end-continuation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAGtE,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,2BAA2B,CAAC;AAQ9E,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAEvC,UAAU,mBAAmB;IAC5B,QAAQ,CAAC,GAAG,EAAE,gBAAgB,CAAC;IAC/B,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC;IAC9B,QAAQ,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,CAAC;CAC3B;AAED,wBAAsB,yBAAyB,CAC9C,OAAO,EAAE,4BAA4B,EACrC,OAAO,EAAE,mBAAmB,GAC1B,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC,CAkDtB"}
@@ -1,7 +1,8 @@
1
1
  import { isMalformedToolUseTurn } from "./continuation.js";
2
+ import { providerAuthBlockedReason, providerAuthRecoveryHint } from "./continuation-recovery.js";
2
3
  import { updateGoal } from "./store.js";
3
4
  import { goalStoreRef } from "./store-ref.js";
4
- import { didTerminalPolicyRejectionEndTurn, didTerminalProviderErrorEndTurn } from "./terminal-provider-error.js";
5
+ import { didTerminalPolicyRejectionEndTurn, didTerminalProviderErrorEndTurn, terminalProviderAuthFailure, } from "./terminal-provider-error.js";
5
6
  export async function continueGoalAfterAgentEnd(monitor, options) {
6
7
  if (options.goal?.status === "active" && didTerminalPolicyRejectionEndTurn(options.event)) {
7
8
  const blocked = await updateGoal(goalStoreRef(options.ctx.sessionManager, options.ctx.cwd), {
@@ -13,6 +14,17 @@ export async function continueGoalAfterAgentEnd(monitor, options) {
13
14
  monitor.syncGoal(blocked);
14
15
  return blocked;
15
16
  }
17
+ const authFailure = options.goal?.status === "active" ? terminalProviderAuthFailure(options.event) : undefined;
18
+ if (authFailure !== undefined) {
19
+ const blocked = await updateGoal(goalStoreRef(options.ctx.sessionManager, options.ctx.cwd), {
20
+ status: "blocked",
21
+ reason: providerAuthBlockedReason(authFailure),
22
+ });
23
+ monitor.syncGoal(blocked);
24
+ if (options.ctx.hasUI)
25
+ options.ctx.ui.notify(providerAuthRecoveryHint(authFailure), "warning");
26
+ return blocked;
27
+ }
16
28
  if (options.event.aborted === true && options.event.abortSource === "system") {
17
29
  return monitor.afterSystemAbort({
18
30
  ctx: options.ctx,
@@ -1 +1 @@
1
- {"version":3,"file":"agent-end-continuation.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/goal/agent-end-continuation.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAE3D,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,iCAAiC,EAAE,+BAA+B,EAAE,MAAM,8BAA8B,CAAC;AASlH,MAAM,CAAC,KAAK,UAAU,yBAAyB,CAC9C,OAAqC,EACrC,OAA4B;IAE5B,IAAI,OAAO,CAAC,IAAI,EAAE,MAAM,KAAK,QAAQ,IAAI,iCAAiC,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QAC3F,MAAM,OAAO,GAAG,MAAM,UAAU,CAAC,YAAY,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,EAAE,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE;YAC3F,MAAM,EAAE,SAAS;YACjB,MAAM,EAAE,0CAA0C;SAClD,CAAC,CAAC;QACH,0EAA0E;QAC1E,0EAA0E;QAC1E,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QAC1B,OAAO,OAAO,CAAC;IAChB,CAAC;IACD,IAAI,OAAO,CAAC,KAAK,CAAC,OAAO,KAAK,IAAI,IAAI,OAAO,CAAC,KAAK,CAAC,WAAW,KAAK,QAAQ,EAAE,CAAC;QAC9E,OAAO,OAAO,CAAC,gBAAgB,CAAC;YAC/B,GAAG,EAAE,OAAO,CAAC,GAAG;YAChB,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,QAAQ,EAAE,OAAO,CAAC,KAAK,CAAC,QAAQ;YAChC,SAAS,EAAE,OAAO,CAAC,KAAK,CAAC,SAAS,KAAK,IAAI;SAC3C,CAAC,CAAC;IACJ,CAAC;IACD,MAAM,aAAa,GAAG,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,KAAK,WAAW,CAAC,CAAC;IAC5G,IAAI,aAAa,EAAE,IAAI,KAAK,WAAW,IAAI,sBAAsB,CAAC,aAAa,CAAC,EAAE,CAAC;QAClF,OAAO,OAAO,CAAC,oBAAoB,CAAC;YACnC,GAAG,EAAE,OAAO,CAAC,GAAG;YAChB,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,QAAQ,EAAE,OAAO,CAAC,KAAK,CAAC,QAAQ;YAChC,SAAS,EAAE,OAAO,CAAC,KAAK,CAAC,SAAS,KAAK,IAAI;SAC3C,CAAC,CAAC;IACJ,CAAC;IACD,IAAI,+BAA+B,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACpD,OAAO,OAAO,CAAC,oBAAoB,CAAC;YACnC,GAAG,EAAE,OAAO,CAAC,GAAG;YAChB,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,QAAQ,EAAE,OAAO,CAAC,KAAK,CAAC,QAAQ;YAChC,SAAS,EAAE,OAAO,CAAC,KAAK,CAAC,SAAS,KAAK,IAAI;SAC3C,CAAC,CAAC;IACJ,CAAC;IACD,OAAO,OAAO,CAAC,aAAa,CAAC,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,QAAQ,EAAE,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC;AAC1G,CAAC","sourcesContent":["import type { AgentEndEvent, ExtensionContext } from \"../../types.ts\";\nimport { isMalformedToolUseTurn } from \"./continuation.ts\";\nimport type { MonitorAwareGoalContinuation } from \"./monitor-continuation.ts\";\nimport { updateGoal } from \"./store.ts\";\nimport { goalStoreRef } from \"./store-ref.ts\";\nimport { didTerminalPolicyRejectionEndTurn, didTerminalProviderErrorEndTurn } from \"./terminal-provider-error.ts\";\nimport type { Goal } from \"./types.ts\";\n\ninterface GoalAgentEndOptions {\n\treadonly ctx: ExtensionContext;\n\treadonly event: AgentEndEvent;\n\treadonly goal: Goal | null;\n}\n\nexport async function continueGoalAfterAgentEnd(\n\tmonitor: MonitorAwareGoalContinuation,\n\toptions: GoalAgentEndOptions,\n): Promise<Goal | null> {\n\tif (options.goal?.status === \"active\" && didTerminalPolicyRejectionEndTurn(options.event)) {\n\t\tconst blocked = await updateGoal(goalStoreRef(options.ctx.sessionManager, options.ctx.cwd), {\n\t\t\tstatus: \"blocked\",\n\t\t\treason: \"provider policy rejection ended the turn\",\n\t\t});\n\t\t// Cancel armed timers and staged recoveries; only an explicit goal resume\n\t\t// may restart a policy-blocked goal, not an infrastructure recovery path.\n\t\tmonitor.syncGoal(blocked);\n\t\treturn blocked;\n\t}\n\tif (options.event.aborted === true && options.event.abortSource === \"system\") {\n\t\treturn monitor.afterSystemAbort({\n\t\t\tctx: options.ctx,\n\t\t\tevent: options.event,\n\t\t\tgoal: options.goal,\n\t\t\tmessages: options.event.messages,\n\t\t\twillRetry: options.event.willRetry === true,\n\t\t});\n\t}\n\tconst lastAssistant = [...options.event.messages].reverse().find((message) => message.role === \"assistant\");\n\tif (lastAssistant?.role === \"assistant\" && isMalformedToolUseTurn(lastAssistant)) {\n\t\treturn monitor.afterProviderFailure({\n\t\t\tctx: options.ctx,\n\t\t\tevent: options.event,\n\t\t\tgoal: options.goal,\n\t\t\tmessages: options.event.messages,\n\t\t\twillRetry: options.event.willRetry === true,\n\t\t});\n\t}\n\tif (didTerminalProviderErrorEndTurn(options.event)) {\n\t\treturn monitor.afterProviderFailure({\n\t\t\tctx: options.ctx,\n\t\t\tevent: options.event,\n\t\t\tgoal: options.goal,\n\t\t\tmessages: options.event.messages,\n\t\t\twillRetry: options.event.willRetry === true,\n\t\t});\n\t}\n\treturn monitor.afterAgentEnd({ ctx: options.ctx, goal: options.goal, messages: options.event.messages });\n}\n"]}
1
+ {"version":3,"file":"agent-end-continuation.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/goal/agent-end-continuation.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AgentEndEvent, ExtensionContext } from \"../../types.ts\";\nimport { isMalformedToolUseTurn } from \"./continuation.ts\";\nimport { providerAuthBlockedReason, providerAuthRecoveryHint } from \"./continuation-recovery.ts\";\nimport type { MonitorAwareGoalContinuation } from \"./monitor-continuation.ts\";\nimport { updateGoal } from \"./store.ts\";\nimport { goalStoreRef } from \"./store-ref.ts\";\nimport {\n\tdidTerminalPolicyRejectionEndTurn,\n\tdidTerminalProviderErrorEndTurn,\n\tterminalProviderAuthFailure,\n} from \"./terminal-provider-error.ts\";\nimport type { Goal } from \"./types.ts\";\n\ninterface GoalAgentEndOptions {\n\treadonly ctx: ExtensionContext;\n\treadonly event: AgentEndEvent;\n\treadonly goal: Goal | null;\n}\n\nexport async function continueGoalAfterAgentEnd(\n\tmonitor: MonitorAwareGoalContinuation,\n\toptions: GoalAgentEndOptions,\n): Promise<Goal | null> {\n\tif (options.goal?.status === \"active\" && didTerminalPolicyRejectionEndTurn(options.event)) {\n\t\tconst blocked = await updateGoal(goalStoreRef(options.ctx.sessionManager, options.ctx.cwd), {\n\t\t\tstatus: \"blocked\",\n\t\t\treason: \"provider policy rejection ended the turn\",\n\t\t});\n\t\t// Cancel armed timers and staged recoveries; only an explicit goal resume\n\t\t// may restart a policy-blocked goal, not an infrastructure recovery path.\n\t\tmonitor.syncGoal(blocked);\n\t\treturn blocked;\n\t}\n\tconst authFailure = options.goal?.status === \"active\" ? terminalProviderAuthFailure(options.event) : undefined;\n\tif (authFailure !== undefined) {\n\t\tconst blocked = await updateGoal(goalStoreRef(options.ctx.sessionManager, options.ctx.cwd), {\n\t\t\tstatus: \"blocked\",\n\t\t\treason: providerAuthBlockedReason(authFailure),\n\t\t});\n\t\tmonitor.syncGoal(blocked);\n\t\tif (options.ctx.hasUI) options.ctx.ui.notify(providerAuthRecoveryHint(authFailure), \"warning\");\n\t\treturn blocked;\n\t}\n\tif (options.event.aborted === true && options.event.abortSource === \"system\") {\n\t\treturn monitor.afterSystemAbort({\n\t\t\tctx: options.ctx,\n\t\t\tevent: options.event,\n\t\t\tgoal: options.goal,\n\t\t\tmessages: options.event.messages,\n\t\t\twillRetry: options.event.willRetry === true,\n\t\t});\n\t}\n\tconst lastAssistant = [...options.event.messages].reverse().find((message) => message.role === \"assistant\");\n\tif (lastAssistant?.role === \"assistant\" && isMalformedToolUseTurn(lastAssistant)) {\n\t\treturn monitor.afterProviderFailure({\n\t\t\tctx: options.ctx,\n\t\t\tevent: options.event,\n\t\t\tgoal: options.goal,\n\t\t\tmessages: options.event.messages,\n\t\t\twillRetry: options.event.willRetry === true,\n\t\t});\n\t}\n\tif (didTerminalProviderErrorEndTurn(options.event)) {\n\t\treturn monitor.afterProviderFailure({\n\t\t\tctx: options.ctx,\n\t\t\tevent: options.event,\n\t\t\tgoal: options.goal,\n\t\t\tmessages: options.event.messages,\n\t\t\twillRetry: options.event.willRetry === true,\n\t\t});\n\t}\n\treturn monitor.afterAgentEnd({ ctx: options.ctx, goal: options.goal, messages: options.event.messages });\n}\n"]}
@@ -4,6 +4,14 @@ export declare const LENGTH_EXHAUSTED_BLOCKED_REASON = "output truncation repeat
4
4
  export declare const UNATTENDED_CONTINUATION_BLOCKED_REASON = "unattended continuation limit reached";
5
5
  export declare const PROVIDER_ERROR_BLOCKED_REASON = "provider error ended the turn (retries exhausted)";
6
6
  export declare const CONTEXT_OVERFLOW_BLOCKED_REASON = "context overflow ended the turn (compaction did not recover)";
7
+ export declare const PROVIDER_AUTH_BLOCKED_REASON_PREFIX = "provider rejected the request: ";
7
8
  export declare function isMechanicalContinuationBlock(blockedReason: string | undefined): boolean;
9
+ export interface ProviderAuthBlock {
10
+ readonly httpStatus: 401 | 403;
11
+ readonly provider: string;
12
+ readonly model: string;
13
+ }
14
+ export declare function providerAuthBlockedReason(block: ProviderAuthBlock): string;
15
+ export declare function providerAuthRecoveryHint(block: ProviderAuthBlock): string;
8
16
  export declare function continuationCapRecoveryHint(blockedReason: string): string;
9
17
  //# sourceMappingURL=continuation-recovery.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"continuation-recovery.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/goal/continuation-recovery.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,+BAA+B,6BAA6B,CAAC;AAC1E,eAAO,MAAM,yBAAyB,8BAA8B,CAAC;AACrE,eAAO,MAAM,+BAA+B,+BAA+B,CAAC;AAC5E,eAAO,MAAM,sCAAsC,0CAA0C,CAAC;AAC9F,eAAO,MAAM,6BAA6B,sDAAsD,CAAC;AACjG,eAAO,MAAM,+BAA+B,iEAAiE,CAAC;AAkB9G,wBAAgB,6BAA6B,CAAC,aAAa,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAGxF;AAED,wBAAgB,2BAA2B,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM,CAGzE"}
1
+ {"version":3,"file":"continuation-recovery.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/goal/continuation-recovery.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,+BAA+B,6BAA6B,CAAC;AAC1E,eAAO,MAAM,yBAAyB,8BAA8B,CAAC;AACrE,eAAO,MAAM,+BAA+B,+BAA+B,CAAC;AAC5E,eAAO,MAAM,sCAAsC,0CAA0C,CAAC;AAC9F,eAAO,MAAM,6BAA6B,sDAAsD,CAAC;AACjG,eAAO,MAAM,+BAA+B,iEAAiE,CAAC;AAC9G,eAAO,MAAM,mCAAmC,oCAAoC,CAAC;AAkBrF,wBAAgB,6BAA6B,CAAC,aAAa,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAMxF;AAED,MAAM,WAAW,iBAAiB;IACjC,QAAQ,CAAC,UAAU,EAAE,GAAG,GAAG,GAAG,CAAC;IAC/B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACvB;AAED,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,iBAAiB,GAAG,MAAM,CAG1E;AAMD,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,iBAAiB,GAAG,MAAM,CAUzE;AAED,wBAAgB,2BAA2B,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM,CAGzE"}
@@ -4,6 +4,7 @@ export const LENGTH_EXHAUSTED_BLOCKED_REASON = "output truncation repeated";
4
4
  export const UNATTENDED_CONTINUATION_BLOCKED_REASON = "unattended continuation limit reached";
5
5
  export const PROVIDER_ERROR_BLOCKED_REASON = "provider error ended the turn (retries exhausted)";
6
6
  export const CONTEXT_OVERFLOW_BLOCKED_REASON = "context overflow ended the turn (compaction did not recover)";
7
+ export const PROVIDER_AUTH_BLOCKED_REASON_PREFIX = "provider rejected the request: ";
7
8
  // Mechanical blocks are stops the runtime imposed on itself, not decisions the
8
9
  // user or the model made. A terminal provider error belongs here: the provider
9
10
  // failing is infrastructure, and the user's next message is exactly the retry
@@ -21,8 +22,29 @@ const RESUME_GUIDANCE = "Send any message to resume.";
21
22
  export function isMechanicalContinuationBlock(blockedReason) {
22
23
  if (blockedReason === undefined)
23
24
  return false;
25
+ // A rejected credential is fixed outside the session (/login, a new key), so
26
+ // the user's next message is the signal that the fix is in.
27
+ if (blockedReason.startsWith(PROVIDER_AUTH_BLOCKED_REASON_PREFIX))
28
+ return true;
24
29
  return MECHANICAL_CONTINUATION_BLOCKS.includes(blockedReason);
25
30
  }
31
+ export function providerAuthBlockedReason(block) {
32
+ const verdict = block.httpStatus === 401 ? "authentication failed" : "access denied";
33
+ return `${PROVIDER_AUTH_BLOCKED_REASON_PREFIX}HTTP ${block.httpStatus} ${verdict} for ${block.provider}/${block.model}`;
34
+ }
35
+ function planName(provider) {
36
+ return provider === "github-copilot" ? "your Copilot plan" : "your account or plan";
37
+ }
38
+ export function providerAuthRecoveryHint(block) {
39
+ const fix = block.httpStatus === 401
40
+ ? `Run /login ${block.provider} to sign in again, or check the API key or token for ${block.provider}`
41
+ : `Run /login ${block.provider} to refresh the account, or check that ${block.model} is enabled for ${planName(block.provider)}`;
42
+ return [
43
+ `Goal continuation blocked: ${providerAuthBlockedReason(block)}.`,
44
+ "Retrying would get the same rejection, so the goal stopped instead of retrying.",
45
+ `${fix}, and check any proxy or gateway in front of it. Then send any message to resume.`,
46
+ ].join(" ");
47
+ }
26
48
  export function continuationCapRecoveryHint(blockedReason) {
27
49
  if (!isMechanicalContinuationBlock(blockedReason))
28
50
  return `Goal continuation blocked: ${blockedReason}`;
@@ -1 +1 @@
1
- {"version":3,"file":"continuation-recovery.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/goal/continuation-recovery.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,+BAA+B,GAAG,0BAA0B,CAAC;AAC1E,MAAM,CAAC,MAAM,yBAAyB,GAAG,2BAA2B,CAAC;AACrE,MAAM,CAAC,MAAM,+BAA+B,GAAG,4BAA4B,CAAC;AAC5E,MAAM,CAAC,MAAM,sCAAsC,GAAG,uCAAuC,CAAC;AAC9F,MAAM,CAAC,MAAM,6BAA6B,GAAG,mDAAmD,CAAC;AACjG,MAAM,CAAC,MAAM,+BAA+B,GAAG,8DAA8D,CAAC;AAE9G,+EAA+E;AAC/E,+EAA+E;AAC/E,8EAA8E;AAC9E,4EAA4E;AAC5E,8BAA8B;AAC9B,MAAM,8BAA8B,GAAsB;IACzD,+BAA+B;IAC/B,yBAAyB;IACzB,+BAA+B;IAC/B,sCAAsC;IACtC,6BAA6B;IAC7B,+BAA+B;CAC/B,CAAC;AAEF,MAAM,eAAe,GAAG,6BAA6B,CAAC;AAEtD,MAAM,UAAU,6BAA6B,CAAC,aAAiC;IAC9E,IAAI,aAAa,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC;IAC9C,OAAO,8BAA8B,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC;AAC/D,CAAC;AAED,MAAM,UAAU,2BAA2B,CAAC,aAAqB;IAChE,IAAI,CAAC,6BAA6B,CAAC,aAAa,CAAC;QAAE,OAAO,8BAA8B,aAAa,EAAE,CAAC;IACxG,OAAO,8BAA8B,aAAa,KAAK,eAAe,EAAE,CAAC;AAC1E,CAAC","sourcesContent":["export const CONTINUATION_CAP_BLOCKED_REASON = \"continuation cap reached\";\nexport const REPETITION_BLOCKED_REASON = \"repeated assistant output\";\nexport const LENGTH_EXHAUSTED_BLOCKED_REASON = \"output truncation repeated\";\nexport const UNATTENDED_CONTINUATION_BLOCKED_REASON = \"unattended continuation limit reached\";\nexport const PROVIDER_ERROR_BLOCKED_REASON = \"provider error ended the turn (retries exhausted)\";\nexport const CONTEXT_OVERFLOW_BLOCKED_REASON = \"context overflow ended the turn (compaction did not recover)\";\n\n// Mechanical blocks are stops the runtime imposed on itself, not decisions the\n// user or the model made. A terminal provider error belongs here: the provider\n// failing is infrastructure, and the user's next message is exactly the retry\n// signal, so the goal resumes instead of stranding behind a block that only\n// `/goal resume` could clear.\nconst MECHANICAL_CONTINUATION_BLOCKS: readonly string[] = [\n\tCONTINUATION_CAP_BLOCKED_REASON,\n\tREPETITION_BLOCKED_REASON,\n\tLENGTH_EXHAUSTED_BLOCKED_REASON,\n\tUNATTENDED_CONTINUATION_BLOCKED_REASON,\n\tPROVIDER_ERROR_BLOCKED_REASON,\n\tCONTEXT_OVERFLOW_BLOCKED_REASON,\n];\n\nconst RESUME_GUIDANCE = \"Send any message to resume.\";\n\nexport function isMechanicalContinuationBlock(blockedReason: string | undefined): boolean {\n\tif (blockedReason === undefined) return false;\n\treturn MECHANICAL_CONTINUATION_BLOCKS.includes(blockedReason);\n}\n\nexport function continuationCapRecoveryHint(blockedReason: string): string {\n\tif (!isMechanicalContinuationBlock(blockedReason)) return `Goal continuation blocked: ${blockedReason}`;\n\treturn `Goal continuation blocked: ${blockedReason}. ${RESUME_GUIDANCE}`;\n}\n"]}
1
+ {"version":3,"file":"continuation-recovery.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/goal/continuation-recovery.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,+BAA+B,GAAG,0BAA0B,CAAC;AAC1E,MAAM,CAAC,MAAM,yBAAyB,GAAG,2BAA2B,CAAC;AACrE,MAAM,CAAC,MAAM,+BAA+B,GAAG,4BAA4B,CAAC;AAC5E,MAAM,CAAC,MAAM,sCAAsC,GAAG,uCAAuC,CAAC;AAC9F,MAAM,CAAC,MAAM,6BAA6B,GAAG,mDAAmD,CAAC;AACjG,MAAM,CAAC,MAAM,+BAA+B,GAAG,8DAA8D,CAAC;AAC9G,MAAM,CAAC,MAAM,mCAAmC,GAAG,iCAAiC,CAAC;AAErF,+EAA+E;AAC/E,+EAA+E;AAC/E,8EAA8E;AAC9E,4EAA4E;AAC5E,8BAA8B;AAC9B,MAAM,8BAA8B,GAAsB;IACzD,+BAA+B;IAC/B,yBAAyB;IACzB,+BAA+B;IAC/B,sCAAsC;IACtC,6BAA6B;IAC7B,+BAA+B;CAC/B,CAAC;AAEF,MAAM,eAAe,GAAG,6BAA6B,CAAC;AAEtD,MAAM,UAAU,6BAA6B,CAAC,aAAiC;IAC9E,IAAI,aAAa,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC;IAC9C,6EAA6E;IAC7E,4DAA4D;IAC5D,IAAI,aAAa,CAAC,UAAU,CAAC,mCAAmC,CAAC;QAAE,OAAO,IAAI,CAAC;IAC/E,OAAO,8BAA8B,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC;AAC/D,CAAC;AAQD,MAAM,UAAU,yBAAyB,CAAC,KAAwB;IACjE,MAAM,OAAO,GAAG,KAAK,CAAC,UAAU,KAAK,GAAG,CAAC,CAAC,CAAC,uBAAuB,CAAC,CAAC,CAAC,eAAe,CAAC;IACrF,OAAO,GAAG,mCAAmC,QAAQ,KAAK,CAAC,UAAU,IAAI,OAAO,QAAQ,KAAK,CAAC,QAAQ,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;AACzH,CAAC;AAED,SAAS,QAAQ,CAAC,QAAgB;IACjC,OAAO,QAAQ,KAAK,gBAAgB,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,sBAAsB,CAAC;AACrF,CAAC;AAED,MAAM,UAAU,wBAAwB,CAAC,KAAwB;IAChE,MAAM,GAAG,GACR,KAAK,CAAC,UAAU,KAAK,GAAG;QACvB,CAAC,CAAC,cAAc,KAAK,CAAC,QAAQ,wDAAwD,KAAK,CAAC,QAAQ,EAAE;QACtG,CAAC,CAAC,cAAc,KAAK,CAAC,QAAQ,0CAA0C,KAAK,CAAC,KAAK,mBAAmB,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC;IACnI,OAAO;QACN,8BAA8B,yBAAyB,CAAC,KAAK,CAAC,GAAG;QACjE,iFAAiF;QACjF,GAAG,GAAG,mFAAmF;KACzF,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACb,CAAC;AAED,MAAM,UAAU,2BAA2B,CAAC,aAAqB;IAChE,IAAI,CAAC,6BAA6B,CAAC,aAAa,CAAC;QAAE,OAAO,8BAA8B,aAAa,EAAE,CAAC;IACxG,OAAO,8BAA8B,aAAa,KAAK,eAAe,EAAE,CAAC;AAC1E,CAAC","sourcesContent":["export const CONTINUATION_CAP_BLOCKED_REASON = \"continuation cap reached\";\nexport const REPETITION_BLOCKED_REASON = \"repeated assistant output\";\nexport const LENGTH_EXHAUSTED_BLOCKED_REASON = \"output truncation repeated\";\nexport const UNATTENDED_CONTINUATION_BLOCKED_REASON = \"unattended continuation limit reached\";\nexport const PROVIDER_ERROR_BLOCKED_REASON = \"provider error ended the turn (retries exhausted)\";\nexport const CONTEXT_OVERFLOW_BLOCKED_REASON = \"context overflow ended the turn (compaction did not recover)\";\nexport const PROVIDER_AUTH_BLOCKED_REASON_PREFIX = \"provider rejected the request: \";\n\n// Mechanical blocks are stops the runtime imposed on itself, not decisions the\n// user or the model made. A terminal provider error belongs here: the provider\n// failing is infrastructure, and the user's next message is exactly the retry\n// signal, so the goal resumes instead of stranding behind a block that only\n// `/goal resume` could clear.\nconst MECHANICAL_CONTINUATION_BLOCKS: readonly string[] = [\n\tCONTINUATION_CAP_BLOCKED_REASON,\n\tREPETITION_BLOCKED_REASON,\n\tLENGTH_EXHAUSTED_BLOCKED_REASON,\n\tUNATTENDED_CONTINUATION_BLOCKED_REASON,\n\tPROVIDER_ERROR_BLOCKED_REASON,\n\tCONTEXT_OVERFLOW_BLOCKED_REASON,\n];\n\nconst RESUME_GUIDANCE = \"Send any message to resume.\";\n\nexport function isMechanicalContinuationBlock(blockedReason: string | undefined): boolean {\n\tif (blockedReason === undefined) return false;\n\t// A rejected credential is fixed outside the session (/login, a new key), so\n\t// the user's next message is the signal that the fix is in.\n\tif (blockedReason.startsWith(PROVIDER_AUTH_BLOCKED_REASON_PREFIX)) return true;\n\treturn MECHANICAL_CONTINUATION_BLOCKS.includes(blockedReason);\n}\n\nexport interface ProviderAuthBlock {\n\treadonly httpStatus: 401 | 403;\n\treadonly provider: string;\n\treadonly model: string;\n}\n\nexport function providerAuthBlockedReason(block: ProviderAuthBlock): string {\n\tconst verdict = block.httpStatus === 401 ? \"authentication failed\" : \"access denied\";\n\treturn `${PROVIDER_AUTH_BLOCKED_REASON_PREFIX}HTTP ${block.httpStatus} ${verdict} for ${block.provider}/${block.model}`;\n}\n\nfunction planName(provider: string): string {\n\treturn provider === \"github-copilot\" ? \"your Copilot plan\" : \"your account or plan\";\n}\n\nexport function providerAuthRecoveryHint(block: ProviderAuthBlock): string {\n\tconst fix =\n\t\tblock.httpStatus === 401\n\t\t\t? `Run /login ${block.provider} to sign in again, or check the API key or token for ${block.provider}`\n\t\t\t: `Run /login ${block.provider} to refresh the account, or check that ${block.model} is enabled for ${planName(block.provider)}`;\n\treturn [\n\t\t`Goal continuation blocked: ${providerAuthBlockedReason(block)}.`,\n\t\t\"Retrying would get the same rejection, so the goal stopped instead of retrying.\",\n\t\t`${fix}, and check any proxy or gateway in front of it. Then send any message to resume.`,\n\t].join(\" \");\n}\n\nexport function continuationCapRecoveryHint(blockedReason: string): string {\n\tif (!isMechanicalContinuationBlock(blockedReason)) return `Goal continuation blocked: ${blockedReason}`;\n\treturn `Goal continuation blocked: ${blockedReason}. ${RESUME_GUIDANCE}`;\n}\n"]}
@@ -1,4 +1,15 @@
1
1
  import type { AgentEndEvent } from "../../types.ts";
2
2
  export declare function didTerminalPolicyRejectionEndTurn(event: AgentEndEvent): boolean;
3
+ export interface TerminalProviderAuthFailure {
4
+ readonly httpStatus: 401 | 403;
5
+ readonly provider: string;
6
+ readonly model: string;
7
+ }
8
+ /**
9
+ * A 401/403 that still ends the turn after every retry owner declined (#2293).
10
+ * The credential pool already failed over or refreshed what it could, so the
11
+ * same request is rejected again on every continuation.
12
+ */
13
+ export declare function terminalProviderAuthFailure(event: AgentEndEvent): TerminalProviderAuthFailure | undefined;
3
14
  export declare function didTerminalProviderErrorEndTurn(event: AgentEndEvent): boolean;
4
15
  //# sourceMappingURL=terminal-provider-error.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"terminal-provider-error.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/goal/terminal-provider-error.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAsCpD,wBAAgB,iCAAiC,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAO/E;AAED,wBAAgB,+BAA+B,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAM7E"}
1
+ {"version":3,"file":"terminal-provider-error.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/goal/terminal-provider-error.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAsCpD,wBAAgB,iCAAiC,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAO/E;AAED,MAAM,WAAW,2BAA2B;IAC3C,QAAQ,CAAC,UAAU,EAAE,GAAG,GAAG,GAAG,CAAC;IAC/B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACvB;AAmBD;;;;GAIG;AACH,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,aAAa,GAAG,2BAA2B,GAAG,SAAS,CAQzG;AAED,wBAAgB,+BAA+B,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAM7E"}
@@ -41,6 +41,37 @@ export function didTerminalPolicyRejectionEndTurn(event) {
41
41
  // only the unstructured Codex diagnostic needs the identity check.
42
42
  return isClassifierRefusal(message) || isCodexPolicyRejection(message);
43
43
  }
44
+ const LEADING_AUTH_STATUS_PATTERN = /^(401|403)\b/;
45
+ function authStatusOf(message) {
46
+ const diagnostic = message.providerDiagnostic;
47
+ // The adapter's structured reading of the transport error outranks the text;
48
+ // the leading status is only consulted for adapters that mint no diagnostic.
49
+ if (diagnostic !== undefined) {
50
+ if (diagnostic.httpStatus === 401 || diagnostic.httpStatus === 403)
51
+ return diagnostic.httpStatus;
52
+ return diagnostic.category === "auth" ? 401 : undefined;
53
+ }
54
+ const status = LEADING_AUTH_STATUS_PATTERN.exec(message.errorMessage ?? "")?.[1];
55
+ return status === "401" ? 401 : status === "403" ? 403 : undefined;
56
+ }
57
+ /**
58
+ * A 401/403 that still ends the turn after every retry owner declined (#2293).
59
+ * The credential pool already failed over or refreshed what it could, so the
60
+ * same request is rejected again on every continuation.
61
+ */
62
+ export function terminalProviderAuthFailure(event) {
63
+ if (event.abortSource === "system")
64
+ return undefined;
65
+ if (event.willRetry !== false)
66
+ return undefined;
67
+ const message = lastAssistantMessage(event.messages);
68
+ if (message?.stopReason !== "error")
69
+ return undefined;
70
+ const httpStatus = authStatusOf(message);
71
+ if (httpStatus === undefined)
72
+ return undefined;
73
+ return { httpStatus, provider: message.provider, model: message.model };
74
+ }
44
75
  export function didTerminalProviderErrorEndTurn(event) {
45
76
  if (event.abortSource === "system")
46
77
  return false;
@@ -1 +1 @@
1
- {"version":3,"file":"terminal-provider-error.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/goal/terminal-provider-error.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAE5D,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AAEnE,wFAAwF;AACxF,kFAAkF;AAClF,mFAAmF;AACnF,iFAAiF;AACjF,wDAAwD;AACxD,MAAM,4BAA4B,GAAG,CAAC,oDAAoD,EAAE,oBAAoB,CAAC,CAAC;AAElH,SAAS,2BAA2B,CACnC,OAA6E;IAE7E,IAAI,OAAO,EAAE,GAAG,KAAK,kBAAkB,IAAI,OAAO,CAAC,UAAU,KAAK,MAAM;QAAE,OAAO,KAAK,CAAC;IACvF,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC;QAC1C,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;QACpF,CAAC,CAAC,EAAE,CAAC;IACN,OAAO,4BAA4B,CAAC,KAAK,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;AAC9E,CAAC;AAED,8EAA8E;AAC9E,sEAAsE;AACtE,MAAM,0BAA0B,GAC/B,uFAAuF,CAAC;AACzF,MAAM,mBAAmB,GAAG,wBAAwB,CAAC;AAErD;;;;;GAKG;AACH,SAAS,sBAAsB,CAAC,OAAqE;IACpG,IAAI,OAAO,CAAC,GAAG,KAAK,mBAAmB;QAAE,OAAO,KAAK,CAAC;IACtD,IAAI,OAAO,CAAC,UAAU,KAAK,OAAO;QAAE,OAAO,KAAK,CAAC;IACjD,OAAO,0BAA0B,CAAC,IAAI,CAAC,OAAO,CAAC,YAAY,IAAI,EAAE,CAAC,CAAC;AACpE,CAAC;AAED,MAAM,UAAU,iCAAiC,CAAC,KAAoB;IACrE,IAAI,KAAK,CAAC,SAAS,KAAK,KAAK;QAAE,OAAO,KAAK,CAAC;IAC5C,MAAM,OAAO,GAAG,oBAAoB,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IACrD,IAAI,OAAO,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC;IACxC,2EAA2E;IAC3E,mEAAmE;IACnE,OAAO,mBAAmB,CAAC,OAAO,CAAC,IAAI,sBAAsB,CAAC,OAAO,CAAC,CAAC;AACxE,CAAC;AAED,MAAM,UAAU,+BAA+B,CAAC,KAAoB;IACnE,IAAI,KAAK,CAAC,WAAW,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IACjD,IAAI,KAAK,CAAC,SAAS,KAAK,KAAK;QAAE,OAAO,KAAK,CAAC;IAC5C,MAAM,OAAO,GAAG,oBAAoB,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IACrD,IAAI,2BAA2B,CAAC,OAAO,CAAC;QAAE,OAAO,IAAI,CAAC;IACtD,OAAO,OAAO,EAAE,UAAU,KAAK,OAAO,IAAI,CAAC,OAAO,EAAE,UAAU,KAAK,SAAS,IAAI,KAAK,CAAC,WAAW,KAAK,MAAM,CAAC,CAAC;AAC/G,CAAC","sourcesContent":["import { isClassifierRefusal } from \"@earendil-works/pi-ai\";\nimport type { AgentEndEvent } from \"../../types.ts\";\nimport { lastAssistantMessage } from \"./last-assistant-message.ts\";\n\n// The anthropic-subscription account-rotating proxy reports total account exhaustion as\n// an assistant message with `stopReason: \"stop\"` and zero usage, so it slips past\n// the stopReason checks below and the goal reads it as a clean turn end. Match the\n// two stable phrases of that exact response; the account count and the `Retry in\n// NNNs` suffix vary, so they are not part of the match.\nconst SDK_OAUTH_EXHAUSTION_MARKERS = [\"API Error: Server is temporarily limiting requests\", \"accounts exhausted\"];\n\nfunction isSdkOauthAccountExhaustion(\n\tmessage: { api?: string; stopReason?: string; content?: unknown } | undefined,\n): boolean {\n\tif (message?.api !== \"claude-sdk-oauth\" || message.stopReason !== \"stop\") return false;\n\tconst text = Array.isArray(message.content)\n\t\t? message.content.map((part) => (part?.type === \"text\" ? part.text : \"\")).join(\"\\n\")\n\t\t: \"\";\n\treturn SDK_OAUTH_EXHAUSTION_MARKERS.every((marker) => text.includes(marker));\n}\n\n// Codex backend type:error responses persist only the message, not the policy\n// code/payload. Match that diagnostic, never ordinary assistant text.\nconst CODEX_POLICY_ERROR_PATTERN =\n\t/^(?:Codex error: )?This request was blocked by our safety systems\\.(?: Reason: .+)?$/i;\nconst CODEX_RESPONSES_API = \"openai-codex-responses\";\n\n/**\n * The sentence above is a provider-agnostic string with no policy code, so it is\n * only trustworthy as a terminal policy signal on the API that produces it.\n * Another provider or gateway emitting the same text keeps the existing\n * provider/system recovery path instead of being stranded as blocked.\n */\nfunction isCodexPolicyRejection(message: { api?: string; stopReason?: string; errorMessage?: string }): boolean {\n\tif (message.api !== CODEX_RESPONSES_API) return false;\n\tif (message.stopReason !== \"error\") return false;\n\treturn CODEX_POLICY_ERROR_PATTERN.test(message.errorMessage ?? \"\");\n}\n\nexport function didTerminalPolicyRejectionEndTurn(event: AgentEndEvent): boolean {\n\tif (event.willRetry !== false) return false;\n\tconst message = lastAssistantMessage(event.messages);\n\tif (message === undefined) return false;\n\t// Structured refusals carry their own provider-independent policy details;\n\t// only the unstructured Codex diagnostic needs the identity check.\n\treturn isClassifierRefusal(message) || isCodexPolicyRejection(message);\n}\n\nexport function didTerminalProviderErrorEndTurn(event: AgentEndEvent): boolean {\n\tif (event.abortSource === \"system\") return false;\n\tif (event.willRetry !== false) return false;\n\tconst message = lastAssistantMessage(event.messages);\n\tif (isSdkOauthAccountExhaustion(message)) return true;\n\treturn message?.stopReason === \"error\" || (message?.stopReason === \"aborted\" && event.abortSource !== \"user\");\n}\n"]}
1
+ {"version":3,"file":"terminal-provider-error.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/goal/terminal-provider-error.ts"],"names":[],"mappings":"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","sourcesContent":["import { isClassifierRefusal } from \"@earendil-works/pi-ai\";\nimport type { AgentEndEvent } from \"../../types.ts\";\nimport { lastAssistantMessage } from \"./last-assistant-message.ts\";\n\n// The anthropic-subscription account-rotating proxy reports total account exhaustion as\n// an assistant message with `stopReason: \"stop\"` and zero usage, so it slips past\n// the stopReason checks below and the goal reads it as a clean turn end. Match the\n// two stable phrases of that exact response; the account count and the `Retry in\n// NNNs` suffix vary, so they are not part of the match.\nconst SDK_OAUTH_EXHAUSTION_MARKERS = [\"API Error: Server is temporarily limiting requests\", \"accounts exhausted\"];\n\nfunction isSdkOauthAccountExhaustion(\n\tmessage: { api?: string; stopReason?: string; content?: unknown } | undefined,\n): boolean {\n\tif (message?.api !== \"claude-sdk-oauth\" || message.stopReason !== \"stop\") return false;\n\tconst text = Array.isArray(message.content)\n\t\t? message.content.map((part) => (part?.type === \"text\" ? part.text : \"\")).join(\"\\n\")\n\t\t: \"\";\n\treturn SDK_OAUTH_EXHAUSTION_MARKERS.every((marker) => text.includes(marker));\n}\n\n// Codex backend type:error responses persist only the message, not the policy\n// code/payload. Match that diagnostic, never ordinary assistant text.\nconst CODEX_POLICY_ERROR_PATTERN =\n\t/^(?:Codex error: )?This request was blocked by our safety systems\\.(?: Reason: .+)?$/i;\nconst CODEX_RESPONSES_API = \"openai-codex-responses\";\n\n/**\n * The sentence above is a provider-agnostic string with no policy code, so it is\n * only trustworthy as a terminal policy signal on the API that produces it.\n * Another provider or gateway emitting the same text keeps the existing\n * provider/system recovery path instead of being stranded as blocked.\n */\nfunction isCodexPolicyRejection(message: { api?: string; stopReason?: string; errorMessage?: string }): boolean {\n\tif (message.api !== CODEX_RESPONSES_API) return false;\n\tif (message.stopReason !== \"error\") return false;\n\treturn CODEX_POLICY_ERROR_PATTERN.test(message.errorMessage ?? \"\");\n}\n\nexport function didTerminalPolicyRejectionEndTurn(event: AgentEndEvent): boolean {\n\tif (event.willRetry !== false) return false;\n\tconst message = lastAssistantMessage(event.messages);\n\tif (message === undefined) return false;\n\t// Structured refusals carry their own provider-independent policy details;\n\t// only the unstructured Codex diagnostic needs the identity check.\n\treturn isClassifierRefusal(message) || isCodexPolicyRejection(message);\n}\n\nexport interface TerminalProviderAuthFailure {\n\treadonly httpStatus: 401 | 403;\n\treadonly provider: string;\n\treadonly model: string;\n}\n\nconst LEADING_AUTH_STATUS_PATTERN = /^(401|403)\\b/;\n\nfunction authStatusOf(message: {\n\terrorMessage?: string;\n\tproviderDiagnostic?: { category: string; httpStatus?: number };\n}): 401 | 403 | undefined {\n\tconst diagnostic = message.providerDiagnostic;\n\t// The adapter's structured reading of the transport error outranks the text;\n\t// the leading status is only consulted for adapters that mint no diagnostic.\n\tif (diagnostic !== undefined) {\n\t\tif (diagnostic.httpStatus === 401 || diagnostic.httpStatus === 403) return diagnostic.httpStatus;\n\t\treturn diagnostic.category === \"auth\" ? 401 : undefined;\n\t}\n\tconst status = LEADING_AUTH_STATUS_PATTERN.exec(message.errorMessage ?? \"\")?.[1];\n\treturn status === \"401\" ? 401 : status === \"403\" ? 403 : undefined;\n}\n\n/**\n * A 401/403 that still ends the turn after every retry owner declined (#2293).\n * The credential pool already failed over or refreshed what it could, so the\n * same request is rejected again on every continuation.\n */\nexport function terminalProviderAuthFailure(event: AgentEndEvent): TerminalProviderAuthFailure | undefined {\n\tif (event.abortSource === \"system\") return undefined;\n\tif (event.willRetry !== false) return undefined;\n\tconst message = lastAssistantMessage(event.messages);\n\tif (message?.stopReason !== \"error\") return undefined;\n\tconst httpStatus = authStatusOf(message);\n\tif (httpStatus === undefined) return undefined;\n\treturn { httpStatus, provider: message.provider, model: message.model };\n}\n\nexport function didTerminalProviderErrorEndTurn(event: AgentEndEvent): boolean {\n\tif (event.abortSource === \"system\") return false;\n\tif (event.willRetry !== false) return false;\n\tconst message = lastAssistantMessage(event.messages);\n\tif (isSdkOauthAccountExhaustion(message)) return true;\n\treturn message?.stopReason === \"error\" || (message?.stopReason === \"aborted\" && event.abortSource !== \"user\");\n}\n"]}
@@ -45,7 +45,7 @@ export const defaultModelPerProvider = {
45
45
  venice: "z-ai-glm-5-3",
46
46
  baseten: "zai-org/GLM-5.2",
47
47
  opencode: "kimi-k2.6",
48
- "opencode-go": "kimi-k2.6",
48
+ "opencode-go": "kimi-k3",
49
49
  "kimi-coding": "kimi-for-coding",
50
50
  "cloudflare-workers-ai": "@cf/moonshotai/kimi-k2.6",
51
51
  "cloudflare-ai-gateway": "workers-ai/@cf/moonshotai/kimi-k2.6",