@k2b/cloud 0.46.0 → 0.47.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/package.json +8 -4
- package/scripts/build.ts +5 -1
- package/scripts/preload.ts +5 -1
- package/src/_internal/define-app.ts +38 -0
- package/src/_internal/heartbeat.ts +19 -0
- package/src/_internal/postgres-application-name.ts +11 -0
- package/src/_internal/process-sync.ts +9 -0
- package/src/_internal/readiness.ts +6 -1
- package/src/_internal/resource-principals.ts +4 -34
- package/src/_internal/workload-credential.ts +153 -0
- package/src/_internal/workload-protocol.ts +36 -0
- package/src/ai/application-tasks.ts +5 -2
- package/src/ai/chart-block.ts +36 -711
- package/src/ai/default-tool-contracts.ts +21 -259
- package/src/api/admin-app-keys.ts +66 -0
- package/src/api/admin-core-settings.ts +2 -0
- package/src/api/admin-identity.ts +27 -1
- package/src/api/admin-settings-env.ts +120 -0
- package/src/api/capabilities.ts +9 -3
- package/src/api/index.ts +3 -0
- package/src/api/settings-ops.ts +35 -0
- package/src/app-key.ts +125 -0
- package/src/browser/CloudResourceSearch.tsx +48 -41
- package/src/capabilities/discussion-providers.ts +3 -2
- package/src/capabilities/resource-readers.ts +13 -2
- package/src/capabilities/response.ts +4 -1
- package/src/capabilities/server-invoke.ts +46 -28
- package/src/capabilities/server.ts +1 -1
- package/src/capabilities/types.ts +1 -1
- package/src/cli/admin/app-credentials.ts +32 -7
- package/src/cli/admin/app-keys.ts +226 -0
- package/src/cli/admin/index.ts +7 -1
- package/src/cli/admin/settings.ts +62 -0
- package/src/config/define-env.ts +63 -8
- package/src/config/env.ts +27 -21
- package/src/config/index.ts +12 -1
- package/src/config/workflow-ai.ts +28 -0
- package/src/contracts/settings-env.ts +21 -0
- package/src/contracts/settings-types.ts +6 -0
- package/src/index.ts +9 -0
- package/src/runtime/clients.ts +72 -0
- package/src/runtime/connections.ts +37 -0
- package/src/runtime/resolve-connections.ts +91 -0
- package/src/server/client-ip.ts +1 -1
- package/src/services/app-keys.ts +298 -0
- package/src/services/gateway.ts +6 -0
- package/src/services/identity/index.ts +3 -0
- package/src/services/identity/resource-readers.ts +80 -0
- package/src/services/identity/runtime-config.ts +14 -6
- package/src/services/identity/workload-runtime.ts +253 -0
- package/src/services/index.ts +4 -1
- package/src/services/outgoing-mail/resolve-host.ts +5 -4
- package/src/services/service-account-credentials.ts +63 -21
- package/src/services/settings/api.ts +3 -3
- package/src/services/settings/binding.ts +45 -0
- package/src/services/settings/core-settings.ts +99 -1
- package/src/services/settings/defaults.ts +16 -2
- package/src/services/settings/env-status.ts +69 -0
- package/src/services/settings/index.ts +69 -26
- package/src/services/settings/store.ts +73 -8
- package/src/services/settings/validation.ts +40 -0
- package/src/shared/index.ts +11 -10
- package/src/shared/markdown/extensions/tables.ts +10 -1
- package/src/start.ts +36 -0
- package/src/workflows/ai/index.ts +1 -0
- package/src/workflows/ai/runtime.ts +16 -8
- package/src/workflows/ai/settings.ts +5 -0
- package/src/shared/markdown/formula.ts +0 -1283
package/src/start.ts
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
// Keep this entry independent of the platform barrel and application modules.
|
|
2
|
+
import { initializeClients } from "./runtime/clients";
|
|
3
|
+
import { bindConnections, hasConnections } from "./runtime/connections";
|
|
4
|
+
import { resolveConnections } from "./runtime/resolve-connections";
|
|
5
|
+
|
|
6
|
+
export type PlatformStartOptions = {
|
|
7
|
+
appId: string;
|
|
8
|
+
/** Core and Gateway always use infrastructure environment values. */
|
|
9
|
+
source?: "env";
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
/** Initialize before importing any application module, also in dev and data workers. */
|
|
13
|
+
export const initializePlatform = async ({ appId, source }: PlatformStartOptions): Promise<void> => {
|
|
14
|
+
if (!/^[a-z][a-z0-9-]{0,79}$/.test(appId)) throw new Error("Platform start requires a valid appId");
|
|
15
|
+
if (hasConnections()) throw new Error("Platform has already started");
|
|
16
|
+
if (appId === "core" || appId === "gateway") source = "env";
|
|
17
|
+
// Slice 6b seam: validate the app key and fetch missing values from Core here,
|
|
18
|
+
// then pass the typed response to resolveConnections({ appId, core }).
|
|
19
|
+
// A present key must never silently fall back to the legacy env mode.
|
|
20
|
+
if (source !== "env" && (process.env.CLOUD_APP_KEY?.trim() || process.env.CLOUD_APP_KEY_FILE?.trim())) {
|
|
21
|
+
throw new Error("Core connection bootstrap is not available yet");
|
|
22
|
+
}
|
|
23
|
+
const resolved = resolveConnections({ appId });
|
|
24
|
+
bindConnections(resolved);
|
|
25
|
+
try {
|
|
26
|
+
await initializeClients();
|
|
27
|
+
} catch (error) {
|
|
28
|
+
bindConnections(undefined);
|
|
29
|
+
throw error;
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
export const startPlatform = async <T>({ load, ...options }: PlatformStartOptions & { load: () => Promise<T> }): Promise<T> => {
|
|
34
|
+
await initializePlatform(options);
|
|
35
|
+
return load();
|
|
36
|
+
};
|
|
@@ -7,8 +7,10 @@ import { resolveAiWorkflowModel, runAiStructured } from "../../ai/structured";
|
|
|
7
7
|
import { executeAiTask } from "../../ai/task-execution";
|
|
8
8
|
import { resolveApplicationAiTaskModel } from "../../ai/task-model";
|
|
9
9
|
import { isAiSettingsError } from "../../ai/validate";
|
|
10
|
-
import {
|
|
10
|
+
import { DEFAULT_WORKFLOW_AI_BUDGET } from "../../config/workflow-ai";
|
|
11
|
+
import { coreSettings } from "../../services/settings/api";
|
|
11
12
|
import { WorkflowAiAdmissionError, workflowAiModelHash } from "./policy";
|
|
13
|
+
import { getWorkflowAiBudget } from "./settings";
|
|
12
14
|
|
|
13
15
|
import {
|
|
14
16
|
claimWorkflowAiTask,
|
|
@@ -44,13 +46,14 @@ export type WorkflowAiProcessOptions = Required<Omit<WorkflowAiRuntimeOptions, "
|
|
|
44
46
|
attemptTimeoutMs?: number;
|
|
45
47
|
};
|
|
46
48
|
|
|
49
|
+
let workerBudget = DEFAULT_WORKFLOW_AI_BUDGET;
|
|
47
50
|
const workflowAiJob = lazySync((sync) =>
|
|
48
51
|
sync.job<{ taskId: string }>({
|
|
49
52
|
id: WORKFLOW_AI_JOB_ID,
|
|
50
53
|
whenFull: "reject",
|
|
51
54
|
owner: "cloud",
|
|
52
55
|
delivery: {
|
|
53
|
-
maxInFlight:
|
|
56
|
+
maxInFlight: workerBudget.globalConcurrent,
|
|
54
57
|
ackWaitMs: 30_000,
|
|
55
58
|
maxAttempts: MAX_ATTEMPTS,
|
|
56
59
|
backoffMs: [1_000, 2_000],
|
|
@@ -137,6 +140,7 @@ export const processWorkflowAiTask = async (
|
|
|
137
140
|
ctx: { signal: AbortSignal; heartbeat(): Promise<void> },
|
|
138
141
|
options: WorkflowAiProcessOptions,
|
|
139
142
|
): Promise<void> => {
|
|
143
|
+
const attemptTimeoutMs = options.attemptTimeoutMs ?? (await coreSettings.get<number>("ai.workflow_attempt_timeout_ms"));
|
|
140
144
|
const task = await claimWorkflowAiTask(taskId);
|
|
141
145
|
if (!task) {
|
|
142
146
|
const terminal = await getWorkflowAiTask(taskId);
|
|
@@ -150,7 +154,7 @@ export const processWorkflowAiTask = async (
|
|
|
150
154
|
const deadline = setTimeout(() => {
|
|
151
155
|
timedOut = true;
|
|
152
156
|
controller.abort(new Error("Workflow AI attempt deadline exceeded. Retry the workflow or inspect the provider."));
|
|
153
|
-
},
|
|
157
|
+
}, attemptTimeoutMs);
|
|
154
158
|
let canceled = false;
|
|
155
159
|
let monitorError: unknown;
|
|
156
160
|
let checking = false;
|
|
@@ -230,9 +234,12 @@ let recovery: Promise<void> | null = null;
|
|
|
230
234
|
let shutdown: AbortController | null = null;
|
|
231
235
|
|
|
232
236
|
const recover = (): Promise<void> => {
|
|
233
|
-
recovery ??=
|
|
234
|
-
|
|
235
|
-
|
|
237
|
+
recovery ??= coreSettings
|
|
238
|
+
.get<number>("ai.workflow_queue_timeout_ms")
|
|
239
|
+
.then((timeout) => expireWorkflowAiTasks(timeout))
|
|
240
|
+
.finally(() => {
|
|
241
|
+
recovery = null;
|
|
242
|
+
});
|
|
236
243
|
return recovery;
|
|
237
244
|
};
|
|
238
245
|
|
|
@@ -242,14 +249,15 @@ export const startWorkflowAiRuntime = async (input: WorkflowAiRuntimeOptions = {
|
|
|
242
249
|
runStructured: input.runStructured ?? runAiStructured,
|
|
243
250
|
maxAttempts: MAX_ATTEMPTS,
|
|
244
251
|
cancelPollMs: input.cancelPollMs ?? DEFAULT_CANCEL_POLL_MS,
|
|
245
|
-
attemptTimeoutMs: input.attemptTimeoutMs
|
|
252
|
+
attemptTimeoutMs: input.attemptTimeoutMs,
|
|
246
253
|
};
|
|
254
|
+
workerBudget = await getWorkflowAiBudget();
|
|
247
255
|
const next = workflowAiJob();
|
|
248
256
|
activeJob = next;
|
|
249
257
|
const controller = new AbortController();
|
|
250
258
|
shutdown = controller;
|
|
251
259
|
try {
|
|
252
|
-
activeWorker = await next.process({ concurrency:
|
|
260
|
+
activeWorker = await next.process({ concurrency: workerBudget.globalConcurrent }, async (context) => {
|
|
253
261
|
try {
|
|
254
262
|
await processWorkflowAiTask(
|
|
255
263
|
context.input.taskId,
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { workflowAiBudgetSchema } from "../../config/workflow-ai";
|
|
2
|
+
import { coreSettings } from "../../services/settings/api";
|
|
3
|
+
|
|
4
|
+
export const getWorkflowAiBudget = async () =>
|
|
5
|
+
workflowAiBudgetSchema.parse(JSON.parse(await coreSettings.get<string>("ai.workflow_budget")));
|