muonroi-cli 1.8.3 → 1.8.5

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 (477) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +133 -122
  3. package/dist/packages/agent-harness-core/src/driver.d.ts +27 -1
  4. package/dist/packages/agent-harness-core/src/driver.js +46 -0
  5. package/dist/packages/agent-harness-core/src/event-tee.d.ts +48 -0
  6. package/dist/packages/agent-harness-core/src/event-tee.js +77 -0
  7. package/dist/packages/agent-harness-core/src/mcp-server.d.ts +11 -0
  8. package/dist/packages/agent-harness-core/src/mcp-server.js +87 -15
  9. package/dist/packages/agent-harness-core/src/protocol.d.ts +66 -2
  10. package/dist/packages/agent-harness-core/src/protocol.js +15 -0
  11. package/dist/packages/agent-harness-core/src/visual-quality.d.ts +58 -0
  12. package/dist/packages/agent-harness-core/src/visual-quality.js +141 -0
  13. package/dist/packages/agent-harness-opentui/src/agent-mode.d.ts +6 -0
  14. package/dist/packages/agent-harness-opentui/src/agent-mode.js +14 -1
  15. package/dist/packages/agent-harness-opentui/src/input-bridge.d.ts +2 -10
  16. package/dist/packages/agent-harness-opentui/src/input-bridge.js +103 -16
  17. package/dist/packages/agent-harness-opentui/src/install.d.ts +8 -0
  18. package/dist/packages/agent-harness-opentui/src/install.js +10 -0
  19. package/dist/packages/agent-harness-opentui/src/semantic.js +12 -10
  20. package/dist/packages/agent-harness-opentui/src/visual-capture.d.ts +56 -0
  21. package/dist/packages/agent-harness-opentui/src/visual-capture.js +103 -0
  22. package/dist/src/agent-harness/mock-model.d.ts +28 -0
  23. package/dist/src/agent-harness/mock-model.js +63 -1
  24. package/dist/src/agent-harness/test-spawn.js +31 -0
  25. package/dist/src/cli/config/screen-providers.js +1 -1
  26. package/dist/src/cli/cost-forensics.d.ts +10 -0
  27. package/dist/src/cli/cost-forensics.js +30 -15
  28. package/dist/src/cli/keys-bundle.d.ts +1 -1
  29. package/dist/src/cli/keys-bundle.js +1 -1
  30. package/dist/src/cli/keys.d.ts +2 -2
  31. package/dist/src/cli/keys.js +19 -81
  32. package/dist/src/council/clarifier.d.ts +28 -2
  33. package/dist/src/council/clarifier.js +81 -15
  34. package/dist/src/council/context.js +49 -15
  35. package/dist/src/council/debate-checkpoint.d.ts +129 -0
  36. package/dist/src/council/debate-checkpoint.js +176 -0
  37. package/dist/src/council/debate-planner.js +51 -3
  38. package/dist/src/council/debate-summary.d.ts +25 -0
  39. package/dist/src/council/debate-summary.js +85 -0
  40. package/dist/src/council/debate.d.ts +169 -2
  41. package/dist/src/council/debate.js +1210 -134
  42. package/dist/src/council/index.d.ts +85 -1
  43. package/dist/src/council/index.js +634 -196
  44. package/dist/src/council/leader.d.ts +26 -0
  45. package/dist/src/council/leader.js +150 -9
  46. package/dist/src/council/llm.d.ts +32 -0
  47. package/dist/src/council/llm.js +231 -38
  48. package/dist/src/council/panel-select.d.ts +30 -0
  49. package/dist/src/council/panel-select.js +72 -0
  50. package/dist/src/council/planner.js +23 -0
  51. package/dist/src/council/preflight.d.ts +7 -0
  52. package/dist/src/council/preflight.js +14 -2
  53. package/dist/src/council/prompts.d.ts +30 -3
  54. package/dist/src/council/prompts.js +254 -84
  55. package/dist/src/council/stance-recall.d.ts +42 -0
  56. package/dist/src/council/stance-recall.js +57 -0
  57. package/dist/src/council/strip-think.d.ts +17 -0
  58. package/dist/src/council/strip-think.js +33 -0
  59. package/dist/src/council/types.d.ts +128 -0
  60. package/dist/src/ee/artifact-cache.d.ts +16 -0
  61. package/dist/src/ee/artifact-cache.js +32 -0
  62. package/dist/src/ee/auth.d.ts +1 -0
  63. package/dist/src/ee/auth.js +15 -2
  64. package/dist/src/ee/bridge.d.ts +10 -0
  65. package/dist/src/ee/bridge.js +58 -0
  66. package/dist/src/ee/client.js +81 -18
  67. package/dist/src/ee/export-transcripts.d.ts +1 -0
  68. package/dist/src/ee/export-transcripts.js +8 -10
  69. package/dist/src/ee/extract-session.js +29 -0
  70. package/dist/src/ee/extract-style.d.ts +58 -0
  71. package/dist/src/ee/extract-style.js +270 -0
  72. package/dist/src/ee/recall-ledger.d.ts +9 -0
  73. package/dist/src/ee/recall-ledger.js +3 -0
  74. package/dist/src/ee/scope.d.ts +1 -0
  75. package/dist/src/ee/scope.js +26 -1
  76. package/dist/src/ee/search.d.ts +7 -0
  77. package/dist/src/ee/search.js +24 -0
  78. package/dist/src/ee/transcript-emit.js +2 -0
  79. package/dist/src/ee/types.d.ts +22 -0
  80. package/dist/src/ee/who-am-i-brain.d.ts +35 -0
  81. package/dist/src/ee/who-am-i-brain.js +220 -0
  82. package/dist/src/ee/who-am-i.d.ts +10 -3
  83. package/dist/src/ee/who-am-i.js +12 -0
  84. package/dist/src/ee/workflow-event.d.ts +48 -0
  85. package/dist/src/ee/workflow-event.js +81 -0
  86. package/dist/src/flow/compaction/compress.d.ts +3 -3
  87. package/dist/src/flow/compaction/compress.js +45 -8
  88. package/dist/src/flow/compaction/extract.d.ts +4 -7
  89. package/dist/src/flow/compaction/extract.js +50 -10
  90. package/dist/src/flow/compaction/index.d.ts +13 -1
  91. package/dist/src/flow/compaction/index.js +70 -3
  92. package/dist/src/flow/compaction/input-guard.d.ts +24 -0
  93. package/dist/src/flow/compaction/input-guard.js +43 -0
  94. package/dist/src/flow/fold-planning.d.ts +36 -0
  95. package/dist/src/flow/fold-planning.js +83 -0
  96. package/dist/src/flow/hierarchy.d.ts +146 -0
  97. package/dist/src/flow/hierarchy.js +427 -0
  98. package/dist/src/flow/index.d.ts +1 -0
  99. package/dist/src/flow/index.js +2 -0
  100. package/dist/src/flow/run-artifacts.d.ts +102 -0
  101. package/dist/src/flow/run-artifacts.js +208 -0
  102. package/dist/src/generated/version.d.ts +1 -1
  103. package/dist/src/generated/version.js +1 -1
  104. package/dist/src/gsd/assessment-schema.d.ts +44 -0
  105. package/dist/src/gsd/assessment-schema.js +134 -0
  106. package/dist/src/gsd/capability-registry.d.ts +45 -0
  107. package/dist/src/gsd/capability-registry.js +337 -0
  108. package/dist/src/gsd/complexity-assessor.d.ts +39 -0
  109. package/dist/src/gsd/complexity-assessor.js +152 -0
  110. package/dist/src/gsd/config-bridge.d.ts +7 -0
  111. package/dist/src/gsd/config-bridge.js +114 -0
  112. package/dist/src/gsd/config-loader.d.ts +27 -0
  113. package/dist/src/gsd/config-loader.js +50 -0
  114. package/dist/src/gsd/council-context.d.ts +44 -0
  115. package/dist/src/gsd/council-context.js +114 -0
  116. package/dist/src/gsd/ee-closure.d.ts +28 -0
  117. package/dist/src/gsd/ee-closure.js +49 -0
  118. package/dist/src/gsd/flags.d.ts +55 -0
  119. package/dist/src/gsd/flags.js +83 -0
  120. package/dist/src/gsd/gsd-dispatch.d.ts +58 -0
  121. package/dist/src/gsd/gsd-dispatch.js +131 -0
  122. package/dist/src/gsd/gsd-runtime.d.ts +22 -0
  123. package/dist/src/gsd/gsd-runtime.js +37 -0
  124. package/dist/src/gsd/host-adapter.d.ts +11 -0
  125. package/dist/src/gsd/host-adapter.js +29 -0
  126. package/dist/src/gsd/index.d.ts +24 -1
  127. package/dist/src/gsd/index.js +27 -0
  128. package/dist/src/gsd/loop-host-contract.d.ts +21 -0
  129. package/dist/src/gsd/loop-host-contract.js +39 -0
  130. package/dist/src/gsd/loop-host.d.ts +69 -0
  131. package/dist/src/gsd/loop-host.js +245 -0
  132. package/dist/src/gsd/loop-resolver.d.ts +36 -0
  133. package/dist/src/gsd/loop-resolver.js +79 -0
  134. package/dist/src/gsd/model-tier.d.ts +13 -0
  135. package/dist/src/gsd/model-tier.js +45 -0
  136. package/dist/src/gsd/mutation-gate.d.ts +16 -0
  137. package/dist/src/gsd/mutation-gate.js +41 -0
  138. package/dist/src/gsd/native-roadmap.d.ts +89 -0
  139. package/dist/src/gsd/native-roadmap.js +343 -0
  140. package/dist/src/gsd/native-state.d.ts +47 -0
  141. package/dist/src/gsd/native-state.js +220 -0
  142. package/dist/src/gsd/paths.d.ts +23 -0
  143. package/dist/src/gsd/paths.js +66 -0
  144. package/dist/src/gsd/phase-dag.d.ts +12 -0
  145. package/dist/src/gsd/phase-dag.js +94 -0
  146. package/dist/src/gsd/phase-sync.d.ts +42 -0
  147. package/dist/src/gsd/phase-sync.js +321 -0
  148. package/dist/src/gsd/pil-gate-context.d.ts +13 -0
  149. package/dist/src/gsd/pil-gate-context.js +64 -0
  150. package/dist/src/gsd/pil-gate-critic.d.ts +19 -0
  151. package/dist/src/gsd/pil-gate-critic.js +74 -0
  152. package/dist/src/gsd/plan-council-prompts.d.ts +25 -0
  153. package/dist/src/gsd/plan-council-prompts.js +79 -0
  154. package/dist/src/gsd/plan-council.d.ts +44 -0
  155. package/dist/src/gsd/plan-council.js +251 -0
  156. package/dist/src/gsd/plan-gate-vocabulary.d.ts +40 -0
  157. package/dist/src/gsd/plan-gate-vocabulary.js +64 -0
  158. package/dist/src/gsd/product-workspace.d.ts +13 -0
  159. package/dist/src/gsd/product-workspace.js +124 -0
  160. package/dist/src/gsd/ship-bridge.d.ts +25 -0
  161. package/dist/src/gsd/ship-bridge.js +65 -0
  162. package/dist/src/gsd/state-document.d.ts +40 -0
  163. package/dist/src/gsd/state-document.js +163 -0
  164. package/dist/src/gsd/verdict-schema.d.ts +39 -0
  165. package/dist/src/gsd/verdict-schema.js +144 -0
  166. package/dist/src/gsd/verify-context.d.ts +22 -0
  167. package/dist/src/gsd/verify-context.js +27 -0
  168. package/dist/src/gsd/verify-council-prompts.d.ts +19 -0
  169. package/dist/src/gsd/verify-council-prompts.js +85 -0
  170. package/dist/src/gsd/verify-council.d.ts +25 -0
  171. package/dist/src/gsd/verify-council.js +119 -0
  172. package/dist/src/gsd/verify-gate-vocabulary.d.ts +25 -0
  173. package/dist/src/gsd/verify-gate-vocabulary.js +46 -0
  174. package/dist/src/gsd/workflow-engine.d.ts +60 -0
  175. package/dist/src/gsd/workflow-engine.js +207 -0
  176. package/dist/src/gsd/workflow-tools.d.ts +13 -0
  177. package/dist/src/gsd/workflow-tools.js +277 -0
  178. package/dist/src/hooks/index.js +1 -1
  179. package/dist/src/index.js +44 -11
  180. package/dist/src/maintain/pr-builder.js +23 -13
  181. package/dist/src/mcp/auto-setup.js +57 -32
  182. package/dist/src/mcp/client-pool.js +1 -1
  183. package/dist/src/mcp/ee-tools.js +1 -0
  184. package/dist/src/mcp/oauth-callback.js +2 -2
  185. package/dist/src/mcp/research-onboarding.js +8 -7
  186. package/dist/src/mcp/runtime.js +34 -2
  187. package/dist/src/mcp/setup-guide-text.d.ts +1 -1
  188. package/dist/src/mcp/setup-guide-text.js +77 -76
  189. package/dist/src/models/catalog-client.d.ts +87 -0
  190. package/dist/src/models/catalog-client.js +105 -38
  191. package/dist/src/models/catalog.json +528 -265
  192. package/dist/src/models/registry.d.ts +22 -7
  193. package/dist/src/models/registry.js +73 -10
  194. package/dist/src/ops/doctor.js +8 -8
  195. package/dist/src/orchestrator/auto-commit.js +1 -1
  196. package/dist/src/orchestrator/batch-turn-runner.js +2 -2
  197. package/dist/src/orchestrator/cache-prefix.d.ts +67 -0
  198. package/dist/src/orchestrator/cache-prefix.js +83 -0
  199. package/dist/src/orchestrator/compact-request.d.ts +32 -0
  200. package/dist/src/orchestrator/compact-request.js +41 -0
  201. package/dist/src/orchestrator/compaction.d.ts +10 -0
  202. package/dist/src/orchestrator/compaction.js +27 -7
  203. package/dist/src/orchestrator/council-manager.d.ts +12 -3
  204. package/dist/src/orchestrator/council-manager.js +65 -24
  205. package/dist/src/orchestrator/cross-turn-dedup.d.ts +6 -0
  206. package/dist/src/orchestrator/cross-turn-dedup.js +22 -1
  207. package/dist/src/orchestrator/error-utils.d.ts +29 -0
  208. package/dist/src/orchestrator/error-utils.js +132 -24
  209. package/dist/src/orchestrator/grounding-check.js +39 -1
  210. package/dist/src/orchestrator/message-processor.js +242 -33
  211. package/dist/src/orchestrator/orchestrator.d.ts +39 -3
  212. package/dist/src/orchestrator/orchestrator.js +651 -102
  213. package/dist/src/orchestrator/preprocessor.js +1 -1
  214. package/dist/src/orchestrator/proactive-compact-detector.d.ts +26 -0
  215. package/dist/src/orchestrator/proactive-compact-detector.js +36 -0
  216. package/dist/src/orchestrator/prompts.js +159 -159
  217. package/dist/src/orchestrator/reactive-delegation.d.ts +39 -0
  218. package/dist/src/orchestrator/reactive-delegation.js +59 -0
  219. package/dist/src/orchestrator/retry-classifier.d.ts +2 -1
  220. package/dist/src/orchestrator/retry-classifier.js +46 -2
  221. package/dist/src/orchestrator/safety-intercept.d.ts +45 -0
  222. package/dist/src/orchestrator/safety-intercept.js +55 -0
  223. package/dist/src/orchestrator/scope-reminder.js +1 -1
  224. package/dist/src/orchestrator/session-experience.d.ts +2 -1
  225. package/dist/src/orchestrator/session-experience.js +2 -1
  226. package/dist/src/orchestrator/should-run-gate.d.ts +5 -0
  227. package/dist/src/orchestrator/should-run-gate.js +18 -0
  228. package/dist/src/orchestrator/stall-watchdog.d.ts +24 -3
  229. package/dist/src/orchestrator/stall-watchdog.js +47 -13
  230. package/dist/src/orchestrator/stream-runner.js +62 -29
  231. package/dist/src/orchestrator/sub-agent-cap.d.ts +13 -1
  232. package/dist/src/orchestrator/sub-agent-cap.js +16 -1
  233. package/dist/src/orchestrator/sub-agent-model-tier.d.ts +13 -1
  234. package/dist/src/orchestrator/sub-agent-model-tier.js +16 -2
  235. package/dist/src/orchestrator/subagent-compactor.d.ts +53 -1
  236. package/dist/src/orchestrator/subagent-compactor.js +126 -15
  237. package/dist/src/orchestrator/tool-engine.d.ts +26 -0
  238. package/dist/src/orchestrator/tool-engine.js +669 -56
  239. package/dist/src/orchestrator/tool-limit-auto-recover.d.ts +22 -0
  240. package/dist/src/orchestrator/tool-limit-auto-recover.js +30 -0
  241. package/dist/src/orchestrator/turn-runner-deps.d.ts +19 -0
  242. package/dist/src/orchestrator/turn-watchdog.d.ts +37 -0
  243. package/dist/src/orchestrator/turn-watchdog.js +55 -0
  244. package/dist/src/pil/agent-operating-contract.d.ts +1 -1
  245. package/dist/src/pil/agent-operating-contract.js +1 -1
  246. package/dist/src/pil/cheap-model-playbook.d.ts +1 -1
  247. package/dist/src/pil/cheap-model-playbook.js +5 -1
  248. package/dist/src/pil/cheap-model-workbooks.d.ts +1 -1
  249. package/dist/src/pil/cheap-model-workbooks.js +1 -1
  250. package/dist/src/pil/discovery-types.d.ts +1 -0
  251. package/dist/src/pil/discovery.js +16 -11
  252. package/dist/src/pil/layer1-intent.d.ts +18 -6
  253. package/dist/src/pil/layer1-intent.js +66 -757
  254. package/dist/src/pil/layer15-context-scan.js +15 -1
  255. package/dist/src/pil/layer2_5-ponytail.js +8 -8
  256. package/dist/src/pil/layer3-ee-injection.js +23 -8
  257. package/dist/src/pil/layer4-gsd.js +69 -16
  258. package/dist/src/pil/layer5-context.js +7 -3
  259. package/dist/src/pil/layer6-output.d.ts +23 -0
  260. package/dist/src/pil/layer6-output.js +5 -1
  261. package/dist/src/pil/llm-classify.d.ts +33 -2
  262. package/dist/src/pil/llm-classify.js +123 -131
  263. package/dist/src/pil/native-capabilities-workbook.d.ts +1 -1
  264. package/dist/src/pil/native-capabilities-workbook.js +1 -0
  265. package/dist/src/pil/pipeline.js +34 -2
  266. package/dist/src/pil/response-tools.js +5 -3
  267. package/dist/src/pil/schema.d.ts +1 -0
  268. package/dist/src/pil/schema.js +2 -0
  269. package/dist/src/pil/types.d.ts +18 -0
  270. package/dist/src/playbook/directives.d.ts +4 -0
  271. package/dist/src/playbook/directives.js +17 -5
  272. package/dist/src/product-loop/backlog-builder.d.ts +14 -1
  273. package/dist/src/product-loop/backlog-builder.js +30 -6
  274. package/dist/src/product-loop/discovery-context-format.js +3 -1
  275. package/dist/src/product-loop/discovery-ecosystem.js +4 -1
  276. package/dist/src/product-loop/discovery-interview.js +32 -3
  277. package/dist/src/product-loop/discovery-schema.js +5 -1
  278. package/dist/src/product-loop/done-gate.js +3 -3
  279. package/dist/src/product-loop/ideal-trace.d.ts +7 -0
  280. package/dist/src/product-loop/ideal-trace.js +64 -0
  281. package/dist/src/product-loop/index.d.ts +13 -1
  282. package/dist/src/product-loop/index.js +333 -52
  283. package/dist/src/product-loop/loop-driver.d.ts +7 -0
  284. package/dist/src/product-loop/loop-driver.js +327 -116
  285. package/dist/src/product-loop/phase-plan.d.ts +5 -0
  286. package/dist/src/product-loop/phase-plan.js +39 -2
  287. package/dist/src/product-loop/phase-runner.js +9 -1
  288. package/dist/src/product-loop/progress-snapshot.js +4 -4
  289. package/dist/src/product-loop/sprint-runner.d.ts +111 -0
  290. package/dist/src/product-loop/sprint-runner.js +559 -16
  291. package/dist/src/product-loop/types.d.ts +36 -5
  292. package/dist/src/providers/adapter.d.ts +1 -1
  293. package/dist/src/providers/adapter.js +3 -4
  294. package/dist/src/providers/auth/browser-flow.d.ts +1 -1
  295. package/dist/src/providers/auth/browser-flow.js +1 -1
  296. package/dist/src/providers/auth/openai-oauth.js +1 -1
  297. package/dist/src/providers/auth/registry.js +0 -34
  298. package/dist/src/providers/auth/token-store.js +4 -1
  299. package/dist/src/providers/auth/types.d.ts +1 -1
  300. package/dist/src/providers/auth/types.js +1 -1
  301. package/dist/src/providers/capabilities.d.ts +24 -5
  302. package/dist/src/providers/capabilities.js +42 -24
  303. package/dist/src/providers/endpoints.d.ts +2 -2
  304. package/dist/src/providers/endpoints.js +11 -10
  305. package/dist/src/providers/keychain.d.ts +1 -1
  306. package/dist/src/providers/keychain.js +7 -9
  307. package/dist/src/providers/mcp-vision-bridge.js +82 -172
  308. package/dist/src/providers/openai-compatible.js +8 -1
  309. package/dist/src/providers/pricing.d.ts +2 -2
  310. package/dist/src/providers/pricing.js +3 -13
  311. package/dist/src/providers/runtime.d.ts +27 -2
  312. package/dist/src/providers/runtime.js +78 -15
  313. package/dist/src/providers/strategies/base.strategy.d.ts +16 -0
  314. package/dist/src/providers/strategies/base.strategy.js +24 -1
  315. package/dist/src/providers/strategies/{siliconflow.strategy.d.ts → opencode-go.strategy.d.ts} +3 -3
  316. package/dist/src/providers/strategies/opencode-go.strategy.js +83 -0
  317. package/dist/src/providers/strategies/registry.js +4 -4
  318. package/dist/src/providers/strategies/thinking-mode.d.ts +109 -0
  319. package/dist/src/providers/strategies/thinking-mode.js +280 -1
  320. package/dist/src/providers/strategies/zai.strategy.d.ts +14 -0
  321. package/dist/src/providers/strategies/zai.strategy.js +44 -0
  322. package/dist/src/providers/types.d.ts +5 -6
  323. package/dist/src/providers/types.js +2 -2
  324. package/dist/src/providers/vision-backend.d.ts +47 -0
  325. package/dist/src/providers/vision-backend.js +258 -0
  326. package/dist/src/providers/vision-proxy.d.ts +22 -9
  327. package/dist/src/providers/vision-proxy.js +63 -132
  328. package/dist/src/providers/wire-debug.js +95 -0
  329. package/dist/src/reporter/index.js +1 -1
  330. package/dist/src/router/decide.d.ts +13 -0
  331. package/dist/src/router/decide.js +138 -36
  332. package/dist/src/router/peak-hour.d.ts +38 -0
  333. package/dist/src/router/peak-hour.js +107 -0
  334. package/dist/src/router/step-router.js +3 -2
  335. package/dist/src/router/warm.js +4 -5
  336. package/dist/src/scaffold/bb-ecosystem-apply.js +47 -47
  337. package/dist/src/scaffold/bb-quality-gate.js +5 -5
  338. package/dist/src/scaffold/continuation-prompt.d.ts +11 -0
  339. package/dist/src/scaffold/continuation-prompt.js +86 -60
  340. package/dist/src/scaffold/init-new.js +453 -453
  341. package/dist/src/scaffold/point-to-existing.d.ts +21 -0
  342. package/dist/src/scaffold/point-to-existing.js +25 -0
  343. package/dist/src/self-qa/agentic-loop.js +22 -22
  344. package/dist/src/{ui/state → state}/active-run.d.ts +19 -0
  345. package/dist/src/{ui/state → state}/active-run.js +21 -0
  346. package/dist/src/{ui/status-bar/store.d.ts → state/status-bar-store.d.ts} +4 -1
  347. package/dist/src/{ui/status-bar/store.js → state/status-bar-store.js} +12 -9
  348. package/dist/src/state/turn-trace.d.ts +43 -0
  349. package/dist/src/state/turn-trace.js +32 -0
  350. package/dist/src/storage/db.js +2 -1
  351. package/dist/src/storage/index.d.ts +1 -1
  352. package/dist/src/storage/index.js +1 -1
  353. package/dist/src/storage/interaction-log.d.ts +1 -1
  354. package/dist/src/storage/interaction-log.js +5 -5
  355. package/dist/src/storage/migrations.js +196 -126
  356. package/dist/src/storage/session-experience-store.js +4 -4
  357. package/dist/src/storage/sessions.d.ts +28 -10
  358. package/dist/src/storage/sessions.js +112 -55
  359. package/dist/src/storage/transcript-view.js +1 -1
  360. package/dist/src/storage/transcript.d.ts +51 -0
  361. package/dist/src/storage/transcript.js +383 -112
  362. package/dist/src/storage/usage.js +14 -14
  363. package/dist/src/storage/workspaces.js +12 -12
  364. package/dist/src/tools/file.d.ts +15 -0
  365. package/dist/src/tools/file.js +32 -0
  366. package/dist/src/tools/native-tools.js +5 -0
  367. package/dist/src/tools/registry.d.ts +3 -0
  368. package/dist/src/tools/registry.js +460 -22
  369. package/dist/src/tools/research.d.ts +29 -0
  370. package/dist/src/tools/research.js +233 -0
  371. package/dist/src/types/index.d.ts +118 -3
  372. package/dist/src/ui/app.js +0 -0
  373. package/dist/src/ui/cards/product-status-card.js +1 -1
  374. package/dist/src/ui/components/bubble-body-guard.d.ts +27 -0
  375. package/dist/src/ui/components/bubble-body-guard.js +50 -0
  376. package/dist/src/ui/components/context-rail.d.ts +26 -0
  377. package/dist/src/ui/components/context-rail.js +33 -0
  378. package/dist/src/ui/components/council-conclusion-card.d.ts +73 -0
  379. package/dist/src/ui/components/council-conclusion-card.js +420 -0
  380. package/dist/src/ui/components/council-debate-pill.d.ts +36 -0
  381. package/dist/src/ui/components/council-debate-pill.js +34 -0
  382. package/dist/src/ui/components/council-info-card.js +2 -2
  383. package/dist/src/ui/components/council-leader-bubble.d.ts +10 -3
  384. package/dist/src/ui/components/council-leader-bubble.js +21 -11
  385. package/dist/src/ui/components/council-message-bubble.d.ts +15 -2
  386. package/dist/src/ui/components/council-message-bubble.js +16 -15
  387. package/dist/src/ui/components/council-phase-timeline.d.ts +9 -1
  388. package/dist/src/ui/components/council-phase-timeline.js +49 -15
  389. package/dist/src/ui/components/council-placeholder-bubble.d.ts +16 -9
  390. package/dist/src/ui/components/council-placeholder-bubble.js +32 -29
  391. package/dist/src/ui/components/council-question-card.js +12 -12
  392. package/dist/src/ui/components/council-rail-rounds.d.ts +26 -0
  393. package/dist/src/ui/components/council-rail-rounds.js +57 -0
  394. package/dist/src/ui/components/council-round-group.d.ts +38 -0
  395. package/dist/src/ui/components/council-round-group.js +88 -0
  396. package/dist/src/ui/components/council-status-list.d.ts +3 -1
  397. package/dist/src/ui/components/council-status-list.js +36 -24
  398. package/dist/src/ui/components/council-synthesis-banner.d.ts +7 -2
  399. package/dist/src/ui/components/council-synthesis-banner.js +20 -5
  400. package/dist/src/ui/components/halt-recovery-card.js +9 -5
  401. package/dist/src/ui/components/jump-to-latest-pill.d.ts +11 -0
  402. package/dist/src/ui/components/jump-to-latest-pill.js +14 -0
  403. package/dist/src/ui/components/prompt-box.js +18 -16
  404. package/dist/src/ui/components/session-tree-card.d.ts +14 -0
  405. package/dist/src/ui/components/session-tree-card.js +46 -0
  406. package/dist/src/ui/components/slash-inline-menu.d.ts +12 -0
  407. package/dist/src/ui/components/slash-inline-menu.js +26 -5
  408. package/dist/src/ui/components/task-list-panel.d.ts +14 -1
  409. package/dist/src/ui/components/task-list-panel.js +22 -2
  410. package/dist/src/ui/containers/modals-layer.d.ts +2 -1
  411. package/dist/src/ui/hooks/use-session-picker.d.ts +3 -3
  412. package/dist/src/ui/mcp-modal.js +2 -4
  413. package/dist/src/ui/modals/api-key-modal.js +1 -1
  414. package/dist/src/ui/modals/connect-modal.js +4 -3
  415. package/dist/src/ui/modals/session-picker-modal.d.ts +2 -2
  416. package/dist/src/ui/modals/session-picker-modal.js +3 -5
  417. package/dist/src/ui/picker-providers.d.ts +1 -1
  418. package/dist/src/ui/picker-providers.js +1 -1
  419. package/dist/src/ui/primitives/index.d.ts +1 -0
  420. package/dist/src/ui/primitives/index.js +2 -0
  421. package/dist/src/ui/primitives/semantic-primitives.d.ts +76 -0
  422. package/dist/src/ui/primitives/semantic-primitives.js +81 -0
  423. package/dist/src/ui/slash/compact.js +5 -7
  424. package/dist/src/ui/slash/cost.js +1 -1
  425. package/dist/src/ui/slash/council-inspect.js +4 -4
  426. package/dist/src/ui/slash/council.js +19 -1
  427. package/dist/src/ui/slash/debug.d.ts +3 -31
  428. package/dist/src/ui/slash/debug.js +9 -20
  429. package/dist/src/ui/slash/ideal.d.ts +6 -2
  430. package/dist/src/ui/slash/ideal.js +97 -7
  431. package/dist/src/ui/slash/menu-items.d.ts +7 -0
  432. package/dist/src/ui/slash/menu-items.js +12 -18
  433. package/dist/src/ui/slash/registry.d.ts +2 -0
  434. package/dist/src/ui/slash/registry.js +4 -0
  435. package/dist/src/ui/status-bar/cache-hit.d.ts +6 -0
  436. package/dist/src/ui/status-bar/cache-hit.js +9 -0
  437. package/dist/src/ui/status-bar/index.d.ts +1 -1
  438. package/dist/src/ui/status-bar/index.js +7 -3
  439. package/dist/src/ui/status-bar/usd-meter.d.ts +5 -4
  440. package/dist/src/ui/status-bar/usd-meter.js +6 -4
  441. package/dist/src/ui/theme.d.ts +1 -0
  442. package/dist/src/ui/theme.js +2 -0
  443. package/dist/src/ui/types.d.ts +7 -0
  444. package/dist/src/ui/use-app-logic.js +0 -0
  445. package/dist/src/ui/utils/format.d.ts +14 -0
  446. package/dist/src/ui/utils/format.js +23 -3
  447. package/dist/src/usage/downgrade.js +2 -2
  448. package/dist/src/usage/product-ledger.js +2 -2
  449. package/dist/src/utils/clipboard-image.js +23 -23
  450. package/dist/src/utils/install-manager.js +14 -11
  451. package/dist/src/utils/logger.js +2 -2
  452. package/dist/src/utils/permission-mode.js +5 -3
  453. package/dist/src/utils/redactor.js +1 -1
  454. package/dist/src/utils/settings.d.ts +153 -5
  455. package/dist/src/utils/settings.js +233 -29
  456. package/dist/src/utils/side-question.js +2 -2
  457. package/dist/src/utils/skills.js +3 -3
  458. package/dist/src/utils/visible-retry.d.ts +11 -0
  459. package/dist/src/utils/visible-retry.js +10 -1
  460. package/dist/src/verify/entrypoint.d.ts +1 -1
  461. package/dist/src/verify/entrypoint.js +1 -1
  462. package/dist/src/verify/recipes.d.ts +13 -0
  463. package/dist/src/verify/recipes.js +15 -0
  464. package/package.json +135 -132
  465. package/dist/src/providers/auth/gcloud.d.ts +0 -28
  466. package/dist/src/providers/auth/gcloud.js +0 -102
  467. package/dist/src/providers/auth/gemini-oauth.d.ts +0 -82
  468. package/dist/src/providers/auth/gemini-oauth.js +0 -472
  469. package/dist/src/providers/gemini.d.ts +0 -11
  470. package/dist/src/providers/gemini.js +0 -45
  471. package/dist/src/providers/siliconflow-sse-repair.d.ts +0 -58
  472. package/dist/src/providers/siliconflow-sse-repair.js +0 -177
  473. package/dist/src/providers/strategies/google.strategy.d.ts +0 -22
  474. package/dist/src/providers/strategies/google.strategy.js +0 -174
  475. package/dist/src/providers/strategies/siliconflow.strategy.js +0 -29
  476. package/dist/src/ui/containers/chat-feed.d.ts +0 -40
  477. package/dist/src/ui/containers/chat-feed.js +0 -66
