@armadra/agent 0.0.0-stage → 0.3.0

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 (433) hide show
  1. package/CHANGELOG.md +37 -0
  2. package/LICENSE +21 -0
  3. package/README.md +470 -2
  4. package/dist/agent/agent.d.ts +56 -0
  5. package/dist/agent/agent.js +129 -0
  6. package/dist/agent/loop.d.ts +51 -0
  7. package/dist/agent/loop.js +158 -0
  8. package/dist/agent/queue.d.ts +25 -0
  9. package/dist/agent/queue.js +55 -0
  10. package/dist/agent/retry.d.ts +22 -0
  11. package/dist/agent/retry.js +92 -0
  12. package/dist/agent/schema.d.ts +27 -0
  13. package/dist/agent/schema.js +186 -0
  14. package/dist/agent/session-cache.d.ts +100 -0
  15. package/dist/agent/session-cache.js +514 -0
  16. package/dist/agent/session-compaction.d.ts +49 -0
  17. package/dist/agent/session-compaction.js +251 -0
  18. package/dist/agent/session-core.d.ts +103 -0
  19. package/dist/agent/session-core.js +7 -0
  20. package/dist/agent/session-run.d.ts +55 -0
  21. package/dist/agent/session-run.js +246 -0
  22. package/dist/agent/session-state.d.ts +39 -0
  23. package/dist/agent/session-state.js +119 -0
  24. package/dist/agent/session-subagent.d.ts +54 -0
  25. package/dist/agent/session-subagent.js +157 -0
  26. package/dist/agent/session-sync.d.ts +20 -0
  27. package/dist/agent/session-sync.js +111 -0
  28. package/dist/agent/session-tools.d.ts +24 -0
  29. package/dist/agent/session-tools.js +277 -0
  30. package/dist/agent/session.d.ts +117 -0
  31. package/dist/agent/session.js +485 -0
  32. package/dist/agent/system-prompt.d.ts +49 -0
  33. package/dist/agent/system-prompt.js +121 -0
  34. package/dist/agent/tool-runner.d.ts +64 -0
  35. package/dist/agent/tool-runner.js +309 -0
  36. package/dist/agent/transform.d.ts +26 -0
  37. package/dist/agent/transform.js +171 -0
  38. package/dist/agent/types.d.ts +378 -0
  39. package/dist/agent/types.js +21 -0
  40. package/dist/ai/apis/anthropic-messages.d.ts +26 -0
  41. package/dist/ai/apis/anthropic-messages.js +214 -0
  42. package/dist/ai/apis/anthropic-request.d.ts +42 -0
  43. package/dist/ai/apis/anthropic-request.js +282 -0
  44. package/dist/ai/apis/api.d.ts +28 -0
  45. package/dist/ai/apis/api.js +102 -0
  46. package/dist/ai/apis/cache-params.d.ts +48 -0
  47. package/dist/ai/apis/cache-params.js +163 -0
  48. package/dist/ai/apis/google-generative-ai.d.ts +32 -0
  49. package/dist/ai/apis/google-generative-ai.js +249 -0
  50. package/dist/ai/apis/google-request.d.ts +40 -0
  51. package/dist/ai/apis/google-request.js +255 -0
  52. package/dist/ai/apis/openai-compat.d.ts +35 -0
  53. package/dist/ai/apis/openai-compat.js +142 -0
  54. package/dist/ai/apis/openai-completions.d.ts +28 -0
  55. package/dist/ai/apis/openai-completions.js +246 -0
  56. package/dist/ai/apis/openai-request.d.ts +35 -0
  57. package/dist/ai/apis/openai-request.js +303 -0
  58. package/dist/ai/apis/openai-responses-request.d.ts +52 -0
  59. package/dist/ai/apis/openai-responses-request.js +266 -0
  60. package/dist/ai/apis/openai-responses.d.ts +28 -0
  61. package/dist/ai/apis/openai-responses.js +304 -0
  62. package/dist/ai/apis/shared.d.ts +56 -0
  63. package/dist/ai/apis/shared.js +179 -0
  64. package/dist/ai/cache/economics.d.ts +24 -0
  65. package/dist/ai/cache/economics.js +69 -0
  66. package/dist/ai/cache/fingerprint.d.ts +17 -0
  67. package/dist/ai/cache/fingerprint.js +39 -0
  68. package/dist/ai/cache/miss.d.ts +49 -0
  69. package/dist/ai/cache/miss.js +96 -0
  70. package/dist/ai/cache/reporting.d.ts +39 -0
  71. package/dist/ai/cache/reporting.js +103 -0
  72. package/dist/ai/cache/types.d.ts +94 -0
  73. package/dist/ai/cache/types.js +19 -0
  74. package/dist/ai/cache/warmer.d.ts +94 -0
  75. package/dist/ai/cache/warmer.js +224 -0
  76. package/dist/ai/context.d.ts +35 -0
  77. package/dist/ai/context.js +114 -0
  78. package/dist/ai/cost.d.ts +21 -0
  79. package/dist/ai/cost.js +60 -0
  80. package/dist/ai/event-stream.d.ts +33 -0
  81. package/dist/ai/event-stream.js +101 -0
  82. package/dist/ai/fake/fake-provider.d.ts +68 -0
  83. package/dist/ai/fake/fake-provider.js +278 -0
  84. package/dist/ai/fake/fake-script.d.ts +69 -0
  85. package/dist/ai/fake/fake-script.js +142 -0
  86. package/dist/ai/http.d.ts +54 -0
  87. package/dist/ai/http.js +212 -0
  88. package/dist/ai/json-partial.d.ts +17 -0
  89. package/dist/ai/json-partial.js +243 -0
  90. package/dist/ai/overflow.d.ts +22 -0
  91. package/dist/ai/overflow.js +61 -0
  92. package/dist/ai/providers/auth.d.ts +71 -0
  93. package/dist/ai/providers/auth.js +202 -0
  94. package/dist/ai/providers/builtin.d.ts +23 -0
  95. package/dist/ai/providers/builtin.js +148 -0
  96. package/dist/ai/providers/catalog-data.d.ts +5 -0
  97. package/dist/ai/providers/catalog-data.js +19 -0
  98. package/dist/ai/providers/catalog.d.ts +28 -0
  99. package/dist/ai/providers/catalog.js +166 -0
  100. package/dist/ai/providers/channels.d.ts +51 -0
  101. package/dist/ai/providers/channels.js +96 -0
  102. package/dist/ai/providers/enrich.d.ts +34 -0
  103. package/dist/ai/providers/enrich.js +86 -0
  104. package/dist/ai/providers/models-dev-cache.d.ts +53 -0
  105. package/dist/ai/providers/models-dev-cache.js +147 -0
  106. package/dist/ai/providers/models-dev.d.ts +99 -0
  107. package/dist/ai/providers/models-dev.js +315 -0
  108. package/dist/ai/providers/registry.d.ts +114 -0
  109. package/dist/ai/providers/registry.js +458 -0
  110. package/dist/ai/sse.d.ts +32 -0
  111. package/dist/ai/sse.js +140 -0
  112. package/dist/ai/thinking.d.ts +42 -0
  113. package/dist/ai/thinking.js +101 -0
  114. package/dist/ai/types.d.ts +448 -0
  115. package/dist/ai/types.js +19 -0
  116. package/dist/bundle/ama-sandbox.cjs +324 -0
  117. package/dist/bundle/ama.cjs +27837 -0
  118. package/dist/bundle.d.ts +9 -0
  119. package/dist/bundle.js +15 -0
  120. package/dist/cli/args.d.ts +85 -0
  121. package/dist/cli/args.js +408 -0
  122. package/dist/cli/bootstrap.d.ts +18 -0
  123. package/dist/cli/bootstrap.js +399 -0
  124. package/dist/cli/compose-providers.d.ts +37 -0
  125. package/dist/cli/compose-providers.js +107 -0
  126. package/dist/cli/compose-session.d.ts +72 -0
  127. package/dist/cli/compose-session.js +370 -0
  128. package/dist/cli/compose-store.d.ts +24 -0
  129. package/dist/cli/compose-store.js +125 -0
  130. package/dist/cli/compose.d.ts +108 -0
  131. package/dist/cli/compose.js +221 -0
  132. package/dist/cli/default-model.d.ts +16 -0
  133. package/dist/cli/default-model.js +24 -0
  134. package/dist/cli/deps.d.ts +207 -0
  135. package/dist/cli/deps.js +12 -0
  136. package/dist/cli/exit-codes.d.ts +29 -0
  137. package/dist/cli/exit-codes.js +40 -0
  138. package/dist/cli/main.d.ts +27 -0
  139. package/dist/cli/main.js +177 -0
  140. package/dist/cli/runtime.d.ts +90 -0
  141. package/dist/cli/runtime.js +8 -0
  142. package/dist/cli/startup-screen.d.ts +15 -0
  143. package/dist/cli/startup-screen.js +56 -0
  144. package/dist/cli/startup-steps.d.ts +35 -0
  145. package/dist/cli/startup-steps.js +202 -0
  146. package/dist/cli/subcommands/auth.d.ts +12 -0
  147. package/dist/cli/subcommands/auth.js +91 -0
  148. package/dist/cli/subcommands/config.d.ts +53 -0
  149. package/dist/cli/subcommands/config.js +277 -0
  150. package/dist/cli/subcommands/context.d.ts +21 -0
  151. package/dist/cli/subcommands/context.js +42 -0
  152. package/dist/cli/subcommands/doctor.d.ts +11 -0
  153. package/dist/cli/subcommands/doctor.js +246 -0
  154. package/dist/cli/subcommands/init.d.ts +6 -0
  155. package/dist/cli/subcommands/init.js +22 -0
  156. package/dist/cli/subcommands/model-meta.d.ts +16 -0
  157. package/dist/cli/subcommands/model-meta.js +54 -0
  158. package/dist/cli/subcommands/models-cache-probe.d.ts +34 -0
  159. package/dist/cli/subcommands/models-cache-probe.js +190 -0
  160. package/dist/cli/subcommands/models-discover.d.ts +46 -0
  161. package/dist/cli/subcommands/models-discover.js +232 -0
  162. package/dist/cli/subcommands/models.d.ts +40 -0
  163. package/dist/cli/subcommands/models.js +152 -0
  164. package/dist/cli/subcommands/providers-list.d.ts +8 -0
  165. package/dist/cli/subcommands/providers-list.js +97 -0
  166. package/dist/cli/subcommands/providers-plan.d.ts +79 -0
  167. package/dist/cli/subcommands/providers-plan.js +215 -0
  168. package/dist/cli/subcommands/providers.d.ts +27 -0
  169. package/dist/cli/subcommands/providers.js +433 -0
  170. package/dist/cli/subcommands/sessions.d.ts +11 -0
  171. package/dist/cli/subcommands/sessions.js +100 -0
  172. package/dist/codemode/capability.d.ts +37 -0
  173. package/dist/codemode/capability.js +55 -0
  174. package/dist/codemode/declarations.d.ts +44 -0
  175. package/dist/codemode/declarations.js +111 -0
  176. package/dist/codemode/host-side.d.ts +59 -0
  177. package/dist/codemode/host-side.js +253 -0
  178. package/dist/codemode/modes.d.ts +23 -0
  179. package/dist/codemode/modes.js +40 -0
  180. package/dist/codemode/protocol.d.ts +91 -0
  181. package/dist/codemode/protocol.js +114 -0
  182. package/dist/codemode/sandbox-entry.d.ts +25 -0
  183. package/dist/codemode/sandbox-entry.js +323 -0
  184. package/dist/codemode/store.d.ts +26 -0
  185. package/dist/codemode/store.js +53 -0
  186. package/dist/codemode/tool.d.ts +105 -0
  187. package/dist/codemode/tool.js +283 -0
  188. package/dist/compaction/branch-summary.d.ts +30 -0
  189. package/dist/compaction/branch-summary.js +79 -0
  190. package/dist/compaction/breaker.d.ts +32 -0
  191. package/dist/compaction/breaker.js +65 -0
  192. package/dist/compaction/cut-point.d.ts +23 -0
  193. package/dist/compaction/cut-point.js +70 -0
  194. package/dist/compaction/estimate.d.ts +30 -0
  195. package/dist/compaction/estimate.js +114 -0
  196. package/dist/compaction/prune-tier.d.ts +31 -0
  197. package/dist/compaction/prune-tier.js +83 -0
  198. package/dist/compaction/serialize.d.ts +20 -0
  199. package/dist/compaction/serialize.js +115 -0
  200. package/dist/compaction/summarize-tier.d.ts +111 -0
  201. package/dist/compaction/summarize-tier.js +305 -0
  202. package/dist/config/auth-file.d.ts +39 -0
  203. package/dist/config/auth-file.js +92 -0
  204. package/dist/config/context-files.d.ts +30 -0
  205. package/dist/config/context-files.js +77 -0
  206. package/dist/config/init.d.ts +30 -0
  207. package/dist/config/init.js +92 -0
  208. package/dist/config/json-schema.d.ts +14 -0
  209. package/dist/config/json-schema.js +182 -0
  210. package/dist/config/load.d.ts +45 -0
  211. package/dist/config/load.js +97 -0
  212. package/dist/config/merge.d.ts +73 -0
  213. package/dist/config/merge.js +248 -0
  214. package/dist/config/paths.d.ts +38 -0
  215. package/dist/config/paths.js +108 -0
  216. package/dist/config/profile.d.ts +27 -0
  217. package/dist/config/profile.js +65 -0
  218. package/dist/config/schema.d.ts +34 -0
  219. package/dist/config/schema.js +476 -0
  220. package/dist/config/trust.d.ts +42 -0
  221. package/dist/config/trust.js +122 -0
  222. package/dist/config/types.d.ts +190 -0
  223. package/dist/config/types.js +29 -0
  224. package/dist/config/write.d.ts +10 -0
  225. package/dist/config/write.js +25 -0
  226. package/dist/errors.d.ts +28 -0
  227. package/dist/errors.js +30 -0
  228. package/dist/hooks/config.d.ts +49 -0
  229. package/dist/hooks/config.js +102 -0
  230. package/dist/hooks/dispatcher.d.ts +41 -0
  231. package/dist/hooks/dispatcher.js +104 -0
  232. package/dist/hooks/matcher.d.ts +22 -0
  233. package/dist/hooks/matcher.js +108 -0
  234. package/dist/hooks/protocol.d.ts +33 -0
  235. package/dist/hooks/protocol.js +240 -0
  236. package/dist/hooks/runner.d.ts +30 -0
  237. package/dist/hooks/runner.js +143 -0
  238. package/dist/hooks/types.d.ts +147 -0
  239. package/dist/hooks/types.js +20 -0
  240. package/dist/host/api-impl.d.ts +75 -0
  241. package/dist/host/api-impl.js +173 -0
  242. package/dist/host/loader.d.ts +31 -0
  243. package/dist/host/loader.js +147 -0
  244. package/dist/host/types.d.ts +169 -0
  245. package/dist/host/types.js +14 -0
  246. package/dist/host.d.ts +5 -0
  247. package/dist/host.js +4 -0
  248. package/dist/index.d.ts +41 -0
  249. package/dist/index.js +28 -0
  250. package/dist/modes/commands-core.d.ts +44 -0
  251. package/dist/modes/commands-core.js +171 -0
  252. package/dist/modes/image-input.d.ts +27 -0
  253. package/dist/modes/image-input.js +78 -0
  254. package/dist/modes/interactive/approval-dialog.d.ts +48 -0
  255. package/dist/modes/interactive/approval-dialog.js +202 -0
  256. package/dist/modes/interactive/commands.d.ts +41 -0
  257. package/dist/modes/interactive/commands.js +201 -0
  258. package/dist/modes/interactive/completion.d.ts +53 -0
  259. package/dist/modes/interactive/completion.js +157 -0
  260. package/dist/modes/interactive/interactive-mode.d.ts +46 -0
  261. package/dist/modes/interactive/interactive-mode.js +491 -0
  262. package/dist/modes/interactive/key-dispatch.d.ts +29 -0
  263. package/dist/modes/interactive/key-dispatch.js +107 -0
  264. package/dist/modes/interactive/line/line-editor.d.ts +50 -0
  265. package/dist/modes/interactive/line/line-editor.js +232 -0
  266. package/dist/modes/interactive/line/line-mode.d.ts +20 -0
  267. package/dist/modes/interactive/line/line-mode.js +218 -0
  268. package/dist/modes/interactive/line/line-render.d.ts +35 -0
  269. package/dist/modes/interactive/line/line-render.js +171 -0
  270. package/dist/modes/interactive/line/paste-state.d.ts +26 -0
  271. package/dist/modes/interactive/line/paste-state.js +72 -0
  272. package/dist/modes/interactive/message-view.d.ts +77 -0
  273. package/dist/modes/interactive/message-view.js +269 -0
  274. package/dist/modes/interactive/pickers.d.ts +42 -0
  275. package/dist/modes/interactive/pickers.js +115 -0
  276. package/dist/modes/interactive/startup-ui.d.ts +33 -0
  277. package/dist/modes/interactive/startup-ui.js +268 -0
  278. package/dist/modes/interactive/status-bar.d.ts +48 -0
  279. package/dist/modes/interactive/status-bar.js +139 -0
  280. package/dist/modes/interactive/tool-view.d.ts +95 -0
  281. package/dist/modes/interactive/tool-view.js +344 -0
  282. package/dist/modes/print/json-event.d.ts +15 -0
  283. package/dist/modes/print/json-event.js +39 -0
  284. package/dist/modes/print/print-mode.d.ts +17 -0
  285. package/dist/modes/print/print-mode.js +107 -0
  286. package/dist/modes/rpc/commands.d.ts +40 -0
  287. package/dist/modes/rpc/commands.js +263 -0
  288. package/dist/modes/rpc/jsonl.d.ts +16 -0
  289. package/dist/modes/rpc/jsonl.js +55 -0
  290. package/dist/modes/rpc/rpc-mode.d.ts +22 -0
  291. package/dist/modes/rpc/rpc-mode.js +153 -0
  292. package/dist/modes/session-report.d.ts +55 -0
  293. package/dist/modes/session-report.js +278 -0
  294. package/dist/modes/shared.d.ts +13 -0
  295. package/dist/modes/shared.js +52 -0
  296. package/dist/modes/startup-ui-text.d.ts +16 -0
  297. package/dist/modes/startup-ui-text.js +103 -0
  298. package/dist/permissions/broker.d.ts +47 -0
  299. package/dist/permissions/broker.js +107 -0
  300. package/dist/permissions/dangerous.d.ts +47 -0
  301. package/dist/permissions/dangerous.js +370 -0
  302. package/dist/permissions/pipeline.d.ts +51 -0
  303. package/dist/permissions/pipeline.js +181 -0
  304. package/dist/permissions/preview.d.ts +43 -0
  305. package/dist/permissions/preview.js +463 -0
  306. package/dist/permissions/rules.d.ts +58 -0
  307. package/dist/permissions/rules.js +249 -0
  308. package/dist/permissions/types.d.ts +100 -0
  309. package/dist/permissions/types.js +18 -0
  310. package/dist/rpc.d.ts +173 -0
  311. package/dist/rpc.js +13 -0
  312. package/dist/sdk.d.ts +98 -0
  313. package/dist/sdk.js +195 -0
  314. package/dist/session/manager.d.ts +70 -0
  315. package/dist/session/manager.js +278 -0
  316. package/dist/session/migrate.d.ts +19 -0
  317. package/dist/session/migrate.js +53 -0
  318. package/dist/session/projection.d.ts +50 -0
  319. package/dist/session/projection.js +184 -0
  320. package/dist/session/store.d.ts +47 -0
  321. package/dist/session/store.js +210 -0
  322. package/dist/session/tree.d.ts +21 -0
  323. package/dist/session/tree.js +88 -0
  324. package/dist/session/types.d.ts +201 -0
  325. package/dist/session/types.js +18 -0
  326. package/dist/skills/discover.d.ts +60 -0
  327. package/dist/skills/discover.js +160 -0
  328. package/dist/skills/expand.d.ts +35 -0
  329. package/dist/skills/expand.js +46 -0
  330. package/dist/skills/frontmatter.d.ts +27 -0
  331. package/dist/skills/frontmatter.js +157 -0
  332. package/dist/skills/index-prompt.d.ts +13 -0
  333. package/dist/skills/index-prompt.js +42 -0
  334. package/dist/skills/templates.d.ts +52 -0
  335. package/dist/skills/templates.js +177 -0
  336. package/dist/tools/bash.d.ts +49 -0
  337. package/dist/tools/bash.js +222 -0
  338. package/dist/tools/edit-fuzzy.d.ts +36 -0
  339. package/dist/tools/edit-fuzzy.js +129 -0
  340. package/dist/tools/edit.d.ts +38 -0
  341. package/dist/tools/edit.js +241 -0
  342. package/dist/tools/file-mutex.d.ts +8 -0
  343. package/dist/tools/file-mutex.js +29 -0
  344. package/dist/tools/glob.d.ts +44 -0
  345. package/dist/tools/glob.js +217 -0
  346. package/dist/tools/grep.d.ts +39 -0
  347. package/dist/tools/grep.js +179 -0
  348. package/dist/tools/ignore.d.ts +40 -0
  349. package/dist/tools/ignore.js +174 -0
  350. package/dist/tools/image-file.d.ts +31 -0
  351. package/dist/tools/image-file.js +114 -0
  352. package/dist/tools/ls.d.ts +21 -0
  353. package/dist/tools/ls.js +96 -0
  354. package/dist/tools/output-accumulator.d.ts +48 -0
  355. package/dist/tools/output-accumulator.js +106 -0
  356. package/dist/tools/paths.d.ts +20 -0
  357. package/dist/tools/paths.js +58 -0
  358. package/dist/tools/presets.d.ts +71 -0
  359. package/dist/tools/presets.js +128 -0
  360. package/dist/tools/process-tree.d.ts +35 -0
  361. package/dist/tools/process-tree.js +125 -0
  362. package/dist/tools/read.d.ts +24 -0
  363. package/dist/tools/read.js +132 -0
  364. package/dist/tools/registry.d.ts +43 -0
  365. package/dist/tools/registry.js +106 -0
  366. package/dist/tools/shell.d.ts +38 -0
  367. package/dist/tools/shell.js +91 -0
  368. package/dist/tools/task.d.ts +29 -0
  369. package/dist/tools/task.js +107 -0
  370. package/dist/tools/todo.d.ts +28 -0
  371. package/dist/tools/todo.js +107 -0
  372. package/dist/tools/truncate.d.ts +44 -0
  373. package/dist/tools/truncate.js +175 -0
  374. package/dist/tools/types.d.ts +135 -0
  375. package/dist/tools/types.js +19 -0
  376. package/dist/tools/write.d.ts +20 -0
  377. package/dist/tools/write.js +84 -0
  378. package/dist/tui/ansi.d.ts +29 -0
  379. package/dist/tui/ansi.js +420 -0
  380. package/dist/tui/component.d.ts +38 -0
  381. package/dist/tui/component.js +13 -0
  382. package/dist/tui/components/box.d.ts +26 -0
  383. package/dist/tui/components/box.js +65 -0
  384. package/dist/tui/components/container.d.ts +14 -0
  385. package/dist/tui/components/container.js +39 -0
  386. package/dist/tui/components/editor-buffer.d.ts +67 -0
  387. package/dist/tui/components/editor-buffer.js +300 -0
  388. package/dist/tui/components/editor-paste.d.ts +29 -0
  389. package/dist/tui/components/editor-paste.js +64 -0
  390. package/dist/tui/components/editor.d.ts +114 -0
  391. package/dist/tui/components/editor.js +530 -0
  392. package/dist/tui/components/key-value.d.ts +29 -0
  393. package/dist/tui/components/key-value.js +48 -0
  394. package/dist/tui/components/loader.d.ts +35 -0
  395. package/dist/tui/components/loader.js +71 -0
  396. package/dist/tui/components/markdown.d.ts +90 -0
  397. package/dist/tui/components/markdown.js +462 -0
  398. package/dist/tui/components/meter.d.ts +29 -0
  399. package/dist/tui/components/meter.js +47 -0
  400. package/dist/tui/components/overlay.d.ts +24 -0
  401. package/dist/tui/components/overlay.js +52 -0
  402. package/dist/tui/components/select-list.d.ts +57 -0
  403. package/dist/tui/components/select-list.js +179 -0
  404. package/dist/tui/components/spacer.d.ts +11 -0
  405. package/dist/tui/components/spacer.js +16 -0
  406. package/dist/tui/components/text.d.ts +30 -0
  407. package/dist/tui/components/text.js +65 -0
  408. package/dist/tui/keybindings.d.ts +66 -0
  409. package/dist/tui/keybindings.js +120 -0
  410. package/dist/tui/keys.d.ts +38 -0
  411. package/dist/tui/keys.js +275 -0
  412. package/dist/tui/stdin-buffer.d.ts +41 -0
  413. package/dist/tui/stdin-buffer.js +206 -0
  414. package/dist/tui/terminal.d.ts +79 -0
  415. package/dist/tui/terminal.js +153 -0
  416. package/dist/tui/theme.d.ts +31 -0
  417. package/dist/tui/theme.js +199 -0
  418. package/dist/tui/tui.d.ts +103 -0
  419. package/dist/tui/tui.js +363 -0
  420. package/dist/tui/vt-screen.d.ts +46 -0
  421. package/dist/tui/vt-screen.js +251 -0
  422. package/dist/tui.d.ts +30 -0
  423. package/dist/tui.js +31 -0
  424. package/dist/version.d.ts +8 -0
  425. package/dist/version.js +24 -0
  426. package/docs/codemode.md +102 -0
  427. package/docs/hooks.md +196 -0
  428. package/docs/host-api.md +161 -0
  429. package/docs/providers.md +531 -0
  430. package/docs/rpc.md +253 -0
  431. package/docs/session-format.md +119 -0
  432. package/docs/tui.md +170 -0
  433. package/package.json +101 -4
