saeeol 1.1.1 → 1.2.1

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 (379) hide show
  1. package/package.json +14 -14
  2. package/script/build.ts +1 -1
  3. package/src/addons/addon-analytics.ts +1 -1
  4. package/src/cli/cmd/tui/routes/session/suggest.tsx +1 -1
  5. package/src/cli/logo.ts +1 -1
  6. package/src/cli/ui.ts +1 -1
  7. package/src/config/config-loader.ts +1 -1
  8. package/src/config/config-schema.ts +1 -1
  9. package/src/config/config.ts +1 -1
  10. package/src/config/markdown.ts +1 -1
  11. package/src/index.ts +2 -2
  12. package/src/lsp/lsp.ts +1 -1
  13. package/src/lsp/server-web.ts +1 -1
  14. package/src/mcp/oauth-callback.ts +1 -1
  15. package/src/{saeeol → overlay}/encoding.ts +1 -1
  16. package/src/{saeeol → overlay}/text-stream.ts +1 -1
  17. package/src/{saeeol → overlay}/tool/encoded-io.ts +1 -1
  18. package/src/patch/patch-apply.ts +1 -1
  19. package/src/patch/patch-parse.ts +1 -1
  20. package/src/session/compaction-helpers.ts +1 -169
  21. package/src/session/compaction.ts +1 -712
  22. package/src/session/core/compaction/compaction-helpers.ts +169 -0
  23. package/src/session/core/compaction/compaction.ts +712 -0
  24. package/src/session/core/compaction/overflow.ts +28 -0
  25. package/src/session/core/instruction.ts +234 -0
  26. package/src/session/core/llm.ts +504 -0
  27. package/src/session/core/network.ts +392 -0
  28. package/src/session/core/processor.ts +731 -0
  29. package/src/session/core/projectors.ts +139 -0
  30. package/src/session/core/resolve-tools.ts +241 -0
  31. package/src/session/core/retry.ts +149 -0
  32. package/src/session/core/revert.ts +173 -0
  33. package/src/session/core/run-state.ts +110 -0
  34. package/src/session/core/schema.ts +35 -0
  35. package/src/session/core/session-types.ts +160 -0
  36. package/src/session/core/session.sql.ts +124 -0
  37. package/src/session/core/session.ts +948 -0
  38. package/src/session/core/shell-exec.ts +205 -0
  39. package/src/session/core/status.ts +100 -0
  40. package/src/session/core/subtask.ts +268 -0
  41. package/src/session/core/summary.ts +173 -0
  42. package/src/session/core/system.ts +114 -0
  43. package/src/session/core/todo.ts +86 -0
  44. package/src/session/core/user-part.ts +293 -0
  45. package/src/session/instruction.ts +1 -234
  46. package/src/session/llm.ts +1 -504
  47. package/src/session/message/message-errors.ts +83 -0
  48. package/src/session/message/message-parts.ts +89 -0
  49. package/src/session/message/message-query.ts +107 -0
  50. package/src/session/message/message-transform.ts +156 -0
  51. package/src/session/message/message-types.ts +68 -0
  52. package/src/session/message/message-v2.ts +73 -0
  53. package/src/session/message/message.ts +192 -0
  54. package/src/session/message-errors.ts +1 -83
  55. package/src/session/message-parts.ts +1 -89
  56. package/src/session/message-query.ts +1 -107
  57. package/src/session/message-transform.ts +1 -156
  58. package/src/session/message-types.ts +1 -68
  59. package/src/session/message-v2.ts +1 -73
  60. package/src/session/message.ts +1 -192
  61. package/src/session/network.ts +1 -392
  62. package/src/session/overflow.ts +1 -28
  63. package/src/session/processor.ts +1 -731
  64. package/src/session/projectors.ts +2 -139
  65. package/src/session/prompt/prompt-command.ts +93 -0
  66. package/src/session/prompt/prompt-loop.ts +299 -0
  67. package/src/session/prompt/prompt-model.ts +44 -0
  68. package/src/session/prompt/prompt-reminders.ts +120 -0
  69. package/src/session/prompt/prompt-resolve.ts +42 -0
  70. package/src/session/prompt/prompt-schemas.ts +128 -0
  71. package/src/session/prompt/prompt-title.ts +55 -0
  72. package/src/session/prompt/prompt-types.ts +47 -0
  73. package/src/session/prompt/prompt-user-msg.ts +80 -0
  74. package/src/session/prompt/prompt.ts +211 -0
  75. package/src/session/prompt-command.ts +1 -93
  76. package/src/session/prompt-loop.ts +1 -299
  77. package/src/session/prompt-model.ts +1 -44
  78. package/src/session/prompt-reminders.ts +1 -120
  79. package/src/session/prompt-resolve.ts +1 -42
  80. package/src/session/prompt-schemas.ts +1 -128
  81. package/src/session/prompt-title.ts +1 -55
  82. package/src/session/prompt-types.ts +1 -47
  83. package/src/session/prompt-user-msg.ts +1 -80
  84. package/src/session/prompt.ts +1 -211
  85. package/src/session/resolve-tools.ts +1 -241
  86. package/src/session/retry.ts +1 -149
  87. package/src/session/revert.ts +1 -173
  88. package/src/session/run-state.ts +1 -110
  89. package/src/session/schema.ts +1 -35
  90. package/src/session/session-types.ts +1 -160
  91. package/src/session/session.sql.ts +1 -124
  92. package/src/session/session.ts +1 -948
  93. package/src/session/shell-exec.ts +1 -205
  94. package/src/session/status.ts +1 -100
  95. package/src/session/subtask.ts +1 -268
  96. package/src/session/summary.ts +1 -173
  97. package/src/session/system.ts +1 -114
  98. package/src/session/todo.ts +1 -86
  99. package/src/session/user-part.ts +1 -293
  100. package/src/skill/index.ts +1 -1
  101. package/src/suggestion/index.ts +1 -1
  102. package/src/tool/apply_patch.ts +2 -2
  103. package/src/tool/edit.ts +2 -2
  104. package/src/tool/read.ts +2 -2
  105. package/src/tool/recall.ts +1 -1
  106. package/src/tool/registry.ts +2 -2
  107. package/src/tool/suggest.ts +1 -1
  108. package/src/tool/task.ts +3 -3
  109. package/src/tool/todo.ts +1 -1
  110. package/src/tool/write.ts +2 -2
  111. package/test/lsp/index.test.ts +1 -1
  112. package/test/saeeol/agent-manager-tool.test.ts +1 -1
  113. package/test/saeeol/ask-agent-permissions.test.ts +1 -1
  114. package/test/saeeol/bash-hierarchy.test.ts +1 -1
  115. package/test/saeeol/builtin-skills.test.ts +1 -1
  116. package/test/saeeol/cli/dev-setup.test.ts +1 -1
  117. package/test/saeeol/cli/roll-call.test.ts +1 -1
  118. package/test/saeeol/cli-run-auto-helper.test.ts +1 -1
  119. package/test/saeeol/codex-auth-refresh.test.ts +1 -1
  120. package/test/saeeol/commit-message/generate.test.ts +1 -1
  121. package/test/saeeol/commit-message/git-context.test.ts +1 -1
  122. package/test/saeeol/commit-message-windows.test.ts +1 -1
  123. package/test/saeeol/compaction-payload-recovery.test.ts +1 -1
  124. package/test/saeeol/config/config.test.ts +1 -1
  125. package/test/saeeol/config-injector.test.ts +1 -1
  126. package/test/saeeol/config-validation.test.ts +1 -1
  127. package/test/saeeol/cost-propagation.test.ts +1 -1
  128. package/test/saeeol/custom-provider-delete.test.ts +1 -1
  129. package/test/saeeol/diff-full.test.ts +1 -1
  130. package/test/saeeol/encoding.test.ts +1 -1
  131. package/test/saeeol/enhance-prompt.test.ts +1 -1
  132. package/test/saeeol/ensure-plan-dir.test.ts +1 -1
  133. package/test/saeeol/errors.test.ts +1 -1
  134. package/test/saeeol/help.test.ts +3 -3
  135. package/test/saeeol/ignore-migrator.test.ts +1 -1
  136. package/test/saeeol/indexing-auth.test.ts +1 -1
  137. package/test/saeeol/indexing-feature.test.ts +1 -1
  138. package/test/saeeol/indexing-label.test.ts +1 -1
  139. package/test/saeeol/indexing-startup.test.ts +1 -1
  140. package/test/saeeol/indexing-worktree.test.ts +1 -1
  141. package/test/saeeol/lancedb-runtime.test.ts +9 -9
  142. package/test/saeeol/logo.test.ts +1 -1
  143. package/test/saeeol/lsp-typescript-lightweight.test.ts +2 -2
  144. package/test/saeeol/mcp-migrator.test.ts +1 -1
  145. package/test/saeeol/model-info-panel-utils.test.ts +1 -1
  146. package/test/saeeol/modes-migrator.test.ts +1 -1
  147. package/test/saeeol/paths.test.ts +1 -1
  148. package/test/saeeol/permission/config-paths.test.ts +2 -2
  149. package/test/saeeol/permission/external-directory-allow.test.ts +1 -1
  150. package/test/saeeol/plan-exit-detection.test.ts +1 -1
  151. package/test/saeeol/plan-followup.test.ts +2 -2
  152. package/test/saeeol/project-id.test.ts +1 -1
  153. package/test/saeeol/question-dismiss-all.test.ts +1 -1
  154. package/test/saeeol/rules-migrator.test.ts +1 -1
  155. package/test/saeeol/semantic-search.test.ts +2 -2
  156. package/test/saeeol/session/platform-attribution.test.ts +1 -1
  157. package/test/saeeol/session-compaction-cap.test.ts +2 -2
  158. package/test/saeeol/session-compaction-chunks.test.ts +1 -1
  159. package/test/saeeol/session-compaction-safety.test.ts +1 -1
  160. package/test/saeeol/session-import-service.test.ts +1 -1
  161. package/test/saeeol/session-processor-empty-tool-calls.test.ts +1 -1
  162. package/test/saeeol/session-processor-review-telemetry.test.ts +1 -1
  163. package/test/saeeol/session-prompt-queue.test.ts +1 -1
  164. package/test/saeeol/sessions/remote-sender.test.ts +1 -1
  165. package/test/saeeol/snapshot-track-timeout.test.ts +1 -1
  166. package/test/saeeol/suggestion/auto-dismiss.test.ts +2 -2
  167. package/test/saeeol/suggestion/suggestion.test.ts +1 -1
  168. package/test/saeeol/suggestion/tool.test.ts +2 -2
  169. package/test/saeeol/system-prompt.test.ts +1 -1
  170. package/test/saeeol/todo-view.test.ts +1 -1
  171. package/test/saeeol/tool-registry-indexing.test.ts +3 -3
  172. package/test/saeeol/tui-diff.test.ts +1 -1
  173. package/test/saeeol/tui-sync.test.ts +1 -1
  174. package/test/saeeol/util/url.test.ts +1 -1
  175. package/test/saeeol/workflows-migrator.test.ts +1 -1
  176. package/test/saeeol/worktree-diff-summary.test.ts +1 -1
  177. package/tsconfig.json +1 -1
  178. /package/src/{saeeol → overlay}/agent/agent-remove.ts +0 -0
  179. /package/src/{saeeol → overlay}/agent/index.ts +0 -0
  180. /package/src/{saeeol → overlay}/agent/patch-agents.ts +0 -0
  181. /package/src/{saeeol → overlay}/agent/permissions.ts +0 -0
  182. /package/src/{saeeol → overlay}/agent-manager/event.ts +0 -0
  183. /package/src/{saeeol → overlay}/bash-hierarchy.ts +0 -0
  184. /package/src/{saeeol → overlay}/bell.ts +0 -0
  185. /package/src/{saeeol → overlay}/bootstrap.ts +0 -0
  186. /package/src/{saeeol → overlay}/claw/autocomplete-popup.tsx +0 -0
  187. /package/src/{saeeol → overlay}/claw/autocomplete-ref.ts +0 -0
  188. /package/src/{saeeol → overlay}/claw/autocomplete-types.ts +0 -0
  189. /package/src/{saeeol → overlay}/claw/autocomplete.tsx +0 -0
  190. /package/src/{saeeol → overlay}/claw/chat-client.ts +0 -0
  191. /package/src/{saeeol → overlay}/claw/chat.tsx +0 -0
  192. /package/src/{saeeol → overlay}/claw/client-events.ts +0 -0
  193. /package/src/{saeeol → overlay}/claw/client-helpers.ts +0 -0
  194. /package/src/{saeeol → overlay}/claw/client.ts +0 -0
  195. /package/src/{saeeol → overlay}/claw/dialog-conversation-list.tsx +0 -0
  196. /package/src/{saeeol → overlay}/claw/event-service-client-core.ts +0 -0
  197. /package/src/{saeeol → overlay}/claw/event-service-client-impl.ts +0 -0
  198. /package/src/{saeeol → overlay}/claw/event-service-client.ts +0 -0
  199. /package/src/{saeeol → overlay}/claw/hooks.ts +0 -0
  200. /package/src/{saeeol → overlay}/claw/sidebar.tsx +0 -0
  201. /package/src/{saeeol → overlay}/claw/types.ts +0 -0
  202. /package/src/{saeeol → overlay}/claw/view.tsx +0 -0
  203. /package/src/{saeeol → overlay}/cli/cmd/roll-call-call.ts +0 -0
  204. /package/src/{saeeol → overlay}/cli/cmd/roll-call-format.ts +0 -0
  205. /package/src/{saeeol → overlay}/cli/cmd/roll-call.ts +0 -0
  206. /package/src/{saeeol → overlay}/cli/cmd/tui/app.tsx +0 -0
  207. /package/src/{saeeol → overlay}/cli/cmd/tui/component/dialog-provider.tsx +0 -0
  208. /package/src/{saeeol → overlay}/cli/cmd/tui/feedback.ts +0 -0
  209. /package/src/{saeeol → overlay}/cli/cmd/tui/util/terminal.ts +0 -0
  210. /package/src/{saeeol → overlay}/cli/dev-setup-utils.ts +0 -0
  211. /package/src/{saeeol → overlay}/cli/dev-setup.ts +0 -0
  212. /package/src/{saeeol → overlay}/cli/heap-snapshot.ts +0 -0
  213. /package/src/{saeeol → overlay}/cli/logo.ts +0 -0
  214. /package/src/{saeeol → overlay}/cli/run-auto.ts +0 -0
  215. /package/src/{saeeol → overlay}/cli/saeeol-logo.ts +0 -0
  216. /package/src/{saeeol → overlay}/cloud-session.ts +0 -0
  217. /package/src/{saeeol → overlay}/commands-index.ts +0 -0
  218. /package/src/{saeeol → overlay}/commands.ts +0 -0
  219. /package/src/{saeeol → overlay}/commands.tsx +0 -0
  220. /package/src/{saeeol → overlay}/commit-message/generate.ts +0 -0
  221. /package/src/{saeeol → overlay}/commit-message/git-context.ts +0 -0
  222. /package/src/{saeeol → overlay}/commit-message/index.ts +0 -0
  223. /package/src/{saeeol → overlay}/commit-message/types.ts +0 -0
  224. /package/src/{saeeol → overlay}/components/dialog-auto-method.tsx +0 -0
  225. /package/src/{saeeol → overlay}/components/dialog-claw-setup.tsx +0 -0
  226. /package/src/{saeeol → overlay}/components/dialog-claw-upgrade.tsx +0 -0
  227. /package/src/{saeeol → overlay}/components/dialog-indexing-helpers.ts +0 -0
  228. /package/src/{saeeol → overlay}/components/dialog-indexing.tsx +0 -0
  229. /package/src/{saeeol → overlay}/components/dialog-notifications.tsx +0 -0
  230. /package/src/{saeeol → overlay}/components/dialog-organization.tsx +0 -0
  231. /package/src/{saeeol → overlay}/components/dialog-profile.tsx +0 -0
  232. /package/src/{saeeol → overlay}/components/dialog-provider-settings.tsx +0 -0
  233. /package/src/{saeeol → overlay}/components/dialog-team-select.tsx +0 -0
  234. /package/src/{saeeol → overlay}/components/dialog-tuning.tsx +0 -0
  235. /package/src/{saeeol → overlay}/components/dialog-vector-store.tsx +0 -0
  236. /package/src/{saeeol → overlay}/components/error-display.tsx +0 -0
  237. /package/src/{saeeol → overlay}/components/model-info-panel-utils.ts +0 -0
  238. /package/src/{saeeol → overlay}/components/model-info-panel.tsx +0 -0
  239. /package/src/{saeeol → overlay}/components/news.tsx +0 -0
  240. /package/src/{saeeol → overlay}/components/notification-banner.tsx +0 -0
  241. /package/src/{saeeol → overlay}/components/session-indexing.tsx +0 -0
  242. /package/src/{saeeol → overlay}/components/tips.tsx +0 -0
  243. /package/src/{saeeol → overlay}/config/config-core.ts +0 -0
  244. /package/src/{saeeol → overlay}/config/config-helpers.ts +0 -0
  245. /package/src/{saeeol → overlay}/config/config-legacy.ts +0 -0
  246. /package/src/{saeeol → overlay}/config/config.ts +0 -0
  247. /package/src/{saeeol → overlay}/config/default-plugins.ts +0 -0
  248. /package/src/{saeeol → overlay}/config/markdown.ts +0 -0
  249. /package/src/{saeeol → overlay}/config-injector.ts +0 -0
  250. /package/src/{saeeol → overlay}/config-validation.ts +0 -0
  251. /package/src/{saeeol → overlay}/const.ts +0 -0
  252. /package/src/{saeeol → overlay}/cost-tracker/format.ts +0 -0
  253. /package/src/{saeeol → overlay}/cost-tracker/index.ts +0 -0
  254. /package/src/{saeeol → overlay}/cost-tracker/state.ts +0 -0
  255. /package/src/{saeeol → overlay}/cost-tracker/types.ts +0 -0
  256. /package/src/{saeeol → overlay}/docs/migration.md +0 -0
  257. /package/src/{saeeol → overlay}/docs/rules-migration.md +0 -0
  258. /package/src/{saeeol → overlay}/editor-context.ts +0 -0
  259. /package/src/{saeeol → overlay}/enhance-prompt.ts +0 -0
  260. /package/src/{saeeol → overlay}/errors.ts +0 -0
  261. /package/src/{saeeol → overlay}/generate-cli-docs.ts +0 -0
  262. /package/src/{saeeol → overlay}/help-command.ts +0 -0
  263. /package/src/{saeeol → overlay}/help.ts +0 -0
  264. /package/src/{saeeol → overlay}/i18n/index.ts +0 -0
  265. /package/src/{saeeol → overlay}/ignore-migrator.ts +0 -0
  266. /package/src/{saeeol → overlay}/index.ts +0 -0
  267. /package/src/{saeeol → overlay}/indexing-auth.ts +0 -0
  268. /package/src/{saeeol → overlay}/indexing-feature.ts +0 -0
  269. /package/src/{saeeol → overlay}/indexing-helpers.ts +0 -0
  270. /package/src/{saeeol → overlay}/indexing-label.ts +0 -0
  271. /package/src/{saeeol → overlay}/indexing-state.ts +0 -0
  272. /package/src/{saeeol → overlay}/indexing-types.ts +0 -0
  273. /package/src/{saeeol → overlay}/indexing.ts +0 -0
  274. /package/src/{saeeol → overlay}/lancedb.ts +0 -0
  275. /package/src/{saeeol → overlay}/mcp-migrator.ts +0 -0
  276. /package/src/{saeeol → overlay}/mcp-oauth-callback.ts +0 -0
  277. /package/src/{saeeol → overlay}/memory/age.ts +0 -0
  278. /package/src/{saeeol → overlay}/memory/index.ts +0 -0
  279. /package/src/{saeeol → overlay}/memory/paths.ts +0 -0
  280. /package/src/{saeeol → overlay}/memory/scan.ts +0 -0
  281. /package/src/{saeeol → overlay}/memory/types.ts +0 -0
  282. /package/src/{saeeol → overlay}/model-match.ts +0 -0
  283. /package/src/{saeeol → overlay}/modes-migrator.ts +0 -0
  284. /package/src/{saeeol → overlay}/paths.ts +0 -0
  285. /package/src/{saeeol → overlay}/permission/config-paths.ts +0 -0
  286. /package/src/{saeeol → overlay}/permission/drain.ts +0 -0
  287. /package/src/{saeeol → overlay}/permission/external-directory.ts +0 -0
  288. /package/src/{saeeol → overlay}/permission/read.ts +0 -0
  289. /package/src/{saeeol → overlay}/permission/routes.ts +0 -0
  290. /package/src/{saeeol → overlay}/permission/rule.ts +0 -0
  291. /package/src/{saeeol → overlay}/plan-followup-handover.ts +0 -0
  292. /package/src/{saeeol → overlay}/plan-followup-runtime.ts +0 -0
  293. /package/src/{saeeol → overlay}/plan-followup-session.ts +0 -0
  294. /package/src/{saeeol → overlay}/plan-followup.ts +0 -0
  295. /package/src/{saeeol → overlay}/plugins/home-footer.tsx +0 -0
  296. /package/src/{saeeol → overlay}/plugins/home-news.tsx +0 -0
  297. /package/src/{saeeol → overlay}/plugins/home-onboarding.tsx +0 -0
  298. /package/src/{saeeol → overlay}/plugins/sidebar-footer.tsx +0 -0
  299. /package/src/{saeeol → overlay}/plugins/sidebar-pr.tsx +0 -0
  300. /package/src/{saeeol → overlay}/plugins/sidebar-usage.tsx +0 -0
  301. /package/src/{saeeol → overlay}/project-id.ts +0 -0
  302. /package/src/{saeeol → overlay}/provider/codex-refresh.ts +0 -0
  303. /package/src/{saeeol → overlay}/provider/provider.ts +0 -0
  304. /package/src/{saeeol → overlay}/provider-options.ts +0 -0
  305. /package/src/{saeeol → overlay}/question/index.ts +0 -0
  306. /package/src/{saeeol → overlay}/remote-tui.tsx +0 -0
  307. /package/src/{saeeol → overlay}/review/command.ts +0 -0
  308. /package/src/{saeeol → overlay}/review/diff.ts +0 -0
  309. /package/src/{saeeol → overlay}/review/prompt.ts +0 -0
  310. /package/src/{saeeol → overlay}/review/review.ts +0 -0
  311. /package/src/{saeeol → overlay}/review/types.ts +0 -0
  312. /package/src/{saeeol → overlay}/review/worktree-diff.ts +0 -0
  313. /package/src/{saeeol → overlay}/rules-migrator.ts +0 -0
  314. /package/src/{saeeol → overlay}/server/instance.ts +0 -0
  315. /package/src/{saeeol → overlay}/server/router.ts +0 -0
  316. /package/src/{saeeol → overlay}/server/routes/commit-message.ts +0 -0
  317. /package/src/{saeeol → overlay}/server/routes/indexing.ts +0 -0
  318. /package/src/{saeeol → overlay}/server/server.ts +0 -0
  319. /package/src/{saeeol → overlay}/session/compaction-chunks-core.ts +0 -0
  320. /package/src/{saeeol → overlay}/session/compaction-chunks-utils.ts +0 -0
  321. /package/src/{saeeol → overlay}/session/compaction-chunks.ts +0 -0
  322. /package/src/{saeeol → overlay}/session/compaction-payload-recovery.ts +0 -0
  323. /package/src/{saeeol → overlay}/session/cost-propagation.ts +0 -0
  324. /package/src/{saeeol → overlay}/session/digest-storage.ts +0 -0
  325. /package/src/{saeeol → overlay}/session/fork.ts +0 -0
  326. /package/src/{saeeol → overlay}/session/index.ts +0 -0
  327. /package/src/{saeeol → overlay}/session/instruction.ts +0 -0
  328. /package/src/{saeeol → overlay}/session/kg-compaction.ts +0 -0
  329. /package/src/{saeeol → overlay}/session/llm.ts +0 -0
  330. /package/src/{saeeol → overlay}/session/overflow.ts +0 -0
  331. /package/src/{saeeol → overlay}/session/platform.ts +0 -0
  332. /package/src/{saeeol → overlay}/session/processor.ts +0 -0
  333. /package/src/{saeeol → overlay}/session/prompt-context.ts +0 -0
  334. /package/src/{saeeol → overlay}/session/prompt-plan.ts +0 -0
  335. /package/src/{saeeol → overlay}/session/prompt-queue.ts +0 -0
  336. /package/src/{saeeol → overlay}/session/prompt.ts +0 -0
  337. /package/src/{saeeol → overlay}/session/queries.ts +0 -0
  338. /package/src/{saeeol → overlay}/session/tui-sync.ts +0 -0
  339. /package/src/{saeeol → overlay}/session-import/routes.ts +0 -0
  340. /package/src/{saeeol → overlay}/session-import/service.ts +0 -0
  341. /package/src/{saeeol → overlay}/session-import/types.ts +0 -0
  342. /package/src/{saeeol → overlay}/skills/builtin.ts +0 -0
  343. /package/src/{saeeol → overlay}/skills/config.md +0 -0
  344. /package/src/{saeeol → overlay}/snapshot/diff-full.ts +0 -0
  345. /package/src/{saeeol → overlay}/snapshot/index.ts +0 -0
  346. /package/src/{saeeol → overlay}/snapshot/track-hooks.ts +0 -0
  347. /package/src/{saeeol → overlay}/snapshot/track-types.ts +0 -0
  348. /package/src/{saeeol → overlay}/snapshot/track.ts +0 -0
  349. /package/src/{saeeol → overlay}/soul.txt +0 -0
  350. /package/src/{saeeol → overlay}/suggestion/index.ts +0 -0
  351. /package/src/{saeeol → overlay}/suggestion/routes.ts +0 -0
  352. /package/src/{saeeol → overlay}/suggestion/tool.ts +0 -0
  353. /package/src/{saeeol → overlay}/suggestion/tool.txt +0 -0
  354. /package/src/{saeeol → overlay}/suggestion/tui/bar.tsx +0 -0
  355. /package/src/{saeeol → overlay}/suggestion/tui/prompt.tsx +0 -0
  356. /package/src/{saeeol → overlay}/suggestion/tui/render.tsx +0 -0
  357. /package/src/{saeeol → overlay}/suggestion/tui/sync.ts +0 -0
  358. /package/src/{saeeol → overlay}/system-prompt.ts +0 -0
  359. /package/src/{saeeol → overlay}/todo-view.ts +0 -0
  360. /package/src/{saeeol → overlay}/tool/agent-manager.ts +0 -0
  361. /package/src/{saeeol → overlay}/tool/agent-manager.txt +0 -0
  362. /package/src/{saeeol → overlay}/tool/bash-security-patterns.ts +0 -0
  363. /package/src/{saeeol → overlay}/tool/bash-security.ts +0 -0
  364. /package/src/{saeeol → overlay}/tool/question.ts +0 -0
  365. /package/src/{saeeol → overlay}/tool/registry.ts +0 -0
  366. /package/src/{saeeol → overlay}/tool/semantic-search.ts +0 -0
  367. /package/src/{saeeol → overlay}/tool/semantic-search.txt +0 -0
  368. /package/src/{saeeol → overlay}/tool/task.ts +0 -0
  369. /package/src/{saeeol → overlay}/ts-check.ts +0 -0
  370. /package/src/{saeeol → overlay}/ts-client.ts +0 -0
  371. /package/src/{saeeol → overlay}/tui/diff.ts +0 -0
  372. /package/src/{saeeol → overlay}/util/url.ts +0 -0
  373. /package/src/{saeeol → overlay}/worker/index.ts +0 -0
  374. /package/src/{saeeol → overlay}/worker/pool.ts +0 -0
  375. /package/src/{saeeol → overlay}/worker/store.ts +0 -0
  376. /package/src/{saeeol → overlay}/worker/types.ts +0 -0
  377. /package/src/{saeeol → overlay}/workflows-migrator.ts +0 -0
  378. /package/src/{saeeol → overlay}/worktree-cleanup.ts +0 -0
  379. /package/src/{saeeol → overlay}/worktree-family.ts +0 -0