@@ -12,16 +12,8 @@
12
12
  */
13
13
  import { existsSync, readFileSync } from "node:fs";
14
14
  import { extname, resolve } from "node:path";
15
- import { apiBaseFor } from "./endpoints.js";
16
- import { loadKeyForProvider } from "./keychain.js";
15
+ import { callVisionBackend, formatNativeVisionObservation, formatNativeVisionUnavailable, looksLikeOcrIntent, resolveAvailableVisionChain, wrapAnalyzerInstructions, } from "./vision-backend.js";
17
16
  import { needsVisionProxy } from "./vision-proxy.js";
18
- const VISION_MODELS = [
19
- "Qwen/Qwen3-VL-8B-Instruct",
20
- "Qwen/Qwen3-VL-30B-A3B-Instruct",
21
- "Qwen/Qwen3-VL-32B-Instruct",
22
- ];
23
- const SILICONFLOW_BASE = apiBaseFor("siliconflow");
24
- const REQUEST_TIMEOUT_MS = 90_000;
25
17
  const IMAGE_CACHE_MAX = 20;
26
18
  const IMAGE_CACHE_TTL_MS = 15 * 60 * 1000; // 15 minutes
27
19
  /**
@@ -48,27 +40,27 @@ const IMAGE_EXTENSIONS = new Set([".png", ".jpg", ".jpeg", ".gif", ".webp", ".bm
48
40
  * Downstream agents consume this JSON directly instead of re-parsing markdown.
49
41
  * Kept embedded in the prompt (not strict JSON-schema mode) for cross-provider portability.
50
42
  */
