@velum-labs/routekit-daemon 1.3.2 → 1.5.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/dist/account-enroll-service.d.ts +1 -3
- package/dist/account-enroll-service.js +262 -262
- package/dist/account-mutation-service.d.ts +1 -3
- package/dist/account-mutation-service.js +302 -283
- package/dist/account-query-service.d.ts +1 -3
- package/dist/account-query-service.js +88 -86
- package/dist/call-attribution-store.js +544 -1
- package/dist/control-dispatch.js +9 -15
- package/dist/daemon-bootstrap-preflight.js +1 -1
- package/dist/daemon-control-handlers.d.ts +1 -1
- package/dist/daemon-control-handlers.js +24 -27
- package/dist/daemon-generations.d.ts +14 -28
- package/dist/daemon-generations.js +114 -53
- package/dist/daemon-lifecycle-service.d.ts +1 -3
- package/dist/daemon-lifecycle-service.js +88 -94
- package/dist/daemon-maintenance.d.ts +27 -49
- package/dist/daemon-maintenance.js +5 -1
- package/dist/daemon-options.d.ts +3 -2
- package/dist/daemon-policy-context.d.ts +1 -0
- package/dist/daemon-policy-context.js +1 -0
- package/dist/daemon-runtime-state.d.ts +1 -1
- package/dist/daemon-runtime-state.js +2 -3
- package/dist/daemon-state-context.d.ts +1 -1
- package/dist/daemon-state-context.js +1 -38
- package/dist/doctor-service.d.ts +1 -3
- package/dist/doctor-service.js +87 -91
- package/dist/effect/daemon-live.d.ts +7 -6
- package/dist/effect/daemon-live.js +57 -135
- package/dist/eval-routing-service.d.ts +1 -3
- package/dist/eval-routing-service.js +45 -69
- package/dist/eval-session-execution-store.d.ts +24 -0
- package/dist/eval-session-execution-store.js +253 -0
- package/dist/host-protocol.d.ts +1 -0
- package/dist/host.js +3 -0
- package/dist/internal-providers/provider-anthropic/index.d.ts +23 -0
- package/dist/internal-providers/provider-anthropic/index.js +42 -0
- package/dist/internal-providers/provider-anthropic/test/provider.test.js +33 -0
- package/dist/internal-providers/provider-azure/index.d.ts +25 -0
- package/dist/internal-providers/provider-azure/index.js +101 -0
- package/dist/internal-providers/provider-azure/test/provider.test.js +83 -0
- package/dist/internal-providers/provider-bedrock/codec.d.ts +11 -0
- package/dist/internal-providers/provider-bedrock/codec.js +484 -0
- package/dist/internal-providers/provider-bedrock/connection-settings.d.ts +6 -0
- package/dist/internal-providers/provider-bedrock/connection-settings.js +41 -0
- package/dist/internal-providers/provider-bedrock/connection.d.ts +17 -0
- package/dist/internal-providers/provider-bedrock/connection.js +143 -0
- package/dist/internal-providers/provider-bedrock/index.d.ts +27 -0
- package/dist/internal-providers/provider-bedrock/index.js +47 -0
- package/dist/internal-providers/provider-bedrock/source.d.ts +39 -0
- package/dist/internal-providers/provider-bedrock/source.js +454 -0
- package/dist/internal-providers/provider-bedrock/test/bedrock-source.test.d.ts +1 -0
- package/dist/internal-providers/provider-bedrock/test/bedrock-source.test.js +786 -0
- package/dist/internal-providers/provider-bedrock/test/connection.test.d.ts +1 -0
- package/dist/internal-providers/provider-bedrock/test/connection.test.js +249 -0
- package/dist/internal-providers/provider-bedrock/test/workload-credentials.test.d.ts +1 -0
- package/dist/internal-providers/provider-bedrock/test/workload-credentials.test.js +29 -0
- package/dist/internal-providers/provider-bedrock/workload-credentials.d.ts +5 -0
- package/dist/internal-providers/provider-bedrock/workload-credentials.js +14 -0
- package/dist/internal-providers/provider-claude-code/index.d.ts +6 -0
- package/dist/internal-providers/provider-claude-code/index.js +4 -0
- package/dist/internal-providers/provider-claude-code/module-api.d.ts +25 -0
- package/dist/internal-providers/provider-claude-code/module-api.js +31 -0
- package/dist/internal-providers/provider-claude-code/relay.d.ts +20 -0
- package/dist/internal-providers/provider-claude-code/relay.js +115 -0
- package/dist/internal-providers/provider-claude-code/subscription.d.ts +2 -0
- package/dist/internal-providers/provider-claude-code/subscription.js +194 -0
- package/dist/internal-providers/provider-claude-code/test/http-submission.test.d.ts +1 -0
- package/dist/internal-providers/provider-claude-code/test/http-submission.test.js +140 -0
- package/dist/internal-providers/provider-claude-code/test/relay.test.d.ts +1 -0
- package/dist/internal-providers/provider-claude-code/test/relay.test.js +379 -0
- package/dist/internal-providers/provider-claude-code/test/subscription.test.d.ts +1 -0
- package/dist/internal-providers/provider-claude-code/test/subscription.test.js +256 -0
- package/dist/internal-providers/provider-cliproxy/index.d.ts +9 -0
- package/dist/internal-providers/provider-cliproxy/index.js +15 -0
- package/dist/internal-providers/provider-codex/index.d.ts +6 -0
- package/dist/internal-providers/provider-codex/index.js +7 -0
- package/dist/internal-providers/provider-codex/module-api.d.ts +25 -0
- package/dist/internal-providers/provider-codex/module-api.js +31 -0
- package/dist/internal-providers/provider-codex/relay.d.ts +123 -0
- package/dist/internal-providers/provider-codex/relay.js +261 -0
- package/dist/internal-providers/provider-codex/subscription.d.ts +2 -0
- package/dist/internal-providers/provider-codex/subscription.js +555 -0
- package/dist/internal-providers/provider-codex/test/http-submission.test.d.ts +1 -0
- package/dist/internal-providers/provider-codex/test/http-submission.test.js +142 -0
- package/dist/internal-providers/provider-codex/test/relay.test.d.ts +1 -0
- package/dist/internal-providers/provider-codex/test/relay.test.js +600 -0
- package/dist/internal-providers/provider-codex/test/subscription.test.d.ts +1 -0
- package/dist/internal-providers/provider-codex/test/subscription.test.js +70 -0
- package/dist/internal-providers/provider-codex/test/translated-content.test.d.ts +1 -0
- package/dist/internal-providers/provider-codex/test/translated-content.test.js +91 -0
- package/dist/internal-providers/provider-custom/index.d.ts +9 -0
- package/dist/internal-providers/provider-custom/index.js +15 -0
- package/dist/internal-providers/provider-google/index.d.ts +23 -0
- package/dist/internal-providers/provider-google/index.js +43 -0
- package/dist/internal-providers/provider-google/test/provider.test.d.ts +1 -0
- package/dist/internal-providers/provider-google/test/provider.test.js +34 -0
- package/dist/internal-providers/provider-google-vertex/index.d.ts +28 -0
- package/dist/internal-providers/provider-google-vertex/index.js +137 -0
- package/dist/internal-providers/provider-google-vertex/test/provider.test.d.ts +1 -0
- package/dist/internal-providers/provider-google-vertex/test/provider.test.js +85 -0
- package/dist/internal-providers/provider-openai/documented-reasoning.d.ts +9 -0
- package/dist/internal-providers/provider-openai/documented-reasoning.js +26 -0
- package/dist/internal-providers/provider-openai/index.d.ts +23 -0
- package/dist/internal-providers/provider-openai/index.js +74 -0
- package/dist/internal-providers/provider-openai/test/provider.test.d.ts +1 -0
- package/dist/internal-providers/provider-openai/test/provider.test.js +268 -0
- package/dist/internal-providers/provider-openai-compatible/index.d.ts +9 -0
- package/dist/internal-providers/provider-openai-compatible/index.js +15 -0
- package/dist/internal-providers/provider-openai-compatible/test/provider.test.d.ts +1 -0
- package/dist/internal-providers/provider-openai-compatible/test/provider.test.js +40 -0
- package/dist/internal-providers/provider-openrouter/connection.d.ts +5 -0
- package/dist/internal-providers/provider-openrouter/connection.js +143 -0
- package/dist/internal-providers/provider-openrouter/index.d.ts +28 -0
- package/dist/internal-providers/provider-openrouter/index.js +42 -0
- package/dist/internal-providers/provider-openrouter/pricing.d.ts +4 -0
- package/dist/internal-providers/provider-openrouter/pricing.js +108 -0
- package/dist/internal-providers/provider-openrouter/test/connection.test.d.ts +1 -0
- package/dist/internal-providers/provider-openrouter/test/connection.test.js +71 -0
- package/dist/internal-providers/provider-openrouter/test/pricing.test.d.ts +1 -0
- package/dist/internal-providers/provider-openrouter/test/pricing.test.js +45 -0
- package/dist/internal-providers/provider-openrouter/test/provider.test.d.ts +1 -0
- package/dist/internal-providers/provider-openrouter/test/provider.test.js +141 -0
- package/dist/internal-providers/provider-openrouter/test/validation.test.d.ts +1 -0
- package/dist/internal-providers/provider-openrouter/test/validation.test.js +225 -0
- package/dist/launcher-service.d.ts +3 -7
- package/dist/launcher-service.js +144 -133
- package/dist/provider-modules.d.ts +6 -0
- package/dist/provider-modules.js +55 -0
- package/dist/provider-query-service.d.ts +1 -3
- package/dist/provider-query-service.js +140 -143
- package/dist/router-generation-service.d.ts +1 -3
- package/dist/router-generation-service.js +83 -78
- package/dist/services/eval-session/service.d.ts +20 -8
- package/dist/services/eval-session/service.js +410 -40
- package/dist/services/gateway-generation/service.d.ts +7 -3
- package/dist/services/gateway-generation/service.js +126 -63
- package/dist/services/generations/service.d.ts +3 -3
- package/dist/services/generations/service.js +5 -1
- package/dist/telemetry-application-service.d.ts +1 -3
- package/dist/telemetry-application-service.js +41 -45
- package/dist/test/call-attribution-store.test.js +186 -0
- package/dist/test/daemon-accounts.test.js +2 -2
- package/dist/test/daemon-data-plane.test.js +24 -45
- package/dist/test/daemon-fixtures.js +1 -1
- package/dist/test/daemon-generation-transaction.test.js +66 -2
- package/dist/test/daemon-runtime-state.test.js +28 -1
- package/dist/test/effect-daemon.test.js +38 -0
- package/dist/test/eval-routing-application-service.test.js +6 -6
- package/dist/test/eval-session-execution.test.d.ts +1 -0
- package/dist/test/eval-session-execution.test.js +356 -0
- package/dist/test/eval-session-service.test.js +70 -1
- package/dist/test/host-worker-session.test.js +1 -0
- package/dist/test/launcher-session.test.d.ts +1 -0
- package/dist/test/launcher-session.test.js +87 -0
- package/dist/test/leaderboard.test.js +25 -1
- package/dist/test/provider-modules.test.d.ts +1 -0
- package/dist/test/provider-modules.test.js +65 -0
- package/dist/test/routekit-upstream-sources.test.d.ts +1 -0
- package/dist/test/routekit-upstream-sources.test.js +40 -0
- package/dist/test/runtime-composition-types.test.js +11 -0
- package/dist/token-application-service.d.ts +1 -3
- package/dist/token-application-service.js +38 -44
- package/dist/worker.js +5 -3
- package/package.json +35 -11
- package/dist/application-services.d.ts +0 -10
- package/dist/application-services.js +0 -22
- package/dist/daemon-lifecycle.d.ts +0 -54
- package/dist/daemon-lifecycle.js +0 -177
- package/dist/test/application-services.test.js +0 -135
- package/dist/test/daemon-lifecycle.test.js +0 -182
- /package/dist/{test/application-services.test.d.ts → internal-providers/provider-anthropic/test/provider.test.d.ts} +0 -0
- /package/dist/{test/daemon-lifecycle.test.d.ts → internal-providers/provider-azure/test/provider.test.d.ts} +0 -0
|
@@ -1,41 +1,39 @@
|
|
|
1
1
|
import { join } from "node:path";
|
|
2
|
-
import { CLIPROXY_API_KEY_ENV, CLIPROXY_BASE_URL_ENV, cliproxyApiKey, cliproxyBaseUrl, subscriptionAccountIdentity, subscriptionCredentialFingerprint } from "@velum-labs/routekit-accounts";
|
|
3
2
|
import { AccountActivity, AccountAuth } from "@velum-labs/routekit-accounts/effect";
|
|
4
3
|
import { resolveLeaderboardConfig } from "@velum-labs/routekit-config";
|
|
5
4
|
import { ROUTEKIT_CONTROL_CAPABILITY, ROUTEKIT_DAEMON_ROLL_CAPABILITY } from "@velum-labs/routekit-control";
|
|
5
|
+
import { toPromiseControlHandlers } from "@velum-labs/routekit-control/effect";
|
|
6
6
|
import { createWorkloadJwtVerifier } from "@velum-labs/routekit-gateway";
|
|
7
7
|
import { startSwitchingGatewayProxyEffect } from "@velum-labs/routekit-gateway/effect";
|
|
8
8
|
import { CONTROL_PROTOCOL_VERSION, ControlError, generateControlToken } from "@velum-labs/routekit-runtime/control";
|
|
9
|
-
import { RouteKitLive, startControlServerEffect, toRouteKitFailure
|
|
9
|
+
import { RouteKitLive, startControlServerEffect, toRouteKitFailure } from "@velum-labs/routekit-runtime/effect";
|
|
10
10
|
import { createPortlessSession } from "@velum-labs/routekit-runtime/network";
|
|
11
11
|
import { nextServiceGeneration, processIdentity, supervisorFromEnv } from "@velum-labs/routekit-runtime/service";
|
|
12
12
|
import { Context, Effect, Layer, Ref } from "effect";
|
|
13
|
-
import {
|
|
13
|
+
import { AccountRecovery } from "../account-recovery-context.js";
|
|
14
14
|
import { createCliproxySidecar, createHostedCliproxySidecar } from "../cliproxy-sidecar.js";
|
|
15
15
|
import { createDaemonControlDispatch } from "../control-dispatch.js";
|
|
16
16
|
import { prepareDaemonBootstrap } from "../daemon-bootstrap-preflight.js";
|
|
17
17
|
import { createDaemonControlHandlers } from "../daemon-control-handlers.js";
|
|
18
|
-
import {
|
|
19
|
-
import {
|
|
18
|
+
import { DaemonEnv } from "../daemon-env-context.js";
|
|
19
|
+
import { DaemonHost } from "../daemon-host-context.js";
|
|
20
|
+
import { canonicalConfigDocument, redactedProcessArgs } from "../daemon-maintenance.js";
|
|
21
|
+
import { DaemonPolicy, wantsCliproxySidecar } from "../daemon-policy-context.js";
|
|
20
22
|
import { healthyControl, removeDaemonPublicRecord, workloadJwtOptions, writeDaemonPublicRecord, writeDaemonRevisions } from "../daemon-state.js";
|
|
21
|
-
import {
|
|
23
|
+
import { DaemonState } from "../daemon-state-context.js";
|
|
24
|
+
import { DataPlane } from "../data-plane-context.js";
|
|
25
|
+
import { makeEvalSessionExecutionStore } from "../eval-session-execution-store.js";
|
|
22
26
|
import { LeaderboardRollupStore } from "../leaderboard.js";
|
|
23
|
-
import {
|
|
27
|
+
import { Leaderboard } from "../leaderboard-context.js";
|
|
24
28
|
import { ActiveGateway } from "../services/active-gateway/service.js";
|
|
25
29
|
import { CallAttributions } from "../services/call-attributions/service.js";
|
|
26
|
-
import { DaemonEnv } from "../daemon-env-context.js";
|
|
27
|
-
import { DaemonHost } from "../daemon-host-context.js";
|
|
28
|
-
import { DaemonPolicy } from "../daemon-policy-context.js";
|
|
29
30
|
import { DaemonRuntime } from "../services/daemon-runtime/service.js";
|
|
30
|
-
import { DaemonState } from "../daemon-state-context.js";
|
|
31
|
-
import { DataPlane } from "../data-plane-context.js";
|
|
32
31
|
import { EvalSessions } from "../services/eval-session/service.js";
|
|
33
32
|
import { Generations } from "../services/generations/service.js";
|
|
34
33
|
import { LauncherSessions } from "../services/launcher-session/service.js";
|
|
35
|
-
import { Leaderboard } from "../leaderboard-context.js";
|
|
36
|
-
import { Sidecar } from "../sidecar-context.js";
|
|
37
34
|
import { Telemetry } from "../services/telemetry/service.js";
|
|
38
35
|
import { Tokens } from "../services/tokens/service.js";
|
|
36
|
+
import { Sidecar } from "../sidecar-context.js";
|
|
39
37
|
const ROUTEKIT_DAEMON_KIND = "daemon";
|
|
40
38
|
const ROUTEKIT_PRODUCT = "routekit";
|
|
41
39
|
class DaemonFoundation extends Context.Service()("@velum-labs/routekit-daemon/DaemonFoundation") {
|
|
@@ -73,37 +71,6 @@ const prepareFoundation = (options) => Effect.acquireRelease(Effect.tryPromise({
|
|
|
73
71
|
}), (foundation) => Effect.sync(() => {
|
|
74
72
|
foundation.authority?.release();
|
|
75
73
|
}));
|
|
76
|
-
const wantsSidecar = (config) => config.providers.cliproxy !== undefined;
|
|
77
|
-
const activeCredentialFingerprints = (env) => new Map(accountEntriesWithPaths(env).flatMap((entry) => entry.connector === "native"
|
|
78
|
-
? [
|
|
79
|
-
[
|
|
80
|
-
subscriptionAccountIdentity(entry.subscriptionKind, entry.label),
|
|
81
|
-
subscriptionCredentialFingerprint(entry.path)
|
|
82
|
-
]
|
|
83
|
-
]
|
|
84
|
-
: []));
|
|
85
|
-
const routerEnv = (env) => {
|
|
86
|
-
const injected = { ...env };
|
|
87
|
-
if ((env[CLIPROXY_API_KEY_ENV] ?? "").length === 0) {
|
|
88
|
-
const key = cliproxyApiKey(env);
|
|
89
|
-
if (key !== undefined)
|
|
90
|
-
injected[CLIPROXY_API_KEY_ENV] = key;
|
|
91
|
-
}
|
|
92
|
-
if ((env[CLIPROXY_BASE_URL_ENV] ?? "").length === 0) {
|
|
93
|
-
injected[CLIPROXY_BASE_URL_ENV] = cliproxyBaseUrl(env);
|
|
94
|
-
}
|
|
95
|
-
return injected;
|
|
96
|
-
};
|
|
97
|
-
function promiseHandlers(handlers, context) {
|
|
98
|
-
return new Proxy(handlers, {
|
|
99
|
-
get(target, method, receiver) {
|
|
100
|
-
const handler = Reflect.get(target, method, receiver);
|
|
101
|
-
if (typeof handler !== "function")
|
|
102
|
-
return handler;
|
|
103
|
-
return (params, handlerContext) => Effect.runPromiseWith(context)(withAbortSignal(handler(params, handlerContext), handlerContext.signal));
|
|
104
|
-
}
|
|
105
|
-
});
|
|
106
|
-
}
|
|
107
74
|
const acquireRunningDaemon = Effect.fn("Daemon.acquireRunning")(function* (options) {
|
|
108
75
|
const foundation = yield* DaemonFoundation;
|
|
109
76
|
const state = yield* DaemonState;
|
|
@@ -116,16 +83,15 @@ const acquireRunningDaemon = Effect.fn("Daemon.acquireRunning")(function* (optio
|
|
|
116
83
|
const telemetry = yield* Telemetry;
|
|
117
84
|
const auth = yield* AccountAuth;
|
|
118
85
|
const context = yield* Effect.context();
|
|
119
|
-
const provideRuntime = (effect) => effect.pipe(Effect.provide(context));
|
|
120
86
|
yield* Effect.addFinalizer(() => Effect.sync(() => foundation.runtimeState.markClosed()));
|
|
121
|
-
yield* sidecar.reconcile(
|
|
87
|
+
yield* sidecar.reconcile(wantsCliproxySidecar(state.config));
|
|
122
88
|
const router = yield* generations.start(state.config);
|
|
123
89
|
yield* Ref.update(gateway.state, (current) => ({ ...current, router }));
|
|
124
90
|
yield* Effect.addFinalizer(() => {
|
|
125
91
|
const active = gateway.router();
|
|
126
92
|
return active === undefined ? Effect.void : active.close.pipe(Effect.ignore);
|
|
127
93
|
});
|
|
128
|
-
yield* auth.reconcileActiveCredentials(activeCredentialFingerprints(
|
|
94
|
+
yield* auth.reconcileActiveCredentials(router.activeCredentialFingerprints());
|
|
129
95
|
const workloadJwt = workloadJwtOptions(options.workloadJwt, foundation.env);
|
|
130
96
|
const verifyWorkloadJwt = workloadJwt === undefined ? undefined : createWorkloadJwtVerifier(workloadJwt);
|
|
131
97
|
const proxy = yield* startSwitchingGatewayProxyEffect({
|
|
@@ -134,6 +100,7 @@ const acquireRunningDaemon = Effect.fn("Daemon.acquireRunning")(function* (optio
|
|
|
134
100
|
host: options.host ?? "127.0.0.1",
|
|
135
101
|
port: options.port ?? 8080,
|
|
136
102
|
authToken: tokens.dataAuth.token,
|
|
103
|
+
bindEvalSubmission: (sessionId, request) => evalSessions.bindIngress(sessionId, request),
|
|
137
104
|
resolveDataPrincipal: (presented) => {
|
|
138
105
|
const launcherPrincipal = launcherSessions.resolve(presented);
|
|
139
106
|
if (launcherPrincipal !== undefined)
|
|
@@ -164,7 +131,7 @@ const acquireRunningDaemon = Effect.fn("Daemon.acquireRunning")(function* (optio
|
|
|
164
131
|
const dataUrl = foundation.hosted?.dataUrl() ??
|
|
165
132
|
(portless?.enabled === true ? portless.register("gateway", proxy.port()) : proxy.url());
|
|
166
133
|
yield* Ref.update(gateway.state, (current) => ({ ...current, proxy, dataUrl }));
|
|
167
|
-
const handlers =
|
|
134
|
+
const handlers = toPromiseControlHandlers(createDaemonControlHandlers(), context);
|
|
168
135
|
const dispatch = createDaemonControlDispatch({
|
|
169
136
|
handlers,
|
|
170
137
|
runtimeState: foundation.runtimeState,
|
|
@@ -197,16 +164,17 @@ const acquireRunningDaemon = Effect.fn("Daemon.acquireRunning")(function* (optio
|
|
|
197
164
|
});
|
|
198
165
|
yield* Effect.addFinalizer(() => control.close.pipe(Effect.ignore));
|
|
199
166
|
yield* Ref.update(gateway.state, (current) => ({ ...current, control }));
|
|
167
|
+
const identity = processIdentity(process.pid);
|
|
168
|
+
const supervisor = supervisorFromEnv(foundation.env);
|
|
200
169
|
const recordInput = {
|
|
201
170
|
kind: ROUTEKIT_DAEMON_KIND,
|
|
202
171
|
pid: process.pid,
|
|
203
|
-
...(
|
|
204
|
-
? {}
|
|
205
|
-
: { processIdentity: processIdentity(process.pid) }),
|
|
172
|
+
...(identity === undefined ? {} : { processIdentity: identity }),
|
|
206
173
|
url: control.url,
|
|
207
174
|
port: control.port,
|
|
208
175
|
startedAt: foundation.startedAt,
|
|
209
176
|
version: options.packageVersion,
|
|
177
|
+
...(options.sourceBuildId === undefined ? {} : { sourceBuildId: options.sourceBuildId }),
|
|
210
178
|
protocolVersion: CONTROL_PROTOCOL_VERSION,
|
|
211
179
|
controlToken: control.token,
|
|
212
180
|
dataUrl,
|
|
@@ -216,7 +184,7 @@ const acquireRunningDaemon = Effect.fn("Daemon.acquireRunning")(function* (optio
|
|
|
216
184
|
drainGraceMs: foundation.drainGraceMs,
|
|
217
185
|
authTokenFile: tokens.dataAuth.path,
|
|
218
186
|
generation: foundation.generation,
|
|
219
|
-
supervisor
|
|
187
|
+
supervisor,
|
|
220
188
|
...(process.argv[1] === undefined ? {} : { binPath: process.argv[1] }),
|
|
221
189
|
args: redactedProcessArgs(process.argv.slice(2)),
|
|
222
190
|
cwd: process.cwd()
|
|
@@ -241,31 +209,28 @@ const acquireRunningDaemon = Effect.fn("Daemon.acquireRunning")(function* (optio
|
|
|
241
209
|
removeDaemonPublicRecord(foundation.home);
|
|
242
210
|
}));
|
|
243
211
|
}
|
|
244
|
-
|
|
245
|
-
action: "started",
|
|
212
|
+
const lifecycleProperties = {
|
|
246
213
|
outcome: "success",
|
|
247
|
-
supervisor
|
|
248
|
-
? supervisorFromEnv(foundation.env)
|
|
249
|
-
: "unknown",
|
|
214
|
+
supervisor,
|
|
250
215
|
version: options.packageVersion
|
|
216
|
+
};
|
|
217
|
+
telemetry.daemon.capture("routekit.daemon_lifecycle", {
|
|
218
|
+
...lifecycleProperties,
|
|
219
|
+
action: "started"
|
|
251
220
|
});
|
|
252
221
|
const prepareClose = Effect.gen(function* () {
|
|
253
222
|
foundation.runtimeState.beginShutdown();
|
|
254
|
-
yield* foundation.runtimeState.awaitMutations
|
|
223
|
+
yield* foundation.runtimeState.awaitMutations;
|
|
255
224
|
telemetry.daemon.capture("routekit.daemon_lifecycle", {
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
supervisor: ["systemd", "launchd", "detached"].includes(supervisorFromEnv(foundation.env))
|
|
259
|
-
? supervisorFromEnv(foundation.env)
|
|
260
|
-
: "unknown",
|
|
261
|
-
version: options.packageVersion
|
|
225
|
+
...lifecycleProperties,
|
|
226
|
+
action: "stopped"
|
|
262
227
|
});
|
|
263
228
|
foundation.runtimeState.markDraining();
|
|
264
229
|
yield* proxy.drain(foundation.drainGraceMs);
|
|
265
230
|
});
|
|
266
231
|
const prepareRetire = (graceMs = foundation.drainGraceMs) => Effect.gen(function* () {
|
|
267
232
|
foundation.runtimeState.beginRetire();
|
|
268
|
-
yield* foundation.runtimeState.awaitMutations
|
|
233
|
+
yield* foundation.runtimeState.awaitMutations;
|
|
269
234
|
foundation.runtimeState.markDraining();
|
|
270
235
|
yield* Effect.all([proxy.retire(graceMs), control.retire(Math.min(graceMs, 2_000))], {
|
|
271
236
|
concurrency: "unbounded"
|
|
@@ -282,20 +247,19 @@ const acquireRunningDaemon = Effect.fn("Daemon.acquireRunning")(function* (optio
|
|
|
282
247
|
record,
|
|
283
248
|
dataUrl,
|
|
284
249
|
controlUrl: control.url,
|
|
285
|
-
prepareClose
|
|
286
|
-
prepareRetire
|
|
287
|
-
pauseMutations:
|
|
250
|
+
prepareClose,
|
|
251
|
+
prepareRetire,
|
|
252
|
+
pauseMutations: Effect.gen(function* () {
|
|
288
253
|
foundation.runtimeState.pause();
|
|
289
|
-
yield* foundation.runtimeState.awaitMutations
|
|
254
|
+
yield* foundation.runtimeState.awaitMutations;
|
|
290
255
|
return foundation.runtimeState.snapshot();
|
|
291
|
-
})
|
|
292
|
-
resumeMutations:
|
|
293
|
-
snapshot:
|
|
294
|
-
reload:
|
|
256
|
+
}),
|
|
257
|
+
resumeMutations: Effect.sync(() => foundation.runtimeState.resume()),
|
|
258
|
+
snapshot: Effect.sync(() => foundation.runtimeState.snapshot()),
|
|
259
|
+
reload: Effect.provide(reload, context)
|
|
295
260
|
});
|
|
296
261
|
});
|
|
297
|
-
|
|
298
|
-
export function daemonLive(options) {
|
|
262
|
+
function daemonLayers(options) {
|
|
299
263
|
const foundation = Layer.effect(DaemonFoundation, prepareFoundation(options));
|
|
300
264
|
const platform = RouteKitLive.pipe(Layer.provideMerge(foundation));
|
|
301
265
|
const owned = Layer.mergeAll(Layer.effect(Sidecar, Effect.flatMap(DaemonFoundation, (value) => Effect.acquireRelease(Effect.sync(() => value.hosted === undefined
|
|
@@ -328,7 +292,11 @@ export function daemonLive(options) {
|
|
|
328
292
|
});
|
|
329
293
|
}
|
|
330
294
|
});
|
|
331
|
-
}), (leaderboard) => Effect.sync(() => leaderboard.rollups.flush())))),
|
|
295
|
+
}), (leaderboard) => Effect.sync(() => leaderboard.rollups.flush())))), Layer.unwrap(Effect.gen(function* () {
|
|
296
|
+
const foundation = yield* DaemonFoundation;
|
|
297
|
+
const store = yield* makeEvalSessionExecutionStore(join(foundation.home, "eval-sessions", "execution-v1"));
|
|
298
|
+
return EvalSessions.layer({ store });
|
|
299
|
+
})), LauncherSessions.layer()).pipe(Layer.provideMerge(platform));
|
|
332
300
|
const staticServices = Layer.mergeAll(Layer.effect(DaemonEnv, Effect.map(DaemonFoundation, (value) => DaemonEnv.of({
|
|
333
301
|
home: value.home,
|
|
334
302
|
configPath: value.configPath,
|
|
@@ -340,7 +308,7 @@ export function daemonLive(options) {
|
|
|
340
308
|
}))), Layer.unwrap(Effect.map(DaemonFoundation, (value) => DaemonState.layer(value.runtimeState))), Layer.effect(DataPlane, Effect.map(Tokens, (tokens) => ({
|
|
341
309
|
token: tokens.dataAuth.token,
|
|
342
310
|
path: tokens.dataAuth.path
|
|
343
|
-
}))), Layer.effect(AccountRecovery, Effect.map(DaemonFoundation, (value) => value.accountRecovery)), Layer.unwrap(Effect.map(DaemonFoundation, (value) => CallAttributions.layer(resolveLeaderboardConfig(value.runtimeState.config)))), Layer.
|
|
311
|
+
}))), Layer.effect(AccountRecovery, Effect.map(DaemonFoundation, (value) => value.accountRecovery)), Layer.unwrap(Effect.map(DaemonFoundation, (value) => CallAttributions.layer(resolveLeaderboardConfig(value.runtimeState.config)))), Layer.succeed(DaemonPolicy, { wantsCliproxySidecar }), Layer.effect(DaemonHost, Effect.map(DaemonFoundation, (value) => ({
|
|
344
312
|
...(options.onShutdownRequested === undefined
|
|
345
313
|
? {}
|
|
346
314
|
: {
|
|
@@ -358,61 +326,15 @@ export function daemonLive(options) {
|
|
|
358
326
|
? {}
|
|
359
327
|
: { onAccountTransactionPhase: options.onAccountTransactionPhase })
|
|
360
328
|
}))), ActiveGateway.layer, Layer.unwrap(Effect.map(DaemonFoundation, (value) => AccountActivity.layer({ statePath: join(value.home, "usage", "account-activity.v1.json") }))), Layer.unwrap(Effect.map(DaemonFoundation, (value) => AccountAuth.layer({ statePath: join(value.home, "subscriptions", "account-auth.v1.json") })))).pipe(Layer.provideMerge(owned));
|
|
361
|
-
const generations = Layer.
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
configPath: foundation.configPath,
|
|
373
|
-
home: foundation.home,
|
|
374
|
-
drainGraceMs: foundation.drainGraceMs,
|
|
375
|
-
sidecar,
|
|
376
|
-
routerEnv: () => routerEnv(foundation.env),
|
|
377
|
-
provenance: {
|
|
378
|
-
onModelCall(record) {
|
|
379
|
-
callAttributions.onModelCall(record);
|
|
380
|
-
const inspection = callInspection(record);
|
|
381
|
-
if (inspection !== undefined)
|
|
382
|
-
leaderboard.rollups.record(inspection);
|
|
383
|
-
telemetry.gateway.record(record);
|
|
384
|
-
}
|
|
385
|
-
},
|
|
386
|
-
compositionalPolicyReader: makeCompositionalRoutingPolicyReader(foundation.home),
|
|
387
|
-
activity,
|
|
388
|
-
authHealth: auth,
|
|
389
|
-
wantsSidecar,
|
|
390
|
-
getCurrentConfig: () => state.config,
|
|
391
|
-
setCurrentConfig: (config) => {
|
|
392
|
-
state.config = config;
|
|
393
|
-
},
|
|
394
|
-
getCurrentDocument: () => state.document,
|
|
395
|
-
setCurrentDocument: (document) => {
|
|
396
|
-
state.document = document;
|
|
397
|
-
},
|
|
398
|
-
getRevisions: () => state.revisions,
|
|
399
|
-
setRevisions: (revisions) => {
|
|
400
|
-
state.revisions = revisions;
|
|
401
|
-
},
|
|
402
|
-
getActiveRouter: () => gateway.router(),
|
|
403
|
-
setActiveRouter: (router) => Ref.update(gateway.state, (current) => ({ ...current, router })),
|
|
404
|
-
getProxy: () => gateway.proxy(),
|
|
405
|
-
activeCredentialFingerprints: () => activeCredentialFingerprints(foundation.env),
|
|
406
|
-
applyConfig: (config) => {
|
|
407
|
-
leaderboard.applyConfig(config);
|
|
408
|
-
const current = leaderboard.config();
|
|
409
|
-
callAttributions.configureBudget({
|
|
410
|
-
limit: current.liveLimit,
|
|
411
|
-
ttlMs: current.liveTtlHours * 60 * 60 * 1_000
|
|
412
|
-
});
|
|
413
|
-
},
|
|
414
|
-
...(options.onGenerationStage === undefined ? {} : { onStage: options.onGenerationStage })
|
|
415
|
-
});
|
|
416
|
-
})).pipe(Layer.provideMerge(staticServices));
|
|
417
|
-
return Layer.effect(DaemonRuntime, acquireRunningDaemon(options)).pipe(Layer.provideMerge(generations));
|
|
329
|
+
const generations = Layer.unwrap(Effect.map(DaemonFoundation, (foundation) => Generations.layer({
|
|
330
|
+
drainGraceMs: foundation.drainGraceMs,
|
|
331
|
+
...(options.onGenerationStage === undefined ? {} : { onStage: options.onGenerationStage })
|
|
332
|
+
}))).pipe(Layer.provideMerge(staticServices));
|
|
333
|
+
return generations;
|
|
334
|
+
}
|
|
335
|
+
/** Construct and own the complete daemon worker lifetime. */
|
|
336
|
+
export function daemonLive(options) {
|
|
337
|
+
// The published service union deliberately excludes platform/foundation and
|
|
338
|
+
// private launcher credentials. Runtime composition still owns all of them.
|
|
339
|
+
return Layer.effect(DaemonRuntime, acquireRunningDaemon(options)).pipe(Layer.provideMerge(daemonLayers(options)));
|
|
418
340
|
}
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import type { EffectRouteKitControlHandlers } from "@velum-labs/routekit-control/effect";
|
|
2
2
|
type EvalRoutingHandlers = Pick<EffectRouteKitControlHandlers, "evalRouting.status" | "evalRouting.activate" | "evalRouting.installAuthoritative" | "evalRouting.rollbackAuthoritative">;
|
|
3
3
|
/** Owns target-local compositional routing status and atomic activation. */
|
|
4
|
-
export declare
|
|
5
|
-
handlers(): EvalRoutingHandlers;
|
|
6
|
-
}
|
|
4
|
+
export declare const evalRoutingHandlers: EvalRoutingHandlers;
|
|
7
5
|
export {};
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { DEFAULT_CLASSIFIER_MODEL } from "@velum-labs/routekit-config";
|
|
2
|
-
import { AnyPublishedRoutingActivation, assertPublishedRoutingActivation, assertPublishedRoutingActivationV3 } from "@velum-labs/routekit-eval-contracts";
|
|
3
2
|
import { makeRoutingActivationStore, RoutingActivationConflictError, RoutingDeploymentConflictError } from "@velum-labs/routekit-eval-store/effect";
|
|
4
3
|
import { ControlError } from "@velum-labs/routekit-runtime/control";
|
|
5
|
-
import { Effect
|
|
4
|
+
import { Effect } from "effect";
|
|
6
5
|
import { DaemonEnv } from "./daemon-env-context.js";
|
|
7
6
|
import { DaemonState } from "./daemon-state-context.js";
|
|
8
7
|
import { evalRoutingSnapshotDirectory } from "./eval-routing-policy.js";
|
|
@@ -20,26 +19,6 @@ function identity(revision) {
|
|
|
20
19
|
evidenceDigest: revision.activation.evidenceDigest
|
|
21
20
|
};
|
|
22
21
|
}
|
|
23
|
-
function decodeAnyActivation(value) {
|
|
24
|
-
return Schema.decodeUnknownEffect(AnyPublishedRoutingActivation)(value).pipe(Effect.flatMap((activation) => Effect.try({
|
|
25
|
-
try: () => {
|
|
26
|
-
if (activation.version === 2)
|
|
27
|
-
assertPublishedRoutingActivation(activation);
|
|
28
|
-
else
|
|
29
|
-
assertPublishedRoutingActivationV3(activation);
|
|
30
|
-
return activation;
|
|
31
|
-
},
|
|
32
|
-
catch: (cause) => new ControlError({
|
|
33
|
-
code: "bad_request",
|
|
34
|
-
message: `routing activation is invalid: ${detailOf(cause)}`
|
|
35
|
-
})
|
|
36
|
-
})), Effect.mapError((cause) => cause instanceof ControlError
|
|
37
|
-
? cause
|
|
38
|
-
: new ControlError({
|
|
39
|
-
code: "bad_request",
|
|
40
|
-
message: `routing activation is invalid: ${detailOf(cause)}`
|
|
41
|
-
})));
|
|
42
|
-
}
|
|
43
22
|
const mapStoreError = (operation) => (cause) => cause instanceof RoutingActivationConflictError ||
|
|
44
23
|
cause instanceof RoutingDeploymentConflictError
|
|
45
24
|
? new ControlError({ code: "conflict", message: cause.message })
|
|
@@ -47,6 +26,7 @@ const mapStoreError = (operation) => (cause) => cause instanceof RoutingActivati
|
|
|
47
26
|
code: "internal",
|
|
48
27
|
message: `failed to ${operation}: ${detailOf(cause)}`
|
|
49
28
|
});
|
|
29
|
+
const routingStore = Effect.map(DaemonEnv, ({ home }) => makeRoutingActivationStore(evalRoutingSnapshotDirectory(home)));
|
|
50
30
|
function validateRuntimeCompatibility(activation) {
|
|
51
31
|
return Effect.gen(function* () {
|
|
52
32
|
const state = yield* DaemonState;
|
|
@@ -89,52 +69,48 @@ function validateRuntimeCompatibility(activation) {
|
|
|
89
69
|
});
|
|
90
70
|
}
|
|
91
71
|
/** Owns target-local compositional routing status and atomic activation. */
|
|
92
|
-
export
|
|
93
|
-
|
|
72
|
+
export const evalRoutingHandlers = {
|
|
73
|
+
"evalRouting.status": () => Effect.gen(function* () {
|
|
74
|
+
const store = yield* routingStore;
|
|
75
|
+
const deployment = yield* store
|
|
76
|
+
.readDeployment()
|
|
77
|
+
.pipe(Effect.mapError(mapStoreError("read routing deployment")));
|
|
94
78
|
return {
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
.readDeployment()
|
|
99
|
-
.pipe(Effect.mapError(mapStoreError("read routing deployment")));
|
|
100
|
-
return {
|
|
101
|
-
stateRevision: deployment.stateRevision,
|
|
102
|
-
authoritative: identity(deployment.authoritative),
|
|
103
|
-
previousAuthoritative: identity(deployment.previousAuthoritative)
|
|
104
|
-
};
|
|
105
|
-
}),
|
|
106
|
-
"evalRouting.activate": (params) => Effect.fail(new ControlError({
|
|
107
|
-
code: "bad_request",
|
|
108
|
-
message: "Classification V2 activation is rollback-only; install a qualified Classification V3 activation or restore the retained V2 revision with evalRouting.rollbackAuthoritative"
|
|
109
|
-
})),
|
|
110
|
-
"evalRouting.installAuthoritative": (params) => Effect.gen(function* () {
|
|
111
|
-
const env = yield* DaemonEnv;
|
|
112
|
-
const activation = yield* makeRoutingActivationStore(evalRoutingSnapshotDirectory(env.home))
|
|
113
|
-
.readActivation(params.activationPath)
|
|
114
|
-
.pipe(Effect.mapError(mapStoreError("read authoritative routing policy")));
|
|
115
|
-
yield* validateRuntimeCompatibility(activation);
|
|
116
|
-
const deployment = yield* makeRoutingActivationStore(evalRoutingSnapshotDirectory(env.home))
|
|
117
|
-
.installAuthoritative(activation, params.activationPath, params.expectedAuthoritativeRevisionDigest, params.expectedPreviousAuthoritativeRevisionDigest)
|
|
118
|
-
.pipe(Effect.mapError(mapStoreError("install authoritative routing policy")));
|
|
119
|
-
return {
|
|
120
|
-
installed: true,
|
|
121
|
-
stateRevision: deployment.stateRevision,
|
|
122
|
-
authoritative: identity(deployment.authoritative),
|
|
123
|
-
previousAuthoritative: identity(deployment.previousAuthoritative)
|
|
124
|
-
};
|
|
125
|
-
}),
|
|
126
|
-
"evalRouting.rollbackAuthoritative": (params) => Effect.gen(function* () {
|
|
127
|
-
const env = yield* DaemonEnv;
|
|
128
|
-
const deployment = yield* makeRoutingActivationStore(evalRoutingSnapshotDirectory(env.home))
|
|
129
|
-
.rollbackAuthoritative(params.expectedAuthoritativeRevisionDigest, params.expectedPreviousAuthoritativeRevisionDigest)
|
|
130
|
-
.pipe(Effect.mapError(mapStoreError("roll back authoritative routing policy")));
|
|
131
|
-
return {
|
|
132
|
-
rolledBack: true,
|
|
133
|
-
stateRevision: deployment.stateRevision,
|
|
134
|
-
authoritative: identity(deployment.authoritative),
|
|
135
|
-
previousAuthoritative: identity(deployment.previousAuthoritative)
|
|
136
|
-
};
|
|
137
|
-
})
|
|
79
|
+
stateRevision: deployment.stateRevision,
|
|
80
|
+
authoritative: identity(deployment.authoritative),
|
|
81
|
+
previousAuthoritative: identity(deployment.previousAuthoritative)
|
|
138
82
|
};
|
|
139
|
-
}
|
|
140
|
-
|
|
83
|
+
}),
|
|
84
|
+
"evalRouting.activate": () => Effect.fail(new ControlError({
|
|
85
|
+
code: "bad_request",
|
|
86
|
+
message: "Classification V2 activation is rollback-only; install a qualified Classification V3 activation or restore the retained V2 revision with evalRouting.rollbackAuthoritative"
|
|
87
|
+
})),
|
|
88
|
+
"evalRouting.installAuthoritative": (params) => Effect.gen(function* () {
|
|
89
|
+
const store = yield* routingStore;
|
|
90
|
+
const activation = yield* store
|
|
91
|
+
.readActivation(params.activationPath)
|
|
92
|
+
.pipe(Effect.mapError(mapStoreError("read authoritative routing policy")));
|
|
93
|
+
yield* validateRuntimeCompatibility(activation);
|
|
94
|
+
const deployment = yield* store
|
|
95
|
+
.installAuthoritative(activation, params.activationPath, params.expectedAuthoritativeRevisionDigest, params.expectedPreviousAuthoritativeRevisionDigest)
|
|
96
|
+
.pipe(Effect.mapError(mapStoreError("install authoritative routing policy")));
|
|
97
|
+
return {
|
|
98
|
+
installed: true,
|
|
99
|
+
stateRevision: deployment.stateRevision,
|
|
100
|
+
authoritative: identity(deployment.authoritative),
|
|
101
|
+
previousAuthoritative: identity(deployment.previousAuthoritative)
|
|
102
|
+
};
|
|
103
|
+
}),
|
|
104
|
+
"evalRouting.rollbackAuthoritative": (params) => Effect.gen(function* () {
|
|
105
|
+
const store = yield* routingStore;
|
|
106
|
+
const deployment = yield* store
|
|
107
|
+
.rollbackAuthoritative(params.expectedAuthoritativeRevisionDigest, params.expectedPreviousAuthoritativeRevisionDigest)
|
|
108
|
+
.pipe(Effect.mapError(mapStoreError("roll back authoritative routing policy")));
|
|
109
|
+
return {
|
|
110
|
+
rolledBack: true,
|
|
111
|
+
stateRevision: deployment.stateRevision,
|
|
112
|
+
authoritative: identity(deployment.authoritative),
|
|
113
|
+
previousAuthoritative: identity(deployment.previousAuthoritative)
|
|
114
|
+
};
|
|
115
|
+
})
|
|
116
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { EvalSessionExecutionEvidence } from "@velum-labs/routekit-control";
|
|
2
|
+
import { HttpSubmissionError } from "@velum-labs/routekit-runtime/effect";
|
|
3
|
+
import { Effect, FileSystem, Path } from "effect";
|
|
4
|
+
export type EvalSessionExecutionStore = {
|
|
5
|
+
readonly directory: string;
|
|
6
|
+
readonly create: (evidence: EvalSessionExecutionEvidence) => Effect.Effect<EvalSessionExecutionEvidence, HttpSubmissionError>;
|
|
7
|
+
readonly read: (executionDigest: string, sessionId?: string) => Effect.Effect<EvalSessionExecutionEvidence | undefined, HttpSubmissionError>;
|
|
8
|
+
readonly update: (executionDigest: string, update: (current: EvalSessionExecutionEvidence) => EvalSessionExecutionEvidence, options?: {
|
|
9
|
+
readonly allowReadinessReopen?: boolean;
|
|
10
|
+
}) => Effect.Effect<EvalSessionExecutionEvidence, HttpSubmissionError>;
|
|
11
|
+
readonly recover: (now: string) => Effect.Effect<readonly EvalSessionExecutionEvidence[], HttpSubmissionError>;
|
|
12
|
+
};
|
|
13
|
+
/** Derive closure without ever converting a pending or unknown receipt to success. */
|
|
14
|
+
export declare function normalizeExecutionEvidence(evidence: EvalSessionExecutionEvidence): EvalSessionExecutionEvidence;
|
|
15
|
+
/**
|
|
16
|
+
* Private payload-free authority store. Each operation reads current durable
|
|
17
|
+
* state under the existing process-identity lifecycle lock before an atomic
|
|
18
|
+
* replacement. A retiring worker therefore cannot overwrite a successor's
|
|
19
|
+
* revocation, recovered unknown receipt, or consumed execution identity.
|
|
20
|
+
*
|
|
21
|
+
* The lock is transaction-scoped, not another gateway/request resource owner.
|
|
22
|
+
* Atomic rename covers interruption and reported I/O faults, not power loss.
|
|
23
|
+
*/
|
|
24
|
+
export declare const makeEvalSessionExecutionStore: (inputDirectory: string) => Effect.Effect<EvalSessionExecutionStore, HttpSubmissionError, FileSystem.FileSystem | Path.Path>;
|