okengine 0.18.5 → 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/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 +20 -10
- 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 +63 -36
- package/site/content/docs/meta.json +8 -7
- 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/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 +257 -43
- 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 -144
- 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 -114
- 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-3-EFj-2G.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-cVFnA4HH.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-CMIgUbD0.js +0 -66
- package/src/console/ui-next/dist/assets/index-Ck88Jmv8.css +0 -2
- package/src/console/ui-next/dist/assets/link-BX6Vqztd.js +0 -1
- package/src/console/ui-next/dist/assets/observability-page-CQ3p34ip.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-l8FeKfnP.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-CL-d_mLE.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,9 +1,24 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Postgres placeholder conversion.
|
|
2
|
+
* Postgres placeholder conversion + shared pool lifecycle.
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
import { describe, expect, test } from "bun:test";
|
|
6
|
-
import {
|
|
5
|
+
import { afterEach, describe, expect, test } from "bun:test";
|
|
6
|
+
import {
|
|
7
|
+
closeSharedPostgresClients,
|
|
8
|
+
connectPostgres,
|
|
9
|
+
isPostgresConnectionNoise,
|
|
10
|
+
isSharedPostgresPaused,
|
|
11
|
+
pauseSharedPostgresClients,
|
|
12
|
+
resumeSharedPostgresClients,
|
|
13
|
+
SharedPostgresPausedError,
|
|
14
|
+
sharedPostgresClient,
|
|
15
|
+
toPostgresParams,
|
|
16
|
+
} from "./postgres.ts";
|
|
17
|
+
|
|
18
|
+
afterEach(async () => {
|
|
19
|
+
resumeSharedPostgresClients();
|
|
20
|
+
await closeSharedPostgresClients();
|
|
21
|
+
});
|
|
7
22
|
|
|
8
23
|
describe("toPostgresParams", () => {
|
|
9
24
|
test("rewrites ? only when values are bound", () => {
|
|
@@ -21,3 +36,59 @@ describe("toPostgresParams", () => {
|
|
|
21
36
|
expect(toPostgresParams(sql, [])).toBe(sql);
|
|
22
37
|
});
|
|
23
38
|
});
|
|
39
|
+
|
|
40
|
+
describe("closeSharedPostgresClients", () => {
|
|
41
|
+
test("drops cached pools so the next checkout is a new client", async () => {
|
|
42
|
+
const url = "postgres://127.0.0.1:9/oke-close-shared-test";
|
|
43
|
+
const first = sharedPostgresClient(url);
|
|
44
|
+
expect(sharedPostgresClient(url)).toBe(first);
|
|
45
|
+
await closeSharedPostgresClients();
|
|
46
|
+
const second = sharedPostgresClient(url);
|
|
47
|
+
expect(second).not.toBe(first);
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
test("holder close is a no-op so seed stop cannot leave a dead cached pool", async () => {
|
|
51
|
+
const url = "postgres://127.0.0.1:9/oke-holder-close-shared-test";
|
|
52
|
+
const first = sharedPostgresClient(url);
|
|
53
|
+
await first.close?.({ timeout: 1 });
|
|
54
|
+
// Same live pool — journal/instances close during in-process seed must not
|
|
55
|
+
// tear Bun.SQL while the map still hands out this client.
|
|
56
|
+
expect(sharedPostgresClient(url)).toBe(first);
|
|
57
|
+
await expect(first.close?.({ timeout: 1 })).resolves.toBeUndefined();
|
|
58
|
+
});
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
describe("pauseSharedPostgresClients", () => {
|
|
62
|
+
test("blocks new pools and fails soft on existing wrappers", async () => {
|
|
63
|
+
const url = "postgres://127.0.0.1:9/oke-pause-shared-test";
|
|
64
|
+
const sql = await connectPostgres({ url });
|
|
65
|
+
const held = sharedPostgresClient(url);
|
|
66
|
+
await pauseSharedPostgresClients();
|
|
67
|
+
expect(isSharedPostgresPaused()).toBe(true);
|
|
68
|
+
expect(() => sharedPostgresClient(url)).toThrow(SharedPostgresPausedError);
|
|
69
|
+
await expect(sql.query("SELECT 1")).rejects.toBeInstanceOf(SharedPostgresPausedError);
|
|
70
|
+
// Fleet wrappers (journal / clock / instances) call .unsafe on the held client.
|
|
71
|
+
expect(() => held.unsafe("SELECT 1")).toThrow(SharedPostgresPausedError);
|
|
72
|
+
resumeSharedPostgresClients();
|
|
73
|
+
expect(isSharedPostgresPaused()).toBe(false);
|
|
74
|
+
const next = sharedPostgresClient(url);
|
|
75
|
+
expect(next).toBeDefined();
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
test("isPostgresConnectionNoise matches Bun close / refuse codes", () => {
|
|
79
|
+
expect(
|
|
80
|
+
isPostgresConnectionNoise({
|
|
81
|
+
code: "ERR_POSTGRES_CONNECTION_CLOSED",
|
|
82
|
+
message: "Connection closed",
|
|
83
|
+
}),
|
|
84
|
+
).toBe(true);
|
|
85
|
+
expect(
|
|
86
|
+
isPostgresConnectionNoise({
|
|
87
|
+
code: "ERR_POSTGRES_CONNECTION_REFUSED",
|
|
88
|
+
message: "Failed to connect",
|
|
89
|
+
}),
|
|
90
|
+
).toBe(true);
|
|
91
|
+
expect(isPostgresConnectionNoise(new SharedPostgresPausedError())).toBe(true);
|
|
92
|
+
expect(isPostgresConnectionNoise(new Error("relation missing"))).toBe(false);
|
|
93
|
+
});
|
|
94
|
+
});
|
package/src/drivers/postgres.ts
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
import type { SqlConnectOptions, SqlConnection, SqlDriver, SqlRole, SqlRow } from "./types.ts";
|
|
8
|
+
import { hostFromUrl } from "./external.ts";
|
|
8
9
|
|
|
9
10
|
/** Bun.SQL client checked out via {@link PostgresClientLike.reserve}. */
|
|
10
11
|
export interface PostgresReservedClient extends PostgresClientLike {
|
|
@@ -36,7 +37,35 @@ export interface PostgresClientLike {
|
|
|
36
37
|
/** Cap shared Bun.SQL pools so one process cannot outrun PgDog (default 10). */
|
|
37
38
|
export const POSTGRES_POOL_MAX = 8;
|
|
38
39
|
|
|
39
|
-
|
|
40
|
+
/** One shared pool entry — raw Bun.SQL plus a pause-aware facade. */
|
|
41
|
+
type SharedPostgresEntry = {
|
|
42
|
+
readonly raw: PostgresClientLike;
|
|
43
|
+
readonly guarded: PostgresClientLike;
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
const sharedClients = new Map<string, SharedPostgresEntry>();
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* When true, shared pools stay closed and every query fails fast — no Bun.SQL
|
|
50
|
+
* reconnect into a torn-down Postgres (see {@link pauseSharedPostgresClients}).
|
|
51
|
+
*/
|
|
52
|
+
let sharedPostgresPaused = false;
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Thrown when Console / host code touches SQL after `oke dev` paused Postgres
|
|
56
|
+
* for compose stop. Fail soft — never open a new TCP connection.
|
|
57
|
+
*/
|
|
58
|
+
export class SharedPostgresPausedError extends Error {
|
|
59
|
+
readonly code = "ERR_OKE_POSTGRES_PAUSED";
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* @param message - Operator-facing reason
|
|
63
|
+
*/
|
|
64
|
+
constructor(message = "shared Postgres pools are paused (compose stopped)") {
|
|
65
|
+
super(message);
|
|
66
|
+
this.name = "SharedPostgresPausedError";
|
|
67
|
+
}
|
|
68
|
+
}
|
|
40
69
|
|
|
41
70
|
/**
|
|
42
71
|
* Resolve the Postgres URL (injected, `DATABASE_URL`, then localhost).
|
|
@@ -47,18 +76,145 @@ export function resolvePostgresUrl(url?: string): string {
|
|
|
47
76
|
return url ?? process.env.DATABASE_URL ?? "postgres://localhost:5432/oke";
|
|
48
77
|
}
|
|
49
78
|
|
|
79
|
+
/**
|
|
80
|
+
* True while {@link pauseSharedPostgresClients} has not been resumed.
|
|
81
|
+
*/
|
|
82
|
+
export function isSharedPostgresPaused(): boolean {
|
|
83
|
+
return sharedPostgresPaused;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Bun / driver connection failures that flood the TTY when Postgres dies
|
|
88
|
+
* under an open pool (compose stop).
|
|
89
|
+
*
|
|
90
|
+
* @param reason - Rejection reason
|
|
91
|
+
*/
|
|
92
|
+
export function isPostgresConnectionNoise(reason: unknown): boolean {
|
|
93
|
+
if (reason instanceof SharedPostgresPausedError) return true;
|
|
94
|
+
if (!reason || typeof reason !== "object") return false;
|
|
95
|
+
const code = (reason as { code?: unknown }).code;
|
|
96
|
+
if (typeof code === "string") {
|
|
97
|
+
if (
|
|
98
|
+
code === "ERR_POSTGRES_CONNECTION_CLOSED" ||
|
|
99
|
+
code === "ERR_POSTGRES_CONNECTION_REFUSED" ||
|
|
100
|
+
code === "ERR_POSTGRES_CONNECTION_TIMEOUT" ||
|
|
101
|
+
code === "ERR_OKE_POSTGRES_PAUSED"
|
|
102
|
+
) {
|
|
103
|
+
return true;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
const message = (reason as { message?: unknown }).message;
|
|
107
|
+
if (typeof message !== "string") return false;
|
|
108
|
+
return (
|
|
109
|
+
message === "Connection closed" ||
|
|
110
|
+
/Failed to connect/i.test(message) ||
|
|
111
|
+
/ECONNREFUSED/i.test(message)
|
|
112
|
+
);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function assertSharedPostgresReady(): void {
|
|
116
|
+
if (sharedPostgresPaused) throw new SharedPostgresPausedError();
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Pause-aware facade over a Bun.SQL client so journal / clock / instances /
|
|
121
|
+
* Console wrappers that call `.unsafe` directly cannot reconnect after pause.
|
|
122
|
+
*
|
|
123
|
+
* @param raw - Underlying Bun.SQL (or test fake)
|
|
124
|
+
*/
|
|
125
|
+
function guardSharedPostgresClient(raw: PostgresClientLike): PostgresClientLike {
|
|
126
|
+
const guarded: PostgresClientLike = {
|
|
127
|
+
unsafe(sql, values) {
|
|
128
|
+
assertSharedPostgresReady();
|
|
129
|
+
return raw.unsafe(sql, values);
|
|
130
|
+
},
|
|
131
|
+
async reserve() {
|
|
132
|
+
assertSharedPostgresReady();
|
|
133
|
+
if (typeof raw.reserve !== "function") {
|
|
134
|
+
throw new Error("postgres client needs reserve()");
|
|
135
|
+
}
|
|
136
|
+
const reserved = await raw.reserve();
|
|
137
|
+
const guardedReserved = guardSharedPostgresClient(reserved) as PostgresReservedClient;
|
|
138
|
+
return Object.assign(guardedReserved, {
|
|
139
|
+
release(): void {
|
|
140
|
+
reserved.release();
|
|
141
|
+
},
|
|
142
|
+
});
|
|
143
|
+
},
|
|
144
|
+
begin(fn) {
|
|
145
|
+
assertSharedPostgresReady();
|
|
146
|
+
if (typeof raw.begin !== "function") {
|
|
147
|
+
throw new Error("postgres client needs begin()");
|
|
148
|
+
}
|
|
149
|
+
return raw.begin((tx) => fn(guardSharedPostgresClient(tx)));
|
|
150
|
+
},
|
|
151
|
+
async close(): Promise<void> {
|
|
152
|
+
// Shared pools are process-owned ({@link closeSharedPostgresClients}).
|
|
153
|
+
// Journal / clock / instances / store holders must not tear down Bun.SQL
|
|
154
|
+
// or the map keeps a dead client — next checkout returns
|
|
155
|
+
// ERR_POSTGRES_CONNECTION_CLOSED (e.g. after in-process `oke db seed`
|
|
156
|
+
// stops the temporary app boot inside `oke dev`).
|
|
157
|
+
},
|
|
158
|
+
};
|
|
159
|
+
return guarded;
|
|
160
|
+
}
|
|
161
|
+
|
|
50
162
|
/**
|
|
51
163
|
* One Bun.SQL pool per URL for store / journal / clock / vault / console.
|
|
52
164
|
*
|
|
165
|
+
* Returns a pause-aware client — holders (including fleet store wrappers)
|
|
166
|
+
* fail soft after {@link pauseSharedPostgresClients} instead of reconnecting.
|
|
167
|
+
*
|
|
53
168
|
* @param url - Connection URL
|
|
54
169
|
*/
|
|
55
170
|
export function sharedPostgresClient(url?: string): PostgresClientLike {
|
|
171
|
+
assertSharedPostgresReady();
|
|
56
172
|
const key = resolvePostgresUrl(url);
|
|
57
173
|
const existing = sharedClients.get(key);
|
|
58
|
-
if (existing) return existing;
|
|
59
|
-
const
|
|
60
|
-
|
|
61
|
-
|
|
174
|
+
if (existing) return existing.guarded;
|
|
175
|
+
const raw = new Bun.SQL(key, { max: POSTGRES_POOL_MAX }) as unknown as PostgresClientLike;
|
|
176
|
+
const guarded = guardSharedPostgresClient(raw);
|
|
177
|
+
sharedClients.set(key, { raw, guarded });
|
|
178
|
+
return guarded;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Close and drop every shared Bun.SQL pool.
|
|
183
|
+
*
|
|
184
|
+
* Prefer {@link pauseSharedPostgresClients} from `oke dev` — close alone does
|
|
185
|
+
* not stop Console from opening a fresh pool on the next poll.
|
|
186
|
+
*/
|
|
187
|
+
export async function closeSharedPostgresClients(): Promise<void> {
|
|
188
|
+
const clients = [...sharedClients.values()];
|
|
189
|
+
sharedClients.clear();
|
|
190
|
+
await Promise.all(
|
|
191
|
+
clients.map(async (entry) => {
|
|
192
|
+
try {
|
|
193
|
+
await entry.raw.close?.({ timeout: 1 });
|
|
194
|
+
} catch {
|
|
195
|
+
// Pool already closed / server already gone.
|
|
196
|
+
}
|
|
197
|
+
}),
|
|
198
|
+
);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* Pause shared Postgres: block new pools, fail soft on existing wrappers, and
|
|
203
|
+
* close open clients.
|
|
204
|
+
*
|
|
205
|
+
* Used by `oke dev` **`x`** before `docker compose stop` so parent Console
|
|
206
|
+
* polls do not keep reconnecting into a torn-down Postgres/PgDog.
|
|
207
|
+
*/
|
|
208
|
+
export async function pauseSharedPostgresClients(): Promise<void> {
|
|
209
|
+
sharedPostgresPaused = true;
|
|
210
|
+
await closeSharedPostgresClients();
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* Allow shared pools again after compose is back ( `oke dev` **`u`** ).
|
|
215
|
+
*/
|
|
216
|
+
export function resumeSharedPostgresClients(): void {
|
|
217
|
+
sharedPostgresPaused = false;
|
|
62
218
|
}
|
|
63
219
|
|
|
64
220
|
/**
|
|
@@ -135,6 +291,7 @@ export async function connectPostgres(options: SqlConnectOptions = {}): Promise<
|
|
|
135
291
|
: sharedPostgresClient(options.url));
|
|
136
292
|
return wrapPostgresClient(client, role, {
|
|
137
293
|
shared: injected === undefined && !dedicated,
|
|
294
|
+
...(options.url !== undefined ? { url: options.url } : {}),
|
|
138
295
|
});
|
|
139
296
|
}
|
|
140
297
|
|
|
@@ -153,18 +310,29 @@ function dedicatedPostgresClient(url: string): PostgresClientLike {
|
|
|
153
310
|
function wrapPostgresClient(
|
|
154
311
|
client: PostgresClientLike,
|
|
155
312
|
role: SqlRole,
|
|
156
|
-
opts: {
|
|
313
|
+
opts: {
|
|
314
|
+
readonly shared?: boolean;
|
|
315
|
+
readonly pinned?: boolean;
|
|
316
|
+
readonly url?: string;
|
|
317
|
+
} = {},
|
|
157
318
|
): SqlConnection {
|
|
319
|
+
const host = opts.url ? hostFromUrl(opts.url) : undefined;
|
|
158
320
|
const connection: SqlConnection = {
|
|
159
321
|
driverId: "postgres",
|
|
160
322
|
role,
|
|
323
|
+
...(host !== undefined
|
|
324
|
+
? { external: { host, provider: "postgres", kind: "infrastructure" as const } }
|
|
325
|
+
: {}),
|
|
161
326
|
async query(sql, params = []) {
|
|
327
|
+
// Shared wrappers outlive pause — fail soft before Bun.SQL reconnects.
|
|
328
|
+
if (opts.shared) assertSharedPostgresReady();
|
|
162
329
|
const pg = toPostgresParams(sql, params);
|
|
163
330
|
const result = await client.unsafe(pg, [...params]);
|
|
164
331
|
if (Array.isArray(result)) return result as SqlRow[];
|
|
165
332
|
return Array.from(result as ArrayLike<SqlRow>);
|
|
166
333
|
},
|
|
167
334
|
async exec(sql, params = []) {
|
|
335
|
+
if (opts.shared) assertSharedPostgresReady();
|
|
168
336
|
const pg = toPostgresParams(sql, params);
|
|
169
337
|
const result = await client.unsafe(pg, [...params]);
|
|
170
338
|
if (
|
|
@@ -181,6 +349,7 @@ function wrapPostgresClient(
|
|
|
181
349
|
return { changes: 0 };
|
|
182
350
|
},
|
|
183
351
|
async transaction(fn) {
|
|
352
|
+
if (opts.shared) assertSharedPostgresReady();
|
|
184
353
|
if (opts.pinned) return fn(connection);
|
|
185
354
|
return withPinnedPostgres(client, (tx) => fn(wrapPostgresClient(tx, role, { pinned: true })));
|
|
186
355
|
},
|
|
@@ -150,7 +150,7 @@ export interface SignalReplayMessageResult {
|
|
|
150
150
|
|
|
151
151
|
/** Irreversible effect intercepted during a dry-run replay. */
|
|
152
152
|
export interface SignalDryRunStub {
|
|
153
|
-
readonly kind: "send" | "ask";
|
|
153
|
+
readonly kind: "send" | "ask" | "embed" | "fetch";
|
|
154
154
|
readonly resource: string;
|
|
155
155
|
readonly messageId?: string;
|
|
156
156
|
}
|
|
@@ -201,7 +201,7 @@ export interface LiveEvent {
|
|
|
201
201
|
export interface LiveSubscribeOptions {
|
|
202
202
|
/**
|
|
203
203
|
* Exclusive SSE cursor — replay events after this id, then continue.
|
|
204
|
-
* Omit for the full retained tape. Unknown / pruned ids throw
|
|
204
|
+
* Omit for the full retained tape. Unknown / pruned ids throw OKE1210.
|
|
205
205
|
*/
|
|
206
206
|
readonly afterId?: string;
|
|
207
207
|
}
|
|
@@ -332,7 +332,7 @@ export interface SignalBus {
|
|
|
332
332
|
*
|
|
333
333
|
* Replays retained history, then yields new events until the iterator
|
|
334
334
|
* returns. `delivery` must be `"live"`. `afterId` skips through that
|
|
335
|
-
* id (exclusive); unknown or pruned ids throw
|
|
335
|
+
* id (exclusive); unknown or pruned ids throw OKE1210.
|
|
336
336
|
*
|
|
337
337
|
* @param signal - Signal name
|
|
338
338
|
* @param opts - Optional resume cursor
|
|
@@ -341,7 +341,7 @@ export interface SignalBus {
|
|
|
341
341
|
/**
|
|
342
342
|
* Validate a live resume cursor without waiting for new events.
|
|
343
343
|
*
|
|
344
|
-
* Prunes the tape first. Throws
|
|
344
|
+
* Prunes the tape first. Throws OKE1210 when `afterId` is absent.
|
|
345
345
|
*
|
|
346
346
|
* @param signal - Signal name
|
|
347
347
|
* @param afterId - SSE cursor
|
|
@@ -399,7 +399,7 @@ export interface SignalDriver {
|
|
|
399
399
|
/**
|
|
400
400
|
* Validate an emit payload against the signal declaration's Standard Schema.
|
|
401
401
|
*
|
|
402
|
-
* @param name - Signal name (for
|
|
402
|
+
* @param name - Signal name (for OKE1250)
|
|
403
403
|
* @param decl - Declared signal
|
|
404
404
|
* @param payload - Raw emit payload
|
|
405
405
|
*/
|
package/src/drivers/types.ts
CHANGED
|
@@ -48,6 +48,11 @@ export interface SqlConnection {
|
|
|
48
48
|
readonly driverId: "postgres" | "pglite" | "memory";
|
|
49
49
|
/** Primary vs replica. */
|
|
50
50
|
readonly role: SqlRole;
|
|
51
|
+
/**
|
|
52
|
+
* Egress identity when queries leave the process (remote Postgres).
|
|
53
|
+
* Omitted for in-process drivers (`pglite`, `memory`).
|
|
54
|
+
*/
|
|
55
|
+
readonly external?: import("./external.ts").DriverExternal;
|
|
51
56
|
/**
|
|
52
57
|
* Run a parameterised query and return rows.
|
|
53
58
|
*
|
|
@@ -338,6 +343,8 @@ export interface TextIndexSearchResult {
|
|
|
338
343
|
/** Full-text index handle. */
|
|
339
344
|
export interface TextIndexStore {
|
|
340
345
|
readonly driverId: "meilisearch";
|
|
346
|
+
/** Egress identity for Meilisearch HTTP calls. */
|
|
347
|
+
readonly external?: import("./external.ts").DriverExternal;
|
|
341
348
|
/**
|
|
342
349
|
* Upsert a document.
|
|
343
350
|
*
|
|
@@ -54,6 +54,11 @@ export interface VaultOpenOptions {
|
|
|
54
54
|
export interface VaultBag {
|
|
55
55
|
/** Protocol driver id. */
|
|
56
56
|
readonly driverId: VaultDriverId;
|
|
57
|
+
/**
|
|
58
|
+
* Egress identity when the bag was opened / mutated over the network.
|
|
59
|
+
* Omitted for `env` / `memory` / injected managed bags.
|
|
60
|
+
*/
|
|
61
|
+
readonly external?: import("./external.ts").DriverExternal;
|
|
57
62
|
/**
|
|
58
63
|
* Read a secret by name.
|
|
59
64
|
*
|
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
} from "../../kernel/element-registries.ts";
|
|
14
14
|
import { mcpToolRef, type McpToolRef } from "../../manifest/mcp-ref.ts";
|
|
15
15
|
import type { VaultSecretDecl } from "../vault/declare.ts";
|
|
16
|
+
import { formatAiProviderTier2Warn, resolveAiModelBaseUrl } from "./providers.ts";
|
|
16
17
|
|
|
17
18
|
/** Budget for a prompt or agent. */
|
|
18
19
|
export interface AiBudgetDecl {
|
|
@@ -27,14 +28,15 @@ export interface AiModelOptions {
|
|
|
27
28
|
readonly model?: string;
|
|
28
29
|
/**
|
|
29
30
|
* Optional endpoint override for this logical binding (openai-compatible /
|
|
30
|
-
*
|
|
31
|
-
*
|
|
31
|
+
* local). When omitted and `provider` is a known OpenAI-compatible name,
|
|
32
|
+
* the verified registry base URL is filled in automatically. Explicit
|
|
33
|
+
* `baseUrl` always wins (self-hosted proxy / mirror).
|
|
32
34
|
*/
|
|
33
35
|
readonly baseUrl?: string;
|
|
34
36
|
/** Optional API key override for this binding (cloud providers). */
|
|
35
37
|
readonly apiKey?: string;
|
|
36
38
|
/**
|
|
37
|
-
* Protocol driver for this binding (`anthropic`, `
|
|
39
|
+
* Protocol driver for this binding (`anthropic`, `openai-compatible`, …).
|
|
38
40
|
* When omitted, the app-level default driver is used.
|
|
39
41
|
*/
|
|
40
42
|
readonly driverId?: string;
|
|
@@ -260,13 +262,24 @@ export const ai: AiNamespace = {
|
|
|
260
262
|
*/
|
|
261
263
|
model(name: string, options: AiModelOptions = {}): AiModelDecl {
|
|
262
264
|
if (!name) throw new TypeError("ai.model: name is required");
|
|
265
|
+
const resolved = resolveAiModelBaseUrl({
|
|
266
|
+
...(options.provider !== undefined ? { provider: options.provider } : {}),
|
|
267
|
+
...(options.baseUrl !== undefined ? { baseUrl: options.baseUrl } : {}),
|
|
268
|
+
...(options.driverId !== undefined ? { driverId: options.driverId } : {}),
|
|
269
|
+
});
|
|
270
|
+
if (resolved.tier2Caveat !== undefined && resolved.tier2Provider !== undefined) {
|
|
271
|
+
console.warn(
|
|
272
|
+
formatAiProviderTier2Warn(resolved.tier2Provider, resolved.tier2Caveat, "ai.model"),
|
|
273
|
+
);
|
|
274
|
+
}
|
|
275
|
+
const baseUrl = resolved.baseUrl;
|
|
263
276
|
const decl: AiModelDecl = {
|
|
264
277
|
kind: "model",
|
|
265
278
|
name,
|
|
266
279
|
...(options.provider !== undefined ? { provider: options.provider } : {}),
|
|
267
280
|
...(options.tier !== undefined ? { tier: options.tier } : {}),
|
|
268
281
|
...(options.model !== undefined ? { model: options.model } : {}),
|
|
269
|
-
...(
|
|
282
|
+
...(baseUrl !== undefined ? { baseUrl } : {}),
|
|
270
283
|
...(options.apiKey !== undefined ? { apiKey: options.apiKey } : {}),
|
|
271
284
|
...(options.driverId !== undefined ? { driverId: options.driverId } : {}),
|
|
272
285
|
prompt(promptName, promptOpts = {}) {
|
package/src/elements/ai/eval.ts
CHANGED
|
@@ -126,7 +126,7 @@ export async function runPromptEvals(options: RunPromptEvalsOptions): Promise<Ev
|
|
|
126
126
|
export function parseEvalJsonl(text: string): EvalCase[] {
|
|
127
127
|
const jsonl = (Bun as typeof Bun & { JSONL?: { parse: (t: string) => unknown[] } }).JSONL;
|
|
128
128
|
if (!jsonl) {
|
|
129
|
-
throw new Error("ai.eval: Bun.JSONL is required (Bun >= 1.4.
|
|
129
|
+
throw new Error("ai.eval: Bun.JSONL is required (Bun >= 1.4.2)");
|
|
130
130
|
}
|
|
131
131
|
return jsonl.parse(text) as EvalCase[];
|
|
132
132
|
}
|
|
@@ -153,7 +153,7 @@ async function readSseJsonRpc(
|
|
|
153
153
|
function responseTextStream(res: Response): AsyncIterable<string> {
|
|
154
154
|
const stream = (res as Response & { textStream?: () => AsyncIterable<string> }).textStream;
|
|
155
155
|
if (typeof stream !== "function") {
|
|
156
|
-
throw new Error("ai.mcp: Response.textStream is required (Bun >= 1.4.
|
|
156
|
+
throw new Error("ai.mcp: Response.textStream is required (Bun >= 1.4.2)");
|
|
157
157
|
}
|
|
158
158
|
return stream.call(res);
|
|
159
159
|
}
|
package/src/elements/ai/pii.ts
CHANGED
|
@@ -70,7 +70,7 @@ function isPiiTags(tags: ColumnClassification | string | readonly string[] | und
|
|
|
70
70
|
function isThirdParty(provider: string | undefined): boolean {
|
|
71
71
|
if (!provider) return true;
|
|
72
72
|
const p = provider.toLowerCase();
|
|
73
|
-
return p !== "mock" && p !== "
|
|
73
|
+
return p !== "mock" && p !== "local" && p !== "openai-compatible";
|
|
74
74
|
}
|
|
75
75
|
|
|
76
76
|
/**
|