51
- export const UI_LAYOUT_SCHEMA_HINT = `{
52
- "viewport": { "width": number, "height": number, "deviceClass": "mobile" | "tablet" | "desktop" },
53
- "tokens": {
54
- "colors": [{ "name": string, "hex": string, "role": "primary" | "secondary" | "accent" | "bg" | "fg" | "border" | "muted" }],
55
- "typography": [{ "role": "heading" | "body" | "caption" | "label", "fontFamily": string, "sizePx": number, "weight": number }],
56
- "spacingScalePx": number[],
57
- "radiusScalePx": number[]
58
- },
59
- "layout": { "type": "stack" | "grid" | "flex" | "absolute", "direction": "row" | "column", "gapPx": number, "columns": number | null },
60
- "components": [{
61
- "id": string,
62
- "role": "button" | "input" | "card" | "nav" | "header" | "footer" | "image" | "icon" | "text" | "list" | "modal" | "tabs" | "table" | "chart" | "container" | "other",
63
- "label": string,
64
- "text": string | null,
65
- "bbox": { "x": number, "y": number, "w": number, "h": number },
66
- "style": { "bgHex": string | null, "fgHex": string | null, "borderHex": string | null, "radiusPx": number | null, "shadow": string | null },
67
- "state": "default" | "hover" | "active" | "disabled" | "focus" | "error",
68
- "children": string[]
69
- }],
70
- "hierarchy": [{ "level": 1 | 2 | 3, "text": string, "componentId": string }],
71
- "notes": string[]
43
+ export const UI_LAYOUT_SCHEMA_HINT = `{
44
+ "viewport": { "width": number, "height": number, "deviceClass": "mobile" | "tablet" | "desktop" },
45
+ "tokens": {
46
+ "colors": [{ "name": string, "hex": string, "role": "primary" | "secondary" | "accent" | "bg" | "fg" | "border" | "muted" }],
47
+ "typography": [{ "role": "heading" | "body" | "caption" | "label", "fontFamily": string, "sizePx": number, "weight": number }],
48
+ "spacingScalePx": number[],
49
+ "radiusScalePx": number[]
50
+ },
51
+ "layout": { "type": "stack" | "grid" | "flex" | "absolute", "direction": "row" | "column", "gapPx": number, "columns": number | null },
52
+ "components": [{
53
+ "id": string,
54
+ "role": "button" | "input" | "card" | "nav" | "header" | "footer" | "image" | "icon" | "text" | "list" | "modal" | "tabs" | "table" | "chart" | "container" | "other",
55
+ "label": string,
56
+ "text": string | null,
57
+ "bbox": { "x": number, "y": number, "w": number, "h": number },
58
+ "style": { "bgHex": string | null, "fgHex": string | null, "borderHex": string | null, "radiusPx": number | null, "shadow": string | null },
59
+ "state": "default" | "hover" | "active" | "disabled" | "focus" | "error",
60
+ "children": string[]
61
+ }],
62
+ "hierarchy": [{ "level": 1 | 2 | 3, "text": string, "componentId": string }],
63
+ "notes": string[]
72
64
  }`;
73
65
  const MIME_MAP = {
74
66
  ".png": "image/png",
@@ -174,8 +166,8 @@ export async function bridgeMcpToolResult(toolName, toolOutput, modelId, signal,
174
166
  }
175
167
  // Detect context for better analysis prompt
176
168
  const context = detectImageContext(toolName, toolOutput);
177
- const description = await analyzeImages(images, context, signal);
178
- if (!description) {
169
+ const rawObservation = await analyzeImages(images, context, signal);
170
+ if (!rawObservation) {
179
171
  // Even when the vision proxy fails (no API key / network error), we MUST
180
172
  // still strip the base64 payload from the tool output. Otherwise a single
181
173
  // Playwright screenshot (~1.5MB of base64) lands in conversation history
@@ -187,15 +179,21 @@ export async function bridgeMcpToolResult(toolName, toolOutput, modelId, signal,
187
179
  proxied: true,
188
180
  };
189
181
  }
190
- const cachedIds = addToCache(images.map((img) => ({ ...img, source: baseName || toolName })), description, `${baseName} result`);
182
+ const cachedIds = addToCache(images.map((img) => ({ ...img, source: baseName || toolName })), rawObservation, `${baseName} result`);
191
183
  const cleanOutput = stripBase64FromOutput(toolOutput);
192
- const cacheHint = `\n[Cached as ${cachedIds.join(", ")} — use ask_vision_proxy for follow-up questions]`;
193
- const fullDescription = `${description}${cacheHint}`;
184
+ const fullDescription = formatNativeVisionObservation(rawObservation, {
185
+ imageCount: images.length,
186
+ cachedIds,
187
+ });
194
188
  const enhanced = typeof cleanOutput === "string"
195
189
  ? `${cleanOutput}\n\n${fullDescription}`
196
- : { ...cleanOutput, _visionDescription: description, _cachedImageIds: cachedIds };
190
+ : {
191
+ ...cleanOutput,
192
+ _visionDescription: fullDescription,
193
+ _cachedImageIds: cachedIds,
194
+ };
197
195
  recordBridgedDescription(toolCallId, fullDescription);
198
- return { output: enhanced, proxied: true, description, cachedImageIds: cachedIds };
196
+ return { output: enhanced, proxied: true, description: fullDescription, cachedImageIds: cachedIds };
199
197
  }
200
198
  /**
201
199
  * Proactively analyze an image from a file path, URL, or raw base64.
@@ -246,12 +244,13 @@ export async function analyzeImageFromSource(source, question, cwd, signal) {
246
244
  }
247
245
  const context = question ? { type: "user-query", hint: question } : { type: "generic" };
248
246
  const prompt = question ? buildFollowUpPrompt(question, images.length) : undefined;
249
- const description = await analyzeImages(images, context, signal, prompt);
250
- if (!description) {
251
- return "Vision proxy could not analyze the image. Check SILICONFLOW_API_KEY configuration.";
247
+ const rawObservation = await analyzeImages(images, context, signal, prompt);
248
+ if (!rawObservation) {
249
+ const { collectVisionUnavailableReasons } = await import("./vision-backend.js");
250
+ return formatNativeVisionUnavailable(1, await collectVisionUnavailableReasons());
252
251
  }
253
- const cachedIds = addToCache(images, description, source);
254
- return `${description}\n[Cached as ${cachedIds.join(", ")} — use ask_vision_proxy for follow-up questions]`;
252
+ const cachedIds = addToCache(images, rawObservation, source);
253
+ return formatNativeVisionObservation(rawObservation, { imageCount: images.length, cachedIds });
255
254
  }
256
255
  /**
257
256
  * Ask a follow-up question about a previously cached image,
@@ -278,17 +277,10 @@ export async function askVisionProxy(question, imageIdOrPath, cwd, signal) {
278
277
  }
279
278
  return `No matching image. Available:\n${cached.map((c) => `- ${c.id}: ${c.label} (${c.age})`).join("\n")}\n\nSpecify image_id, or provide a file_path to analyze a new image.`;
280
279
  }
281
- let apiKey;
282
- try {
283
- apiKey = await loadKeyForProvider("siliconflow");
284
- }
285
- catch {
286
- return "Vision proxy unavailable — SILICONFLOW_API_KEY not configured.";
287
- }
288
280
  const visionContent = [];
289
281
  visionContent.push({
290
282
  type: "text",
291
- text: buildFollowUpPrompt(question, targets.length),
283
+ text: wrapAnalyzerInstructions(buildFollowUpPrompt(question, targets.length), looksLikeOcrIntent(question) ? "ocr" : "default"),
292
284
  });
293
285
  for (const img of targets) {
294
286
  visionContent.push({
@@ -299,19 +291,15 @@ export async function askVisionProxy(question, imageIdOrPath, cwd, signal) {
299
291
  },
300
292
  });
301
293
  }
302
- for (const model of VISION_MODELS) {
303
- try {
304
- const result = await callVisionModel(model, visionContent, apiKey, signal);
305
- if (result) {
306
- return `[Vision Proxy Answer — via ${model}]\n${result}\n[/Vision Proxy Answer]`;
307
- }
308
- }
309
- catch (err) {
310
- if (signal?.aborted)
311
- throw err;
312
- }
294
+ const kind = looksLikeOcrIntent(question) ? "ocr" : "default";
295
+ const result = await callVisionBackend(await resolveAvailableVisionChain(kind), visionContent, signal);
296
+ if (result.ok) {
297
+ return formatNativeVisionObservation(result.text, {
298
+ imageCount: targets.length,
299
+ cachedIds: targets.map((t) => t.id),
300
+ });
313
301
  }
314
- return "Vision proxy failed. Try again or describe what you need help with.";
302
+ return formatNativeVisionUnavailable(targets.length, [result.reason]);
315
303
  }
316
304
  /**
317
305
  * System prompt guidance for text-only models — UNIVERSAL, not Playwright-specific.
@@ -319,33 +307,28 @@ export async function askVisionProxy(question, imageIdOrPath, cwd, signal) {
319
307
  export function getVisionGuidanceForTextOnly(modelId) {
320
308
  if (!needsVisionProxy(modelId))
321
309
  return "";
322
- return `
323
- VISION PROXY (text-only model):
324
- You cannot see images directly. You have vision proxy tools to work with ANY image:
325
-
326
- TOOLS:
327
- - analyze_image: Proactively analyze an image from a file path, URL, or base64. Use this FIRST when you encounter or need to work with an image.
328
- - ask_vision_proxy: Ask a specific follow-up question about any cached image (or provide a file path for a new image).
329
- - list_vision_cache: See all cached images available for querying.
330
-
331
- WHEN TO USE (be PROACTIVE, not passive):
332
- - User mentions an image file → analyze_image immediately
333
- - User pastes or references a screenshot it's auto-analyzed, use ask_vision_proxy for details
334
- - Working with UI/web pagesprefer browser_snapshot (text-based), use screenshot + ask_vision_proxy when visual details matter
335
- - Reviewing design mockups, diagrams, charts analyze_image the file
336
- - Debugging visual issues (CSS, layout, colors) take screenshot, then ask_vision_proxy specific questions
337
- - Comparing before/after → analyze both images, ask about differences
338
- - Reading text from images (OCR) → analyze_image with a question like "transcribe all text"
339
- - Any file with image extension (.png, .jpg, .gif, .webp, .svg, etc.) → analyze_image
340
-
341
- WORKFLOW:
342
- 1. Encounter image → analyze_image (or it's auto-analyzed from tool results)
343
- 2. Need more detail ask_vision_proxy with specific question
344
- 3. Need to verify changes → take new screenshot/analyze new image → compare
345
-
346
- Images are cached (up to ${IMAGE_CACHE_MAX}, ${IMAGE_CACHE_TTL_MS / 60000}min TTL). You can reference them by ID for follow-ups.
347
-
348
- IMPORTANT: Do NOT guess what an image contains. Always use the proxy to get accurate information.
310
+ return `
311
+ VISION (extended capability):
312
+ You have full visual understanding via auto-injected <vision-observation> blocks and vision tools.
313
+ Treat every <vision-observation> as YOUR direct sight — respond naturally as if you saw the image yourself.
314
+
315
+ TOOLS (when you need a closer look or a new image):
316
+ - analyze_image: Inspect an image file path, data URI, or base64. Use when you encounter a new image or need a fresh screenshot analyzed.
317
+ - ask_vision_proxy: Ask a follow-up about a cached image (by ID) or a file path — zoom in on a region, read text, compare colors.
318
+ - list_vision_cache: List cached image IDs available for follow-up questions.
319
+
320
+ WHEN TO ACT:
321
+ - User mentions an imageanalyze_image immediately (do not guess)
322
+ - Tool results include <vision-observation>use that as your sight; ask_vision_proxy if any detail is unclear
323
+ - UI debugging screenshot + ask_vision_proxy for specific elements
324
+ - OCR / transcribe analyze_image with question "transcribe all visible text"
325
+
326
+ IF STILL UNCLEAR after an observation:
327
+ 1. ask_vision_proxy with a precise question about the unclear region or text
328
+ 2. analyze_image again on a new or higher-resolution file
329
+ 3. Ask the user to share another screenshot or clarify what to focus on
330
+
331
+ Never invent visual details. Cached images: up to ${IMAGE_CACHE_MAX}, ${IMAGE_CACHE_TTL_MS / 60000}min TTL.
349
332
  `;
350
333
  }