@@ -1,211 +1 @@
1
- // @ts-ignore
2
- globalThis.AI_SDK_LOG_WARNINGS = false
3
-
4
- import { Effect, Layer, Scope, Latch, Context } from "effect"
5
- import { ChildProcessSpawner } from "effect/unstable/process"
6
- import { CrossSpawnSpawner } from "@saeeol/core/cross-spawn-spawner"
7
- import { SaeeolSessionPrompt } from "@/saeeol/session/prompt"
8
- import { SaeeolSessionPromptQueue } from "@/saeeol/session/prompt-queue"
9
- import { SaeeolSession } from "@/saeeol/session"
10
- import { SaeeolSessionProcessor } from "@/saeeol/session/processor"
11
- import { Suggestion } from "@/saeeol/suggestion"
12
- import { Question } from "@/question"
13
- import { SessionID, MessageID } from "./schema"
14
- import { MessageV2 } from "./message-v2"
15
- import { makeRuntime } from "@/effect/run-service"
16
- import { InstanceState } from "@/effect/instance-state"
17
- import { EffectBridge } from "@/effect/bridge"
18
- import { SessionRunState } from "./run-state"
19
- import { SessionStatus } from "./status"
20
- import { SessionCompaction } from "./compaction"
21
- import { SessionProcessor } from "./processor"
22
- import { Command } from "../command"
23
- import { Permission } from "@/permission"
24
- import { MCP } from "../mcp"
25
- import { LSP } from "@/lsp/lsp"
26
- import { ToolRegistry } from "@/tool/registry"
27
- import { Truncate } from "@/tool/truncate"
28
- import { Provider } from "@/provider/provider"
29
- import { Config } from "@/config/config"
30
- import { Instruction } from "./instruction"
31
- import { AppFileSystem } from "@saeeol/core/filesystem"
32
- import { Plugin } from "../plugin"
33
- import { Session as SessionMod } from "./session"
34
- import { SessionRevert } from "./revert"
35
- import { SessionSummary } from "./summary"
36
- import { Agent } from "../agent/agent"
37
- import { SystemPrompt } from "./system"
38
- import { LLM } from "./llm"
39
- import { Bus } from "../bus"
40
- import { Service as ResolveToolsService, defaultLayer as resolveToolsLayer } from "./resolve-tools"
41
- import { Service as UserPartService, defaultLayer as userPartLayer } from "./user-part"
42
- import { Service as SubtaskService, defaultLayer as subtaskLayer } from "./subtask"
43
- import { Service as ShellService, defaultLayer as shellLayer } from "./shell-exec"
44
- import { type PromptInput, type ShellInput, type CommandInput, LoopInput } from "./prompt-schemas"
45
- import { type Interface, Service } from "./prompt-types"
46
- import { resolvePromptParts } from "./prompt-resolve"
47
- import { getModel, lastModel, lastAssistant } from "./prompt-model"
48
- import { createUserMessage } from "./prompt-user-msg"
49
- import { ensureTitle } from "./prompt-title"
50
- import { insertReminders } from "./prompt-reminders"
51
- import { commandHandler } from "./prompt-command"
52
- import { createRunLoop } from "./prompt-loop"
53
-
54
- export const shouldAskPlanFollowup = SaeeolSessionPrompt.shouldAskPlanFollowup
55
-
56
- export const layer = Layer.effect(
57
- Service,
58
- Effect.gen(function* () {
59
- const bus = yield* Bus.Service
60
- const status = yield* SessionStatus.Service
61
- const sessions = yield* SessionMod.Service
62
- const agents = yield* Agent.Service
63
- const provider = yield* Provider.Service
64
- const processor = yield* SessionProcessor.Service
65
- const compaction = yield* SessionCompaction.Service
66
- const plugin = yield* Plugin.Service
67
- const commands = yield* Command.Service
68
- const config = yield* Config.Service
69
- const permission = yield* Permission.Service
70
- const fsys = yield* AppFileSystem.Service
71
- const mcp = yield* MCP.Service
72
- const lsp = yield* LSP.Service
73
- const registry = yield* ToolRegistry.Service
74
- const truncate = yield* Truncate.Service
75
- const spawner = yield* ChildProcessSpawner.ChildProcessSpawner
76
- const scope = yield* Scope.Scope
77
- const instruction = yield* Instruction.Service
78
- const state = yield* SessionRunState.Service
79
- const revert = yield* SessionRevert.Service
80
- const summary = yield* SessionSummary.Service
81
- const sys = yield* SystemPrompt.Service
82
- const llm = yield* LLM.Service
83
- const resolveToolsSvc = yield* ResolveToolsService
84
- const userPartSvc = yield* UserPartService
85
- const subtaskSvc = yield* SubtaskService
86
- const shellSvc = yield* ShellService
87
-
88
- const deps = {
89
- bus, status, sessions, agents, provider, processor, compaction, plugin,
90
- commands, config, permission, fsys, mcp, lsp, registry, truncate,
91
- spawner, scope, instruction, state, revert, summary, sys, llm,
92
- resolveToolsSvc, userPartSvc, subtaskSvc, shellSvc,
93
- }
94
-
95
- const resolvePromptPartsFn = resolvePromptParts(deps as any)
96
- const getModelFn = getModel(deps as any)
97
- const lastModelFn = lastModel(deps as any)
98
- const lastAssistantFn = lastAssistant(deps as any)
99
- const createUserMessageFn = createUserMessage(deps as any)
100
- const ensureTitleFn = ensureTitle(deps as any)
101
- const insertRemindersFn = insertReminders(deps as any, SaeeolSessionPrompt)
102
- const commandFn = commandHandler(deps as any, SaeeolSessionProcessor.markReviewTelemetry.bind(SaeeolSessionProcessor))
103
-
104
- const cancel = Effect.fn("SessionPrompt.cancel")(function* (sessionID: SessionID) {
105
- yield* SaeeolSessionPromptQueue.cancel(sessionID)
106
- SaeeolSessionPrompt.abortPlanFollowup(sessionID)
107
- yield* state.cancel(sessionID)
108
- })
109
-
110
- const { runLoop, loop, shell } = createRunLoop(
111
- deps as any,
112
- {
113
- getModel: getModelFn,
114
- lastModel: lastModelFn,
115
- lastAssistant: lastAssistantFn,
116
- createUserMessage: createUserMessageFn,
117
- ensureTitle: ensureTitleFn,
118
- insertReminders: insertRemindersFn,
119
- resolvePromptParts: resolvePromptPartsFn,
120
- commandHandler: commandFn,
121
- SaeeolSessionPrompt,
122
- SaeeolSessionPromptQueue,
123
- SaeeolSession,
124
- SaeeolSessionProcessor,
125
- } as any,
126
- )
127
-
128
- let promptFn: any
129
-
130
- const promptImpl = Effect.fn("SessionPrompt.prompt")(function* (input: PromptInput) {
131
- return yield* promptFn(input)
132
- })
133
-
134
- promptFn = Effect.fn("SessionPrompt.prompt")(function* (input: PromptInput) {
135
- const session = yield* sessions.get(input.sessionID)
136
- yield* revert.cleanup(session)
137
- yield* SaeeolSessionPrompt.recoverDanglingAssistant({ sessionID: input.sessionID, status, sessions })
138
- yield* SaeeolSessionPrompt.recoverProviderFinishError({ sessionID: input.sessionID, status, sessions })
139
- const message = yield* createUserMessageFn(input)
140
- yield* sessions.touch(input.sessionID)
141
- const permissions: Permission.Ruleset = []
142
- for (const [t, enabled] of Object.entries(input.tools ?? {})) {
143
- permissions.push({ permission: t, action: enabled ? "allow" : "deny", pattern: "*" })
144
- }
145
- if (permissions.length > 0) {
146
- session.permission = permissions
147
- yield* sessions.setPermission({ sessionID: session.id, permission: permissions })
148
- }
149
- yield* Effect.promise(() => Suggestion.dismissAll(input.sessionID))
150
- yield* Effect.promise(() => Question.dismissAll(input.sessionID))
151
- if (input.noReply === true) return message
152
- return yield* (SaeeolSessionPromptQueue.enqueue as any)(
153
- input.sessionID, message.info.id,
154
- loop({ sessionID: input.sessionID }),
155
- lastAssistantFn(input.sessionID),
156
- )
157
- })
158
-
159
- return Service.of({
160
- cancel,
161
- prompt: promptFn,
162
- loop: loop as any,
163
- shell: shell as any,
164
- command: commandFn as any,
165
- resolvePromptParts: resolvePromptPartsFn as any,
166
- })
167
- }),
168
- )
169
-
170
- export const defaultLayer = Layer.suspend(() =>
171
- layer.pipe(
172
- Layer.provide(
173
- Layer.mergeAll(
174
- resolveToolsLayer, userPartLayer, subtaskLayer, shellLayer,
175
- SessionRunState.defaultLayer, SessionStatus.defaultLayer,
176
- SessionCompaction.defaultLayer, SessionProcessor.defaultLayer,
177
- Command.defaultLayer, Permission.defaultLayer, MCP.defaultLayer,
178
- LSP.defaultLayer, ToolRegistry.defaultLayer, Truncate.defaultLayer,
179
- Provider.defaultLayer, Config.defaultLayer, Instruction.defaultLayer,
180
- AppFileSystem.defaultLayer, Plugin.defaultLayer, SessionMod.defaultLayer,
181
- SessionRevert.defaultLayer, SessionSummary.defaultLayer, Agent.defaultLayer,
182
- SystemPrompt.defaultLayer, LLM.defaultLayer, Bus.layer,
183
- CrossSpawnSpawner.defaultLayer,
184
- ),
185
- ),
186
- ),
187
- )
188
-
189
- export { Service } from "./prompt-types"
190
- export type { Interface } from "./prompt-types"
191
-
192
- export {
193
- PromptInput,
194
- type PromptInput as PromptInputType,
195
- ShellInput,
196
- type ShellInput as ShellInputType,
197
- CommandInput,
198
- type CommandInput as CommandInputType,
199
- LoopInput,
200
- createStructuredOutputTool,
201
- STRUCTURED_OUTPUT_DESCRIPTION, STRUCTURED_OUTPUT_SYSTEM_PROMPT,
202
- REQUEST_PRUNE_BYTES,
203
- bashRegex, argsRegex, placeholderRegex, quoteTrimRegex,
204
- } from "./prompt-schemas"
205
-
206
- const { runPromise } = makeRuntime(Service, defaultLayer)
207
- export const prompt = (input: PromptInput) => runPromise((svc) => svc.prompt(input))
208
- export const loopExport = (input: LoopInput) => runPromise((svc) => svc.loop(input))
209
- export const cancel = (sessionID: SessionID) => runPromise((svc) => svc.cancel(sessionID))
210
-
211
- export * as SessionPrompt from "./prompt"
1
+ export * from "./prompt/prompt"
@@ -1,241 +1 @@
1
- import { type Tool as AITool, tool, jsonSchema, type ToolExecutionOptions, asSchema } from "ai"
2
- import { Effect, Context, Layer } from "effect"
3
- import * as EffectZod from "@/util/effect-zod"
4
- import { ModelID, ProviderID } from "../provider/schema"
5
- import { SessionID, PartID } from "./schema"
6
- import { MessageV2 } from "./message-v2"
7
- import * as Session from "./session"
8
- import { Agent } from "../agent/agent"
9
- import { Provider } from "@/provider/provider"
10
- import { ProviderTransform } from "@/provider/transform"
11
- import { ToolRegistry } from "@/tool/registry"
12
- import { MCP } from "../mcp"
13
- import { Plugin } from "../plugin"
14
- import { Permission } from "@/permission"
15
- import { Truncate } from "@/tool/truncate"
16
- import { SessionProcessor } from "./processor"
17
- import { SaeeolSessionPrompt } from "@/saeeol/session/prompt"
18
- import { EffectBridge } from "@/effect/bridge"
19
- import { Tool } from "@/tool/tool"
20
- import { type TaskPromptOps } from "@/tool/task"
21
- import * as Log from "@saeeol/core/util/log"
22
-
23
- const log = Log.create({ service: "session.resolve-tools" })
24
-
25
- export interface ResolveToolsInput {
26
- agent: Agent.Info
27
- model: Provider.Model
28
- session: Session.Info
29
- tools?: Record<string, boolean>
30
- processor: Pick<SessionProcessor.Handle, "message" | "updateToolCall" | "completeToolCall">
31
- bypassAgentCheck: boolean
32
- messages: MessageV2.WithParts[]
33
- }
34
-
35
- export interface Interface {
36
- readonly resolve: (input: ResolveToolsInput) => Effect.Effect<Record<string, AITool>>
37
- }
38
-
39
- export class Service extends Context.Service<Service, Interface>()("@saeeol/SessionResolveTools") {}
40
-
41
- export const layer = Layer.effect(
42
- Service,
43
- Effect.gen(function* () {
44
- const registry = yield* ToolRegistry.Service
45
- const plugin = yield* Plugin.Service
46
- const permission = yield* Permission.Service
47
- const mcp = yield* MCP.Service
48
- const truncate = yield* Truncate.Service
49
-
50
- const resolve = Effect.fn("SessionResolveTools.resolve")(function* (input: ResolveToolsInput) {
51
- using _ = log.time("resolveTools")
52
- const tools: Record<string, AITool> = {}
53
- const bridge = yield* EffectBridge.make()
54
- const promptOps: TaskPromptOps = {
55
- cancel: (sessionID: SessionID) => Effect.void,
56
- resolvePromptParts: (template: string) => Effect.succeed([{ type: "text" as const, text: template }]) as any,
57
- prompt: (_input: any) => Effect.fail(new Error("not available")) as any,
58
- }
59
-
60
- const context = (args: any, options: ToolExecutionOptions): Tool.Context => ({
61
- sessionID: input.session.id,
62
- abort: options.abortSignal!,
63
- messageID: input.processor.message.id,
64
- callID: options.toolCallId,
65
- extra: { model: input.model, bypassAgentCheck: input.bypassAgentCheck, promptOps },
66
- agent: input.agent.name,
67
- messages: input.messages,
68
- metadata: (val: any) =>
69
- input.processor.updateToolCall(options.toolCallId, (match) => {
70
- if (!["running", "pending"].includes(match.state.status)) return match
71
- return {
72
- ...match,
73
- state: {
74
- title: val.title,
75
- metadata: val.metadata,
76
- status: "running",
77
- input: args,
78
- time: { start: Date.now() },
79
- },
80
- }
81
- }),
82
- ask: (req: any) =>
83
- permission
84
- .ask({
85
- ...req,
86
- sessionID: input.session.id,
87
- tool: { messageID: input.processor.message.id, callID: options.toolCallId },
88
- ruleset: Permission.merge(
89
- input.agent.permission,
90
- SaeeolSessionPrompt.guardPermissions({ agent: input.agent, session: input.session }),
91
- ),
92
- hardRuleset: SaeeolSessionPrompt.hardPermissions({ agent: input.agent }),
93
- })
94
- .pipe(Effect.orDie),
95
- })
96
-
97
- for (const item of yield* registry.tools({
98
- modelID: ModelID.make(input.model.api.id),
99
- providerID: input.model.providerID,
100
- agent: input.agent,
101
- })) {
102
- const schema = ProviderTransform.schema(input.model, EffectZod.toJsonSchema(item.parameters))
103
- tools[item.id] = tool({
104
- description: item.description,
105
- inputSchema: jsonSchema(schema),
106
- execute(args, options) {
107
- return bridge.promise(
108
- Effect.gen(function* () {
109
- const ctx = context(args, options)
110
- yield* plugin.trigger(
111
- "tool.execute.before",
112
- { tool: item.id, sessionID: ctx.sessionID, callID: ctx.callID },
113
- { args },
114
- )
115
- const result = yield* item.execute(args, ctx)
116
- const output = {
117
- ...result,
118
- attachments: result.attachments?.map((attachment) => ({
119
- ...attachment,
120
- id: PartID.ascending(),
121
- sessionID: ctx.sessionID,
122
- messageID: input.processor.message.id,
123
- })),
124
- }
125
- yield* plugin.trigger(
126
- "tool.execute.after",
127
- { tool: item.id, sessionID: ctx.sessionID, callID: ctx.callID, args },
128
- output,
129
- )
130
- if (options.abortSignal?.aborted) {
131
- yield* input.processor.completeToolCall(options.toolCallId, output)
132
- }
133
- return output
134
- }),
135
- )
136
- },
137
- })
138
- }
139
-
140
- for (const [key, item] of Object.entries(yield* mcp.tools())) {
141
- const execute = item.execute
142
- if (!execute) continue
143
- const schema = yield* Effect.promise(() => Promise.resolve(asSchema(item.inputSchema).jsonSchema))
144
- const transformed = ProviderTransform.schema(input.model, schema)
145
- item.inputSchema = jsonSchema(transformed)
146
- item.execute = (args, opts) =>
147
- bridge.promise(
148
- Effect.gen(function* () {
149
- const ctx = context(args, opts)
150
- yield* plugin.trigger(
151
- "tool.execute.before",
152
- { tool: key, sessionID: ctx.sessionID, callID: opts.toolCallId },
153
- { args },
154
- )
155
- const result: Awaited<ReturnType<NonNullable<typeof execute>>> = yield* Effect.gen(function* () {
156
- yield* ctx.ask({ permission: key, metadata: {}, patterns: ["*"], always: ["*"] })
157
- return yield* Effect.promise(() => execute(args, opts))
158
- }).pipe(
159
- Effect.withSpan("Tool.execute", {
160
- attributes: {
161
- "tool.name": key,
162
- "tool.call_id": opts.toolCallId,
163
- "session.id": ctx.sessionID,
164
- "message.id": input.processor.message.id,
165
- },
166
- }),
167
- )
168
- yield* plugin.trigger(
169
- "tool.execute.after",
170
- { tool: key, sessionID: ctx.sessionID, callID: opts.toolCallId, args },
171
- result,
172
- )
173
-
174
- const textParts: string[] = []
175
- const attachments: Omit<MessageV2.FilePart, "id" | "sessionID" | "messageID">[] = []
176
- for (const contentItem of result.content) {
177
- if (contentItem.type === "text") textParts.push(contentItem.text)
178
- else if (contentItem.type === "image") {
179
- attachments.push({
180
- type: "file",
181
- mime: contentItem.mimeType,
182
- url: `data:${contentItem.mimeType};base64,${contentItem.data}`,
183
- })
184
- } else if (contentItem.type === "resource") {
185
- const { resource } = contentItem
186
- if (resource.text) textParts.push(resource.text)
187
- if (resource.blob) {
188
- attachments.push({
189
- type: "file",
190
- mime: resource.mimeType ?? "application/octet-stream",
191
- url: `data:${resource.mimeType ?? "application/octet-stream"};base64,${resource.blob}`,
192
- filename: resource.uri,
193
- })
194
- }
195
- }
196
- }
197
-
198
- const truncated = yield* truncate.output(textParts.join("\n\n"), {}, input.agent)
199
- const metadata = {
200
- ...result.metadata,
201
- truncated: truncated.truncated,
202
- ...(truncated.truncated && { outputPath: truncated.outputPath }),
203
- }
204
- const output = {
205
- title: "",
206
- metadata,
207
- output: truncated.content,
208
- attachments: attachments.map((attachment) => ({
209
- ...attachment,
210
- id: PartID.ascending(),
211
- sessionID: ctx.sessionID,
212
- messageID: input.processor.message.id,
213
- })),
214
- content: result.content,
215
- }
216
- if (opts.abortSignal?.aborted) {
217
- yield* input.processor.completeToolCall(opts.toolCallId, output)
218
- }
219
- return output
220
- }),
221
- )
222
- tools[key] = item
223
- }
224
-
225
- return tools
226
- })
227
-
228
- return { resolve }
229
- }),
230
- )
231
-
232
- export const defaultLayer = Layer.suspend(() =>
233
- layer.pipe(
234
- Layer.provide(ToolRegistry.defaultLayer),
235
- Layer.provide(MCP.defaultLayer),
236
- Layer.provide(Plugin.defaultLayer),
237
- Layer.provide(Permission.defaultLayer),
238
- Layer.provide(Truncate.defaultLayer),
239
- Layer.provide(Provider.defaultLayer),
240
- ),
241
- )
1
+ export * from "./core/resolve-tools"
@@ -1,149 +1 @@
1
- import type { NamedError } from "@saeeol/core/util/error"
2
- import { Cause, Clock, Duration, Effect, Schedule } from "effect"
3
- import { MessageV2 } from "./message-v2"
4
- import { isSaeeolError } from "@/saeeol/errors"
5
- import { SessionNetwork } from "./network"
6
- import { iife } from "@/util/iife"
7
-
8
- export type Err = ReturnType<NamedError["toObject"]>
9
-
10
- // This exported message is shared with the TUI upsell detector. Matching on a
11
- // literal error string kind of sucks, but it is the simplest for now.
12
- export const GO_UPSELL_MESSAGE = "Free usage exceeded, subscribe to Go https://saeeol.ai/go"
13
-
14
- export const RETRY_INITIAL_DELAY = 2000
15
- export const RETRY_BACKOFF_FACTOR = 2
16
- export const RETRY_MAX_DELAY_NO_HEADERS = 30_000 // 30 seconds
17
- export const RETRY_MAX_DELAY = 2_147_483_647 // max 32-bit signed integer for setTimeout
18
-
19
- function cap(ms: number) {
20
- return Math.min(ms, RETRY_MAX_DELAY)
21
- }
22
-
23
- export function delay(attempt: number, error?: MessageV2.APIError) {
24
- if (error) {
25
- const headers = error.data.responseHeaders
26
- if (headers) {
27
- const retryAfterMs = headers["retry-after-ms"]
28
- if (retryAfterMs) {
29
- const parsedMs = Number.parseFloat(retryAfterMs)
30
- if (!Number.isNaN(parsedMs)) {
31
- return cap(parsedMs)
32
- }
33
- }
34
-
35
- const retryAfter = headers["retry-after"]
36
- if (retryAfter) {
37
- const parsedSeconds = Number.parseFloat(retryAfter)
38
- if (!Number.isNaN(parsedSeconds)) {
39
- // convert seconds to milliseconds
40
- return cap(Math.ceil(parsedSeconds * 1000))
41
- }
42
- // Try parsing as HTTP date format
43
- const parsed = Date.parse(retryAfter) - Date.now()
44
- if (!Number.isNaN(parsed) && parsed > 0) {
45
- return cap(Math.ceil(parsed))
46
- }
47
- }
48
-
49
- return cap(RETRY_INITIAL_DELAY * Math.pow(RETRY_BACKOFF_FACTOR, attempt - 1))
50
- }
51
- }
52
-
53
- return cap(Math.min(RETRY_INITIAL_DELAY * Math.pow(RETRY_BACKOFF_FACTOR, attempt - 1), RETRY_MAX_DELAY_NO_HEADERS))
54
- }
55
-
56
- export function retryable(error: Err) {
57
- // context overflow errors should not be retried
58
- if (MessageV2.ContextOverflowError.isInstance(error)) return undefined
59
- if (MessageV2.APIError.isInstance(error)) {
60
- const status = error.data.statusCode
61
- if (isSaeeolError(error)) return undefined
62
-
63
- // 5xx errors are transient server failures and should always be retried,
64
- // even when the provider SDK doesn't explicitly mark them as retryable.
65
- if (!error.data.isRetryable && !(status !== undefined && status >= 500)) return undefined
66
- // capped model is futile and the backoff loop cannot be broken by switching
67
- // models in the chat selector (the retry loop holds a stale model ref).
68
- if (error.data.responseBody?.includes("FreeUsageLimitError")) return undefined
69
- return error.data.message.includes("Overloaded") ? "Provider is overloaded" : error.data.message
70
- }
71
-
72
- // Check for rate limit patterns in plain text error messages
73
- const msg = error.data?.message
74
- if (typeof msg === "string") {
75
- const lower = msg.toLowerCase()
76
- if (
77
- lower.includes("rate increased too quickly") ||
78
- lower.includes("rate limit") ||
79
- lower.includes("too many requests")
80
- ) {
81
- return msg
82
- }
83
- }
84
-
85
- const json = iife(() => {
86
- try {
87
- if (typeof error.data?.message === "string") {
88
- const parsed = JSON.parse(error.data.message)
89
- return parsed
90
- }
91
-
92
- return JSON.parse(error.data.message)
93
- } catch {
94
- return undefined
95
- }
96
- })
97
- if (!json || typeof json !== "object") return undefined
98
- const code = typeof json.code === "string" ? json.code : ""
99
-
100
- if (json.type === "error" && json.error?.type === "too_many_requests") {
101
- return "Too Many Requests"
102
- }
103
- if (code.includes("exhausted") || code.includes("unavailable")) {
104
- return "Provider is overloaded"
105
- }
106
- if (json.type === "error" && typeof json.error?.code === "string" && json.error.code.includes("rate_limit")) {
107
- return "Rate Limited"
108
- }
109
- return undefined
110
- }
111
-
112
- export function policy(opts: {
113
- parse: (error: unknown) => Err
114
- set: (input: { attempt: number; message: string; next: number }) => Effect.Effect<void>
115
- limit?: number
116
- offline?: (input: { error: unknown; message: string }) => Effect.Effect<"retry" | "blocked" | "aborted">
117
- }) {
118
- return Schedule.fromStepWithMetadata(
119
- Effect.succeed((meta: Schedule.InputMetadata<unknown>) => {
120
- if (opts.limit !== undefined && meta.attempt > opts.limit) {
121
- return Cause.done(meta.attempt)
122
- }
123
-
124
- const error = opts.parse(meta.input)
125
- const message = retryable(error)
126
- if (!message) return Cause.done(meta.attempt)
127
- return Effect.gen(function* () {
128
- if (opts.offline && SessionNetwork.disconnected(meta.input)) {
129
- const result = yield* opts.offline({
130
- error: meta.input,
131
- message: SessionNetwork.message(meta.input),
132
- })
133
- if (result !== "retry") {
134
- return yield* Cause.done(meta.attempt)
135
- }
136
- yield* opts.set({ attempt: 0, message: "Reconnected", next: Date.now() })
137
- return [0, Duration.zero] as [number, Duration.Duration]
138
- }
139
-
140
- const wait = delay(meta.attempt, MessageV2.APIError.isInstance(error) ? error : undefined)
141
- const now = yield* Clock.currentTimeMillis
142
- yield* opts.set({ attempt: meta.attempt, message, next: now + wait })
143
- return [meta.attempt, Duration.millis(wait)] as [number, Duration.Duration]
144
- })
145
- }),
146
- )
147
- }
148
-
149
- export * as SessionRetry from "./retry"
1
+ export * from "./core/retry"