@alumbwe/anvil 1.0.20 → 1.0.22

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 (328) hide show
  1. package/package.json +74 -70
  2. package/src/agents/bundled-agents.generated.ts +4 -4
  3. package/src/chat.tsx +1703 -1698
  4. package/src/cli-args.ts +134 -134
  5. package/src/components/status-bar.tsx +331 -313
  6. package/src/hooks/helpers/send-message.ts +663 -654
  7. package/src/hooks/use-send-message.ts +806 -773
  8. package/src/index.tsx +473 -473
  9. package/src/state/chat-store.ts +553 -544
  10. package/src/utils/create-run-config.ts +121 -121
  11. package/src/utils/format-compact-number.ts +37 -0
  12. package/vendor/@anvil/common/package.json +27 -0
  13. package/vendor/@anvil/common/src/__tests__/agent-validation.test.ts +846 -0
  14. package/vendor/@anvil/common/src/__tests__/anvil-model-availability.test.ts +101 -0
  15. package/vendor/@anvil/common/src/__tests__/anvil-models.test.ts +1408 -0
  16. package/vendor/@anvil/common/src/__tests__/anvil-public-data-use-copy.test.ts +258 -0
  17. package/vendor/@anvil/common/src/__tests__/anvil-referral-tiers.test.ts +48 -0
  18. package/vendor/@anvil/common/src/__tests__/anvil-spend-ceilings.test.ts +282 -0
  19. package/vendor/@anvil/common/src/__tests__/anvil-trust.test.ts +526 -0
  20. package/vendor/@anvil/common/src/__tests__/deepseek-direct.test.ts +68 -0
  21. package/vendor/@anvil/common/src/__tests__/disposable-email.test.ts +132 -0
  22. package/vendor/@anvil/common/src/__tests__/dynamic-agent-template-schema.test.ts +422 -0
  23. package/vendor/@anvil/common/src/__tests__/env-ci.test.ts +167 -0
  24. package/vendor/@anvil/common/src/__tests__/env-process.test.ts +145 -0
  25. package/vendor/@anvil/common/src/__tests__/foreign-client-shipped-agents.test.ts +234 -0
  26. package/vendor/@anvil/common/src/__tests__/foreign-client-signals.test.ts +379 -0
  27. package/vendor/@anvil/common/src/__tests__/free-agents.test.ts +807 -0
  28. package/vendor/@anvil/common/src/__tests__/gravity-capi.test.ts +154 -0
  29. package/vendor/@anvil/common/src/__tests__/handlesteps-parsing.test.ts +246 -0
  30. package/vendor/@anvil/common/src/__tests__/kimi-k3-god-only.test.ts +77 -0
  31. package/vendor/@anvil/common/src/__tests__/model-config.test.ts +89 -0
  32. package/vendor/@anvil/common/src/__tests__/project-file-tree.test.ts +298 -0
  33. package/vendor/@anvil/common/src/__tests__/provisioned-model-tiers.test.ts +116 -0
  34. package/vendor/@anvil/common/src/__tests__/reasoning-effort.test.ts +167 -0
  35. package/vendor/@anvil/common/src/__tests__/reddit-capi.test.ts +132 -0
  36. package/vendor/@anvil/common/src/__tests__/response-ad-positions.test.ts +72 -0
  37. package/vendor/@anvil/common/src/__tests__/user-state.test.ts +30 -0
  38. package/vendor/@anvil/common/src/actions.ts +215 -0
  39. package/vendor/@anvil/common/src/analytics-core.ts +69 -0
  40. package/vendor/@anvil/common/src/analytics.ts +93 -0
  41. package/vendor/@anvil/common/src/api-keys/constants.ts +26 -0
  42. package/vendor/@anvil/common/src/browser-actions.ts +413 -0
  43. package/vendor/@anvil/common/src/constants/__tests__/anvil-onboarding-gate.test.ts +63 -0
  44. package/vendor/@anvil/common/src/constants/__tests__/anvil-onboarding.test.ts +246 -0
  45. package/vendor/@anvil/common/src/constants/__tests__/cf-worker-signals.test.ts +106 -0
  46. package/vendor/@anvil/common/src/constants/agents.ts +99 -0
  47. package/vendor/@anvil/common/src/constants/analytics-events.ts +435 -0
  48. package/vendor/@anvil/common/src/constants/anthropic.ts +73 -0
  49. package/vendor/@anvil/common/src/constants/anvil-data-use.ts +81 -0
  50. package/vendor/@anvil/common/src/constants/anvil-errors.ts +7 -0
  51. package/vendor/@anvil/common/src/constants/anvil-gemini-thinker.ts +21 -0
  52. package/vendor/@anvil/common/src/constants/anvil-model-ids.ts +11 -0
  53. package/vendor/@anvil/common/src/constants/anvil-models.ts +2130 -0
  54. package/vendor/@anvil/common/src/constants/anvil-onboarding-gate.ts +55 -0
  55. package/vendor/@anvil/common/src/constants/anvil-onboarding.ts +307 -0
  56. package/vendor/@anvil/common/src/constants/anvil-referral-tiers.ts +87 -0
  57. package/vendor/@anvil/common/src/constants/anvil-signup-block.ts +68 -0
  58. package/vendor/@anvil/common/src/constants/anvil-spend-ceilings.ts +450 -0
  59. package/vendor/@anvil/common/src/constants/anvil-trust.ts +976 -0
  60. package/vendor/@anvil/common/src/constants/auth.ts +18 -0
  61. package/vendor/@anvil/common/src/constants/byok.ts +2 -0
  62. package/vendor/@anvil/common/src/constants/cf-worker-signals.ts +132 -0
  63. package/vendor/@anvil/common/src/constants/composio.ts +34 -0
  64. package/vendor/@anvil/common/src/constants/deepseek-direct.ts +55 -0
  65. package/vendor/@anvil/common/src/constants/feedback.ts +13 -0
  66. package/vendor/@anvil/common/src/constants/foreign-client-signals.ts +272 -0
  67. package/vendor/@anvil/common/src/constants/free-agents.ts +777 -0
  68. package/vendor/@anvil/common/src/constants/gemini.ts +15 -0
  69. package/vendor/@anvil/common/src/constants/grant-priorities.ts +13 -0
  70. package/vendor/@anvil/common/src/constants/hosts.ts +6 -0
  71. package/vendor/@anvil/common/src/constants/images.ts +51 -0
  72. package/vendor/@anvil/common/src/constants/index.ts +7 -0
  73. package/vendor/@anvil/common/src/constants/knowledge.ts +35 -0
  74. package/vendor/@anvil/common/src/constants/limits.ts +23 -0
  75. package/vendor/@anvil/common/src/constants/model-config.ts +277 -0
  76. package/vendor/@anvil/common/src/constants/openrouter-attribution.ts +8 -0
  77. package/vendor/@anvil/common/src/constants/paths.ts +69 -0
  78. package/vendor/@anvil/common/src/constants/provider-routes.ts +317 -0
  79. package/vendor/@anvil/common/src/constants/reasoning-effort.ts +79 -0
  80. package/vendor/@anvil/common/src/constants/skills.ts +60 -0
  81. package/vendor/@anvil/common/src/constants/subscription-plans.ts +49 -0
  82. package/vendor/@anvil/common/src/constants/ui.ts +25 -0
  83. package/vendor/@anvil/common/src/env-ci.ts +36 -0
  84. package/vendor/@anvil/common/src/env-process.ts +95 -0
  85. package/vendor/@anvil/common/src/env-schema.ts +95 -0
  86. package/vendor/@anvil/common/src/env.ts +24 -0
  87. package/vendor/@anvil/common/src/gravity-capi.ts +207 -0
  88. package/vendor/@anvil/common/src/mcp/client.ts +233 -0
  89. package/vendor/@anvil/common/src/old-constants.ts +10 -0
  90. package/vendor/@anvil/common/src/project-file-tree.ts +355 -0
  91. package/vendor/@anvil/common/src/reddit-capi.ts +254 -0
  92. package/vendor/@anvil/common/src/schemas/feedback.ts +52 -0
  93. package/vendor/@anvil/common/src/schemas/logs.ts +66 -0
  94. package/vendor/@anvil/common/src/templates/agent-validation.ts +392 -0
  95. package/vendor/@anvil/common/src/templates/initial-agents-dir/LICENSE +202 -0
  96. package/vendor/@anvil/common/src/templates/initial-agents-dir/README.md +294 -0
  97. package/vendor/@anvil/common/src/templates/initial-agents-dir/examples/01-basic-diff-reviewer.ts +17 -0
  98. package/vendor/@anvil/common/src/templates/initial-agents-dir/examples/02-intermediate-git-committer.ts +78 -0
  99. package/vendor/@anvil/common/src/templates/initial-agents-dir/examples/03-advanced-file-explorer.ts +73 -0
  100. package/vendor/@anvil/common/src/templates/initial-agents-dir/my-custom-agent.ts +40 -0
  101. package/vendor/@anvil/common/src/templates/initial-agents-dir/package.json +6 -0
  102. package/vendor/@anvil/common/src/templates/initial-agents-dir/skills/README.md +65 -0
  103. package/vendor/@anvil/common/src/templates/initial-agents-dir/skills/example-skill/SKILL.md +29 -0
  104. package/vendor/@anvil/common/src/templates/initial-agents-dir/types/agent-definition.ts +497 -0
  105. package/vendor/@anvil/common/src/templates/initial-agents-dir/types/tools.ts +444 -0
  106. package/vendor/@anvil/common/src/templates/initial-agents-dir/types/util-types.ts +178 -0
  107. package/vendor/@anvil/common/src/testing/TESTING_PATTERNS.md +351 -0
  108. package/vendor/@anvil/common/src/testing/anvil-offer-invariants.ts +169 -0
  109. package/vendor/@anvil/common/src/testing/errors.ts +33 -0
  110. package/vendor/@anvil/common/src/testing/fixtures/agent-runtime.ts +334 -0
  111. package/vendor/@anvil/common/src/testing/impl/agent-runtime.ts +6 -0
  112. package/vendor/@anvil/common/src/testing/index.ts +84 -0
  113. package/vendor/@anvil/common/src/testing/mock-modules.ts +53 -0
  114. package/vendor/@anvil/common/src/testing/mock-types.ts +123 -0
  115. package/vendor/@anvil/common/src/testing/mocks/analytics.ts +261 -0
  116. package/vendor/@anvil/common/src/testing/mocks/child-process.ts +93 -0
  117. package/vendor/@anvil/common/src/testing/mocks/crypto.ts +218 -0
  118. package/vendor/@anvil/common/src/testing/mocks/database.ts +337 -0
  119. package/vendor/@anvil/common/src/testing/mocks/fetch.ts +219 -0
  120. package/vendor/@anvil/common/src/testing/mocks/filesystem.ts +166 -0
  121. package/vendor/@anvil/common/src/testing/mocks/index.ts +101 -0
  122. package/vendor/@anvil/common/src/testing/mocks/logger.ts +135 -0
  123. package/vendor/@anvil/common/src/testing/mocks/stream.ts +313 -0
  124. package/vendor/@anvil/common/src/testing/mocks/timers.ts +132 -0
  125. package/vendor/@anvil/common/src/testing/mocks/tree-sitter.ts +127 -0
  126. package/vendor/@anvil/common/src/testing/setup.ts +282 -0
  127. package/vendor/@anvil/common/src/testing-env-ci.ts +15 -0
  128. package/vendor/@anvil/common/src/testing-env-process.ts +78 -0
  129. package/vendor/@anvil/common/src/tools/__tests__/compile-tool-definitions.test.ts +34 -0
  130. package/vendor/@anvil/common/src/tools/compile-tool-definitions.ts +157 -0
  131. package/vendor/@anvil/common/src/tools/constants.ts +117 -0
  132. package/vendor/@anvil/common/src/tools/list.ts +190 -0
  133. package/vendor/@anvil/common/src/tools/params/__tests__/coerce-to-array.test.ts +213 -0
  134. package/vendor/@anvil/common/src/tools/params/__tests__/read-docs.test.ts +47 -0
  135. package/vendor/@anvil/common/src/tools/params/__tests__/render-ui.test.ts +65 -0
  136. package/vendor/@anvil/common/src/tools/params/tool/__tests__/run-terminal-command-timeout.test.ts +49 -0
  137. package/vendor/@anvil/common/src/tools/params/tool/add-message.ts +39 -0
  138. package/vendor/@anvil/common/src/tools/params/tool/add-subgoal.ts +57 -0
  139. package/vendor/@anvil/common/src/tools/params/tool/apply-patch.ts +110 -0
  140. package/vendor/@anvil/common/src/tools/params/tool/ask-user.ts +181 -0
  141. package/vendor/@anvil/common/src/tools/params/tool/browser-logs.ts +85 -0
  142. package/vendor/@anvil/common/src/tools/params/tool/cloud-plan-ready.ts +94 -0
  143. package/vendor/@anvil/common/src/tools/params/tool/code-search.ts +159 -0
  144. package/vendor/@anvil/common/src/tools/params/tool/composio.ts +131 -0
  145. package/vendor/@anvil/common/src/tools/params/tool/create-plan.ts +80 -0
  146. package/vendor/@anvil/common/src/tools/params/tool/end-turn.ts +57 -0
  147. package/vendor/@anvil/common/src/tools/params/tool/find-files.ts +60 -0
  148. package/vendor/@anvil/common/src/tools/params/tool/glob.ts +80 -0
  149. package/vendor/@anvil/common/src/tools/params/tool/gravity-index.ts +93 -0
  150. package/vendor/@anvil/common/src/tools/params/tool/list-directory.ts +58 -0
  151. package/vendor/@anvil/common/src/tools/params/tool/lookup-agent-info.ts +37 -0
  152. package/vendor/@anvil/common/src/tools/params/tool/propose-str-replace.ts +103 -0
  153. package/vendor/@anvil/common/src/tools/params/tool/propose-write-file.ts +71 -0
  154. package/vendor/@anvil/common/src/tools/params/tool/read-docs.ts +90 -0
  155. package/vendor/@anvil/common/src/tools/params/tool/read-files.ts +109 -0
  156. package/vendor/@anvil/common/src/tools/params/tool/read-subtree.ts +79 -0
  157. package/vendor/@anvil/common/src/tools/params/tool/read-url.ts +81 -0
  158. package/vendor/@anvil/common/src/tools/params/tool/render-ui.ts +168 -0
  159. package/vendor/@anvil/common/src/tools/params/tool/run-file-change-hooks.ts +57 -0
  160. package/vendor/@anvil/common/src/tools/params/tool/run-terminal-command.ts +211 -0
  161. package/vendor/@anvil/common/src/tools/params/tool/screenshot.ts +97 -0
  162. package/vendor/@anvil/common/src/tools/params/tool/set-messages.ts +44 -0
  163. package/vendor/@anvil/common/src/tools/params/tool/set-output.ts +61 -0
  164. package/vendor/@anvil/common/src/tools/params/tool/skill.ts +59 -0
  165. package/vendor/@anvil/common/src/tools/params/tool/spawn-agent-inline.ts +56 -0
  166. package/vendor/@anvil/common/src/tools/params/tool/spawn-agents.ts +154 -0
  167. package/vendor/@anvil/common/src/tools/params/tool/str-replace.ts +107 -0
  168. package/vendor/@anvil/common/src/tools/params/tool/suggest-followups.ts +97 -0
  169. package/vendor/@anvil/common/src/tools/params/tool/task-completed.ts +61 -0
  170. package/vendor/@anvil/common/src/tools/params/tool/think-deeply.ts +56 -0
  171. package/vendor/@anvil/common/src/tools/params/tool/update-subgoal.ts +89 -0
  172. package/vendor/@anvil/common/src/tools/params/tool/vision-analyze.ts +82 -0
  173. package/vendor/@anvil/common/src/tools/params/tool/web-search.ts +73 -0
  174. package/vendor/@anvil/common/src/tools/params/tool/write-file.ts +71 -0
  175. package/vendor/@anvil/common/src/tools/params/tool/write-todos.ts +67 -0
  176. package/vendor/@anvil/common/src/tools/params/utils.ts +150 -0
  177. package/vendor/@anvil/common/src/tools/utils.ts +24 -0
  178. package/vendor/@anvil/common/src/types/__tests__/dynamic-agent-template.test.ts +20 -0
  179. package/vendor/@anvil/common/src/types/agent-template.ts +215 -0
  180. package/vendor/@anvil/common/src/types/anvil-session.ts +535 -0
  181. package/vendor/@anvil/common/src/types/anvil-streak.ts +6 -0
  182. package/vendor/@anvil/common/src/types/anvil-usage.ts +64 -0
  183. package/vendor/@anvil/common/src/types/api/agents/publish.ts +61 -0
  184. package/vendor/@anvil/common/src/types/bun-test.d.ts +5 -0
  185. package/vendor/@anvil/common/src/types/contracts/agent-runtime.ts +75 -0
  186. package/vendor/@anvil/common/src/types/contracts/analytics.ts +9 -0
  187. package/vendor/@anvil/common/src/types/contracts/bigquery.ts +55 -0
  188. package/vendor/@anvil/common/src/types/contracts/billing.ts +46 -0
  189. package/vendor/@anvil/common/src/types/contracts/client.ts +53 -0
  190. package/vendor/@anvil/common/src/types/contracts/database.ts +112 -0
  191. package/vendor/@anvil/common/src/types/contracts/env.ts +203 -0
  192. package/vendor/@anvil/common/src/types/contracts/llm.ts +191 -0
  193. package/vendor/@anvil/common/src/types/contracts/logger.ts +14 -0
  194. package/vendor/@anvil/common/src/types/contracts/logs.ts +34 -0
  195. package/vendor/@anvil/common/src/types/contracts/trace.ts +21 -0
  196. package/vendor/@anvil/common/src/types/dynamic-agent-template.ts +328 -0
  197. package/vendor/@anvil/common/src/types/filesystem.ts +10 -0
  198. package/vendor/@anvil/common/src/types/function-params.ts +33 -0
  199. package/vendor/@anvil/common/src/types/grant.ts +20 -0
  200. package/vendor/@anvil/common/src/types/gravity-index.ts +170 -0
  201. package/vendor/@anvil/common/src/types/json.ts +29 -0
  202. package/vendor/@anvil/common/src/types/mcp.ts +24 -0
  203. package/vendor/@anvil/common/src/types/messages/anvil-message.ts +58 -0
  204. package/vendor/@anvil/common/src/types/messages/content-part.ts +59 -0
  205. package/vendor/@anvil/common/src/types/messages/data-content.ts +14 -0
  206. package/vendor/@anvil/common/src/types/messages/provider-metadata.ts +13 -0
  207. package/vendor/@anvil/common/src/types/organization.ts +118 -0
  208. package/vendor/@anvil/common/src/types/print-mode.ts +121 -0
  209. package/vendor/@anvil/common/src/types/publisher.ts +67 -0
  210. package/vendor/@anvil/common/src/types/session-state.ts +149 -0
  211. package/vendor/@anvil/common/src/types/skill.ts +86 -0
  212. package/vendor/@anvil/common/src/types/source.ts +11 -0
  213. package/vendor/@anvil/common/src/types/spawn.ts +13 -0
  214. package/vendor/@anvil/common/src/types/subscription.ts +67 -0
  215. package/vendor/@anvil/common/src/types/usage.ts +16 -0
  216. package/vendor/@anvil/common/src/types/util.ts +3 -0
  217. package/vendor/@anvil/common/src/util/__tests__/ad-user-agent.test.ts +26 -0
  218. package/vendor/@anvil/common/src/util/__tests__/analytics-dispatcher.test.ts +122 -0
  219. package/vendor/@anvil/common/src/util/__tests__/analytics-log.test.ts +102 -0
  220. package/vendor/@anvil/common/src/util/__tests__/analytics-sampling.test.ts +143 -0
  221. package/vendor/@anvil/common/src/util/__tests__/anvil-streak.test.ts +202 -0
  222. package/vendor/@anvil/common/src/util/__tests__/anvil-usage-summary.test.ts +193 -0
  223. package/vendor/@anvil/common/src/util/__tests__/axiom-only-log.test.ts +140 -0
  224. package/vendor/@anvil/common/src/util/__tests__/client-user-agent.test.ts +148 -0
  225. package/vendor/@anvil/common/src/util/__tests__/engagement-tracker.test.ts +115 -0
  226. package/vendor/@anvil/common/src/util/__tests__/env-file-path.test.ts +57 -0
  227. package/vendor/@anvil/common/src/util/__tests__/error-abort.test.ts +774 -0
  228. package/vendor/@anvil/common/src/util/__tests__/error-api-details.test.ts +206 -0
  229. package/vendor/@anvil/common/src/util/__tests__/file-read-limits.test.ts +173 -0
  230. package/vendor/@anvil/common/src/util/__tests__/format-code-search.test.ts +60 -0
  231. package/vendor/@anvil/common/src/util/__tests__/log-mirror.test.ts +31 -0
  232. package/vendor/@anvil/common/src/util/__tests__/messages.test.ts +1252 -0
  233. package/vendor/@anvil/common/src/util/__tests__/partial-json-delta.test.ts +505 -0
  234. package/vendor/@anvil/common/src/util/__tests__/path.test.ts +22 -0
  235. package/vendor/@anvil/common/src/util/__tests__/project-ignore.test.ts +90 -0
  236. package/vendor/@anvil/common/src/util/__tests__/promise.test.ts +325 -0
  237. package/vendor/@anvil/common/src/util/__tests__/rate-limit.test.ts +28 -0
  238. package/vendor/@anvil/common/src/util/__tests__/reddit-anvil-retention.test.ts +130 -0
  239. package/vendor/@anvil/common/src/util/__tests__/saxy.test.ts +1008 -0
  240. package/vendor/@anvil/common/src/util/__tests__/split-data.test.ts +289 -0
  241. package/vendor/@anvil/common/src/util/__tests__/string.test.ts +239 -0
  242. package/vendor/@anvil/common/src/util/__tests__/thread-title.test.ts +70 -0
  243. package/vendor/@anvil/common/src/util/__tests__/tool-result-media-order.test.ts +108 -0
  244. package/vendor/@anvil/common/src/util/__tests__/ttft-histogram.test.ts +180 -0
  245. package/vendor/@anvil/common/src/util/__tests__/with-timeout.test.ts +24 -0
  246. package/vendor/@anvil/common/src/util/__tests__/zoned-time.test.ts +88 -0
  247. package/vendor/@anvil/common/src/util/ad-user-agent.ts +25 -0
  248. package/vendor/@anvil/common/src/util/agent-file-utils.ts +110 -0
  249. package/vendor/@anvil/common/src/util/agent-id-parsing.ts +136 -0
  250. package/vendor/@anvil/common/src/util/agent-name-normalization.ts +38 -0
  251. package/vendor/@anvil/common/src/util/agent-name-resolver.ts +86 -0
  252. package/vendor/@anvil/common/src/util/analytics-dispatcher.ts +82 -0
  253. package/vendor/@anvil/common/src/util/analytics-log.ts +78 -0
  254. package/vendor/@anvil/common/src/util/analytics-sampling.ts +255 -0
  255. package/vendor/@anvil/common/src/util/anvil-model-availability.ts +102 -0
  256. package/vendor/@anvil/common/src/util/anvil-privacy.ts +82 -0
  257. package/vendor/@anvil/common/src/util/anvil-streak-line.ts +103 -0
  258. package/vendor/@anvil/common/src/util/anvil-streak.ts +156 -0
  259. package/vendor/@anvil/common/src/util/anvil-usage-summary.ts +125 -0
  260. package/vendor/@anvil/common/src/util/array.ts +31 -0
  261. package/vendor/@anvil/common/src/util/axiom-only-log.ts +124 -0
  262. package/vendor/@anvil/common/src/util/cache-debug.ts +171 -0
  263. package/vendor/@anvil/common/src/util/client-user-agent.ts +114 -0
  264. package/vendor/@anvil/common/src/util/credentials.ts +26 -0
  265. package/vendor/@anvil/common/src/util/currency.ts +25 -0
  266. package/vendor/@anvil/common/src/util/dates.ts +81 -0
  267. package/vendor/@anvil/common/src/util/disposable-email.ts +277 -0
  268. package/vendor/@anvil/common/src/util/engagement-tracker.ts +129 -0
  269. package/vendor/@anvil/common/src/util/env-file-path.ts +40 -0
  270. package/vendor/@anvil/common/src/util/error.ts +562 -0
  271. package/vendor/@anvil/common/src/util/file-read-limits.ts +236 -0
  272. package/vendor/@anvil/common/src/util/file.ts +339 -0
  273. package/vendor/@anvil/common/src/util/format-code-search.ts +115 -0
  274. package/vendor/@anvil/common/src/util/lazy-response-ads.ts +92 -0
  275. package/vendor/@anvil/common/src/util/log-data.ts +57 -0
  276. package/vendor/@anvil/common/src/util/log-ingest.ts +58 -0
  277. package/vendor/@anvil/common/src/util/log-mirror.ts +34 -0
  278. package/vendor/@anvil/common/src/util/lru-cache.ts +67 -0
  279. package/vendor/@anvil/common/src/util/messages.ts +685 -0
  280. package/vendor/@anvil/common/src/util/min-heap.ts +87 -0
  281. package/vendor/@anvil/common/src/util/model-utils.ts +4 -0
  282. package/vendor/@anvil/common/src/util/object.ts +128 -0
  283. package/vendor/@anvil/common/src/util/partial-json-delta.ts +89 -0
  284. package/vendor/@anvil/common/src/util/path.ts +15 -0
  285. package/vendor/@anvil/common/src/util/project-ignore.ts +119 -0
  286. package/vendor/@anvil/common/src/util/promise.ts +73 -0
  287. package/vendor/@anvil/common/src/util/random.ts +15 -0
  288. package/vendor/@anvil/common/src/util/rate-limit.ts +56 -0
  289. package/vendor/@anvil/common/src/util/reddit-anvil-retention.ts +60 -0
  290. package/vendor/@anvil/common/src/util/reddit-capi-events.ts +36 -0
  291. package/vendor/@anvil/common/src/util/response-ad-positions.ts +54 -0
  292. package/vendor/@anvil/common/src/util/saxy.ts +741 -0
  293. package/vendor/@anvil/common/src/util/skills.test.ts +44 -0
  294. package/vendor/@anvil/common/src/util/skills.ts +36 -0
  295. package/vendor/@anvil/common/src/util/split-data.ts +259 -0
  296. package/vendor/@anvil/common/src/util/stop-sequence.ts +61 -0
  297. package/vendor/@anvil/common/src/util/string.ts +426 -0
  298. package/vendor/@anvil/common/src/util/system-info.ts +53 -0
  299. package/vendor/@anvil/common/src/util/thread-title.ts +46 -0
  300. package/vendor/@anvil/common/src/util/ttft-histogram.ts +73 -0
  301. package/vendor/@anvil/common/src/util/xml-parser.ts +27 -0
  302. package/vendor/@anvil/common/src/util/xml.ts +17 -0
  303. package/vendor/@anvil/common/src/util/zod-schema.ts +25 -0
  304. package/vendor/@anvil/common/src/util/zoned-time.ts +136 -0
  305. package/vendor/@anvil/common/src/utils/ask-user-bridge.ts +44 -0
  306. package/vendor/@anvil/sdk/dist/index.cjs +52297 -0
  307. package/vendor/@anvil/sdk/dist/index.cjs.map +440 -0
  308. package/vendor/@anvil/sdk/dist/index.d.ts +4277 -0
  309. package/vendor/@anvil/sdk/dist/index.mjs +52290 -0
  310. package/vendor/@anvil/sdk/dist/index.mjs.map +440 -0
  311. package/vendor/@anvil/sdk/dist/vendor/ai.cjs +30886 -0
  312. package/vendor/@anvil/sdk/dist/vendor/ripgrep/arm64-darwin/rg +0 -0
  313. package/vendor/@anvil/sdk/dist/vendor/ripgrep/arm64-linux/rg +0 -0
  314. package/vendor/@anvil/sdk/dist/vendor/ripgrep/x64-darwin/rg +0 -0
  315. package/vendor/@anvil/sdk/dist/vendor/ripgrep/x64-linux/rg +0 -0
  316. package/vendor/@anvil/sdk/dist/vendor/ripgrep/x64-win32/rg.exe +0 -0
  317. package/vendor/@anvil/sdk/dist/wasm/tree-sitter-c-sharp.wasm +0 -0
  318. package/vendor/@anvil/sdk/dist/wasm/tree-sitter-cpp.wasm +0 -0
  319. package/vendor/@anvil/sdk/dist/wasm/tree-sitter-go.wasm +0 -0
  320. package/vendor/@anvil/sdk/dist/wasm/tree-sitter-java.wasm +0 -0
  321. package/vendor/@anvil/sdk/dist/wasm/tree-sitter-javascript.wasm +0 -0
  322. package/vendor/@anvil/sdk/dist/wasm/tree-sitter-python.wasm +0 -0
  323. package/vendor/@anvil/sdk/dist/wasm/tree-sitter-ruby.wasm +0 -0
  324. package/vendor/@anvil/sdk/dist/wasm/tree-sitter-rust.wasm +0 -0
  325. package/vendor/@anvil/sdk/dist/wasm/tree-sitter-tsx.wasm +0 -0
  326. package/vendor/@anvil/sdk/dist/wasm/tree-sitter-typescript.wasm +0 -0
  327. package/vendor/@anvil/sdk/dist/wasm/tree-sitter.wasm +0 -0
  328. package/vendor/@anvil/sdk/package.json +21 -0