351
334
  // Keep backward compat export
@@ -380,17 +363,11 @@ async function analyzeImages(images, context, signal, customPrompt) {
380
363
  const svgFast = trySvgFastPath(images, context);
381
364
  if (svgFast)
382
365
  return svgFast;
383
- let apiKey;
384
- try {
385
- apiKey = await loadKeyForProvider("siliconflow");
386
- }
387
- catch {
388
- return null;
389
- }
366
+ const kind = context.type === "design" ? "design" : customPrompt && looksLikeOcrIntent(customPrompt) ? "ocr" : "default";
390
367
  const visionContent = [];
391
368
  visionContent.push({
392
369
  type: "text",
393
- text: customPrompt ?? buildContextualPrompt(images.length, context),
370
+ text: wrapAnalyzerInstructions(customPrompt ?? buildContextualPrompt(images.length, context), kind),
394
371
  });
395
372
  for (const img of images) {
396
373
  visionContent.push({
@@ -401,22 +378,10 @@ async function analyzeImages(images, context, signal, customPrompt) {
401
378
  },
402
379
  });
403
380
  }
404
- // Force JSON output for the design contract. Markdown narrative is fine for
405
- // debug-style contexts (terminal, code) where the human reads the result,
406
- // but design output is consumed machine-to-machine.
407
381
  const responseFormat = context.type === "design" ? { type: "json_object" } : undefined;
408
- for (const model of VISION_MODELS) {
409
- try {
410
- const result = await callVisionModel(model, visionContent, apiKey, signal, responseFormat);
411
- if (result) {
412
- return formatBridgeResult(result, images.length, model, context.type);
413
- }
414
- }
415
- catch (err) {
416
- if (signal?.aborted)
417
- throw err;
418
- }
419
- }
382
+ const result = await callVisionBackend(await resolveAvailableVisionChain(kind), visionContent, signal, responseFormat);
383
+ if (result.ok)
384
+ return result.text;
420
385
  return null;
421
386
  }
