@code-yeongyu/senpi 2026.8.6 → 2026.8.9-2

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 (224) hide show
  1. package/CHANGELOG.md +156 -0
  2. package/dist/core/agent-session.d.ts +14 -0
  3. package/dist/core/agent-session.d.ts.map +1 -1
  4. package/dist/core/agent-session.js +81 -50
  5. package/dist/core/agent-session.js.map +1 -1
  6. package/dist/core/extensions/builtin/bash-timeout/index.d.ts +2 -2
  7. package/dist/core/extensions/builtin/bash-timeout/index.d.ts.map +1 -1
  8. package/dist/core/extensions/builtin/bash-timeout/index.js +17 -20
  9. package/dist/core/extensions/builtin/bash-timeout/index.js.map +1 -1
  10. package/dist/core/extensions/builtin/bash-timeout/timeout.d.ts +7 -12
  11. package/dist/core/extensions/builtin/bash-timeout/timeout.d.ts.map +1 -1
  12. package/dist/core/extensions/builtin/bash-timeout/timeout.js +11 -19
  13. package/dist/core/extensions/builtin/bash-timeout/timeout.js.map +1 -1
  14. package/dist/core/extensions/builtin/cache-keepalive/index.d.ts +30 -0
  15. package/dist/core/extensions/builtin/cache-keepalive/index.d.ts.map +1 -0
  16. package/dist/core/extensions/builtin/cache-keepalive/index.js +281 -0
  17. package/dist/core/extensions/builtin/cache-keepalive/index.js.map +1 -0
  18. package/dist/core/extensions/builtin/compaction/index.js +9 -9
  19. package/dist/core/extensions/builtin/compaction/index.js.map +1 -1
  20. package/dist/core/extensions/builtin/goal/cache-warm-renderer.d.ts.map +1 -1
  21. package/dist/core/extensions/builtin/goal/cache-warm-renderer.js +21 -8
  22. package/dist/core/extensions/builtin/goal/cache-warm-renderer.js.map +1 -1
  23. package/dist/core/extensions/builtin/goal/cache-warm.d.ts +11 -0
  24. package/dist/core/extensions/builtin/goal/cache-warm.d.ts.map +1 -1
  25. package/dist/core/extensions/builtin/goal/cache-warm.js +16 -0
  26. package/dist/core/extensions/builtin/goal/cache-warm.js.map +1 -1
  27. package/dist/core/extensions/builtin/goal/index.d.ts.map +1 -1
  28. package/dist/core/extensions/builtin/goal/index.js +31 -1
  29. package/dist/core/extensions/builtin/goal/index.js.map +1 -1
  30. package/dist/core/extensions/builtin/goal/monitor-continuation-types.d.ts +1 -0
  31. package/dist/core/extensions/builtin/goal/monitor-continuation-types.d.ts.map +1 -1
  32. package/dist/core/extensions/builtin/goal/monitor-continuation-types.js.map +1 -1
  33. package/dist/core/extensions/builtin/goal/monitor-continuation.d.ts +2 -1
  34. package/dist/core/extensions/builtin/goal/monitor-continuation.d.ts.map +1 -1
  35. package/dist/core/extensions/builtin/goal/monitor-continuation.js +153 -51
  36. package/dist/core/extensions/builtin/goal/monitor-continuation.js.map +1 -1
  37. package/dist/core/extensions/builtin/goal/prompt.d.ts +1 -1
  38. package/dist/core/extensions/builtin/goal/prompt.d.ts.map +1 -1
  39. package/dist/core/extensions/builtin/goal/prompt.js +21 -7
  40. package/dist/core/extensions/builtin/goal/prompt.js.map +1 -1
  41. package/dist/core/extensions/builtin/goal/store-changed-event.d.ts +8 -0
  42. package/dist/core/extensions/builtin/goal/store-changed-event.d.ts.map +1 -0
  43. package/dist/core/extensions/builtin/goal/store-changed-event.js +9 -0
  44. package/dist/core/extensions/builtin/goal/store-changed-event.js.map +1 -0
  45. package/dist/core/extensions/builtin/goal/wait-progress.d.ts +3 -1
  46. package/dist/core/extensions/builtin/goal/wait-progress.d.ts.map +1 -1
  47. package/dist/core/extensions/builtin/goal/wait-progress.js +27 -3
  48. package/dist/core/extensions/builtin/goal/wait-progress.js.map +1 -1
  49. package/dist/core/extensions/builtin/goal/wait-ticker.d.ts +4 -3
  50. package/dist/core/extensions/builtin/goal/wait-ticker.d.ts.map +1 -1
  51. package/dist/core/extensions/builtin/goal/wait-ticker.js +6 -6
  52. package/dist/core/extensions/builtin/goal/wait-ticker.js.map +1 -1
  53. package/dist/core/extensions/builtin/import-repro.d.ts.map +1 -1
  54. package/dist/core/extensions/builtin/import-repro.js +9 -0
  55. package/dist/core/extensions/builtin/import-repro.js.map +1 -1
  56. package/dist/core/extensions/builtin/index.d.ts.map +1 -1
  57. package/dist/core/extensions/builtin/index.js +2 -0
  58. package/dist/core/extensions/builtin/index.js.map +1 -1
  59. package/dist/core/extensions/builtin/model-fallback/settings.d.ts.map +1 -1
  60. package/dist/core/extensions/builtin/model-fallback/settings.js +21 -1
  61. package/dist/core/extensions/builtin/model-fallback/settings.js.map +1 -1
  62. package/dist/core/extensions/builtin/monitor-state-event.d.ts +16 -0
  63. package/dist/core/extensions/builtin/monitor-state-event.d.ts.map +1 -1
  64. package/dist/core/extensions/builtin/monitor-state-event.js +15 -0
  65. package/dist/core/extensions/builtin/monitor-state-event.js.map +1 -1
  66. package/dist/core/extensions/builtin/terminal/extension.d.ts.map +1 -1
  67. package/dist/core/extensions/builtin/terminal/extension.js +20 -1
  68. package/dist/core/extensions/builtin/terminal/extension.js.map +1 -1
  69. package/dist/core/extensions/builtin/terminal/session-bundle.d.ts +5 -1
  70. package/dist/core/extensions/builtin/terminal/session-bundle.d.ts.map +1 -1
  71. package/dist/core/extensions/builtin/terminal/session-bundle.js +19 -2
  72. package/dist/core/extensions/builtin/terminal/session-bundle.js.map +1 -1
  73. package/dist/core/extensions/builtin/terminal/tools/bash.d.ts.map +1 -1
  74. package/dist/core/extensions/builtin/terminal/tools/bash.js +24 -10
  75. package/dist/core/extensions/builtin/terminal/tools/bash.js.map +1 -1
  76. package/dist/core/extensions/builtin/terminal/tools/context.d.ts +2 -0
  77. package/dist/core/extensions/builtin/terminal/tools/context.d.ts.map +1 -1
  78. package/dist/core/extensions/builtin/terminal/tools/context.js.map +1 -1
  79. package/dist/core/extensions/builtin/terminal/tools/foreground-window.d.ts +11 -0
  80. package/dist/core/extensions/builtin/terminal/tools/foreground-window.d.ts.map +1 -0
  81. package/dist/core/extensions/builtin/terminal/tools/foreground-window.js +16 -0
  82. package/dist/core/extensions/builtin/terminal/tools/foreground-window.js.map +1 -0
  83. package/dist/core/extensions/builtin/terminal/tools/sleep-wait.d.ts +28 -0
  84. package/dist/core/extensions/builtin/terminal/tools/sleep-wait.d.ts.map +1 -0
  85. package/dist/core/extensions/builtin/terminal/tools/sleep-wait.js +75 -0
  86. package/dist/core/extensions/builtin/terminal/tools/sleep-wait.js.map +1 -0
  87. package/dist/core/extensions/builtin/tps.d.ts.map +1 -1
  88. package/dist/core/extensions/builtin/tps.js +3 -3
  89. package/dist/core/extensions/builtin/tps.js.map +1 -1
  90. package/dist/core/extensions/runner.d.ts +2 -0
  91. package/dist/core/extensions/runner.d.ts.map +1 -1
  92. package/dist/core/extensions/runner.js +15 -2
  93. package/dist/core/extensions/runner.js.map +1 -1
  94. package/dist/core/extensions/types.d.ts +16 -0
  95. package/dist/core/extensions/types.d.ts.map +1 -1
  96. package/dist/core/extensions/types.js.map +1 -1
  97. package/dist/core/resource-loader.d.ts +4 -0
  98. package/dist/core/resource-loader.d.ts.map +1 -1
  99. package/dist/core/resource-loader.js +6 -0
  100. package/dist/core/resource-loader.js.map +1 -1
  101. package/dist/core/retry-fallback/chains.d.ts +13 -1
  102. package/dist/core/retry-fallback/chains.d.ts.map +1 -1
  103. package/dist/core/retry-fallback/chains.js +80 -8
  104. package/dist/core/retry-fallback/chains.js.map +1 -1
  105. package/dist/core/retry-fallback/controller.d.ts +2 -0
  106. package/dist/core/retry-fallback/controller.d.ts.map +1 -1
  107. package/dist/core/retry-fallback/controller.js.map +1 -1
  108. package/dist/core/retry-fallback/expansion.d.ts +46 -0
  109. package/dist/core/retry-fallback/expansion.d.ts.map +1 -0
  110. package/dist/core/retry-fallback/expansion.js +113 -0
  111. package/dist/core/retry-fallback/expansion.js.map +1 -0
  112. package/dist/core/retry-fallback/hint-policy.d.ts +14 -0
  113. package/dist/core/retry-fallback/hint-policy.d.ts.map +1 -1
  114. package/dist/core/retry-fallback/hint-policy.js +14 -0
  115. package/dist/core/retry-fallback/hint-policy.js.map +1 -1
  116. package/dist/core/retry-fallback/settings.d.ts +6 -0
  117. package/dist/core/retry-fallback/settings.d.ts.map +1 -1
  118. package/dist/core/retry-fallback/settings.js +12 -10
  119. package/dist/core/retry-fallback/settings.js.map +1 -1
  120. package/dist/core/retry-fallback/validate.d.ts.map +1 -1
  121. package/dist/core/retry-fallback/validate.js +14 -1
  122. package/dist/core/retry-fallback/validate.js.map +1 -1
  123. package/dist/core/session-manager.d.ts +1 -1
  124. package/dist/core/session-manager.d.ts.map +1 -1
  125. package/dist/core/session-manager.js.map +1 -1
  126. package/dist/core/settings-manager.d.ts +10 -0
  127. package/dist/core/settings-manager.d.ts.map +1 -1
  128. package/dist/core/settings-manager.js +14 -0
  129. package/dist/core/settings-manager.js.map +1 -1
  130. package/dist/main.d.ts.map +1 -1
  131. package/dist/main.js +18 -3
  132. package/dist/main.js.map +1 -1
  133. package/dist/modes/app-server/threads/goal-handlers.d.ts.map +1 -1
  134. package/dist/modes/app-server/threads/goal-handlers.js +7 -0
  135. package/dist/modes/app-server/threads/goal-handlers.js.map +1 -1
  136. package/dist/modes/interactive/components/favorite-models-selector.d.ts +4 -0
  137. package/dist/modes/interactive/components/favorite-models-selector.d.ts.map +1 -1
  138. package/dist/modes/interactive/components/favorite-models-selector.js +23 -7
  139. package/dist/modes/interactive/components/favorite-models-selector.js.map +1 -1
  140. package/dist/modes/interactive/components/model-selector.d.ts +1 -0
  141. package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
  142. package/dist/modes/interactive/components/model-selector.js +11 -7
  143. package/dist/modes/interactive/components/model-selector.js.map +1 -1
  144. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  145. package/dist/modes/interactive/interactive-mode.js +26 -6
  146. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  147. package/dist/modes/interactive/model-search-rank.d.ts +13 -0
  148. package/dist/modes/interactive/model-search-rank.d.ts.map +1 -0
  149. package/dist/modes/interactive/model-search-rank.js +200 -0
  150. package/dist/modes/interactive/model-search-rank.js.map +1 -0
  151. package/dist/modes/interactive/model-search.d.ts +0 -5
  152. package/dist/modes/interactive/model-search.d.ts.map +1 -1
  153. package/dist/modes/interactive/model-search.js +0 -9
  154. package/dist/modes/interactive/model-search.js.map +1 -1
  155. package/dist/modes/rpc/session-command-router.d.ts.map +1 -1
  156. package/dist/modes/rpc/session-command-router.js +3 -2
  157. package/dist/modes/rpc/session-command-router.js.map +1 -1
  158. package/dist/modes/rpc/session-registry.d.ts +1 -1
  159. package/dist/modes/rpc/session-registry.d.ts.map +1 -1
  160. package/dist/modes/rpc/session-registry.js +3 -3
  161. package/dist/modes/rpc/session-registry.js.map +1 -1
  162. package/docs/providers.md +23 -3
  163. package/docs/settings.md +1 -1
  164. package/node_modules/@code-yeongyu/senpi-codemode/CHANGELOG.md +50 -0
  165. package/node_modules/@code-yeongyu/senpi-codemode/package.json +4 -4
  166. package/node_modules/@code-yeongyu/senpi-codemode/src/extension/wake-source-state.ts +29 -0
  167. package/node_modules/@code-yeongyu/senpi-codemode/src/index.ts +10 -0
  168. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/detached-cell-manager.ts +27 -1
  169. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/render.ts +2 -1
  170. package/node_modules/@earendil-works/pi-agent-core/dist/empty-assistant-recovery.d.ts.map +1 -1
  171. package/node_modules/@earendil-works/pi-agent-core/dist/empty-assistant-recovery.js +4 -7
  172. package/node_modules/@earendil-works/pi-agent-core/dist/empty-assistant-recovery.js.map +1 -1
  173. package/node_modules/@earendil-works/pi-agent-core/package.json +2 -2
  174. package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.d.ts +3 -1
  175. package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.d.ts.map +1 -1
  176. package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.js +13 -0
  177. package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.js.map +1 -1
  178. package/node_modules/@earendil-works/pi-ai/dist/api/bedrock-converse-stream.d.ts.map +1 -1
  179. package/node_modules/@earendil-works/pi-ai/dist/api/bedrock-converse-stream.js +6 -3
  180. package/node_modules/@earendil-works/pi-ai/dist/api/bedrock-converse-stream.js.map +1 -1
  181. package/node_modules/@earendil-works/pi-ai/dist/api/openai-completions.d.ts.map +1 -1
  182. package/node_modules/@earendil-works/pi-ai/dist/api/openai-completions.js +6 -2
  183. package/node_modules/@earendil-works/pi-ai/dist/api/openai-completions.js.map +1 -1
  184. package/node_modules/@earendil-works/pi-ai/dist/api/warm-prompt-cache.d.ts +17 -0
  185. package/node_modules/@earendil-works/pi-ai/dist/api/warm-prompt-cache.d.ts.map +1 -0
  186. package/node_modules/@earendil-works/pi-ai/dist/api/warm-prompt-cache.js +52 -0
  187. package/node_modules/@earendil-works/pi-ai/dist/api/warm-prompt-cache.js.map +1 -0
  188. package/node_modules/@earendil-works/pi-ai/dist/index.d.ts +3 -1
  189. package/node_modules/@earendil-works/pi-ai/dist/index.d.ts.map +1 -1
  190. package/node_modules/@earendil-works/pi-ai/dist/index.js +3 -1
  191. package/node_modules/@earendil-works/pi-ai/dist/index.js.map +1 -1
  192. package/node_modules/@earendil-works/pi-ai/dist/providers/data/.manifest.json +1 -1
  193. package/node_modules/@earendil-works/pi-ai/dist/providers/data/github-copilot.json +1 -1
  194. package/node_modules/@earendil-works/pi-ai/dist/providers/data/huggingface.json +1 -1
  195. package/node_modules/@earendil-works/pi-ai/dist/providers/data/moonshotai-cn.json +1 -1
  196. package/node_modules/@earendil-works/pi-ai/dist/providers/data/moonshotai.json +1 -1
  197. package/node_modules/@earendil-works/pi-ai/dist/providers/data/nvidia.json +1 -1
  198. package/node_modules/@earendil-works/pi-ai/dist/providers/data/opencode-go.json +1 -1
  199. package/node_modules/@earendil-works/pi-ai/dist/providers/data/opencode.json +1 -1
  200. package/node_modules/@earendil-works/pi-ai/dist/providers/data/openrouter.json +1 -1
  201. package/node_modules/@earendil-works/pi-ai/dist/providers/data/vercel-ai-gateway.json +1 -1
  202. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/antml/recovery-stream.d.ts.map +1 -1
  203. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/antml/recovery-stream.js +120 -1
  204. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/antml/recovery-stream.js.map +1 -1
  205. package/node_modules/@earendil-works/pi-ai/dist/types.d.ts +2 -0
  206. package/node_modules/@earendil-works/pi-ai/dist/types.d.ts.map +1 -1
  207. package/node_modules/@earendil-works/pi-ai/dist/types.js.map +1 -1
  208. package/node_modules/@earendil-works/pi-ai/dist/utils/prompt-cache-ttl.d.ts +3 -1
  209. package/node_modules/@earendil-works/pi-ai/dist/utils/prompt-cache-ttl.d.ts.map +1 -1
  210. package/node_modules/@earendil-works/pi-ai/dist/utils/prompt-cache-ttl.js +17 -3
  211. package/node_modules/@earendil-works/pi-ai/dist/utils/prompt-cache-ttl.js.map +1 -1
  212. package/node_modules/@earendil-works/pi-ai/dist/utils/visible-text.d.ts +4 -0
  213. package/node_modules/@earendil-works/pi-ai/dist/utils/visible-text.d.ts.map +1 -0
  214. package/node_modules/@earendil-works/pi-ai/dist/utils/visible-text.js +8 -0
  215. package/node_modules/@earendil-works/pi-ai/dist/utils/visible-text.js.map +1 -0
  216. package/node_modules/@earendil-works/pi-ai/package.json +1 -1
  217. package/node_modules/@earendil-works/pi-pty/dist/pipe-fallback.d.ts +12 -0
  218. package/node_modules/@earendil-works/pi-pty/dist/pipe-fallback.d.ts.map +1 -1
  219. package/node_modules/@earendil-works/pi-pty/dist/pipe-fallback.js +34 -2
  220. package/node_modules/@earendil-works/pi-pty/dist/pipe-fallback.js.map +1 -1
  221. package/node_modules/@earendil-works/pi-pty/native/prebuilds/darwin-arm64/senpi_pty.darwin-arm64.node +0 -0
  222. package/node_modules/@earendil-works/pi-pty/package.json +1 -1
  223. package/node_modules/@earendil-works/pi-tui/package.json +1 -1
  224. package/package.json +6 -6