@@ -0,0 +1,117 @@
1
+ import { COMPOSIO_META_TOOL_NAMES } from '../constants/composio'
2
+
3
+ import type { ToolResultOutput } from '../types/messages/content-part'
4
+ import type { Tool } from 'ai'
5
+
6
+ export const toolNameParam = 'cb_tool_name'
7
+ export const endsAgentStepParam = 'cb_easp'
8
+ export const toolXmlName = 'anvil_tool_call'
9
+ export const startToolTag = `<${toolXmlName}>\n`
10
+ export const endToolTag = `\n</${toolXmlName}>`
11
+
12
+ export const TOOLS_WHICH_WONT_FORCE_NEXT_STEP = [
13
+ 'think_deeply',
14
+ 'set_output',
15
+ 'set_messages',
16
+ 'add_message',
17
+ 'update_subgoal',
18
+ 'create_plan',
19
+ 'render_ui',
20
+ 'suggest_followups',
21
+ 'suggest_prompts',
22
+ 'task_completed',
23
+ ]
24
+
25
+ // List of all available tools
26
+ export const toolNames = [
27
+ 'apply_patch',
28
+ 'add_subgoal',
29
+ 'add_message',
30
+ 'ask_user',
31
+ 'browser_logs',
32
+ 'code_search',
33
+ 'cloud_plan_ready',
34
+ 'create_plan',
35
+ 'end_turn',
36
+ 'find_files',
37
+ 'glob',
38
+ 'gravity_index',
39
+ 'list_directory',
40
+ 'lookup_agent_info',
41
+ 'propose_str_replace',
42
+ 'propose_write_file',
43
+ 'read_docs',
44
+ 'read_files',
45
+ 'read_subtree',
46
+ 'read_url',
47
+ 'render_ui',
48
+ 'run_file_change_hooks',
49
+ 'run_terminal_command',
50
+ 'set_messages',
51
+ 'set_output',
52
+ 'skill',
53
+ 'spawn_agents',
54
+ 'spawn_agent_inline',
55
+ 'str_replace',
56
+ 'suggest_followups',
57
+ 'task_completed',
58
+ 'think_deeply',
59
+ 'update_subgoal',
60
+ 'screenshot',
61
+ 'vision_analyze',
62
+ 'web_search',
63
+ 'write_file',
64
+ 'write_todos',
65
+ ...COMPOSIO_META_TOOL_NAMES,
66
+ ] as const
67
+
68
+ export const publishedTools = [
69
+ 'apply_patch',
70
+ 'add_message',
71
+ 'ask_user',
72
+ 'code_search',
73
+ 'cloud_plan_ready',
74
+ 'end_turn',
75
+ 'find_files',
76
+ 'glob',
77
+ 'gravity_index',
78
+ 'list_directory',
79
+ 'lookup_agent_info',
80
+ 'propose_str_replace',
81
+ 'propose_write_file',
82
+ 'read_docs',
83
+ 'read_files',
84
+ 'read_subtree',
85
+ 'read_url',
86
+ 'render_ui',
87
+ 'run_file_change_hooks',
88
+ 'run_terminal_command',
89
+ 'screenshot',
90
+ 'vision_analyze',
91
+ 'set_messages',
92
+ 'set_output',
93
+ 'skill',
94
+ 'spawn_agents',
95
+ 'str_replace',
96
+ 'suggest_followups',
97
+ 'task_completed',
98
+ 'think_deeply',
99
+ 'web_search',
100
+ 'write_file',
101
+ 'write_todos',
102
+ // 'spawn_agent_inline',
103
+ ] as const
104
+
105
+ export type ToolName = (typeof toolNames)[number]
106
+ export type PublishedToolName = (typeof publishedTools)[number]
107
+
108
+ /** Only used for validating tool definitions */
109
+ export type $ToolParams<T extends ToolName = ToolName> = Required<
110
+ Pick<
111
+ Tool<any, ToolResultOutput[]>,
112
+ 'description' | 'inputSchema' | 'outputSchema'
113
+ >
114
+ > & {
115
+ toolName: T
116
+ endsAgentStep: boolean
117
+ }
@@ -0,0 +1,190 @@
1
+ import z from 'zod/v4'
2
+
3
+ import { FileChangeSchema } from '../actions'
4
+ import { addMessageParams } from './params/tool/add-message'
5
+ import { addSubgoalParams } from './params/tool/add-subgoal'
6
+ import { applyPatchParams } from './params/tool/apply-patch'
7
+ import { askUserParams } from './params/tool/ask-user'
8
+ import { browserLogsParams } from './params/tool/browser-logs'
9
+ import { codeSearchParams } from './params/tool/code-search'
10
+ import { cloudPlanReadyParams } from './params/tool/cloud-plan-ready'
11
+ import { composioMetaToolParams } from './params/tool/composio'
12
+ import { createPlanParams } from './params/tool/create-plan'
13
+ import { endTurnParams } from './params/tool/end-turn'
14
+ import { findFilesParams } from './params/tool/find-files'
15
+ import { globParams } from './params/tool/glob'
16
+ import { gravityIndexParams } from './params/tool/gravity-index'
17
+ import { listDirectoryParams } from './params/tool/list-directory'
18
+ import { lookupAgentInfoParams } from './params/tool/lookup-agent-info'
19
+ import { proposeStrReplaceParams } from './params/tool/propose-str-replace'
20
+ import { proposeWriteFileParams } from './params/tool/propose-write-file'
21
+ import { readDocsParams } from './params/tool/read-docs'
22
+ import { readFilesParams } from './params/tool/read-files'
23
+ import { readSubtreeParams } from './params/tool/read-subtree'
24
+ import { readUrlParams } from './params/tool/read-url'
25
+ import { renderUIParams } from './params/tool/render-ui'
26
+ import { runFileChangeHooksParams } from './params/tool/run-file-change-hooks'
27
+ import { screenshotParams } from './params/tool/screenshot'
28
+ import { visionAnalyzeParams } from './params/tool/vision-analyze'
29
+ import { runTerminalCommandParams } from './params/tool/run-terminal-command'
30
+ import { setMessagesParams } from './params/tool/set-messages'
31
+ import { setOutputParams } from './params/tool/set-output'
32
+ import { skillParams } from './params/tool/skill'
33
+ import { spawnAgentInlineParams } from './params/tool/spawn-agent-inline'
34
+ import { spawnAgentsParams } from './params/tool/spawn-agents'
35
+ import { strReplaceParams } from './params/tool/str-replace'
36
+ import { suggestFollowupsParams } from './params/tool/suggest-followups'
37
+ import { taskCompletedParams } from './params/tool/task-completed'
38
+ import { thinkDeeplyParams } from './params/tool/think-deeply'
39
+ import { updateSubgoalParams } from './params/tool/update-subgoal'
40
+ import { webSearchParams } from './params/tool/web-search'
41
+ import { writeFileParams } from './params/tool/write-file'
42
+ import { writeTodosParams } from './params/tool/write-todos'
43
+
44
+ import type { $ToolParams, PublishedToolName, ToolName } from './constants'
45
+ import type { ToolMessage } from '../types/messages/anvil-message'
46
+ import type { ToolCallPart } from '../types/messages/content-part'
47
+
48
+ export const toolParams = {
49
+ add_message: addMessageParams,
50
+ add_subgoal: addSubgoalParams,
51
+ apply_patch: applyPatchParams,
52
+ ask_user: askUserParams,
53
+ browser_logs: browserLogsParams,
54
+ code_search: codeSearchParams,
55
+ cloud_plan_ready: cloudPlanReadyParams,
56
+ create_plan: createPlanParams,
57
+ end_turn: endTurnParams,
58
+ find_files: findFilesParams,
59
+ glob: globParams,
60
+ gravity_index: gravityIndexParams,
61
+ list_directory: listDirectoryParams,
62
+ lookup_agent_info: lookupAgentInfoParams,
63
+ propose_str_replace: proposeStrReplaceParams,
64
+ propose_write_file: proposeWriteFileParams,
65
+ read_docs: readDocsParams,
66
+ read_files: readFilesParams,
67
+ read_subtree: readSubtreeParams,
68
+ read_url: readUrlParams,
69
+ render_ui: renderUIParams,
70
+ run_file_change_hooks: runFileChangeHooksParams,
71
+ run_terminal_command: runTerminalCommandParams,
72
+ set_messages: setMessagesParams,
73
+ set_output: setOutputParams,
74
+ skill: skillParams,
75
+ spawn_agents: spawnAgentsParams,
76
+ spawn_agent_inline: spawnAgentInlineParams,
77
+ str_replace: strReplaceParams,
78
+ suggest_followups: suggestFollowupsParams,
79
+ task_completed: taskCompletedParams,
80
+ think_deeply: thinkDeeplyParams,
81
+ update_subgoal: updateSubgoalParams,
82
+ screenshot: screenshotParams,
83
+ vision_analyze: visionAnalyzeParams,
84
+ web_search: webSearchParams,
85
+ write_file: writeFileParams,
86
+ write_todos: writeTodosParams,
87
+ ...composioMetaToolParams,
88
+ } satisfies {
89
+ [K in ToolName]: $ToolParams<K>
90
+ }
91
+
92
+ // Tool call from LLM after parsing
93
+ export type AnvilToolCall<T extends ToolName = ToolName> = {
94
+ [K in ToolName]: {
95
+ toolName: K
96
+ input: z.infer<(typeof toolParams)[K]['inputSchema']>
97
+ } & Omit<ToolCallPart, 'type'>
98
+ }[T]
99
+
100
+ export type AnvilToolOutput<T extends ToolName = ToolName> = {
101
+ [K in ToolName]: K extends ToolName
102
+ ? z.infer<(typeof toolParams)[K]['outputSchema']>
103
+ : never
104
+ }[T]
105
+
106
+ export type AnvilToolMessage<T extends ToolName = ToolName> = ToolMessage & {
107
+ content: AnvilToolOutput<T>
108
+ }
109
+
110
+ // Tool call to send to client
111
+ export const clientToolCallSchema = z.discriminatedUnion('toolName', [
112
+ z.object({
113
+ toolName: z.literal('apply_patch'),
114
+ input: toolParams.apply_patch.inputSchema,
115
+ }),
116
+ z.object({
117
+ toolName: z.literal('ask_user'),
118
+ input: toolParams.ask_user.inputSchema,
119
+ }),
120
+ z.object({
121
+ toolName: z.literal('browser_logs'),
122
+ input: toolParams.browser_logs.inputSchema,
123
+ }),
124
+ z.object({
125
+ toolName: z.literal('code_search'),
126
+ input: toolParams.code_search.inputSchema,
127
+ }),
128
+ z.object({
129
+ toolName: z.literal('create_plan'),
130
+ input: FileChangeSchema,
131
+ }),
132
+ z.object({
133
+ toolName: z.literal('glob'),
134
+ input: toolParams.glob.inputSchema,
135
+ }),
136
+ z.object({
137
+ toolName: z.literal('list_directory'),
138
+ input: toolParams.list_directory.inputSchema,
139
+ }),
140
+ z.object({
141
+ toolName: z.literal('run_file_change_hooks'),
142
+ input: toolParams.run_file_change_hooks.inputSchema,
143
+ }),
144
+ z.object({
145
+ toolName: z.literal('read_url'),
146
+ input: toolParams.read_url.inputSchema,
147
+ }),
148
+ z.object({
149
+ toolName: z.literal('run_terminal_command'),
150
+ input: toolParams.run_terminal_command.inputSchema.and(
151
+ z.object({ mode: z.enum(['assistant', 'user']) }),
152
+ ),
153
+ }),
154
+ z.object({
155
+ toolName: z.literal('str_replace'),
156
+ input: FileChangeSchema,
157
+ }),
158
+ z.object({
159
+ toolName: z.literal('write_file'),
160
+ input: FileChangeSchema,
161
+ }),
162
+ z.object({
163
+ toolName: z.literal('composio_manage_connections'),
164
+ input: toolParams.composio_manage_connections.inputSchema,
165
+ }),
166
+ z.object({
167
+ toolName: z.literal('composio_multi_execute_tool'),
168
+ input: toolParams.composio_multi_execute_tool.inputSchema,
169
+ }),
170
+ z.object({
171
+ toolName: z.literal('composio_search_tools'),
172
+ input: toolParams.composio_search_tools.inputSchema,
173
+ }),
174
+ z.object({
175
+ toolName: z.literal('composio_get_tool_schemas'),
176
+ input: toolParams.composio_get_tool_schemas.inputSchema,
177
+ }),
178
+ ])
179
+ export const clientToolNames = clientToolCallSchema.def.options.map(
180
+ (opt) => opt.shape.toolName.value,
181
+ ) satisfies ToolName[]
182
+ export type ClientToolName = (typeof clientToolNames)[number]
183
+
184
+ export type ClientToolCall<T extends ClientToolName = ClientToolName> = Extract<
185
+ z.infer<typeof clientToolCallSchema>,
186
+ { toolName: T }
187
+ > &
188
+ Pick<ToolCallPart, 'toolCallId' | 'toolName' | 'input' | 'providerOptions'>
189
+
190
+ export type PublishedClientToolName = Extract<ClientToolName, PublishedToolName>
@@ -0,0 +1,213 @@
1
+ import { describe, expect, it } from 'bun:test'
2
+ import z from 'zod/v4'
3
+
4
+ import {
5
+ coerceToArray,
6
+ coerceToObject,
7
+ normalizeReplacementAliases,
8
+ } from '../utils'
9
+
10
+ describe('coerceToArray', () => {
11
+ it('passes through arrays unchanged', () => {
12
+ expect(coerceToArray(['a', 'b'])).toEqual(['a', 'b'])
13
+ expect(coerceToArray([{ old: 'x', new: 'y' }])).toEqual([
14
+ { old: 'x', new: 'y' },
15
+ ])
16
+ expect(coerceToArray([])).toEqual([])
17
+ })
18
+
19
+ it('wraps a single string in an array', () => {
20
+ expect(coerceToArray('file.ts')).toEqual(['file.ts'])
21
+ })
22
+
23
+ it('wraps a single object in an array', () => {
24
+ expect(coerceToArray({ old: 'x', new: 'y' })).toEqual([
25
+ { old: 'x', new: 'y' },
26
+ ])
27
+ })
28
+
29
+ it('wraps a single number in an array', () => {
30
+ expect(coerceToArray(42)).toEqual([42])
31
+ })
32
+
33
+ it('parses a stringified JSON array', () => {
34
+ expect(coerceToArray('["file1.ts", "file2.ts"]')).toEqual([
35
+ 'file1.ts',
36
+ 'file2.ts',
37
+ ])
38
+ })
39
+
40
+ it('wraps a non-JSON string (does not parse as array)', () => {
41
+ expect(coerceToArray('not-json')).toEqual(['not-json'])
42
+ })
43
+
44
+ it('wraps a stringified JSON object (not an array) in an array', () => {
45
+ expect(coerceToArray('{"key": "value"}')).toEqual(['{"key": "value"}'])
46
+ })
47
+
48
+ it('passes through null', () => {
49
+ expect(coerceToArray(null)).toBeNull()
50
+ })
51
+
52
+ it('passes through undefined', () => {
53
+ expect(coerceToArray(undefined)).toBeUndefined()
54
+ })
55
+ })
56
+
57
+ describe('coerceToObject', () => {
58
+ it('passes through objects unchanged', () => {
59
+ expect(coerceToObject({ key: 'value' })).toEqual({ key: 'value' })
60
+ })
61
+
62
+ it('parses a stringified JSON object', () => {
63
+ expect(coerceToObject('{"key": "value"}')).toEqual({ key: 'value' })
64
+ })
65
+
66
+ it('leaves non-JSON strings untouched', () => {
67
+ expect(coerceToObject('not-json')).toBe('not-json')
68
+ })
69
+
70
+ it('passes through arrays and primitives so validation can reject them', () => {
71
+ expect(coerceToObject(['a'])).toEqual(['a'])
72
+ expect(coerceToObject(1)).toBe(1)
73
+ })
74
+ })
75
+
76
+ describe('coerceToArray with Zod schemas', () => {
77
+ it('coerces a single string into an array for z.array(z.string())', () => {
78
+ const schema = z.object({
79
+ paths: z.preprocess(coerceToArray, z.array(z.string())),
80
+ })
81
+ const result = schema.safeParse({ paths: 'file.ts' })
82
+ expect(result.success).toBe(true)
83
+ if (result.success) {
84
+ expect(result.data.paths).toEqual(['file.ts'])
85
+ }
86
+ })
87
+
88
+ it('coerces a single object into an array for z.array(z.object(...))', () => {
89
+ const schema = z.object({
90
+ replacements: z.preprocess(
91
+ coerceToArray,
92
+ z.array(z.object({ old: z.string(), new: z.string() })),
93
+ ),
94
+ })
95
+ const result = schema.safeParse({ replacements: { old: 'x', new: 'y' } })
96
+ expect(result.success).toBe(true)
97
+ if (result.success) {
98
+ expect(result.data.replacements).toEqual([{ old: 'x', new: 'y' }])
99
+ }
100
+ })
101
+
102
+ it('still validates correctly when already an array', () => {
103
+ const schema = z.object({
104
+ paths: z.preprocess(coerceToArray, z.array(z.string())),
105
+ })
106
+ const result = schema.safeParse({ paths: ['a.ts', 'b.ts'] })
107
+ expect(result.success).toBe(true)
108
+ if (result.success) {
109
+ expect(result.data.paths).toEqual(['a.ts', 'b.ts'])
110
+ }
111
+ })
112
+
113
+ it('still rejects invalid inner types after coercion', () => {
114
+ const schema = z.object({
115
+ paths: z.preprocess(coerceToArray, z.array(z.string())),
116
+ })
117
+ const result = schema.safeParse({ paths: 123 })
118
+ expect(result.success).toBe(false)
119
+ })
120
+
121
+ it('works with optional arrays', () => {
122
+ const schema = z.object({
123
+ paths: z.preprocess(coerceToArray, z.array(z.string())).optional(),
124
+ })
125
+ const withValue = schema.safeParse({ paths: 'file.ts' })
126
+ expect(withValue.success).toBe(true)
127
+ if (withValue.success) {
128
+ expect(withValue.data.paths).toEqual(['file.ts'])
129
+ }
130
+
131
+ const withoutValue = schema.safeParse({})
132
+ expect(withoutValue.success).toBe(true)
133
+ if (withoutValue.success) {
134
+ expect(withoutValue.data.paths).toBeUndefined()
135
+ }
136
+ })
137
+
138
+ it('produces identical JSON schema with or without preprocess', () => {
139
+ const plain = z.object({ paths: z.array(z.string()) })
140
+ const coerced = z.object({
141
+ paths: z.preprocess(coerceToArray, z.array(z.string())),
142
+ })
143
+
144
+ const plainSchema = z.toJSONSchema(plain, { io: 'input' })
145
+ const coercedSchema = z.toJSONSchema(coerced, { io: 'input' })
146
+ expect(coercedSchema).toEqual(plainSchema)
147
+ })
148
+ })
149
+
150
+ describe('coerceToObject with Zod schemas', () => {
151
+ it('produces identical JSON schema with or without preprocess', () => {
152
+ const plain = z.object({
153
+ params: z.record(z.string(), z.any()).optional(),
154
+ })
155
+ const coerced = z.object({
156
+ params: z
157
+ .preprocess(coerceToObject, z.record(z.string(), z.any()))
158
+ .optional(),
159
+ })
160
+
161
+ const plainSchema = z.toJSONSchema(plain, { io: 'input' })
162
+ const coercedSchema = z.toJSONSchema(coerced, { io: 'input' })
163
+ expect(coercedSchema).toEqual(plainSchema)
164
+ })
165
+ })
166
+
167
+ describe('normalizeReplacementAliases', () => {
168
+ it('maps old_str and new_str onto the documented replacement keys', () => {
169
+ expect(
170
+ normalizeReplacementAliases({
171
+ old_str: 'before',
172
+ new_str: 'after',
173
+ allowMultiple: true,
174
+ }),
175
+ ).toEqual({
176
+ old_str: 'before',
177
+ new_str: 'after',
178
+ oldString: 'before',
179
+ newString: 'after',
180
+ allowMultiple: true,
181
+ })
182
+ })
183
+
184
+ it('maps old_string and new_string onto the documented replacement keys', () => {
185
+ expect(
186
+ normalizeReplacementAliases({
187
+ old_string: 'before',
188
+ new_string: 'after',
189
+ }),
190
+ ).toEqual({
191
+ old_string: 'before',
192
+ new_string: 'after',
193
+ oldString: 'before',
194
+ newString: 'after',
195
+ })
196
+ })
197
+
198
+ it('does not overwrite documented replacement keys', () => {
199
+ expect(
200
+ normalizeReplacementAliases({
201
+ oldString: 'before',
202
+ newString: 'after',
203
+ old_str: 'ignored',
204
+ new_str: 'ignored',
205
+ }),
206
+ ).toEqual({
207
+ oldString: 'before',
208
+ newString: 'after',
209
+ old_str: 'ignored',
210
+ new_str: 'ignored',
211
+ })
212
+ })
213
+ })
@@ -0,0 +1,47 @@
1
+ import { describe, expect, test } from 'bun:test'
2
+
3
+ import { readDocsParams } from '../tool/read-docs'
4
+
5
+ describe('read_docs parameters', () => {
6
+ test('trims text inputs and defaults max_tokens', () => {
7
+ const result = readDocsParams.inputSchema.parse({
8
+ libraryTitle: ' React ',
9
+ topic: ' hooks ',
10
+ })
11
+
12
+ expect(result).toEqual({
13
+ libraryTitle: 'React',
14
+ topic: 'hooks',
15
+ max_tokens: 10_000,
16
+ })
17
+ })
18
+
19
+ test('rejects empty text and invalid token counts', () => {
20
+ expect(
21
+ readDocsParams.inputSchema.safeParse({
22
+ libraryTitle: ' ',
23
+ topic: 'hooks',
24
+ }).success,
25
+ ).toBe(false)
26
+ expect(
27
+ readDocsParams.inputSchema.safeParse({
28
+ libraryTitle: 'React',
29
+ topic: ' ',
30
+ }).success,
31
+ ).toBe(false)
32
+ expect(
33
+ readDocsParams.inputSchema.safeParse({
34
+ libraryTitle: 'React',
35
+ topic: 'hooks',
36
+ max_tokens: -1,
37
+ }).success,
38
+ ).toBe(false)
39
+ expect(
40
+ readDocsParams.inputSchema.safeParse({
41
+ libraryTitle: 'React',
42
+ topic: 'hooks',
43
+ max_tokens: 1.5,
44
+ }).success,
45
+ ).toBe(false)
46
+ })
47
+ })
@@ -0,0 +1,65 @@
1
+ import { describe, expect, it } from 'bun:test'
2
+
3
+ import { parseRenderUIButtonWidget } from '../tool/render-ui'
4
+
5
+ describe('parseRenderUIButtonWidget', () => {
6
+ it('preserves the resolved URL exactly', () => {
7
+ const link =
8
+ 'https://index.trygravity.ai/go/resend?token=a%2Fb&opaque=(keep)'
9
+
10
+ expect(
11
+ parseRenderUIButtonWidget({
12
+ type: 'button',
13
+ text: ' Get Resend ',
14
+ link,
15
+ variant: 'secondary',
16
+ }),
17
+ ).toEqual({
18
+ type: 'button',
19
+ text: 'Get Resend',
20
+ link,
21
+ variant: 'secondary',
22
+ })
23
+ })
24
+
25
+ it('defaults the visual variant and rejects unsafe or unresolved links', () => {
26
+ expect(
27
+ parseRenderUIButtonWidget({
28
+ type: 'button',
29
+ text: 'Open',
30
+ link: 'https://example.com',
31
+ }),
32
+ ).toEqual({
33
+ type: 'button',
34
+ text: 'Open',
35
+ link: 'https://example.com',
36
+ variant: 'primary',
37
+ })
38
+
39
+ expect(
40
+ parseRenderUIButtonWidget({
41
+ type: 'button',
42
+ text: 'Bad',
43
+ link: 'javascript:alert(1)',
44
+ }),
45
+ ).toBeNull()
46
+ expect(
47
+ parseRenderUIButtonWidget({
48
+ type: 'button',
49
+ text: 'Padded',
50
+ link: ' https://example.com ',
51
+ }),
52
+ ).toBeNull()
53
+ expect(
54
+ parseRenderUIButtonWidget({
55
+ type: 'button',
56
+ text: 'Unresolved',
57
+ link: {
58
+ source: 'gravity_index',
59
+ search_id: 's1',
60
+ service_slug: 'resend',
61
+ },
62
+ }),
63
+ ).toBeNull()
64
+ })
65
+ })
@@ -0,0 +1,49 @@
1
+ import { describe, expect, it } from 'bun:test'
2
+
3
+ import {
4
+ clampTerminalTimeoutSeconds,
5
+ MAX_TERMINAL_TIMEOUT_SECONDS,
6
+ } from '../run-terminal-command'
7
+
8
+ describe('clampTerminalTimeoutSeconds', () => {
9
+ it('clamps the exaggerated budgets models actually pick', () => {
10
+ // Reported from production: 3-minute, 10-minute and 50-minute waits for
11
+ // work that finishes in seconds. Nothing in the runtime bounded these —
12
+ // the model's number reached the client verbatim.
13
+ expect(clampTerminalTimeoutSeconds(3000)).toBe(MAX_TERMINAL_TIMEOUT_SECONDS)
14
+ expect(clampTerminalTimeoutSeconds(1800)).toBe(MAX_TERMINAL_TIMEOUT_SECONDS)
15
+ expect(clampTerminalTimeoutSeconds(601)).toBe(MAX_TERMINAL_TIMEOUT_SECONDS)
16
+ })
17
+
18
+ it('leaves ordinary budgets alone', () => {
19
+ expect(clampTerminalTimeoutSeconds(30)).toBe(30)
20
+ expect(clampTerminalTimeoutSeconds(180)).toBe(180)
21
+ expect(clampTerminalTimeoutSeconds(MAX_TERMINAL_TIMEOUT_SECONDS)).toBe(
22
+ MAX_TERMINAL_TIMEOUT_SECONDS,
23
+ )
24
+ })
25
+
26
+ it('preserves the -1 no-timeout sentinel', () => {
27
+ // The explicit escape hatch for genuinely open-ended commands. Clamping it
28
+ // to 600 would silently break `cli/src/commands/router.ts`, which passes -1
29
+ // deliberately.
30
+ expect(clampTerminalTimeoutSeconds(-1)).toBe(-1)
31
+ })
32
+
33
+ it('leaves an absent value to the schema default', () => {
34
+ expect(clampTerminalTimeoutSeconds(undefined)).toBeUndefined()
35
+ })
36
+
37
+ it('treats nonsense values as the default rather than an instant timeout', () => {
38
+ // 0 or a stray negative is a malformed choice, not a request to fail
39
+ // immediately — which is what passing it through would cause.
40
+ expect(clampTerminalTimeoutSeconds(0)).toBe(30)
41
+ expect(clampTerminalTimeoutSeconds(-5)).toBe(30)
42
+ expect(clampTerminalTimeoutSeconds(Number.NaN)).toBe(
43
+ MAX_TERMINAL_TIMEOUT_SECONDS,
44
+ )
45
+ expect(clampTerminalTimeoutSeconds(Number.POSITIVE_INFINITY)).toBe(
46
+ MAX_TERMINAL_TIMEOUT_SECONDS,
47
+ )
48
+ })
49
+ })