422
387
  function trySvgFastPath(images, context) {
@@ -437,11 +402,10 @@ function trySvgFastPath(images, context) {
437
402
  return svg.length > 32_000 ? `${svg.slice(0, 32_000)}\n<!-- truncated -->` : svg;
438
403
  })
439
404
  .join("\n\n");
440
- const header = `[Vision Bridge — ${images.length} SVG source(s) passed through (${context.type}, fast-path, no vision call)]`;
441
- const guidance = context.type === "design"
442
- ? `\nThe raw SVG below IS the layout contract. Coordinates and colors are exact. Map <rect>/<text>/<g> nodes to the schema:\n${UI_LAYOUT_SCHEMA_HINT}\n`
443
- : "\nThe raw SVG below is vector text — read element attributes (x, y, width, fill, text content) directly.\n";
444
- return `\n${header}${guidance}\n\`\`\`svg\n${decoded}\n\`\`\`\n[/Vision Bridge]\n`;
405
+ const observation = context.type === "design"
406
+ ? `I see ${images.length} SVG source(s). Vector markup is exact — map nodes to:\n${UI_LAYOUT_SCHEMA_HINT}\n\n\`\`\`svg\n${decoded}\n\`\`\``
407
+ : `I see ${images.length} SVG source(s). Vector markup:\n\n\`\`\`svg\n${decoded}\n\`\`\``;
408
+ return observation;
445
409
  }
