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
|
@@ -1,385 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
title: "AI"
|
|
3
|
-
description: "Reaching machine intelligence — models, versioned prompts, embeddings, and bounded agents, with cost and PII egress as first-class constraints."
|
|
4
|
-
icon: "Bot"
|
|
5
|
-
source: "docs/spec/unified-theory.md"
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
AI is how your app calls **machine intelligence**: triage a ticket, embed a knowledge base, let an agent resolve a support case. Model calls differ from every other effect — they are nondeterministic, they cost money per call, and your data leaves the building — so prompts are **versioned artifacts**, not strings buried in a handler.
|
|
9
|
-
|
|
10
|
-
<Callout title="The one rule">
|
|
11
|
-
The production model is **declared, never guessed** — there is no prod default. Development uses
|
|
12
|
-
`mock` for determinism, and sending PII to a third-party model fails the **build** unless you
|
|
13
|
-
explicitly acknowledge it.
|
|
14
|
-
</Callout>
|
|
15
|
-
|
|
16
|
-
## Quick start
|
|
17
|
-
|
|
18
|
-
<Steps>
|
|
19
|
-
|
|
20
|
-
<Step>
|
|
21
|
-
### Declare a model and a prompt
|
|
22
|
-
|
|
23
|
-
The model is a logical binding (`smart`, `fast`); the prompt is a versioned artifact with a typed output:
|
|
24
|
-
|
|
25
|
-
```typescript title="src/ai.ts"
|
|
26
|
-
import { ai } from "okengine";
|
|
27
|
-
import { z } from "zod";
|
|
28
|
-
|
|
29
|
-
export const smart = ai.model("smart", { provider: "anthropic", tier: "opus" });
|
|
30
|
-
|
|
31
|
-
export const triage = smart.prompt("ticket-triage", {
|
|
32
|
-
in: z.object({ subject: z.string(), body: z.string() }),
|
|
33
|
-
out: z.object({ urgency: z.enum(["low", "high"]), team: z.string(), summary: z.string() }),
|
|
34
|
-
version: 3,
|
|
35
|
-
budget: { maxCostPerCall: 0.02 },
|
|
36
|
-
});
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
</Step>
|
|
40
|
-
|
|
41
|
-
<Step>
|
|
42
|
-
### Ask it from a Flow
|
|
43
|
-
|
|
44
|
-
`fx.ask` routes the call through the declared model and validates the response against `out`:
|
|
45
|
-
|
|
46
|
-
```typescript title="src/flows/support/triage.ts"
|
|
47
|
-
do: async (input, fx) => {
|
|
48
|
-
const result = await fx.ask(triage, { subject: input.subject, body: input.body });
|
|
49
|
-
// result is typed by the prompt's `out` schema
|
|
50
|
-
};
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
</Step>
|
|
54
|
-
|
|
55
|
-
<Step>
|
|
56
|
-
### Gate regressions in CI
|
|
57
|
-
|
|
58
|
-
Point the prompt at an eval set and it becomes a CI check — a prompt change that degrades answers fails the build like a broken test:
|
|
59
|
-
|
|
60
|
-
```typescript
|
|
61
|
-
export const triage = smart.prompt("ticket-triage", {
|
|
62
|
-
// …
|
|
63
|
-
evals: "./evals/triage.jsonl", // run with `oke eval`
|
|
64
|
-
});
|
|
65
|
-
```
|
|
66
|
-
|
|
67
|
-
</Step>
|
|
68
|
-
|
|
69
|
-
</Steps>
|
|
70
|
-
|
|
71
|
-
## The building blocks
|
|
72
|
-
|
|
73
|
-
| Declaration | Produces |
|
|
74
|
-
| -------------------------- | ------------------------------------------------------------------------------- |
|
|
75
|
-
| `ai.model(name, opts)` | Logical model binding — provider / tier / model id / optional `driverId` |
|
|
76
|
-
| `model.prompt(name, opts)` | Versioned prompt with typed in/out, evals, budget |
|
|
77
|
-
| `ai.embed(name, opts)` | Embedding pipeline into a `store.index` (searched via `fx.search`) |
|
|
78
|
-
| `ai.agent(name, opts)` | Bounded agent whose tools are **your own flows** |
|
|
79
|
-
| `ai.mcpServer(name, opts)` | External MCP server — allowlisted tools join `fx.call` as `mcp:<server>/<tool>` |
|
|
80
|
-
|
|
81
|
-
<AiBlocks />
|
|
82
|
-
|
|
83
|
-
### Prompt options
|
|
84
|
-
|
|
85
|
-
| Option | Type | Meaning |
|
|
86
|
-
| ------------ | --------------------- | -------------------------------------------------------------------------------------- |
|
|
87
|
-
| `in` / `out` | zod / Standard Schema | Input and output contracts — responses validated against `out` |
|
|
88
|
-
| `version` | number | Artifact version — diffs and regressions tracked per version. Pins use `name@version`. |
|
|
89
|
-
| `evals` | string | Path to a `.jsonl` eval set, regression-gated via `oke eval` |
|
|
90
|
-
| `budget` | object | `maxCostPerCall` / `maxCostPerRun` — cost, not time |
|
|
91
|
-
| `via` | `string[]` | Ordered recovery chain of logical model names for this prompt |
|
|
92
|
-
| `timeout` | `string \| number` | Deadline — clock duration (`"30s"`) or milliseconds |
|
|
93
|
-
|
|
94
|
-
## Recovery chain + per-command timeout
|
|
95
|
-
|
|
96
|
-
Fallback is **recovery**, not a fixed cloud→local doctrine. Declare the chain and deadline on the prompt; the call site stays thin:
|
|
97
|
-
|
|
98
|
-
```typescript
|
|
99
|
-
export const summarizeNote = smart.prompt("summarize-note", {
|
|
100
|
-
via: ["smart", "local"],
|
|
101
|
-
timeout: "30s",
|
|
102
|
-
});
|
|
103
|
-
|
|
104
|
-
// in a flow
|
|
105
|
-
const out = await fx.ask(summarizeNote, { title, body });
|
|
106
|
-
// out.via is the logical model that answered
|
|
107
|
-
```
|
|
108
|
-
|
|
109
|
-
Resolution: `fx.ask(…, { via })` overrides `prompt.via`, else the prompt’s bound model. On each model the runtime retries **once** for retryable failures (timeout / 429 / 5xx / network), then advances.
|
|
110
|
-
|
|
111
|
-
Permanent failures (401 / other 4xx / schema invalid / client disconnect / `maxCostPerCall` exceeded) stop the chain. When every eligible attempt fails, `fx.ask` throws — map that to a typed error in the flow (no silent text excerpt).
|
|
112
|
-
|
|
113
|
-
`timeout` uses the same duration vocabulary as Clock (`"30s"`, `"2m"`, or a millisecond number). Ask-time `fx.ask(…, { timeout: "10s" })` overrides the prompt. Omit = no artificial cap. `budget.maxCostPerCall` is enforced at runtime (not just observed). Set `driverId` on a model to open a different protocol than the app default.
|
|
114
|
-
|
|
115
|
-
## Declared guardrails
|
|
116
|
-
|
|
117
|
-
Cost, egress, and model choice are contracts — not runtime hope. Each guardrail is declared up front; violating one fails the build or the run.
|
|
118
|
-
|
|
119
|
-
<AiGuardrails />
|
|
120
|
-
|
|
121
|
-
## Tools are flows (same `fx.call` path)
|
|
122
|
-
|
|
123
|
-
Offer flows as tools on a one-shot ask — each model-initiated call goes through the host flow’s `fx.call`, so capability, Manifest `calls`, and Runs stay honest. No silent extra authority for the model:
|
|
124
|
-
|
|
125
|
-
```typescript
|
|
126
|
-
const result = await fx.ask(triage, input, {
|
|
127
|
-
tools: [getBooking, refundBooking],
|
|
128
|
-
maxSteps: 6,
|
|
129
|
-
});
|
|
130
|
-
```
|
|
131
|
-
|
|
132
|
-
External MCP tools take the same path. In OKE, **MCP is a surface of the model, not the model itself** — `ai.mcpServer` models the client role (consuming external tools), while `mcp.tool()` + Gate models the provider role (exposing your flows to agents). Declare a server with a **required** allowlist, then pass `server.tool("…")` — never whatever `tools/list` happens to expose:
|
|
133
|
-
|
|
134
|
-
```typescript
|
|
135
|
-
export const github = ai.mcpServer("github", {
|
|
136
|
-
url: "https://mcp.example/github",
|
|
137
|
-
auth: { bearer: githubToken },
|
|
138
|
-
tools: ["create_issue"],
|
|
139
|
-
});
|
|
140
|
-
|
|
141
|
-
await fx.ask(triage, input, {
|
|
142
|
-
tools: [github.tool("create_issue")],
|
|
143
|
-
});
|
|
144
|
-
```
|
|
145
|
-
|
|
146
|
-
Capability refs are `mcp:<server>/<tool>`. An undeclared call throws **OKE1007**. See [MCP](/docs/ai/mcp).
|
|
147
|
-
|
|
148
|
-
## Agents with real guardrails
|
|
149
|
-
|
|
150
|
-
An agent's tools are your flows — each carrying its own gates, effects, and typed errors, so the agent can never do anything a flow couldn't:
|
|
151
|
-
|
|
152
|
-
```typescript
|
|
153
|
-
export const support = ai.agent("support", {
|
|
154
|
-
model: smart,
|
|
155
|
-
tools: [getBooking, refundBooking], // flows, with their gates attached
|
|
156
|
-
maxSteps: 6,
|
|
157
|
-
budget: { maxCostPerRun: 0.25 },
|
|
158
|
-
});
|
|
159
|
-
```
|
|
160
|
-
|
|
161
|
-
`maxSteps` bounds the loop; `budget.maxCostPerRun` is enforced after the run. Both are declared, so "the agent ran away" is a violated contract, not a surprise. `fx.run(support, { message })` uses the same tool loop and the same `fx.call` dispatch as `fx.ask(…, { tools })`.
|
|
162
|
-
|
|
163
|
-
## Rate limits via Gate
|
|
164
|
-
|
|
165
|
-
AI calls are expensive — reuse `gate.rate`, don’t invent a parallel budget. Presets: `aiRateGate("ask" | "agent" | "embed")` (defaults 20 / 10 / 60 per minute, `keyBy: "user"`). Attach on the HTTP trigger:
|
|
166
|
-
|
|
167
|
-
```typescript
|
|
168
|
-
on(http.post("/triage").gate(member, aiRateGate("ask")), triageFlow);
|
|
169
|
-
```
|
|
170
|
-
|
|
171
|
-
Use `keyBy: "ip"` on public unauthenticated AI edges. Cost caps stay on prompt/agent `budget` decls.
|
|
172
|
-
|
|
173
|
-
## Secrets stay out of prompts
|
|
174
|
-
|
|
175
|
-
`Redacted` values (e.g. from `fx.vault.get`) stringify to `[redacted]` in provider-facing messages — the same placeholder as logs. Never cleartext to a model.
|
|
176
|
-
|
|
177
|
-
## Streaming
|
|
178
|
-
|
|
179
|
-
`fx.stream(model, { prompt, via? })` yields real provider tokens (Ollama NDJSON, OpenAI-compatible SSE). Cancel by aborting the ambient signal — the same one `fx.all` / `fx.race` already use. Drivers without `stream` fail loud (no stub echo).
|
|
180
|
-
|
|
181
|
-
Return those chunks on HTTP with `fx.json.stream(...)`. The kernel answers `text/event-stream` (`data:` frames, then `data: [DONE]`). JSON flows stay buffered `{ data, error }`.
|
|
182
|
-
|
|
183
|
-
```typescript
|
|
184
|
-
on(
|
|
185
|
-
http.post("/complete").public(),
|
|
186
|
-
flow("chat.complete", {
|
|
187
|
-
do: (input, fx) => fx.json.stream(fx.stream(smart, { prompt: input.prompt })),
|
|
188
|
-
}),
|
|
189
|
-
);
|
|
190
|
-
```
|
|
191
|
-
|
|
192
|
-
Disconnect cancels the provider call automatically (`request.signal` → ambient abort). An `AbortError` from hang-up does not retry or advance `via`. Console Traces stay empty until the stream closes — then the run is one completed row whose duration covers the open stream, not just time-to-first-byte.
|
|
193
|
-
|
|
194
|
-
## PII cannot leak by accident
|
|
195
|
-
|
|
196
|
-
At build time, OKE checks which fields each `fx.ask` sends against your store classifications. If a PII field (`.pii()` in your schema) would reach a third-party model, the build fails:
|
|
197
|
-
|
|
198
|
-
<AiPiiEgress />
|
|
199
|
-
|
|
200
|
-
```text
|
|
201
|
-
build failed: flow "ticket-triage" sends pii field(s) [email] to a third-party model without allowPii
|
|
202
|
-
```
|
|
203
|
-
|
|
204
|
-
The escape hatch is explicit acknowledgment — `allowPii: true` (or `pii: "allow"`) on the flow — so egress is a decision that shows up in code review. The `mock` driver and local models are not third-party; the check targets external providers.
|
|
205
|
-
|
|
206
|
-
## Nondeterminism is priced in
|
|
207
|
-
|
|
208
|
-
Because `fx.ask` is nondeterministic, the runtime adjusts around it: journaling is **forced** on (durable flows can replay), and auto-caching is disabled for the call. In development and tests the `mock` driver makes model calls deterministic — your suite never hits a network, and CI never flakes on a provider.
|
|
209
|
-
|
|
210
|
-
## Per-environment drivers
|
|
211
|
-
|
|
212
|
-
| Driver | What it is |
|
|
213
|
-
| ------------------- | ----------------------------------------------------- |
|
|
214
|
-
| `mock` | Deterministic fake — dev + test default |
|
|
215
|
-
| `anthropic` | Anthropic API |
|
|
216
|
-
| `openai-compatible` | Any OpenAI-compatible endpoint |
|
|
217
|
-
| `bedrock` | AWS Bedrock |
|
|
218
|
-
| `vertex` | Google Vertex AI |
|
|
219
|
-
| `ollama` | Local models — counts as on-premise for the PII check |
|
|
220
|
-
|
|
221
|
-
There is deliberately **no production default**: `prod` must name a driver, which keeps the model choice visible in `oke.config.ts` where review can see it.
|
|
222
|
-
|
|
223
|
-
### Setup wizard
|
|
224
|
-
|
|
225
|
-
```bash title="Terminal"
|
|
226
|
-
oke ai setup
|
|
227
|
-
oke ai setup --provider llama-cpp --yes
|
|
228
|
-
oke ai setup --provider ollama --yes
|
|
229
|
-
```
|
|
230
|
-
|
|
231
|
-
Writes `drivers.ai`, commented AI overrides in `.env.local` (so `oke
|
|
232
|
-
dev --docker` can write the live compose URL), and AI models into
|
|
233
|
-
`src/core.ts`. Uncomment `.env.local` only for a host-managed endpoint.
|
|
234
|
-
|
|
235
|
-
**Recommended** defaults to llama.cpp (lightest local footprint). Customize
|
|
236
|
-
offers llama.cpp · Ollama · vLLM · SGLang · cloud providers.
|
|
237
|
-
|
|
238
|
-
llama.cpp and Ollama: machine banner → model tier / manual (Docker Hub `ai/` vs
|
|
239
|
-
Ollama library). Cloud: API token → model.
|
|
240
|
-
|
|
241
|
-
`create-oke` customize offers **AI setup** (Recommended llama.cpp · Customize ·
|
|
242
|
-
Off) before install; `--ai` forces the full model wizard.
|
|
243
|
-
|
|
244
|
-
### Local inference (decision matrix)
|
|
245
|
-
|
|
246
|
-
| Workload | Image recipe / driver |
|
|
247
|
-
| -------------------------------- | ---------------------------------------------------------- |
|
|
248
|
-
| Single-user / dev (default) | [llama.cpp](/docs/recipes/llama-cpp) + `openai-compatible` |
|
|
249
|
-
| Local library UX | [Ollama](/docs/recipes/ollama) + `ollama` |
|
|
250
|
-
| Multi-user GPU concurrency | [vLLM](/docs/recipes/vllm) + `openai-compatible` |
|
|
251
|
-
| Structured / agent GPU workloads | [SGLang](/docs/recipes/sglang) + `openai-compatible` |
|
|
252
|
-
| Managed cloud | `anthropic` / `openai-compatible` / … (no `images.ai`) |
|
|
253
|
-
|
|
254
|
-
All local recipes **loopback-publish only**, pin explicit tags (never
|
|
255
|
-
`latest`), and require curated model sources — never arbitrary untrusted GGUF
|
|
256
|
-
(2026 GGUF-parser CVEs).
|
|
257
|
-
|
|
258
|
-
### Default local: llama.cpp
|
|
259
|
-
|
|
260
|
-
```typescript title="oke.config.ts"
|
|
261
|
-
import { defineConfig } from "okengine/config";
|
|
262
|
-
|
|
263
|
-
export default defineConfig({
|
|
264
|
-
drivers: {
|
|
265
|
-
ai: { dev: "openai-compatible", test: "mock", prod: "anthropic" },
|
|
266
|
-
},
|
|
267
|
-
images: {
|
|
268
|
-
ai: "ghcr.io/ggml-org/llama.cpp:server-b10450", // ≥ b8146; never :latest
|
|
269
|
-
},
|
|
270
|
-
});
|
|
271
|
-
```
|
|
272
|
-
|
|
273
|
-
```typescript title="src/core.ts"
|
|
274
|
-
export const smart = ai.model("smart", {
|
|
275
|
-
provider: "openai-compatible",
|
|
276
|
-
model: process.env.OKE_AI_MODEL ?? "granite3.3:2b", // Docker Hub ai/ id
|
|
277
|
-
});
|
|
278
|
-
```
|
|
279
|
-
|
|
280
|
-
- **URL:** `http://127.0.0.1:8080/v1` (recipe writes `OKE_AI_URL`).
|
|
281
|
-
- **Model:** curated Docker Hub [`ai/`](https://hub.docker.com/u/ai) id via `OKE_AI_MODEL`.
|
|
282
|
-
- **PII:** local OpenAI-compatible endpoints count as on-premise when they are not third-party cloud.
|
|
283
|
-
|
|
284
|
-
### Ollama (fully supported alternative)
|
|
285
|
-
|
|
286
|
-
Native `ollama` driver — `complete`, `stream`, `embed` without an OpenAI shim.
|
|
287
|
-
Pin `ollama/ollama:0.32.13` or newer (≥ **0.17.1**). See
|
|
288
|
-
[Ollama recipe](/docs/recipes/ollama).
|
|
289
|
-
|
|
290
|
-
### OpenAI-compatible endpoints (one driver)
|
|
291
|
-
|
|
292
|
-
`openai-compatible` is the shared chat/completions client — OpenAI, Groq,
|
|
293
|
-
Together, OpenRouter, llama.cpp, vLLM, SGLang, LM Studio, and Ollama’s `/v1`
|
|
294
|
-
shim. Only `baseUrl`, `apiKey`, `model`, and optional `headers` change.
|
|
295
|
-
|
|
296
|
-
| Target | Typical `baseUrl` | Key |
|
|
297
|
-
| ------------------- | ------------------------------------- | ----------------------------------------------------------- |
|
|
298
|
-
| OpenAI | `https://api.openai.com/v1` (default) | required (`OPENAI_API_KEY`) |
|
|
299
|
-
| llama.cpp (default) | `http://127.0.0.1:8080/v1` | optional |
|
|
300
|
-
| vLLM / SGLang | `http://127.0.0.1:8000/v1` / `:30000` | optional |
|
|
301
|
-
| Groq | `https://api.groq.com/openai/v1` | required |
|
|
302
|
-
| Together | `https://api.together.xyz/v1` | required |
|
|
303
|
-
| OpenRouter | `https://openrouter.ai/api/v1` | required; optional `HTTP-Referer` / `X-Title` via `headers` |
|
|
304
|
-
| LM Studio / local | e.g. `http://127.0.0.1:1234/v1` | optional |
|
|
305
|
-
| Ollama OpenAI shim | `http://127.0.0.1:11434/v1` | optional |
|
|
306
|
-
|
|
307
|
-
Prefer the native `ollama` driver for local Ollama (`/api/chat`).
|
|
308
|
-
|
|
309
|
-
**Consequence:** a missing key against the default OpenAI cloud base fails at open; a custom `baseUrl` may omit the key. HTTP errors always throw — never a silent mock fallback.
|
|
310
|
-
|
|
311
|
-
## Troubleshooting
|
|
312
|
-
|
|
313
|
-
<Accordions>
|
|
314
|
-
<Accordion title="Build fails with AiPiiBuildError">
|
|
315
|
-
|
|
316
|
-
A flow sends a classified PII field to a third-party model. Either stop sending that field (drop it from the `fx.ask` input), or acknowledge the egress with `allowPii: true` on the flow — the error message names the exact fields.
|
|
317
|
-
|
|
318
|
-
</Accordion>
|
|
319
|
-
<Accordion title="Which model will prod actually call?">
|
|
320
|
-
|
|
321
|
-
The one you declared. There is no fallback or guess — if `prod` has no AI driver configured, that's a configuration gap to fix, not a silent default.
|
|
322
|
-
|
|
323
|
-
</Accordion>
|
|
324
|
-
<Accordion title="oke boot: ollama driver needs OKE_AI_URL">
|
|
325
|
-
|
|
326
|
-
Docker mode writes `OKE_AI_URL` into `.env.local` when `images.ai` is pinned. Leave leftover `OKE_AI_*` pins commented if you want `oke dev` to refresh that URL. Locally, the Ollama default is `http://127.0.0.1:11434`. If asks fail with `OllamaUnavailableError`, confirm the server answers at that URL and that the model is listed under `GET /api/tags` (boot pulls via `POST /api/pull` against the container — do not rely on a host `ollama pull`, which may talk to a different install). Prefer `oke ai setup` to wire driver, commented env overrides, and AI models in `src/core.ts` in one pass.
|
|
327
|
-
|
|
328
|
-
</Accordion>
|
|
329
|
-
<Accordion title="A prompt edit made answers worse — how do I catch that pre-merge?">
|
|
330
|
-
|
|
331
|
-
Attach `evals: "./evals/<name>.jsonl"` to the prompt and run `oke eval` in CI. The suite replays the eval cases and fails on regressions, per prompt version.
|
|
332
|
-
|
|
333
|
-
</Accordion>
|
|
334
|
-
<Accordion title="Call API returns Unavailable ai: unknown prompt">
|
|
335
|
-
|
|
336
|
-
Capability pins and Call API pass `name@version`. `fx.ask` resolves the bare
|
|
337
|
-
prompt id. A pin that does not match `prompt.version` throws
|
|
338
|
-
`ai: unknown prompt "name@version"`.
|
|
339
|
-
|
|
340
|
-
</Accordion>
|
|
341
|
-
<Accordion title="OKE1007 when the model calls an MCP tool">
|
|
342
|
-
|
|
343
|
-
Add `mcp:<server>/<tool>` to that flow’s `effects.calls` — the same token as `fx.call`. The allowlist on `ai.mcpServer` is not a capability grant.
|
|
344
|
-
|
|
345
|
-
</Accordion>
|
|
346
|
-
<Accordion title="An agent looped and burned budget">
|
|
347
|
-
|
|
348
|
-
Bound it at declaration: `maxSteps` caps iterations, `budget.maxCostPerRun` caps spend.
|
|
349
|
-
|
|
350
|
-
`fx.ask` stamps `promptVersion` on the run. Cost is recorded only when the
|
|
351
|
-
driver reports `usage.cost` — tokens land on the ask journal either way.
|
|
352
|
-
|
|
353
|
-
</Accordion>
|
|
354
|
-
<Accordion title="The client hung up but the model kept generating">
|
|
355
|
-
|
|
356
|
-
HTTP flows install `request.signal` as the ambient abort. `fx.ask` / `fx.stream` /
|
|
357
|
-
`fx.run` cancel the provider fetch. Return tokens with `fx.json.stream(fx.stream(...))`
|
|
358
|
-
so disconnect is observable.
|
|
359
|
-
|
|
360
|
-
A hang-up is `AbortError` — it does not retry or advance `via`.
|
|
361
|
-
|
|
362
|
-
</Accordion>
|
|
363
|
-
</Accordions>
|
|
364
|
-
|
|
365
|
-
## Learn more
|
|
366
|
-
|
|
367
|
-
- [Project structure](/docs/get-started/project-structure) — agent `tools` are Flow names (`notes.get`), not URLs
|
|
368
|
-
- [Flow](/docs/elements/flow) — `fx.ask` and `fx.search` inside `do`
|
|
369
|
-
- [Store](/docs/elements/store) — `store.index`, the home of embeddings
|
|
370
|
-
- [MCP](/docs/ai/mcp) — serve the app to agents, or consume external servers as tools
|
|
371
|
-
|
|
372
|
-
## Next
|
|
373
|
-
|
|
374
|
-
<Cards>
|
|
375
|
-
<Card
|
|
376
|
-
title="Basic Usage"
|
|
377
|
-
description="Build from the standard starter."
|
|
378
|
-
href="/docs/get-started/basic-usage"
|
|
379
|
-
/>
|
|
380
|
-
<Card
|
|
381
|
-
title="Introduction"
|
|
382
|
-
description="Eight elements overview."
|
|
383
|
-
href="/docs/get-started/introduction"
|
|
384
|
-
/>
|
|
385
|
-
</Cards>
|