mixdog 0.7.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 (404) hide show
  1. package/.claude-plugin/marketplace.json +31 -0
  2. package/.claude-plugin/plugin.json +20 -0
  3. package/.gitattributes +34 -0
  4. package/.mcp.json +14 -0
  5. package/ARCHITECTURE.md +77 -0
  6. package/CHANGELOG.md +7 -0
  7. package/CONTRIBUTING.md +45 -0
  8. package/DATA-FLOW.md +79 -0
  9. package/LICENSE +21 -0
  10. package/README.md +389 -0
  11. package/SECURITY.md +138 -0
  12. package/UNINSTALL.md +112 -0
  13. package/agents/maintenance.md +5 -0
  14. package/agents/memory-classification.md +30 -0
  15. package/agents/scheduler-task.md +18 -0
  16. package/agents/webhook-handler.md +27 -0
  17. package/agents/worker.md +24 -0
  18. package/bin/bridge +133 -0
  19. package/bin/statusline-launcher.mjs +78 -0
  20. package/bin/statusline-lib.mjs +550 -0
  21. package/bin/statusline.mjs +607 -0
  22. package/bun.lock +802 -0
  23. package/commands/config.md +16 -0
  24. package/commands/doctor.md +13 -0
  25. package/commands/setup.md +17 -0
  26. package/defaults/cycle3-review-prompt.md +90 -0
  27. package/defaults/hidden-roles.json +65 -0
  28. package/defaults/memory-chunk-prompt.md +63 -0
  29. package/defaults/memory-promote-prompt.md +135 -0
  30. package/defaults/mixdog-config.template.json +27 -0
  31. package/defaults/user-workflow.json +8 -0
  32. package/defaults/user-workflow.md +12 -0
  33. package/hooks/hooks.json +73 -0
  34. package/hooks/lib/active-instance.cjs +77 -0
  35. package/hooks/lib/permission-evaluator.cjs +411 -0
  36. package/hooks/lib/permission-route.cjs +63 -0
  37. package/hooks/lib/permission-rules.cjs +170 -0
  38. package/hooks/lib/settings-loader.cjs +116 -0
  39. package/hooks/post-tool-use.cjs +84 -0
  40. package/hooks/pre-mcp-sandbox.cjs +158 -0
  41. package/hooks/pre-tool-subagent.cjs +253 -0
  42. package/hooks/session-start.cjs +1372 -0
  43. package/hooks/turn-timer.cjs +82 -0
  44. package/lib/claude-md-writer.cjs +386 -0
  45. package/lib/config-cjs.cjs +61 -0
  46. package/lib/hook-pipe-path.cjs +10 -0
  47. package/lib/keychain-cjs.cjs +263 -0
  48. package/lib/plugin-paths.cjs +61 -0
  49. package/lib/rules-builder.cjs +241 -0
  50. package/lib/text-utils.cjs +61 -0
  51. package/native/README.md +117 -0
  52. package/native/prebuilt/linux-aarch64/mixdog-shim +0 -0
  53. package/native/prebuilt/linux-x86_64/mixdog-shim +0 -0
  54. package/native/prebuilt/macos-aarch64/mixdog-shim +0 -0
  55. package/native/prebuilt/macos-x86_64/mixdog-shim +0 -0
  56. package/native/prebuilt/windows-x86_64/mixdog-shim.exe +0 -0
  57. package/package.json +107 -0
  58. package/prompts/code-review.txt +16 -0
  59. package/prompts/security-audit.txt +17 -0
  60. package/rules/bridge/00-common.md +39 -0
  61. package/rules/bridge/20-skip-protocol.md +18 -0
  62. package/rules/bridge/30-explorer.md +33 -0
  63. package/rules/bridge/40-cycle1-agent.md +52 -0
  64. package/rules/bridge/41-cycle2-agent.md +62 -0
  65. package/rules/bridge/42-cycle3-agent.md +44 -0
  66. package/rules/lead/00-tool-lead.md +61 -0
  67. package/rules/lead/01-general.md +23 -0
  68. package/rules/lead/02-channels.md +49 -0
  69. package/rules/lead/03-team.md +27 -0
  70. package/rules/lead/04-workflow.md +20 -0
  71. package/rules/shared/00-language.md +14 -0
  72. package/rules/shared/01-tool.md +138 -0
  73. package/scripts/bootstrap.mjs +184 -0
  74. package/scripts/bridge-unify-smoke.mjs +308 -0
  75. package/scripts/build-runtime-linux.sh +348 -0
  76. package/scripts/build-runtime-macos.sh +217 -0
  77. package/scripts/build-runtime-windows.ps1 +242 -0
  78. package/scripts/builtin-utils-smoke.mjs +392 -0
  79. package/scripts/check-json.mjs +45 -0
  80. package/scripts/check-syntax-changed.mjs +102 -0
  81. package/scripts/check-syntax.mjs +58 -0
  82. package/scripts/code-graph-batch.test.mjs +33 -0
  83. package/scripts/config-preserve-smoke.mjs +180 -0
  84. package/scripts/doctor.mjs +484 -0
  85. package/scripts/edit-normalize-fuzz.mjs +130 -0
  86. package/scripts/edit-normalize-smoke.mjs +401 -0
  87. package/scripts/edit-operation-smoke.mjs +369 -0
  88. package/scripts/edit2-smoke.mjs +63 -0
  89. package/scripts/fuzzy-e2e.mjs +28 -0
  90. package/scripts/fuzzy-smoke.mjs +26 -0
  91. package/scripts/generate-runtime-manifest.mjs +166 -0
  92. package/scripts/guard-smoke.mjs +66 -0
  93. package/scripts/hidden-role-schema-smoke.mjs +162 -0
  94. package/scripts/hook-routing-smoke.mjs +29 -0
  95. package/scripts/inject-input.ps1 +204 -0
  96. package/scripts/io-complex-smoke.mjs +667 -0
  97. package/scripts/io-explore-bench.mjs +424 -0
  98. package/scripts/io-guardrails-smoke.mjs +205 -0
  99. package/scripts/io-mini-bench-baseline.json +11 -0
  100. package/scripts/io-mini-bench.mjs +216 -0
  101. package/scripts/io-route-harness.mjs +933 -0
  102. package/scripts/io-telemetry-report.mjs +691 -0
  103. package/scripts/mutation-bench.mjs +564 -0
  104. package/scripts/mutation-io-smoke.mjs +1081 -0
  105. package/scripts/native-patch-bridge-smoke.mjs +288 -0
  106. package/scripts/native-patch-smoke.mjs +304 -0
  107. package/scripts/patch-interior-context-smoke.mjs +49 -0
  108. package/scripts/patch-newline-utf8-smoke.mjs +157 -0
  109. package/scripts/perf-hook-smoke.mjs +71 -0
  110. package/scripts/permission-eval-smoke.mjs +426 -0
  111. package/scripts/prep-patch.mjs +53 -0
  112. package/scripts/prep-shim.mjs +96 -0
  113. package/scripts/provider-cache-smoke.mjs +687 -0
  114. package/scripts/report-runtime-health.mjs +132 -0
  115. package/scripts/run-mcp.mjs +1547 -0
  116. package/scripts/salvage-v4a-shatter.test.mjs +58 -0
  117. package/scripts/scoped-cache-io-smoke.mjs +103 -0
  118. package/scripts/shell-policy-round3-smoke.mjs +46 -0
  119. package/scripts/smoke-runtime-negative.ps1 +100 -0
  120. package/scripts/smoke-runtime-negative.sh +95 -0
  121. package/scripts/stall-policy-smoke.mjs +50 -0
  122. package/scripts/start-memory-worker.mjs +23 -0
  123. package/scripts/statusline-launcher-smoke.mjs +82 -0
  124. package/scripts/stress-atomic-write.mjs +1028 -0
  125. package/scripts/test-config-rmw-restore.mjs +122 -0
  126. package/scripts/test-fault-inject.mjs +164 -0
  127. package/scripts/test-large-file.mjs +174 -0
  128. package/scripts/tool-edge-smoke.mjs +209 -0
  129. package/scripts/uninstall.mjs +201 -0
  130. package/scripts/webhook-selfheal-smoke.mjs +29 -0
  131. package/scripts/write-overwrite-guard-smoke.mjs +56 -0
  132. package/server-main.mjs +3055 -0
  133. package/server.mjs +468 -0
  134. package/setup/config-merge.mjs +254 -0
  135. package/setup/install.mjs +120 -0
  136. package/setup/launch-core.mjs +507 -0
  137. package/setup/launch.mjs +101 -0
  138. package/setup/setup-server.mjs +3206 -0
  139. package/setup/setup.html +3693 -0
  140. package/skills/retro-skill-proposer/SKILL.md +92 -0
  141. package/skills/schedule-add/SKILL.md +77 -0
  142. package/skills/setup/SKILL.md +346 -0
  143. package/skills/webhook-add/SKILL.md +81 -0
  144. package/src/agent/bridge-stall-watchdog.mjs +337 -0
  145. package/src/agent/index.mjs +2138 -0
  146. package/src/agent/orchestrator/activity-bus.mjs +38 -0
  147. package/src/agent/orchestrator/ai-wrapped-dispatch.mjs +1010 -0
  148. package/src/agent/orchestrator/bridge-retry.mjs +220 -0
  149. package/src/agent/orchestrator/bridge-trace.mjs +583 -0
  150. package/src/agent/orchestrator/cache-mtime.mjs +58 -0
  151. package/src/agent/orchestrator/config.mjs +358 -0
  152. package/src/agent/orchestrator/context/collect.mjs +651 -0
  153. package/src/agent/orchestrator/dispatch-persist.mjs +549 -0
  154. package/src/agent/orchestrator/drain-registry.mjs +50 -0
  155. package/src/agent/orchestrator/explore-validator.mjs +8 -0
  156. package/src/agent/orchestrator/internal-roles.mjs +118 -0
  157. package/src/agent/orchestrator/internal-tools.mjs +88 -0
  158. package/src/agent/orchestrator/jobs.mjs +116 -0
  159. package/src/agent/orchestrator/mcp/client.mjs +364 -0
  160. package/src/agent/orchestrator/providers/anthropic-betas.mjs +21 -0
  161. package/src/agent/orchestrator/providers/anthropic-oauth.mjs +1745 -0
  162. package/src/agent/orchestrator/providers/anthropic.mjs +437 -0
  163. package/src/agent/orchestrator/providers/gemini.mjs +1175 -0
  164. package/src/agent/orchestrator/providers/grok-oauth.mjs +782 -0
  165. package/src/agent/orchestrator/providers/model-catalog.mjs +241 -0
  166. package/src/agent/orchestrator/providers/openai-compat.mjs +1467 -0
  167. package/src/agent/orchestrator/providers/openai-oauth-ws.mjs +1890 -0
  168. package/src/agent/orchestrator/providers/openai-oauth.mjs +1307 -0
  169. package/src/agent/orchestrator/providers/openai-ws.mjs +104 -0
  170. package/src/agent/orchestrator/providers/registry.mjs +192 -0
  171. package/src/agent/orchestrator/providers/retry-classifier.mjs +325 -0
  172. package/src/agent/orchestrator/session/abort-lookup.mjs +13 -0
  173. package/src/agent/orchestrator/session/cache/post-edit-marks.mjs +42 -0
  174. package/src/agent/orchestrator/session/cache/prefetch-cache.mjs +142 -0
  175. package/src/agent/orchestrator/session/cache/read-cache.mjs +319 -0
  176. package/src/agent/orchestrator/session/cache/scoped-cache-outcome.mjs +11 -0
  177. package/src/agent/orchestrator/session/cache/scoped-cache.mjs +361 -0
  178. package/src/agent/orchestrator/session/cache/util.mjs +49 -0
  179. package/src/agent/orchestrator/session/loop.mjs +1478 -0
  180. package/src/agent/orchestrator/session/manager.mjs +1975 -0
  181. package/src/agent/orchestrator/session/read-dedup.mjs +6 -0
  182. package/src/agent/orchestrator/session/result-classification.mjs +65 -0
  183. package/src/agent/orchestrator/session/save-session-worker.mjs +18 -0
  184. package/src/agent/orchestrator/session/store.mjs +624 -0
  185. package/src/agent/orchestrator/session/stream-watchdog.mjs +130 -0
  186. package/src/agent/orchestrator/session/tool-result-offload.mjs +166 -0
  187. package/src/agent/orchestrator/session/trim.mjs +491 -0
  188. package/src/agent/orchestrator/smart-bridge/CACHE-SHARD.md +115 -0
  189. package/src/agent/orchestrator/smart-bridge/bridge-llm.mjs +327 -0
  190. package/src/agent/orchestrator/smart-bridge/cache-obs.mjs +150 -0
  191. package/src/agent/orchestrator/smart-bridge/cache-strategy.mjs +228 -0
  192. package/src/agent/orchestrator/smart-bridge/index.mjs +215 -0
  193. package/src/agent/orchestrator/smart-bridge/profiles.mjs +37 -0
  194. package/src/agent/orchestrator/smart-bridge/registry.mjs +348 -0
  195. package/src/agent/orchestrator/smart-bridge/session-builder.mjs +116 -0
  196. package/src/agent/orchestrator/stall-policy.mjs +195 -0
  197. package/src/agent/orchestrator/tool-loop-guard.mjs +75 -0
  198. package/src/agent/orchestrator/tools/bash-policy-scan.mjs +77 -0
  199. package/src/agent/orchestrator/tools/bash-session.mjs +721 -0
  200. package/src/agent/orchestrator/tools/builtin/advisory-lock.mjs +171 -0
  201. package/src/agent/orchestrator/tools/builtin/arg-guard.mjs +455 -0
  202. package/src/agent/orchestrator/tools/builtin/atomic-write.mjs +236 -0
  203. package/src/agent/orchestrator/tools/builtin/bash-tool.mjs +480 -0
  204. package/src/agent/orchestrator/tools/builtin/binary-file.mjs +76 -0
  205. package/src/agent/orchestrator/tools/builtin/builtin-tools.mjs +256 -0
  206. package/src/agent/orchestrator/tools/builtin/cache-layers.mjs +386 -0
  207. package/src/agent/orchestrator/tools/builtin/cwd-utils.mjs +37 -0
  208. package/src/agent/orchestrator/tools/builtin/device-paths.mjs +154 -0
  209. package/src/agent/orchestrator/tools/builtin/diagnostics-tool.mjs +292 -0
  210. package/src/agent/orchestrator/tools/builtin/diff-utils.mjs +109 -0
  211. package/src/agent/orchestrator/tools/builtin/edit-base-guard.mjs +58 -0
  212. package/src/agent/orchestrator/tools/builtin/edit-byte-plan.mjs +240 -0
  213. package/src/agent/orchestrator/tools/builtin/edit-byte-utils.mjs +113 -0
  214. package/src/agent/orchestrator/tools/builtin/edit-commit.mjs +74 -0
  215. package/src/agent/orchestrator/tools/builtin/edit-context-utils.mjs +242 -0
  216. package/src/agent/orchestrator/tools/builtin/edit-diagnostics.mjs +211 -0
  217. package/src/agent/orchestrator/tools/builtin/edit-engine.mjs +1364 -0
  218. package/src/agent/orchestrator/tools/builtin/edit-failure-context.mjs +126 -0
  219. package/src/agent/orchestrator/tools/builtin/edit-hint.mjs +141 -0
  220. package/src/agent/orchestrator/tools/builtin/edit-match-utils.mjs +194 -0
  221. package/src/agent/orchestrator/tools/builtin/edit-partial-write.mjs +60 -0
  222. package/src/agent/orchestrator/tools/builtin/edit-stale-refresh.mjs +168 -0
  223. package/src/agent/orchestrator/tools/builtin/edit-tool.mjs +173 -0
  224. package/src/agent/orchestrator/tools/builtin/edit-utf8-guard.mjs +48 -0
  225. package/src/agent/orchestrator/tools/builtin/fs-reachability.mjs +48 -0
  226. package/src/agent/orchestrator/tools/builtin/fuzzy-match.mjs +99 -0
  227. package/src/agent/orchestrator/tools/builtin/glob-walk.mjs +170 -0
  228. package/src/agent/orchestrator/tools/builtin/grep-formatting.mjs +113 -0
  229. package/src/agent/orchestrator/tools/builtin/hash-utils.mjs +6 -0
  230. package/src/agent/orchestrator/tools/builtin/list-formatting.mjs +7 -0
  231. package/src/agent/orchestrator/tools/builtin/list-tool.mjs +593 -0
  232. package/src/agent/orchestrator/tools/builtin/native-edit-runner.mjs +89 -0
  233. package/src/agent/orchestrator/tools/builtin/notebook-edit-tool.mjs +300 -0
  234. package/src/agent/orchestrator/tools/builtin/open-config-tool.mjs +26 -0
  235. package/src/agent/orchestrator/tools/builtin/path-diagnostics.mjs +152 -0
  236. package/src/agent/orchestrator/tools/builtin/path-locks.mjs +35 -0
  237. package/src/agent/orchestrator/tools/builtin/path-utils.mjs +201 -0
  238. package/src/agent/orchestrator/tools/builtin/read-args.mjs +103 -0
  239. package/src/agent/orchestrator/tools/builtin/read-batch.mjs +172 -0
  240. package/src/agent/orchestrator/tools/builtin/read-constants.mjs +40 -0
  241. package/src/agent/orchestrator/tools/builtin/read-formatting.mjs +118 -0
  242. package/src/agent/orchestrator/tools/builtin/read-image-resize.mjs +189 -0
  243. package/src/agent/orchestrator/tools/builtin/read-image.mjs +88 -0
  244. package/src/agent/orchestrator/tools/builtin/read-lines.mjs +12 -0
  245. package/src/agent/orchestrator/tools/builtin/read-mode-tool.mjs +455 -0
  246. package/src/agent/orchestrator/tools/builtin/read-open.mjs +190 -0
  247. package/src/agent/orchestrator/tools/builtin/read-range-index.mjs +271 -0
  248. package/src/agent/orchestrator/tools/builtin/read-ranges.mjs +26 -0
  249. package/src/agent/orchestrator/tools/builtin/read-single-tool.mjs +728 -0
  250. package/src/agent/orchestrator/tools/builtin/read-snapshot-runtime.mjs +173 -0
  251. package/src/agent/orchestrator/tools/builtin/read-special-files.mjs +268 -0
  252. package/src/agent/orchestrator/tools/builtin/read-streaming.mjs +602 -0
  253. package/src/agent/orchestrator/tools/builtin/read-tool.mjs +530 -0
  254. package/src/agent/orchestrator/tools/builtin/read-windows.mjs +107 -0
  255. package/src/agent/orchestrator/tools/builtin/rename-tool.mjs +196 -0
  256. package/src/agent/orchestrator/tools/builtin/rg-runner.mjs +422 -0
  257. package/src/agent/orchestrator/tools/builtin/search-builders.mjs +158 -0
  258. package/src/agent/orchestrator/tools/builtin/search-tool.mjs +869 -0
  259. package/src/agent/orchestrator/tools/builtin/shell-analysis.mjs +653 -0
  260. package/src/agent/orchestrator/tools/builtin/shell-jobs.mjs +936 -0
  261. package/src/agent/orchestrator/tools/builtin/shell-output.mjs +36 -0
  262. package/src/agent/orchestrator/tools/builtin/shell-runtime.mjs +214 -0
  263. package/src/agent/orchestrator/tools/builtin/snapshot-helpers.mjs +143 -0
  264. package/src/agent/orchestrator/tools/builtin/snapshot-store.mjs +206 -0
  265. package/src/agent/orchestrator/tools/builtin/snapshot-validation.mjs +98 -0
  266. package/src/agent/orchestrator/tools/builtin/text-stats.mjs +69 -0
  267. package/src/agent/orchestrator/tools/builtin/windows-roots.mjs +23 -0
  268. package/src/agent/orchestrator/tools/builtin/write-tool.mjs +401 -0
  269. package/src/agent/orchestrator/tools/builtin.mjs +500 -0
  270. package/src/agent/orchestrator/tools/code-graph-prewarm-worker.mjs +39 -0
  271. package/src/agent/orchestrator/tools/code-graph-tool-defs.mjs +24 -0
  272. package/src/agent/orchestrator/tools/code-graph.mjs +4095 -0
  273. package/src/agent/orchestrator/tools/cwd-tool.mjs +298 -0
  274. package/src/agent/orchestrator/tools/destructive-warning.mjs +323 -0
  275. package/src/agent/orchestrator/tools/edit-normalize.mjs +603 -0
  276. package/src/agent/orchestrator/tools/env-scrub.mjs +100 -0
  277. package/src/agent/orchestrator/tools/graph-binary-fetcher.mjs +144 -0
  278. package/src/agent/orchestrator/tools/graph-manifest.json +26 -0
  279. package/src/agent/orchestrator/tools/host-input.mjs +204 -0
  280. package/src/agent/orchestrator/tools/mutation-content-cache.mjs +67 -0
  281. package/src/agent/orchestrator/tools/mutation-planner.mjs +75 -0
  282. package/src/agent/orchestrator/tools/next-call-utils.mjs +48 -0
  283. package/src/agent/orchestrator/tools/patch-binary-fetcher.mjs +133 -0
  284. package/src/agent/orchestrator/tools/patch-manifest.json +26 -0
  285. package/src/agent/orchestrator/tools/patch-tool-defs.mjs +20 -0
  286. package/src/agent/orchestrator/tools/patch.mjs +2754 -0
  287. package/src/agent/orchestrator/tools/progress-message.mjs +118 -0
  288. package/src/agent/orchestrator/tools/result-compression.mjs +279 -0
  289. package/src/agent/orchestrator/tools/shell-command.mjs +865 -0
  290. package/src/agent/orchestrator/tools/shell-exec-policy.mjs +89 -0
  291. package/src/agent/orchestrator/tools/shell-policy-danger-target.mjs +27 -0
  292. package/src/agent/orchestrator/tools/shell-policy-imports.mjs +7 -0
  293. package/src/agent/orchestrator/tools/shell-policy.mjs +345 -0
  294. package/src/agent/orchestrator/tools/shell-snapshot.mjs +313 -0
  295. package/src/agent/orchestrator/workflow-store.mjs +93 -0
  296. package/src/agent/tool-defs.mjs +103 -0
  297. package/src/channels/backends/discord.mjs +784 -0
  298. package/src/channels/data/voice-runtime-manifest.json +138 -0
  299. package/src/channels/index.mjs +3229 -0
  300. package/src/channels/lib/cli-worker-host.mjs +12 -0
  301. package/src/channels/lib/config-lock.mjs +13 -0
  302. package/src/channels/lib/config.mjs +292 -0
  303. package/src/channels/lib/drop-trace.mjs +71 -0
  304. package/src/channels/lib/event-pipeline.mjs +81 -0
  305. package/src/channels/lib/event-queue.mjs +345 -0
  306. package/src/channels/lib/executor.mjs +168 -0
  307. package/src/channels/lib/format.mjs +188 -0
  308. package/src/channels/lib/holidays.mjs +138 -0
  309. package/src/channels/lib/hook-pipe-server.mjs +802 -0
  310. package/src/channels/lib/interaction-workflows.mjs +184 -0
  311. package/src/channels/lib/memory-client.mjs +149 -0
  312. package/src/channels/lib/output-forwarder.mjs +765 -0
  313. package/src/channels/lib/runtime-paths.mjs +479 -0
  314. package/src/channels/lib/scheduler.mjs +723 -0
  315. package/src/channels/lib/session-control.mjs +36 -0
  316. package/src/channels/lib/session-discovery.mjs +103 -0
  317. package/src/channels/lib/settings.mjs +11 -0
  318. package/src/channels/lib/state-file.mjs +68 -0
  319. package/src/channels/lib/status-snapshot.mjs +219 -0
  320. package/src/channels/lib/tool-format.mjs +140 -0
  321. package/src/channels/lib/transcript-discovery.mjs +195 -0
  322. package/src/channels/lib/voice-runtime-fetcher.mjs +734 -0
  323. package/src/channels/lib/webhook.mjs +1179 -0
  324. package/src/channels/lib/whisper-server.mjs +477 -0
  325. package/src/channels/tool-defs.mjs +170 -0
  326. package/src/daemon/host.mjs +118 -0
  327. package/src/daemon/mcp-transport.mjs +47 -0
  328. package/src/daemon/session.mjs +100 -0
  329. package/src/daemon/thin-client.mjs +71 -0
  330. package/src/daemon/transport.mjs +163 -0
  331. package/src/memory/data/runtime-manifest.json +40 -0
  332. package/src/memory/index.mjs +3305 -0
  333. package/src/memory/lib/agent-ipc.mjs +93 -0
  334. package/src/memory/lib/bridge-trace-queries.mjs +120 -0
  335. package/src/memory/lib/core-memory-store.mjs +330 -0
  336. package/src/memory/lib/embedding-provider.mjs +269 -0
  337. package/src/memory/lib/embedding-worker.mjs +323 -0
  338. package/src/memory/lib/llm-worker-host.mjs +17 -0
  339. package/src/memory/lib/memory-cycle.mjs +11 -0
  340. package/src/memory/lib/memory-cycle1.mjs +641 -0
  341. package/src/memory/lib/memory-cycle2.mjs +1284 -0
  342. package/src/memory/lib/memory-cycle3.mjs +540 -0
  343. package/src/memory/lib/memory-embed.mjs +299 -0
  344. package/src/memory/lib/memory-extraction.mjs +5 -0
  345. package/src/memory/lib/memory-maintenance-store.mjs +32 -0
  346. package/src/memory/lib/memory-ops-policy.mjs +190 -0
  347. package/src/memory/lib/memory-recall-id-patch.mjs +15 -0
  348. package/src/memory/lib/memory-recall-read-query.mjs +7 -0
  349. package/src/memory/lib/memory-recall-scope-filter.mjs +63 -0
  350. package/src/memory/lib/memory-recall-store.mjs +621 -0
  351. package/src/memory/lib/memory-retrievers.mjs +112 -0
  352. package/src/memory/lib/memory-score.mjs +71 -0
  353. package/src/memory/lib/memory-text-utils.mjs +58 -0
  354. package/src/memory/lib/memory.mjs +412 -0
  355. package/src/memory/lib/model-profile.mjs +85 -0
  356. package/src/memory/lib/pg/adapter.mjs +308 -0
  357. package/src/memory/lib/pg/process.mjs +360 -0
  358. package/src/memory/lib/pg/supervisor.mjs +396 -0
  359. package/src/memory/lib/project-id-resolver.mjs +86 -0
  360. package/src/memory/lib/runtime-fetcher.mjs +442 -0
  361. package/src/memory/lib/trace-store.mjs +728 -0
  362. package/src/memory/tool-defs.mjs +79 -0
  363. package/src/search/index.mjs +1173 -0
  364. package/src/search/lib/backends/anthropic-oauth.mjs +98 -0
  365. package/src/search/lib/backends/exa.mjs +50 -0
  366. package/src/search/lib/backends/firecrawl.mjs +61 -0
  367. package/src/search/lib/backends/gemini-api.mjs +83 -0
  368. package/src/search/lib/backends/grok-oauth.mjs +86 -0
  369. package/src/search/lib/backends/index.mjs +150 -0
  370. package/src/search/lib/backends/openai-api.mjs +144 -0
  371. package/src/search/lib/backends/openai-oauth.mjs +98 -0
  372. package/src/search/lib/backends/openai-web-search.mjs +76 -0
  373. package/src/search/lib/backends/tavily.mjs +55 -0
  374. package/src/search/lib/backends/xai-api.mjs +113 -0
  375. package/src/search/lib/cache.mjs +131 -0
  376. package/src/search/lib/config.mjs +192 -0
  377. package/src/search/lib/formatter.mjs +115 -0
  378. package/src/search/lib/provider-usage.mjs +67 -0
  379. package/src/search/lib/providers.mjs +47 -0
  380. package/src/search/lib/search-intent.mjs +109 -0
  381. package/src/search/lib/setup-handler.mjs +261 -0
  382. package/src/search/lib/state.mjs +201 -0
  383. package/src/search/lib/web-tools.mjs +1207 -0
  384. package/src/search/tool-defs.mjs +83 -0
  385. package/src/setup/defender-exclusion.mjs +183 -0
  386. package/src/shared/abort-controller.mjs +15 -0
  387. package/src/shared/atomic-file.mjs +420 -0
  388. package/src/shared/config.mjs +350 -0
  389. package/src/shared/daemon-recycle.mjs +108 -0
  390. package/src/shared/disable-claude-builtins.mjs +88 -0
  391. package/src/shared/err-text.mjs +12 -0
  392. package/src/shared/llm/cost.mjs +66 -0
  393. package/src/shared/llm/http-agent.mjs +123 -0
  394. package/src/shared/llm/index.mjs +41 -0
  395. package/src/shared/llm/pid-cleanup.mjs +27 -0
  396. package/src/shared/llm/usage-log.mjs +47 -0
  397. package/src/shared/plugin-paths.mjs +58 -0
  398. package/src/shared/schedules-store.mjs +70 -0
  399. package/src/shared/seed.mjs +119 -0
  400. package/src/shared/user-cwd.mjs +213 -0
  401. package/src/shared/user-data-guard.mjs +238 -0
  402. package/src/status/aggregator.mjs +584 -0
  403. package/src/status/server.mjs +413 -0
  404. package/tools.json +1653 -0