446
410
  function buildContextualPrompt(imageCount, context) {
447
411
  const plural = imageCount > 1 ? `${imageCount} images` : "the image";
@@ -799,63 +763,9 @@ function walkAndStrip(obj) {
799
763
  }
800
764
  }
801
765
  function wrapWithFallback(output, imageCount) {
802
- const notice = `\n[Vision Bridge — ${imageCount} image(s) could not be analyzed. Use analyze_image or ask_vision_proxy with a file path to retry.]\n`;
766
+ const notice = formatNativeVisionUnavailable(imageCount, ["auto-analysis failed"]);
803
767
  if (typeof output === "string")
804
768
  return `${output}\n${notice}`;
805
769
  return { ...output, _visionNotice: notice };
806
770
  }
807
- async function callVisionModel(model, content, apiKey, signal, responseFormat) {
808
- const controller = new AbortController();
809
- let timedOut = false;
810
- const timeout = setTimeout(() => {
811
- timedOut = true;
812
- controller.abort();
813
- }, REQUEST_TIMEOUT_MS);
814
- if (signal) {
815
- signal.addEventListener("abort", () => controller.abort(), { once: true });
816
- }
817
- let res;
818
- try {
819
- res = await fetch(`${SILICONFLOW_BASE}/chat/completions`, {
820
- method: "POST",
821
- headers: {
822
- "Content-Type": "application/json",
823
- Authorization: `Bearer ${apiKey}`,
824
- },
825
- body: JSON.stringify({
826
- model,
827
- messages: [{ role: "user", content }],
828
- max_tokens: 3072,
829
- temperature: 0.1,
830
- ...(responseFormat ? { response_format: responseFormat } : {}),
831
- }),
832
- signal: controller.signal,
833
- });
834
- }
835
- catch (err) {
836
- clearTimeout(timeout);
837
- if (timedOut) {
838
- console.warn(`[vision-bridge] ${model} timed out after ${REQUEST_TIMEOUT_MS}ms`);
839
- return null;
840
- }
841
- if (signal?.aborted)
842
- throw err;
843
- console.warn(`[vision-bridge] ${model} network error: ${err instanceof Error ? err.message : String(err)}`);
844
- return null;
845
- }
846
- clearTimeout(timeout);
847
- if (!res.ok) {
848
- const errText = await res.text().catch(() => "");
849
- console.warn(`[vision-bridge] ${model} HTTP ${res.status}: ${errText.slice(0, 200)}`);
850
- return null;
851
- }
852
- const data = (await res.json().catch(() => null));
853
- return data?.choices?.[0]?.message?.content ?? null;
854
- }
855
- function formatBridgeResult(description, imageCount, model, contextType) {
856
- const header = imageCount > 1
857
- ? `[Vision Bridge — ${imageCount} images analyzed (${contextType}) via ${model}]`
858
- : `[Vision Bridge — image analyzed (${contextType}) via ${model}]`;
859
- return `\n${header}\n${description}\n[/Vision Bridge]\n`;
860
- }
861
771
  //# sourceMappingURL=mcp-vision-bridge.js.map
