blume 2.0.3 → 2.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (607) hide show
  1. package/AGENTS.md +1 -0
  2. package/CHANGELOG.md +142 -0
  3. package/README.md +1 -1
  4. package/dist/cli/{chunk-5f86nr5m.js → chunk-073rdvgb.js} +21 -48
  5. package/dist/cli/{chunk-5f86nr5m.js.map → chunk-073rdvgb.js.map} +4 -5
  6. package/dist/cli/{chunk-ga0pf4aj.js → chunk-0n9xkp3d.js} +12 -3
  7. package/dist/cli/{chunk-ga0pf4aj.js.map → chunk-0n9xkp3d.js.map} +3 -3
  8. package/dist/cli/chunk-150jk7km.js +52 -0
  9. package/dist/cli/chunk-150jk7km.js.map +10 -0
  10. package/dist/cli/{chunk-9t7a85s3.js → chunk-313vnn40.js} +30 -19
  11. package/dist/cli/chunk-313vnn40.js.map +10 -0
  12. package/dist/cli/{chunk-tkacnehg.js → chunk-3v3ffbrj.js} +2 -2
  13. package/dist/cli/{chunk-q58y5e6a.js → chunk-3x6x3pph.js} +46 -24
  14. package/dist/cli/chunk-3x6x3pph.js.map +10 -0
  15. package/dist/cli/{chunk-1d7ve1dm.js → chunk-42t4jxdx.js} +37 -5
  16. package/dist/cli/chunk-42t4jxdx.js.map +12 -0
  17. package/dist/cli/{chunk-8ktnccpt.js → chunk-54ztw1nj.js} +21 -2
  18. package/dist/cli/chunk-54ztw1nj.js.map +10 -0
  19. package/dist/cli/{chunk-hm3vjy5s.js → chunk-5vjtgs6e.js} +28 -10
  20. package/dist/cli/{chunk-hm3vjy5s.js.map → chunk-5vjtgs6e.js.map} +4 -4
  21. package/dist/cli/chunk-66w9j7p6.js +322 -0
  22. package/dist/cli/chunk-66w9j7p6.js.map +14 -0
  23. package/dist/cli/{chunk-2hsdwb9n.js → chunk-7ppf1rva.js} +34 -18
  24. package/dist/cli/chunk-7ppf1rva.js.map +10 -0
  25. package/dist/cli/{chunk-r9rcc4w7.js → chunk-8y2kmjv8.js} +7 -7
  26. package/dist/cli/{chunk-r20tn01b.js → chunk-c1y538kd.js} +8 -2
  27. package/dist/cli/{chunk-r20tn01b.js.map → chunk-c1y538kd.js.map} +3 -3
  28. package/dist/cli/{chunk-2eytanqx.js → chunk-c887fj0s.js} +2 -2
  29. package/dist/cli/{chunk-p3v96n38.js → chunk-cfyg47zg.js} +16 -6
  30. package/dist/cli/chunk-cfyg47zg.js.map +10 -0
  31. package/dist/cli/chunk-cm89scdv.js +443 -0
  32. package/dist/cli/chunk-cm89scdv.js.map +11 -0
  33. package/dist/cli/{chunk-akbpwfxc.js → chunk-dzwehpy7.js} +2 -2
  34. package/dist/cli/{chunk-wrr3j9w9.js → chunk-e6atmn4h.js} +299 -72
  35. package/dist/cli/chunk-e6atmn4h.js.map +36 -0
  36. package/dist/cli/{chunk-tzmab476.js → chunk-e8xw9qkh.js} +8 -6
  37. package/dist/cli/{chunk-tzmab476.js.map → chunk-e8xw9qkh.js.map} +3 -3
  38. package/dist/cli/{chunk-6dsbexzp.js → chunk-e9q7a2ak.js} +17 -15
  39. package/dist/cli/{chunk-6dsbexzp.js.map → chunk-e9q7a2ak.js.map} +2 -2
  40. package/dist/cli/{chunk-pv29h0wf.js → chunk-ehweg4fr.js} +5155 -1249
  41. package/dist/cli/chunk-ehweg4fr.js.map +218 -0
  42. package/dist/cli/{chunk-c8chx29p.js → chunk-ep6nd0rn.js} +390 -318
  43. package/dist/cli/chunk-ep6nd0rn.js.map +36 -0
  44. package/dist/cli/{chunk-p73c0m7w.js → chunk-fdrkhpjy.js} +18 -15
  45. package/dist/cli/{chunk-p73c0m7w.js.map → chunk-fdrkhpjy.js.map} +3 -3
  46. package/dist/cli/{chunk-2z928egk.js → chunk-ft9vfys6.js} +5 -5
  47. package/dist/cli/{chunk-5m5nmvyq.js → chunk-gb420vvz.js} +316 -79
  48. package/dist/cli/chunk-gb420vvz.js.map +17 -0
  49. package/dist/cli/{chunk-vg9r4eb9.js → chunk-hebn0tpx.js} +86 -13
  50. package/dist/cli/chunk-hebn0tpx.js.map +14 -0
  51. package/dist/cli/{chunk-35d4wj9f.js → chunk-htrwgabr.js} +41 -23
  52. package/dist/cli/chunk-htrwgabr.js.map +15 -0
  53. package/dist/cli/{chunk-g4hq16wv.js → chunk-hx3xqnk9.js} +16 -14
  54. package/dist/cli/{chunk-g4hq16wv.js.map → chunk-hx3xqnk9.js.map} +2 -2
  55. package/dist/cli/chunk-j134vrp2.js +65 -0
  56. package/dist/cli/chunk-j134vrp2.js.map +10 -0
  57. package/dist/cli/{chunk-a58773jm.js → chunk-kma9f6sf.js} +2 -2
  58. package/dist/cli/chunk-kwrg63tm.js +31 -0
  59. package/dist/cli/chunk-kwrg63tm.js.map +10 -0
  60. package/dist/cli/{chunk-ey84smr6.js → chunk-mrcccgnh.js} +6 -6
  61. package/dist/cli/{chunk-ey84smr6.js.map → chunk-mrcccgnh.js.map} +1 -1
  62. package/dist/cli/{chunk-yfyb25rh.js → chunk-n0v7m8ry.js} +24 -8
  63. package/dist/cli/chunk-n0v7m8ry.js.map +14 -0
  64. package/dist/cli/{chunk-j85vccga.js → chunk-ncj7w596.js} +576 -367
  65. package/dist/cli/chunk-ncj7w596.js.map +35 -0
  66. package/dist/cli/{chunk-5xvm6tfj.js → chunk-nq1d20w2.js} +17 -15
  67. package/dist/cli/{chunk-5xvm6tfj.js.map → chunk-nq1d20w2.js.map} +2 -2
  68. package/dist/cli/{chunk-pehfxfta.js → chunk-nrns10mj.js} +6 -98
  69. package/dist/cli/chunk-nrns10mj.js.map +10 -0
  70. package/dist/cli/{chunk-crgn1q09.js → chunk-sds923fa.js} +4 -4
  71. package/dist/cli/chunk-t2m5j4pr.js +104 -0
  72. package/dist/cli/chunk-t2m5j4pr.js.map +11 -0
  73. package/dist/cli/{chunk-acanzt5p.js → chunk-tdqhyxfz.js} +6 -6
  74. package/dist/cli/chunk-tphac74f.js +126 -0
  75. package/dist/cli/chunk-tphac74f.js.map +11 -0
  76. package/dist/cli/chunk-w1r4vase.js +18 -0
  77. package/dist/cli/chunk-w1r4vase.js.map +10 -0
  78. package/dist/cli/{chunk-3em5wd2y.js → chunk-zccbjcj0.js} +4 -3
  79. package/dist/cli/{chunk-3em5wd2y.js.map → chunk-zccbjcj0.js.map} +2 -2
  80. package/dist/cli/index.js +31 -20
  81. package/dist/cli/index.js.map +5 -5
  82. package/dist/types/ai/agent-surface.d.ts +8 -7
  83. package/dist/types/ai/ai-catalog.d.ts +7 -0
  84. package/dist/types/ai/ask-context.d.ts +26 -0
  85. package/dist/types/ai/ask.d.ts +271 -58
  86. package/dist/types/ai/component-markdown.d.ts +2 -0
  87. package/dist/types/ai/index.d.ts +2 -2
  88. package/dist/types/ai/openapi-components.d.ts +4 -1
  89. package/dist/types/ai/site-skill.d.ts +26 -0
  90. package/dist/types/ai/skills.d.ts +16 -0
  91. package/dist/types/astro/integration.d.ts +9 -0
  92. package/dist/types/astro/markdown-negotiation.d.ts +3 -0
  93. package/dist/types/astro/pages.d.ts +10 -0
  94. package/dist/types/captcha/hcaptcha.d.ts +27 -0
  95. package/dist/types/captcha/index.d.ts +28 -0
  96. package/dist/types/captcha/schema.d.ts +29 -0
  97. package/dist/types/captcha/turnstile.d.ts +28 -0
  98. package/dist/types/cli/init/scaffold.d.ts +1 -1
  99. package/dist/types/components/content/api-field.d.ts +62 -0
  100. package/dist/types/components/content/api-page.d.ts +100 -0
  101. package/dist/types/components/layout/nav-utils.d.ts +26 -0
  102. package/dist/types/components/openapi/code-samples.d.ts +29 -0
  103. package/dist/types/components/openapi/helpers.d.ts +158 -0
  104. package/dist/types/components/openapi/security.d.ts +95 -0
  105. package/dist/types/components/openapi/snippets.d.ts +60 -0
  106. package/dist/types/consent/ethyca.d.ts +48 -0
  107. package/dist/types/consent/index.d.ts +37 -0
  108. package/dist/types/consent/native.d.ts +28 -0
  109. package/dist/types/consent/osano.d.ts +42 -0
  110. package/dist/types/consent/schema.d.ts +110 -0
  111. package/dist/types/core/changelog-index.d.ts +8 -0
  112. package/dist/types/core/config-input.d.ts +217 -23
  113. package/dist/types/core/data.d.ts +53 -4
  114. package/dist/types/core/footer.d.ts +8 -0
  115. package/dist/types/core/i18n-ui.d.ts +88 -0
  116. package/dist/types/core/includes.d.ts +8 -2
  117. package/dist/types/core/links.d.ts +8 -0
  118. package/dist/types/core/localizable.d.ts +7 -0
  119. package/dist/types/core/page-modes.d.ts +29 -0
  120. package/dist/types/core/probe.d.ts +2 -0
  121. package/dist/types/core/project-graph.d.ts +6 -0
  122. package/dist/types/core/redirect-patterns.d.ts +152 -0
  123. package/dist/types/core/related.d.ts +40 -0
  124. package/dist/types/core/schema.d.ts +670 -56
  125. package/dist/types/core/sources/cache.d.ts +3 -0
  126. package/dist/types/core/sources/contentful-rich-text.d.ts +11 -2
  127. package/dist/types/core/sources/contentful.d.ts +17 -1
  128. package/dist/types/core/sources/lexical.d.ts +5 -0
  129. package/dist/types/core/sources/normalize.d.ts +20 -1
  130. package/dist/types/core/sources/read.d.ts +5 -0
  131. package/dist/types/core/sources/remote.d.ts +37 -10
  132. package/dist/types/core/sources/sanity.d.ts +1 -1
  133. package/dist/types/core/types.d.ts +18 -1
  134. package/dist/types/core/variables.d.ts +42 -0
  135. package/dist/types/deploy/adapter-output.d.ts +2 -1
  136. package/dist/types/deploy/adapters/cloudflare.d.ts +7 -5
  137. package/dist/types/deploy/adapters/node.d.ts +58 -23
  138. package/dist/types/deploy/adapters/registry.d.ts +10 -0
  139. package/dist/types/deploy/adapters/types.d.ts +3 -2
  140. package/dist/types/deploy/node-headers.d.ts +13 -2
  141. package/dist/types/deploy/platforms/cloudflare.d.ts +15 -7
  142. package/dist/types/deploy/platforms/netlify.d.ts +7 -0
  143. package/dist/types/deploy/platforms/node.d.ts +3 -1
  144. package/dist/types/deploy/platforms/types.d.ts +18 -7
  145. package/dist/types/deploy/platforms/vercel.d.ts +26 -1
  146. package/dist/types/deploy/redirects.d.ts +55 -11
  147. package/dist/types/deploy/sitemap.d.ts +2 -1
  148. package/dist/types/deploy/vercel-negotiation.d.ts +51 -21
  149. package/dist/types/markdown/code-title.d.ts +17 -0
  150. package/dist/types/markdown/features.d.ts +3 -2
  151. package/dist/types/narration/build.d.ts +70 -0
  152. package/dist/types/narration/provider.d.ts +26 -0
  153. package/dist/types/narration/script.d.ts +154 -0
  154. package/dist/types/openapi/checks.d.ts +27 -0
  155. package/dist/types/openapi/graphql.d.ts +6 -0
  156. package/dist/types/openapi/model.d.ts +27 -10
  157. package/dist/types/openapi/overlay.d.ts +54 -0
  158. package/dist/types/openapi/parse.d.ts +16 -0
  159. package/dist/types/openapi/references.d.ts +30 -4
  160. package/dist/types/ratelimit/cloudflare.d.ts +39 -0
  161. package/dist/types/ratelimit/index.d.ts +27 -0
  162. package/dist/types/ratelimit/memory.d.ts +36 -0
  163. package/dist/types/ratelimit/schema.d.ts +119 -0
  164. package/dist/types/ratelimit/upstash.d.ts +46 -0
  165. package/dist/types/ratelimit/wrangler.d.ts +23 -0
  166. package/dist/types/reference/asyncapi.d.ts +10 -10
  167. package/dist/types/reference/graphql.d.ts +89 -11
  168. package/dist/types/reference/index.d.ts +1 -1
  169. package/dist/types/reference/openapi.d.ts +33 -12
  170. package/dist/types/reference/options.d.ts +82 -6
  171. package/dist/types/reference/scalar.d.ts +13 -0
  172. package/dist/types/reference/schema.d.ts +144 -36
  173. package/dist/types/search/adapters/registry.d.ts +3 -0
  174. package/dist/types/search/adapters/typesense.d.ts +14 -4
  175. package/dist/types/search/build.d.ts +3 -1
  176. package/dist/types/search/documents.d.ts +12 -1
  177. package/dist/types/search/orama-index.d.ts +13 -9
  178. package/dist/types/search/sync/algolia.d.ts +5 -2
  179. package/dist/types/search/sync/index.d.ts +3 -1
  180. package/dist/types/search/sync/typesense.d.ts +11 -7
  181. package/dist/types/seo/metatags.d.ts +20 -0
  182. package/dist/types/sources/contentful.d.ts +16 -0
  183. package/dist/types/sources/github-releases.d.ts +8 -1
  184. package/dist/types/sources/payload.d.ts +2 -0
  185. package/dist/types/sources/registry.d.ts +54 -0
  186. package/dist/types/sources/shared.d.ts +3 -0
  187. package/dist/types/sources/strapi.d.ts +2 -0
  188. package/docs/01-quickstart.mdx +4 -2
  189. package/docs/02-deployment.mdx +71 -17
  190. package/docs/03-upgrading.mdx +4 -4
  191. package/docs/04-migrating.mdx +1 -1
  192. package/docs/advanced/changelog.mdx +13 -2
  193. package/docs/advanced/skills.mdx +15 -1
  194. package/docs/cli/audit.mdx +51 -8
  195. package/docs/cli/doctor.mdx +5 -1
  196. package/docs/cli/evals.mdx +4 -4
  197. package/docs/cli/index.mdx +1 -0
  198. package/docs/cli/translate.mdx +1 -0
  199. package/docs/cli/validate.mdx +4 -3
  200. package/docs/configuration/analytics.mdx +3 -1
  201. package/docs/configuration/assistant.mdx +194 -38
  202. package/docs/configuration/consent.mdx +100 -0
  203. package/docs/configuration/customization.mdx +8 -6
  204. package/docs/configuration/export.mdx +5 -3
  205. package/docs/configuration/index.mdx +64 -5
  206. package/docs/configuration/meta.ts +3 -0
  207. package/docs/configuration/narration.mdx +119 -0
  208. package/docs/configuration/rate-limiting.mdx +90 -0
  209. package/docs/configuration/search.mdx +63 -12
  210. package/docs/configuration/theming.mdx +3 -1
  211. package/docs/content/components.mdx +108 -2
  212. package/docs/content/frontmatter.mdx +80 -2
  213. package/docs/content/i18n.mdx +39 -4
  214. package/docs/content/includes.mdx +16 -0
  215. package/docs/content/meta.mdx +1 -0
  216. package/docs/content/meta.ts +1 -0
  217. package/docs/content/navigation.mdx +32 -10
  218. package/docs/content/sources/contentful.mdx +35 -0
  219. package/docs/content/sources/custom.mdx +43 -0
  220. package/docs/content/sources/github-releases.mdx +39 -0
  221. package/docs/content/sources/index.mdx +91 -0
  222. package/docs/content/sources/meta.ts +16 -0
  223. package/docs/content/sources/notion.mdx +32 -0
  224. package/docs/content/sources/obsidian.mdx +37 -0
  225. package/docs/content/sources/payload.mdx +31 -0
  226. package/docs/content/sources/remote-mdx.mdx +44 -0
  227. package/docs/content/sources/sanity.mdx +29 -0
  228. package/docs/content/sources/strapi.mdx +32 -0
  229. package/docs/content/syntax.mdx +69 -4
  230. package/docs/content/variables.mdx +41 -0
  231. package/docs/discoverability/agent-discovery.mdx +29 -2
  232. package/docs/discoverability/index.mdx +2 -2
  233. package/docs/discoverability/json-api.mdx +2 -0
  234. package/docs/discoverability/llms-txt.mdx +2 -2
  235. package/docs/discoverability/markdown.mdx +3 -1
  236. package/docs/discoverability/mcp.mdx +4 -0
  237. package/docs/discoverability/metadata.mdx +17 -0
  238. package/docs/discoverability/sitemap-and-robots.mdx +1 -1
  239. package/docs/references/api-pages.mdx +74 -0
  240. package/docs/references/asyncapi.mdx +4 -2
  241. package/docs/references/graphql.mdx +14 -2
  242. package/docs/references/meta.ts +1 -1
  243. package/docs/references/openapi.mdx +148 -7
  244. package/docs/references/scalar.mdx +3 -1
  245. package/package.json +43 -8
  246. package/skills/blume/SKILL.md +3 -0
  247. package/skills/blume-migrate/SKILL.md +6 -6
  248. package/skills/blume-migrate/references/docusaurus.md +7 -7
  249. package/skills/blume-migrate/references/fumadocs.md +17 -13
  250. package/skills/blume-migrate/references/mintlify.md +37 -19
  251. package/skills/blume-migrate/references/nextra.md +10 -7
  252. package/skills/blume-migrate/references/starlight.md +11 -8
  253. package/skills/blume-migrate/scripts/mintlify-codemod.mjs +60 -14
  254. package/skills/blume-write-skill/SKILL.md +82 -0
  255. package/src/ai/agent-readability.ts +2 -1
  256. package/src/ai/agent-surface.ts +9 -7
  257. package/src/ai/ai-catalog.ts +6 -3
  258. package/src/ai/ask-context.ts +103 -20
  259. package/src/ai/ask-data.ts +6 -0
  260. package/src/ai/ask-limits.ts +13 -0
  261. package/src/ai/ask-tools.ts +142 -0
  262. package/src/ai/ask.ts +354 -76
  263. package/src/ai/changelog-markdown.ts +11 -6
  264. package/src/ai/component-markdown.ts +76 -1
  265. package/src/ai/cors.ts +14 -3
  266. package/src/ai/index.ts +12 -0
  267. package/src/ai/llms.ts +6 -2
  268. package/src/ai/markdown.ts +2 -1
  269. package/src/ai/mcp/data.ts +6 -0
  270. package/src/ai/mcp/query.ts +14 -6
  271. package/src/ai/openapi-components.ts +36 -6
  272. package/src/ai/relative-links.ts +4 -38
  273. package/src/ai/site-skill.ts +274 -0
  274. package/src/ai/skills.ts +35 -2
  275. package/src/ai/write-skill.ts +97 -0
  276. package/src/astro/generate.ts +210 -66
  277. package/src/astro/index.ts +1 -0
  278. package/src/astro/integration.ts +42 -4
  279. package/src/astro/markdown-negotiation.ts +3 -0
  280. package/src/astro/module-types.ts +9 -1
  281. package/src/astro/pages.ts +23 -0
  282. package/src/astro/templates.ts +406 -108
  283. package/src/astro/variables.ts +31 -0
  284. package/src/audit/catalog.ts +38 -3
  285. package/src/audit/checks/contrast.ts +183 -0
  286. package/src/audit/checks/i18n.ts +2 -3
  287. package/src/audit/checks/indexability.ts +2 -3
  288. package/src/audit/checks/links.ts +19 -13
  289. package/src/audit/checks/network.ts +110 -6
  290. package/src/audit/checks/redirects.ts +6 -4
  291. package/src/audit/checks/robots.ts +58 -2
  292. package/src/audit/checks/sitemap.ts +2 -3
  293. package/src/audit/redirects.ts +46 -15
  294. package/src/audit/run.ts +5 -0
  295. package/src/audit/types.ts +4 -1
  296. package/src/audit/url.ts +14 -5
  297. package/src/blume-modules.d.ts +12 -1
  298. package/src/captcha/client.ts +152 -0
  299. package/src/captcha/hcaptcha.ts +36 -0
  300. package/src/captcha/index.ts +28 -0
  301. package/src/captcha/schema.ts +32 -0
  302. package/src/captcha/turnstile.ts +38 -0
  303. package/src/captcha/verify.ts +71 -0
  304. package/src/cli/args.ts +51 -0
  305. package/src/cli/build-failure.ts +23 -0
  306. package/src/cli/command-meta.ts +5 -0
  307. package/src/cli/commands/audit.ts +10 -1
  308. package/src/cli/commands/dev.ts +18 -2
  309. package/src/cli/commands/doctor.ts +67 -28
  310. package/src/cli/commands/eval.ts +36 -4
  311. package/src/cli/commands/init.ts +6 -4
  312. package/src/cli/commands/skill.ts +96 -0
  313. package/src/cli/commands/validate.ts +10 -1
  314. package/src/cli/index.ts +5 -0
  315. package/src/cli/init/scaffold.ts +3 -3
  316. package/src/cli/prepare.ts +6 -3
  317. package/src/cli/required-secrets.ts +72 -30
  318. package/src/components/BlumePage.astro +2 -0
  319. package/src/components/content/ApiEndpoint.astro +18 -0
  320. package/src/components/content/ApiField.astro +79 -0
  321. package/src/components/content/ApiPlayground.astro +66 -0
  322. package/src/components/content/ApiRail.astro +19 -0
  323. package/src/components/content/Color.astro +1 -0
  324. package/src/components/content/FileTree.astro +1 -0
  325. package/src/components/content/GithubInfo.astro +1 -0
  326. package/src/components/content/Panel.astro +1 -0
  327. package/src/components/content/ParamField.astro +25 -0
  328. package/src/components/content/RequestExample.astro +17 -0
  329. package/src/components/content/ResponseExample.astro +17 -0
  330. package/src/components/content/ResponseField.astro +32 -0
  331. package/src/components/content/Step.astro +1 -0
  332. package/src/components/content/Tile.astro +1 -0
  333. package/src/components/content/Tooltip.astro +1 -0
  334. package/src/components/content/Tree.astro +1 -0
  335. package/src/components/content/TypeTable.astro +4 -1
  336. package/src/components/content/View.astro +21 -0
  337. package/src/components/content/ViewSwitcher.astro +168 -0
  338. package/src/components/content/api-field.ts +103 -0
  339. package/src/components/content/api-page.ts +248 -0
  340. package/src/components/content/mermaid-element.ts +15 -1
  341. package/src/components/content/view-switcher.ts +71 -0
  342. package/src/components/index.ts +2 -0
  343. package/src/components/islands/Assistant.astro +10 -1
  344. package/src/components/islands/assistant.tsx +104 -14
  345. package/src/components/islands/code-question.ts +62 -0
  346. package/src/components/islands/hooks.ts +136 -21
  347. package/src/components/islands/support-link.ts +68 -0
  348. package/src/components/layout/Analytics.astro +11 -2
  349. package/src/components/layout/Banner.astro +14 -10
  350. package/src/components/layout/Breadcrumbs.astro +6 -2
  351. package/src/components/layout/ConsentBanner.astro +62 -0
  352. package/src/components/layout/ConsentHead.astro +38 -0
  353. package/src/components/layout/Directory.astro +94 -0
  354. package/src/components/layout/DrawerSwitchers.astro +51 -0
  355. package/src/components/layout/Empty.astro +2 -2
  356. package/src/components/layout/Header.astro +122 -80
  357. package/src/components/layout/LanguageSwitcher.astro +48 -15
  358. package/src/components/layout/NarrationPlayer.astro +1085 -0
  359. package/src/components/layout/NavSelector.astro +33 -7
  360. package/src/components/layout/PageActions.astro +139 -24
  361. package/src/components/layout/PageFeedback.astro +54 -49
  362. package/src/components/layout/PageLayout.astro +71 -3
  363. package/src/components/layout/ReferenceLayout.astro +17 -6
  364. package/src/components/layout/RelatedPages.astro +42 -0
  365. package/src/components/layout/RootLayout.astro +318 -47
  366. package/src/components/layout/Search.astro +47 -19
  367. package/src/components/layout/SiteFooter.astro +124 -0
  368. package/src/components/layout/SiteMetatags.astro +16 -0
  369. package/src/components/layout/TableOfContents.astro +24 -17
  370. package/src/components/layout/consent/native.ts +79 -0
  371. package/src/components/layout/consent/types.ts +37 -0
  372. package/src/components/layout/footer-links.ts +53 -0
  373. package/src/components/layout/footer-socials.ts +87 -0
  374. package/src/components/layout/head-scripts.ts +6 -1
  375. package/src/components/layout/locale-redirect.ts +107 -0
  376. package/src/components/layout/nav-utils.ts +83 -0
  377. package/src/components/layout/page-feedback.ts +96 -0
  378. package/src/components/layout/search/algolia.ts +10 -1
  379. package/src/components/layout/search/analytics.ts +126 -0
  380. package/src/components/layout/search/endpoint.ts +48 -5
  381. package/src/components/layout/search/flexsearch.ts +17 -5
  382. package/src/components/layout/search/orama-cloud.ts +26 -14
  383. package/src/components/layout/search/pagefind.ts +114 -5
  384. package/src/components/layout/search/types.ts +32 -0
  385. package/src/components/layout/search/typesense.ts +19 -3
  386. package/src/components/openapi/AsyncApiOperation.astro +14 -7
  387. package/src/components/openapi/Authorization.astro +10 -0
  388. package/src/components/openapi/GraphqlOperation.astro +5 -0
  389. package/src/components/openapi/Operation.astro +184 -13
  390. package/src/components/openapi/ParametersTable.astro +8 -4
  391. package/src/components/openapi/Playground.astro +7 -1
  392. package/src/components/openapi/RequestBody.astro +24 -5
  393. package/src/components/openapi/RequestPanel.astro +59 -7
  394. package/src/components/openapi/Responses.astro +7 -4
  395. package/src/components/openapi/SchemaTable.astro +15 -3
  396. package/src/components/openapi/async-snippets.ts +65 -9
  397. package/src/components/openapi/async.ts +123 -29
  398. package/src/components/openapi/code-samples.ts +97 -0
  399. package/src/components/openapi/graphql-helpers.ts +35 -12
  400. package/src/components/openapi/helpers.ts +36 -2
  401. package/src/components/openapi/message-model.ts +54 -11
  402. package/src/components/openapi/message.ts +14 -4
  403. package/src/components/openapi/operation-model.ts +16 -7
  404. package/src/components/openapi/playground-client.ts +24 -5
  405. package/src/components/openapi/playground-schema.ts +1 -1
  406. package/src/components/openapi/schema-tree.ts +44 -14
  407. package/src/components/openapi/security.ts +16 -3
  408. package/src/components/openapi/snippets.ts +873 -10
  409. package/src/components/openapi/validate-json.ts +4 -3
  410. package/src/components/props.ts +6 -0
  411. package/src/consent/client.ts +95 -0
  412. package/src/consent/clients.ts +19 -0
  413. package/src/consent/ethyca.ts +71 -0
  414. package/src/consent/head.ts +24 -0
  415. package/src/consent/index.ts +37 -0
  416. package/src/consent/init.ts +29 -0
  417. package/src/consent/native.ts +36 -0
  418. package/src/consent/osano.ts +59 -0
  419. package/src/consent/schema.ts +30 -0
  420. package/src/core/builtin-tags.ts +5 -0
  421. package/src/core/changelog-index.ts +31 -1
  422. package/src/core/client-address.ts +19 -0
  423. package/src/core/component-diagnostics.ts +53 -0
  424. package/src/core/component-overrides.ts +32 -0
  425. package/src/core/config-input.ts +225 -23
  426. package/src/core/data.ts +46 -4
  427. package/src/core/diagnostics.ts +8 -2
  428. package/src/core/footer.ts +26 -0
  429. package/src/core/graph.ts +39 -36
  430. package/src/core/i18n-ui.ts +84 -2
  431. package/src/core/includes.ts +21 -4
  432. package/src/core/links.ts +63 -19
  433. package/src/core/localizable.ts +26 -0
  434. package/src/core/navigation.ts +43 -12
  435. package/src/core/page-modes.ts +56 -0
  436. package/src/core/probe.ts +26 -6
  437. package/src/core/project-graph.ts +163 -16
  438. package/src/core/redirect-patterns.ts +520 -0
  439. package/src/core/related.ts +131 -0
  440. package/src/core/schema.ts +339 -66
  441. package/src/core/sources/cache.ts +6 -0
  442. package/src/core/sources/contentful-rich-text.ts +29 -6
  443. package/src/core/sources/contentful.ts +135 -25
  444. package/src/core/sources/filesystem.ts +26 -4
  445. package/src/core/sources/github-releases.ts +12 -1
  446. package/src/core/sources/lexical.ts +15 -10
  447. package/src/core/sources/mdx-remote.ts +62 -10
  448. package/src/core/sources/normalize.ts +228 -41
  449. package/src/core/sources/notion.ts +7 -1
  450. package/src/core/sources/obsidian.ts +16 -3
  451. package/src/core/sources/payload.ts +38 -15
  452. package/src/core/sources/read.ts +8 -3
  453. package/src/core/sources/remote.ts +72 -15
  454. package/src/core/sources/resolve.ts +11 -1
  455. package/src/core/sources/sanity.ts +43 -25
  456. package/src/core/sources/strapi.ts +2 -2
  457. package/src/core/types.ts +19 -1
  458. package/src/core/ui-packs/ar.ts +44 -0
  459. package/src/core/ui-packs/bg.ts +46 -0
  460. package/src/core/ui-packs/bn.ts +44 -0
  461. package/src/core/ui-packs/ca.ts +47 -0
  462. package/src/core/ui-packs/cs.ts +45 -0
  463. package/src/core/ui-packs/da.ts +46 -0
  464. package/src/core/ui-packs/de.ts +47 -0
  465. package/src/core/ui-packs/el.ts +46 -0
  466. package/src/core/ui-packs/es.ts +47 -0
  467. package/src/core/ui-packs/fa.ts +46 -0
  468. package/src/core/ui-packs/fi.ts +46 -0
  469. package/src/core/ui-packs/fr.ts +47 -0
  470. package/src/core/ui-packs/he.ts +44 -0
  471. package/src/core/ui-packs/hi.ts +45 -0
  472. package/src/core/ui-packs/hr.ts +46 -0
  473. package/src/core/ui-packs/hu.ts +45 -0
  474. package/src/core/ui-packs/id.ts +46 -0
  475. package/src/core/ui-packs/it.ts +46 -0
  476. package/src/core/ui-packs/ja.ts +46 -0
  477. package/src/core/ui-packs/ko.ts +45 -0
  478. package/src/core/ui-packs/nl.ts +47 -0
  479. package/src/core/ui-packs/no.ts +45 -0
  480. package/src/core/ui-packs/pl.ts +46 -0
  481. package/src/core/ui-packs/pt-br.ts +47 -0
  482. package/src/core/ui-packs/pt.ts +46 -0
  483. package/src/core/ui-packs/ro.ts +46 -0
  484. package/src/core/ui-packs/ru.ts +46 -0
  485. package/src/core/ui-packs/sk.ts +45 -0
  486. package/src/core/ui-packs/sr.ts +46 -0
  487. package/src/core/ui-packs/sv.ts +45 -0
  488. package/src/core/ui-packs/th.ts +44 -0
  489. package/src/core/ui-packs/tr.ts +46 -0
  490. package/src/core/ui-packs/uk.ts +46 -0
  491. package/src/core/ui-packs/vi.ts +46 -0
  492. package/src/core/ui-packs/zh-tw.ts +44 -0
  493. package/src/core/ui-packs/zh.ts +44 -0
  494. package/src/core/variables.ts +103 -0
  495. package/src/deploy/adapter-output.ts +7 -2
  496. package/src/deploy/adapters/cloudflare.ts +7 -5
  497. package/src/deploy/adapters/node.ts +47 -9
  498. package/src/deploy/adapters/types.ts +7 -3
  499. package/src/deploy/artifacts.ts +79 -9
  500. package/src/deploy/cloudflare-negotiation.ts +35 -5
  501. package/src/deploy/headers.ts +2 -1
  502. package/src/deploy/node-headers.ts +63 -9
  503. package/src/deploy/platforms/cloudflare.ts +45 -9
  504. package/src/deploy/platforms/netlify.ts +35 -2
  505. package/src/deploy/platforms/node.ts +12 -2
  506. package/src/deploy/platforms/types.ts +21 -7
  507. package/src/deploy/platforms/vercel.ts +149 -17
  508. package/src/deploy/redirects.ts +151 -24
  509. package/src/deploy/rss.ts +3 -1
  510. package/src/deploy/sitemap.ts +39 -5
  511. package/src/deploy/vercel-negotiation.ts +326 -102
  512. package/src/eval/agents.ts +18 -1
  513. package/src/eval/prompts.ts +6 -3
  514. package/src/eval/report.ts +34 -13
  515. package/src/eval/run.ts +5 -0
  516. package/src/markdown/api-rail.ts +259 -0
  517. package/src/markdown/code-title.ts +35 -9
  518. package/src/markdown/features.ts +3 -2
  519. package/src/markdown/fence-meta.ts +2 -0
  520. package/src/markdown/include.ts +11 -1
  521. package/src/markdown/index.ts +28 -5
  522. package/src/markdown/math.ts +4 -4
  523. package/src/markdown/relative-links.ts +3 -2
  524. package/src/markdown/variables.ts +56 -0
  525. package/src/markdown/views.ts +82 -0
  526. package/src/narration/build.ts +412 -0
  527. package/src/narration/player.ts +249 -0
  528. package/src/narration/provider.ts +29 -0
  529. package/src/narration/script.ts +592 -0
  530. package/src/og/card.ts +7 -6
  531. package/src/openapi/checks.ts +273 -0
  532. package/src/openapi/graphql-build.ts +21 -0
  533. package/src/openapi/graphql.ts +11 -0
  534. package/src/openapi/model.ts +72 -27
  535. package/src/openapi/overlay.ts +256 -0
  536. package/src/openapi/parse.ts +182 -4
  537. package/src/openapi/references.ts +64 -8
  538. package/src/openapi/render-mdx.ts +5 -1
  539. package/src/openapi/scalar.ts +40 -6
  540. package/src/openapi/source.ts +40 -15
  541. package/src/ratelimit/cloudflare.ts +54 -0
  542. package/src/ratelimit/index.ts +30 -0
  543. package/src/ratelimit/memory.ts +45 -0
  544. package/src/ratelimit/runtime.ts +247 -0
  545. package/src/ratelimit/schema.ts +28 -0
  546. package/src/ratelimit/upstash.ts +60 -0
  547. package/src/ratelimit/wrangler.ts +70 -0
  548. package/src/reference/asyncapi.ts +2 -2
  549. package/src/reference/graphql.ts +20 -3
  550. package/src/reference/index.ts +1 -0
  551. package/src/reference/openapi.ts +21 -7
  552. package/src/reference/options.ts +80 -8
  553. package/src/reference/scalar.ts +33 -8
  554. package/src/registry/eject.ts +23 -5
  555. package/src/registry/registry.ts +7 -0
  556. package/src/search/adapters/locale-scope.ts +30 -0
  557. package/src/search/adapters/typesense.ts +14 -4
  558. package/src/search/build.ts +21 -3
  559. package/src/search/documents.ts +26 -2
  560. package/src/search/orama-index.ts +191 -34
  561. package/src/search/pagefind-ranking.ts +39 -0
  562. package/src/search/source-pages.ts +29 -0
  563. package/src/search/sync/algolia.ts +111 -10
  564. package/src/search/sync/index.ts +52 -13
  565. package/src/search/sync/orama-cloud.ts +3 -0
  566. package/src/search/sync/typesense.ts +76 -26
  567. package/src/seo/metatags.ts +67 -0
  568. package/src/sources/contentful.ts +12 -0
  569. package/src/sources/github-releases.ts +7 -1
  570. package/src/sources/shared.ts +3 -0
  571. package/src/theme/chrome-icons.ts +1 -0
  572. package/src/theme/color.ts +500 -0
  573. package/src/theme/entry.ts +85 -6
  574. package/src/theme/palette.ts +121 -45
  575. package/src/translate/prompts.ts +1 -0
  576. package/src/translate/validate.ts +31 -3
  577. package/src/upgrade/upgrade.ts +4 -171
  578. package/dist/cli/chunk-1d7ve1dm.js.map +0 -12
  579. package/dist/cli/chunk-2hsdwb9n.js.map +0 -10
  580. package/dist/cli/chunk-35d4wj9f.js.map +0 -15
  581. package/dist/cli/chunk-364znk6q.js +0 -75
  582. package/dist/cli/chunk-364znk6q.js.map +0 -11
  583. package/dist/cli/chunk-5m5nmvyq.js.map +0 -13
  584. package/dist/cli/chunk-8ktnccpt.js.map +0 -10
  585. package/dist/cli/chunk-9t7a85s3.js.map +0 -10
  586. package/dist/cli/chunk-b07cmahc.js +0 -145
  587. package/dist/cli/chunk-b07cmahc.js.map +0 -11
  588. package/dist/cli/chunk-c8chx29p.js.map +0 -36
  589. package/dist/cli/chunk-e04dxsz1.js +0 -39
  590. package/dist/cli/chunk-e04dxsz1.js.map +0 -10
  591. package/dist/cli/chunk-j85vccga.js.map +0 -36
  592. package/dist/cli/chunk-p3v96n38.js.map +0 -10
  593. package/dist/cli/chunk-pehfxfta.js.map +0 -10
  594. package/dist/cli/chunk-pv29h0wf.js.map +0 -190
  595. package/dist/cli/chunk-q58y5e6a.js.map +0 -10
  596. package/dist/cli/chunk-vg9r4eb9.js.map +0 -14
  597. package/dist/cli/chunk-wrr3j9w9.js.map +0 -35
  598. package/dist/cli/chunk-yfyb25rh.js.map +0 -14
  599. package/docs/content/sources.mdx +0 -334
  600. /package/dist/cli/{chunk-tkacnehg.js.map → chunk-3v3ffbrj.js.map} +0 -0
  601. /package/dist/cli/{chunk-r9rcc4w7.js.map → chunk-8y2kmjv8.js.map} +0 -0
  602. /package/dist/cli/{chunk-2eytanqx.js.map → chunk-c887fj0s.js.map} +0 -0
  603. /package/dist/cli/{chunk-akbpwfxc.js.map → chunk-dzwehpy7.js.map} +0 -0
  604. /package/dist/cli/{chunk-2z928egk.js.map → chunk-ft9vfys6.js.map} +0 -0
  605. /package/dist/cli/{chunk-a58773jm.js.map → chunk-kma9f6sf.js.map} +0 -0
  606. /package/dist/cli/{chunk-crgn1q09.js.map → chunk-sds923fa.js.map} +0 -0
  607. /package/dist/cli/{chunk-acanzt5p.js.map → chunk-tdqhyxfz.js.map} +0 -0
