okengine 0.18.4 → 0.19.0

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 (512) hide show
  1. package/AGENTS.md +18 -10
  2. package/README.md +2 -2
  3. package/package.json +51 -50
  4. package/site/content/docs/ai/index.mdx +25 -6
  5. package/site/content/docs/ai/llms-txt.mdx +1 -1
  6. package/site/content/docs/ai/meta.json +1 -1
  7. package/site/content/docs/ai/skills.mdx +4 -1
  8. package/site/content/docs/ai/try-it.mdx +58 -0
  9. package/site/content/docs/client/auth.mdx +208 -0
  10. package/site/content/docs/client/calling.mdx +451 -0
  11. package/site/content/docs/client/index.mdx +209 -0
  12. package/site/content/docs/client/live.mdx +234 -0
  13. package/site/content/docs/client/meta.json +5 -0
  14. package/site/content/docs/client/react.mdx +249 -0
  15. package/site/content/docs/elements/ai/agents.mdx +232 -0
  16. package/site/content/docs/elements/ai/index.mdx +341 -0
  17. package/site/content/docs/elements/ai/mcp.mdx +275 -0
  18. package/site/content/docs/elements/ai/meta.json +5 -0
  19. package/site/content/docs/elements/ai/models.mdx +283 -0
  20. package/site/content/docs/elements/ai/prompts.mdx +256 -0
  21. package/site/content/docs/elements/channel/email.mdx +266 -0
  22. package/site/content/docs/elements/channel/index.mdx +344 -0
  23. package/site/content/docs/elements/channel/meta.json +5 -0
  24. package/site/content/docs/elements/channel/push.mdx +218 -0
  25. package/site/content/docs/elements/channel/receipts.mdx +206 -0
  26. package/site/content/docs/elements/channel/sms.mdx +264 -0
  27. package/site/content/docs/elements/channel/whatsapp.mdx +220 -0
  28. package/site/content/docs/elements/clock/index.mdx +300 -0
  29. package/site/content/docs/elements/clock/meta.json +5 -0
  30. package/site/content/docs/elements/clock/schedules.mdx +508 -0
  31. package/site/content/docs/elements/clock/sleep.mdx +445 -0
  32. package/site/content/docs/elements/flow/consumers.mdx +707 -0
  33. package/site/content/docs/elements/flow/http.mdx +1080 -0
  34. package/site/content/docs/elements/flow/index.mdx +618 -0
  35. package/site/content/docs/elements/flow/meta.json +5 -0
  36. package/site/content/docs/elements/flow/routing.mdx +559 -0
  37. package/site/content/docs/elements/flow/workflows.mdx +640 -0
  38. package/site/content/docs/elements/gate/auth.mdx +371 -0
  39. package/site/content/docs/elements/gate/authorization.mdx +298 -0
  40. package/site/content/docs/elements/gate/index.mdx +418 -0
  41. package/site/content/docs/elements/gate/meta.json +5 -0
  42. package/site/content/docs/elements/gate/rate-limits.mdx +365 -0
  43. package/site/content/docs/elements/gate/rls.mdx +303 -0
  44. package/site/content/docs/elements/gate/tenancy.mdx +372 -0
  45. package/site/content/docs/elements/index.mdx +52 -11
  46. package/site/content/docs/elements/signal/broadcast.mdx +517 -0
  47. package/site/content/docs/elements/signal/index.mdx +352 -0
  48. package/site/content/docs/elements/signal/live.mdx +590 -0
  49. package/site/content/docs/elements/signal/meta.json +5 -0
  50. package/site/content/docs/elements/signal/once.mdx +596 -0
  51. package/site/content/docs/elements/store/files.mdx +659 -0
  52. package/site/content/docs/elements/store/index.mdx +310 -0
  53. package/site/content/docs/elements/store/kv.mdx +629 -0
  54. package/site/content/docs/elements/store/meta.json +5 -0
  55. package/site/content/docs/elements/store/search.mdx +946 -0
  56. package/site/content/docs/elements/store/sql.mdx +937 -0
  57. package/site/content/docs/elements/vault/config.mdx +256 -0
  58. package/site/content/docs/elements/vault/index.mdx +356 -0
  59. package/site/content/docs/elements/vault/meta.json +5 -0
  60. package/site/content/docs/elements/vault/rotation.mdx +273 -0
  61. package/site/content/docs/elements/vault/secrets.mdx +285 -0
  62. package/site/content/docs/index.mdx +78 -30
  63. package/site/content/docs/meta.json +11 -8
  64. package/site/content/docs/plugins/cors.mdx +2 -1
  65. package/site/content/docs/plugins/csrf.mdx +4 -1
  66. package/site/content/docs/plugins/headers.mdx +2 -1
  67. package/site/content/docs/plugins/ip-allowlist.mdx +2 -1
  68. package/site/content/docs/plugins/magic-link.mdx +6 -0
  69. package/site/content/docs/plugins/maintenance-mode.mdx +2 -1
  70. package/site/content/docs/plugins/oauth.mdx +1 -1
  71. package/site/content/docs/plugins/otp.mdx +12 -1
  72. package/site/content/docs/plugins/passkey.mdx +39 -15
  73. package/site/content/docs/plugins/two-factor.mdx +91 -34
  74. package/site/content/docs/plugins/username.mdx +1 -1
  75. package/site/content/docs/recipes/caddy.mdx +3 -3
  76. package/site/content/docs/recipes/index.mdx +18 -28
  77. package/site/content/docs/recipes/mailpit.mdx +1 -1
  78. package/site/content/docs/recipes/meilisearch.mdx +3 -3
  79. package/site/content/docs/recipes/meta.json +1 -4
  80. package/site/content/docs/recipes/nginx.mdx +2 -2
  81. package/site/content/docs/recipes/openrouter.mdx +283 -0
  82. package/site/content/docs/recipes/pgdog.mdx +3 -3
  83. package/site/content/docs/recipes/postgres.mdx +1 -2
  84. package/site/content/docs/recipes/rustfs.mdx +2 -2
  85. package/site/content/docs/recipes/traefik.mdx +3 -3
  86. package/site/content/docs/reference/cli.mdx +231 -0
  87. package/site/content/docs/reference/configuration.mdx +30 -10
  88. package/site/content/docs/reference/environment-variables.mdx +93 -20
  89. package/site/content/docs/reference/errors.mdx +132 -29
  90. package/site/content/docs/reference/fx.mdx +137 -73
  91. package/site/content/docs/reference/index.mdx +13 -21
  92. package/site/content/docs/reference/meta.json +4 -5
  93. package/site/content/docs/reference/okid.mdx +42 -17
  94. package/site/content/docs/reference/plugins.mdx +4 -3
  95. package/site/content/docs/reference/security.mdx +197 -0
  96. package/site/content/docs/understand/meta.json +5 -0
  97. package/site/content/docs/understand/the-anatomy.mdx +132 -0
  98. package/site/content/docs/understand/the-model.mdx +32 -0
  99. package/site/content/docs/understand/the-problem.mdx +74 -0
  100. package/site/content/docs/understand/the-vocabulary.mdx +26 -0
  101. package/src/auth/api-keys.ts +2 -1
  102. package/src/auth/bindings.ts +64 -16
  103. package/src/auth/gate-auth.test.ts +6 -1
  104. package/src/auth/identity.ts +152 -5
  105. package/src/auth/index.ts +29 -0
  106. package/src/auth/invites.ts +2 -1
  107. package/src/auth/method-context.ts +41 -0
  108. package/src/auth/oauth-as/crypto.ts +2 -1
  109. package/src/auth/oauth-as/stores.ts +2 -1
  110. package/src/auth/operator.ts +2 -1
  111. package/src/auth/sessions-jwt.test.ts +77 -0
  112. package/src/auth/sessions.ts +20 -4
  113. package/src/auth/tenants.ts +3 -2
  114. package/src/auth/two-factor-challenge.test.ts +61 -0
  115. package/src/auth/two-factor-challenge.ts +284 -0
  116. package/src/auth/verification.ts +5 -0
  117. package/src/bench/REPORT.md +49 -0
  118. package/src/bench/g03-signal-once.bench.ts +1 -1
  119. package/src/bench/g10-observability-contention.bench.ts +1 -1
  120. package/src/bench/g17-hybrid-search.bench.ts +572 -0
  121. package/src/bench/load-app.ts +2 -10
  122. package/src/cli/ai-setup/ai-setup.test.ts +331 -42
  123. package/src/cli/ai-setup/apply.ts +294 -52
  124. package/src/cli/ai-setup/catalog.ts +238 -1342
  125. package/src/cli/ai-setup/index.ts +14 -99
  126. package/src/cli/ai-setup/prompts.ts +60 -443
  127. package/src/cli/ask-seed.test.ts +96 -0
  128. package/src/cli/ask-seed.ts +82 -0
  129. package/src/cli/ask-vault-gaps.test.ts +84 -0
  130. package/src/cli/ask-vault-gaps.ts +146 -0
  131. package/src/cli/build.ts +2 -2
  132. package/src/cli/client-add.test.ts +26 -1
  133. package/src/cli/client-add.ts +106 -27
  134. package/src/cli/competitor-mention-removal.test.ts +1 -1
  135. package/src/cli/db-seed.ts +2 -0
  136. package/src/cli/db.ts +150 -11
  137. package/src/cli/dev.ts +119 -211
  138. package/src/cli/docker-clean.ts +2 -2
  139. package/src/cli/docker-cli.test.ts +1 -1
  140. package/src/cli/doctor-diff.ts +4 -2
  141. package/src/cli/doctor-pii.test.ts +1 -1
  142. package/src/cli/doctor.ts +14 -1
  143. package/src/cli/hero-meta.test.ts +4 -2
  144. package/src/cli/load-config.images.test.ts +8 -10
  145. package/src/cli/load-config.ts +1 -1
  146. package/src/cli/registry.ts +22 -10
  147. package/src/cli/replay.ts +3 -1
  148. package/src/cli/start.ts +1 -1
  149. package/src/cli/tui/keys.ts +2 -3
  150. package/src/client/auth/cookies.ts +74 -0
  151. package/src/client/auth/create-auth-client.ts +636 -0
  152. package/src/client/auth/denials.ts +99 -0
  153. package/src/client/auth/session.ts +283 -0
  154. package/src/client/auth.test.ts +251 -0
  155. package/src/client/auth.ts +39 -114
  156. package/src/client/create-with-session.ts +245 -0
  157. package/src/client/create.ts +51 -5
  158. package/src/client/index.ts +11 -1
  159. package/src/client/live.ts +11 -79
  160. package/src/client/notes-contract.test.ts +5 -10
  161. package/src/client/sse.ts +137 -0
  162. package/src/client/stream.ts +147 -0
  163. package/src/client/transport.test.ts +32 -0
  164. package/src/client/transport.ts +123 -26
  165. package/src/client/types.ts +118 -14
  166. package/src/client-react/index.ts +185 -24
  167. package/src/client-react/use-live-query.ts +13 -3
  168. package/src/compiler/aot.test.ts +7 -4
  169. package/src/compiler/effects-embed.test.ts +56 -0
  170. package/src/compiler/effects-fetch.test.ts +43 -0
  171. package/src/compiler/effects-infer.ts +58 -2
  172. package/src/compiler/extract.test.ts +258 -44
  173. package/src/compiler/extract.ts +566 -48
  174. package/src/compiler/fixtures/skyport/src/flows/bookings/index.ts +7 -4
  175. package/src/compiler/fixtures/skyport/src/flows/bookings/signals.ts +2 -8
  176. package/src/compiler/fixtures/skyport.expected.json +4 -4
  177. package/src/compiler/fixtures/triggers/five-triggers.ts +14 -10
  178. package/src/compiler/response.ts +2 -2
  179. package/src/compiler/search-writer-isolation.test.ts +40 -0
  180. package/src/config/index.ts +11 -0
  181. package/src/console/server/app.ts +17 -23
  182. package/src/console/server/bind.ts +4 -0
  183. package/src/console/server/console.test.ts +2 -2
  184. package/src/console/server/flows-invoke.test.ts +50 -34
  185. package/src/console/server/flows.ts +436 -255
  186. package/src/console/server/runs-ingest.test.ts +6 -3
  187. package/src/console/server/serve.ts +1 -1
  188. package/src/console/server/signals.test.ts +1 -5
  189. package/src/console/server/signals.ts +8 -6
  190. package/src/console/server/state.ts +6 -1
  191. package/src/console/server/store.ts +1 -1
  192. package/src/console/ui-next/dist/assets/FileExportIcon-Ck-5od4R.js +1 -0
  193. package/src/console/ui-next/dist/assets/MoreHorizontalCircle01Icon-gMNGsE37.js +1 -0
  194. package/src/console/ui-next/dist/assets/PlusSignIcon-CwG3nxfu.js +1 -0
  195. package/src/console/ui-next/dist/assets/UnavailableIcon-D9cvHVPr.js +1 -0
  196. package/src/console/ui-next/dist/assets/UserIcon-DaE2PB5_.js +1 -0
  197. package/src/console/ui-next/dist/assets/access-page-DFeymU07.js +4 -0
  198. package/src/console/ui-next/dist/assets/agent-disclosure-U1rdfblp.js +1 -0
  199. package/src/console/ui-next/dist/assets/cache-glyph-BeFJeqBG.js +1 -0
  200. package/src/console/ui-next/dist/assets/call-pii-button-CVAONPii.js +1 -0
  201. package/src/console/ui-next/dist/assets/collapsible-D2A6NJ-3.js +1 -0
  202. package/src/console/ui-next/dist/assets/copy-inline-button-CAYD18cr.js +1 -0
  203. package/src/console/ui-next/dist/assets/dagre.esm-B1_XeuLP.js +1 -0
  204. package/src/console/ui-next/dist/assets/detail-header-DVWNjWjg.js +1 -0
  205. package/src/console/ui-next/dist/assets/dropdown-menu-4h2LOVXM.js +1 -0
  206. package/src/console/ui-next/dist/assets/duration-tone-Cgk_h5ja.js +9 -0
  207. package/src/console/ui-next/dist/assets/element-icons-BI8cJgdh.js +1 -0
  208. package/src/console/ui-next/dist/assets/explorer-empty-CJs5A-wm.js +1 -0
  209. package/src/console/ui-next/dist/assets/flows-page-Dss7941e.js +1 -0
  210. package/src/console/ui-next/dist/assets/highlighted-json-MYZQtRnw.js +154 -0
  211. package/src/console/ui-next/dist/assets/http-method-Jrh39p7A.js +1 -0
  212. package/src/console/ui-next/dist/assets/index-D0zS5rKO.css +2 -0
  213. package/src/console/ui-next/dist/assets/index-DXP2dBIF.js +63 -0
  214. package/src/console/ui-next/dist/assets/observability-page-HvolXxTI.js +4 -0
  215. package/src/console/ui-next/dist/assets/react-dom-Ddte4I-Q.js +9 -0
  216. package/src/console/ui-next/dist/assets/replica-lag-CSh2dzrb.js +18 -0
  217. package/src/console/ui-next/dist/assets/request-meta-BatF8KrK.js +1 -0
  218. package/src/console/ui-next/dist/assets/shortcut-keys-3ILd8oGn.js +1 -0
  219. package/src/console/ui-next/dist/assets/{sql-BskegiFM.js → sql-BsFa4tDR.js} +1 -1
  220. package/src/console/ui-next/dist/assets/store-page-eiKiHnNe.js +41 -0
  221. package/src/console/ui-next/dist/assets/trace-detail-sheet-CZkMeKS-.js +2 -0
  222. package/src/console/ui-next/dist/assets/tree-expand-toggle-CW8y5A2h.js +55 -0
  223. package/src/console/ui-next/dist/assets/units-page-B_RWJrEO.js +1 -0
  224. package/src/console/ui-next/dist/assets/{use-vault-list-uk4WVboC.js → use-vault-list-CT4-gajj.js} +1 -1
  225. package/src/console/ui-next/dist/assets/vault-page-CWrg-A68.js +2 -0
  226. package/src/console/ui-next/dist/assets/xyflow-CSyC6ryz.css +1 -0
  227. package/src/console/ui-next/dist/assets/xyflow-yApv7D4e.js +7 -0
  228. package/src/console/ui-next/dist/index.html +6 -13
  229. package/src/console/ui-next/seed-invoke-host.ts +21 -18
  230. package/src/console/ui-next/src/client.ts +7 -2
  231. package/src/console/ui-next/src/features/flows/graph/element-map.ts +2 -0
  232. package/src/console/ui-next/src/features/flows/traces/effect-kind.ts +12 -2
  233. package/src/console/ui-next/src/features/flows/traces/effect-summary.ts +4 -0
  234. package/src/console/ui-next/src/features/flows/traces/trace-detail-sheet.tsx +8 -0
  235. package/src/console/ui-next/src/features/flows/traces/waterfall-bars.ts +4 -0
  236. package/src/console/ui-next/src/features/flows/traces/waterfall-tooltip.ts +9 -3
  237. package/src/console/ui-next/src/features/store/detail/reveal-cell.tsx +7 -11
  238. package/src/console/ui-next/src/features/store/detail/store-row-detail-sheet.tsx +2 -2
  239. package/src/console/ui-next/src/features/store/lib/fields-from-table.ts +2 -0
  240. package/src/console/ui-next/src/features/store/lib/grid-model.test.ts +25 -1
  241. package/src/console/ui-next/src/features/store/lib/grid-model.ts +36 -1
  242. package/src/console/ui-next/src/features/store/query/query-results.tsx +3 -3
  243. package/src/console/ui-next/src/features/units/detail/effects-summary.tsx +2 -0
  244. package/src/console/ui-next/src/features/units/lib/call-read-safe.ts +3 -1
  245. package/src/console/ui-next/src/features/units/lib/fields-from-schema.ts +6 -0
  246. package/src/docker/ai-model-status.test.ts +1 -12
  247. package/src/docker/ai-model-status.ts +10 -38
  248. package/src/docker/compose-up.test.ts +100 -0
  249. package/src/docker/compose-up.ts +292 -0
  250. package/src/docker/compose.ts +4 -14
  251. package/src/docker/derive.ts +9 -34
  252. package/src/docker/docker.test.ts +16 -261
  253. package/src/docker/images-config.test.ts +13 -25
  254. package/src/docker/index.ts +1 -24
  255. package/src/docker/recipes/index.ts +0 -23
  256. package/src/docker/recipes/pgdog.ts +6 -4
  257. package/src/docker/stack-id.test.ts +2 -2
  258. package/src/docker/stack-id.ts +0 -1
  259. package/src/docker/types.ts +2 -2
  260. package/src/drivers/ai-anthropic.ts +10 -0
  261. package/src/drivers/ai-openai-compatible.ts +34 -7
  262. package/src/drivers/ai-providers.test.ts +0 -107
  263. package/src/drivers/ai-stream.test.ts +0 -34
  264. package/src/drivers/ai-types.ts +17 -8
  265. package/src/drivers/channel-fcm.ts +6 -1
  266. package/src/drivers/channel-msegat.ts +6 -1
  267. package/src/drivers/channel-resend.ts +5 -1
  268. package/src/drivers/channel-smtp.ts +5 -1
  269. package/src/drivers/channel-sndr.ts +10 -1
  270. package/src/drivers/channel-taqnyat-mail.ts +5 -1
  271. package/src/drivers/channel-taqnyat-whatsapp.ts +6 -1
  272. package/src/drivers/channel-taqnyat.ts +6 -1
  273. package/src/drivers/channel-types.ts +10 -0
  274. package/src/drivers/channel-unifonic.ts +6 -1
  275. package/src/drivers/channel-wa-cloud.ts +6 -1
  276. package/src/drivers/channel-webpush.ts +6 -1
  277. package/src/drivers/external.ts +33 -0
  278. package/src/drivers/index.ts +0 -10
  279. package/src/drivers/meilisearch.ts +6 -0
  280. package/src/drivers/oauth-types.ts +4 -0
  281. package/src/drivers/postgres.test.ts +74 -3
  282. package/src/drivers/postgres.ts +175 -6
  283. package/src/drivers/signal-types.ts +5 -5
  284. package/src/drivers/types.ts +7 -0
  285. package/src/drivers/vault-types.ts +5 -0
  286. package/src/elements/ai/declare.ts +17 -4
  287. package/src/elements/ai/eval.ts +1 -1
  288. package/src/elements/ai/mcp-http.ts +1 -1
  289. package/src/elements/ai/pii.ts +1 -1
  290. package/src/elements/ai/providers.test.ts +289 -0
  291. package/src/elements/ai/providers.ts +169 -0
  292. package/src/elements/ai/runtime.ts +68 -5
  293. package/src/elements/ai/schema.ts +2 -2
  294. package/src/elements/ai.test.ts +7 -7
  295. package/src/elements/ai.ts +17 -1
  296. package/src/elements/channel/runtime.ts +105 -12
  297. package/src/elements/clock/cron-fields.test.ts +144 -0
  298. package/src/elements/clock/cron-fields.ts +185 -0
  299. package/src/elements/clock/declare.ts +247 -3
  300. package/src/elements/clock.ts +21 -1
  301. package/src/elements/index.ts +15 -0
  302. package/src/elements/signal/chaos-child.ts +1 -2
  303. package/src/elements/signal/declare.ts +65 -37
  304. package/src/elements/signal/delivery-modes.test.ts +11 -31
  305. package/src/elements/signal/dry-run-replay.test.ts +1 -7
  306. package/src/elements/signal/dry-run-write-isolation.test.ts +1 -7
  307. package/src/elements/signal/key-ordering.test.ts +6 -26
  308. package/src/elements/signal/lease-reclaim.test.ts +2 -6
  309. package/src/elements/signal/optional-emit.test.ts +6 -9
  310. package/src/elements/signal/order-lifecycle.test.ts +4 -17
  311. package/src/elements/signal/orphan-messages.test.ts +4 -15
  312. package/src/elements/signal/reconcile.test.ts +2 -2
  313. package/src/elements/signal/runtime.ts +1 -1
  314. package/src/elements/signal/schema-emit.test.ts +4 -8
  315. package/src/elements/signal.test.ts +24 -49
  316. package/src/elements/signal.ts +9 -2
  317. package/src/elements/store/domain-ddl.test.ts +1 -1
  318. package/src/elements/store/live-http.test.ts +9 -4
  319. package/src/elements/store/prepare-row.test.ts +123 -0
  320. package/src/elements/store/resource.ts +43 -12
  321. package/src/elements/store/schema-decl.ts +117 -0
  322. package/src/elements/store/search-backfill.ts +205 -0
  323. package/src/elements/store/search-bind.ts +66 -0
  324. package/src/elements/store/search-bm25.ts +78 -0
  325. package/src/elements/store/search-ddl.ts +156 -0
  326. package/src/elements/store/search-embed-flow.ts +141 -0
  327. package/src/elements/store/search-errors.ts +34 -0
  328. package/src/elements/store/search-fusion.ts +112 -0
  329. package/src/elements/store/search-lsh.ts +179 -0
  330. package/src/elements/store/search-runtime.ts +300 -0
  331. package/src/elements/store/search.test.ts +144 -0
  332. package/src/elements/store/sql-session.test.ts +1 -0
  333. package/src/elements/store/sql-session.ts +83 -3
  334. package/src/elements/store/table.ts +23 -2
  335. package/src/elements/store/upsert-app.test.ts +1 -3
  336. package/src/elements/store.ts +50 -0
  337. package/src/full.ts +4 -2
  338. package/src/http.ts +4 -1
  339. package/src/i18n/catalogs/ar.ts +14 -6
  340. package/src/i18n/catalogs/en.ts +14 -6
  341. package/src/index.ts +6 -1
  342. package/src/kernel/adopt-barrel-fresh.test.ts +7 -7
  343. package/src/kernel/adopt-routes.ts +9 -1
  344. package/src/kernel/app-auth.ts +5 -0
  345. package/src/kernel/app.ts +102 -9
  346. package/src/kernel/auto-cache.test.ts +6 -12
  347. package/src/kernel/auto-registry.test.ts +3 -3
  348. package/src/kernel/boot-bind/ai.test.ts +22 -19
  349. package/src/kernel/boot-bind/ai.ts +5 -43
  350. package/src/kernel/boot-bind/clock.ts +23 -5
  351. package/src/kernel/boot-bind/honor-config.test.ts +4 -4
  352. package/src/kernel/boot.test.ts +11 -6
  353. package/src/kernel/boot.ts +66 -16
  354. package/src/kernel/boundary-contract.ts +93 -0
  355. package/src/kernel/budget.test.ts +1 -1
  356. package/src/kernel/call.ts +89 -0
  357. package/src/kernel/capability.ts +6 -0
  358. package/src/kernel/client-descriptor.ts +123 -0
  359. package/src/kernel/clock-timezone.test.ts +80 -0
  360. package/src/kernel/correlation.test.ts +1 -1
  361. package/src/kernel/dry-run.ts +11 -8
  362. package/src/kernel/effects-stamping.test.ts +42 -9
  363. package/src/kernel/effects.test.ts +4 -2
  364. package/src/kernel/effects.ts +51 -9
  365. package/src/kernel/errors-channel.ts +17 -0
  366. package/src/kernel/errors-live-resume.ts +3 -2
  367. package/src/kernel/errors-tenant.ts +7 -4
  368. package/src/kernel/errors.registry-helpers.ts +96 -0
  369. package/src/kernel/errors.registry.test.ts +139 -25
  370. package/src/kernel/errors.ts +102 -23
  371. package/src/kernel/external-effects.test.ts +196 -0
  372. package/src/kernel/flow.test.ts +13 -4
  373. package/src/kernel/flow.ts +69 -71
  374. package/src/kernel/fx-ask-telemetry.test.ts +2 -2
  375. package/src/kernel/fx-dead-letters.test.ts +3 -3
  376. package/src/kernel/fx-fetch.ts +55 -0
  377. package/src/kernel/fx-live-stream.ts +2 -2
  378. package/src/kernel/fx-live.test.ts +8 -8
  379. package/src/kernel/fx.test.ts +17 -11
  380. package/src/kernel/fx.ts +180 -57
  381. package/src/kernel/horizontal-child.ts +1 -1
  382. package/src/kernel/http-query.test.ts +3 -6
  383. package/src/kernel/index.ts +13 -3
  384. package/src/kernel/instance-id.ts +1 -1
  385. package/src/kernel/instances.test.ts +40 -0
  386. package/src/kernel/instances.ts +47 -9
  387. package/src/kernel/live-http.test.ts +6 -7
  388. package/src/kernel/live-http.ts +6 -2
  389. package/src/kernel/live-resume.test.ts +1 -1
  390. package/src/kernel/mcp-tool.test.ts +3 -3
  391. package/src/kernel/on.ts +98 -4
  392. package/src/kernel/pipeline.test.ts +12 -15
  393. package/src/kernel/plugin-elements.test.ts +1 -1
  394. package/src/kernel/stamp-http.test.ts +3 -3
  395. package/src/kernel/triggers.ts +210 -95
  396. package/src/kernel-entry.ts +0 -1
  397. package/src/manifest/diff.ts +11 -1
  398. package/src/manifest/fixtures/skyport.excerpt.json +1 -1
  399. package/src/manifest/types.ts +46 -2
  400. package/src/mcp/docs-index.ts +3 -3
  401. package/src/mcp/docs-mcp.test.ts +2 -2
  402. package/src/mcp/docs-tools.ts +1 -1
  403. package/src/okid.test.ts +56 -0
  404. package/src/okid.ts +55 -11
  405. package/src/plugins/anonymous.ts +8 -4
  406. package/src/plugins/auth/shared.ts +27 -3
  407. package/src/plugins/auth-delivery.mailpit.integration.test.ts +1 -1
  408. package/src/plugins/auth-methods.security.test.ts +561 -23
  409. package/src/plugins/config-source.ts +1 -1
  410. package/src/plugins/csrf.test.ts +65 -0
  411. package/src/plugins/index.ts +2 -0
  412. package/src/plugins/magic-link.ts +36 -16
  413. package/src/plugins/oauth/shared.ts +3 -1
  414. package/src/plugins/oauth.ts +22 -14
  415. package/src/plugins/otp.ts +37 -21
  416. package/src/plugins/passkey-webauthn.ts +9 -6
  417. package/src/plugins/passkey.ts +98 -26
  418. package/src/plugins/pre-account-hijack.test.ts +223 -0
  419. package/src/plugins/two-factor.ts +466 -37
  420. package/src/plugins/username.ts +19 -7
  421. package/src/release/build-lib.ts +1 -0
  422. package/src/release/limits.ts +2 -2
  423. package/src/release/measure.ts +1 -1
  424. package/src/runs/collect.test.ts +0 -2
  425. package/src/runtime/json-code-block.test.ts +250 -20
  426. package/src/runtime/json-code-block.ts +1261 -41
  427. package/src/term.test.ts +1 -1
  428. package/src/test/create-test-app.test.ts +12 -12
  429. package/src/test/live-signals.test.ts +6 -6
  430. package/src/test/provisions.integration.test.ts +10 -14
  431. package/src/test/reset-element-registries.ts +1 -1
  432. package/src/test/tenant-isolation.test.ts +12 -6
  433. package/site/content/docs/deployment/docker-swarm.mdx +0 -164
  434. package/site/content/docs/deployment/docker.mdx +0 -227
  435. package/site/content/docs/deployment/index.mdx +0 -83
  436. package/site/content/docs/deployment/kubernetes.mdx +0 -176
  437. package/site/content/docs/deployment/meta.json +0 -5
  438. package/site/content/docs/deployment/reverse-proxy.mdx +0 -234
  439. package/site/content/docs/elements/ai.mdx +0 -385
  440. package/site/content/docs/elements/channel.mdx +0 -346
  441. package/site/content/docs/elements/clock.mdx +0 -244
  442. package/site/content/docs/elements/flow.mdx +0 -420
  443. package/site/content/docs/elements/gate.mdx +0 -436
  444. package/site/content/docs/elements/signal.mdx +0 -380
  445. package/site/content/docs/elements/store.mdx +0 -1099
  446. package/site/content/docs/elements/vault.mdx +0 -405
  447. package/site/content/docs/get-started/basic-usage.mdx +0 -173
  448. package/site/content/docs/get-started/index.mdx +0 -43
  449. package/site/content/docs/get-started/installation.mdx +0 -220
  450. package/site/content/docs/get-started/introduction.mdx +0 -132
  451. package/site/content/docs/get-started/meta.json +0 -13
  452. package/site/content/docs/get-started/project-structure.mdx +0 -925
  453. package/site/content/docs/get-started/testing.mdx +0 -328
  454. package/site/content/docs/get-started/why.mdx +0 -162
  455. package/site/content/docs/recipes/llama-cpp.mdx +0 -151
  456. package/site/content/docs/recipes/ollama.mdx +0 -142
  457. package/site/content/docs/recipes/sglang.mdx +0 -105
  458. package/site/content/docs/recipes/vllm.mdx +0 -106
  459. package/site/content/docs/reference/cli.md +0 -232
  460. package/site/content/docs/reference/client.mdx +0 -469
  461. package/site/content/docs/reference/security.md +0 -74
  462. package/src/cli/ai-setup/detect-ollama.ts +0 -213
  463. package/src/cli/ai-setup/recommend.test.ts +0 -225
  464. package/src/cli/ai-setup/recommend.ts +0 -225
  465. package/src/cli/dev-controls.test.ts +0 -122
  466. package/src/cli/dev-controls.ts +0 -164
  467. package/src/cli/tui/DevLive.tsx +0 -126
  468. package/src/console/ui-next/dist/assets/access-page-De7Lc2JC.js +0 -4
  469. package/src/console/ui-next/dist/assets/agent-disclosure-BP0Y0Sux.js +0 -1
  470. package/src/console/ui-next/dist/assets/cache-glyph-B5X-NM0-.js +0 -1
  471. package/src/console/ui-next/dist/assets/call-pii-button-ChAUiLo9.js +0 -1
  472. package/src/console/ui-next/dist/assets/collapsible-DGnOM2ph.js +0 -1
  473. package/src/console/ui-next/dist/assets/copy-inline-button-DBHhgHKP.js +0 -1
  474. package/src/console/ui-next/dist/assets/dagre.esm-ZwcdTuZZ.js +0 -1
  475. package/src/console/ui-next/dist/assets/detail-header-DhHM1iaZ.js +0 -1
  476. package/src/console/ui-next/dist/assets/dropdown-menu-_NjTEo5_.js +0 -1
  477. package/src/console/ui-next/dist/assets/duration-tone-sC3lGABz.js +0 -9
  478. package/src/console/ui-next/dist/assets/element-icons-BVXtRyd3.js +0 -1
  479. package/src/console/ui-next/dist/assets/explorer-empty-2uIhBu0_.js +0 -1
  480. package/src/console/ui-next/dist/assets/flows-page-RGy7VEA_.js +0 -1
  481. package/src/console/ui-next/dist/assets/highlighted-json-Awq7gYdu.js +0 -154
  482. package/src/console/ui-next/dist/assets/http-method-_UHM2ODJ.js +0 -1
  483. package/src/console/ui-next/dist/assets/index-Ck88Jmv8.css +0 -2
  484. package/src/console/ui-next/dist/assets/index-_rgpdVzo.js +0 -66
  485. package/src/console/ui-next/dist/assets/link-BX6Vqztd.js +0 -1
  486. package/src/console/ui-next/dist/assets/observability-page-Ds6pcnh-.js +0 -4
  487. package/src/console/ui-next/dist/assets/preload-helper-oH4irX4C.js +0 -1
  488. package/src/console/ui-next/dist/assets/react-D8E3mtu1.js +0 -1
  489. package/src/console/ui-next/dist/assets/react-dom-Bph1y7z7.js +0 -9
  490. package/src/console/ui-next/dist/assets/replica-lag-DKRrbvdo.js +0 -18
  491. package/src/console/ui-next/dist/assets/request-meta-DV0ywz7t.js +0 -1
  492. package/src/console/ui-next/dist/assets/shortcut-JQIZlWfm.js +0 -1
  493. package/src/console/ui-next/dist/assets/shortcut-keys-DKxNTe_m.js +0 -1
  494. package/src/console/ui-next/dist/assets/skeleton-D-czQJT6.js +0 -1
  495. package/src/console/ui-next/dist/assets/store-page-02xOiqIK.js +0 -41
  496. package/src/console/ui-next/dist/assets/trace-detail-sheet-B09O8rA6.js +0 -2
  497. package/src/console/ui-next/dist/assets/tree-expand-toggle-BtyhmWb4.js +0 -55
  498. package/src/console/ui-next/dist/assets/units-page-4rHOePuE.js +0 -1
  499. package/src/console/ui-next/dist/assets/useMutation-B8EO02Ej.js +0 -1
  500. package/src/console/ui-next/dist/assets/useRender-BE2A9BWC.js +0 -1
  501. package/src/console/ui-next/dist/assets/vault-page-DISPgxLM.js +0 -2
  502. package/src/console/ui-next/dist/assets/xyflow-D7n4g6go.js +0 -7
  503. package/src/console/ui-next/dist/assets/xyflow-DZ0Ws1xk.css +0 -1
  504. package/src/docker/ollama-pull.ts +0 -232
  505. package/src/docker/recipes/llama-cpp.ts +0 -298
  506. package/src/docker/recipes/ollama.ts +0 -44
  507. package/src/docker/recipes/sglang.ts +0 -55
  508. package/src/docker/recipes/vllm.ts +0 -44
  509. package/src/drivers/ai-ollama-tools.integration.test.ts +0 -109
  510. package/src/drivers/ai-ollama.integration.test.ts +0 -184
  511. package/src/drivers/ai-ollama.ts +0 -389
  512. package/src/drivers/ollama.ts +0 -14