@@ -28,6 +28,12 @@ export function createOpenAICompatibleAdapter(config) {
28
28
  // placeholder because the SDK always emits an Authorization header from it.
29
29
  apiKey: config.apiKey ?? (config.oauthHeaders ? "oauth" : undefined),
30
30
  ...(config.oauthHeaders ? { headers: config.oauthHeaders } : {}),
31
+ transformRequestBody: (body) => {
32
+ const next = { ...body };
33
+ delete next.reasoning_effort;
34
+ delete next.verbosity;
35
+ return next;
36
+ },
31
37
  });
32
38
  return {
33
39
  id: config.id,
@@ -44,8 +50,9 @@ export function createOpenAICompatibleAdapter(config) {
44
50
  : undefined,
45
51
  });
46
52
  }
53
+ const cleanModel = config.model.startsWith("opencode/") ? config.model.slice(9) : config.model;
47
54
  const result = streamText({
48
- model: provider(config.model),
55
+ model: provider(cleanModel),
49
56
  messages: req.messages,
50
57
  tools: req.tools,
51
58
  toolChoice: req.toolChoice,
@@ -2,7 +2,7 @@
2
2
  * src/providers/pricing.ts
3
3
  *
4
4
  * Pricing lookup: catalog-first, then static fallback for providers not in catalog
5
- * (anthropic, openai, google — they're not in catalog.json).
5
+ * (anthropic, openai — they're not in catalog.json).
6
6
  * Phase 1 ships static; Phase 4 (WEB-02) adds remote fetch.
7
7
  * PROV-06 requirement.
8
8
  *
@@ -31,7 +31,7 @@ export declare const STATIC_PRICING_FALLBACK: Record<string, Record<string, Pric
31
31
  /**
32
32
  * Look up pricing for a (provider, model) pair.
33
33
  * Checks catalog first (preferred — single source of truth).
34
- * Falls back to static table for models not in catalog (anthropic, openai, google, legacy providers).
34
+ * Falls back to static table for models not in catalog (anthropic, openai, legacy providers).
35
35
  * Returns undefined if provider or model is not found in either source.
36
36
  * Ollama uses a '*' wildcard in the static table that matches any model.
37
37
  */
@@ -2,7 +2,7 @@
2
2
  * src/providers/pricing.ts
3
3
  *
4
4
  * Pricing lookup: catalog-first, then static fallback for providers not in catalog
5
- * (anthropic, openai, google — they're not in catalog.json).
5
+ * (anthropic, openai — they're not in catalog.json).
6
6
  * Phase 1 ships static; Phase 4 (WEB-02) adds remote fetch.
7
7
  * PROV-06 requirement.
8
8
  *
@@ -10,7 +10,7 @@
10
10
  * Freshness policy: re-verify every 60 days.
11
11
  */
12
12
  import { MODELS } from "../models/registry.js";
13
- // Static fallback for providers not in catalog (anthropic, openai, google).
13
+ // Static fallback for providers not in catalog (anthropic, openai).
14
14
  // verified 2026-04-29 from official provider pricing pages; cache prices
15
15
  // re-verified 2026-05-08 against deepseek-platform / openai / anthropic docs
16
16
  export const STATIC_PRICING_FALLBACK = {
@@ -51,10 +51,6 @@ export const STATIC_PRICING_FALLBACK = {
51
51
  cached_input_per_million_usd: 7.5,
52
52
  },
53
53
  },
54
- google: {
55
- "gemini-2.5-flash": { input_per_million_usd: 0.3, output_per_million_usd: 2.5 }, // ai.google.dev/pricing
56
- "gemini-pro-latest": { input_per_million_usd: 1.25, output_per_million_usd: 10.0 }, // ai.google.dev/pricing
57
- },
58
54
  deepseek: {
59
55
  // DeepSeek V4 chat: $0.27/M input miss, $0.027/M input hit, $1.10/M output
60
56
  // (api-docs.deepseek.com/quick_start/pricing). Flash/Pro split below mirrors
@@ -70,12 +66,6 @@ export const STATIC_PRICING_FALLBACK = {
70
66
  output_per_million_usd: 2.19,
71
67
  },
72
68
  },
73
- siliconflow: {
74
- "Qwen/Qwen2.5-Coder-32B-Instruct": { input_per_million_usd: 0.18, output_per_million_usd: 0.18 }, // siliconflow.com/pricing
75
- // DeepSeek models served via SiliconFlow — keep in sync with catalog.json.
76
- "deepseek-ai/DeepSeek-V4-Flash": { input_per_million_usd: 0.1, output_per_million_usd: 0.4 },
77
- "deepseek-ai/DeepSeek-V4-Pro": { input_per_million_usd: 2.0, output_per_million_usd: 8.0 },
78
- },
79
69
  ollama: {
80
70
  // local-only — zero variable cost
81
71
  "*": { input_per_million_usd: 0, output_per_million_usd: 0 },
@@ -84,7 +74,7 @@ export const STATIC_PRICING_FALLBACK = {
84
74
  /**
85
75
  * Look up pricing for a (provider, model) pair.
86
76
  * Checks catalog first (preferred — single source of truth).
87
- * Falls back to static table for models not in catalog (anthropic, openai, google, legacy providers).
77
+ * Falls back to static table for models not in catalog (anthropic, openai, legacy providers).
88
78
  * Returns undefined if provider or model is not found in either source.
89
79
  * Ollama uses a '*' wildcard in the static table that matches any model.
90
80
  */
@@ -6,6 +6,15 @@ export type ProviderFactory = ((modelId: string) => any) & {
6
6
  defaultProviderOptions?: Record<string, unknown>;
7
7
  /** AI SDK top-level call params to strip (backend doesn't accept them). */
8
8
  unsupportedParams?: ReadonlyArray<"maxOutputTokens" | "temperature" | "topP">;
9
+ /**
10
+ * The provider this factory talks to. Stamped by createProviderFactory so a
11
+ * caller that blindly reuses one provider's factory with a model from a
12
+ * DIFFERENT provider can be detected and auto-corrected in resolveModelRuntime
13
+ * (see the factory registry below) — otherwise the request would hit the wrong
14
+ * endpoint (e.g. a gateway-routed model POSTed straight to a native API,
15
+ * bypassing the configured gateway).
16
+ */
17
+ providerId?: ProviderId;
9
18
  };
10
19
  export interface ProviderFactoryResult {
11
20
  id: ProviderId;
@@ -19,6 +28,8 @@ export interface ResolvedModelRuntime {
19
28
  /** Top-level streamText params to omit (backend doesn't accept them). */
20
29
  unsupportedParams?: ReadonlyArray<"maxOutputTokens" | "temperature" | "topP">;
21
30
  }
31
+ /** Test seam: clear the registry between cases so entries never leak across specs. */
32
+ export declare function __resetProviderFactoryRegistry(): void;
22
33
  /**
23
34
  * Phase 12.2-G4: thin dispatcher delegating to the provider strategy registry.
24
35
  * Each provider's SDK wiring + `factory.responses` + `defaultProviderOptions`
@@ -34,8 +45,6 @@ export declare function createProviderFactory(id: ProviderId, opts: {
34
45
  * For OpenAI: loads stored OAuth tokens (auto-refreshing if expiring) and injects
35
46
  * them as Authorization / ChatGPT-Account-ID headers so subscription-backed
36
47
  * ChatGPT Plus/Pro accounts work without an API key.
37
- * For Google: loads stored Agy OAuth tokens and injects Authorization header
38
- * so users can authenticate via their Google account without a GOOGLE_API_KEY.
39
48
  * Falls back to API-key path when no tokens are stored.
40
49
  * All other providers: identical to createProviderFactory.
41
50
  */
@@ -87,5 +96,21 @@ export declare function buildTurnProviderOptions(runtime: ResolvedModelRuntime,
87
96
  * top-level path, and cost-leak specs cannot drift apart.
88
97
  */
89
98
  export declare function shouldDropParam(runtime: ResolvedModelRuntime, param: "maxOutputTokens" | "temperature" | "topP"): boolean;
99
+ /**
100
+ * Resolve the `temperature` spread for a streamText/generateText call.
101
+ *
102
+ * Returns `{}` (omit the param) when the model does not accept temperature
103
+ * (reasoning models, OAuth `unsupportedParams`), `{ temperature: <fixed> }`
104
+ * when the catalog pins a `fixed_temperature` (e.g. Moonshot/Kimi via
105
+ * opencode-go reject any value but `1` with "invalid temperature: only 1 is
106
+ * allowed for this model"), otherwise `{ temperature: <desired> }`.
107
+ *
108
+ * Every orchestrator call site that sets a temperature MUST go through this
109
+ * helper — inlining `temperature: 0.7` is what made every Kimi tool-loop turn
110
+ * fail wholesale (mirrors `resolveTemperature` used in src/council/llm.ts).
111
+ */
112
+ export declare function resolveTemperatureParam(runtime: ResolvedModelRuntime, desired: number): {
113
+ temperature?: number;
114
+ };
90
115
  export declare function detectProviderForModel(modelId: string): ProviderId;
91
116
  export declare function requireRuntimeProvider(runtime: ResolvedModelRuntime): ProviderId;