mixdog 0.9.2 → 0.9.4

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 (417) hide show
  1. package/package.json +8 -3
  2. package/scripts/anthropic-maxtokens-test.mjs +119 -0
  3. package/scripts/bench/lead-review-tasks-r3.json +20 -0
  4. package/scripts/bench/lead-review-tasks.json +20 -0
  5. package/scripts/bench/r4-mixed-tasks.json +20 -0
  6. package/scripts/bench/review-tasks.json +20 -0
  7. package/scripts/bench/round-codex.json +114 -0
  8. package/scripts/bench/round-mixdog-lead-r3.json +269 -0
  9. package/scripts/bench/round-mixdog-lead.json +269 -0
  10. package/scripts/bench/round-mixdog.json +126 -0
  11. package/scripts/bench/round-r10-bigsample.json +679 -0
  12. package/scripts/bench/round-r11-codexalign.json +257 -0
  13. package/scripts/bench/round-r4-codex.json +114 -0
  14. package/scripts/bench/round-r4-mixed.json +225 -0
  15. package/scripts/bench/round-r5-gpt-lead.json +259 -0
  16. package/scripts/bench/round-r6-codex.json +114 -0
  17. package/scripts/bench/round-r6-solo.json +257 -0
  18. package/scripts/bench/round-r7-full.json +254 -0
  19. package/scripts/bench/round-r8-fulldefault.json +255 -0
  20. package/scripts/bench-run.mjs +215 -29
  21. package/scripts/build-tui.mjs +13 -1
  22. package/scripts/explore-bench.mjs +124 -0
  23. package/scripts/freevar-smoke.mjs +95 -0
  24. package/scripts/hook-bus-test.mjs +191 -0
  25. package/scripts/internal-comms-bench.mjs +1 -0
  26. package/scripts/internal-comms-smoke.mjs +10 -9
  27. package/scripts/mouse-probe.mjs +45 -0
  28. package/scripts/output-style-bench.mjs +13 -6
  29. package/scripts/output-style-smoke.mjs +4 -4
  30. package/scripts/path-suffix-test.mjs +57 -0
  31. package/scripts/provider-toolcall-test.mjs +7 -3
  32. package/scripts/recall-bench.mjs +207 -0
  33. package/scripts/recall-usecase-cases.json +18 -0
  34. package/scripts/recall-usecase-probe.json +6 -0
  35. package/scripts/session-bench.mjs +152 -6
  36. package/scripts/tool-smoke.mjs +30 -67
  37. package/scripts/tui-render-smoke.mjs +90 -0
  38. package/scripts/webhook-smoke.mjs +208 -0
  39. package/src/agents/debugger/AGENT.md +5 -2
  40. package/src/agents/heavy-worker/AGENT.md +21 -11
  41. package/src/agents/maintainer/AGENT.md +4 -0
  42. package/src/agents/reviewer/AGENT.md +3 -2
  43. package/src/agents/worker/AGENT.md +21 -11
  44. package/src/lib/rules-builder.cjs +4 -0
  45. package/src/mixdog-session-runtime.mjs +933 -3731
  46. package/src/output-styles/default.md +34 -9
  47. package/src/output-styles/{oneline.md → extreme-minimal.md} +5 -4
  48. package/src/output-styles/minimal.md +4 -1
  49. package/src/output-styles/simple.md +22 -7
  50. package/src/repl.mjs +5 -5
  51. package/src/rules/agent/00-common.md +2 -0
  52. package/src/rules/agent/30-explorer.md +8 -11
  53. package/src/rules/lead/lead-brief.md +12 -0
  54. package/src/rules/lead/lead-tool.md +2 -9
  55. package/src/rules/shared/01-tool.md +11 -5
  56. package/src/runtime/agent/orchestrator/agent-runtime/agent-loop-policy.mjs +25 -0
  57. package/src/runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs +100 -23
  58. package/src/runtime/agent/orchestrator/agent-runtime/session-builder.mjs +6 -15
  59. package/src/runtime/agent/orchestrator/agent-trace-format.mjs +362 -0
  60. package/src/runtime/agent/orchestrator/agent-trace-io.mjs +410 -0
  61. package/src/runtime/agent/orchestrator/agent-trace.mjs +16 -735
  62. package/src/runtime/agent/orchestrator/config.mjs +69 -2
  63. package/src/runtime/agent/orchestrator/context/collect.mjs +51 -0
  64. package/src/runtime/agent/orchestrator/mcp/client.mjs +6 -2
  65. package/src/runtime/agent/orchestrator/providers/anthropic-effort.mjs +63 -21
  66. package/src/runtime/agent/orchestrator/providers/anthropic-max-tokens.mjs +93 -0
  67. package/src/runtime/agent/orchestrator/providers/anthropic-model-resolve.mjs +209 -0
  68. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-credentials.mjs +489 -0
  69. package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +97 -1343
  70. package/src/runtime/agent/orchestrator/providers/anthropic-sse.mjs +607 -0
  71. package/src/runtime/agent/orchestrator/providers/anthropic.mjs +78 -10
  72. package/src/runtime/agent/orchestrator/providers/api-usage.mjs +1 -13
  73. package/src/runtime/agent/orchestrator/providers/codex-client-meta.mjs +81 -0
  74. package/src/runtime/agent/orchestrator/providers/gemini-cache.mjs +248 -0
  75. package/src/runtime/agent/orchestrator/providers/gemini-schema.mjs +303 -0
  76. package/src/runtime/agent/orchestrator/providers/gemini-stream.mjs +505 -0
  77. package/src/runtime/agent/orchestrator/providers/gemini.mjs +44 -1014
  78. package/src/runtime/agent/orchestrator/providers/grok-oauth.mjs +18 -4
  79. package/src/runtime/agent/orchestrator/providers/lib/usage-primitives.mjs +32 -0
  80. package/src/runtime/agent/orchestrator/providers/model-catalog.mjs +86 -11
  81. package/src/runtime/agent/orchestrator/providers/model-list-sanitize.mjs +348 -0
  82. package/src/runtime/agent/orchestrator/providers/oauth-usage.mjs +54 -20
  83. package/src/runtime/agent/orchestrator/providers/openai-codex-model.mjs +108 -0
  84. package/src/runtime/agent/orchestrator/providers/openai-compat-stream.mjs +19 -12
  85. package/src/runtime/agent/orchestrator/providers/openai-compat-trace.mjs +58 -0
  86. package/src/runtime/agent/orchestrator/providers/openai-compat-wire.mjs +368 -0
  87. package/src/runtime/agent/orchestrator/providers/openai-compat-xai.mjs +760 -0
  88. package/src/runtime/agent/orchestrator/providers/openai-compat.mjs +41 -1142
  89. package/src/runtime/agent/orchestrator/providers/openai-oauth-http-sse.mjs +732 -0
  90. package/src/runtime/agent/orchestrator/providers/openai-oauth-login.mjs +193 -0
  91. package/src/runtime/agent/orchestrator/providers/openai-oauth-ws.mjs +303 -2119
  92. package/src/runtime/agent/orchestrator/providers/openai-oauth.mjs +140 -995
  93. package/src/runtime/agent/orchestrator/providers/openai-ws-delta.mjs +227 -0
  94. package/src/runtime/agent/orchestrator/providers/openai-ws-events.mjs +67 -0
  95. package/src/runtime/agent/orchestrator/providers/openai-ws-pool.mjs +436 -0
  96. package/src/runtime/agent/orchestrator/providers/openai-ws-stream.mjs +1105 -0
  97. package/src/runtime/agent/orchestrator/providers/openai-ws.mjs +2 -1
  98. package/src/runtime/agent/orchestrator/providers/opencode-go-usage.mjs +38 -12
  99. package/src/runtime/agent/orchestrator/providers/retry-classifier.mjs +7 -8
  100. package/src/runtime/agent/orchestrator/session/compact/budget.mjs +288 -0
  101. package/src/runtime/agent/orchestrator/session/compact/constants.mjs +85 -0
  102. package/src/runtime/agent/orchestrator/session/compact/engine.mjs +749 -0
  103. package/src/runtime/agent/orchestrator/session/compact/messages.mjs +82 -0
  104. package/src/runtime/agent/orchestrator/session/compact/summary-schema.mjs +315 -0
  105. package/src/runtime/agent/orchestrator/session/compact/summary.mjs +643 -0
  106. package/src/runtime/agent/orchestrator/session/compact/text-utils.mjs +326 -0
  107. package/src/runtime/agent/orchestrator/session/compact.mjs +40 -2282
  108. package/src/runtime/agent/orchestrator/session/loop/compact-debug.mjs +28 -0
  109. package/src/runtime/agent/orchestrator/session/loop/compact-policy.mjs +274 -0
  110. package/src/runtime/agent/orchestrator/session/loop/completion-guards.mjs +61 -0
  111. package/src/runtime/agent/orchestrator/session/loop/context-overflow.mjs +38 -0
  112. package/src/runtime/agent/orchestrator/session/loop/env.mjs +14 -0
  113. package/src/runtime/agent/orchestrator/session/loop/hidden-agents.mjs +21 -0
  114. package/src/runtime/agent/orchestrator/session/loop/pre-dispatch-deny.mjs +47 -0
  115. package/src/runtime/agent/orchestrator/session/loop/recall-fasttrack.mjs +182 -0
  116. package/src/runtime/agent/orchestrator/session/loop/steering-ladder.mjs +173 -0
  117. package/src/runtime/agent/orchestrator/session/loop/steering.mjs +63 -0
  118. package/src/runtime/agent/orchestrator/session/loop/stored-tool-args.mjs +100 -0
  119. package/src/runtime/agent/orchestrator/session/loop/termination.mjs +58 -0
  120. package/src/runtime/agent/orchestrator/session/loop/tool-classify.mjs +52 -0
  121. package/src/runtime/agent/orchestrator/session/loop/tool-exec.mjs +239 -0
  122. package/src/runtime/agent/orchestrator/session/loop/tool-helpers.mjs +218 -0
  123. package/src/runtime/agent/orchestrator/session/loop/transcript-repair.mjs +101 -0
  124. package/src/runtime/agent/orchestrator/session/loop/usage.mjs +35 -0
  125. package/src/runtime/agent/orchestrator/session/loop.mjs +409 -1304
  126. package/src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs +471 -0
  127. package/src/runtime/agent/orchestrator/session/manager/context-meta.mjs +230 -0
  128. package/src/runtime/agent/orchestrator/session/manager/pending-messages.mjs +235 -0
  129. package/src/runtime/agent/orchestrator/session/manager/prompt-utils.mjs +149 -0
  130. package/src/runtime/agent/orchestrator/session/manager/rules-cache.mjs +155 -0
  131. package/src/runtime/agent/orchestrator/session/manager/runtime-liveness.mjs +406 -0
  132. package/src/runtime/agent/orchestrator/session/manager/status-telemetry.mjs +80 -0
  133. package/src/runtime/agent/orchestrator/session/manager/tool-resolution.mjs +303 -0
  134. package/src/runtime/agent/orchestrator/session/manager/usage-metrics.mjs +210 -0
  135. package/src/runtime/agent/orchestrator/session/manager.mjs +226 -2114
  136. package/src/runtime/agent/orchestrator/session/store-summary-index.mjs +189 -0
  137. package/src/runtime/agent/orchestrator/session/store.mjs +74 -179
  138. package/src/runtime/agent/orchestrator/stall-policy.mjs +3 -3
  139. package/src/runtime/agent/orchestrator/tools/builtin/arg-guard.mjs +70 -20
  140. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +22 -2
  141. package/src/runtime/agent/orchestrator/tools/builtin/builtin-tools.mjs +33 -42
  142. package/src/runtime/agent/orchestrator/tools/builtin/external-tool-adapters.mjs +241 -0
  143. package/src/runtime/agent/orchestrator/tools/builtin/fuzzy-match.mjs +1 -1
  144. package/src/runtime/agent/orchestrator/tools/builtin/list-tool.mjs +40 -0
  145. package/src/runtime/agent/orchestrator/tools/builtin/path-diagnostics.mjs +42 -2
  146. package/src/runtime/agent/orchestrator/tools/builtin/read-formatting.mjs +1 -1
  147. package/src/runtime/agent/orchestrator/tools/builtin/read-single-tool.mjs +11 -4
  148. package/src/runtime/agent/orchestrator/tools/builtin/rg-runner.mjs +29 -0
  149. package/src/runtime/agent/orchestrator/tools/builtin/search-builders.mjs +8 -0
  150. package/src/runtime/agent/orchestrator/tools/builtin/search-path-diagnostics.mjs +126 -0
  151. package/src/runtime/agent/orchestrator/tools/builtin/search-tool.mjs +81 -87
  152. package/src/runtime/agent/orchestrator/tools/builtin/shell-job-paths.mjs +161 -0
  153. package/src/runtime/agent/orchestrator/tools/builtin/shell-job-process.mjs +108 -0
  154. package/src/runtime/agent/orchestrator/tools/builtin/shell-jobs.mjs +78 -304
  155. package/src/runtime/agent/orchestrator/tools/builtin.mjs +11 -6
  156. package/src/runtime/agent/orchestrator/tools/code-graph/build.mjs +303 -0
  157. package/src/runtime/agent/orchestrator/tools/code-graph/constants.mjs +43 -0
  158. package/src/runtime/agent/orchestrator/tools/code-graph/disk-cache.mjs +382 -0
  159. package/src/runtime/agent/orchestrator/tools/code-graph/dispatch.mjs +551 -0
  160. package/src/runtime/agent/orchestrator/tools/code-graph/graph-binary.mjs +295 -0
  161. package/src/runtime/agent/orchestrator/tools/code-graph/graph-model.mjs +158 -0
  162. package/src/runtime/agent/orchestrator/tools/code-graph/keyword-match.mjs +82 -0
  163. package/src/runtime/agent/orchestrator/tools/code-graph/lang-predicates.mjs +128 -0
  164. package/src/runtime/agent/orchestrator/tools/code-graph/memory-cache.mjs +66 -0
  165. package/src/runtime/agent/orchestrator/tools/code-graph/project-root.mjs +44 -0
  166. package/src/runtime/agent/orchestrator/tools/code-graph/search.mjs +1080 -0
  167. package/src/runtime/agent/orchestrator/tools/code-graph/source-access.mjs +81 -0
  168. package/src/runtime/agent/orchestrator/tools/code-graph/span.mjs +19 -0
  169. package/src/runtime/agent/orchestrator/tools/code-graph/symbol-index.mjs +280 -0
  170. package/src/runtime/agent/orchestrator/tools/code-graph/text-columns.mjs +45 -0
  171. package/src/runtime/agent/orchestrator/tools/code-graph/text-mask.mjs +347 -0
  172. package/src/runtime/agent/orchestrator/tools/code-graph-tool-defs.mjs +6 -6
  173. package/src/runtime/agent/orchestrator/tools/code-graph.mjs +36 -4277
  174. package/src/runtime/agent/orchestrator/tools/graph-binary-fetcher.mjs +6 -3
  175. package/src/runtime/agent/orchestrator/tools/patch/constants.mjs +9 -0
  176. package/src/runtime/agent/orchestrator/tools/patch/dispatch.mjs +171 -0
  177. package/src/runtime/agent/orchestrator/tools/patch/matcher.mjs +471 -0
  178. package/src/runtime/agent/orchestrator/tools/patch/native-server.mjs +436 -0
  179. package/src/runtime/agent/orchestrator/tools/patch/orchestrator.mjs +342 -0
  180. package/src/runtime/agent/orchestrator/tools/patch/parsing.mjs +359 -0
  181. package/src/runtime/agent/orchestrator/tools/patch/paths.mjs +340 -0
  182. package/src/runtime/agent/orchestrator/tools/patch/v4a-convert.mjs +643 -0
  183. package/src/runtime/agent/orchestrator/tools/patch.mjs +36 -2959
  184. package/src/runtime/agent/orchestrator/tools/progress-message.mjs +1 -23
  185. package/src/runtime/agent/orchestrator/tools/shell-command.mjs +10 -74
  186. package/src/runtime/agent/orchestrator/tools/shell-powershell.mjs +77 -0
  187. package/src/runtime/agent/orchestrator/tools/shell-snapshot.mjs +2 -4
  188. package/src/runtime/agent/orchestrator/tools/shell-state.mjs +154 -0
  189. package/src/runtime/channels/backends/discord-access.mjs +32 -0
  190. package/src/runtime/channels/backends/discord-attachments.mjs +65 -0
  191. package/src/runtime/channels/backends/discord-gateway.mjs +233 -0
  192. package/src/runtime/channels/backends/discord.mjs +12 -292
  193. package/src/runtime/channels/index.mjs +241 -894
  194. package/src/runtime/channels/lib/backend-dispatch.mjs +44 -0
  195. package/src/runtime/channels/lib/boot-profile.mjs +23 -0
  196. package/src/runtime/channels/lib/crash-log.mjs +106 -0
  197. package/src/runtime/channels/lib/event-pipeline.mjs +18 -1
  198. package/src/runtime/channels/lib/event-queue.mjs +63 -4
  199. package/src/runtime/channels/lib/inbound-routing.mjs +111 -0
  200. package/src/runtime/channels/lib/index-drop-trace.mjs +72 -0
  201. package/src/runtime/channels/lib/output-forwarder.mjs +9 -1
  202. package/src/runtime/channels/lib/owner-heartbeat.mjs +75 -0
  203. package/src/runtime/channels/lib/parent-bridge.mjs +88 -0
  204. package/src/runtime/channels/lib/runtime-paths.mjs +14 -4
  205. package/src/runtime/channels/lib/session-discovery.mjs +56 -4
  206. package/src/runtime/channels/lib/telegram-format.mjs +19 -22
  207. package/src/runtime/channels/lib/tool-dispatch.mjs +158 -0
  208. package/src/runtime/channels/lib/tool-format.mjs +1 -1
  209. package/src/runtime/channels/lib/transcript-discovery.mjs +4 -4
  210. package/src/runtime/channels/lib/voice-runtime-fetcher.mjs +6 -3
  211. package/src/runtime/channels/lib/voice-transcription.mjs +179 -0
  212. package/src/runtime/channels/lib/webhook/deliveries.mjs +312 -0
  213. package/src/runtime/channels/lib/webhook/log.mjs +42 -0
  214. package/src/runtime/channels/lib/webhook/ngrok.mjs +181 -0
  215. package/src/runtime/channels/lib/webhook/signature.mjs +60 -0
  216. package/src/runtime/channels/lib/webhook.mjs +36 -570
  217. package/src/runtime/channels/lib/whisper-language.mjs +42 -0
  218. package/src/runtime/channels/tool-defs.mjs +11 -130
  219. package/src/runtime/memory/index.mjs +258 -2050
  220. package/src/runtime/memory/lib/core-memory-store.mjs +351 -1
  221. package/src/runtime/memory/lib/cycle-llm-adapters.mjs +58 -0
  222. package/src/runtime/memory/lib/cycle-scheduler.mjs +497 -0
  223. package/src/runtime/memory/lib/cycle-signatures.mjs +34 -0
  224. package/src/runtime/memory/lib/embedding-warmup.mjs +58 -0
  225. package/src/runtime/memory/lib/http-wire.mjs +57 -0
  226. package/src/runtime/memory/lib/memory-config-flags.mjs +91 -0
  227. package/src/runtime/memory/lib/memory-cycle.mjs +1 -1
  228. package/src/runtime/memory/lib/memory-cycle2-gate.mjs +515 -0
  229. package/src/runtime/memory/lib/memory-cycle2-mutations.mjs +324 -0
  230. package/src/runtime/memory/lib/memory-cycle2-shared.mjs +18 -0
  231. package/src/runtime/memory/lib/memory-cycle2.mjs +72 -837
  232. package/src/runtime/memory/lib/memory-embed.mjs +149 -0
  233. package/src/runtime/memory/lib/memory-process-lock.mjs +162 -0
  234. package/src/runtime/memory/lib/memory-recall-scope-filter.mjs +24 -0
  235. package/src/runtime/memory/lib/memory-recall-store.mjs +22 -2
  236. package/src/runtime/memory/lib/memory-retrievers.mjs +8 -0
  237. package/src/runtime/memory/lib/memory.mjs +20 -0
  238. package/src/runtime/memory/lib/pg/supervisor.mjs +1 -1
  239. package/src/runtime/memory/lib/promotion-fingerprint.mjs +50 -0
  240. package/src/runtime/memory/lib/query-handlers.mjs +780 -0
  241. package/src/runtime/memory/lib/recall-format.mjs +238 -0
  242. package/src/runtime/memory/lib/runtime-fetcher.mjs +8 -3
  243. package/src/runtime/memory/lib/transcript-ingest.mjs +425 -0
  244. package/src/runtime/memory/tool-defs.mjs +6 -14
  245. package/src/runtime/search/lib/http-fetch.mjs +274 -0
  246. package/src/runtime/search/lib/ssrf-guard.mjs +333 -0
  247. package/src/runtime/search/lib/web-tools.mjs +24 -602
  248. package/src/runtime/shared/abort-controller.mjs +1 -1
  249. package/src/runtime/shared/atomic-file.mjs +26 -1
  250. package/src/runtime/shared/background-tasks.mjs +2 -3
  251. package/src/runtime/shared/buffered-appender.mjs +149 -0
  252. package/src/runtime/shared/launcher-control.mjs +2 -2
  253. package/src/runtime/shared/task-notification-envelope.mjs +98 -0
  254. package/src/runtime/shared/tool-execution-contract.mjs +2 -2
  255. package/src/runtime/shared/tool-primitives.mjs +308 -0
  256. package/src/runtime/shared/tool-result-summary.mjs +515 -0
  257. package/src/runtime/shared/tool-surface.mjs +80 -898
  258. package/src/runtime/shared/transcript-writer.mjs +52 -2
  259. package/src/runtime/shared/update-checker.mjs +7 -4
  260. package/src/session-runtime/config-helpers.mjs +291 -0
  261. package/src/session-runtime/config-lifecycle.mjs +232 -0
  262. package/src/session-runtime/cwd-plugins.mjs +226 -0
  263. package/src/session-runtime/effort.mjs +128 -0
  264. package/src/session-runtime/fs-utils.mjs +10 -0
  265. package/src/session-runtime/mcp-glue.mjs +177 -0
  266. package/src/session-runtime/model-capabilities.mjs +130 -0
  267. package/src/session-runtime/model-recency.mjs +111 -0
  268. package/src/session-runtime/native-search.mjs +247 -0
  269. package/src/session-runtime/output-styles.mjs +126 -0
  270. package/src/session-runtime/plugin-mcp.mjs +114 -0
  271. package/src/session-runtime/prewarm.mjs +142 -0
  272. package/src/session-runtime/provider-models.mjs +278 -0
  273. package/src/session-runtime/provider-usage.mjs +120 -0
  274. package/src/session-runtime/quick-model-rows.mjs +170 -0
  275. package/src/session-runtime/quick-search-models.mjs +46 -0
  276. package/src/session-runtime/session-hooks.mjs +93 -0
  277. package/src/session-runtime/session-text.mjs +100 -0
  278. package/src/session-runtime/settings-api.mjs +319 -0
  279. package/src/session-runtime/statusline-route.mjs +35 -0
  280. package/src/session-runtime/tool-catalog.mjs +720 -0
  281. package/src/session-runtime/tool-defs.mjs +84 -0
  282. package/src/session-runtime/warmup-schedulers.mjs +201 -0
  283. package/src/session-runtime/workflow.mjs +358 -0
  284. package/src/standalone/agent-tool/helpers.mjs +237 -0
  285. package/src/standalone/agent-tool/notify.mjs +107 -0
  286. package/src/standalone/agent-tool/provider-init.mjs +143 -0
  287. package/src/standalone/agent-tool/render.mjs +152 -0
  288. package/src/standalone/agent-tool/tool-def.mjs +55 -0
  289. package/src/standalone/agent-tool.mjs +155 -677
  290. package/src/standalone/channel-worker.mjs +7 -9
  291. package/src/standalone/explore-tool.mjs +40 -12
  292. package/src/standalone/hook-bus/config.mjs +207 -0
  293. package/src/standalone/hook-bus/constants.mjs +90 -0
  294. package/src/standalone/hook-bus/handlers.mjs +481 -0
  295. package/src/standalone/hook-bus/payload.mjs +31 -0
  296. package/src/standalone/hook-bus/rules.mjs +77 -0
  297. package/src/standalone/hook-bus.mjs +110 -746
  298. package/src/standalone/memory-runtime-proxy.mjs +7 -0
  299. package/src/standalone/opencode-go-login.mjs +125 -0
  300. package/src/standalone/provider-admin.mjs +15 -19
  301. package/src/standalone/usage-dashboard.mjs +3 -1
  302. package/src/tui/App.jsx +1163 -7571
  303. package/src/tui/app/app-format.mjs +206 -0
  304. package/src/tui/app/channel-pickers.mjs +510 -0
  305. package/src/tui/app/clipboard.mjs +67 -0
  306. package/src/tui/app/core-memory-picker.mjs +210 -0
  307. package/src/tui/app/extension-pickers.mjs +506 -0
  308. package/src/tui/app/input-parsers.mjs +193 -0
  309. package/src/tui/app/maintenance-pickers.mjs +324 -0
  310. package/src/tui/app/model-options.mjs +330 -0
  311. package/src/tui/app/model-picker.mjs +365 -0
  312. package/src/tui/app/onboarding-steps.mjs +400 -0
  313. package/src/tui/app/project-picker.mjs +247 -0
  314. package/src/tui/app/provider-setup-picker.mjs +580 -0
  315. package/src/tui/app/resume-picker.mjs +55 -0
  316. package/src/tui/app/route-pickers.mjs +419 -0
  317. package/src/tui/app/settings-picker.mjs +490 -0
  318. package/src/tui/app/slash-commands.mjs +101 -0
  319. package/src/tui/app/slash-dispatch.mjs +427 -0
  320. package/src/tui/app/text-layout.mjs +46 -0
  321. package/src/tui/app/theme-effort-pickers.mjs +154 -0
  322. package/src/tui/app/transcript-window.mjs +671 -0
  323. package/src/tui/app/use-mouse-input.mjs +460 -0
  324. package/src/tui/app/use-prompt-handlers.mjs +310 -0
  325. package/src/tui/app/use-transcript-scroll.mjs +510 -0
  326. package/src/tui/app/use-transcript-window.mjs +589 -0
  327. package/src/tui/components/ConfirmBar.jsx +1 -1
  328. package/src/tui/components/Picker.jsx +32 -4
  329. package/src/tui/components/PromptInput.jsx +259 -80
  330. package/src/tui/components/SlashCommandPalette.jsx +8 -1
  331. package/src/tui/components/StatusLine.jsx +63 -12
  332. package/src/tui/components/TextEntryPanel.jsx +11 -0
  333. package/src/tui/components/ToolExecution.jsx +56 -588
  334. package/src/tui/components/TranscriptItem.jsx +105 -0
  335. package/src/tui/components/UsagePanel.jsx +18 -4
  336. package/src/tui/components/prompt-input/edit-helpers.mjs +72 -0
  337. package/src/tui/components/prompt-input/voice-indicator.mjs +39 -0
  338. package/src/tui/components/tool-execution/ResultBody.jsx +56 -0
  339. package/src/tui/components/tool-execution/surface-detail.mjs +405 -0
  340. package/src/tui/components/tool-execution/text-format.mjs +161 -0
  341. package/src/tui/components/tool-output-format.mjs +2 -2
  342. package/src/tui/display-width.mjs +20 -3
  343. package/src/tui/dist/index.mjs +18034 -17188
  344. package/src/tui/engine/agent-envelope.mjs +296 -0
  345. package/src/tui/engine/agent-job-feed.mjs +133 -0
  346. package/src/tui/engine/boot-profile.mjs +21 -0
  347. package/src/tui/engine/labels.mjs +67 -0
  348. package/src/tui/engine/notice-text.mjs +112 -0
  349. package/src/tui/engine/notification-plan.mjs +76 -0
  350. package/src/tui/engine/queue-helpers.mjs +161 -0
  351. package/src/tui/engine/render-timing.mjs +17 -0
  352. package/src/tui/engine/session-stats.mjs +46 -0
  353. package/src/tui/engine/tool-approval.mjs +94 -0
  354. package/src/tui/engine/tool-call-fields.mjs +23 -0
  355. package/src/tui/engine/tool-card-results.mjs +234 -0
  356. package/src/tui/engine/tool-result-status.mjs +135 -0
  357. package/src/tui/engine/tool-result-text.mjs +126 -0
  358. package/src/tui/engine.mjs +405 -1385
  359. package/src/tui/figures.mjs +5 -0
  360. package/src/tui/index.jsx +105 -0
  361. package/src/tui/input-editing.mjs +60 -10
  362. package/src/tui/keyboard-protocol.mjs +2 -2
  363. package/src/tui/lib/voice-recorder.mjs +35 -19
  364. package/src/tui/markdown/format-token.mjs +11 -9
  365. package/src/tui/paste-attachments.mjs +38 -0
  366. package/src/tui/statusline-ansi-bridge.mjs +11 -3
  367. package/src/tui/theme.mjs +6 -0
  368. package/src/tui/themes/base.mjs +2 -2
  369. package/src/tui/themes/kanagawa.mjs +4 -4
  370. package/src/tui/themes/teal.mjs +4 -5
  371. package/src/tui/themes/utils.mjs +1 -1
  372. package/src/ui/statusline-agents.mjs +213 -0
  373. package/src/ui/statusline-format.mjs +146 -0
  374. package/src/ui/statusline-segments.mjs +148 -0
  375. package/src/ui/statusline.mjs +77 -462
  376. package/src/ui/tool-card.mjs +0 -1
  377. package/src/vendor/statusline/bin/statusline-route.mjs +15 -2
  378. package/src/workflows/default/WORKFLOW.md +16 -9
  379. package/src/workflows/sequential/WORKFLOW.md +16 -11
  380. package/src/workflows/solo/WORKFLOW.md +5 -1
  381. package/vendor/ink/build/display-width.js +19 -3
  382. package/vendor/ink/build/ink.js +103 -6
  383. package/vendor/ink/build/log-update.js +17 -3
  384. package/vendor/ink/build/wrap-text.js +125 -0
  385. package/scripts/_test-folder-dialog.mjs +0 -30
  386. package/scripts/fix-brief-fn.mjs +0 -35
  387. package/scripts/fix-format-tool-surface.mjs +0 -24
  388. package/scripts/fix-tool-exec-visible.mjs +0 -42
  389. package/scripts/patch-agent-brief.mjs +0 -48
  390. package/scripts/patch-app.mjs +0 -21
  391. package/scripts/patch-app2.mjs +0 -18
  392. package/scripts/patch-dist-brief.mjs +0 -96
  393. package/scripts/patch-tool-exec.mjs +0 -70
  394. package/src/examples/schedules/SCHEDULE.example.md +0 -32
  395. package/src/examples/webhooks/WEBHOOK.example.md +0 -40
  396. package/src/runtime/agent/orchestrator/session/manager.reactive-persist.test.mjs +0 -107
  397. package/src/runtime/agent/orchestrator/tools/builtin/arg-guard.test.mjs +0 -143
  398. package/src/runtime/agent/orchestrator/tools/builtin/diagnostics-tool.mjs +0 -285
  399. package/src/runtime/agent/orchestrator/tools/builtin/open-config-tool.mjs +0 -26
  400. package/src/runtime/shared/channel-notification-routing.test.mjs +0 -45
  401. package/src/runtime/shared/tool-execution-contract.test.mjs +0 -183
  402. package/src/standalone/agent-task-status.test.mjs +0 -76
  403. package/src/tui/components/tool-output-format.test.mjs +0 -399
  404. package/src/tui/display-width.test.mjs +0 -35
  405. package/src/tui/engine-runtime-notification.test.mjs +0 -115
  406. package/src/tui/engine-tool-result-text.test.mjs +0 -75
  407. package/src/tui/markdown/format-token.test.mjs +0 -354
  408. package/src/tui/markdown/render-ansi.test.mjs +0 -108
  409. package/src/tui/markdown/stream-fence.test.mjs +0 -26
  410. package/src/tui/markdown/streaming-markdown.test.mjs +0 -70
  411. package/src/tui/prompt-history-store.test.mjs +0 -52
  412. package/src/tui/statusline-ansi-bridge.test.mjs +0 -159
  413. package/src/tui/transcript-tool-failures.test.mjs +0 -111
  414. package/src/ui/markdown.test.mjs +0 -70
  415. package/src/ui/statusline-context-label.test.mjs +0 -15
  416. package/src/vendor/statusline/bin/statusline-lib.mjs +0 -186
  417. package/src/vendor/statusline/bin/statusline-route.test.mjs +0 -80