@@ -1 +1 @@
1
- {"version":3,"file":"prompt-cache-ttl.js","sourceRoot":"","sources":["../../src/utils/prompt-cache-ttl.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n\tAnthropicMessagesCompat,\n\tApi,\n\tCacheRetention,\n\tModel,\n\tOpenAICompletionsCompat,\n\tProviderEnv,\n} from \"../types.ts\";\nimport { getProviderEnvValue } from \"./provider-env.ts\";\n\nexport const PROMPT_CACHE_TTL_SHORT_SECONDS = 300;\nexport const PROMPT_CACHE_TTL_LONG_SECONDS = 3600;\n\nexport function isAnthropicApiBaseUrl(baseUrl: string): boolean {\n\ttry {\n\t\treturn new URL(baseUrl).hostname === \"api.anthropic.com\";\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nconst CLAUDE_FABLE_OR_MYTHOS_MODEL_ID = /^claude-(?:fable|mythos)(?:-|$)/i;\n\n/**\n * Default for `supportsToolReferences`: first-party Anthropic models except\n * Haiku (rejects client-side tool_reference blocks) and models that predate\n * tool search (Claude 3.x, Opus/Sonnet 4.0, Opus 4.1).\n */\nfunction defaultSupportsToolReferences(model: Model<\"anthropic-messages\">): boolean {\n\tif (model.provider !== \"anthropic\" || model.id.includes(\"haiku\")) return false;\n\tconst version = model.id.match(/^claude-(?:opus|sonnet|fable)-(\\d+)(?:-(\\d+))?(?:-|$)/);\n\tif (!version) return false;\n\tconst major = Number(version[1]);\n\tconst minor = version[2] && version[2].length < 8 ? Number(version[2]) : 0;\n\treturn major > 4 || (major === 4 && minor >= 5);\n}\n\nexport function getAnthropicCompat(\n\tmodel: Model<\"anthropic-messages\">,\n): Required<Omit<AnthropicMessagesCompat, \"forceAdaptiveThinking\">> {\n\t// Auto-detect session affinity and cache control support from provider\n\tconst isFireworks = model.provider === \"fireworks\";\n\tconst isCloudflareAiGatewayAnthropic =\n\t\tmodel.provider === \"cloudflare-ai-gateway\" && model.baseUrl.includes(\"anthropic\");\n\tconst isXiaomi = model.provider === \"xiaomi\" || model.provider.startsWith(\"xiaomi-token-plan-\");\n\treturn {\n\t\tsupportsEagerToolInputStreaming: model.compat?.supportsEagerToolInputStreaming ?? !isFireworks,\n\t\tsupportsLongCacheRetention: model.compat?.supportsLongCacheRetention ?? !isFireworks,\n\t\tsendSessionAffinityHeaders:\n\t\t\tmodel.compat?.sendSessionAffinityHeaders ?? !!(isFireworks || isCloudflareAiGatewayAnthropic),\n\t\tsupportsCacheControlOnTools: model.compat?.supportsCacheControlOnTools ?? !isFireworks,\n\t\tsupportsDisabledThinking: model.compat?.supportsDisabledThinking ?? !isXiaomi,\n\t\tsupportsTemperature: model.compat?.supportsTemperature ?? true,\n\t\tsupportsToolChoice: model.compat?.supportsToolChoice ?? true,\n\t\tsupportsForcedToolChoice:\n\t\t\tmodel.compat?.supportsForcedToolChoice ?? !CLAUDE_FABLE_OR_MYTHOS_MODEL_ID.test(model.id),\n\t\tallowEmptySignature: model.compat?.allowEmptySignature ?? false,\n\t\tunsignedThinkingReplay:\n\t\t\tmodel.compat?.unsignedThinkingReplay ?? (model.compat?.allowEmptySignature ? \"empty-signature\" : \"text\"),\n\t\tsupportsStrictTools: model.compat?.supportsStrictTools ?? false,\n\t\tsupportsToolReferences: model.compat?.supportsToolReferences ?? defaultSupportsToolReferences(model),\n\t\t// Default: first-party Anthropic only. Anthropic-compatible providers\n\t\t// (kimi-coding, fireworks, copilot, gateways) may execute the server-side\n\t\t// search but reject the replayed server_tool_use / web_search_tool_result\n\t\t// blocks on the next request (kimi-coding 400s with `tool_call_id is not\n\t\t// found`).\n\t\tsupportsWebSearch: model.compat?.supportsWebSearch ?? isAnthropicApiBaseUrl(model.baseUrl),\n\t};\n}\n\nexport type ResolvedOpenAICompletionsCompat = Omit<\n\tRequired<OpenAICompletionsCompat>,\n\t\"cacheControlFormat\" | \"toolCallFormat\" | \"deferredToolsMode\" | \"toolSchemaFlavor\"\n> & {\n\tcacheControlFormat?: OpenAICompletionsCompat[\"cacheControlFormat\"];\n\ttoolCallFormat?: OpenAICompletionsCompat[\"toolCallFormat\"];\n\tdeferredToolsMode?: OpenAICompletionsCompat[\"deferredToolsMode\"];\n\ttoolSchemaFlavor?: OpenAICompletionsCompat[\"toolSchemaFlavor\"];\n};\n\n/**\n * Detect compatibility settings from provider and baseUrl for known providers.\n * Provider takes precedence over URL-based detection since it's explicitly configured.\n * Returns a fully resolved OpenAICompletionsCompat object with all fields set.\n */\nfunction detectOpenAICompletionsCompat(model: Model<\"openai-completions\">): ResolvedOpenAICompletionsCompat {\n\tconst provider = model.provider;\n\tconst baseUrl = model.baseUrl;\n\n\tconst isZai =\n\t\tprovider === \"zai\" ||\n\t\tprovider === \"zai-coding-cn\" ||\n\t\tbaseUrl.includes(\"api.z.ai\") ||\n\t\tbaseUrl.includes(\"open.bigmodel.cn\");\n\tconst isTogether =\n\t\tprovider === \"together\" || baseUrl.includes(\"api.together.ai\") || baseUrl.includes(\"api.together.xyz\");\n\tconst isMoonshot = provider === \"moonshotai\" || provider === \"moonshotai-cn\" || baseUrl.includes(\"api.moonshot.\");\n\tconst isOpenRouter = provider === \"openrouter\" || baseUrl.includes(\"openrouter.ai\");\n\tconst isCloudflareWorkersAI = provider === \"cloudflare-workers-ai\" || baseUrl.includes(\"api.cloudflare.com\");\n\tconst isCloudflareAiGateway = provider === \"cloudflare-ai-gateway\" || baseUrl.includes(\"gateway.ai.cloudflare.com\");\n\tconst isNvidia = provider === \"nvidia\" || baseUrl.includes(\"integrate.api.nvidia.com\");\n\tconst isAntLing = provider === \"ant-ling\" || baseUrl.includes(\"api.ant-ling.com\");\n\n\tconst isNonStandard =\n\t\tisNvidia ||\n\t\tprovider === \"cerebras\" ||\n\t\tbaseUrl.includes(\"cerebras.ai\") ||\n\t\tprovider === \"xai\" ||\n\t\tbaseUrl.includes(\"api.x.ai\") ||\n\t\tisTogether ||\n\t\tbaseUrl.includes(\"chutes.ai\") ||\n\t\tbaseUrl.includes(\"deepseek.com\") ||\n\t\tisZai ||\n\t\tisMoonshot ||\n\t\tprovider === \"opencode\" ||\n\t\tbaseUrl.includes(\"opencode.ai\") ||\n\t\tisCloudflareWorkersAI ||\n\t\tisCloudflareAiGateway ||\n\t\tisAntLing;\n\n\tconst useMaxTokens =\n\t\tbaseUrl.includes(\"chutes.ai\") ||\n\t\tisMoonshot ||\n\t\tisCloudflareAiGateway ||\n\t\tisTogether ||\n\t\tisNvidia ||\n\t\tisAntLing ||\n\t\tisZai;\n\n\tconst isGrok = provider === \"xai\" || baseUrl.includes(\"api.x.ai\");\n\tconst isDeepSeek = provider === \"deepseek\" || baseUrl.includes(\"deepseek.com\");\n\tconst isOpenRouterDeveloperRoleModel =\n\t\tisOpenRouter && (model.id.startsWith(\"anthropic/\") || model.id.startsWith(\"openai/\"));\n\tconst cacheControlFormat = provider === \"openrouter\" && model.id.startsWith(\"anthropic/\") ? \"anthropic\" : undefined;\n\n\treturn {\n\t\tsupportsStore: !isNonStandard,\n\t\tsupportsDeveloperRole: isOpenRouterDeveloperRoleModel || (!isNonStandard && !isOpenRouter),\n\t\tsupportsReasoningEffort:\n\t\t\t!isGrok && !isZai && !isMoonshot && !isTogether && !isCloudflareAiGateway && !isNvidia && !isAntLing,\n\t\tsupportsUsageInStreaming: true,\n\t\tsupportsFinishReason: true,\n\t\tmaxTokensField: useMaxTokens ? \"max_tokens\" : \"max_completion_tokens\",\n\t\trequiresToolResultName: false,\n\t\trequiresAssistantAfterToolResult: false,\n\t\trequiresThinkingAsText: false,\n\t\trequiresReasoningContentOnAssistantMessages: isDeepSeek,\n\t\tthinkingFormat: isDeepSeek\n\t\t\t? \"deepseek\"\n\t\t\t: isZai\n\t\t\t\t? \"zai\"\n\t\t\t\t: isTogether\n\t\t\t\t\t? \"together\"\n\t\t\t\t\t: isAntLing\n\t\t\t\t\t\t? \"ant-ling\"\n\t\t\t\t\t\t: isOpenRouter\n\t\t\t\t\t\t\t? \"openrouter\"\n\t\t\t\t\t\t\t: \"openai\",\n\t\topenRouterRouting: {},\n\t\tvercelGatewayRouting: {},\n\t\tchatTemplateKwargs: {},\n\t\tzaiToolStream: false,\n\t\tsupportsStrictMode: !isMoonshot && !isTogether && !isCloudflareAiGateway && !isNvidia,\n\t\ttoolSchemaFlavor: isMoonshot ? \"moonshot-mfjs\" : undefined,\n\t\tsupportsDisabledThinking: true,\n\t\ttoolCallFormat: undefined,\n\t\tsupportsOpenAIGrammarTools: false,\n\t\tcacheControlFormat,\n\t\tsendSessionAffinityHeaders: false,\n\t\tdeferredToolsMode: undefined,\n\t\tsessionAffinityFormat: isOpenRouter ? \"openrouter\" : \"openai\",\n\t\tsupportsLongCacheRetention: !(\n\t\t\tisTogether ||\n\t\t\tisCloudflareWorkersAI ||\n\t\t\tisCloudflareAiGateway ||\n\t\t\tisNvidia ||\n\t\t\tisAntLing\n\t\t),\n\t};\n}\n\n/**\n * Get resolved compatibility settings for a model.\n * Auto-detects from provider/URL then overrides with explicit model.compat.\n */\nexport function getOpenAICompletionsCompat(model: Model<\"openai-completions\">): ResolvedOpenAICompletionsCompat {\n\tconst detected = detectOpenAICompletionsCompat(model);\n\tif (!model.compat) return detected;\n\n\treturn {\n\t\tsupportsStore: model.compat.supportsStore ?? detected.supportsStore,\n\t\tsupportsDeveloperRole: model.compat.supportsDeveloperRole ?? detected.supportsDeveloperRole,\n\t\tsupportsReasoningEffort: model.compat.supportsReasoningEffort ?? detected.supportsReasoningEffort,\n\t\tsupportsUsageInStreaming: model.compat.supportsUsageInStreaming ?? detected.supportsUsageInStreaming,\n\t\tsupportsFinishReason: model.compat.supportsFinishReason ?? detected.supportsFinishReason,\n\t\tmaxTokensField: model.compat.maxTokensField ?? detected.maxTokensField,\n\t\trequiresToolResultName: model.compat.requiresToolResultName ?? detected.requiresToolResultName,\n\t\trequiresAssistantAfterToolResult:\n\t\t\tmodel.compat.requiresAssistantAfterToolResult ?? detected.requiresAssistantAfterToolResult,\n\t\trequiresThinkingAsText: model.compat.requiresThinkingAsText ?? detected.requiresThinkingAsText,\n\t\trequiresReasoningContentOnAssistantMessages:\n\t\t\tmodel.compat.requiresReasoningContentOnAssistantMessages ??\n\t\t\tdetected.requiresReasoningContentOnAssistantMessages,\n\t\tthinkingFormat: model.compat.thinkingFormat ?? detected.thinkingFormat,\n\t\tsupportsDisabledThinking: model.compat.supportsDisabledThinking ?? detected.supportsDisabledThinking,\n\t\topenRouterRouting: model.compat.openRouterRouting ?? detected.openRouterRouting,\n\t\tvercelGatewayRouting: model.compat.vercelGatewayRouting ?? detected.vercelGatewayRouting,\n\t\tchatTemplateKwargs: model.compat.chatTemplateKwargs ?? detected.chatTemplateKwargs,\n\t\tzaiToolStream: model.compat.zaiToolStream ?? detected.zaiToolStream,\n\t\tsupportsStrictMode: model.compat.supportsStrictMode ?? detected.supportsStrictMode,\n\t\ttoolSchemaFlavor: model.compat.toolSchemaFlavor ?? detected.toolSchemaFlavor,\n\t\ttoolCallFormat: model.compat.toolCallFormat ?? detected.toolCallFormat,\n\t\tsupportsOpenAIGrammarTools: model.compat.supportsOpenAIGrammarTools ?? detected.supportsOpenAIGrammarTools,\n\t\tcacheControlFormat: model.compat.cacheControlFormat ?? detected.cacheControlFormat,\n\t\tsendSessionAffinityHeaders: model.compat.sendSessionAffinityHeaders ?? detected.sendSessionAffinityHeaders,\n\t\tdeferredToolsMode: model.compat.deferredToolsMode ?? detected.deferredToolsMode,\n\t\tsessionAffinityFormat: model.compat.sessionAffinityFormat ?? detected.sessionAffinityFormat,\n\t\tsupportsLongCacheRetention: model.compat.supportsLongCacheRetention ?? detected.supportsLongCacheRetention,\n\t};\n}\n\nexport function getBedrockModelMatchCandidates(modelId: string, modelName?: string): string[] {\n\tconst values = modelName ? [modelId, modelName] : [modelId];\n\treturn values.flatMap((value) => {\n\t\tconst lower = value.toLowerCase();\n\t\treturn [lower, lower.replace(/[\\s_.:]+/g, \"-\")];\n\t});\n}\n\n/**\n * Check if the model supports prompt caching.\n * Supported: Claude 3.5 Haiku, Claude 3.7 Sonnet, Claude 4.x models, Claude 5 models\n *\n * For base models and system-defined inference profiles the model ID / ARN\n * contains the model name, so we can decide locally.\n *\n * For application inference profiles (whose ARNs don't contain the model name),\n * also checks model.name which is user-controlled via models.json or registerProvider.\n * As a last resort, set AWS_BEDROCK_FORCE_CACHE=1 to enable cache points.\n * Amazon Nova models have automatic caching and don't need explicit cache points.\n */\nexport function supportsPromptCaching(model: Model<\"bedrock-converse-stream\">, env?: ProviderEnv): boolean {\n\tconst candidates = getBedrockModelMatchCandidates(model.id, model.name);\n\n\tconst hasClaudeRef = candidates.some((s) => s.includes(\"claude\"));\n\tif (!hasClaudeRef) {\n\t\t// Application inference profiles don't contain the model name in the ARN.\n\t\t// Allow users to force cache points via environment variable.\n\t\tif (getProviderEnvValue(\"AWS_BEDROCK_FORCE_CACHE\", env) === \"1\") return true;\n\t\treturn false;\n\t}\n\t// Claude 5 models (fable-5, opus-5, sonnet-5)\n\tif (candidates.some((s) => s.includes(\"fable-5\") || s.includes(\"opus-5\") || s.includes(\"sonnet-5\"))) return true;\n\t// Claude 4.x models (opus-4, sonnet-4, haiku-4)\n\tif (candidates.some((s) => s.includes(\"-4-\"))) return true;\n\t// Claude 3.7 Sonnet\n\tif (candidates.some((s) => s.includes(\"claude-3-7-sonnet\"))) return true;\n\t// Claude 3.5 Haiku\n\tif (candidates.some((s) => s.includes(\"claude-3-5-haiku\"))) return true;\n\treturn false;\n}\n\nfunction resolveAnthropicCacheRetention(\n\tcacheRetention?: CacheRetention,\n\tenv?: ProviderEnv,\n\tfallback: CacheRetention = \"short\",\n): CacheRetention {\n\tif (cacheRetention) {\n\t\treturn cacheRetention;\n\t}\n\tif (getProviderEnvValue(\"PI_CACHE_RETENTION\", env) === \"long\") {\n\t\treturn \"long\";\n\t}\n\tif (typeof process !== \"undefined\" && process.env.PI_CACHE_RETENTION !== undefined) {\n\t\treturn \"short\";\n\t}\n\treturn fallback;\n}\n\nfunction resolveOpenAICompletionsCacheRetention(cacheRetention?: CacheRetention, env?: ProviderEnv): CacheRetention {\n\tif (cacheRetention) {\n\t\treturn cacheRetention;\n\t}\n\tif (getProviderEnvValue(\"PI_CACHE_RETENTION\", env) === \"long\") {\n\t\treturn \"long\";\n\t}\n\treturn \"short\";\n}\n\nfunction resolveBedrockCacheRetention(cacheRetention?: CacheRetention, env?: ProviderEnv): CacheRetention {\n\tif (cacheRetention) {\n\t\treturn cacheRetention;\n\t}\n\tif (getProviderEnvValue(\"PI_CACHE_RETENTION\", env) === \"long\") {\n\t\treturn \"long\";\n\t}\n\treturn \"short\";\n}\n\nfunction resolveOpenAIResponsesCacheRetention(cacheRetention?: CacheRetention, env?: ProviderEnv): CacheRetention {\n\tif (cacheRetention) {\n\t\treturn cacheRetention;\n\t}\n\tif (getProviderEnvValue(\"PI_CACHE_RETENTION\", env) === \"long\") {\n\t\treturn \"long\";\n\t}\n\treturn \"short\";\n}\n\nexport function resolvePromptCacheTtlSeconds(model: Model<Api>, env?: ProviderEnv): number | undefined {\n\tswitch (model.api) {\n\t\tcase \"anthropic-messages\": {\n\t\t\tconst anthropicModel = model as Model<\"anthropic-messages\">;\n\t\t\tconst retention = resolveAnthropicCacheRetention(anthropicModel.cacheRetention, env, \"long\");\n\t\t\tif (retention === \"none\") return undefined;\n\t\t\treturn retention === \"long\" &&\n\t\t\t\tisAnthropicApiBaseUrl(anthropicModel.baseUrl) &&\n\t\t\t\tgetAnthropicCompat(anthropicModel).supportsLongCacheRetention\n\t\t\t\t? PROMPT_CACHE_TTL_LONG_SECONDS\n\t\t\t\t: PROMPT_CACHE_TTL_SHORT_SECONDS;\n\t\t}\n\t\tcase \"bedrock-converse-stream\": {\n\t\t\tconst bedrockModel = model as Model<\"bedrock-converse-stream\">;\n\t\t\tconst retention = resolveBedrockCacheRetention(bedrockModel.cacheRetention, env);\n\t\t\tif (retention === \"none\" || !supportsPromptCaching(bedrockModel, env)) return undefined;\n\t\t\treturn retention === \"long\" ? PROMPT_CACHE_TTL_LONG_SECONDS : PROMPT_CACHE_TTL_SHORT_SECONDS;\n\t\t}\n\t\tcase \"openai-completions\": {\n\t\t\tconst completionsModel = model as Model<\"openai-completions\">;\n\t\t\tconst retention = resolveOpenAICompletionsCacheRetention(completionsModel.cacheRetention, env);\n\t\t\tif (retention === \"none\") return undefined;\n\t\t\tconst compat = getOpenAICompletionsCompat(completionsModel);\n\t\t\tif (compat.cacheControlFormat === \"anthropic\") {\n\t\t\t\treturn retention === \"long\" && compat.supportsLongCacheRetention\n\t\t\t\t\t? PROMPT_CACHE_TTL_LONG_SECONDS\n\t\t\t\t\t: PROMPT_CACHE_TTL_SHORT_SECONDS;\n\t\t\t}\n\t\t\treturn PROMPT_CACHE_TTL_SHORT_SECONDS;\n\t\t}\n\t\tcase \"openai-responses\":\n\t\tcase \"openai-codex-responses\":\n\t\tcase \"azure-openai-responses\": {\n\t\t\tconst retention = resolveOpenAIResponsesCacheRetention(model.cacheRetention, env);\n\t\t\treturn retention === \"none\" ? undefined : PROMPT_CACHE_TTL_SHORT_SECONDS;\n\t\t}\n\t\tdefault:\n\t\t\treturn undefined;\n\t}\n}\n"]}
1
+ {"version":3,"file":"prompt-cache-ttl.js","sourceRoot":"","sources":["../../src/utils/prompt-cache-ttl.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n\tAnthropicMessagesCompat,\n\tApi,\n\tCacheRetention,\n\tModel,\n\tOpenAICompletionsCompat,\n\tProviderEnv,\n} from \"../types.ts\";\nimport { getProviderEnvValue } from \"./provider-env.ts\";\n\nexport const PROMPT_CACHE_TTL_SHORT_SECONDS = 300;\nexport const PROMPT_CACHE_TTL_LONG_SECONDS = 3600;\n\nexport function isAnthropicApiBaseUrl(baseUrl: string): boolean {\n\ttry {\n\t\treturn new URL(baseUrl).hostname === \"api.anthropic.com\";\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nconst CLAUDE_FABLE_OR_MYTHOS_MODEL_ID = /^claude-(?:fable|mythos)(?:-|$)/i;\n\n/**\n * Default for `supportsToolReferences`: first-party Anthropic models except\n * Haiku (rejects client-side tool_reference blocks) and models that predate\n * tool search (Claude 3.x, Opus/Sonnet 4.0, Opus 4.1).\n */\nfunction defaultSupportsToolReferences(model: Model<\"anthropic-messages\">): boolean {\n\tif (model.provider !== \"anthropic\" || model.id.includes(\"haiku\")) return false;\n\tconst version = model.id.match(/^claude-(?:opus|sonnet|fable)-(\\d+)(?:-(\\d+))?(?:-|$)/);\n\tif (!version) return false;\n\tconst major = Number(version[1]);\n\tconst minor = version[2] && version[2].length < 8 ? Number(version[2]) : 0;\n\treturn major > 4 || (major === 4 && minor >= 5);\n}\n\nexport function getAnthropicCompat(\n\tmodel: Model<\"anthropic-messages\">,\n): Required<Omit<AnthropicMessagesCompat, \"forceAdaptiveThinking\">> {\n\t// Auto-detect session affinity and cache control support from provider\n\tconst isFireworks = model.provider === \"fireworks\";\n\tconst isCloudflareAiGatewayAnthropic =\n\t\tmodel.provider === \"cloudflare-ai-gateway\" && model.baseUrl.includes(\"anthropic\");\n\tconst isXiaomi = model.provider === \"xiaomi\" || model.provider.startsWith(\"xiaomi-token-plan-\");\n\treturn {\n\t\tsupportsEagerToolInputStreaming: model.compat?.supportsEagerToolInputStreaming ?? !isFireworks,\n\t\tsupportsLongCacheRetention: model.compat?.supportsLongCacheRetention ?? !isFireworks,\n\t\tsendSessionAffinityHeaders:\n\t\t\tmodel.compat?.sendSessionAffinityHeaders ?? !!(isFireworks || isCloudflareAiGatewayAnthropic),\n\t\tsupportsCacheControlOnTools: model.compat?.supportsCacheControlOnTools ?? !isFireworks,\n\t\tsupportsDisabledThinking: model.compat?.supportsDisabledThinking ?? !isXiaomi,\n\t\tsupportsTemperature: model.compat?.supportsTemperature ?? true,\n\t\tsupportsToolChoice: model.compat?.supportsToolChoice ?? true,\n\t\tsupportsForcedToolChoice:\n\t\t\tmodel.compat?.supportsForcedToolChoice ?? !CLAUDE_FABLE_OR_MYTHOS_MODEL_ID.test(model.id),\n\t\tallowEmptySignature: model.compat?.allowEmptySignature ?? false,\n\t\tunsignedThinkingReplay:\n\t\t\tmodel.compat?.unsignedThinkingReplay ?? (model.compat?.allowEmptySignature ? \"empty-signature\" : \"text\"),\n\t\tsupportsStrictTools: model.compat?.supportsStrictTools ?? false,\n\t\tsupportsToolReferences: model.compat?.supportsToolReferences ?? defaultSupportsToolReferences(model),\n\t\t// Default: first-party Anthropic only. Anthropic-compatible providers\n\t\t// (kimi-coding, fireworks, copilot, gateways) may execute the server-side\n\t\t// search but reject the replayed server_tool_use / web_search_tool_result\n\t\t// blocks on the next request (kimi-coding 400s with `tool_call_id is not\n\t\t// found`).\n\t\tsupportsWebSearch: model.compat?.supportsWebSearch ?? isAnthropicApiBaseUrl(model.baseUrl),\n\t};\n}\n\nexport type ResolvedOpenAICompletionsCompat = Omit<\n\tRequired<OpenAICompletionsCompat>,\n\t\"cacheControlFormat\" | \"toolCallFormat\" | \"deferredToolsMode\" | \"toolSchemaFlavor\" | \"supportsPromptCacheKey\"\n> & {\n\tcacheControlFormat?: OpenAICompletionsCompat[\"cacheControlFormat\"];\n\tsupportsPromptCacheKey?: OpenAICompletionsCompat[\"supportsPromptCacheKey\"];\n\ttoolCallFormat?: OpenAICompletionsCompat[\"toolCallFormat\"];\n\tdeferredToolsMode?: OpenAICompletionsCompat[\"deferredToolsMode\"];\n\ttoolSchemaFlavor?: OpenAICompletionsCompat[\"toolSchemaFlavor\"];\n};\n\n/**\n * Detect compatibility settings from provider and baseUrl for known providers.\n * Provider takes precedence over URL-based detection since it's explicitly configured.\n * Returns a fully resolved OpenAICompletionsCompat object with all fields set.\n */\nfunction detectOpenAICompletionsCompat(model: Model<\"openai-completions\">): ResolvedOpenAICompletionsCompat {\n\tconst provider = model.provider;\n\tconst baseUrl = model.baseUrl;\n\n\tconst isZai =\n\t\tprovider === \"zai\" ||\n\t\tprovider === \"zai-coding-cn\" ||\n\t\tbaseUrl.includes(\"api.z.ai\") ||\n\t\tbaseUrl.includes(\"open.bigmodel.cn\");\n\tconst isTogether =\n\t\tprovider === \"together\" || baseUrl.includes(\"api.together.ai\") || baseUrl.includes(\"api.together.xyz\");\n\tconst isMoonshot = provider === \"moonshotai\" || provider === \"moonshotai-cn\" || baseUrl.includes(\"api.moonshot.\");\n\tconst isOpenRouter = provider === \"openrouter\" || baseUrl.includes(\"openrouter.ai\");\n\tconst isCloudflareWorkersAI = provider === \"cloudflare-workers-ai\" || baseUrl.includes(\"api.cloudflare.com\");\n\tconst isCloudflareAiGateway = provider === \"cloudflare-ai-gateway\" || baseUrl.includes(\"gateway.ai.cloudflare.com\");\n\tconst isNvidia = provider === \"nvidia\" || baseUrl.includes(\"integrate.api.nvidia.com\");\n\tconst isAntLing = provider === \"ant-ling\" || baseUrl.includes(\"api.ant-ling.com\");\n\n\tconst isNonStandard =\n\t\tisNvidia ||\n\t\tprovider === \"cerebras\" ||\n\t\tbaseUrl.includes(\"cerebras.ai\") ||\n\t\tprovider === \"xai\" ||\n\t\tbaseUrl.includes(\"api.x.ai\") ||\n\t\tisTogether ||\n\t\tbaseUrl.includes(\"chutes.ai\") ||\n\t\tbaseUrl.includes(\"deepseek.com\") ||\n\t\tisZai ||\n\t\tisMoonshot ||\n\t\tprovider === \"opencode\" ||\n\t\tbaseUrl.includes(\"opencode.ai\") ||\n\t\tisCloudflareWorkersAI ||\n\t\tisCloudflareAiGateway ||\n\t\tisAntLing;\n\n\tconst useMaxTokens =\n\t\tbaseUrl.includes(\"chutes.ai\") ||\n\t\tisMoonshot ||\n\t\tisCloudflareAiGateway ||\n\t\tisTogether ||\n\t\tisNvidia ||\n\t\tisAntLing ||\n\t\tisZai;\n\n\tconst isGrok = provider === \"xai\" || baseUrl.includes(\"api.x.ai\");\n\tconst isDeepSeek = provider === \"deepseek\" || baseUrl.includes(\"deepseek.com\");\n\tconst isOpenRouterDeveloperRoleModel =\n\t\tisOpenRouter && (model.id.startsWith(\"anthropic/\") || model.id.startsWith(\"openai/\"));\n\tconst openRouterCacheControlPrefixes = [\"anthropic/\", \"qwen/\", \"google/\"];\n\tconst cacheControlModelId = model.id.startsWith(\"~\") ? model.id.slice(1) : model.id;\n\tconst supportsOpenRouterCacheControl = openRouterCacheControlPrefixes.some((prefix) =>\n\t\tcacheControlModelId.startsWith(prefix),\n\t);\n\tconst cacheControlFormat = provider === \"openrouter\" && supportsOpenRouterCacheControl ? \"anthropic\" : undefined;\n\n\treturn {\n\t\tsupportsStore: !isNonStandard,\n\t\tsupportsDeveloperRole: isOpenRouterDeveloperRoleModel || (!isNonStandard && !isOpenRouter),\n\t\tsupportsReasoningEffort:\n\t\t\t!isGrok && !isZai && !isMoonshot && !isTogether && !isCloudflareAiGateway && !isNvidia && !isAntLing,\n\t\tsupportsUsageInStreaming: true,\n\t\tsupportsFinishReason: true,\n\t\tmaxTokensField: useMaxTokens ? \"max_tokens\" : \"max_completion_tokens\",\n\t\trequiresToolResultName: false,\n\t\trequiresAssistantAfterToolResult: false,\n\t\trequiresThinkingAsText: false,\n\t\trequiresReasoningContentOnAssistantMessages: isDeepSeek,\n\t\tthinkingFormat: isDeepSeek\n\t\t\t? \"deepseek\"\n\t\t\t: isZai\n\t\t\t\t? \"zai\"\n\t\t\t\t: isTogether\n\t\t\t\t\t? \"together\"\n\t\t\t\t\t: isAntLing\n\t\t\t\t\t\t? \"ant-ling\"\n\t\t\t\t\t\t: isOpenRouter\n\t\t\t\t\t\t\t? \"openrouter\"\n\t\t\t\t\t\t\t: \"openai\",\n\t\topenRouterRouting: {},\n\t\tvercelGatewayRouting: {},\n\t\tchatTemplateKwargs: {},\n\t\tzaiToolStream: false,\n\t\tsupportsStrictMode: !isMoonshot && !isTogether && !isCloudflareAiGateway && !isNvidia,\n\t\ttoolSchemaFlavor: isMoonshot ? \"moonshot-mfjs\" : undefined,\n\t\tsupportsDisabledThinking: true,\n\t\ttoolCallFormat: undefined,\n\t\tsupportsOpenAIGrammarTools: false,\n\t\tcacheControlFormat,\n\t\tsendSessionAffinityHeaders: isOpenRouter,\n\t\tdeferredToolsMode: undefined,\n\t\tsessionAffinityFormat: isOpenRouter ? \"openrouter\" : \"openai\",\n\t\tsupportsPromptCacheKey: isMoonshot || baseUrl.includes(\"api.openai.com\"),\n\t\tsupportsLongCacheRetention: !(\n\t\t\tisTogether ||\n\t\t\tisCloudflareWorkersAI ||\n\t\t\tisCloudflareAiGateway ||\n\t\t\tisNvidia ||\n\t\t\tisAntLing\n\t\t),\n\t};\n}\n\n/**\n * Get resolved compatibility settings for a model.\n * Auto-detects from provider/URL then overrides with explicit model.compat.\n */\nexport function getOpenAICompletionsCompat(model: Model<\"openai-completions\">): ResolvedOpenAICompletionsCompat {\n\tconst detected = detectOpenAICompletionsCompat(model);\n\tif (!model.compat) return detected;\n\n\treturn {\n\t\tsupportsStore: model.compat.supportsStore ?? detected.supportsStore,\n\t\tsupportsDeveloperRole: model.compat.supportsDeveloperRole ?? detected.supportsDeveloperRole,\n\t\tsupportsReasoningEffort: model.compat.supportsReasoningEffort ?? detected.supportsReasoningEffort,\n\t\tsupportsUsageInStreaming: model.compat.supportsUsageInStreaming ?? detected.supportsUsageInStreaming,\n\t\tsupportsFinishReason: model.compat.supportsFinishReason ?? detected.supportsFinishReason,\n\t\tmaxTokensField: model.compat.maxTokensField ?? detected.maxTokensField,\n\t\trequiresToolResultName: model.compat.requiresToolResultName ?? detected.requiresToolResultName,\n\t\trequiresAssistantAfterToolResult:\n\t\t\tmodel.compat.requiresAssistantAfterToolResult ?? detected.requiresAssistantAfterToolResult,\n\t\trequiresThinkingAsText: model.compat.requiresThinkingAsText ?? detected.requiresThinkingAsText,\n\t\trequiresReasoningContentOnAssistantMessages:\n\t\t\tmodel.compat.requiresReasoningContentOnAssistantMessages ??\n\t\t\tdetected.requiresReasoningContentOnAssistantMessages,\n\t\tthinkingFormat: model.compat.thinkingFormat ?? detected.thinkingFormat,\n\t\tsupportsDisabledThinking: model.compat.supportsDisabledThinking ?? detected.supportsDisabledThinking,\n\t\topenRouterRouting: model.compat.openRouterRouting ?? detected.openRouterRouting,\n\t\tvercelGatewayRouting: model.compat.vercelGatewayRouting ?? detected.vercelGatewayRouting,\n\t\tchatTemplateKwargs: model.compat.chatTemplateKwargs ?? detected.chatTemplateKwargs,\n\t\tzaiToolStream: model.compat.zaiToolStream ?? detected.zaiToolStream,\n\t\tsupportsStrictMode: model.compat.supportsStrictMode ?? detected.supportsStrictMode,\n\t\ttoolSchemaFlavor: model.compat.toolSchemaFlavor ?? detected.toolSchemaFlavor,\n\t\ttoolCallFormat: model.compat.toolCallFormat ?? detected.toolCallFormat,\n\t\tsupportsOpenAIGrammarTools: model.compat.supportsOpenAIGrammarTools ?? detected.supportsOpenAIGrammarTools,\n\t\tcacheControlFormat: model.compat.cacheControlFormat ?? detected.cacheControlFormat,\n\t\tsendSessionAffinityHeaders: model.compat.sendSessionAffinityHeaders ?? detected.sendSessionAffinityHeaders,\n\t\tdeferredToolsMode: model.compat.deferredToolsMode ?? detected.deferredToolsMode,\n\t\tsessionAffinityFormat: model.compat.sessionAffinityFormat ?? detected.sessionAffinityFormat,\n\t\tsupportsPromptCacheKey: model.compat.supportsPromptCacheKey ?? detected.supportsPromptCacheKey,\n\t\tsupportsLongCacheRetention: model.compat.supportsLongCacheRetention ?? detected.supportsLongCacheRetention,\n\t};\n}\n\nexport function getBedrockModelMatchCandidates(modelId: string, modelName?: string): string[] {\n\tconst values = modelName ? [modelId, modelName] : [modelId];\n\treturn values.flatMap((value) => {\n\t\tconst lower = value.toLowerCase();\n\t\treturn [lower, lower.replace(/[\\s_.:]+/g, \"-\")];\n\t});\n}\n\nexport function supportsOneHourCacheTtl(model: Model<\"bedrock-converse-stream\">): boolean {\n\tconst candidates = getBedrockModelMatchCandidates(model.id, model.name);\n\treturn candidates.some((candidate) =>\n\t\t[\"opus-4-5\", \"sonnet-4-5\", \"haiku-4-5\"].some((modelVersion) => candidate.includes(modelVersion)),\n\t);\n}\n\n/**\n * Check if the model supports prompt caching.\n * Supported: Claude 3.5 Haiku, Claude 3.7 Sonnet, Claude 4.x models, Claude 5 models\n *\n * For base models and system-defined inference profiles the model ID / ARN\n * contains the model name, so we can decide locally.\n *\n * For application inference profiles (whose ARNs don't contain the model name),\n * also checks model.name which is user-controlled via models.json or registerProvider.\n * As a last resort, set AWS_BEDROCK_FORCE_CACHE=1 to enable cache points.\n * Amazon Nova models have automatic caching and don't need explicit cache points.\n */\nexport function supportsPromptCaching(model: Model<\"bedrock-converse-stream\">, env?: ProviderEnv): boolean {\n\tconst candidates = getBedrockModelMatchCandidates(model.id, model.name);\n\n\tconst hasClaudeRef = candidates.some((s) => s.includes(\"claude\"));\n\tif (!hasClaudeRef) {\n\t\t// Application inference profiles don't contain the model name in the ARN.\n\t\t// Allow users to force cache points via environment variable.\n\t\tif (getProviderEnvValue(\"AWS_BEDROCK_FORCE_CACHE\", env) === \"1\") return true;\n\t\treturn false;\n\t}\n\t// Claude 5 models (fable-5, opus-5, sonnet-5)\n\tif (candidates.some((s) => s.includes(\"fable-5\") || s.includes(\"opus-5\") || s.includes(\"sonnet-5\"))) return true;\n\t// Claude 4.x models (opus-4, sonnet-4, haiku-4)\n\tif (candidates.some((s) => s.includes(\"-4-\"))) return true;\n\t// Claude 3.7 Sonnet\n\tif (candidates.some((s) => s.includes(\"claude-3-7-sonnet\"))) return true;\n\t// Claude 3.5 Haiku\n\tif (candidates.some((s) => s.includes(\"claude-3-5-haiku\"))) return true;\n\treturn false;\n}\n\nfunction resolveAnthropicCacheRetention(\n\tcacheRetention?: CacheRetention,\n\tenv?: ProviderEnv,\n\tfallback: CacheRetention = \"short\",\n): CacheRetention {\n\tif (cacheRetention) {\n\t\treturn cacheRetention;\n\t}\n\tif (getProviderEnvValue(\"PI_CACHE_RETENTION\", env) === \"long\") {\n\t\treturn \"long\";\n\t}\n\tif (typeof process !== \"undefined\" && process.env.PI_CACHE_RETENTION !== undefined) {\n\t\treturn \"short\";\n\t}\n\treturn fallback;\n}\n\nfunction resolveOpenAICompletionsCacheRetention(cacheRetention?: CacheRetention, env?: ProviderEnv): CacheRetention {\n\tif (cacheRetention) {\n\t\treturn cacheRetention;\n\t}\n\tif (getProviderEnvValue(\"PI_CACHE_RETENTION\", env) === \"long\") {\n\t\treturn \"long\";\n\t}\n\treturn \"short\";\n}\n\nfunction resolveBedrockCacheRetention(cacheRetention?: CacheRetention, env?: ProviderEnv): CacheRetention {\n\tif (cacheRetention) {\n\t\treturn cacheRetention;\n\t}\n\tif (getProviderEnvValue(\"PI_CACHE_RETENTION\", env) === \"long\") {\n\t\treturn \"long\";\n\t}\n\treturn \"short\";\n}\n\nfunction resolveOpenAIResponsesCacheRetention(cacheRetention?: CacheRetention, env?: ProviderEnv): CacheRetention {\n\tif (cacheRetention) {\n\t\treturn cacheRetention;\n\t}\n\tif (getProviderEnvValue(\"PI_CACHE_RETENTION\", env) === \"long\") {\n\t\treturn \"long\";\n\t}\n\treturn \"short\";\n}\n\nexport function resolvePromptCacheTtlSeconds(model: Model<Api>, env?: ProviderEnv): number | undefined {\n\tswitch (model.api) {\n\t\tcase \"claude-sdk-oauth\":\n\t\t\t// The Claude SDK owns prompt caching for this lane and uses Anthropic's default 5m TTL.\n\t\t\treturn PROMPT_CACHE_TTL_SHORT_SECONDS;\n\t\tcase \"anthropic-messages\": {\n\t\t\tconst anthropicModel = model as Model<\"anthropic-messages\">;\n\t\t\tconst retention = resolveAnthropicCacheRetention(anthropicModel.cacheRetention, env, \"long\");\n\t\t\tif (retention === \"none\") return undefined;\n\t\t\treturn retention === \"long\" &&\n\t\t\t\tisAnthropicApiBaseUrl(anthropicModel.baseUrl) &&\n\t\t\t\tgetAnthropicCompat(anthropicModel).supportsLongCacheRetention\n\t\t\t\t? PROMPT_CACHE_TTL_LONG_SECONDS\n\t\t\t\t: PROMPT_CACHE_TTL_SHORT_SECONDS;\n\t\t}\n\t\tcase \"bedrock-converse-stream\": {\n\t\t\tconst bedrockModel = model as Model<\"bedrock-converse-stream\">;\n\t\t\tconst retention = resolveBedrockCacheRetention(bedrockModel.cacheRetention, env);\n\t\t\tif (retention === \"none\" || !supportsPromptCaching(bedrockModel, env)) return undefined;\n\t\t\treturn retention === \"long\" && supportsOneHourCacheTtl(bedrockModel)\n\t\t\t\t? PROMPT_CACHE_TTL_LONG_SECONDS\n\t\t\t\t: PROMPT_CACHE_TTL_SHORT_SECONDS;\n\t\t}\n\t\tcase \"openai-completions\": {\n\t\t\tconst completionsModel = model as Model<\"openai-completions\">;\n\t\t\tconst retention = resolveOpenAICompletionsCacheRetention(completionsModel.cacheRetention, env);\n\t\t\tif (retention === \"none\") return undefined;\n\t\t\tconst compat = getOpenAICompletionsCompat(completionsModel);\n\t\t\tif (compat.cacheControlFormat === \"anthropic\") {\n\t\t\t\treturn retention === \"long\" && compat.supportsLongCacheRetention\n\t\t\t\t\t? PROMPT_CACHE_TTL_LONG_SECONDS\n\t\t\t\t\t: PROMPT_CACHE_TTL_SHORT_SECONDS;\n\t\t\t}\n\t\t\treturn PROMPT_CACHE_TTL_SHORT_SECONDS;\n\t\t}\n\t\tcase \"openai-responses\":\n\t\tcase \"openai-codex-responses\":\n\t\tcase \"azure-openai-responses\": {\n\t\t\tconst retention = resolveOpenAIResponsesCacheRetention(model.cacheRetention, env);\n\t\t\treturn retention === \"none\" ? undefined : PROMPT_CACHE_TTL_SHORT_SECONDS;\n\t\t}\n\t\tdefault:\n\t\t\treturn undefined;\n\t}\n}\n"]}
@@ -0,0 +1,4 @@
1
+ import type { AssistantMessage } from "../types.ts";
2
+ export declare function hasVisibleText(text: string): boolean;
3
+ export declare function hasVisibleAssistantContent(message: AssistantMessage): boolean;
4
+ //# sourceMappingURL=visible-text.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"visible-text.d.ts","sourceRoot":"","sources":["../../src/utils/visible-text.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAIpD,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEpD;AAED,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAI7E"}
@@ -0,0 +1,8 @@
1
+ const INVISIBLE_FORMAT_CHARS = /\p{Cf}/gu;
2
+ export function hasVisibleText(text) {
3
+ return text.replace(INVISIBLE_FORMAT_CHARS, "").trim().length > 0;
4
+ }
5
+ export function hasVisibleAssistantContent(message) {
6
+ return message.content.some((block) => block.type === "toolCall" || (block.type === "text" && hasVisibleText(block.text)));
7
+ }
8
+ //# sourceMappingURL=visible-text.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"visible-text.js","sourceRoot":"","sources":["../../src/utils/visible-text.ts"],"names":[],"mappings":"AAEA,MAAM,sBAAsB,GAAG,UAAU,CAAC;AAE1C,MAAM,UAAU,cAAc,CAAC,IAAY;IAC1C,OAAO,IAAI,CAAC,OAAO,CAAC,sBAAsB,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC;AACnE,CAAC;AAED,MAAM,UAAU,0BAA0B,CAAC,OAAyB;IACnE,OAAO,OAAO,CAAC,OAAO,CAAC,IAAI,CAC1B,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,UAAU,IAAI,CAAC,KAAK,CAAC,IAAI,KAAK,MAAM,IAAI,cAAc,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAC7F,CAAC;AACH,CAAC","sourcesContent":["import type { AssistantMessage } from \"../types.ts\";\n\nconst INVISIBLE_FORMAT_CHARS = /\\p{Cf}/gu;\n\nexport function hasVisibleText(text: string): boolean {\n\treturn text.replace(INVISIBLE_FORMAT_CHARS, \"\").trim().length > 0;\n}\n\nexport function hasVisibleAssistantContent(message: AssistantMessage): boolean {\n\treturn message.content.some(\n\t\t(block) => block.type === \"toolCall\" || (block.type === \"text\" && hasVisibleText(block.text)),\n\t);\n}\n"]}
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@earendil-works/pi-ai",
3
3
  "private": true,
