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.
- package/AGENTS.md +18 -10
- package/README.md +2 -2
- package/package.json +51 -50
- package/site/content/docs/ai/index.mdx +25 -6
- package/site/content/docs/ai/llms-txt.mdx +1 -1
- package/site/content/docs/ai/meta.json +1 -1
- package/site/content/docs/ai/skills.mdx +4 -1
- package/site/content/docs/ai/try-it.mdx +58 -0
- package/site/content/docs/client/auth.mdx +208 -0
- package/site/content/docs/client/calling.mdx +451 -0
- package/site/content/docs/client/index.mdx +209 -0
- package/site/content/docs/client/live.mdx +234 -0
- package/site/content/docs/client/meta.json +5 -0
- package/site/content/docs/client/react.mdx +249 -0
- package/site/content/docs/elements/ai/agents.mdx +232 -0
- package/site/content/docs/elements/ai/index.mdx +341 -0
- package/site/content/docs/elements/ai/mcp.mdx +275 -0
- package/site/content/docs/elements/ai/meta.json +5 -0
- package/site/content/docs/elements/ai/models.mdx +283 -0
- package/site/content/docs/elements/ai/prompts.mdx +256 -0
- package/site/content/docs/elements/channel/email.mdx +266 -0
- package/site/content/docs/elements/channel/index.mdx +344 -0
- package/site/content/docs/elements/channel/meta.json +5 -0
- package/site/content/docs/elements/channel/push.mdx +218 -0
- package/site/content/docs/elements/channel/receipts.mdx +206 -0
- package/site/content/docs/elements/channel/sms.mdx +264 -0
- package/site/content/docs/elements/channel/whatsapp.mdx +220 -0
- package/site/content/docs/elements/clock/index.mdx +300 -0
- package/site/content/docs/elements/clock/meta.json +5 -0
- package/site/content/docs/elements/clock/schedules.mdx +508 -0
- package/site/content/docs/elements/clock/sleep.mdx +445 -0
- package/site/content/docs/elements/flow/consumers.mdx +707 -0
- package/site/content/docs/elements/flow/http.mdx +1080 -0
- package/site/content/docs/elements/flow/index.mdx +618 -0
- package/site/content/docs/elements/flow/meta.json +5 -0
- package/site/content/docs/elements/flow/routing.mdx +559 -0
- package/site/content/docs/elements/flow/workflows.mdx +640 -0
- package/site/content/docs/elements/gate/auth.mdx +371 -0
- package/site/content/docs/elements/gate/authorization.mdx +298 -0
- package/site/content/docs/elements/gate/index.mdx +418 -0
- package/site/content/docs/elements/gate/meta.json +5 -0
- package/site/content/docs/elements/gate/rate-limits.mdx +365 -0
- package/site/content/docs/elements/gate/rls.mdx +303 -0
- package/site/content/docs/elements/gate/tenancy.mdx +372 -0
- package/site/content/docs/elements/index.mdx +52 -11
- package/site/content/docs/elements/signal/broadcast.mdx +517 -0
- package/site/content/docs/elements/signal/index.mdx +352 -0
- package/site/content/docs/elements/signal/live.mdx +590 -0
- package/site/content/docs/elements/signal/meta.json +5 -0
- package/site/content/docs/elements/signal/once.mdx +596 -0
- package/site/content/docs/elements/store/files.mdx +659 -0
- package/site/content/docs/elements/store/index.mdx +310 -0
- package/site/content/docs/elements/store/kv.mdx +629 -0
- package/site/content/docs/elements/store/meta.json +5 -0
- package/site/content/docs/elements/store/search.mdx +946 -0
- package/site/content/docs/elements/store/sql.mdx +937 -0
- package/site/content/docs/elements/vault/config.mdx +256 -0
- package/site/content/docs/elements/vault/index.mdx +356 -0
- package/site/content/docs/elements/vault/meta.json +5 -0
- package/site/content/docs/elements/vault/rotation.mdx +273 -0
- package/site/content/docs/elements/vault/secrets.mdx +285 -0
- package/site/content/docs/index.mdx +78 -30
- package/site/content/docs/meta.json +11 -8
- package/site/content/docs/plugins/cors.mdx +2 -1
- package/site/content/docs/plugins/csrf.mdx +4 -1
- package/site/content/docs/plugins/headers.mdx +2 -1
- package/site/content/docs/plugins/ip-allowlist.mdx +2 -1
- package/site/content/docs/plugins/magic-link.mdx +6 -0
- package/site/content/docs/plugins/maintenance-mode.mdx +2 -1
- package/site/content/docs/plugins/oauth.mdx +1 -1
- package/site/content/docs/plugins/otp.mdx +12 -1
- package/site/content/docs/plugins/passkey.mdx +39 -15
- package/site/content/docs/plugins/two-factor.mdx +91 -34
- package/site/content/docs/plugins/username.mdx +1 -1
- package/site/content/docs/recipes/caddy.mdx +3 -3
- package/site/content/docs/recipes/index.mdx +18 -28
- package/site/content/docs/recipes/mailpit.mdx +1 -1
- package/site/content/docs/recipes/meilisearch.mdx +3 -3
- package/site/content/docs/recipes/meta.json +1 -4
- package/site/content/docs/recipes/nginx.mdx +2 -2
- package/site/content/docs/recipes/openrouter.mdx +283 -0
- package/site/content/docs/recipes/pgdog.mdx +3 -3
- package/site/content/docs/recipes/postgres.mdx +1 -2
- package/site/content/docs/recipes/rustfs.mdx +2 -2
- package/site/content/docs/recipes/traefik.mdx +3 -3
- package/site/content/docs/reference/cli.mdx +231 -0
- package/site/content/docs/reference/configuration.mdx +30 -10
- package/site/content/docs/reference/environment-variables.mdx +93 -20
- package/site/content/docs/reference/errors.mdx +132 -29
- package/site/content/docs/reference/fx.mdx +137 -73
- package/site/content/docs/reference/index.mdx +13 -21
- package/site/content/docs/reference/meta.json +4 -5
- package/site/content/docs/reference/okid.mdx +42 -17
- package/site/content/docs/reference/plugins.mdx +4 -3
- package/site/content/docs/reference/security.mdx +197 -0
- package/site/content/docs/understand/meta.json +5 -0
- package/site/content/docs/understand/the-anatomy.mdx +132 -0
- package/site/content/docs/understand/the-model.mdx +32 -0
- package/site/content/docs/understand/the-problem.mdx +74 -0
- package/site/content/docs/understand/the-vocabulary.mdx +26 -0
- package/src/auth/api-keys.ts +2 -1
- package/src/auth/bindings.ts +64 -16
- package/src/auth/gate-auth.test.ts +6 -1
- package/src/auth/identity.ts +152 -5
- package/src/auth/index.ts +29 -0
- package/src/auth/invites.ts +2 -1
- package/src/auth/method-context.ts +41 -0
- package/src/auth/oauth-as/crypto.ts +2 -1
- package/src/auth/oauth-as/stores.ts +2 -1
- package/src/auth/operator.ts +2 -1
- package/src/auth/sessions-jwt.test.ts +77 -0
- package/src/auth/sessions.ts +20 -4
- package/src/auth/tenants.ts +3 -2
- package/src/auth/two-factor-challenge.test.ts +61 -0
- package/src/auth/two-factor-challenge.ts +284 -0
- package/src/auth/verification.ts +5 -0
- package/src/bench/REPORT.md +49 -0
- package/src/bench/g03-signal-once.bench.ts +1 -1
- package/src/bench/g10-observability-contention.bench.ts +1 -1
- package/src/bench/g17-hybrid-search.bench.ts +572 -0
- package/src/bench/load-app.ts +2 -10
- package/src/cli/ai-setup/ai-setup.test.ts +331 -42
- package/src/cli/ai-setup/apply.ts +294 -52
- package/src/cli/ai-setup/catalog.ts +238 -1342
- package/src/cli/ai-setup/index.ts +14 -99
- package/src/cli/ai-setup/prompts.ts +60 -443
- package/src/cli/ask-seed.test.ts +96 -0
- package/src/cli/ask-seed.ts +82 -0
- package/src/cli/ask-vault-gaps.test.ts +84 -0
- package/src/cli/ask-vault-gaps.ts +146 -0
- package/src/cli/build.ts +2 -2
- package/src/cli/client-add.test.ts +26 -1
- package/src/cli/client-add.ts +106 -27
- package/src/cli/competitor-mention-removal.test.ts +1 -1
- package/src/cli/db-seed.ts +2 -0
- package/src/cli/db.ts +150 -11
- package/src/cli/dev.ts +119 -211
- package/src/cli/docker-clean.ts +2 -2
- package/src/cli/docker-cli.test.ts +1 -1
- package/src/cli/doctor-diff.ts +4 -2
- package/src/cli/doctor-pii.test.ts +1 -1
- package/src/cli/doctor.ts +14 -1
- package/src/cli/hero-meta.test.ts +4 -2
- package/src/cli/load-config.images.test.ts +8 -10
- package/src/cli/load-config.ts +1 -1
- package/src/cli/registry.ts +22 -10
- package/src/cli/replay.ts +3 -1
- package/src/cli/start.ts +1 -1
- package/src/cli/tui/keys.ts +2 -3
- package/src/client/auth/cookies.ts +74 -0
- package/src/client/auth/create-auth-client.ts +636 -0
- package/src/client/auth/denials.ts +99 -0
- package/src/client/auth/session.ts +283 -0
- package/src/client/auth.test.ts +251 -0
- package/src/client/auth.ts +39 -114
- package/src/client/create-with-session.ts +245 -0
- package/src/client/create.ts +51 -5
- package/src/client/index.ts +11 -1
- package/src/client/live.ts +11 -79
- package/src/client/notes-contract.test.ts +5 -10
- package/src/client/sse.ts +137 -0
- package/src/client/stream.ts +147 -0
- package/src/client/transport.test.ts +32 -0
- package/src/client/transport.ts +123 -26
- package/src/client/types.ts +118 -14
- package/src/client-react/index.ts +185 -24
- package/src/client-react/use-live-query.ts +13 -3
- package/src/compiler/aot.test.ts +7 -4
- package/src/compiler/effects-embed.test.ts +56 -0
- package/src/compiler/effects-fetch.test.ts +43 -0
- package/src/compiler/effects-infer.ts +58 -2
- package/src/compiler/extract.test.ts +258 -44
- package/src/compiler/extract.ts +566 -48
- package/src/compiler/fixtures/skyport/src/flows/bookings/index.ts +7 -4
- package/src/compiler/fixtures/skyport/src/flows/bookings/signals.ts +2 -8
- package/src/compiler/fixtures/skyport.expected.json +4 -4
- package/src/compiler/fixtures/triggers/five-triggers.ts +14 -10
- package/src/compiler/response.ts +2 -2
- package/src/compiler/search-writer-isolation.test.ts +40 -0
- package/src/config/index.ts +11 -0
- package/src/console/server/app.ts +17 -23
- package/src/console/server/bind.ts +4 -0
- package/src/console/server/console.test.ts +2 -2
- package/src/console/server/flows-invoke.test.ts +50 -34
- package/src/console/server/flows.ts +436 -255
- package/src/console/server/runs-ingest.test.ts +6 -3
- package/src/console/server/serve.ts +1 -1
- package/src/console/server/signals.test.ts +1 -5
- package/src/console/server/signals.ts +8 -6
- package/src/console/server/state.ts +6 -1
- package/src/console/server/store.ts +1 -1
- package/src/console/ui-next/dist/assets/FileExportIcon-Ck-5od4R.js +1 -0
- package/src/console/ui-next/dist/assets/MoreHorizontalCircle01Icon-gMNGsE37.js +1 -0
- package/src/console/ui-next/dist/assets/PlusSignIcon-CwG3nxfu.js +1 -0
- package/src/console/ui-next/dist/assets/UnavailableIcon-D9cvHVPr.js +1 -0
- package/src/console/ui-next/dist/assets/UserIcon-DaE2PB5_.js +1 -0
- package/src/console/ui-next/dist/assets/access-page-DFeymU07.js +4 -0
- package/src/console/ui-next/dist/assets/agent-disclosure-U1rdfblp.js +1 -0
- package/src/console/ui-next/dist/assets/cache-glyph-BeFJeqBG.js +1 -0
- package/src/console/ui-next/dist/assets/call-pii-button-CVAONPii.js +1 -0
- package/src/console/ui-next/dist/assets/collapsible-D2A6NJ-3.js +1 -0
- package/src/console/ui-next/dist/assets/copy-inline-button-CAYD18cr.js +1 -0
- package/src/console/ui-next/dist/assets/dagre.esm-B1_XeuLP.js +1 -0
- package/src/console/ui-next/dist/assets/detail-header-DVWNjWjg.js +1 -0
- package/src/console/ui-next/dist/assets/dropdown-menu-4h2LOVXM.js +1 -0
- package/src/console/ui-next/dist/assets/duration-tone-Cgk_h5ja.js +9 -0
- package/src/console/ui-next/dist/assets/element-icons-BI8cJgdh.js +1 -0
- package/src/console/ui-next/dist/assets/explorer-empty-CJs5A-wm.js +1 -0
- package/src/console/ui-next/dist/assets/flows-page-Dss7941e.js +1 -0
- package/src/console/ui-next/dist/assets/highlighted-json-MYZQtRnw.js +154 -0
- package/src/console/ui-next/dist/assets/http-method-Jrh39p7A.js +1 -0
- package/src/console/ui-next/dist/assets/index-D0zS5rKO.css +2 -0
- package/src/console/ui-next/dist/assets/index-DXP2dBIF.js +63 -0
- package/src/console/ui-next/dist/assets/observability-page-HvolXxTI.js +4 -0
- package/src/console/ui-next/dist/assets/react-dom-Ddte4I-Q.js +9 -0
- package/src/console/ui-next/dist/assets/replica-lag-CSh2dzrb.js +18 -0
- package/src/console/ui-next/dist/assets/request-meta-BatF8KrK.js +1 -0
- package/src/console/ui-next/dist/assets/shortcut-keys-3ILd8oGn.js +1 -0
- package/src/console/ui-next/dist/assets/{sql-BskegiFM.js → sql-BsFa4tDR.js} +1 -1
- package/src/console/ui-next/dist/assets/store-page-eiKiHnNe.js +41 -0
- package/src/console/ui-next/dist/assets/trace-detail-sheet-CZkMeKS-.js +2 -0
- package/src/console/ui-next/dist/assets/tree-expand-toggle-CW8y5A2h.js +55 -0
- package/src/console/ui-next/dist/assets/units-page-B_RWJrEO.js +1 -0
- package/src/console/ui-next/dist/assets/{use-vault-list-uk4WVboC.js → use-vault-list-CT4-gajj.js} +1 -1
- package/src/console/ui-next/dist/assets/vault-page-CWrg-A68.js +2 -0
- package/src/console/ui-next/dist/assets/xyflow-CSyC6ryz.css +1 -0
- package/src/console/ui-next/dist/assets/xyflow-yApv7D4e.js +7 -0
- package/src/console/ui-next/dist/index.html +6 -13
- package/src/console/ui-next/seed-invoke-host.ts +21 -18
- package/src/console/ui-next/src/client.ts +7 -2
- package/src/console/ui-next/src/features/flows/graph/element-map.ts +2 -0
- package/src/console/ui-next/src/features/flows/traces/effect-kind.ts +12 -2
- package/src/console/ui-next/src/features/flows/traces/effect-summary.ts +4 -0
- package/src/console/ui-next/src/features/flows/traces/trace-detail-sheet.tsx +8 -0
- package/src/console/ui-next/src/features/flows/traces/waterfall-bars.ts +4 -0
- package/src/console/ui-next/src/features/flows/traces/waterfall-tooltip.ts +9 -3
- package/src/console/ui-next/src/features/store/detail/reveal-cell.tsx +7 -11
- package/src/console/ui-next/src/features/store/detail/store-row-detail-sheet.tsx +2 -2
- package/src/console/ui-next/src/features/store/lib/fields-from-table.ts +2 -0
- package/src/console/ui-next/src/features/store/lib/grid-model.test.ts +25 -1
- package/src/console/ui-next/src/features/store/lib/grid-model.ts +36 -1
- package/src/console/ui-next/src/features/store/query/query-results.tsx +3 -3
- package/src/console/ui-next/src/features/units/detail/effects-summary.tsx +2 -0
- package/src/console/ui-next/src/features/units/lib/call-read-safe.ts +3 -1
- package/src/console/ui-next/src/features/units/lib/fields-from-schema.ts +6 -0
- package/src/docker/ai-model-status.test.ts +1 -12
- package/src/docker/ai-model-status.ts +10 -38
- package/src/docker/compose-up.test.ts +100 -0
- package/src/docker/compose-up.ts +292 -0
- package/src/docker/compose.ts +4 -14
- package/src/docker/derive.ts +9 -34
- package/src/docker/docker.test.ts +16 -261
- package/src/docker/images-config.test.ts +13 -25
- package/src/docker/index.ts +1 -24
- package/src/docker/recipes/index.ts +0 -23
- package/src/docker/recipes/pgdog.ts +6 -4
- package/src/docker/stack-id.test.ts +2 -2
- package/src/docker/stack-id.ts +0 -1
- package/src/docker/types.ts +2 -2
- package/src/drivers/ai-anthropic.ts +10 -0
- package/src/drivers/ai-openai-compatible.ts +34 -7
- package/src/drivers/ai-providers.test.ts +0 -107
- package/src/drivers/ai-stream.test.ts +0 -34
- package/src/drivers/ai-types.ts +17 -8
- package/src/drivers/channel-fcm.ts +6 -1
- package/src/drivers/channel-msegat.ts +6 -1
- package/src/drivers/channel-resend.ts +5 -1
- package/src/drivers/channel-smtp.ts +5 -1
- package/src/drivers/channel-sndr.ts +10 -1
- package/src/drivers/channel-taqnyat-mail.ts +5 -1
- package/src/drivers/channel-taqnyat-whatsapp.ts +6 -1
- package/src/drivers/channel-taqnyat.ts +6 -1
- package/src/drivers/channel-types.ts +10 -0
- package/src/drivers/channel-unifonic.ts +6 -1
- package/src/drivers/channel-wa-cloud.ts +6 -1
- package/src/drivers/channel-webpush.ts +6 -1
- package/src/drivers/external.ts +33 -0
- package/src/drivers/index.ts +0 -10
- package/src/drivers/meilisearch.ts +6 -0
- package/src/drivers/oauth-types.ts +4 -0
- package/src/drivers/postgres.test.ts +74 -3
- package/src/drivers/postgres.ts +175 -6
- package/src/drivers/signal-types.ts +5 -5
- package/src/drivers/types.ts +7 -0
- package/src/drivers/vault-types.ts +5 -0
- package/src/elements/ai/declare.ts +17 -4
- package/src/elements/ai/eval.ts +1 -1
- package/src/elements/ai/mcp-http.ts +1 -1
- package/src/elements/ai/pii.ts +1 -1
- package/src/elements/ai/providers.test.ts +289 -0
- package/src/elements/ai/providers.ts +169 -0
- package/src/elements/ai/runtime.ts +68 -5
- package/src/elements/ai/schema.ts +2 -2
- package/src/elements/ai.test.ts +7 -7
- package/src/elements/ai.ts +17 -1
- package/src/elements/channel/runtime.ts +105 -12
- package/src/elements/clock/cron-fields.test.ts +144 -0
- package/src/elements/clock/cron-fields.ts +185 -0
- package/src/elements/clock/declare.ts +247 -3
- package/src/elements/clock.ts +21 -1
- package/src/elements/index.ts +15 -0
- package/src/elements/signal/chaos-child.ts +1 -2
- package/src/elements/signal/declare.ts +65 -37
- package/src/elements/signal/delivery-modes.test.ts +11 -31
- package/src/elements/signal/dry-run-replay.test.ts +1 -7
- package/src/elements/signal/dry-run-write-isolation.test.ts +1 -7
- package/src/elements/signal/key-ordering.test.ts +6 -26
- package/src/elements/signal/lease-reclaim.test.ts +2 -6
- package/src/elements/signal/optional-emit.test.ts +6 -9
- package/src/elements/signal/order-lifecycle.test.ts +4 -17
- package/src/elements/signal/orphan-messages.test.ts +4 -15
- package/src/elements/signal/reconcile.test.ts +2 -2
- package/src/elements/signal/runtime.ts +1 -1
- package/src/elements/signal/schema-emit.test.ts +4 -8
- package/src/elements/signal.test.ts +24 -49
- package/src/elements/signal.ts +9 -2
- package/src/elements/store/domain-ddl.test.ts +1 -1
- package/src/elements/store/live-http.test.ts +9 -4
- package/src/elements/store/prepare-row.test.ts +123 -0
- package/src/elements/store/resource.ts +43 -12
- package/src/elements/store/schema-decl.ts +117 -0
- package/src/elements/store/search-backfill.ts +205 -0
- package/src/elements/store/search-bind.ts +66 -0
- package/src/elements/store/search-bm25.ts +78 -0
- package/src/elements/store/search-ddl.ts +156 -0
- package/src/elements/store/search-embed-flow.ts +141 -0
- package/src/elements/store/search-errors.ts +34 -0
- package/src/elements/store/search-fusion.ts +112 -0
- package/src/elements/store/search-lsh.ts +179 -0
- package/src/elements/store/search-runtime.ts +300 -0
- package/src/elements/store/search.test.ts +144 -0
- package/src/elements/store/sql-session.test.ts +1 -0
- package/src/elements/store/sql-session.ts +83 -3
- package/src/elements/store/table.ts +23 -2
- package/src/elements/store/upsert-app.test.ts +1 -3
- package/src/elements/store.ts +50 -0
- package/src/full.ts +4 -2
- package/src/http.ts +4 -1
- package/src/i18n/catalogs/ar.ts +14 -6
- package/src/i18n/catalogs/en.ts +14 -6
- package/src/index.ts +6 -1
- package/src/kernel/adopt-barrel-fresh.test.ts +7 -7
- package/src/kernel/adopt-routes.ts +9 -1
- package/src/kernel/app-auth.ts +5 -0
- package/src/kernel/app.ts +102 -9
- package/src/kernel/auto-cache.test.ts +6 -12
- package/src/kernel/auto-registry.test.ts +3 -3
- package/src/kernel/boot-bind/ai.test.ts +22 -19
- package/src/kernel/boot-bind/ai.ts +5 -43
- package/src/kernel/boot-bind/clock.ts +23 -5
- package/src/kernel/boot-bind/honor-config.test.ts +4 -4
- package/src/kernel/boot.test.ts +11 -6
- package/src/kernel/boot.ts +66 -16
- package/src/kernel/boundary-contract.ts +93 -0
- package/src/kernel/budget.test.ts +1 -1
- package/src/kernel/call.ts +89 -0
- package/src/kernel/capability.ts +6 -0
- package/src/kernel/client-descriptor.ts +123 -0
- package/src/kernel/clock-timezone.test.ts +80 -0
- package/src/kernel/correlation.test.ts +1 -1
- package/src/kernel/dry-run.ts +11 -8
- package/src/kernel/effects-stamping.test.ts +42 -9
- package/src/kernel/effects.test.ts +4 -2
- package/src/kernel/effects.ts +51 -9
- package/src/kernel/errors-channel.ts +17 -0
- package/src/kernel/errors-live-resume.ts +3 -2
- package/src/kernel/errors-tenant.ts +7 -4
- package/src/kernel/errors.registry-helpers.ts +96 -0
- package/src/kernel/errors.registry.test.ts +139 -25
- package/src/kernel/errors.ts +102 -23
- package/src/kernel/external-effects.test.ts +196 -0
- package/src/kernel/flow.test.ts +13 -4
- package/src/kernel/flow.ts +69 -71
- package/src/kernel/fx-ask-telemetry.test.ts +2 -2
- package/src/kernel/fx-dead-letters.test.ts +3 -3
- package/src/kernel/fx-fetch.ts +55 -0
- package/src/kernel/fx-live-stream.ts +2 -2
- package/src/kernel/fx-live.test.ts +8 -8
- package/src/kernel/fx.test.ts +17 -11
- package/src/kernel/fx.ts +180 -57
- package/src/kernel/horizontal-child.ts +1 -1
- package/src/kernel/http-query.test.ts +3 -6
- package/src/kernel/index.ts +13 -3
- package/src/kernel/instance-id.ts +1 -1
- package/src/kernel/instances.test.ts +40 -0
- package/src/kernel/instances.ts +47 -9
- package/src/kernel/live-http.test.ts +6 -7
- package/src/kernel/live-http.ts +6 -2
- package/src/kernel/live-resume.test.ts +1 -1
- package/src/kernel/mcp-tool.test.ts +3 -3
- package/src/kernel/on.ts +98 -4
- package/src/kernel/pipeline.test.ts +12 -15
- package/src/kernel/plugin-elements.test.ts +1 -1
- package/src/kernel/stamp-http.test.ts +3 -3
- package/src/kernel/triggers.ts +210 -95
- package/src/kernel-entry.ts +0 -1
- package/src/manifest/diff.ts +11 -1
- package/src/manifest/fixtures/skyport.excerpt.json +1 -1
- package/src/manifest/types.ts +46 -2
- package/src/mcp/docs-index.ts +3 -3
- package/src/mcp/docs-mcp.test.ts +2 -2
- package/src/mcp/docs-tools.ts +1 -1
- package/src/okid.test.ts +56 -0
- package/src/okid.ts +55 -11
- package/src/plugins/anonymous.ts +8 -4
- package/src/plugins/auth/shared.ts +27 -3
- package/src/plugins/auth-delivery.mailpit.integration.test.ts +1 -1
- package/src/plugins/auth-methods.security.test.ts +561 -23
- package/src/plugins/config-source.ts +1 -1
- package/src/plugins/csrf.test.ts +65 -0
- package/src/plugins/index.ts +2 -0
- package/src/plugins/magic-link.ts +36 -16
- package/src/plugins/oauth/shared.ts +3 -1
- package/src/plugins/oauth.ts +22 -14
- package/src/plugins/otp.ts +37 -21
- package/src/plugins/passkey-webauthn.ts +9 -6
- package/src/plugins/passkey.ts +98 -26
- package/src/plugins/pre-account-hijack.test.ts +223 -0
- package/src/plugins/two-factor.ts +466 -37
- package/src/plugins/username.ts +19 -7
- package/src/release/build-lib.ts +1 -0
- package/src/release/limits.ts +2 -2
- package/src/release/measure.ts +1 -1
- package/src/runs/collect.test.ts +0 -2
- package/src/runtime/json-code-block.test.ts +250 -20
- package/src/runtime/json-code-block.ts +1261 -41
- package/src/term.test.ts +1 -1
- package/src/test/create-test-app.test.ts +12 -12
- package/src/test/live-signals.test.ts +6 -6
- package/src/test/provisions.integration.test.ts +10 -14
- package/src/test/reset-element-registries.ts +1 -1
- package/src/test/tenant-isolation.test.ts +12 -6
- package/site/content/docs/deployment/docker-swarm.mdx +0 -164
- package/site/content/docs/deployment/docker.mdx +0 -227
- package/site/content/docs/deployment/index.mdx +0 -83
- package/site/content/docs/deployment/kubernetes.mdx +0 -176
- package/site/content/docs/deployment/meta.json +0 -5
- package/site/content/docs/deployment/reverse-proxy.mdx +0 -234
- package/site/content/docs/elements/ai.mdx +0 -385
- package/site/content/docs/elements/channel.mdx +0 -346
- package/site/content/docs/elements/clock.mdx +0 -244
- package/site/content/docs/elements/flow.mdx +0 -420
- package/site/content/docs/elements/gate.mdx +0 -436
- package/site/content/docs/elements/signal.mdx +0 -380
- package/site/content/docs/elements/store.mdx +0 -1099
- package/site/content/docs/elements/vault.mdx +0 -405
- package/site/content/docs/get-started/basic-usage.mdx +0 -173
- package/site/content/docs/get-started/index.mdx +0 -43
- package/site/content/docs/get-started/installation.mdx +0 -220
- package/site/content/docs/get-started/introduction.mdx +0 -132
- package/site/content/docs/get-started/meta.json +0 -13
- package/site/content/docs/get-started/project-structure.mdx +0 -925
- package/site/content/docs/get-started/testing.mdx +0 -328
- package/site/content/docs/get-started/why.mdx +0 -162
- package/site/content/docs/recipes/llama-cpp.mdx +0 -151
- package/site/content/docs/recipes/ollama.mdx +0 -142
- package/site/content/docs/recipes/sglang.mdx +0 -105
- package/site/content/docs/recipes/vllm.mdx +0 -106
- package/site/content/docs/reference/cli.md +0 -232
- package/site/content/docs/reference/client.mdx +0 -469
- package/site/content/docs/reference/security.md +0 -74
- package/src/cli/ai-setup/detect-ollama.ts +0 -213
- package/src/cli/ai-setup/recommend.test.ts +0 -225
- package/src/cli/ai-setup/recommend.ts +0 -225
- package/src/cli/dev-controls.test.ts +0 -122
- package/src/cli/dev-controls.ts +0 -164
- package/src/cli/tui/DevLive.tsx +0 -126
- package/src/console/ui-next/dist/assets/access-page-De7Lc2JC.js +0 -4
- package/src/console/ui-next/dist/assets/agent-disclosure-BP0Y0Sux.js +0 -1
- package/src/console/ui-next/dist/assets/cache-glyph-B5X-NM0-.js +0 -1
- package/src/console/ui-next/dist/assets/call-pii-button-ChAUiLo9.js +0 -1
- package/src/console/ui-next/dist/assets/collapsible-DGnOM2ph.js +0 -1
- package/src/console/ui-next/dist/assets/copy-inline-button-DBHhgHKP.js +0 -1
- package/src/console/ui-next/dist/assets/dagre.esm-ZwcdTuZZ.js +0 -1
- package/src/console/ui-next/dist/assets/detail-header-DhHM1iaZ.js +0 -1
- package/src/console/ui-next/dist/assets/dropdown-menu-_NjTEo5_.js +0 -1
- package/src/console/ui-next/dist/assets/duration-tone-sC3lGABz.js +0 -9
- package/src/console/ui-next/dist/assets/element-icons-BVXtRyd3.js +0 -1
- package/src/console/ui-next/dist/assets/explorer-empty-2uIhBu0_.js +0 -1
- package/src/console/ui-next/dist/assets/flows-page-RGy7VEA_.js +0 -1
- package/src/console/ui-next/dist/assets/highlighted-json-Awq7gYdu.js +0 -154
- package/src/console/ui-next/dist/assets/http-method-_UHM2ODJ.js +0 -1
- package/src/console/ui-next/dist/assets/index-Ck88Jmv8.css +0 -2
- package/src/console/ui-next/dist/assets/index-_rgpdVzo.js +0 -66
- package/src/console/ui-next/dist/assets/link-BX6Vqztd.js +0 -1
- package/src/console/ui-next/dist/assets/observability-page-Ds6pcnh-.js +0 -4
- package/src/console/ui-next/dist/assets/preload-helper-oH4irX4C.js +0 -1
- package/src/console/ui-next/dist/assets/react-D8E3mtu1.js +0 -1
- package/src/console/ui-next/dist/assets/react-dom-Bph1y7z7.js +0 -9
- package/src/console/ui-next/dist/assets/replica-lag-DKRrbvdo.js +0 -18
- package/src/console/ui-next/dist/assets/request-meta-DV0ywz7t.js +0 -1
- package/src/console/ui-next/dist/assets/shortcut-JQIZlWfm.js +0 -1
- package/src/console/ui-next/dist/assets/shortcut-keys-DKxNTe_m.js +0 -1
- package/src/console/ui-next/dist/assets/skeleton-D-czQJT6.js +0 -1
- package/src/console/ui-next/dist/assets/store-page-02xOiqIK.js +0 -41
- package/src/console/ui-next/dist/assets/trace-detail-sheet-B09O8rA6.js +0 -2
- package/src/console/ui-next/dist/assets/tree-expand-toggle-BtyhmWb4.js +0 -55
- package/src/console/ui-next/dist/assets/units-page-4rHOePuE.js +0 -1
- package/src/console/ui-next/dist/assets/useMutation-B8EO02Ej.js +0 -1
- package/src/console/ui-next/dist/assets/useRender-BE2A9BWC.js +0 -1
- package/src/console/ui-next/dist/assets/vault-page-DISPgxLM.js +0 -2
- package/src/console/ui-next/dist/assets/xyflow-D7n4g6go.js +0 -7
- package/src/console/ui-next/dist/assets/xyflow-DZ0Ws1xk.css +0 -1
- package/src/docker/ollama-pull.ts +0 -232
- package/src/docker/recipes/llama-cpp.ts +0 -298
- package/src/docker/recipes/ollama.ts +0 -44
- package/src/docker/recipes/sglang.ts +0 -55
- package/src/docker/recipes/vllm.ts +0 -44
- package/src/drivers/ai-ollama-tools.integration.test.ts +0 -109
- package/src/drivers/ai-ollama.integration.test.ts +0 -184
- package/src/drivers/ai-ollama.ts +0 -389
- 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>
|