@@ -6,6 +6,7 @@ import { join } from 'path';
6
6
  import { updateJsonAtomicSync } from '../../../shared/atomic-file.mjs';
7
7
  import { resolvePluginData } from '../../../shared/plugin-paths.mjs';
8
8
  import { getLlmDispatcher } from '../../../shared/llm/http-agent.mjs';
9
+ import { num, round, cleanString } from './lib/usage-primitives.mjs';
9
10
 
10
11
  const CACHE_FILE = 'gateway-oauth-usage-cache.json';
11
12
  const LIVE_CACHE_TTL_MS = 60_000;
@@ -21,24 +22,6 @@ const lastWarnAt = new Map();
21
22
  let pendingDiskSnapshots = new Map();
22
23
  let pendingDiskFlushTimer = null;
23
24
 
24
- function num(value, fallback = null) {
25
- if (value === null || value === undefined || value === '') return fallback;
26
- const n = Number(value);
27
- return Number.isFinite(n) ? n : fallback;
28
- }
29
-
30
- function round(value, digits = 4) {
31
- const n = Number(value);
32
- if (!Number.isFinite(n)) return null;
33
- const scale = 10 ** digits;
34
- return Math.round(n * scale) / scale;
35
- }
36
-
37
- function cleanString(value) {
38
- const s = typeof value === 'string' ? value.trim() : '';
39
- return s || null;
40
- }
41
-
42
25
  function providerKey(routeInfo = {}) {
43
26
  return String(routeInfo?.provider || '').toLowerCase();
44
27
  }