4
- "version": "2026.8.6",
4
+ "version": "2026.8.9-2",
5
5
  "description": "Unified LLM API with automatic model discovery and provider configuration",
6
6
  "type": "module",
7
7
  "main": "./dist/index.js",
@@ -1,3 +1,4 @@
1
+ import { spawn } from "node:child_process";
1
2
  import type { NativePtyLoadResult } from "./native-loader.ts";
2
3
  export interface PipeFallbackSessionOptions {
3
4
  readonly command: string;
@@ -24,10 +25,21 @@ export type PipeFallbackOperationResult = {
24
25
  readonly code: "exited" | "not_pty" | "not_started" | "stdin_unavailable";
25
26
  readonly note: string;
26
27
  };
28
+ type ChildProcessHandle = ReturnType<typeof spawn>;
27
29
  type DataHandler = (chunk: Buffer) => void;
28
30
  type ExitHandler = (exit: PipeFallbackSessionExit) => void;
29
31
  export declare function isPipeFallbackForced(env?: Readonly<Record<string, string | undefined>>): boolean;
30
32
  export declare function shouldUsePipeFallback(nativeLoadResult: NativePtyLoadResult, env?: Readonly<Record<string, string | undefined>>): boolean;
33
+ /**
34
+ * Terminate the child, preferring its whole process group on POSIX. The
35
+ * detached child is its own group leader and grandchildren inherit the stdio
36
+ * pipes, so leaving them alive keeps 'close' from ever firing (the POSIX twin
37
+ * of the Windows taskkill /T branch below). Every path that stops a child must
38
+ * go through here: when the group signal is unavailable (Windows, no pid) or
39
+ * the group is already gone, it still falls back to a direct kill, so the
40
+ * child is never left running.
41
+ */
42
+ export declare function terminateChildTree(child: Pick<ChildProcessHandle, "pid" | "kill">, signal: NodeJS.Signals): "group" | "direct";
31
43
  export declare class PipeFallbackSession {
32
44
  readonly backend = "pipe-fallback";
33
45
  readonly note = "Running with child_process pipe fallback because no PTY backend is active; terminal screen state and resize are unavailable.";
@@ -1 +1 @@
1
- {"version":3,"file":"pipe-fallback.d.ts","sourceRoot":"","sources":["../src/pipe-fallback.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"pipe-fallback.d.ts","sourceRoot":"","sources":["../src/pipe-fallback.ts"],"names":[],"mappings":"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"}
@@ -7,6 +7,29 @@ export function isPipeFallbackForced(env = process.env) {
7
7
  export function shouldUsePipeFallback(nativeLoadResult, env = process.env) {
8
8
  return isPipeFallbackForced(env) || nativeLoadResult.native === null;
9
9
  }
10
+ /**
11
+ * Terminate the child, preferring its whole process group on POSIX. The
12
+ * detached child is its own group leader and grandchildren inherit the stdio
13
+ * pipes, so leaving them alive keeps 'close' from ever firing (the POSIX twin
14
+ * of the Windows taskkill /T branch below). Every path that stops a child must
15
+ * go through here: when the group signal is unavailable (Windows, no pid) or
16
+ * the group is already gone, it still falls back to a direct kill, so the
17
+ * child is never left running.
18
+ */
19
+ export function terminateChildTree(child, signal) {
20
+ const pid = child.pid;
21
+ if (pid !== undefined && process.platform !== "win32") {
22
+ try {
23
+ process.kill(-pid, signal);
24
+ return "group";
25
+ }
26
+ catch {
27
+ // Group already gone — fall through to the direct kill.
28
+ }
29
+ }
30
+ child.kill(signal);
31
+ return "direct";
32
+ }
10
33
  function normalizeSpawnError(command, error) {
11
34
  return {
12
35
  code: "spawn_error",
@@ -53,6 +76,13 @@ export class PipeFallbackSession {
53
76
  cwd: this.options.cwd,
54
77
  env: this.options.env ? { ...process.env, ...this.options.env } : process.env,
55
78
  stdio: ["pipe", "pipe", "pipe"],
79
+ // Detach on POSIX so the child leads its own session with no
80
+ // controlling terminal. Without this, a tty-reading program (e.g. a
81
+ // sudo password prompt) opens /dev/tty — the user's real terminal —
82
+ // and races the TUI's raw-mode stdin reader byte-by-byte, splitting
83
+ // keystrokes and Kitty escape sequences between the two readers.
84
+ // Detached, the /dev/tty open fails with a clear error instead.
85
+ detached: process.platform !== "win32",
56
86
  windowsHide: true,
57
87
  });
58
88
  this.child = child;
@@ -73,7 +103,7 @@ export class PipeFallbackSession {
73
103
  if (this.options.timeoutMs !== undefined) {
74
104
  this.timeoutHandle = setTimeout(() => {
75
105
  this.timedOut = true;
76
- child.kill("SIGTERM");
106
+ terminateChildTree(child, "SIGTERM");
77
107
  }, this.options.timeoutMs);
78
108
  }
79
109
  }
@@ -164,7 +194,9 @@ export class PipeFallbackSession {
164
194
  // Fall through to the direct kill if taskkill is unavailable.
165
195
  }
166
196
  }
167
- this.child.kill(signal);
197
+ if (terminateChildTree(this.child, signal) === "group") {
198
+ return { ok: true, note: `Sent ${signal} to child_process pipe fallback process group (pgid ${pid}).` };
199
+ }
168
200
  return { ok: true, note: `Sent ${signal} to child_process pipe fallback session.` };
169
201
  }
170
202
  waitExit() {
@@ -1 +1 @@
1
- {"version":3,"file":"pipe-fallback.js","sourceRoot":"","sources":["../src/pipe-fallback.ts"],"names":[],"mappings":"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","sourcesContent":["import { spawn } from \"node:child_process\";\nimport type { NativePtyLoadResult } from \"./native-loader.ts\";\n\nexport interface PipeFallbackSessionOptions {\n\treadonly command: string;\n\treadonly args?: readonly string[];\n\treadonly cwd?: string;\n\treadonly env?: Readonly<Record<string, string | undefined>>;\n\treadonly timeoutMs?: number;\n}\n\nexport interface PipeFallbackSessionError {\n\treadonly code: \"spawn_error\";\n\treadonly message: string;\n}\n\nexport interface PipeFallbackSessionExit {\n\treadonly exitCode: number | null;\n\treadonly signal: NodeJS.Signals | null;\n\treadonly timedOut: boolean;\n\treadonly error?: PipeFallbackSessionError;\n}\n\nexport type PipeFallbackOperationResult =\n\t| {\n\t\t\treadonly ok: true;\n\t\t\treadonly note: string;\n\t }\n\t| {\n\t\t\treadonly ok: false;\n\t\t\treadonly code: \"exited\" | \"not_pty\" | \"not_started\" | \"stdin_unavailable\";\n\t\t\treadonly note: string;\n\t };\n\ntype ChildProcessHandle = ReturnType<typeof spawn>;\ntype DataHandler = (chunk: Buffer) => void;\ntype ExitHandler = (exit: PipeFallbackSessionExit) => void;\n\nconst PIPE_FALLBACK_NOTE =\n\t\"Running with child_process pipe fallback because no PTY backend is active; terminal screen state and resize are unavailable.\";\n\nexport function isPipeFallbackForced(env: Readonly<Record<string, string | undefined>> = process.env): boolean {\n\tconst value = env.SENPI_PTY_FORCE_PIPE;\n\treturn value === \"1\" || value === \"true\";\n}\n\nexport function shouldUsePipeFallback(\n\tnativeLoadResult: NativePtyLoadResult,\n\tenv: Readonly<Record<string, string | undefined>> = process.env,\n): boolean {\n\treturn isPipeFallbackForced(env) || nativeLoadResult.native === null;\n}\n\nfunction normalizeSpawnError(command: string, error: Error): PipeFallbackSessionError {\n\treturn {\n\t\tcode: \"spawn_error\",\n\t\tmessage: `Failed to spawn pipe fallback command \"${command}\": ${error.message}`,\n\t};\n}\n\nfunction toBuffer(chunk: string | Buffer): Buffer {\n\treturn Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);\n}\n\nfunction validateTimeout(timeoutMs: number | undefined): void {\n\tif (timeoutMs === undefined) return;\n\tif (!Number.isFinite(timeoutMs) || timeoutMs <= 0) {\n\t\tthrow new Error(\"Invalid timeoutMs: must be a finite positive number\");\n\t}\n}\n\nexport class PipeFallbackSession {\n\treadonly backend = \"pipe-fallback\";\n\treadonly note = PIPE_FALLBACK_NOTE;\n\treadonly options: PipeFallbackSessionOptions;\n\tprivate child: ChildProcessHandle | null = null;\n\tprivate exitResult: PipeFallbackSessionExit | null = null;\n\tprivate exitPromise: Promise<PipeFallbackSessionExit>;\n\tprivate resolveExit: ((exit: PipeFallbackSessionExit) => void) | null = null;\n\tprivate spawnError: PipeFallbackSessionError | undefined;\n\tprivate timedOut = false;\n\tprivate timeoutHandle: NodeJS.Timeout | undefined;\n\tprivate readonly dataHandlers = new Set<DataHandler>();\n\tprivate readonly exitHandlers = new Set<ExitHandler>();\n\n\tconstructor(options: PipeFallbackSessionOptions) {\n\t\tthis.options = {\n\t\t\t...options,\n\t\t\targs: options.args ? [...options.args] : undefined,\n\t\t\tenv: options.env ? { ...options.env } : undefined,\n\t\t};\n\t\tthis.exitPromise = new Promise((resolve) => {\n\t\t\tthis.resolveExit = resolve;\n\t\t});\n\t}\n\n\tstart(): this {\n\t\tif (this.exitResult !== null) throw new Error(\"Cannot restart exited pipe fallback session\");\n\t\tif (this.child !== null) throw new Error(\"Pipe fallback session has already been started\");\n\t\tvalidateTimeout(this.options.timeoutMs);\n\n\t\ttry {\n\t\t\tconst child = spawn(this.options.command, [...(this.options.args ?? [])], {\n\t\t\t\tcwd: this.options.cwd,\n\t\t\t\tenv: this.options.env ? { ...process.env, ...this.options.env } : process.env,\n\t\t\t\tstdio: [\"pipe\", \"pipe\", \"pipe\"],\n\t\t\t\twindowsHide: true,\n\t\t\t});\n\t\t\tthis.child = child;\n\t\t\tchild.stdout?.on(\"data\", (chunk: string | Buffer) => this.emitData(toBuffer(chunk)));\n\t\t\tchild.stderr?.on(\"data\", (chunk: string | Buffer) => this.emitData(toBuffer(chunk)));\n\t\t\tchild.stdin?.on(\"error\", () => {});\n\t\t\tchild.on(\"error\", (error: Error) => {\n\t\t\t\tthis.spawnError = normalizeSpawnError(this.options.command, error);\n\t\t\t});\n\t\t\tchild.on(\"close\", (exitCode, signal) => {\n\t\t\t\tthis.settleExit({\n\t\t\t\t\texitCode: this.spawnError ? null : exitCode,\n\t\t\t\t\tsignal,\n\t\t\t\t\ttimedOut: this.timedOut,\n\t\t\t\t\terror: this.spawnError,\n\t\t\t\t});\n\t\t\t});\n\t\t\tif (this.options.timeoutMs !== undefined) {\n\t\t\t\tthis.timeoutHandle = setTimeout(() => {\n\t\t\t\t\tthis.timedOut = true;\n\t\t\t\t\tchild.kill(\"SIGTERM\");\n\t\t\t\t}, this.options.timeoutMs);\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tconst cause = error instanceof Error ? error : new Error(String(error));\n\t\t\tthis.settleExit({\n\t\t\t\texitCode: null,\n\t\t\t\tsignal: null,\n\t\t\t\ttimedOut: false,\n\t\t\t\terror: normalizeSpawnError(this.options.command, cause),\n\t\t\t});\n\t\t}\n\t\treturn this;\n\t}\n\n\tonData(handler: DataHandler): () => void {\n\t\tthis.dataHandlers.add(handler);\n\t\treturn () => this.dataHandlers.delete(handler);\n\t}\n\n\tonExit(handler: ExitHandler): () => void {\n\t\tconst exitResult = this.exitResult;\n\t\tif (exitResult !== null) queueMicrotask(() => handler(exitResult));\n\t\telse this.exitHandlers.add(handler);\n\t\treturn () => this.exitHandlers.delete(handler);\n\t}\n\n\twrite(data: string | Uint8Array): PipeFallbackOperationResult {\n\t\tif (this.exitResult !== null) {\n\t\t\treturn { ok: false, code: \"exited\", note: \"Cannot write to pipe fallback stdin: session has exited.\" };\n\t\t}\n\t\tif (this.child === null) {\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\tcode: \"not_started\",\n\t\t\t\tnote: \"Cannot write to pipe fallback stdin: session has not started.\",\n\t\t\t};\n\t\t}\n\t\tif (!this.child.stdin || this.child.stdin.destroyed || this.child.stdin.writableEnded) {\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\tcode: \"stdin_unavailable\",\n\t\t\t\tnote: \"Cannot write to pipe fallback stdin: child stdin is unavailable.\",\n\t\t\t};\n\t\t}\n\t\tconst accepted = this.child.stdin.write(data);\n\t\treturn {\n\t\t\tok: true,\n\t\t\tnote: accepted\n\t\t\t\t? \"Wrote stdin through child_process pipe fallback; this is not a PTY.\"\n\t\t\t\t: \"Queued stdin through child_process pipe fallback with stream backpressure; this is not a PTY.\",\n\t\t};\n\t}\n\n\tcloseInput(): PipeFallbackOperationResult {\n\t\tif (this.exitResult !== null) {\n\t\t\treturn { ok: false, code: \"exited\", note: \"Cannot close pipe fallback stdin: session has exited.\" };\n\t\t}\n\t\tif (this.child === null) {\n\t\t\treturn { ok: false, code: \"not_started\", note: \"Cannot close pipe fallback stdin: session has not started.\" };\n\t\t}\n\t\tthis.child.stdin?.end();\n\t\treturn { ok: true, note: \"Closed child_process pipe fallback stdin.\" };\n\t}\n\n\tresize(cols: number, rows: number): PipeFallbackOperationResult {\n\t\treturn {\n\t\t\tok: false,\n\t\t\tcode: \"not_pty\",\n\t\t\tnote: `Cannot resize pipe fallback session to ${cols}x${rows}: child_process pipes are not a PTY; session is still valid.`,\n\t\t};\n\t}\n\n\tkill(signal: NodeJS.Signals = \"SIGTERM\"): PipeFallbackOperationResult {\n\t\tif (this.exitResult !== null) {\n\t\t\treturn { ok: false, code: \"exited\", note: \"Cannot kill pipe fallback session: session has exited.\" };\n\t\t}\n\t\tif (this.child === null) {\n\t\t\treturn { ok: false, code: \"not_started\", note: \"Cannot kill pipe fallback session: session has not started.\" };\n\t\t}\n\t\tconst pid = this.child.pid;\n\t\tif (process.platform === \"win32\" && pid !== undefined) {\n\t\t\t// On Windows child.kill() TerminateProcess-es only the direct child, leaving\n\t\t\t// grandchildren (e.g. `sleep` under `bash.exe -c`) alive and holding the stdout\n\t\t\t// pipe open — so 'close' never fires and waitExit() hangs teardown. taskkill /T /F\n\t\t\t// terminates the whole tree so the pipe EOFs and the session settles.\n\t\t\ttry {\n\t\t\t\tspawn(\"taskkill\", [\"/pid\", String(pid), \"/T\", \"/F\"], { stdio: \"ignore\", windowsHide: true });\n\t\t\t\treturn { ok: true, note: `Terminated child_process pipe fallback process tree (pid ${pid}).` };\n\t\t\t} catch {\n\t\t\t\t// Fall through to the direct kill if taskkill is unavailable.\n\t\t\t}\n\t\t}\n\t\tthis.child.kill(signal);\n\t\treturn { ok: true, note: `Sent ${signal} to child_process pipe fallback session.` };\n\t}\n\n\twaitExit(): Promise<PipeFallbackSessionExit> {\n\t\treturn this.exitPromise;\n\t}\n\n\tprivate emitData(chunk: Buffer): void {\n\t\tfor (const handler of this.dataHandlers) handler(chunk);\n\t}\n\n\tprivate settleExit(exit: PipeFallbackSessionExit): void {\n\t\tif (this.exitResult !== null) return;\n\t\tif (this.timeoutHandle) clearTimeout(this.timeoutHandle);\n\t\tthis.exitResult = exit;\n\t\tthis.resolveExit?.(exit);\n\t\tfor (const handler of this.exitHandlers) handler(exit);\n\t\tthis.exitHandlers.clear();\n\t}\n}\n\nexport function createPipeFallbackSession(options: PipeFallbackSessionOptions): PipeFallbackSession {\n\treturn new PipeFallbackSession(options).start();\n}\n"]}
1
+ {"version":3,"file":"pipe-fallback.js","sourceRoot":"","sources":["../src/pipe-fallback.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAsC3C,MAAM,kBAAkB,GACvB,8HAA8H,CAAC;AAEhI,MAAM,UAAU,oBAAoB,CAAC,GAAG,GAAiD,OAAO,CAAC,GAAG;IACnG,MAAM,KAAK,GAAG,GAAG,CAAC,oBAAoB,CAAC;IACvC,OAAO,KAAK,KAAK,GAAG,IAAI,KAAK,KAAK,MAAM,CAAC;AAC1C,CAAC;AAED,MAAM,UAAU,qBAAqB,CACpC,gBAAqC,EACrC,GAAG,GAAiD,OAAO,CAAC,GAAG;IAE/D,OAAO,oBAAoB,CAAC,GAAG,CAAC,IAAI,gBAAgB,CAAC,MAAM,KAAK,IAAI,CAAC;AACtE,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,kBAAkB,CACjC,KAA+C,EAC/C,MAAsB;IAEtB,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC;IACtB,IAAI,GAAG,KAAK,SAAS,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QACvD,IAAI,CAAC;YACJ,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;YAC3B,OAAO,OAAO,CAAC;QAChB,CAAC;QAAC,MAAM,CAAC;YACR,wDAAwD;QACzD,CAAC;IACF,CAAC;IACD,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACnB,OAAO,QAAQ,CAAC;AACjB,CAAC;AAED,SAAS,mBAAmB,CAAC,OAAe,EAAE,KAAY;IACzD,OAAO;QACN,IAAI,EAAE,aAAa;QACnB,OAAO,EAAE,0CAA0C,OAAO,MAAM,KAAK,CAAC,OAAO,EAAE;KAC/E,CAAC;AACH,CAAC;AAED,SAAS,QAAQ,CAAC,KAAsB;IACvC,OAAO,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AAC5D,CAAC;AAED,SAAS,eAAe,CAAC,SAA6B;IACrD,IAAI,SAAS,KAAK,SAAS;QAAE,OAAO;IACpC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,SAAS,IAAI,CAAC,EAAE,CAAC;QACnD,MAAM,IAAI,KAAK,CAAC,qDAAqD,CAAC,CAAC;IACxE,CAAC;AACF,CAAC;AAED,MAAM,OAAO,mBAAmB;IAc/B,YAAY,OAAmC;QAbtC,YAAO,GAAG,eAAe,CAAC;QAC1B,SAAI,GAAG,kBAAkB,CAAC;QAE3B,UAAK,GAA8B,IAAI,CAAC;QACxC,eAAU,GAAmC,IAAI,CAAC;QAElD,gBAAW,GAAqD,IAAI,CAAC;QAErE,aAAQ,GAAG,KAAK,CAAC;QAER,iBAAY,GAAG,IAAI,GAAG,EAAe,CAAC;QACtC,iBAAY,GAAG,IAAI,GAAG,EAAe,CAAC;QAGtD,IAAI,CAAC,OAAO,GAAG;YACd,GAAG,OAAO;YACV,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS;YAClD,GAAG,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,SAAS;SACjD,CAAC;QACF,IAAI,CAAC,WAAW,GAAG,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;YAC1C,IAAI,CAAC,WAAW,GAAG,OAAO,CAAC;QAC5B,CAAC,CAAC,CAAC;IACJ,CAAC;IAED,KAAK;QACJ,IAAI,IAAI,CAAC,UAAU,KAAK,IAAI;YAAE,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAC;QAC7F,IAAI,IAAI,CAAC,KAAK,KAAK,IAAI;YAAE,MAAM,IAAI,KAAK,CAAC,gDAAgD,CAAC,CAAC;QAC3F,eAAe,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QAExC,IAAI,CAAC;YACJ,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,EAAE;gBACzE,GAAG,EAAE,IAAI,CAAC,OAAO,CAAC,GAAG;gBACrB,GAAG,EAAE,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG;gBAC7E,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;gBAC/B,6DAA6D;gBAC7D,oEAAoE;gBACpE,oEAAoE;gBACpE,oEAAoE;gBACpE,iEAAiE;gBACjE,gEAAgE;gBAChE,QAAQ,EAAE,OAAO,CAAC,QAAQ,KAAK,OAAO;gBACtC,WAAW,EAAE,IAAI;aACjB,CAAC,CAAC;YACH,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;YACnB,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,KAAsB,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YACrF,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,KAAsB,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YACrF,KAAK,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;YACnC,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,KAAY,EAAE,EAAE;gBAClC,IAAI,CAAC,UAAU,GAAG,mBAAmB,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;YACpE,CAAC,CAAC,CAAC;YACH,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE;gBACtC,IAAI,CAAC,UAAU,CAAC;oBACf,QAAQ,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ;oBAC3C,MAAM;oBACN,QAAQ,EAAE,IAAI,CAAC,QAAQ;oBACvB,KAAK,EAAE,IAAI,CAAC,UAAU;iBACtB,CAAC,CAAC;YACJ,CAAC,CAAC,CAAC;YACH,IAAI,IAAI,CAAC,OAAO,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;gBAC1C,IAAI,CAAC,aAAa,GAAG,UAAU,CAAC,GAAG,EAAE;oBACpC,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;oBACrB,kBAAkB,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;gBACtC,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;YAC5B,CAAC;QACF,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,MAAM,KAAK,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;YACxE,IAAI,CAAC,UAAU,CAAC;gBACf,QAAQ,EAAE,IAAI;gBACd,MAAM,EAAE,IAAI;gBACZ,QAAQ,EAAE,KAAK;gBACf,KAAK,EAAE,mBAAmB,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,KAAK,CAAC;aACvD,CAAC,CAAC;QACJ,CAAC;QACD,OAAO,IAAI,CAAC;IACb,CAAC;IAED,MAAM,CAAC,OAAoB;QAC1B,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAC/B,OAAO,GAAG,EAAE,CAAC,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAChD,CAAC;IAED,MAAM,CAAC,OAAoB;QAC1B,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC;QACnC,IAAI,UAAU,KAAK,IAAI;YAAE,cAAc,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC;;YAC9D,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACpC,OAAO,GAAG,EAAE,CAAC,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAChD,CAAC;IAED,KAAK,CAAC,IAAyB;QAC9B,IAAI,IAAI,CAAC,UAAU,KAAK,IAAI,EAAE,CAAC;YAC9B,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,0DAA0D,EAAE,CAAC;QACxG,CAAC;QACD,IAAI,IAAI,CAAC,KAAK,KAAK,IAAI,EAAE,CAAC;YACzB,OAAO;gBACN,EAAE,EAAE,KAAK;gBACT,IAAI,EAAE,aAAa;gBACnB,IAAI,EAAE,+DAA+D;aACrE,CAAC;QACH,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,SAAS,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,aAAa,EAAE,CAAC;YACvF,OAAO;gBACN,EAAE,EAAE,KAAK;gBACT,IAAI,EAAE,mBAAmB;gBACzB,IAAI,EAAE,kEAAkE;aACxE,CAAC;QACH,CAAC;QACD,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC9C,OAAO;YACN,EAAE,EAAE,IAAI;YACR,IAAI,EAAE,QAAQ;gBACb,CAAC,CAAC,qEAAqE;gBACvE,CAAC,CAAC,+FAA+F;SAClG,CAAC;IACH,CAAC;IAED,UAAU;QACT,IAAI,IAAI,CAAC,UAAU,KAAK,IAAI,EAAE,CAAC;YAC9B,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,uDAAuD,EAAE,CAAC;QACrG,CAAC;QACD,IAAI,IAAI,CAAC,KAAK,KAAK,IAAI,EAAE,CAAC;YACzB,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,4DAA4D,EAAE,CAAC;QAC/G,CAAC;QACD,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,GAAG,EAAE,CAAC;QACxB,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,2CAA2C,EAAE,CAAC;IACxE,CAAC;IAED,MAAM,CAAC,IAAY,EAAE,IAAY;QAChC,OAAO;YACN,EAAE,EAAE,KAAK;YACT,IAAI,EAAE,SAAS;YACf,IAAI,EAAE,0CAA0C,IAAI,IAAI,IAAI,8DAA8D;SAC1H,CAAC;IACH,CAAC;IAED,IAAI,CAAC,MAAM,GAAmB,SAAS;QACtC,IAAI,IAAI,CAAC,UAAU,KAAK,IAAI,EAAE,CAAC;YAC9B,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,wDAAwD,EAAE,CAAC;QACtG,CAAC;QACD,IAAI,IAAI,CAAC,KAAK,KAAK,IAAI,EAAE,CAAC;YACzB,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,6DAA6D,EAAE,CAAC;QAChH,CAAC;QACD,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC;QAC3B,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;YACvD,6EAA6E;YAC7E,gFAAgF;YAChF,mFAAmF;YACnF,sEAAsE;YACtE,IAAI,CAAC;gBACJ,KAAK,CAAC,UAAU,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC;gBAC7F,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,4DAA4D,GAAG,IAAI,EAAE,CAAC;YAChG,CAAC;YAAC,MAAM,CAAC;gBACR,8DAA8D;YAC/D,CAAC;QACF,CAAC;QACD,IAAI,kBAAkB,CAAC,IAAI,CAAC,KAAK,EAAE,MAAM,CAAC,KAAK,OAAO,EAAE,CAAC;YACxD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,MAAM,uDAAuD,GAAG,IAAI,EAAE,CAAC;QACzG,CAAC;QACD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,MAAM,0CAA0C,EAAE,CAAC;IACrF,CAAC;IAED,QAAQ;QACP,OAAO,IAAI,CAAC,WAAW,CAAC;IACzB,CAAC;IAEO,QAAQ,CAAC,KAAa;QAC7B,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,YAAY;YAAE,OAAO,CAAC,KAAK,CAAC,CAAC;IACzD,CAAC;IAEO,UAAU,CAAC,IAA6B;QAC/C,IAAI,IAAI,CAAC,UAAU,KAAK,IAAI;YAAE,OAAO;QACrC,IAAI,IAAI,CAAC,aAAa;YAAE,YAAY,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QACzD,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;QACvB,IAAI,CAAC,WAAW,EAAE,CAAC,IAAI,CAAC,CAAC;QACzB,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,YAAY;YAAE,OAAO,CAAC,IAAI,CAAC,CAAC;QACvD,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,CAAC;IAC3B,CAAC;CACD;AAED,MAAM,UAAU,yBAAyB,CAAC,OAAmC;IAC5E,OAAO,IAAI,mBAAmB,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,CAAC;AACjD,CAAC","sourcesContent":["import { spawn } from \"node:child_process\";\nimport type { NativePtyLoadResult } from \"./native-loader.ts\";\n\nexport interface PipeFallbackSessionOptions {\n\treadonly command: string;\n\treadonly args?: readonly string[];\n\treadonly cwd?: string;\n\treadonly env?: Readonly<Record<string, string | undefined>>;\n\treadonly timeoutMs?: number;\n}\n\nexport interface PipeFallbackSessionError {\n\treadonly code: \"spawn_error\";\n\treadonly message: string;\n}\n\nexport interface PipeFallbackSessionExit {\n\treadonly exitCode: number | null;\n\treadonly signal: NodeJS.Signals | null;\n\treadonly timedOut: boolean;\n\treadonly error?: PipeFallbackSessionError;\n}\n\nexport type PipeFallbackOperationResult =\n\t| {\n\t\t\treadonly ok: true;\n\t\t\treadonly note: string;\n\t }\n\t| {\n\t\t\treadonly ok: false;\n\t\t\treadonly code: \"exited\" | \"not_pty\" | \"not_started\" | \"stdin_unavailable\";\n\t\t\treadonly note: string;\n\t };\n\ntype ChildProcessHandle = ReturnType<typeof spawn>;\ntype DataHandler = (chunk: Buffer) => void;\ntype ExitHandler = (exit: PipeFallbackSessionExit) => void;\n\nconst PIPE_FALLBACK_NOTE =\n\t\"Running with child_process pipe fallback because no PTY backend is active; terminal screen state and resize are unavailable.\";\n\nexport function isPipeFallbackForced(env: Readonly<Record<string, string | undefined>> = process.env): boolean {\n\tconst value = env.SENPI_PTY_FORCE_PIPE;\n\treturn value === \"1\" || value === \"true\";\n}\n\nexport function shouldUsePipeFallback(\n\tnativeLoadResult: NativePtyLoadResult,\n\tenv: Readonly<Record<string, string | undefined>> = process.env,\n): boolean {\n\treturn isPipeFallbackForced(env) || nativeLoadResult.native === null;\n}\n\n/**\n * Terminate the child, preferring its whole process group on POSIX. The\n * detached child is its own group leader and grandchildren inherit the stdio\n * pipes, so leaving them alive keeps 'close' from ever firing (the POSIX twin\n * of the Windows taskkill /T branch below). Every path that stops a child must\n * go through here: when the group signal is unavailable (Windows, no pid) or\n * the group is already gone, it still falls back to a direct kill, so the\n * child is never left running.\n */\nexport function terminateChildTree(\n\tchild: Pick<ChildProcessHandle, \"pid\" | \"kill\">,\n\tsignal: NodeJS.Signals,\n): \"group\" | \"direct\" {\n\tconst pid = child.pid;\n\tif (pid !== undefined && process.platform !== \"win32\") {\n\t\ttry {\n\t\t\tprocess.kill(-pid, signal);\n\t\t\treturn \"group\";\n\t\t} catch {\n\t\t\t// Group already gone — fall through to the direct kill.\n\t\t}\n\t}\n\tchild.kill(signal);\n\treturn \"direct\";\n}\n\nfunction normalizeSpawnError(command: string, error: Error): PipeFallbackSessionError {\n\treturn {\n\t\tcode: \"spawn_error\",\n\t\tmessage: `Failed to spawn pipe fallback command \"${command}\": ${error.message}`,\n\t};\n}\n\nfunction toBuffer(chunk: string | Buffer): Buffer {\n\treturn Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);\n}\n\nfunction validateTimeout(timeoutMs: number | undefined): void {\n\tif (timeoutMs === undefined) return;\n\tif (!Number.isFinite(timeoutMs) || timeoutMs <= 0) {\n\t\tthrow new Error(\"Invalid timeoutMs: must be a finite positive number\");\n\t}\n}\n\nexport class PipeFallbackSession {\n\treadonly backend = \"pipe-fallback\";\n\treadonly note = PIPE_FALLBACK_NOTE;\n\treadonly options: PipeFallbackSessionOptions;\n\tprivate child: ChildProcessHandle | null = null;\n\tprivate exitResult: PipeFallbackSessionExit | null = null;\n\tprivate exitPromise: Promise<PipeFallbackSessionExit>;\n\tprivate resolveExit: ((exit: PipeFallbackSessionExit) => void) | null = null;\n\tprivate spawnError: PipeFallbackSessionError | undefined;\n\tprivate timedOut = false;\n\tprivate timeoutHandle: NodeJS.Timeout | undefined;\n\tprivate readonly dataHandlers = new Set<DataHandler>();\n\tprivate readonly exitHandlers = new Set<ExitHandler>();\n\n\tconstructor(options: PipeFallbackSessionOptions) {\n\t\tthis.options = {\n\t\t\t...options,\n\t\t\targs: options.args ? [...options.args] : undefined,\n\t\t\tenv: options.env ? { ...options.env } : undefined,\n\t\t};\n\t\tthis.exitPromise = new Promise((resolve) => {\n\t\t\tthis.resolveExit = resolve;\n\t\t});\n\t}\n\n\tstart(): this {\n\t\tif (this.exitResult !== null) throw new Error(\"Cannot restart exited pipe fallback session\");\n\t\tif (this.child !== null) throw new Error(\"Pipe fallback session has already been started\");\n\t\tvalidateTimeout(this.options.timeoutMs);\n\n\t\ttry {\n\t\t\tconst child = spawn(this.options.command, [...(this.options.args ?? [])], {\n\t\t\t\tcwd: this.options.cwd,\n\t\t\t\tenv: this.options.env ? { ...process.env, ...this.options.env } : process.env,\n\t\t\t\tstdio: [\"pipe\", \"pipe\", \"pipe\"],\n\t\t\t\t// Detach on POSIX so the child leads its own session with no\n\t\t\t\t// controlling terminal. Without this, a tty-reading program (e.g. a\n\t\t\t\t// sudo password prompt) opens /dev/tty — the user's real terminal —\n\t\t\t\t// and races the TUI's raw-mode stdin reader byte-by-byte, splitting\n\t\t\t\t// keystrokes and Kitty escape sequences between the two readers.\n\t\t\t\t// Detached, the /dev/tty open fails with a clear error instead.\n\t\t\t\tdetached: process.platform !== \"win32\",\n\t\t\t\twindowsHide: true,\n\t\t\t});\n\t\t\tthis.child = child;\n\t\t\tchild.stdout?.on(\"data\", (chunk: string | Buffer) => this.emitData(toBuffer(chunk)));\n\t\t\tchild.stderr?.on(\"data\", (chunk: string | Buffer) => this.emitData(toBuffer(chunk)));\n\t\t\tchild.stdin?.on(\"error\", () => {});\n\t\t\tchild.on(\"error\", (error: Error) => {\n\t\t\t\tthis.spawnError = normalizeSpawnError(this.options.command, error);\n\t\t\t});\n\t\t\tchild.on(\"close\", (exitCode, signal) => {\n\t\t\t\tthis.settleExit({\n\t\t\t\t\texitCode: this.spawnError ? null : exitCode,\n\t\t\t\t\tsignal,\n\t\t\t\t\ttimedOut: this.timedOut,\n\t\t\t\t\terror: this.spawnError,\n\t\t\t\t});\n\t\t\t});\n\t\t\tif (this.options.timeoutMs !== undefined) {\n\t\t\t\tthis.timeoutHandle = setTimeout(() => {\n\t\t\t\t\tthis.timedOut = true;\n\t\t\t\t\tterminateChildTree(child, \"SIGTERM\");\n\t\t\t\t}, this.options.timeoutMs);\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tconst cause = error instanceof Error ? error : new Error(String(error));\n\t\t\tthis.settleExit({\n\t\t\t\texitCode: null,\n\t\t\t\tsignal: null,\n\t\t\t\ttimedOut: false,\n\t\t\t\terror: normalizeSpawnError(this.options.command, cause),\n\t\t\t});\n\t\t}\n\t\treturn this;\n\t}\n\n\tonData(handler: DataHandler): () => void {\n\t\tthis.dataHandlers.add(handler);\n\t\treturn () => this.dataHandlers.delete(handler);\n\t}\n\n\tonExit(handler: ExitHandler): () => void {\n\t\tconst exitResult = this.exitResult;\n\t\tif (exitResult !== null) queueMicrotask(() => handler(exitResult));\n\t\telse this.exitHandlers.add(handler);\n\t\treturn () => this.exitHandlers.delete(handler);\n\t}\n\n\twrite(data: string | Uint8Array): PipeFallbackOperationResult {\n\t\tif (this.exitResult !== null) {\n\t\t\treturn { ok: false, code: \"exited\", note: \"Cannot write to pipe fallback stdin: session has exited.\" };\n\t\t}\n\t\tif (this.child === null) {\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\tcode: \"not_started\",\n\t\t\t\tnote: \"Cannot write to pipe fallback stdin: session has not started.\",\n\t\t\t};\n\t\t}\n\t\tif (!this.child.stdin || this.child.stdin.destroyed || this.child.stdin.writableEnded) {\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\tcode: \"stdin_unavailable\",\n\t\t\t\tnote: \"Cannot write to pipe fallback stdin: child stdin is unavailable.\",\n\t\t\t};\n\t\t}\n\t\tconst accepted = this.child.stdin.write(data);\n\t\treturn {\n\t\t\tok: true,\n\t\t\tnote: accepted\n\t\t\t\t? \"Wrote stdin through child_process pipe fallback; this is not a PTY.\"\n\t\t\t\t: \"Queued stdin through child_process pipe fallback with stream backpressure; this is not a PTY.\",\n\t\t};\n\t}\n\n\tcloseInput(): PipeFallbackOperationResult {\n\t\tif (this.exitResult !== null) {\n\t\t\treturn { ok: false, code: \"exited\", note: \"Cannot close pipe fallback stdin: session has exited.\" };\n\t\t}\n\t\tif (this.child === null) {\n\t\t\treturn { ok: false, code: \"not_started\", note: \"Cannot close pipe fallback stdin: session has not started.\" };\n\t\t}\n\t\tthis.child.stdin?.end();\n\t\treturn { ok: true, note: \"Closed child_process pipe fallback stdin.\" };\n\t}\n\n\tresize(cols: number, rows: number): PipeFallbackOperationResult {\n\t\treturn {\n\t\t\tok: false,\n\t\t\tcode: \"not_pty\",\n\t\t\tnote: `Cannot resize pipe fallback session to ${cols}x${rows}: child_process pipes are not a PTY; session is still valid.`,\n\t\t};\n\t}\n\n\tkill(signal: NodeJS.Signals = \"SIGTERM\"): PipeFallbackOperationResult {\n\t\tif (this.exitResult !== null) {\n\t\t\treturn { ok: false, code: \"exited\", note: \"Cannot kill pipe fallback session: session has exited.\" };\n\t\t}\n\t\tif (this.child === null) {\n\t\t\treturn { ok: false, code: \"not_started\", note: \"Cannot kill pipe fallback session: session has not started.\" };\n\t\t}\n\t\tconst pid = this.child.pid;\n\t\tif (process.platform === \"win32\" && pid !== undefined) {\n\t\t\t// On Windows child.kill() TerminateProcess-es only the direct child, leaving\n\t\t\t// grandchildren (e.g. `sleep` under `bash.exe -c`) alive and holding the stdout\n\t\t\t// pipe open — so 'close' never fires and waitExit() hangs teardown. taskkill /T /F\n\t\t\t// terminates the whole tree so the pipe EOFs and the session settles.\n\t\t\ttry {\n\t\t\t\tspawn(\"taskkill\", [\"/pid\", String(pid), \"/T\", \"/F\"], { stdio: \"ignore\", windowsHide: true });\n\t\t\t\treturn { ok: true, note: `Terminated child_process pipe fallback process tree (pid ${pid}).` };\n\t\t\t} catch {\n\t\t\t\t// Fall through to the direct kill if taskkill is unavailable.\n\t\t\t}\n\t\t}\n\t\tif (terminateChildTree(this.child, signal) === \"group\") {\n\t\t\treturn { ok: true, note: `Sent ${signal} to child_process pipe fallback process group (pgid ${pid}).` };\n\t\t}\n\t\treturn { ok: true, note: `Sent ${signal} to child_process pipe fallback session.` };\n\t}\n\n\twaitExit(): Promise<PipeFallbackSessionExit> {\n\t\treturn this.exitPromise;\n\t}\n\n\tprivate emitData(chunk: Buffer): void {\n\t\tfor (const handler of this.dataHandlers) handler(chunk);\n\t}\n\n\tprivate settleExit(exit: PipeFallbackSessionExit): void {\n\t\tif (this.exitResult !== null) return;\n\t\tif (this.timeoutHandle) clearTimeout(this.timeoutHandle);\n\t\tthis.exitResult = exit;\n\t\tthis.resolveExit?.(exit);\n\t\tfor (const handler of this.exitHandlers) handler(exit);\n\t\tthis.exitHandlers.clear();\n\t}\n}\n\nexport function createPipeFallbackSession(options: PipeFallbackSessionOptions): PipeFallbackSession {\n\treturn new PipeFallbackSession(options).start();\n}\n"]}
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@earendil-works/pi-pty",
3
3
  "private": true,
4
- "version": "2026.8.6",
4
+ "version": "2026.8.9-2",
5
5
  "description": "Typed PTY session loader for Senpi persistent terminals",
6
6
  "type": "module",
7
7
  "main": "./dist/index.js",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@earendil-works/pi-tui",
3
3
  "private": true,
4
- "version": "2026.8.6",
4
+ "version": "2026.8.9-2",
5
5
  "description": "Terminal User Interface library with differential rendering for efficient text-based applications",
6
6
  "type": "module",
7
7
  "main": "dist/index.js",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@code-yeongyu/senpi",
3
- "version": "2026.8.6",
3
+ "version": "2026.8.9-2",
4
4
  "description": "Coding agent CLI with read, bash, edit, write tools and session management",
5
5
  "type": "module",
6
6
  "piConfig": {
@@ -48,11 +48,11 @@
48
48
  "dependencies": {
49
49
  "@anthropic-ai/sdk": "0.91.1",
50
50
  "@aws-sdk/client-bedrock-runtime": "3.1095.0",
51
- "@code-yeongyu/senpi-codemode": "2026.8.6",
52
- "@earendil-works/pi-agent-core": "npm:@code-yeongyu/senpi-agent-core@2026.8.6",
53
- "@earendil-works/pi-ai": "npm:@code-yeongyu/senpi-ai@2026.8.6",
54
- "@earendil-works/pi-pty": "npm:@code-yeongyu/senpi-pty@2026.8.6",
55
- "@earendil-works/pi-tui": "npm:@code-yeongyu/senpi-tui@2026.8.6",
51
+ "@code-yeongyu/senpi-codemode": "2026.8.9-2",
52
+ "@earendil-works/pi-agent-core": "npm:@code-yeongyu/senpi-agent-core@2026.8.9-2",
53
+ "@earendil-works/pi-ai": "npm:@code-yeongyu/senpi-ai@2026.8.9-2",
54
+ "@earendil-works/pi-pty": "npm:@code-yeongyu/senpi-pty@2026.8.9-2",
55
+ "@earendil-works/pi-tui": "npm:@code-yeongyu/senpi-tui@2026.8.9-2",
56
56
  "@mistralai/mistralai": "2.5.0",
57
57
  "@modelcontextprotocol/sdk": "1.30.0",
58
58
  "@mozilla/readability": "0.6.0",