@@ -0,0 +1,39 @@
1
+ /**
2
+ * 前缀指纹(第三波 §1.2):一次请求的「可缓存前缀」= 折叠后的系统提示 + 工具表 + 模型。[W3-C1b]
3
+ *
4
+ * - `system` = sha256(normalizeContext().systemPrompt) 前 64 bit;
5
+ * - `tools` = sha256(JSON.stringify(工具表按名排序)) 前 64 bit;
6
+ * - `model` = `${provider}/${id}` 原文。
7
+ * 纯函数、零请求;每次真实请求算一次(system + tools 通常 < 20 KB)。未命中归因时与上一条
8
+ * 记录比对,说出「变了什么」。
9
+ */
10
+ import { createHash } from "node:crypto";
11
+ import { normalizeContext } from "../context.js";
12
+ /** sha256 的前 16 位 hex(64 bit)。 */
13
+ export function hash16(text) {
14
+ return createHash("sha256").update(text).digest("hex").slice(0, 16);
15
+ }
16
+ export function modelKey(model) {
17
+ return `${model.provider}/${model.id}${model.channel !== undefined ? `@${model.channel}` : ""}`;
18
+ }
19
+ function sortedTools(tools) {
20
+ return [...tools].sort((a, b) => (a.name < b.name ? -1 : a.name > b.name ? 1 : 0));
21
+ }
22
+ export function fingerprintContext(context, model) {
23
+ const normalized = normalizeContext(context);
24
+ return {
25
+ system: hash16(normalized.systemPrompt),
26
+ tools: hash16(JSON.stringify(sortedTools(normalized.tools))),
27
+ model: modelKey(model),
28
+ };
29
+ }
30
+ /** 两个指纹的差异(按归因顺序:system → tools → model);相同返回 undefined。 */
31
+ export function fingerprintChange(prev, cur) {
32
+ if (prev.system !== cur.system)
33
+ return "system";
34
+ if (prev.tools !== cur.tools)
35
+ return "tools";
36
+ if (prev.model !== cur.model)
37
+ return "model";
38
+ return undefined;
39
+ }
@@ -0,0 +1,49 @@
1
+ /**
2
+ * 未命中检测(第三波 §1.5):同一请求链上前后两条 `RequestRecord` 比对,纯函数。[W3-C1b]
3
+ *
4
+ * 1. 不计:没有 prev;本条 promptTokens 为 0;本条读写都为 0 且端点不是 `reported`(§1.6);
5
+ * prev 低于最小可缓存长度(判 unknown,不判 miss)。
6
+ * 2. `missed = min(prev, cur) − cur.cacheRead`;`missed ≤ noiseFloor` 不计,
7
+ * `noiseFloor = max(1024, minTokens, 端点推断的缓存粒度)`(分块报读的端点,不足一块的尾部
8
+ * 不算未命中,见 `reporting.ts`)。
9
+ * 3. 规模自适应:`missed / prev > clamp(0.10 × √(100k / prev), 0.02, 0.30)` 或 `missed ≥ 20k`。
10
+ * 4. 成本:用本条实付反推——`(cost.input + cost.cacheWrite) / (input + cacheWrite)` 减去读价
11
+ * (本条有读用实付,否则用目录价);无价格 → `missedCost` 缺省。
12
+ * 5. 重置点(压缩 / 分支摘要 / 档一裁剪之后的首个请求)由调用方清空 prev;模型切换不豁免。
13
+ * 6. 归因:指纹 system / tools 变 → `prefix_changed`;模型变 → `model_changed`;
14
+ * `idleMs > ttl`(无承诺 TTL 的隐式缓存按 600 s)→ `idle`;task 运行占间隔 ≥ 80% →
15
+ * `subtask`;其余 → `evicted`。
16
+ */
17
+ import type { ModelCost } from "../types.js";
18
+ import type { CacheMiss, CacheReporting, RequestRecord } from "./types.js";
19
+ /** 无承诺 TTL 的端点(隐式缓存)按 10 分钟估。 */
20
+ export declare const IMPLICIT_CACHE_TTL_MS = 600000;
21
+ /** 没有目录 `minTokens` 时的最小可缓存长度与噪声下限。 */
22
+ export declare const DEFAULT_MIN_CACHE_TOKENS = 1024;
23
+ /** 绝对门槛:一次少读这么多 token 无论比例都算未命中。 */
24
+ export declare const MISS_ABSOLUTE_TOKENS = 20000;
25
+ /** 转录 / 消息区只提示超过这两个门槛之一的未命中(统计计入全部)。 */
26
+ export declare const MISS_NOTICE_TOKENS = 20000;
27
+ export declare const MISS_NOTICE_USD = 0.1;
28
+ /** task 运行时间占间隔的比例达到它 → 归因 subtask。 */
29
+ export declare const SUBTASK_SHARE = 0.8;
30
+ export interface MissOptions {
31
+ /** 本条请求所在端点的三态;读写都为 0 时只有 `reported` 才判。 */
32
+ reporting?: CacheReporting;
33
+ /** 目录 `promptCache.minTokens`。 */
34
+ minTokens?: number;
35
+ /** 端点推断的缓存读粒度(`CacheReportingTracker.granularity`)。 */
36
+ granularity?: number;
37
+ /** prev 与 cur 之间 task 工具运行的墙钟时间。 */
38
+ subtaskMs?: number;
39
+ /** 本条没有缓存读时的读价来源(目录价)。 */
40
+ cost?: Pick<ModelCost, "cacheRead">;
41
+ }
42
+ export declare function noiseFloor(minTokens: number | undefined, granularity?: number): number;
43
+ /** 未命中比例门槛:前缀越长越敏感(2%–30%)。 */
44
+ export declare function missRatioThreshold(prevTokens: number): number;
45
+ /** 重计费金额(美元);本条无成本 → undefined。 */
46
+ export declare function missedCostOf(cur: RequestRecord, missed: number, cost?: Pick<ModelCost, "cacheRead">): number | undefined;
47
+ export declare function detectMiss(prev: RequestRecord | undefined, cur: RequestRecord, ttlMs: number | undefined, options?: MissOptions): CacheMiss | undefined;
48
+ /** 转录 / 消息区是否提示这次未命中(`/session` 与 RPC 统计计入全部)。 */
49
+ export declare function isNotableMiss(miss: CacheMiss): boolean;
@@ -0,0 +1,96 @@
1
+ /**
2
+ * 未命中检测(第三波 §1.5):同一请求链上前后两条 `RequestRecord` 比对,纯函数。[W3-C1b]
3
+ *
4
+ * 1. 不计:没有 prev;本条 promptTokens 为 0;本条读写都为 0 且端点不是 `reported`(§1.6);
5
+ * prev 低于最小可缓存长度(判 unknown,不判 miss)。
6
+ * 2. `missed = min(prev, cur) − cur.cacheRead`;`missed ≤ noiseFloor` 不计,
7
+ * `noiseFloor = max(1024, minTokens, 端点推断的缓存粒度)`(分块报读的端点,不足一块的尾部
8
+ * 不算未命中,见 `reporting.ts`)。
9
+ * 3. 规模自适应:`missed / prev > clamp(0.10 × √(100k / prev), 0.02, 0.30)` 或 `missed ≥ 20k`。
10
+ * 4. 成本:用本条实付反推——`(cost.input + cost.cacheWrite) / (input + cacheWrite)` 减去读价
11
+ * (本条有读用实付,否则用目录价);无价格 → `missedCost` 缺省。
12
+ * 5. 重置点(压缩 / 分支摘要 / 档一裁剪之后的首个请求)由调用方清空 prev;模型切换不豁免。
13
+ * 6. 归因:指纹 system / tools 变 → `prefix_changed`;模型变 → `model_changed`;
14
+ * `idleMs > ttl`(无承诺 TTL 的隐式缓存按 600 s)→ `idle`;task 运行占间隔 ≥ 80% →
15
+ * `subtask`;其余 → `evicted`。
16
+ */
17
+ import { fingerprintChange } from "./fingerprint.js";
18
+ /** 无承诺 TTL 的端点(隐式缓存)按 10 分钟估。 */
19
+ export const IMPLICIT_CACHE_TTL_MS = 600_000;
20
+ /** 没有目录 `minTokens` 时的最小可缓存长度与噪声下限。 */
21
+ export const DEFAULT_MIN_CACHE_TOKENS = 1024;
22
+ /** 绝对门槛:一次少读这么多 token 无论比例都算未命中。 */
23
+ export const MISS_ABSOLUTE_TOKENS = 20_000;
24
+ /** 转录 / 消息区只提示超过这两个门槛之一的未命中(统计计入全部)。 */
25
+ export const MISS_NOTICE_TOKENS = 20_000;
26
+ export const MISS_NOTICE_USD = 0.1;
27
+ /** task 运行时间占间隔的比例达到它 → 归因 subtask。 */
28
+ export const SUBTASK_SHARE = 0.8;
29
+ export function noiseFloor(minTokens, granularity) {
30
+ return Math.max(DEFAULT_MIN_CACHE_TOKENS, minTokens ?? DEFAULT_MIN_CACHE_TOKENS, granularity ?? 0);
31
+ }
32
+ /** 未命中比例门槛:前缀越长越敏感(2%–30%)。 */
33
+ export function missRatioThreshold(prevTokens) {
34
+ if (prevTokens <= 0)
35
+ return 0.3;
36
+ const raw = 0.1 * Math.sqrt(100_000 / prevTokens);
37
+ return Math.min(0.3, Math.max(0.02, raw));
38
+ }
39
+ /** 重计费金额(美元);本条无成本 → undefined。 */
40
+ export function missedCostOf(cur, missed, cost) {
41
+ const { usage } = cur;
42
+ if (usage.cost === undefined)
43
+ return undefined;
44
+ const paidTokens = usage.input + usage.cacheWrite;
45
+ if (paidTokens <= 0)
46
+ return 0;
47
+ const paidPerToken = (usage.cost.input + usage.cost.cacheWrite) / paidTokens;
48
+ let readPerToken;
49
+ if (usage.cacheRead > 0)
50
+ readPerToken = usage.cost.cacheRead / usage.cacheRead;
51
+ else if (cost !== undefined)
52
+ readPerToken = cost.cacheRead / 1e6;
53
+ else
54
+ return undefined;
55
+ return missed * Math.max(0, paidPerToken - readPerToken);
56
+ }
57
+ export function detectMiss(prev, cur, ttlMs, options = {}) {
58
+ if (prev === undefined || cur.promptTokens <= 0)
59
+ return undefined;
60
+ const { cacheRead, cacheWrite } = cur.usage;
61
+ if (cacheRead + cacheWrite === 0 && options.reporting !== "reported")
62
+ return undefined;
63
+ const minTokens = options.minTokens ?? DEFAULT_MIN_CACHE_TOKENS;
64
+ if (prev.promptTokens < minTokens)
65
+ return undefined;
66
+ const missed = Math.min(prev.promptTokens, cur.promptTokens) - cacheRead;
67
+ if (missed <= noiseFloor(options.minTokens, options.granularity))
68
+ return undefined;
69
+ const ratio = missed / prev.promptTokens;
70
+ if (ratio <= missRatioThreshold(prev.promptTokens) && missed < MISS_ABSOLUTE_TOKENS) {
71
+ return undefined;
72
+ }
73
+ const idleMs = Math.max(0, cur.at - prev.at);
74
+ const miss = { missedTokens: missed, reason: "evicted", idleMs };
75
+ const cost = missedCostOf(cur, missed, options.cost);
76
+ if (cost !== undefined)
77
+ miss.missedCost = cost;
78
+ const change = fingerprintChange(prev.fingerprint, cur.fingerprint);
79
+ if (change === "system" || change === "tools") {
80
+ miss.reason = "prefix_changed";
81
+ miss.detail = change;
82
+ }
83
+ else if (change === "model")
84
+ miss.reason = "model_changed";
85
+ else if (idleMs > (ttlMs ?? IMPLICIT_CACHE_TTL_MS))
86
+ miss.reason = "idle";
87
+ else if (idleMs > 0 && (options.subtaskMs ?? 0) >= SUBTASK_SHARE * idleMs) {
88
+ miss.reason = "subtask";
89
+ }
90
+ return miss;
91
+ }
92
+ /** 转录 / 消息区是否提示这次未命中(`/session` 与 RPC 统计计入全部)。 */
93
+ export function isNotableMiss(miss) {
94
+ return (miss.missedTokens >= MISS_NOTICE_TOKENS ||
95
+ (miss.missedCost !== undefined && miss.missedCost >= MISS_NOTICE_USD));
96
+ }
@@ -0,0 +1,39 @@
1
+ /**
2
+ * 「供应商不报缓存」三态(第三波 §1.6)。[W3-C1b]
3
+ *
4
+ * 按 `(provider, baseUrl 主机名, model)` 维护 `unknown | reported | silent`:
5
+ * - 出现过 `cacheRead > 0` 或 `cacheWrite > 0` → `reported`(之后一直是);
6
+ * - 连续 K = 3 票 → `silent`;一票 = 前缀 ≥ minTokens 且读写都为 0,并且满足其一:
7
+ * 原始响应里**没有**缓存字段(`cacheReported === false`);或与上一条可比(指纹未变、
8
+ * 间隔 < ttl)——有些中转总塞 `cached_tokens: 0`,单看字段存在不够;
9
+ * - 其余情形(小请求、不可比)既不投票也不清零。`silent` 之后出现命中即转 `reported`。
10
+ * `compat.cacheReporting` 为 `silent` / `reported` 时强制。状态只在内存:进程内跨会话复用
11
+ * (`sharedCacheReporting`),同一端点换会话不必再探 3 次。
12
+ *
13
+ * 同一张表还记缓存读的**分块粒度**:有的端点(如 DeepSeek 经中转)按 2048 token 一块报
14
+ * cacheRead,不足一块的尾部总被算成未读。粒度 = 观察到的非零 cacheRead 的最大公约数,
15
+ * 至少 2 个样本且落在 [128, 8192] 才采信;未命中的噪声下限据此抬高(`miss.ts`)。
16
+ */
17
+ import type { CacheReportingSetting } from "../types.js";
18
+ import type { CacheReporting, RequestRecord } from "./types.js";
19
+ /** 连续这么多票判 silent。 */
20
+ export declare const SILENT_STREAK = 3;
21
+ /** 缓存粒度:样本数下限与采信范围。 */
22
+ export declare const GRANULARITY_MIN_SAMPLES = 2;
23
+ export declare const GRANULARITY_MIN = 128;
24
+ export declare const GRANULARITY_MAX = 8192;
25
+ /** 由非零 cacheRead 的最大公约数与样本数推断粒度;不可信 → undefined。 */
26
+ export declare function inferGranularity(divisor: number, samples: number): number | undefined;
27
+ export declare function endpointKey(record: Pick<RequestRecord, "model" | "baseUrl">): string;
28
+ export declare class CacheReportingTracker {
29
+ private readonly endpoints;
30
+ /** 记一条真实请求,返回该端点(含强制设置后)的状态。 */
31
+ observe(record: RequestRecord, minTokens: number, ttlMs?: number, setting?: CacheReportingSetting): CacheReporting;
32
+ get(key: string, setting?: CacheReportingSetting): CacheReporting;
33
+ /** 端点的缓存读粒度(token);样本不足或不可信 → undefined。 */
34
+ granularity(key: string): number | undefined;
35
+ /** 测试用:清空全部端点。 */
36
+ clear(): void;
37
+ }
38
+ /** 进程内共享(同一端点换会话、子会话都复用)。 */
39
+ export declare const sharedCacheReporting: CacheReportingTracker;
@@ -0,0 +1,103 @@
1
+ /**
2
+ * 「供应商不报缓存」三态(第三波 §1.6)。[W3-C1b]
3
+ *
4
+ * 按 `(provider, baseUrl 主机名, model)` 维护 `unknown | reported | silent`:
5
+ * - 出现过 `cacheRead > 0` 或 `cacheWrite > 0` → `reported`(之后一直是);
6
+ * - 连续 K = 3 票 → `silent`;一票 = 前缀 ≥ minTokens 且读写都为 0,并且满足其一:
7
+ * 原始响应里**没有**缓存字段(`cacheReported === false`);或与上一条可比(指纹未变、
8
+ * 间隔 < ttl)——有些中转总塞 `cached_tokens: 0`,单看字段存在不够;
9
+ * - 其余情形(小请求、不可比)既不投票也不清零。`silent` 之后出现命中即转 `reported`。
10
+ * `compat.cacheReporting` 为 `silent` / `reported` 时强制。状态只在内存:进程内跨会话复用
11
+ * (`sharedCacheReporting`),同一端点换会话不必再探 3 次。
12
+ *
13
+ * 同一张表还记缓存读的**分块粒度**:有的端点(如 DeepSeek 经中转)按 2048 token 一块报
14
+ * cacheRead,不足一块的尾部总被算成未读。粒度 = 观察到的非零 cacheRead 的最大公约数,
15
+ * 至少 2 个样本且落在 [128, 8192] 才采信;未命中的噪声下限据此抬高(`miss.ts`)。
16
+ */
17
+ import { IMPLICIT_CACHE_TTL_MS } from "./miss.js";
18
+ /** 连续这么多票判 silent。 */
19
+ export const SILENT_STREAK = 3;
20
+ /** 缓存粒度:样本数下限与采信范围。 */
21
+ export const GRANULARITY_MIN_SAMPLES = 2;
22
+ export const GRANULARITY_MIN = 128;
23
+ export const GRANULARITY_MAX = 8192;
24
+ function gcd(a, b) {
25
+ while (b > 0)
26
+ [a, b] = [b, a % b];
27
+ return a;
28
+ }
29
+ /** 由非零 cacheRead 的最大公约数与样本数推断粒度;不可信 → undefined。 */
30
+ export function inferGranularity(divisor, samples) {
31
+ if (samples < GRANULARITY_MIN_SAMPLES)
32
+ return undefined;
33
+ return divisor >= GRANULARITY_MIN && divisor <= GRANULARITY_MAX ? divisor : undefined;
34
+ }
35
+ function hostOf(baseUrl) {
36
+ try {
37
+ return new URL(baseUrl).host;
38
+ }
39
+ catch {
40
+ return baseUrl;
41
+ }
42
+ }
43
+ export function endpointKey(record) {
44
+ const channel = record.model.channel !== undefined ? `@${record.model.channel}` : "";
45
+ return `${record.model.provider}|${hostOf(record.baseUrl)}|${record.model.id}${channel}`;
46
+ }
47
+ function sameFingerprint(a, b) {
48
+ return a.system === b.system && a.tools === b.tools && a.model === b.model;
49
+ }
50
+ function forced(setting) {
51
+ return setting === "silent" || setting === "reported" ? setting : undefined;
52
+ }
53
+ export class CacheReportingTracker {
54
+ endpoints = new Map();
55
+ /** 记一条真实请求,返回该端点(含强制设置后)的状态。 */
56
+ observe(record, minTokens, ttlMs, setting) {
57
+ const key = endpointKey(record);
58
+ const entry = this.endpoints.get(key) ?? {
59
+ state: "unknown",
60
+ streak: 0,
61
+ last: undefined,
62
+ divisor: 0,
63
+ samples: 0,
64
+ };
65
+ this.endpoints.set(key, entry);
66
+ const last = entry.last;
67
+ entry.last = record;
68
+ const { cacheRead, cacheWrite, cacheReported } = record.usage;
69
+ if (cacheRead > 0 && Number.isInteger(cacheRead)) {
70
+ entry.divisor = gcd(entry.divisor, cacheRead);
71
+ entry.samples++;
72
+ }
73
+ if (cacheRead + cacheWrite > 0) {
74
+ entry.state = "reported";
75
+ entry.streak = 0;
76
+ }
77
+ else if (entry.state !== "reported" && record.promptTokens >= minTokens) {
78
+ const comparable = last !== undefined &&
79
+ last.promptTokens >= minTokens &&
80
+ sameFingerprint(last.fingerprint, record.fingerprint) &&
81
+ record.at - last.at < (ttlMs ?? IMPLICIT_CACHE_TTL_MS);
82
+ if (cacheReported === false || comparable)
83
+ entry.streak++;
84
+ if (entry.streak >= SILENT_STREAK)
85
+ entry.state = "silent";
86
+ }
87
+ return forced(setting) ?? entry.state;
88
+ }
89
+ get(key, setting) {
90
+ return forced(setting) ?? this.endpoints.get(key)?.state ?? "unknown";
91
+ }
92
+ /** 端点的缓存读粒度(token);样本不足或不可信 → undefined。 */
93
+ granularity(key) {
94
+ const entry = this.endpoints.get(key);
95
+ return entry === undefined ? undefined : inferGranularity(entry.divisor, entry.samples);
96
+ }
97
+ /** 测试用:清空全部端点。 */
98
+ clear() {
99
+ this.endpoints.clear();
100
+ }
101
+ }
102
+ /** 进程内共享(同一端点换会话、子会话都复用)。 */
103
+ export const sharedCacheReporting = new CacheReportingTracker();
@@ -0,0 +1,94 @@
1
+ /**
2
+ * 会话层缓存的共享类型(第三波 §1.2、§1.5–§1.7)。[W3-C0] 契约文件,实现归 W3-C1b。
3
+ *
4
+ * 补全与偏差(相对第三波设计正文):
5
+ * - 设计把本文件列在 C1b;为让 C2(展示)、宿主(`cache.onWarmingDecision`)与配置
6
+ * (`cache.warming`)在 C1b 合入前就能引用同一组名字,类型在契约 PR 里先定死,C1b 只追加。
7
+ * - `CacheMiss.missedCost` 写成可选:§1.5 第 4 步「模型无价格 → undefined」,正文接口写的是
8
+ * `number`,以算法为准。
9
+ * - 补全 `CacheMissReason`、`WarmingPhase`、`WarmerState`、`WarmerStatus` 与 `WarmDecision`
10
+ * 的字段(正文只给了 `decide({ warmCost, missCost, probability, action })`)。
11
+ */
12
+ import type { Api, ModelRef, RequestPurpose, StreamOptions, TranscriptContext, Usage } from "../types.js";
13
+ /** 前缀指纹:各 16 位 hex(sha256 前 64 bit)。 */
14
+ export interface PrefixFingerprint {
15
+ /** `normalizeContext().systemPrompt` 的哈希。 */
16
+ system: string;
17
+ /** 工具表按名排序后 `JSON.stringify` 的哈希。 */
18
+ tools: string;
19
+ /** `${provider}/${id}`(原文,不哈希)。 */
20
+ model: string;
21
+ }
22
+ /** 每次真实请求在会话层记一条(内存,不落盘)。 */
23
+ export interface RequestRecord {
24
+ /** 请求发出时刻(保温计时从这里算,不是响应结束)。 */
25
+ at: number;
26
+ purpose: RequestPurpose;
27
+ model: ModelRef;
28
+ api: Api;
29
+ baseUrl: string;
30
+ fingerprint: PrefixFingerprint;
31
+ /** input + cacheRead + cacheWrite。 */
32
+ promptTokens: number;
33
+ /** 含 cost 与 cacheReported。 */
34
+ usage: Usage;
35
+ /** 保温重放用(同一引用)。 */
36
+ contextRef: TranscriptContext;
37
+ options: Omit<StreamOptions, "signal">;
38
+ }
39
+ /** 「供应商不报缓存」三态(§1.6);按 `(provider, baseUrl 主机名, model)` 维护。 */
40
+ export type CacheReporting = "unknown" | "reported" | "silent";
41
+ /** 未命中原因(§1.5 第 6 步的归因顺序)。 */
42
+ export type CacheMissReason = "prefix_changed" | "model_changed" | "idle" | "subtask" | "evicted";
43
+ export declare const CACHE_MISS_REASONS: readonly CacheMissReason[];
44
+ export interface CacheMiss {
45
+ /** 重计费 token。 */
46
+ missedTokens: number;
47
+ /** 重计费金额(美元);模型无价格时缺省(显示 `$?`)。 */
48
+ missedCost?: number;
49
+ reason: CacheMissReason;
50
+ /** `prefix_changed` 时哪一段变了。 */
51
+ detail?: "system" | "tools";
52
+ /** 与上一条可比请求的间隔。 */
53
+ idleMs: number;
54
+ }
55
+ /** 保温模式(§1.7):off 不保温;streaming 只在工具运行期间;idle 另含空闲相(需 opt-in)。 */
56
+ export type WarmingMode = "off" | "streaming" | "idle";
57
+ export declare const WARMING_MODES: readonly WarmingMode[];
58
+ /** 保温所处的相:agent 运行中(streaming)或已 settle(idle)。 */
59
+ export type WarmingPhase = "streaming" | "idle";
60
+ /** 一次保温前的决策(`economics.evaluateWarm` 产出,宿主否决钩子的入参)。 */
61
+ export interface WarmDecision {
62
+ /** 内置决策。 */
63
+ action: "warm" | "stop";
64
+ phase: WarmingPhase;
65
+ /** 上一次真实请求的 input + cacheRead + cacheWrite。 */
66
+ promptTokens: number;
67
+ /** 一次保温请求的花费(美元);价格缺失时 undefined(经济性不可算 → stop)。 */
68
+ warmCost: number | undefined;
69
+ /** 不保温而失效时多付的金额(美元)。 */
70
+ missCost: number | undefined;
71
+ /** 失效后仍会再发请求的概率:streaming 1、idle 0.15。 */
72
+ probability: number;
73
+ /** stop 的原因(如 `no_price`、`below_min_savings`),warm 时缺省。 */
74
+ reason?: string;
75
+ }
76
+ /** 宿主 / 扩展的否决钩子(HostApi `cache.onWarmingDecision`);出错回落内置决策。 */
77
+ export type WarmingDecisionHandler = (decision: WarmDecision) => "warm" | "stop" | Promise<"warm" | "stop">;
78
+ /** inactive:还没有可重放的真实请求或已 cancel;scheduled:计时器在等;stopped:因故停止。 */
79
+ export type WarmerState = "inactive" | "scheduled" | "stopped";
80
+ export interface WarmerStatus {
81
+ mode: WarmingMode;
82
+ state: WarmerState;
83
+ phase?: WarmingPhase;
84
+ /** 下一次保温的时刻(epoch ms),state 为 scheduled 时给。 */
85
+ nextWarmAt?: number;
86
+ /** stopped 的原因。 */
87
+ reason?: string;
88
+ /** 本会话已发出的保温请求数。 */
89
+ sent?: number;
90
+ /** 保温累计花费(美元)。 */
91
+ costUsd?: number;
92
+ /** 最近一次决策的期望节省(美元)。 */
93
+ expectedSavingsUsd?: number;
94
+ }
@@ -0,0 +1,19 @@
1
+ /**
2
+ * 会话层缓存的共享类型(第三波 §1.2、§1.5–§1.7)。[W3-C0] 契约文件,实现归 W3-C1b。
3
+ *
4
+ * 补全与偏差(相对第三波设计正文):
5
+ * - 设计把本文件列在 C1b;为让 C2(展示)、宿主(`cache.onWarmingDecision`)与配置
6
+ * (`cache.warming`)在 C1b 合入前就能引用同一组名字,类型在契约 PR 里先定死,C1b 只追加。
7
+ * - `CacheMiss.missedCost` 写成可选:§1.5 第 4 步「模型无价格 → undefined」,正文接口写的是
8
+ * `number`,以算法为准。
9
+ * - 补全 `CacheMissReason`、`WarmingPhase`、`WarmerState`、`WarmerStatus` 与 `WarmDecision`
10
+ * 的字段(正文只给了 `decide({ warmCost, missCost, probability, action })`)。
11
+ */
12
+ export const CACHE_MISS_REASONS = [
13
+ "prefix_changed",
14
+ "model_changed",
15
+ "idle",
16
+ "subtask",
17
+ "evicted",
18
+ ];
19
+ export const WARMING_MODES = ["off", "streaming", "idle"];
@@ -0,0 +1,94 @@
1
+ /**
2
+ * 缓存保温状态机(第三波 §1.7)。[W3-C1b]
3
+ *
4
+ * 注入 now / 计时器 / 发送函数,fake 时钟可测:
5
+ * - `start(record, ttlMs)`:每个 turn 请求完成后调用(替换上一轮);计时**从请求发出算**:
6
+ * `delay = max(1s, floor(min(0.9·TTL, TTL − 10s)))`,TTL ≤ 10 s 不保温。
7
+ * - 截止 `deadline = nextWarmAt + (TTL − delay) / 2`:计时器迟到超过截止(睡眠、事件循环阻塞)
8
+ * 直接停——迟到的刷新大概率是一次全价写入。
9
+ * - 上限:streaming 相 60 min、idle 相 30 min(从起始真实请求算);连续 2 次保温响应读写都为
10
+ * 0 即停。
11
+ * - 每次刷新前:`isCurrent(record)` 不成立 → 停;内置经济性决策交给否决钩子 `decide`(出错
12
+ * 回落内置决策)。
13
+ * - `onAgentSettled()`:streaming 模式静默结束本轮;idle 模式转空闲相。
14
+ * - `pause()`:真实请求发出时静默挂起(新请求本身就刷新了缓存);`cancel()` 同时丢弃记录。
15
+ * 只有已排期之后的异常停止(截止、上限、零命中、过期、否决、失败)回调 `onStopped`。
16
+ */
17
+ import type { AssistantMessage, Model, StreamOptions } from "../types.js";
18
+ import type { CacheReporting, RequestRecord, WarmDecision, WarmerStatus, WarmingMode, WarmingPhase } from "./types.js";
19
+ export declare const WARM_MIN_TTL_MS = 10000;
20
+ export declare const WARM_STREAMING_CAP_MS: number;
21
+ export declare const WARM_IDLE_CAP_MS: number;
22
+ export declare const WARM_ZERO_HIT_LIMIT = 2;
23
+ export interface WarmerTimers {
24
+ set(fn: () => void, ms: number): unknown;
25
+ clear(handle: unknown): void;
26
+ }
27
+ /** 真实计时器:`unref()`,保温不拖住进程退出。 */
28
+ export declare const REAL_TIMERS: WarmerTimers;
29
+ export interface WarmerDeps {
30
+ mode(): WarmingMode;
31
+ now(): number;
32
+ timers?: WarmerTimers;
33
+ /** 重放:同 model / context / options,maxTokens 1,purpose warm,不经重试。 */
34
+ send(record: RequestRecord, signal: AbortSignal): Promise<AssistantMessage>;
35
+ /** 模型未变 && 记录的上下文仍是当前转录的同一引用前缀 && system 状态未变。 */
36
+ isCurrent(record: RequestRecord): boolean;
37
+ /** 内置经济性决策。 */
38
+ evaluate(record: RequestRecord, phase: WarmingPhase): WarmDecision;
39
+ /** 宿主 / 扩展否决钩子(每次现取)。 */
40
+ decide?(decision: WarmDecision): Promise<"warm" | "stop"> | "warm" | "stop";
41
+ onWarmed(record: RequestRecord, message: AssistantMessage, sentAt: number): void;
42
+ onScheduled?(nextWarmAt: number): void;
43
+ onStopped(reason: string): void;
44
+ }
45
+ export declare function warmDelay(ttlMs: number): number;
46
+ export interface ReplayCheck {
47
+ model: Pick<Model, "api" | "reasoning" | "compat">;
48
+ options: Pick<StreamOptions, "cacheRetention" | "thinkingLevel">;
49
+ /** `onPayload` 替换过请求体。 */
50
+ payloadReplaced: boolean;
51
+ reporting: CacheReporting;
52
+ }
53
+ /**
54
+ * 不保温的原因(undefined = 可以保温):
55
+ * - `cacheRetention: "none"` 的请求;被 `onPayload` 替换过请求体的请求;
56
+ * - anthropic-messages 开思考且不是自适应思考:预算从 `max_tokens` 推导,`max_tokens: 1` 会
57
+ * 去掉 thinking 块、改变缓存键;
58
+ * - 端点不是 `reported`(未知或不报缓存时看不出保温有没有用,第三波 §4 R2)。
59
+ */
60
+ export declare function replayBlocker(check: ReplayCheck): string | undefined;
61
+ export declare class CacheWarmer {
62
+ private readonly deps;
63
+ private readonly timers;
64
+ private record;
65
+ private origin;
66
+ private ttl;
67
+ private phase;
68
+ private timer;
69
+ private inflight;
70
+ private generation;
71
+ private zeroHits;
72
+ private state;
73
+ private reason;
74
+ private nextWarmAt;
75
+ private deadline;
76
+ private sent;
77
+ private costUsd;
78
+ private savings;
79
+ constructor(deps: WarmerDeps);
80
+ start(record: RequestRecord, ttlMs: number): void;
81
+ /** 不排期并记下原因(无事件:不可重放、端点未报告、经济性不划算等)。 */
82
+ block(reason: string): void;
83
+ onAgentSettled(): void;
84
+ /** 真实请求发出:静默挂起,保留统计。 */
85
+ pause(): void;
86
+ cancel(): void;
87
+ get status(): WarmerStatus;
88
+ private reset;
89
+ private stop;
90
+ private cap;
91
+ private schedule;
92
+ private decide;
93
+ private fire;
94
+ }