@@ -301,7 +284,7 @@ function balanceFromCredits(credits, source) {
301
284
  }
302
285
 
303
286
  function balanceFromExtraUsage(extra) {
304
- if (!extra || typeof extra !== 'object' || extra.is_enabled !== true) return null;
287
+ if (!extra || typeof extra !== 'object') return null;
305
288
  const limit = num(extra.monthly_limit, null);
306
289
  const used = num(extra.used_credits, 0);
307
290
  if (limit === null) return null;
@@ -315,6 +298,57 @@ function balanceFromExtraUsage(extra) {
315
298
  };
316
299
  }
317
300
 
301
+ function balanceFromAnthropicSpend(spend) {
302
+ if (!spend || typeof spend !== 'object') return null;
303
+ const currency = cleanString(spend.used?.currency ?? spend.limit?.currency) || 'USD';
304
+ // spend.balance may be a plain number or a {amount_minor, exponent} money
305
+ // object like used/limit; support both shapes.
306
+ const directBalance = spend.balance && typeof spend.balance === 'object'
307
+ ? (() => {
308
+ const minor = num(spend.balance.amount_minor, null);
309
+ return minor === null ? null : minor / (10 ** num(spend.balance.exponent, 2));
310
+ })()
311
+ : num(spend.balance, null);
312
+ if (directBalance !== null) {
313
+ return {
314
+ source: 'anthropic-oauth-spend',
315
+ remainingUsd: round(directBalance, 4),
316
+ spentUsd: round(num(spend.used?.amount_minor, 0) / (10 ** num(spend.used?.exponent, 2)), 4),
317
+ currency,
318
+ };
319
+ }
320
+
321
+ const usedMinor = num(spend.used?.amount_minor, null);
322
+ const usedExponent = num(spend.used?.exponent, 2);
323
+ const usedUsd = usedMinor === null ? null : usedMinor / (10 ** usedExponent);
324
+
325
+ const capMinor = num(spend.cap?.credits?.amount_minor, null);
326
+ if (capMinor !== null && usedUsd !== null) {
327
+ const capExponent = num(spend.cap?.credits?.exponent, 2);
328
+ const capUsd = capMinor / (10 ** capExponent);
329
+ return {
330
+ source: 'anthropic-oauth-spend',
331
+ remainingUsd: round(Math.max(0, capUsd - usedUsd), 4),
332
+ spentUsd: round(usedUsd, 4),
333
+ currency,
334
+ };
335
+ }
336
+
337
+ const limitMinor = num(spend.limit?.amount_minor, null);
338
+ if (limitMinor !== null && limitMinor > 0 && usedUsd !== null) {
339
+ const limitExponent = num(spend.limit?.exponent, 2);
340
+ const limitUsd = limitMinor / (10 ** limitExponent);
341
+ return {
342
+ source: 'anthropic-oauth-spend',
343
+ remainingUsd: round(Math.max(0, limitUsd - usedUsd), 4),
344
+ spentUsd: round(usedUsd, 4),
345
+ currency,
346
+ };
347
+ }
348
+
349
+ return null;
350
+ }
351
+
318
352
  function normalizeOpenAIWhamUsage(data) {
319
353
  const rate = data?.rate_limit && typeof data.rate_limit === 'object' ? data.rate_limit : null;
320
354
  if (!rate) return null;
@@ -388,7 +422,7 @@ function normalizeAnthropicUsage(data, source = 'anthropic-oauth') {
388
422
  provider: 'anthropic-oauth',
389
423
  source,
390
424
  quotaWindows: windows,
391
- balance: balanceFromExtraUsage(data.extra_usage),
425
+ balance: balanceFromAnthropicSpend(data.spend) || balanceFromExtraUsage(data.extra_usage),
392
426
  rawKeys: Object.keys(data || {}).sort(),
393
427
  };
394
428
  }