@@ -0,0 +1,437 @@
1
+ import Anthropic from '@anthropic-ai/sdk';
2
+ import { loadConfig } from '../config.mjs';
3
+ import { sanitizeToolPairs, sanitizeAnthropicContentPairs } from '../session/trim.mjs';
4
+ import { withRetry } from './retry-classifier.mjs';
5
+ import { traceBridgeUsage } from '../bridge-trace.mjs';
6
+ import {
7
+ PROVIDER_FIRST_BYTE_TIMEOUT_MS,
8
+ PROVIDER_GENERATE_TOTAL_TIMEOUT_MS,
9
+ createTimeoutSignal,
10
+ } from '../stall-policy.mjs';
11
+ import { buildAnthropicBetaHeaders, supportsAnthropicFastMode } from './anthropic-betas.mjs';
12
+
13
+ // 4-BP cache policy aligned with anthropic-oauth — tools + system + tier3
14
+ // + messages-tail. 1h TTL requires the extended-cache-ttl beta header,
15
+ // which we set on the client via defaultHeaders below.
16
+ const CACHE_TTL_STABLE = { type: 'ephemeral', ttl: '1h' };
17
+ const CACHE_TTL_VOLATILE = { type: 'ephemeral' };
18
+
19
+ function withCacheControl(block, ttl = CACHE_TTL_VOLATILE) {
20
+ if (!block || typeof block !== 'object' || block.cache_control) return block;
21
+ return { ...block, cache_control: ttl };
22
+ }
23
+
24
+ function appendCacheControl(content, ttl = CACHE_TTL_VOLATILE) {
25
+ if (Array.isArray(content)) {
26
+ if (content.length === 0) return content;
27
+ const next = [...content];
28
+ next[next.length - 1] = withCacheControl(next[next.length - 1], ttl);
29
+ return next;
30
+ }
31
+ if (typeof content === 'string') {
32
+ return [withCacheControl({ type: 'text', text: content }, ttl)];
33
+ }
34
+ return content;
35
+ }
36
+
37
+ function collectRecentCacheableMessageIndexes(messages, availableSlots = 1) {
38
+ const slots = Math.max(0, Math.min(4, availableSlots));
39
+ const marked = new Set();
40
+ for (let i = messages.length - 1; i >= 0 && marked.size < slots; i--) {
41
+ if (messages[i]?.role !== 'system') marked.add(i);
42
+ }
43
+ return marked;
44
+ }
45
+
46
+ // Mirrors anthropic-oauth.mjs gate: only the explicitly-tagged sessionMarker
47
+ // claims a 1h BP3 slot. composeSystemPrompt prefixes sessionMarker with
48
+ // `<!-- bp3-sentinel -->`; volatileTail (also a `<system-reminder>` user
49
+ // message) deliberately omits the sentinel so it stays on the 5m tail.
50
+ const BP3_SENTINEL = '<!-- bp3-sentinel -->';
51
+
52
+ function findTier3Index(chatMsgs) {
53
+ for (let i = 0; i < chatMsgs.length; i++) {
54
+ const m = chatMsgs[i];
55
+ if (m?.role === 'user' && typeof m.content === 'string'
56
+ && m.content.startsWith('<system-reminder>')
57
+ && m.content.includes(BP3_SENTINEL)) {
58
+ return i;
59
+ }
60
+ }
61
+ return -1;
62
+ }
63
+
64
+ function resolveCacheTtls(opts) {
65
+ const strategy = opts?.cacheStrategy || {};
66
+ const pick = (layer, fallback) => {
67
+ const v = strategy[layer];
68
+ if (v === '1h') return CACHE_TTL_STABLE;
69
+ if (v === '5m') return CACHE_TTL_VOLATILE;
70
+ if (v === 'none') return null;
71
+ return fallback;
72
+ };
73
+ return {
74
+ tools: pick('tools', CACHE_TTL_STABLE),
75
+ system: pick('system', CACHE_TTL_STABLE),
76
+ tier3: pick('tier3', CACHE_TTL_STABLE),
77
+ messages: pick('messages', CACHE_TTL_VOLATILE),
78
+ };
79
+ }
80
+
81
+ const MODELS = [
82
+ { id: 'claude-opus-4-8', name: 'Claude Opus 4.8', provider: 'anthropic', contextWindow: 1000000 },
83
+ { id: 'claude-opus-4-7', name: 'Claude Opus 4.7', provider: 'anthropic', contextWindow: 1000000 },
84
+ { id: 'claude-opus-4-6', name: 'Claude Opus 4.6', provider: 'anthropic', contextWindow: 1000000 },
85
+ { id: 'claude-sonnet-4-6', name: 'Claude Sonnet 4.6', provider: 'anthropic', contextWindow: 1000000 },
86
+ { id: 'claude-haiku-4-5-20251001', name: 'Claude Haiku 4.5', provider: 'anthropic', contextWindow: 200000 },
87
+ ];
88
+ // Family-based heuristic so new model ids (including custom user-configured
89
+ // ones) resolve a sensible max_tokens without requiring a code change.
90
+ function resolveMaxTokens(model) {
91
+ const id = String(model || '').toLowerCase();
92
+ if (id.includes('opus')) return 32768;
93
+ if (id.includes('sonnet')) return 16384;
94
+ if (id.includes('haiku')) return 8192;
95
+ return 8192;
96
+ }
97
+
98
+ // Effort → thinking budget tokens (Anthropic extended thinking)
99
+ const EFFORT_BUDGET = {
100
+ low: 1024,
101
+ medium: 4096,
102
+ high: 16384,
103
+ max: 32768,
104
+ };
105
+ // Anthropic forbids oneOf / allOf / anyOf at the TOP level of input_schema.
106
+ // Mirror the same sanitizer as anthropic-oauth.mjs so both providers are safe.
107
+ function _sanitizeInputSchema(schema, toolName) {
108
+ if (!schema || typeof schema !== 'object') {
109
+ return { type: 'object', properties: {} };
110
+ }
111
+ const compound = schema.oneOf || schema.anyOf || schema.allOf;
112
+ if (!compound) return structuredClone(schema);
113
+ const mergedProps = {};
114
+ const branchDescs = [];
115
+ for (const branch of Array.isArray(compound) ? compound : []) {
116
+ if (branch && typeof branch === 'object' && branch.properties) {
117
+ Object.assign(mergedProps, branch.properties);
118
+ }
119
+ if (branch && typeof branch === 'object') {
120
+ const parts = [];
121
+ if (branch.description) parts.push(branch.description);
122
+ else if (branch.type) parts.push(`type:${branch.type}`);
123
+ if (parts.length) branchDescs.push(parts.join(' '));
124
+ }
125
+ }
126
+ const compoundKey = schema.oneOf ? 'oneOf' : schema.anyOf ? 'anyOf' : 'allOf';
127
+ let description = schema.description || '';
128
+ if (branchDescs.length) {
129
+ const parts = [];
130
+ let used = 0;
131
+ for (let i = 0; i < branchDescs.length; i++) {
132
+ const v = `(variant ${i + 1}: ${branchDescs[i]})`;
133
+ if (used + v.length + (parts.length ? 1 : 0) > 500) break;
134
+ parts.push(v);
135
+ used += v.length + (parts.length > 1 ? 1 : 0);
136
+ }
137
+ const addition = parts.join(' ');
138
+ if (addition) description = description ? `${description} ${addition}` : addition;
139
+ }
140
+ const mergedPropsCount = Object.keys(mergedProps).length;
141
+ process.stderr.write(
142
+ `[anthropic-sanitizer] tool="${toolName ?? ''}" compound="${compoundKey}" branches=${Array.isArray(compound) ? compound.length : 0} mergedProps=${mergedPropsCount}\n`
143
+ );
144
+ return {
145
+ type: 'object',
146
+ ...(description ? { description } : {}),
147
+ properties: mergedProps,
148
+ };
149
+ }
150
+
151
+ function toAnthropicTools(tools) {
152
+ return tools.map((t) => ({
153
+ name: t.name,
154
+ description: t.description,
155
+ input_schema: _sanitizeInputSchema(t.inputSchema, t.name),
156
+ }));
157
+ }
158
+ function toAnthropicMessages(
159
+ messages,
160
+ cacheableIndexes = new Set(),
161
+ messageTtl = CACHE_TTL_VOLATILE,
162
+ tier3Idx = -1,
163
+ tier3Ttl = null,
164
+ ) {
165
+ const applyMsgTtl = messageTtl || CACHE_TTL_VOLATILE;
166
+ const shouldCacheMsg = (idx) => messageTtl !== null && cacheableIndexes.has(idx);
167
+ const shouldCacheTier3 = (idx) => tier3Ttl !== null && idx === tier3Idx;
168
+ const pickTtl = (idx) => shouldCacheTier3(idx) ? tier3Ttl : applyMsgTtl;
169
+ const anyCache = (idx) => shouldCacheMsg(idx) || shouldCacheTier3(idx);
170
+
171
+ const result = [];
172
+ for (let idx = 0; idx < messages.length; idx++) {
173
+ const m = messages[idx];
174
+ if (m.role === 'system') continue;
175
+ if (m.role === 'assistant' && m.toolCalls?.length) {
176
+ let content = [];
177
+ if (m.content) content.push({ type: 'text', text: m.content });
178
+ for (const tc of m.toolCalls) {
179
+ content.push({
180
+ type: 'tool_use',
181
+ id: tc.id,
182
+ name: tc.name,
183
+ input: tc.arguments,
184
+ });
185
+ }
186
+ if (anyCache(idx)) content = appendCacheControl(content, pickTtl(idx));
187
+ result.push({ role: 'assistant', content });
188
+ continue;
189
+ }
190
+ if (m.role === 'tool') {
191
+ const last = result[result.length - 1];
192
+ const block = {
193
+ type: 'tool_result',
194
+ tool_use_id: m.toolCallId || '',
195
+ content: m.content,
196
+ };
197
+ if (last?.role === 'user' && Array.isArray(last.content)) {
198
+ last.content.push(block);
199
+ if (anyCache(idx)) {
200
+ last.content = appendCacheControl(last.content, pickTtl(idx));
201
+ }
202
+ }
203
+ else {
204
+ let content = [block];
205
+ if (anyCache(idx)) content = appendCacheControl(content, pickTtl(idx));
206
+ result.push({ role: 'user', content });
207
+ }
208
+ continue;
209
+ }
210
+ const content = anyCache(idx)
211
+ ? appendCacheControl(m.content, pickTtl(idx))
212
+ : m.content;
213
+ result.push({ role: m.role, content });
214
+ }
215
+ return sanitizeAnthropicContentPairs(result);
216
+ }
217
+ function parseToolCalls(response) {
218
+ const blocks = response.content.filter((b) => b.type === 'tool_use');
219
+ if (!blocks.length)
220
+ return undefined;
221
+ return blocks.map((b) => ({
222
+ id: b.id,
223
+ name: b.name,
224
+ arguments: (b.input ?? {}),
225
+ }));
226
+ }
227
+ export class AnthropicProvider {
228
+ // Anthropic reports usage.input_tokens EXCLUDING cache_read/cache_creation
229
+ // (those are separate fields), so the live context-window footprint must
230
+ // add cache_read back. See providerInputExcludesCache() in registry.mjs.
231
+ static inputExcludesCache = true;
232
+ name = 'anthropic';
233
+ client;
234
+ config;
235
+ fastModeBetaHeaderLatched = false;
236
+ constructor(config) {
237
+ this.config = config;
238
+ this.client = new Anthropic({
239
+ apiKey: config.apiKey || process.env.ANTHROPIC_API_KEY,
240
+ defaultHeaders: { 'anthropic-beta': buildAnthropicBetaHeaders() },
241
+ });
242
+ }
243
+ reloadApiKey() {
244
+ try {
245
+ const freshConfig = loadConfig();
246
+ const cfg = freshConfig.providers?.anthropic;
247
+ const newKey = cfg?.apiKey || process.env.ANTHROPIC_API_KEY;
248
+ if (newKey) {
249
+ this.client = new Anthropic({
250
+ apiKey: newKey,
251
+ defaultHeaders: { 'anthropic-beta': buildAnthropicBetaHeaders() },
252
+ });
253
+ }
254
+ } catch { /* best effort */ }
255
+ }
256
+ async send(messages, model, tools, sendOpts) {
257
+ // Defense-in-depth: enforce tool_use / tool_result pairing before
258
+ // the Anthropic API call. Mirror of the OAuth path; loop.mjs only
259
+ // runs sanitizeToolPairs when budget is exceeded, so an under-budget
260
+ // dispatch with an aborted-mid-flight tool_use would otherwise hit
261
+ // the provider as a hard 400 (`tool_use ids ... without tool_result`).
262
+ messages = sanitizeToolPairs(messages);
263
+ try {
264
+ return await this._doSend(messages, model, tools, sendOpts);
265
+ } catch (err) {
266
+ if (err.message && (err.message.includes('401') || err.message.includes('403'))) {
267
+ process.stderr.write(`[provider] Auth error, re-reading config...\n`);
268
+ this.reloadApiKey();
269
+ return await this._doSend(messages, model, tools, sendOpts);
270
+ }
271
+ throw err;
272
+ }
273
+ }
274
+ async _doSend(messages, model, tools, sendOpts) {
275
+ if (!model) throw new Error('[anthropic] model is required — pass it from the caller preset');
276
+ const useModel = model;
277
+ const maxTokens = resolveMaxTokens(useModel);
278
+ const opts = sendOpts || {};
279
+ const ttls = resolveCacheTtls(opts);
280
+
281
+ const systemMsgs = messages.filter(m => m.role === 'system');
282
+ const chatMsgs = messages.filter(m => m.role !== 'system');
283
+ const systemText = systemMsgs.map(m => m.content).join('\n\n') || undefined;
284
+
285
+ // 4-BP budget: aligned with anthropic-oauth. tools BP is dropped —
286
+ // system BP covers the tools prefix via Anthropic prefix semantics
287
+ // (order: tools → system → messages). That frees 1 slot for
288
+ // messages-tail.
289
+ const toolsBpUsed = 0;
290
+ const systemBpUsed = ttls.system && systemText ? 1 : 0;
291
+ const tier3Idx = ttls.tier3 ? findTier3Index(chatMsgs) : -1;
292
+ const tier3BpUsed = tier3Idx >= 0 ? 1 : 0;
293
+ const usedSlots = toolsBpUsed + systemBpUsed + tier3BpUsed;
294
+ const msgSlots = ttls.messages ? Math.max(0, 4 - usedSlots) : 0;
295
+ const cacheableIndexes = collectRecentCacheableMessageIndexes(chatMsgs, msgSlots);
296
+ if (tier3Idx >= 0) cacheableIndexes.delete(tier3Idx);
297
+
298
+ const anthropicMessages = toAnthropicMessages(
299
+ chatMsgs,
300
+ cacheableIndexes,
301
+ ttls.messages,
302
+ tier3Idx,
303
+ ttls.tier3,
304
+ );
305
+
306
+ const params = {
307
+ model: useModel,
308
+ max_tokens: maxTokens,
309
+ system: systemText
310
+ ? [ttls.system
311
+ ? { type: 'text', text: systemText, cache_control: ttls.system }
312
+ : { type: 'text', text: systemText }]
313
+ : undefined,
314
+ messages: anthropicMessages,
315
+ };
316
+ if (tools?.length) {
317
+ // No cache_control on tools — the system BP covers tools via
318
+ // Anthropic prefix semantics (order: tools → system → messages).
319
+ params.tools = toAnthropicTools(tools);
320
+ }
321
+ // Effort → extended thinking budget
322
+ if (opts.effort && EFFORT_BUDGET[opts.effort]) {
323
+ params.thinking = { type: 'enabled', budget_tokens: EFFORT_BUDGET[opts.effort] };
324
+ }
325
+ // Fast mode → speed: "fast" on models Anthropic marks as speed-capable.
326
+ if (opts.fast === true && supportsAnthropicFastMode(useModel)) {
327
+ params.speed = 'fast';
328
+ this.fastModeBetaHeaderLatched = true;
329
+ }
330
+ const totalSignal = createTimeoutSignal(opts.signal || null, PROVIDER_GENERATE_TOTAL_TIMEOUT_MS, 'Anthropic total');
331
+ params.messages = sanitizeAnthropicContentPairs(params.messages);
332
+ // Wrap the SDK call in shared retry — surfaces "overloaded" / 5xx
333
+ // through populateHttpStatusFromMessage and retries up to 5 times
334
+ // with exponential backoff. The Anthropic SDK throws errors with
335
+ // .status set on HTTP responses; the classifier picks that up too.
336
+ let response;
337
+ try {
338
+ response = await withRetry(
339
+ ({ signal: attemptSignal }) => this.client.messages.create(params, {
340
+ signal: attemptSignal,
341
+ headers: {
342
+ 'anthropic-beta': buildAnthropicBetaHeaders({
343
+ fastMode: this.fastModeBetaHeaderLatched,
344
+ }),
345
+ },
346
+ }),
347
+ {
348
+ signal: totalSignal.signal,
349
+ perAttemptTimeoutMs: PROVIDER_FIRST_BYTE_TIMEOUT_MS,
350
+ perAttemptLabel: 'Anthropic first byte',
351
+ onRetry: ({ attempt, lastErr, delayMs, delayReason }) => {
352
+ const delayLabel = Number.isFinite(Number(delayMs)) ? `, delay ${delayMs}ms${delayReason ? ` (${delayReason})` : ''}` : '';
353
+ process.stderr.write(`[anthropic] retry attempt ${attempt + 1} after ${lastErr?.message || lastErr?.code || 'transient error'}${delayLabel}\n`);
354
+ },
355
+ },
356
+ );
357
+ } finally {
358
+ totalSignal.cleanup();
359
+ }
360
+ const textBlock = response.content.find(b => b.type === 'text');
361
+ const toolCalls = parseToolCalls(response);
362
+ // Mirror anthropic-oauth SSE parser: classify the assistant turn by
363
+ // content-block presence so the orchestrator can distinguish a
364
+ // synthesis-stalled "thinking-only" turn (no text, no tool_use)
365
+ // from a silent empty response. Track block types and a quick
366
+ // hasThinkingContent flag from response.content directly since the
367
+ // non-streaming SDK call exposes the final block list.
368
+ let hasThinkingContent = false;
369
+ const contentBlockTypes = new Set();
370
+ for (const block of Array.isArray(response.content) ? response.content : []) {
371
+ if (block?.type) contentBlockTypes.add(block.type);
372
+ if (block?.type === 'thinking' || block?.type === 'redacted_thinking') {
373
+ hasThinkingContent = true;
374
+ }
375
+ }
376
+ const usageRaw = response.usage || null;
377
+ if (usageRaw) {
378
+ const input = usageRaw.input_tokens || 0;
379
+ const cacheRead = usageRaw.cache_read_input_tokens || 0;
380
+ const cacheWrite = usageRaw.cache_creation_input_tokens || 0;
381
+ traceBridgeUsage({
382
+ sessionId: opts.sessionId || opts.session?.id || null,
383
+ iteration: Number.isFinite(Number(opts.iteration)) ? Number(opts.iteration) : null,
384
+ inputTokens: input,
385
+ outputTokens: usageRaw.output_tokens || 0,
386
+ cachedTokens: cacheRead,
387
+ cacheWriteTokens: cacheWrite,
388
+ promptTokens: input + cacheRead + cacheWrite,
389
+ model: response.model,
390
+ modelDisplay: response.model,
391
+ responseId: response.id || null,
392
+ rawUsage: usageRaw,
393
+ provider: 'anthropic',
394
+ });
395
+ }
396
+ return {
397
+ content: textBlock?.type === 'text' ? textBlock.text : '',
398
+ model: response.model,
399
+ toolCalls,
400
+ stopReason: response.stop_reason || null,
401
+ hasThinkingContent,
402
+ contentBlockTypes: Array.from(contentBlockTypes),
403
+ usage: (() => {
404
+ const input = response.usage.input_tokens || 0;
405
+ const cacheRead = response.usage.cache_read_input_tokens || 0;
406
+ const cacheWrite = response.usage.cache_creation_input_tokens || 0;
407
+ return {
408
+ inputTokens: input,
409
+ outputTokens: response.usage.output_tokens || 0,
410
+ cachedTokens: cacheRead,
411
+ cacheWriteTokens: cacheWrite,
412
+ // Unified prompt volume — what the model actually ingested,
413
+ // regardless of cache splitting. Anthropic reports input
414
+ // uncached-only; sum the three billable slots so the
415
+ // cross-provider `promptTokens` field has consistent meaning.
416
+ promptTokens: input + cacheRead + cacheWrite,
417
+ };
418
+ })(),
419
+ };
420
+ }
421
+ async listModels() {
422
+ return MODELS;
423
+ }
424
+ async isAvailable() {
425
+ try {
426
+ await this.client.messages.create({
427
+ model: 'claude-haiku-4-5-20251001',
428
+ max_tokens: 1,
429
+ messages: [{ role: 'user', content: 'hi' }],
430
+ });
431
+ return true;
432
+ }
433
+ catch {
434
+ return false;
435
+ }
436
+ }
437
+ }