@@ -0,0 +1,232 @@
1
+ ---
2
+ title: "Agents"
3
+ description: "Bounded agents — tools are Flows, maxSteps and budget.maxCostPerRun cap the loop, invoke with fx.run."
4
+ icon: "Bot"
5
+ source: "docs/spec/unified-theory.md"
6
+ ---
7
+
8
+ An agent (`ai.agent`) is a **bounded tool-calling loop**. Tools are your app’s Flows (and
9
+ allowlisted MCP refs) — each step goes through `fx.call`. The loop stops at `maxSteps` or
10
+ `budget.maxCostPerRun`.
11
+
12
+ For developers who need a planner or support assistant without writing a custom tool runtime —
13
+ declare the bag, run with `fx.run`.
14
+
15
+ <Callout title="The one rule">
16
+ Pass Flow names (or handles) in `tools`, set `maxSteps` and `budget.maxCostPerRun`, then
17
+ `fx.run(agent, {message})`. There is no `instructions` / `in` / `out` on `ai.agent` — shape the
18
+ user message yourself.
19
+ </Callout>
20
+
21
+ ## Smallest Example
22
+
23
+ <Steps>
24
+
25
+ <Step>
26
+ ### Declare model + agent
27
+
28
+ ```typescript title="src/core/ai.ts"
29
+ import { ai } from "okengine";
30
+
31
+ export const smart = ai.model("smart", {
32
+ provider: "openrouter",
33
+ model: "openrouter/free",
34
+ apiKey: process.env.OPENROUTER_API_KEY,
35
+ });
36
+
37
+ export const supportAgent = ai.agent("support.assistant", {
38
+ model: "smart",
39
+ tools: ["docs.search", "tickets.create"],
40
+ maxSteps: 5,
41
+ budget: { maxCostPerRun: 0.1 },
42
+ });
43
+ ```
44
+
45
+ </Step>
46
+
47
+ <Step>
48
+ ### Run from a Flow
49
+
50
+ ```typescript title="src/flows/support/assist.ts"
51
+ import { on, flow, http } from "okengine";
52
+ import { z } from "zod";
53
+ import { supportAgent } from "@/core/ai";
54
+ import { member } from "@/core/gate";
55
+
56
+ export const assist = on(
57
+ http.post().gate(member),
58
+ flow({
59
+ in: z.object({ query: z.string().min(1) }),
60
+ do: async ({ query }, fx) => {
61
+ return await fx.run(supportAgent, {
62
+ message: `Help the member: ${query}`,
63
+ });
64
+ },
65
+ }),
66
+ );
67
+ ```
68
+
69
+ Runtime records the agent name under `asks`. Prefer declaring `effects: { asks: ["support.assistant"] }`
70
+ when inference does not see `fx.run`.
71
+
72
+ </Step>
73
+
74
+ <Step>
75
+ ### Bound termination
76
+
77
+ Default `maxSteps` is **6** when omitted. Hitting the step cap ends the loop; exceeding
78
+ `budget.maxCostPerRun` throws `AiBudgetExceededError`:
79
+ `ai: agent "…" exceeded maxCostPerRun N`.
80
+
81
+ </Step>
82
+
83
+ </Steps>
84
+
85
+ ## Progressive Patterns
86
+
87
+ <Tabs items={["Flow tools", "MCP tools", "Ask tools", "Budget"]}>
88
+
89
+ <Tab value="Flow tools">
90
+
91
+ String names or Flow handles — same capability path as `fx.call`:
92
+
93
+ ```typescript
94
+ import { searchDocs } from "@/flows/docs/search";
95
+ import { createTicket } from "@/flows/tickets/create";
96
+
97
+ export const supportAgent = ai.agent("support.assistant", {
98
+ model: smart,
99
+ tools: [searchDocs, createTicket],
100
+ maxSteps: 8,
101
+ });
102
+ ```
103
+
104
+ </Tab>
105
+
106
+ <Tab value="MCP tools">
107
+
108
+ Outbound MCP refs join the same bag (`mcp:<server>/<tool>`):
109
+
110
+ ```typescript
111
+ const github = ai.mcpServer("github", {
112
+ url: "https://mcp.example/github",
113
+ auth: { bearer: vault.secret("GITHUB_MCP_TOKEN") },
114
+ tools: ["create_issue"],
115
+ });
116
+
117
+ export const planner = ai.agent("planner", {
118
+ model: "smart",
119
+ tools: ["tasks.list", github.tool("create_issue")],
120
+ maxSteps: 8,
121
+ budget: { maxCostPerRun: 0.25 },
122
+ });
123
+ ```
124
+
125
+ See [MCP](/docs/elements/ai/mcp).
126
+
127
+ </Tab>
128
+
129
+ <Tab value="Ask tools">
130
+
131
+ One-shot tool loop on `fx.ask` without a named agent:
132
+
133
+ ```typescript
134
+ await fx.ask(triage, input, {
135
+ tools: ["docs.search"],
136
+ maxSteps: 3,
137
+ });
138
+ ```
139
+
140
+ </Tab>
141
+
142
+ <Tab value="Budget">
143
+
144
+ Run cost is on `budget`, not a top-level `maxCostPerRun` field:
145
+
146
+ ```typescript
147
+ ai.agent("planner", {
148
+ tools: ["tasks.list", "tasks.create"],
149
+ budget: { maxCostPerRun: 0.25, maxCostPerCall: 0.05 },
150
+ });
151
+ ```
152
+
153
+ </Tab>
154
+
155
+ </Tabs>
156
+
157
+ ## Options
158
+
159
+ | Option | Type | Default | Meaning |
160
+ | ---------- | ------------------------------------- | ----------- | ---------------------------- |
161
+ | `model` | `AiModelDecl` \| `string` | first model | Logical binding for the loop |
162
+ | `tools` | Flow / MCP refs | `[]` | Callable via `fx.call` |
163
+ | `maxSteps` | `number` | `6` | Hard cap on tool rounds |
164
+ | `budget` | `{ maxCostPerCall?, maxCostPerRun? }` | — | Cost contracts for the run |
165
+
166
+ ## `fx.run` input
167
+
168
+ Pass a string or `{ message: string }` (and any extra fields your tools need in context). The
169
+ agent declaration does **not** take Zod `in` / `out` — validate on the surrounding Flow.
170
+
171
+ ```typescript
172
+ await fx.run(supportAgent, "Summarize open tickets");
173
+ await fx.run(supportAgent, { message: "Summarize open tickets" });
174
+ ```
175
+
176
+ ## Agents vs ask-with-tools
177
+
178
+ | Surface | When |
179
+ | ------------------------------ | -------------------------------------------- |
180
+ | `ai.agent` + `fx.run` | Reusable tool bag, shared step/budget policy |
181
+ | `fx.ask(prompt, …, { tools })` | One prompt, occasional tools |
182
+
183
+ Both default `maxSteps` to `6`. Denied or unknown tools surface as
184
+ `ai: all tool calls denied for prompt "…"` / `ai: model requested unknown tool "…"`.
185
+
186
+ ## Troubleshooting
187
+
188
+ <Accordions>
189
+
190
+ <Accordion title='ai: unknown agent "…"'>
191
+ `fx.run` named an agent that was never declared, or the declaring module was not imported before
192
+ `oke()`.
193
+ </Accordion>
194
+
195
+ <Accordion title='ai: agent "…" exceeded maxCostPerRun'>
196
+ `AiBudgetExceededError` — raise `budget.maxCostPerRun`, lower `maxSteps`, or shrink tools.
197
+ </Accordion>
198
+
199
+ <Accordion title='ai: model requested unknown tool "…"'>
200
+ The model emitted a tool name outside the declared `tools` bag. Align names with Flow / MCP refs,
201
+ or tighten instructions in the user `message`.
202
+ </Accordion>
203
+
204
+ <Accordion title="OKE1005 on agent runs">
205
+ Runtime gates `fx.run` as an ask of the agent name. List `effects: { asks: ["support.assistant"] }`
206
+ when the compiler does not infer `fx.run`.
207
+ </Accordion>
208
+
209
+ </Accordions>
210
+
211
+ ## Learn more
212
+
213
+ - [Prompts](/docs/elements/ai/prompts) — `fx.ask` and ask-time tools
214
+ - [MCP](/docs/elements/ai/mcp) — inbound tools and outbound servers
215
+ - [Flow](/docs/elements/flow) — tools are ordinary Flows
216
+ - [AI](/docs/elements/ai) — guardrails figure and drivers
217
+
218
+ ## Next
219
+
220
+ <Cards>
221
+ <Card
222
+ title="MCP"
223
+ description="Expose and consume Model Context Protocol tools."
224
+ href="/docs/elements/ai/mcp"
225
+ />
226
+ <Card
227
+ title="Prompts"
228
+ description="Versioned fx.ask artifacts."
229
+ href="/docs/elements/ai/prompts"
230
+ />
231
+ <Card title="AI" description="Element overview." href="/docs/elements/ai" />
232
+ </Cards>
@@ -0,0 +1,341 @@
1
+ ---
2
+ title: "Overview"
3
+ description: "Machine intelligence — bind models, ask versioned prompts, run bounded agents, embed into store.index, and connect MCP."
4
+ icon: "Sparkles"
5
+ source: "docs/spec/unified-theory.md"
6
+ ---
7
+
8
+ AI is how your backend **calls a model as a declared effect**. Ticket triage, a weekly
9
+ summary, a planner that tools your own Flows — each ask is a named prompt or agent with
10
+ budgets, not an SDK call buried in `do`.
11
+
12
+ For developers wiring OpenRouter or any OpenAI-compatible `/v1` endpoint — bind a model,
13
+ mint a prompt, ask through `fx`.
14
+
15
+ <Callout title="The one rule">
16
+ Declare `ai.model` → `model.prompt` (or `ai.agent` / `ai.embed`), then call through `fx.ask` /
17
+ `fx.run` / `fx.embed`. There is no top-level `ai.prompt`. Budgets and `maxSteps` are contracts;
18
+ PII to a third-party model needs explicit `allowPii`.
19
+ </Callout>
20
+
21
+ <AiBlocks />
22
+
23
+ ## Smallest Example
24
+
25
+ <Steps>
26
+
27
+ <Step>
28
+ ### Bind a model and mint a prompt
29
+
30
+ ```typescript title="src/core/ai.ts"
31
+ import { ai } from "okengine";
32
+ import { z } from "zod";
33
+
34
+ export const smart = ai.model("smart", {
35
+ provider: "openrouter",
36
+ model: "openrouter/free",
37
+ apiKey: process.env.OPENROUTER_API_KEY,
38
+ });
39
+
40
+ export const triage = smart.prompt("ticket-triage", {
41
+ version: 1,
42
+ budget: { maxCostPerCall: 0.02 },
43
+ out: z.object({
44
+ category: z.enum(["billing", "technical", "other"]),
45
+ urgency: z.enum(["low", "medium", "high"]),
46
+ }),
47
+ });
48
+ ```
49
+
50
+ Import this module before `oke()` so registries adopt the decls.
51
+
52
+ </Step>
53
+
54
+ <Step>
55
+ ### Ask from a Flow
56
+
57
+ ```typescript title="src/flows/support/triage.ts"
58
+ import { on, flow, http } from "okengine";
59
+ import { z } from "zod";
60
+ import { triage } from "@/core/ai";
61
+
62
+ export const classify = on(
63
+ http.post(),
64
+ flow({
65
+ in: z.object({ message: z.string().min(1) }),
66
+ do: async ({ message }, fx) => {
67
+ return await fx.ask(triage, { message });
68
+ },
69
+ }),
70
+ );
71
+ ```
72
+
73
+ The compiler stamps `asks: ["ticket-triage"]` on the Flow’s effects.
74
+
75
+ </Step>
76
+
77
+ <Step>
78
+ ### Call the endpoint
79
+
80
+ ```bash
81
+ curl -X POST http://localhost:6530/support/triage \
82
+ -H "accept: application/json" \
83
+ -H "content-type: application/json" \
84
+ -d '{"message":"Invoice double-charged last week"}'
85
+ ```
86
+
87
+ With `out` set, the model must return JSON matching the schema or the ask throws
88
+ `AiSchemaValidationError`.
89
+
90
+ </Step>
91
+
92
+ </Steps>
93
+
94
+ ## Progressive Patterns
95
+
96
+ From a bare ask to fallback models, tools on ask, and a bounded agent:
97
+
98
+ <Tabs items={["Minimal", "via", "Tools", "Agent"]}>
99
+
100
+ <Tab value="Minimal">
101
+
102
+ Prompt handle + input — model comes from the parent `ai.model`:
103
+
104
+ ```typescript
105
+ const result = await fx.ask(triage, { message: "Cannot reset password" });
106
+ ```
107
+
108
+ </Tab>
109
+
110
+ <Tab value="via">
111
+
112
+ Ordered recovery across logical bindings. Each name opens its **own** client — keys and
113
+ `baseUrl` never mix:
114
+
115
+ ```typescript
116
+ export const triage = smart.prompt("ticket-triage", {
117
+ version: 1,
118
+ via: ["smart", "local"],
119
+ out: z.object({ category: z.string() }),
120
+ });
121
+ ```
122
+
123
+ Override per call with `fx.ask(triage, input, { via: ["local"] })`.
124
+
125
+ </Tab>
126
+
127
+ <Tab value="Tools">
128
+
129
+ Offer Flows as tools on a single ask. Each invocation goes through `fx.call`
130
+ (default `maxSteps: 6`):
131
+
132
+ ```typescript
133
+ await fx.ask(
134
+ triage,
135
+ { message },
136
+ {
137
+ tools: [searchDocs, createTicket],
138
+ maxSteps: 4,
139
+ },
140
+ );
141
+ ```
142
+
143
+ **Consequence:** undeclared tools fail capability checks the same way as `fx.call`.
144
+
145
+ </Tab>
146
+
147
+ <Tab value="Agent">
148
+
149
+ Multi-step loop with a declared tool bag and run budget:
150
+
151
+ ```typescript
152
+ export const supportAgent = ai.agent("support.assistant", {
153
+ model: "smart",
154
+ tools: ["docs.search", "tickets.create"],
155
+ maxSteps: 5,
156
+ budget: { maxCostPerRun: 0.1 },
157
+ });
158
+
159
+ // In a Flow:
160
+ return await fx.run(supportAgent, { message: "Help with billing" });
161
+ ```
162
+
163
+ </Tab>
164
+
165
+ </Tabs>
166
+
167
+ ## Declaration Reference
168
+
169
+ | Declaration | Signature | Purpose |
170
+ | -------------- | ------------------------------ | --------------------------------------------- |
171
+ | `ai.model` | `ai.model(name, options?)` | Logical binding (provider / wire model / key) |
172
+ | `model.prompt` | `model.prompt(name, options?)` | Versioned prompt on that binding |
173
+ | `ai.agent` | `ai.agent(name, options?)` | Bounded tool-calling agent |
174
+ | `ai.embed` | `ai.embed(name, options?)` | Embedding pipeline into `store.index` |
175
+ | `ai.mcpServer` | `ai.mcpServer(name, options)` | Outbound MCP client (allowlisted tools) |
176
+
177
+ There is **no** `ai.prompt(...)` — mint prompts only via `model.prompt`.
178
+
179
+ ## `fx` surface
180
+
181
+ | Method | Capability | Meaning |
182
+ | -------------------------------- | ------------------- | ------------------------------------------------ |
183
+ | `fx.ask(prompt, input?, opts?)` | `asks` | Complete a versioned prompt (optional tool loop) |
184
+ | `fx.run(agent, input?)` | `asks` (agent name) | Run a declared agent |
185
+ | `fx.stream(model, opts?)` | `asks` | Token stream from a model binding |
186
+ | `fx.embed(model, text)` | `embeds` | Return a vector (does not write an index) |
187
+ | `fx.search(embed, query, opts?)` | `reads` | Similarity search over an embed / index |
188
+
189
+ ### `fx.ask` options
190
+
191
+ | Option | Type | Default | Meaning |
192
+ | ---------- | ------------- | ------------------------ | ------------------------------ |
193
+ | `via` | refs | prompt `via` / `[model]` | Recovery chain for this call |
194
+ | `timeout` | `"30s"` \| ms | prompt `timeout` | Per-call deadline |
195
+ | `tools` | Flow refs | — | Offered as tools via `fx.call` |
196
+ | `maxSteps` | `number` | `6` | Cap on tool rounds |
197
+
198
+ Undeclared ask → **OKE1005** `UNDECLARED_ASK`. Undeclared embed → **OKE1009**.
199
+
200
+ ## Guardrails
201
+
202
+ Budgets, version pins, step limits, and PII egress are contracts — not guidelines:
203
+
204
+ <AiGuardrails />
205
+
206
+ ### PII egress
207
+
208
+ Sending a `.pii()` field to a **third-party** provider fails the build unless the Flow
209
+ declares `allowPii: true` (or `pii: "allow"`). `mock`, `local`, and `openai-compatible` are
210
+ not third-party egress.
211
+
212
+ <AiPiiEgress />
213
+
214
+ ```typescript
215
+ flow({
216
+ allowPii: true,
217
+ do: async (input, fx) => fx.ask(triage, { email: input.email }),
218
+ });
219
+ ```
220
+
221
+ ## Per-environment drivers
222
+
223
+ `AiDriverId`: `mock` · `anthropic` · `openai-compatible` · `bedrock` · `vertex`.
224
+
225
+ Boot implements `mock`, `anthropic`, and `openai-compatible`. `bedrock` / `vertex` are
226
+ reserved and throw until implemented. Dev/test fall back to **`mock`** when unset — **prod
227
+ must declare** `drivers.ai`.
228
+
229
+ ```typescript title="oke.config.ts"
230
+ import { defineConfig } from "okengine/config";
231
+
232
+ export default defineConfig({
233
+ drivers: {
234
+ ai: {
235
+ dev: "openai-compatible",
236
+ test: "mock",
237
+ prod: "openai-compatible",
238
+ },
239
+ },
240
+ });
241
+ ```
242
+
243
+ | Driver | Runs as | Best for |
244
+ | ------------------- | ------------------- | ---------------------------------------------- |
245
+ | `mock` | In-process stub | Tests, CI, no network |
246
+ | `openai-compatible` | OpenAI HTTP API | OpenRouter, cloud registries, any `/v1` server |
247
+ | `anthropic` | Native Messages API | Production Claude + reliable tools |
248
+
249
+ Env knobs: `OKE_AI_DRIVER`, `OKE_AI_URL` / `OPENAI_BASE_URL`, provider API keys.
250
+ Compose does not pin inference — BYO URL + keys, or [OpenRouter](/docs/recipes/openrouter).
251
+
252
+ ## The Capabilities of AI
253
+
254
+ <Cards>
255
+ <Card
256
+ title="Models"
257
+ description="Verified providers, limited-compatibility caveats, cloud and BYO bindings."
258
+ href="/docs/elements/ai/models"
259
+ />
260
+ <Card
261
+ title="Prompts"
262
+ description="Versioned artifacts, via chains, budgets, out-schema validation."
263
+ href="/docs/elements/ai/prompts"
264
+ />
265
+ <Card
266
+ title="Agents"
267
+ description="Tool bags are Flows — maxSteps and maxCostPerRun bound the loop."
268
+ href="/docs/elements/ai/agents"
269
+ />
270
+ <Card
271
+ title="Model Context Protocol"
272
+ description="Expose Flows as MCP tools; consume external servers via ai.mcpServer."
273
+ href="/docs/elements/ai/mcp"
274
+ />
275
+ </Cards>
276
+
277
+ ## Troubleshooting
278
+
279
+ <Accordions>
280
+
281
+ <Accordion title='ai: unknown prompt "…"'>
282
+ `fx.ask` named a prompt that was never minted with `model.prompt`, or the declaring module was not
283
+ imported before `oke()`.
284
+ </Accordion>
285
+
286
+ <Accordion title="OKE1005 — UNDECLARED_ASK">
287
+ Cause: `Flow "{flow}" asks "{resource}" without declaring it.` Touch the prompt handle
288
+ inside `do` (inference) or list `effects: { asks: ["ticket-triage"] }`.
289
+ </Accordion>
290
+
291
+ <Accordion title="AiSchemaValidationError / AiSchemaInvalid">
292
+ Cause: `ai: schema validation failed for prompt "…"@N: …` The model reply did not match `out`. Fix
293
+ the schema, the input, or the model — there is no automatic “schema correction” retry.
294
+ </Accordion>
295
+
296
+ <Accordion title="AiBudgetExceededError">
297
+ Cause: `ai: prompt "…" exceeded maxCostPerCall N` or `ai: agent "…" exceeded maxCostPerRun N`.
298
+ Raise the budget or shrink the work.
299
+ </Accordion>
300
+
301
+ <Accordion title="build failed: … without allowPii">
302
+ Cause: `build failed: flow "…" sends pii field(s) […] to a third-party model without allowPii`.
303
+ Set `allowPii: true` on the Flow, or keep the ask on `mock` / `local` / `openai-compatible`.
304
+ </Accordion>
305
+
306
+ <Accordion title="oke boot: unknown AI driver / reserved">
307
+ Prod must pin a real `drivers.ai` id. `bedrock` and `vertex` throw `oke boot: AI driver "…" is
308
+ reserved but not implemented yet`.
309
+ </Accordion>
310
+
311
+ </Accordions>
312
+
313
+ ## Learn more
314
+
315
+ - [Models](/docs/elements/ai/models) — provider registry and `baseUrl` rules
316
+ - [Prompts](/docs/elements/ai/prompts) — `via`, budgets, versions, evals
317
+ - [Agents](/docs/elements/ai/agents) — `fx.run`, tools, `maxSteps`
318
+ - [MCP](/docs/elements/ai/mcp) — inbound `mcp.tool` and outbound `ai.mcpServer`
319
+ - [OpenRouter](/docs/recipes/openrouter) — zero-Docker cloud path
320
+ - [fx](/docs/reference/fx) — `fx.ask` / `fx.run` / `fx.embed`
321
+ - [Errors](/docs/reference/errors) — OKE1005 · OKE1009
322
+
323
+ ## Next
324
+
325
+ <Cards>
326
+ <Card
327
+ title="Models"
328
+ description="Bind providers and wire model ids."
329
+ href="/docs/elements/ai/models"
330
+ />
331
+ <Card
332
+ title="Channel Element"
333
+ description="Reach humans with email, SMS, WhatsApp, and push."
334
+ href="/docs/elements/channel"
335
+ />
336
+ <Card
337
+ title="The Model"
338
+ description="Eight elements overview."
339
+ href="/docs/understand/the-model"
340
+ />
341
+ </Cards>