package/src/ai/ask.ts CHANGED
@@ -34,6 +34,15 @@ export type AssistantProviderOptions = Record<
34
34
  /** The AI SDK provider package the OpenAI-compatible adapters install. */
35
35
  const OPENAI_COMPATIBLE_DEP = "@ai-sdk/openai-compatible";
36
36
 
37
+ /**
38
+ * The AI SDK packages for the providers Blume calls directly: the package and
39
+ * the provider factory the route imports from it.
40
+ */
41
+ const OPENAI_SDK = { factory: "createOpenAI", pkg: "@ai-sdk/openai" };
42
+ const ANTHROPIC_SDK = { factory: "createAnthropic", pkg: "@ai-sdk/anthropic" };
43
+ const GEMINI_SDK = { factory: "createGoogle", pkg: "@ai-sdk/google" };
44
+ const GROK_SDK = { factory: "createXai", pkg: "@ai-sdk/xai" };
45
+
37
46
  // ---------------------------------------------------------------------------
38
47
  // Shared options
39
48
  // ---------------------------------------------------------------------------
@@ -69,7 +78,7 @@ const providerOptionsSchema = z.record(
69
78
  );
70
79
 
71
80
  /** The shared option schema, with the adapter's own key env var default. */
72
- const sharedOptions = (apiKeyEnv: string) => ({
81
+ export const sharedOptions = (apiKeyEnv: string) => ({
73
82
  apiKeyEnv: z.string().min(1).default(apiKeyEnv),
74
83
  headers: z.record(z.string(), z.string()).optional(),
75
84
  providerOptions: providerOptionsSchema.optional(),
@@ -81,13 +90,21 @@ const reasoningOption = z.enum(assistantReasoningLevels).optional();
81
90
  // gateway()
82
91
  // ---------------------------------------------------------------------------
83
92
 
84
- const GATEWAY_API_KEY_ENV = "AI_GATEWAY_API_KEY";
93
+ export const GATEWAY_API_KEY_ENV = "AI_GATEWAY_API_KEY";
85
94
  /** The model the gateway adapter uses when none is configured. */
86
95
  const DEFAULT_GATEWAY_MODEL = "openai/gpt-5.5";
87
96
 
88
97
  /** Options for {@link gateway}. */
89
98
  export interface AssistantGatewayOptions extends AssistantAdapterOptions {
90
- /** A `provider/model` id routed by the gateway. Defaults to `openai/gpt-5.5`. */
99
+ /**
100
+ * Narration only: how the voice should sound, for speech models that take
101
+ * instructions ("Read calmly, like a teacher").
102
+ */
103
+ instructions?: string;
104
+ /**
105
+ * A `provider/model` id routed by the gateway. Defaults to `openai/gpt-5.5`
106
+ * for the assistant and `openai/tts-1-hd` for narration.
107
+ */
91
108
  model?: string;
92
109
  /**
93
110
  * How much the model reasons before answering. Sent as the AI SDK's
@@ -96,6 +113,8 @@ export interface AssistantGatewayOptions extends AssistantAdapterOptions {
96
113
  * offer the level you pick. Omitted keeps the model's default.
97
114
  */
98
115
  reasoning?: AssistantReasoning;
116
+ /** Narration only: the speech model's voice. Defaults to `alloy`. */
117
+ voice?: string;
99
118
  }
100
119
 
101
120
  const gatewayOptionsSchema = z.strictObject({
@@ -115,7 +134,8 @@ export const gatewayAdapterSchema = adapterDescriptorSchema(
115
134
  );
116
135
 
117
136
  /**
118
- * Route the assistant through the Vercel AI Gateway (the default). `model` is a
137
+ * Route the assistant through the Vercel AI Gateway (the default), or generate
138
+ * narration audio with one of its speech models. `model` is a
119
139
  * `provider/model` string; the key is `AI_GATEWAY_API_KEY`, or Vercel's OIDC
120
140
  * token when deployed there. Needs no provider SDK beyond the `ai` package
121
141
  * Blume ships.
@@ -129,6 +149,233 @@ export const gateway = (
129
149
  runtimeDeps: [],
130
150
  });
131
151
 
152
+ // ---------------------------------------------------------------------------
153
+ // openai()
154
+ // ---------------------------------------------------------------------------
155
+
156
+ const OPENAI_API_KEY_ENV = "OPENAI_API_KEY";
157
+
158
+ /** Options for {@link openai}. */
159
+ export interface AssistantOpenAIOptions extends AssistantAdapterOptions {
160
+ /**
161
+ * An OpenAI-compatible endpoint to call instead of OpenAI
162
+ * (`https://llm.internal.example.com/v1`): a self-hosted model or an
163
+ * internal gateway. The route then talks Chat Completions through
164
+ * `@ai-sdk/openai-compatible`, and the docs tools are off unless
165
+ * `ai.assistant.tools` turns them on, since the model may not call tools.
166
+ */
167
+ baseUrl?: string;
168
+ /** The model id (`gpt-5.5`). */
169
+ model: string;
170
+ /**
171
+ * The provider name the AI SDK reports, which a custom endpoint also reads
172
+ * its `providerOptions` under. Defaults to `openai`, or `openai-compatible`
173
+ * with a `baseUrl`.
174
+ */
175
+ name?: string;
176
+ /**
177
+ * How much the model reasons before answering, sent as `reasoning_effort`;
178
+ * with a `baseUrl`, the endpoint has to accept that parameter. Omitted
179
+ * keeps the model's default.
180
+ */
181
+ reasoning?: AssistantReasoning;
182
+ }
183
+
184
+ const openaiOptionsSchema = z.strictObject({
185
+ ...sharedOptions(OPENAI_API_KEY_ENV),
186
+ baseUrl: z.url().optional(),
187
+ model: z.string().min(1),
188
+ name: z.string().min(1).optional(),
189
+ reasoning: reasoningOption,
190
+ });
191
+
192
+ export type AssistantOpenAIAdapter = AdapterDescriptor<
193
+ "openai",
194
+ AssistantOpenAIOptions
195
+ >;
196
+
197
+ export const openaiAdapterSchema = adapterDescriptorSchema(
198
+ "openai",
199
+ openaiOptionsSchema
200
+ );
201
+
202
+ /**
203
+ * Route the assistant to OpenAI, or to any OpenAI-compatible endpoint with
204
+ * `baseUrl`. Reads `OPENAI_API_KEY` and needs `@ai-sdk/openai` installed; a
205
+ * custom endpoint needs `@ai-sdk/openai-compatible` instead, since most
206
+ * don't serve OpenAI's Responses API.
207
+ */
208
+ export const openai = (
209
+ options: AssistantOpenAIOptions
210
+ ): AssistantOpenAIAdapter => ({
211
+ kind: "openai",
212
+ options,
213
+ requiredSecrets: [options.apiKeyEnv ?? OPENAI_API_KEY_ENV],
214
+ runtimeDeps: [options.baseUrl ? OPENAI_COMPATIBLE_DEP : OPENAI_SDK.pkg],
215
+ });
216
+
217
+ /**
218
+ * Options for the deprecated {@link openaiCompatible}: {@link openai}'s, with
219
+ * the endpoint and its key env var required.
220
+ *
221
+ * @deprecated Use {@link AssistantOpenAIOptions}.
222
+ */
223
+ export interface AssistantOpenAICompatibleOptions extends AssistantOpenAIOptions {
224
+ apiKeyEnv: string;
225
+ baseUrl: string;
226
+ }
227
+
228
+ /** @deprecated Use {@link AssistantOpenAIAdapter}. */
229
+ export type AssistantOpenAICompatibleAdapter = AssistantOpenAIAdapter;
230
+
231
+ /**
232
+ * Route the assistant through an OpenAI-compatible endpoint.
233
+ *
234
+ * @deprecated Use `openai({ baseUrl, model, apiKeyEnv })`, which this calls.
235
+ */
236
+ export const openaiCompatible = (
237
+ options: AssistantOpenAICompatibleOptions
238
+ ): AssistantOpenAIAdapter => openai(options);
239
+
240
+ // ---------------------------------------------------------------------------
241
+ // anthropic()
242
+ // ---------------------------------------------------------------------------
243
+
244
+ const ANTHROPIC_API_KEY_ENV = "ANTHROPIC_API_KEY";
245
+
246
+ /** Options for {@link anthropic}. */
247
+ export interface AssistantAnthropicOptions extends AssistantAdapterOptions {
248
+ /** The Claude model id (`claude-sonnet-5`). */
249
+ model: string;
250
+ /**
251
+ * How much the model reasons before answering. The Anthropic provider
252
+ * maps the level to the model's thinking: an effort on models with
253
+ * adaptive thinking, a thinking budget on older ones, and thinking off for
254
+ * `"none"`. Omitted keeps the model's default.
255
+ */
256
+ reasoning?: AssistantReasoning;
257
+ }
258
+
259
+ const anthropicOptionsSchema = z.strictObject({
260
+ ...sharedOptions(ANTHROPIC_API_KEY_ENV),
261
+ model: z.string().min(1),
262
+ reasoning: reasoningOption,
263
+ });
264
+
265
+ export type AssistantAnthropicAdapter = AdapterDescriptor<
266
+ "anthropic",
267
+ AssistantAnthropicOptions
268
+ >;
269
+
270
+ export const anthropicAdapterSchema = adapterDescriptorSchema(
271
+ "anthropic",
272
+ anthropicOptionsSchema
273
+ );
274
+
275
+ /**
276
+ * Route the assistant to Anthropic's Claude API. Reads `ANTHROPIC_API_KEY`
277
+ * and needs `@ai-sdk/anthropic` installed.
278
+ */
279
+ export const anthropic = (
280
+ options: AssistantAnthropicOptions
281
+ ): AssistantAnthropicAdapter => ({
282
+ kind: "anthropic",
283
+ options,
284
+ requiredSecrets: [options.apiKeyEnv ?? ANTHROPIC_API_KEY_ENV],
285
+ runtimeDeps: [ANTHROPIC_SDK.pkg],
286
+ });
287
+
288
+ // ---------------------------------------------------------------------------
289
+ // gemini()
290
+ // ---------------------------------------------------------------------------
291
+
292
+ const GEMINI_API_KEY_ENV = "GEMINI_API_KEY";
293
+
294
+ /** Options for {@link gemini}. */
295
+ export interface AssistantGeminiOptions extends AssistantAdapterOptions {
296
+ /** The Gemini model id (`gemini-3.5-flash`). */
297
+ model: string;
298
+ /**
299
+ * How much the model reasons before answering. The Google provider maps
300
+ * the level to the model's thinking level, or to a thinking budget on
301
+ * models that take one. Omitted keeps the model's default.
302
+ */
303
+ reasoning?: AssistantReasoning;
304
+ }
305
+
306
+ const geminiOptionsSchema = z.strictObject({
307
+ ...sharedOptions(GEMINI_API_KEY_ENV),
308
+ model: z.string().min(1),
309
+ reasoning: reasoningOption,
310
+ });
311
+
312
+ export type AssistantGeminiAdapter = AdapterDescriptor<
313
+ "gemini",
314
+ AssistantGeminiOptions
315
+ >;
316
+
317
+ export const geminiAdapterSchema = adapterDescriptorSchema(
318
+ "gemini",
319
+ geminiOptionsSchema
320
+ );
321
+
322
+ /**
323
+ * Route the assistant to Google's Gemini API. Reads `GEMINI_API_KEY` and
324
+ * needs `@ai-sdk/google` installed.
325
+ */
326
+ export const gemini = (
327
+ options: AssistantGeminiOptions
328
+ ): AssistantGeminiAdapter => ({
329
+ kind: "gemini",
330
+ options,
331
+ requiredSecrets: [options.apiKeyEnv ?? GEMINI_API_KEY_ENV],
332
+ runtimeDeps: [GEMINI_SDK.pkg],
333
+ });
334
+
335
+ // ---------------------------------------------------------------------------
336
+ // grok()
337
+ // ---------------------------------------------------------------------------
338
+
339
+ const GROK_API_KEY_ENV = "XAI_API_KEY";
340
+
341
+ /** Options for {@link grok}. */
342
+ export interface AssistantGrokOptions extends AssistantAdapterOptions {
343
+ /** The Grok model id (`grok-4.7`). */
344
+ model: string;
345
+ /**
346
+ * How much the model reasons before answering, sent as xAI's reasoning
347
+ * effort on the models that take one. Omitted keeps the model's default.
348
+ */
349
+ reasoning?: AssistantReasoning;
350
+ }
351
+
352
+ const grokOptionsSchema = z.strictObject({
353
+ ...sharedOptions(GROK_API_KEY_ENV),
354
+ model: z.string().min(1),
355
+ reasoning: reasoningOption,
356
+ });
357
+
358
+ export type AssistantGrokAdapter = AdapterDescriptor<
359
+ "grok",
360
+ AssistantGrokOptions
361
+ >;
362
+
363
+ export const grokAdapterSchema = adapterDescriptorSchema(
364
+ "grok",
365
+ grokOptionsSchema
366
+ );
367
+
368
+ /**
369
+ * Route the assistant to xAI's Grok models. Reads `XAI_API_KEY` and needs
370
+ * `@ai-sdk/xai` installed.
371
+ */
372
+ export const grok = (options: AssistantGrokOptions): AssistantGrokAdapter => ({
373
+ kind: "grok",
374
+ options,
375
+ requiredSecrets: [options.apiKeyEnv ?? GROK_API_KEY_ENV],
376
+ runtimeDeps: [GROK_SDK.pkg],
377
+ });
378
+
132
379
  // ---------------------------------------------------------------------------
133
380
  // openrouter()
134
381
  // ---------------------------------------------------------------------------
@@ -272,87 +519,39 @@ export const inkeep = (
272
519
  runtimeDeps: [OPENAI_COMPATIBLE_DEP],
273
520
  });
274
521
 
275
- // ---------------------------------------------------------------------------
276
- // openaiCompatible()
277
- // ---------------------------------------------------------------------------
278
-
279
- /** Options for {@link openaiCompatible}. */
280
- export interface AssistantOpenAICompatibleOptions extends AssistantAdapterOptions {
281
- /** Name of the env var holding the endpoint's API key. */
282
- apiKeyEnv: string;
283
- /** The endpoint's base URL (`https://my-gateway.example.com/v1`). */
284
- baseUrl: string;
285
- /** The model id the endpoint serves. */
286
- model: string;
287
- /** The provider name the AI SDK reports. Defaults to `openai-compatible`. */
288
- name?: string;
289
- /**
290
- * How much the model reasons before answering, sent in the request as
291
- * `reasoning_effort`, so the endpoint has to accept that parameter.
292
- * Omitted keeps the model's default.
293
- */
294
- reasoning?: AssistantReasoning;
295
- }
296
-
297
- const openaiCompatibleOptionsSchema = z.strictObject({
298
- ...sharedOptions("API_KEY"),
299
- // A generic endpoint has no preset, so the caller names the key env var.
300
- apiKeyEnv: z.string().min(1),
301
- baseUrl: z.url(),
302
- model: z.string().min(1),
303
- name: z.string().min(1).default("openai-compatible"),
304
- reasoning: reasoningOption,
305
- });
306
-
307
- export type AssistantOpenAICompatibleAdapter = AdapterDescriptor<
308
- "openai-compatible",
309
- AssistantOpenAICompatibleOptions
310
- >;
311
-
312
- export const openaiCompatibleAdapterSchema = adapterDescriptorSchema(
313
- "openai-compatible",
314
- openaiCompatibleOptionsSchema
315
- );
316
-
317
- /**
318
- * Route the assistant through any OpenAI-compatible endpoint: supply its `baseUrl`,
319
- * the `model` it serves, and the env var holding its key. Needs
320
- * `@ai-sdk/openai-compatible` installed.
321
- */
322
- export const openaiCompatible = (
323
- options: AssistantOpenAICompatibleOptions
324
- ): AssistantOpenAICompatibleAdapter => ({
325
- kind: "openai-compatible",
326
- options,
327
- requiredSecrets: [options.apiKeyEnv],
328
- runtimeDeps: [OPENAI_COMPATIBLE_DEP],
329
- });
330
-
331
522
  // ---------------------------------------------------------------------------
332
523
  // The `ai.assistant.provider` schema
333
524
  // ---------------------------------------------------------------------------
334
525
 
335
- /** Which backend answers the assistant: the value of `gateway()`, `openrouter()`, … */
526
+ /** Which backend answers the assistant: the value of `gateway()`, `openai()`, … */
336
527
  export type AssistantAdapter =
337
528
  | AssistantGatewayAdapter
529
+ | AssistantOpenAIAdapter
530
+ | AssistantAnthropicAdapter
531
+ | AssistantGeminiAdapter
532
+ | AssistantGrokAdapter
338
533
  | AssistantOpenRouterAdapter
339
534
  | AssistantLlmGatewayAdapter
340
- | AssistantInkeepAdapter
341
- | AssistantOpenAICompatibleAdapter;
535
+ | AssistantInkeepAdapter;
342
536
 
343
537
  // ---------------------------------------------------------------------------
344
538
  // Blume 1 hints
345
539
  // ---------------------------------------------------------------------------
346
540
 
347
541
  /**
348
- * The 1.x `ai.ask.provider` names — also the adapters' `kind`s — each with the
349
- * `blume/ai` factory that replaced it.
542
+ * The adapters' `kind`s and the 1.x `ai.ask.provider` names, each with the
543
+ * `blume/ai` factory that takes its place.
350
544
  */
351
545
  const FACTORY_BY_PROVIDER = new Map([
546
+ ["anthropic", "anthropic"],
352
547
  ["gateway", "gateway"],
548
+ ["gemini", "gemini"],
549
+ ["grok", "grok"],
353
550
  ["inkeep", "inkeep"],
354
551
  ["llmgateway", "llmgateway"],
355
- ["openai-compatible", "openaiCompatible"],
552
+ ["openai", "openai"],
553
+ // 1.x only: an OpenAI-compatible endpoint is `openai()` with a `baseUrl`.
554
+ ["openai-compatible", "openai"],
356
555
  ["openrouter", "openrouter"],
357
556
  ]);
358
557
 
@@ -417,7 +616,7 @@ const providerNotAdapterMessage = (issue: z.core.$ZodRawIssue): string => {
417
616
  const factory = name.success ? FACTORY_BY_PROVIDER.get(name.data) : undefined;
418
617
  return factory
419
618
  ? `ai.assistant.provider takes an adapter from "blume/ai", not a provider name: \`provider: ${factory}({ model })\`. The 1.x model, apiKeyEnv, baseUrl, headers, and reasoning fields move into the call.`
420
- : 'ai.assistant.provider takes an adapter from "blume/ai": gateway(), openrouter(), llmgateway(), inkeep(), or openaiCompatible().';
619
+ : 'ai.assistant.provider takes an adapter from "blume/ai": openai(), anthropic(), gemini(), grok(), gateway(), openrouter(), llmgateway(), or inkeep().';
421
620
  };
422
621
 
423
622
  /**
@@ -429,10 +628,13 @@ export const assistantAdapterSchema = z.discriminatedUnion(
429
628
  "kind",
430
629
  [
431
630
  gatewayAdapterSchema,
631
+ openaiAdapterSchema,
632
+ anthropicAdapterSchema,
633
+ geminiAdapterSchema,
634
+ grokAdapterSchema,
432
635
  openrouterAdapterSchema,
433
636
  llmgatewayAdapterSchema,
434
637
  inkeepAdapterSchema,
435
- openaiCompatibleAdapterSchema,
436
638
  ],
437
639
  {
438
640
  // A non-object (a 1.x provider name) fails before any discriminator is
@@ -485,6 +687,12 @@ export interface AskBackendTemplate {
485
687
  export interface AskBackend {
486
688
  /** Whether Blume grounds answers in the docs (Inkeep retrieves itself). */
487
689
  grounded: boolean;
690
+ /**
691
+ * Whether the docs tools are on when `ai.assistant.tools` is unset: yes for
692
+ * the hosted model catalogs, whose models call tools, and no for an
693
+ * OpenAI-compatible backend, which may be a local model that can't.
694
+ */
695
+ toolsByDefault: boolean;
488
696
  kind: AssistantAdapterKind;
489
697
  /** Human-readable adapter name for diagnostics ("AI Gateway"). */
490
698
  label: string;
@@ -562,6 +770,7 @@ const gatewayBackend = (
562
770
  apiKey: ${secretExpr(options.apiKeyEnv)},${headersLine(options.headers)}
563
771
  });\n`,
564
772
  },
773
+ toolsByDefault: true,
565
774
  });
566
775
 
567
776
  const openrouterBackend = (
@@ -589,6 +798,7 @@ const openrouterBackend = (
589
798
  apiKey: ${secretExpr(options.apiKeyEnv)},${headersLine(options.headers)}
590
799
  });\n`,
591
800
  },
801
+ toolsByDefault: true,
592
802
  };
593
803
  };
594
804
 
@@ -601,6 +811,7 @@ const openaiCompatibleBackend = (
601
811
  kind: AssistantAdapterKind,
602
812
  label: string,
603
813
  grounded: boolean,
814
+ toolsByDefault: boolean,
604
815
  options: {
605
816
  apiKeyEnv: string;
606
817
  baseUrl: string;
@@ -630,8 +841,66 @@ const openaiCompatibleBackend = (
630
841
  name: ${JSON.stringify(options.name)},
631
842
  });\n`,
632
843
  },
844
+ toolsByDefault,
845
+ });
846
+
847
+ /**
848
+ * The backend for a provider Blume calls directly, through that provider's
849
+ * own AI SDK package, which maps the top-level `reasoning` call option to the
850
+ * model's control itself. Their models all call tools.
851
+ */
852
+ const directBackend = (
853
+ kind: AssistantAdapterKind,
854
+ label: string,
855
+ sdk: { factory: string; pkg: string },
856
+ options: {
857
+ apiKeyEnv: string;
858
+ headers?: Record<string, string>;
859
+ model: string;
860
+ name?: string;
861
+ providerOptions?: z.output<typeof providerOptionsSchema>;
862
+ reasoning?: AssistantReasoning;
863
+ }
864
+ ): AskBackend => ({
865
+ grounded: true,
866
+ kind,
867
+ label,
868
+ template: {
869
+ fields: callFields(options),
870
+ imports: [
871
+ 'import { createTextStreamResponse, streamText, toTextStream } from "ai";',
872
+ `import { ${sdk.factory} } from ${JSON.stringify(sdk.pkg)};`,
873
+ ],
874
+ keyCheck: keyCheck(options.apiKeyEnv),
875
+ model: `provider(${JSON.stringify(options.model)})`,
876
+ setup: `\nconst provider = ${sdk.factory}({
877
+ apiKey: ${secretExpr(options.apiKeyEnv)},${headersLine(options.headers)}${
878
+ options.name ? `\n name: ${JSON.stringify(options.name)},` : ""
879
+ }
880
+ });\n`,
881
+ },
882
+ toolsByDefault: true,
633
883
  });
634
884
 
885
+ /**
886
+ * `openai()`: OpenAI itself through its own SDK, or, with a `baseUrl`, a
887
+ * generic endpoint through the OpenAI-compatible provider — Chat Completions,
888
+ * which most such endpoints serve where the Responses API isn't — with the
889
+ * tools off by default, since a self-hosted model may not call them.
890
+ */
891
+ const openaiBackend = (
892
+ options: z.output<typeof openaiOptionsSchema>
893
+ ): AskBackend => {
894
+ const { baseUrl } = options;
895
+ return baseUrl
896
+ ? openaiCompatibleBackend("openai", "OpenAI-compatible", true, false, {
897
+ ...options,
898
+ baseUrl,
899
+ name: options.name ?? "openai-compatible",
900
+ })
901
+ : directBackend("openai", "OpenAI", OPENAI_SDK, options);
902
+ };
903
+
635
904
  /** Resolve a parsed `ai.assistant.provider` descriptor into its backend. */
636
905
  export const resolveAskBackend = (
637
906
  provider: AssistantAdapterConfig = assistantAdapterSchema.parse(
@@ -642,11 +911,25 @@ export const resolveAskBackend = (
642
911
  case "gateway": {
643
912
  return gatewayBackend(provider.options);
644
913
  }
914
+ case "anthropic": {
915
+ return directBackend(
916
+ "anthropic",
917
+ "Anthropic",
918
+ ANTHROPIC_SDK,
919
+ provider.options
920
+ );
921
+ }
922
+ case "gemini": {
923
+ return directBackend("gemini", "Gemini", GEMINI_SDK, provider.options);
924
+ }
925
+ case "grok": {
926
+ return directBackend("grok", "Grok", GROK_SDK, provider.options);
927
+ }
645
928
  case "openrouter": {
646
929
  return openrouterBackend(provider.options);
647
930
  }
648
931
  case "llmgateway": {
649
- return openaiCompatibleBackend("llmgateway", "LLMGateway", true, {
932
+ return openaiCompatibleBackend("llmgateway", "LLMGateway", true, true, {
650
933
  ...provider.options,
651
934
  name: "llmgateway",
652
935
  });
@@ -654,18 +937,13 @@ export const resolveAskBackend = (
654
937
  case "inkeep": {
655
938
  // Inkeep answers from the content indexed in its dashboard, so injected
656
939
  // excerpts would conflict with its own retrieval.
657
- return openaiCompatibleBackend("inkeep", "Inkeep", false, {
940
+ return openaiCompatibleBackend("inkeep", "Inkeep", false, false, {
658
941
  ...provider.options,
659
942
  name: "inkeep",
660
943
  });
661
944
  }
662
945
  default: {
663
- return openaiCompatibleBackend(
664
- "openai-compatible",
665
- "OpenAI-compatible",
666
- true,
667
- provider.options
668
- );
946
+ return openaiBackend(provider.options);
669
947
  }
670
948
  }
671
949
  };
@@ -1,4 +1,5 @@
1
1
  import { mountBasePath, normalizeBasePath } from "../core/base-path.ts";
2
+ import { withChangelogIndexText } from "../core/changelog-index.ts";
2
3
  import { EN_UI, resolveUIStrings } from "../core/i18n-ui.ts";
3
4
  import type { BlumeProject } from "../core/project-graph.ts";
4
5
  import { absoluteUrl } from "../core/site-url.ts";
@@ -45,12 +46,16 @@ const rowLine = (project: BlumeProject, { date, page }: IndexRow): string => {
45
46
 
46
47
  export const buildChangelogIndexMarkdown = (project: BlumeProject): string => {
47
48
  const { i18n } = project.config;
48
- const ui = i18n
49
- ? resolveUIStrings(i18n.defaultLocale, {
50
- defaultLocale: i18n.defaultLocale,
51
- overrides: i18n.ui,
52
- })
53
- : EN_UI;
49
+ const ui = withChangelogIndexText(
50
+ project.config,
51
+ i18n
52
+ ? resolveUIStrings(i18n.defaultLocale, {
53
+ defaultLocale: i18n.defaultLocale,
54
+ overrides: i18n.ui,
55
+ })
56
+ : EN_UI,
57
+ i18n?.defaultLocale
58
+ );
54
59
  const rows: IndexRow[] = project.graph.pages
55
60
  .filter(
56
61
  (page) =>