@@ -0,0 +1,108 @@
1
+ /**
2
+ * OpenAI Codex OAuth model-catalog transforms.
3
+ *
4
+ * Extracted from openai-oauth.mjs: pure catalog helpers — API-shape
5
+ * normalization, family classification, version comparison, and the
6
+ * per-family "latest" pass. No module state; openai-oauth.mjs re-exports
7
+ * _displayCodexModel for existing importers.
8
+ */
9
+
10
+ // OAuth catalog returns dated ids (gpt-5.4-mini-2026-03-17). Strip the trailing
11
+ // -YYYY-MM-DD to get the version alias (gpt-5.4-mini). Unknown shapes pass
12
+ // through unchanged.
13
+ export function _displayCodexModel(id) {
14
+ if (!id || typeof id !== 'string') return id;
15
+ return id.replace(/-\d{4}-\d{2}-\d{2}$/, '');
16
+ }
17
+
18
+ function _positiveCodexContextWindow(value) {
19
+ const n = Number(value);
20
+ return Number.isFinite(n) && n > 0 ? Math.floor(n) : null;
21
+ }
22
+
23
+ function _codexContextWindowFromApi(m) {
24
+ return _positiveCodexContextWindow(m?.context_window)
25
+ || _positiveCodexContextWindow(m?.max_context_window)
26
+ || null;
27
+ }
28
+
29
+ export function _codexFamily(id) {
30
+ const s = String(id || '').toLowerCase();
31
+ if (s.includes('nano')) return 'gpt-nano';
32
+ if (s.includes('mini')) return 'gpt-mini';
33
+ if (s.includes('codex')) return 'gpt-codex';
34
+ if (s.startsWith('gpt-5.5')) return 'gpt-5.5';
35
+ if (s.startsWith('gpt-5.4')) return 'gpt-5.4';
36
+ if (s.startsWith('gpt-5.2')) return 'gpt-5.2';
37
+ if (s.startsWith('gpt-5')) return 'gpt-5';
38
+ return 'gpt';
39
+ }
40
+
41
+ export function _normalizeCodexModel(m) {
42
+ const id = m?.slug || m?.id;
43
+ const family = _codexFamily(id);
44
+ const serviceTiers = Array.isArray(m?.service_tiers)
45
+ ? m.service_tiers
46
+ .map(t => ({
47
+ id: String(t?.id || '').trim(),
48
+ name: String(t?.name || '').trim(),
49
+ description: String(t?.description || '').trim(),
50
+ }))
51
+ .filter(t => t.id)
52
+ : [];
53
+ const additionalSpeedTiers = Array.isArray(m?.additional_speed_tiers)
54
+ ? m.additional_speed_tiers.map(t => String(t || '').trim()).filter(Boolean)
55
+ : [];
56
+ // Catalog ids are version aliases without separate display dating.
57
+ return {
58
+ id,
59
+ name: m?.display_name || id,
60
+ display: m?.display_name || id,
61
+ family,
62
+ provider: 'openai-oauth',
63
+ contextWindow: _codexContextWindowFromApi(m),
64
+ maxContextWindow: _positiveCodexContextWindow(m?.max_context_window),
65
+ outputTokens: m?.max_output_tokens || m?.output_tokens || 32768,
66
+ autoCompactTokenLimit: m?.auto_compact_token_limit || null,
67
+ effectiveContextWindowPercent: m?.effective_context_window_percent || null,
68
+ tier: 'version',
69
+ latest: false,
70
+ description: m?.description || '',
71
+ reasoningLevels: (m?.supported_reasoning_levels || []).map(r => r.effort),
72
+ serviceTiers,
73
+ defaultServiceTier: m?.default_service_tier || null,
74
+ additionalSpeedTiers,
75
+ };
76
+ }
77
+
78
+ // Compare two model ids by the X.Y version embedded in `gpt-X.Y`. Mirrors
79
+ // anthropic-oauth's _compareVersion; these ids have no trailing date so
80
+ // the version lives in the dotted number, not a -YYYY-MM-DD suffix.
81
+ export function _compareVersion(a, b) {
82
+ const na = (String(a).match(/gpt-(\d+)\.(\d+)/) || []).slice(1).map(Number);
83
+ const nb = (String(b).match(/gpt-(\d+)\.(\d+)/) || []).slice(1).map(Number);
84
+ for (let i = 0; i < Math.max(na.length, nb.length); i++) {
85
+ if ((na[i] || 0) !== (nb[i] || 0)) return (na[i] || 0) - (nb[i] || 0);
86
+ }
87
+ return String(a).localeCompare(String(b));
88
+ }
89
+
90
+ // Main gpt-5 chat family only: exclude the mini/nano/codex variants so "latest"
91
+ // resolves to the flagship, not a smaller sibling.
92
+ export function _isMainCodexFamily(family) {
93
+ return typeof family === 'string' && family.startsWith('gpt-5');
94
+ }
95
+
96
+ // Mark the highest-version model per family as `latest: true`. VERSION-based
97
+ // (ids carry no `created`), mirroring anthropic-oauth's per-family pass.
98
+ export function _markLatestCodex(models) {
99
+ const byFamily = new Map();
100
+ for (const m of models) {
101
+ if (!m?.id) continue;
102
+ const cur = byFamily.get(m.family);
103
+ if (!cur || _compareVersion(m.id, cur.id) > 0) {
104
+ byFamily.set(m.family, m);
105
+ }
106
+ }
107
+ for (const m of byFamily.values()) m.latest = true;
108
+ }
@@ -31,8 +31,7 @@ function truncatedCompatStreamError(label, detail) {
31
31
  );
