okengine 0.9.0 → 0.10.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 +1 -1
- package/manifest.v1.schema.json +9 -1
- package/package.json +3 -3
- package/site/content/docs/console/runs.mdx +10 -0
- package/site/content/docs/console/traces.mdx +4 -0
- package/site/content/docs/elements/ai.mdx +54 -32
- package/site/content/docs/elements/channel.mdx +105 -14
- package/site/content/docs/elements/clock.mdx +1 -0
- package/site/content/docs/elements/flow.mdx +42 -8
- package/site/content/docs/get-started/basic-usage.mdx +5 -1
- package/site/content/docs/get-started/installation.mdx +9 -5
- package/site/content/docs/meta.json +2 -0
- package/site/content/docs/plugins/otp.mdx +58 -46
- package/site/content/docs/providers/azure-redis.mdx +85 -0
- package/site/content/docs/providers/cockroachdb.mdx +86 -0
- package/site/content/docs/providers/digitalocean-caching.mdx +88 -0
- package/site/content/docs/providers/dragonfly-cloud.mdx +82 -0
- package/site/content/docs/providers/elasticache.mdx +92 -0
- package/site/content/docs/providers/index.mdx +101 -0
- package/site/content/docs/providers/memorystore.mdx +89 -0
- package/site/content/docs/providers/meta.json +20 -0
- package/site/content/docs/providers/neon.mdx +115 -0
- package/site/content/docs/providers/redis-cloud.mdx +93 -0
- package/site/content/docs/providers/supabase.mdx +117 -0
- package/site/content/docs/providers/upstash.mdx +91 -0
- package/site/content/docs/providers/yugabytedb.mdx +95 -0
- package/site/content/docs/recipes/caddy.mdx +128 -0
- package/site/content/docs/recipes/cockroachdb.mdx +127 -0
- package/site/content/docs/recipes/dragonfly.mdx +125 -0
- package/site/content/docs/recipes/index.mdx +146 -0
- package/site/content/docs/recipes/llama-cpp.mdx +153 -0
- package/site/content/docs/recipes/mailpit.mdx +136 -0
- package/site/content/docs/recipes/meilisearch.mdx +139 -0
- package/site/content/docs/recipes/meta.json +31 -0
- package/site/content/docs/recipes/ollama.mdx +142 -0
- package/site/content/docs/recipes/openbao.mdx +141 -0
- package/site/content/docs/recipes/pgdog.mdx +137 -0
- package/site/content/docs/recipes/postgres.mdx +136 -0
- package/site/content/docs/recipes/redis.mdx +130 -0
- package/site/content/docs/recipes/rustfs.mdx +148 -0
- package/site/content/docs/recipes/sglang.mdx +105 -0
- package/site/content/docs/recipes/supabase-docker.mdx +145 -0
- package/site/content/docs/recipes/timescale.mdx +129 -0
- package/site/content/docs/recipes/traefik.mdx +136 -0
- package/site/content/docs/recipes/valkey.mdx +121 -0
- package/site/content/docs/recipes/vllm.mdx +106 -0
- package/site/content/docs/recipes/yugabytedb.mdx +135 -0
- package/site/content/docs/reference/cli.md +42 -6
- package/site/content/docs/reference/configuration.mdx +5 -3
- package/site/content/docs/reference/environment-variables.mdx +12 -12
- package/site/content/docs/reference/fx.mdx +38 -4
- package/src/auth/otp-capability.ts +14 -14
- package/src/cli/ai-setup/ai-setup.test.ts +32 -12
- package/src/cli/ai-setup/apply.ts +65 -23
- package/src/cli/ai-setup/catalog.ts +1316 -35
- package/src/cli/ai-setup/detect-ollama.ts +47 -0
- package/src/cli/ai-setup/index.ts +44 -7
- package/src/cli/ai-setup/prompts.ts +430 -486
- package/src/cli/ai-setup/recommend.test.ts +150 -50
- package/src/cli/ai-setup/recommend.ts +118 -101
- package/src/cli/ask-seed.test.ts +68 -0
- package/src/cli/ask-seed.ts +79 -0
- package/src/cli/db-seed-redact.test.ts +25 -0
- package/src/cli/db-seed.ts +36 -7
- package/src/cli/db.test.ts +1 -1
- package/src/cli/db.ts +2 -2
- package/src/cli/dev-controls.test.ts +107 -0
- package/src/cli/dev-controls.ts +354 -0
- package/src/cli/dev-schema-sync.ts +12 -4
- package/src/cli/dev.test.ts +50 -30
- package/src/cli/dev.ts +607 -66
- package/src/cli/drizzle-env.test.ts +40 -6
- package/src/cli/drizzle-env.ts +22 -1
- package/src/cli/ensure-drizzle-config.ts +6 -4
- package/src/cli/hero-meta.test.ts +13 -1
- package/src/cli/hero-meta.ts +28 -6
- package/src/cli/index.ts +5 -0
- package/src/cli/registry.ts +24 -0
- package/src/cli/replay.test.ts +105 -0
- package/src/cli/replay.ts +206 -0
- package/src/compiler/extract.ts +3 -3
- package/src/config/index.ts +3 -3
- package/src/console/server/claim.ts +3 -1
- package/src/console/ui/dist/assets/{index-ClX0ZCe5.js → index-D-9KFce5.js} +2 -2
- package/src/console/ui/dist/assets/panel-overview-CW0CQEc2.js +1 -0
- package/src/console/ui/dist/assets/panel-runs-BxuyDI3x.js +1 -0
- package/src/console/ui/dist/assets/{panel-signals-Dsxdu_AR.js → panel-signals-BXofbj7v.js} +1 -1
- package/src/console/ui/dist/assets/{panel-store-hy7O8HOs.js → panel-store-B8mH-arU.js} +1 -1
- package/src/console/ui/dist/assets/{panel-traces-CBiAe5go.js → panel-traces-DSA-ZWnf.js} +1 -1
- package/src/console/ui/dist/index.html +1 -1
- package/src/console/ui/overview/slo.ts +31 -3
- package/src/console/ui/overview/types.ts +6 -0
- package/src/console/ui/runs/errors.test.ts +53 -0
- package/src/console/ui/runs/errors.ts +88 -0
- package/src/console/ui/runs/index.ts +8 -0
- package/src/console/ui/runs/search.ts +16 -0
- package/src/console/ui/shell/panels/runs/RunsPanel.tsx +72 -1
- package/src/docker/ai-model-status.test.ts +101 -0
- package/src/docker/ai-model-status.ts +276 -0
- package/src/docker/compose-health.test.ts +115 -0
- package/src/docker/compose-health.ts +234 -0
- package/src/docker/compose.ts +24 -8
- package/src/docker/derive.ts +35 -9
- package/src/docker/docker.test.ts +304 -12
- package/src/docker/helpers.ts +56 -0
- package/src/docker/index.ts +52 -0
- package/src/docker/ollama-pull.ts +232 -0
- package/src/docker/recipes/cockroach.ts +24 -0
- package/src/docker/recipes/index.ts +32 -0
- package/src/docker/recipes/llama-cpp.ts +273 -0
- package/src/docker/recipes/ollama.ts +19 -23
- package/src/docker/recipes/pgdog.ts +4 -1
- package/src/docker/recipes/postgres.ts +5 -18
- package/src/docker/recipes/sglang.ts +55 -0
- package/src/docker/recipes/supabase.ts +21 -0
- package/src/docker/recipes/timescale.ts +18 -0
- package/src/docker/recipes/vllm.ts +44 -0
- package/src/docker/recipes/yugabyte.ts +23 -0
- package/src/docker/stack-id.test.ts +22 -0
- package/src/docker/stack-id.ts +38 -4
- package/src/docker/types.ts +15 -0
- package/src/drivers/ai-ollama.integration.test.ts +7 -4
- package/src/drivers/signal-engine.ts +10 -0
- package/src/drivers/signal-postgres.ts +24 -2
- package/src/drivers/signal-types.ts +10 -0
- package/src/elements/channel/fallback.test.ts +91 -0
- package/src/elements/channel/hard-bounce.test.ts +82 -0
- package/src/elements/channel/injection.test.ts +153 -0
- package/src/elements/channel/locale-ar.test.ts +102 -0
- package/src/elements/channel/otp-delivery.ts +5 -2
- package/src/elements/channel/receipts-ledger.test.ts +100 -0
- package/src/elements/channel/runtime.ts +24 -1
- package/src/elements/channel/test-helpers.ts +60 -0
- package/src/elements/channel/whatsapp-compliance.test.ts +124 -0
- package/src/elements/store/cache.ts +1 -1
- package/src/elements/store/emit-drizzle.ts +43 -9
- package/src/elements/store/runtime.ts +1 -1
- package/src/elements/store/schema-decl.test.ts +2 -0
- package/src/elements/store/schema-decl.ts +15 -0
- package/src/elements/store/seed.ts +1 -1
- package/src/index.ts +1 -0
- package/src/kernel/app.ts +118 -11
- package/src/kernel/boot-bind/signal.ts +6 -2
- package/src/kernel/boot-bind/store.ts +2 -1
- package/src/kernel/boot.test.ts +6 -5
- package/src/kernel/boot.ts +8 -3
- package/src/kernel/compensate.test.ts +131 -0
- package/src/kernel/correlation.test.ts +108 -0
- package/src/kernel/effect-timing.test.ts +82 -0
- package/src/kernel/flow.ts +38 -0
- package/src/kernel/fx-runs.test.ts +49 -0
- package/src/kernel/fx.test.ts +14 -0
- package/src/kernel/fx.ts +111 -1
- package/src/manifest/types.ts +8 -2
- package/src/plugins/auth-delivery.mailpit.integration.test.ts +1 -1
- package/src/plugins/auth-methods.security.test.ts +3 -3
- package/src/plugins/auth-methods.test.ts +1 -1
- package/src/plugins/index.ts +2 -2
- package/src/plugins/otp.test.ts +21 -19
- package/src/plugins/otp.ts +36 -34
- package/src/plugins/taqnyat.live.test.ts +3 -3
- package/src/runs/collect.ts +3 -0
- package/src/runs/export-otlp.ts +64 -0
- package/src/runs/index.ts +16 -0
- package/src/runs/parquet.ts +9 -0
- package/src/runs/types.ts +5 -0
- package/src/runs/window.test.ts +68 -0
- package/src/runs/window.ts +148 -0
- package/src/runtime/boot-warn.test.ts +45 -0
- package/src/runtime/boot-warn.ts +17 -0
- package/src/runtime/dev-request-log.ts +5 -5
- package/src/term.test.ts +95 -10
- package/src/term.ts +369 -14
- package/src/console/ui/dist/assets/panel-overview-DONDzBd2.js +0 -1
- package/src/console/ui/dist/assets/panel-runs-D5zf-D9c.js +0 -1
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Write AI driver config, env, and `src/ai.ts` for `oke ai setup`.
|
|
2
|
+
* Write AI driver config, env, and `src/core/ai.ts` for `oke ai setup`.
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
6
6
|
import { dirname, join } from "node:path";
|
|
7
|
+
import { OLLAMA_IMAGE } from "../../docker/recipes/index.ts";
|
|
7
8
|
|
|
8
9
|
/** Choices applied to the project. */
|
|
9
10
|
export type AiSetupApplyInput = {
|
|
@@ -13,6 +14,10 @@ export type AiSetupApplyInput = {
|
|
|
13
14
|
readonly visionModel?: string | null;
|
|
14
15
|
readonly embedModel?: string | null;
|
|
15
16
|
readonly apiKeyEnv?: string;
|
|
17
|
+
/** When set with {@link apiKeyEnv}, writes the token into `.env.local`. */
|
|
18
|
+
readonly apiKey?: string;
|
|
19
|
+
/** Optional `images.ai` pin (llama.cpp / Ollama / vLLM / SGLang). */
|
|
20
|
+
readonly image?: string;
|
|
16
21
|
};
|
|
17
22
|
|
|
18
23
|
/** Options for {@link applyAiSetup}. */
|
|
@@ -49,8 +54,10 @@ export function applyAiSetup(
|
|
|
49
54
|
if (updateDrivers) {
|
|
50
55
|
let config = readFileSync(configPath, "utf8");
|
|
51
56
|
config = upsertAiDrivers(config, input.driver);
|
|
52
|
-
if (input.
|
|
53
|
-
config = upsertImage(config, "ai",
|
|
57
|
+
if (input.image) {
|
|
58
|
+
config = upsertImage(config, "ai", input.image);
|
|
59
|
+
} else if (input.driver === "ollama") {
|
|
60
|
+
config = upsertImage(config, "ai", OLLAMA_IMAGE);
|
|
54
61
|
}
|
|
55
62
|
writeFileSync(configPath, config, "utf8");
|
|
56
63
|
}
|
|
@@ -62,20 +69,29 @@ export function applyAiSetup(
|
|
|
62
69
|
: existsSync(envExample)
|
|
63
70
|
? readFileSync(envExample, "utf8")
|
|
64
71
|
: "";
|
|
65
|
-
|
|
66
|
-
|
|
72
|
+
// Driver / URL stay commented so docker mode can hydrate `OKE_AI_URL` from
|
|
73
|
+
// `docker/.env.docker` without being shadowed. The selected chat model is
|
|
74
|
+
// written active — `oke dev` seeds it into stack controls / `LLAMA_ARG_DOCKER_REPO`
|
|
75
|
+
// (commented-only left the compose default `smollm2` forever).
|
|
76
|
+
env = upsertEnv(env, "OKE_AI_DRIVER", input.driver, { comment: true });
|
|
77
|
+
if (input.baseUrl) env = upsertEnv(env, "OKE_AI_URL", input.baseUrl, { comment: true });
|
|
67
78
|
if (input.chatModel) env = upsertEnv(env, "OKE_AI_MODEL", input.chatModel);
|
|
68
|
-
if (input.visionModel)
|
|
69
|
-
|
|
79
|
+
if (input.visionModel) {
|
|
80
|
+
env = upsertEnv(env, "OKE_AI_VISION_MODEL", input.visionModel, { comment: true });
|
|
81
|
+
}
|
|
82
|
+
if (input.embedModel) {
|
|
83
|
+
env = upsertEnv(env, "OKE_AI_EMBED_MODEL", input.embedModel, { comment: true });
|
|
84
|
+
}
|
|
70
85
|
if (input.apiKeyEnv) {
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
86
|
+
if (input.apiKey !== undefined && input.apiKey.length > 0) {
|
|
87
|
+
env = upsertEnv(env, input.apiKeyEnv, input.apiKey);
|
|
88
|
+
} else if (!new RegExp(`^#?\\s*${input.apiKeyEnv}=`, "m").test(env)) {
|
|
89
|
+
env = `${env.trimEnd()}\n# ${input.apiKeyEnv}=\n`;
|
|
74
90
|
}
|
|
75
91
|
}
|
|
76
92
|
writeFileSync(envPath, env.endsWith("\n") ? env : `${env}\n`, "utf8");
|
|
77
93
|
|
|
78
|
-
const aiTsPath = join(cwd, "src", "ai.ts");
|
|
94
|
+
const aiTsPath = join(cwd, "src", "core", "ai.ts");
|
|
79
95
|
mkdirSync(dirname(aiTsPath), { recursive: true });
|
|
80
96
|
writeFileSync(aiTsPath, renderAiTs(input), "utf8");
|
|
81
97
|
ensureAiImported(cwd);
|
|
@@ -89,11 +105,11 @@ export function applyAiSetup(
|
|
|
89
105
|
*/
|
|
90
106
|
export function upsertAiDrivers(source: string, driver: string): string {
|
|
91
107
|
const block = `{
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
108
|
+
local: "${driver}",
|
|
109
|
+
docker: "${driver === "mock" ? "mock" : driver}",
|
|
110
|
+
test: "mock",
|
|
111
|
+
prod: "${driver === "mock" ? "mock" : driver}",
|
|
112
|
+
}`;
|
|
97
113
|
// Top-level drivers.ai only (4-space indent) — never nest under channel.email.
|
|
98
114
|
const aiRe = /^( {4})ai:\s*\{[\s\S]*?\n\1\}/m;
|
|
99
115
|
if (aiRe.test(source)) {
|
|
@@ -131,13 +147,30 @@ export function upsertImage(source: string, key: string, image: string): string
|
|
|
131
147
|
return source.replace(imagesRe, `images: {${body}\n${line}\n }`);
|
|
132
148
|
}
|
|
133
149
|
|
|
150
|
+
/** Options for {@link upsertEnv}. */
|
|
151
|
+
export type UpsertEnvOptions = {
|
|
152
|
+
/**
|
|
153
|
+
* When true, write `# KEY=value` (opt-in override). Used for AI stack keys
|
|
154
|
+
* so they do not shadow `docker/.env.docker`.
|
|
155
|
+
*/
|
|
156
|
+
readonly comment?: boolean;
|
|
157
|
+
};
|
|
158
|
+
|
|
134
159
|
/**
|
|
160
|
+
* Insert or replace a dotenv assignment (optionally commented).
|
|
161
|
+
*
|
|
135
162
|
* @param env - dotenv text
|
|
136
163
|
* @param key - Variable name
|
|
137
164
|
* @param value - Value
|
|
165
|
+
* @param options - Comment vs active line
|
|
138
166
|
*/
|
|
139
|
-
export function upsertEnv(
|
|
140
|
-
|
|
167
|
+
export function upsertEnv(
|
|
168
|
+
env: string,
|
|
169
|
+
key: string,
|
|
170
|
+
value: string,
|
|
171
|
+
options: UpsertEnvOptions = {},
|
|
172
|
+
): string {
|
|
173
|
+
const line = options.comment ? `# ${key}=${value}` : `${key}=${value}`;
|
|
141
174
|
const re = new RegExp(`^#?\\s*${key}=.*$`, "m");
|
|
142
175
|
if (re.test(env)) return env.replace(re, line);
|
|
143
176
|
const aiSection = /(# ── AI[^\n]*\n)/;
|
|
@@ -197,18 +230,27 @@ export function renderAiTs(input: AiSetupApplyInput): string {
|
|
|
197
230
|
}
|
|
198
231
|
|
|
199
232
|
/**
|
|
200
|
-
* Ensure `src/app.ts`
|
|
233
|
+
* Ensure `src/app.ts` or `src/core/index.ts` imports AI wiring.
|
|
201
234
|
*
|
|
202
235
|
* @param cwd - Project root
|
|
203
236
|
*/
|
|
204
237
|
function ensureAiImported(cwd: string): void {
|
|
205
|
-
|
|
238
|
+
const candidates: ReadonlyArray<{ readonly rel: string; readonly importLine: string }> = [
|
|
239
|
+
{ rel: "src/app.ts", importLine: `import "./core/ai";\n` },
|
|
240
|
+
{ rel: "src/core/index.ts", importLine: `import "./ai";\n` },
|
|
241
|
+
{ rel: "src/core.ts", importLine: `import "./ai";\n` },
|
|
242
|
+
];
|
|
243
|
+
for (const { rel, importLine } of candidates) {
|
|
206
244
|
const path = join(cwd, rel);
|
|
207
245
|
if (!existsSync(path)) continue;
|
|
208
246
|
const src = readFileSync(path, "utf8");
|
|
209
|
-
if (
|
|
210
|
-
|
|
211
|
-
|
|
247
|
+
if (
|
|
248
|
+
/from\s+["']\.\/(?:core\/)?ai["']/.test(src) ||
|
|
249
|
+
/import\s+["']\.\/(?:core\/)?ai["']/.test(src)
|
|
250
|
+
) {
|
|
251
|
+
return;
|
|
252
|
+
}
|
|
253
|
+
writeFileSync(path, `${importLine}${src}`, "utf8");
|
|
212
254
|
return;
|
|
213
255
|
}
|
|
214
256
|
}
|