32
32
  }
33
33
 
34
- // Invalid-tool-args marker. Native-provider convergence (openai-oauth /
35
- // opencode): completed-but-malformed tool_call arguments JSON must NOT throw
34
+ // Invalid-tool-args marker: completed-but-malformed tool_call arguments JSON must NOT throw
36
35
  // (kills the turn) NOR be silently swallowed to `{}`. Instead the parse
37
36
  // failure is carried as data on the tool call's `arguments` slot so the
38
37
  // dispatch loop can turn it into an is_error tool_result and let the model
@@ -49,8 +48,7 @@ export function isInvalidToolArgsMarker(value) {
49
48
  return !!value && typeof value === 'object' && value.__invalidToolArgs === true;
50
49
  }
51
50
  /** Model-facing tool_result text for a tool call whose arguments failed to
52
- * parse. Mirrors opencode `The arguments provided to the tool are invalid` and
53
- * `failed to parse function arguments` — instructs an in-turn retry. */
51
+ * parse; instructs the model to retry with valid JSON in the same turn. */
54
52
  export function formatInvalidToolArgsResult(call) {
55
53
  const name = call?.name || 'tool';
56
54
  const detail = call?.arguments?.__parseError || 'arguments were not valid JSON';
@@ -85,9 +83,9 @@ export function parseCompletedToolCallArgumentsJson(raw, label, meta) {
85
83
  // Invariant: a completion/finish signal was observed for this tool call
86
84
  // (finish_reason present, or a per-call/response "done" event fired), so
87
85
  // the arguments are NOT mid-stream-truncated — they are complete but
88
- // malformed. Native convergence: return an invalid-args MARKER (not a
89
- // throw) so the dispatch loop feeds the parse error back to the model as
90
- // a tool_result and the model self-corrects in the same turn. Only an
86
+ // malformed. Return an invalid-args MARKER (not a throw) so the
87
+ // dispatch loop feeds the parse error back to the model as a
88
+ // tool_result and the model self-corrects in the same turn. Only an
91
89
  // unfinished stream (no finishReason) stays the retryable truncation
92
90
  // case — that transient behavior is deliberately preserved.
93
91
  if (meta?.finishReason) {
@@ -406,7 +404,7 @@ export async function consumeCompatChatCompletionStream(stream, { signal, label,
406
404
  } catch (err) {
407
405
  // Any mid-stream failure after live text was relayed is non-retryable.
408
406
  if (emittedText) throw markErrorLiveTextEmitted(err);
409
- // Partial-final recovery parity: on a mid-stream stall, attach the
407
+ // Partial-final recovery: on a mid-stream stall, attach the
410
408
  // streamed partial state so the loop can accept a wedged FINAL no-tool
411
409
  // summary as partial-final success. pendingToolUse gates out any
412
410
  // in-flight/emitted tool call.
@@ -488,12 +486,15 @@ function handleCompatResponsesStreamEvent(event, state, { label, parseResponsesT
488
486
  if (!item || item.type !== 'tool_search_call') return;
489
487
  const callId = item.call_id || item.id || '';
490
488
  if (!callId || state.toolCalls.some((call) => call.id === callId)) return;
489
+ const _tsArgs = item.arguments && typeof item.arguments === 'object' && !Array.isArray(item.arguments)
490
+ ? item.arguments
491
+ : parseCompletedToolCallArgumentsJson(item.arguments || '{}', label, { id: callId, name: 'tool_search', finishReason: 'done' });
491
492
  const call = {
492
493
  id: callId,
493
494
  name: 'tool_search',
494
- arguments: item.arguments && typeof item.arguments === 'object'
495
- ? item.arguments
496
- : parseCompletedToolCallArgumentsJson(item.arguments || '{}', label, { id: callId, name: 'tool_search', finishReason: 'done' }),
495
+ // Schema is a plain object ({query,select,limit}); an array must
496
+ // never pass through as args.
497
+ arguments: (_tsArgs && typeof _tsArgs === 'object' && !Array.isArray(_tsArgs)) ? _tsArgs : {},
497
498
  nativeType: 'tool_search_call',
498
499
  };
499
500
  state.toolCalls.push(call);
@@ -533,6 +534,12 @@ function handleCompatResponsesStreamEvent(event, state, { label, parseResponsesT
533
534
  state.toolInFlight = true;
534
535
  } else if (event.item?.type === 'custom_tool_call') {
535
536
  state.toolInFlight = true;
537
+ } else if (event.item?.type === 'tool_search_call') {
538
+ // Mark tool_search in-flight at item-added time, same as
539
+ // function_call/custom_tool_call above, so the stall-recovery
540
+ // pendingToolUse gate never drops a mid-flight tool_search
541
+ // before response.output_item.done pushes it.
542
+ state.toolInFlight = true;
536
543
  }
537
544
  try { onStreamDelta?.(); } catch {}
538
545
  break;
@@ -766,7 +773,7 @@ export async function consumeCompatResponsesStream(stream, {
766
773
  }
767
774
  flushLeak();
768
775
  } catch (err) {
769
- // Partial-final recovery parity: attach streamed partial state so a
776
+ // Partial-final recovery: attach streamed partial state so a
770
777
  // wedged FINAL no-tool summary can be accepted as partial-final success.
771
778
  if (err?.streamStalled === true) {
772
779
  try {
@@ -0,0 +1,58 @@
1
+ /**
2
+ * openai-compat-trace.mjs — shared trace/token helpers for the OpenAI-compat
3
+ * provider family.
4
+ *
5
+ * Extracted from openai-compat.mjs. Holds the two low-level helpers
6
+ * (summarizeTraceMessages, extractCompatCachedTokens) consumed by both
7
+ * openai-compat.mjs and openai-compat-xai.mjs cache-trace writers. Isolating
8
+ * them here breaks the former import cycle between those two modules.
9
+ */
10
+ import { traceHash, stableTraceStringify, traceTextShape } from './trace-utils.mjs';
11
+
12
+ export function summarizeTraceMessages(messages) {
13
+ const summaries = (messages || []).map((m, index) => {
14
+ const content = typeof m?.content === 'string'
15
+ ? { type: 'text', ...traceTextShape(m.content) }
16
+ : { type: m?.content == null ? 'null' : typeof m.content, hash: traceHash(stableTraceStringify(m?.content ?? null)) };
17
+ const toolCalls = Array.isArray(m?.tool_calls)
18
+ ? m.tool_calls.map(tc => ({
19
+ name: tc?.function?.name || null,
20
+ argsHash: traceHash(tc?.function?.arguments || ''),
21
+ }))
22
+ : [];
23
+ return {
24
+ index,
25
+ role: m?.role || null,
26
+ content,
27
+ ...(typeof m?.reasoning_content === 'string'
28
+ ? { reasoningContent: traceTextShape(m.reasoning_content) }
29
+ : {}),
30
+ toolCallCount: toolCalls.length,
31
+ ...(toolCalls.length ? { toolCalls } : {}),
32
+ };
33
+ });
34
+ if (summaries.length <= 12) return summaries;
35
+ return [
36
+ ...summaries.slice(0, 8),
37
+ { omittedTurns: summaries.length - 12 },
38
+ ...summaries.slice(-4),
39
+ ];
40
+ }
41
+
42
+ export function extractCompatCachedTokens(usage) {
43
+ const candidates = [
44
+ usage?.prompt_tokens_details?.cached_tokens,
45
+ usage?.input_tokens_details?.cached_tokens,
46
+ usage?.prompt_cache_hit_tokens,
47
+ usage?.cached_prompt_text_tokens,
48
+ ];
49
+ for (const v of candidates) {
50
+ const n = Number(v);
51
+ if (Number.isFinite(n) && n > 0) return n;
52
+ }
53
+ for (const v of candidates) {
54
+ const n = Number(v);
55
+ if (Number.isFinite(n)) return n;
56
+ }
57
+ return 0;
58
+ }