@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.
Files changed (172) hide show
  1. package/dist/account-enroll-service.d.ts +1 -3
  2. package/dist/account-enroll-service.js +262 -262
  3. package/dist/account-mutation-service.d.ts +1 -3
  4. package/dist/account-mutation-service.js +302 -283
  5. package/dist/account-query-service.d.ts +1 -3
  6. package/dist/account-query-service.js +88 -86
  7. package/dist/call-attribution-store.js +544 -1
  8. package/dist/control-dispatch.js +9 -15
  9. package/dist/daemon-bootstrap-preflight.js +1 -1
  10. package/dist/daemon-control-handlers.d.ts +1 -1
  11. package/dist/daemon-control-handlers.js +24 -27
  12. package/dist/daemon-generations.d.ts +14 -28
  13. package/dist/daemon-generations.js +114 -53
  14. package/dist/daemon-lifecycle-service.d.ts +1 -3
  15. package/dist/daemon-lifecycle-service.js +88 -94
  16. package/dist/daemon-maintenance.d.ts +27 -49
  17. package/dist/daemon-maintenance.js +5 -1
  18. package/dist/daemon-options.d.ts +3 -2
  19. package/dist/daemon-policy-context.d.ts +1 -0
  20. package/dist/daemon-policy-context.js +1 -0
  21. package/dist/daemon-runtime-state.d.ts +1 -1
  22. package/dist/daemon-runtime-state.js +2 -3
  23. package/dist/daemon-state-context.d.ts +1 -1
  24. package/dist/daemon-state-context.js +1 -38
  25. package/dist/doctor-service.d.ts +1 -3
  26. package/dist/doctor-service.js +87 -91
  27. package/dist/effect/daemon-live.d.ts +7 -6
  28. package/dist/effect/daemon-live.js +57 -135
  29. package/dist/eval-routing-service.d.ts +1 -3
  30. package/dist/eval-routing-service.js +45 -69
  31. package/dist/eval-session-execution-store.d.ts +24 -0
  32. package/dist/eval-session-execution-store.js +253 -0
  33. package/dist/host-protocol.d.ts +1 -0
  34. package/dist/host.js +3 -0
  35. package/dist/internal-providers/provider-anthropic/index.d.ts +23 -0
  36. package/dist/internal-providers/provider-anthropic/index.js +42 -0
  37. package/dist/internal-providers/provider-anthropic/test/provider.test.js +33 -0
  38. package/dist/internal-providers/provider-azure/index.d.ts +25 -0
  39. package/dist/internal-providers/provider-azure/index.js +101 -0
  40. package/dist/internal-providers/provider-azure/test/provider.test.js +83 -0
  41. package/dist/internal-providers/provider-bedrock/codec.d.ts +11 -0
  42. package/dist/internal-providers/provider-bedrock/codec.js +484 -0
  43. package/dist/internal-providers/provider-bedrock/connection-settings.d.ts +6 -0
  44. package/dist/internal-providers/provider-bedrock/connection-settings.js +41 -0
  45. package/dist/internal-providers/provider-bedrock/connection.d.ts +17 -0
  46. package/dist/internal-providers/provider-bedrock/connection.js +143 -0
  47. package/dist/internal-providers/provider-bedrock/index.d.ts +27 -0
  48. package/dist/internal-providers/provider-bedrock/index.js +47 -0
  49. package/dist/internal-providers/provider-bedrock/source.d.ts +39 -0
  50. package/dist/internal-providers/provider-bedrock/source.js +454 -0
  51. package/dist/internal-providers/provider-bedrock/test/bedrock-source.test.d.ts +1 -0
  52. package/dist/internal-providers/provider-bedrock/test/bedrock-source.test.js +786 -0
  53. package/dist/internal-providers/provider-bedrock/test/connection.test.d.ts +1 -0
  54. package/dist/internal-providers/provider-bedrock/test/connection.test.js +249 -0
  55. package/dist/internal-providers/provider-bedrock/test/workload-credentials.test.d.ts +1 -0
  56. package/dist/internal-providers/provider-bedrock/test/workload-credentials.test.js +29 -0
  57. package/dist/internal-providers/provider-bedrock/workload-credentials.d.ts +5 -0
  58. package/dist/internal-providers/provider-bedrock/workload-credentials.js +14 -0
  59. package/dist/internal-providers/provider-claude-code/index.d.ts +6 -0
  60. package/dist/internal-providers/provider-claude-code/index.js +4 -0
  61. package/dist/internal-providers/provider-claude-code/module-api.d.ts +25 -0
  62. package/dist/internal-providers/provider-claude-code/module-api.js +31 -0
  63. package/dist/internal-providers/provider-claude-code/relay.d.ts +20 -0
  64. package/dist/internal-providers/provider-claude-code/relay.js +115 -0
  65. package/dist/internal-providers/provider-claude-code/subscription.d.ts +2 -0
  66. package/dist/internal-providers/provider-claude-code/subscription.js +194 -0
  67. package/dist/internal-providers/provider-claude-code/test/http-submission.test.d.ts +1 -0
  68. package/dist/internal-providers/provider-claude-code/test/http-submission.test.js +140 -0
  69. package/dist/internal-providers/provider-claude-code/test/relay.test.d.ts +1 -0
  70. package/dist/internal-providers/provider-claude-code/test/relay.test.js +379 -0
  71. package/dist/internal-providers/provider-claude-code/test/subscription.test.d.ts +1 -0
  72. package/dist/internal-providers/provider-claude-code/test/subscription.test.js +256 -0
  73. package/dist/internal-providers/provider-cliproxy/index.d.ts +9 -0
  74. package/dist/internal-providers/provider-cliproxy/index.js +15 -0
  75. package/dist/internal-providers/provider-codex/index.d.ts +6 -0
  76. package/dist/internal-providers/provider-codex/index.js +7 -0
  77. package/dist/internal-providers/provider-codex/module-api.d.ts +25 -0
  78. package/dist/internal-providers/provider-codex/module-api.js +31 -0
  79. package/dist/internal-providers/provider-codex/relay.d.ts +123 -0
  80. package/dist/internal-providers/provider-codex/relay.js +261 -0
  81. package/dist/internal-providers/provider-codex/subscription.d.ts +2 -0
  82. package/dist/internal-providers/provider-codex/subscription.js +555 -0
  83. package/dist/internal-providers/provider-codex/test/http-submission.test.d.ts +1 -0
  84. package/dist/internal-providers/provider-codex/test/http-submission.test.js +142 -0
  85. package/dist/internal-providers/provider-codex/test/relay.test.d.ts +1 -0
  86. package/dist/internal-providers/provider-codex/test/relay.test.js +600 -0
  87. package/dist/internal-providers/provider-codex/test/subscription.test.d.ts +1 -0
  88. package/dist/internal-providers/provider-codex/test/subscription.test.js +70 -0
  89. package/dist/internal-providers/provider-codex/test/translated-content.test.d.ts +1 -0
  90. package/dist/internal-providers/provider-codex/test/translated-content.test.js +91 -0
  91. package/dist/internal-providers/provider-custom/index.d.ts +9 -0
  92. package/dist/internal-providers/provider-custom/index.js +15 -0
  93. package/dist/internal-providers/provider-google/index.d.ts +23 -0
  94. package/dist/internal-providers/provider-google/index.js +43 -0
  95. package/dist/internal-providers/provider-google/test/provider.test.d.ts +1 -0
  96. package/dist/internal-providers/provider-google/test/provider.test.js +34 -0
  97. package/dist/internal-providers/provider-google-vertex/index.d.ts +28 -0
  98. package/dist/internal-providers/provider-google-vertex/index.js +137 -0
  99. package/dist/internal-providers/provider-google-vertex/test/provider.test.d.ts +1 -0
  100. package/dist/internal-providers/provider-google-vertex/test/provider.test.js +85 -0
  101. package/dist/internal-providers/provider-openai/documented-reasoning.d.ts +9 -0
  102. package/dist/internal-providers/provider-openai/documented-reasoning.js +26 -0
  103. package/dist/internal-providers/provider-openai/index.d.ts +23 -0
  104. package/dist/internal-providers/provider-openai/index.js +74 -0
  105. package/dist/internal-providers/provider-openai/test/provider.test.d.ts +1 -0
  106. package/dist/internal-providers/provider-openai/test/provider.test.js +268 -0
  107. package/dist/internal-providers/provider-openai-compatible/index.d.ts +9 -0
  108. package/dist/internal-providers/provider-openai-compatible/index.js +15 -0
  109. package/dist/internal-providers/provider-openai-compatible/test/provider.test.d.ts +1 -0
  110. package/dist/internal-providers/provider-openai-compatible/test/provider.test.js +40 -0
  111. package/dist/internal-providers/provider-openrouter/connection.d.ts +5 -0
  112. package/dist/internal-providers/provider-openrouter/connection.js +143 -0
  113. package/dist/internal-providers/provider-openrouter/index.d.ts +28 -0
  114. package/dist/internal-providers/provider-openrouter/index.js +42 -0
  115. package/dist/internal-providers/provider-openrouter/pricing.d.ts +4 -0
  116. package/dist/internal-providers/provider-openrouter/pricing.js +108 -0
  117. package/dist/internal-providers/provider-openrouter/test/connection.test.d.ts +1 -0
  118. package/dist/internal-providers/provider-openrouter/test/connection.test.js +71 -0
  119. package/dist/internal-providers/provider-openrouter/test/pricing.test.d.ts +1 -0
  120. package/dist/internal-providers/provider-openrouter/test/pricing.test.js +45 -0
  121. package/dist/internal-providers/provider-openrouter/test/provider.test.d.ts +1 -0
  122. package/dist/internal-providers/provider-openrouter/test/provider.test.js +141 -0
  123. package/dist/internal-providers/provider-openrouter/test/validation.test.d.ts +1 -0
  124. package/dist/internal-providers/provider-openrouter/test/validation.test.js +225 -0
  125. package/dist/launcher-service.d.ts +3 -7
  126. package/dist/launcher-service.js +144 -133
  127. package/dist/provider-modules.d.ts +6 -0
  128. package/dist/provider-modules.js +55 -0
  129. package/dist/provider-query-service.d.ts +1 -3
  130. package/dist/provider-query-service.js +140 -143
  131. package/dist/router-generation-service.d.ts +1 -3
  132. package/dist/router-generation-service.js +83 -78
  133. package/dist/services/eval-session/service.d.ts +20 -8
  134. package/dist/services/eval-session/service.js +410 -40
  135. package/dist/services/gateway-generation/service.d.ts +7 -3
  136. package/dist/services/gateway-generation/service.js +126 -63
  137. package/dist/services/generations/service.d.ts +3 -3
  138. package/dist/services/generations/service.js +5 -1
  139. package/dist/telemetry-application-service.d.ts +1 -3
  140. package/dist/telemetry-application-service.js +41 -45
  141. package/dist/test/call-attribution-store.test.js +186 -0
  142. package/dist/test/daemon-accounts.test.js +2 -2
  143. package/dist/test/daemon-data-plane.test.js +24 -45
  144. package/dist/test/daemon-fixtures.js +1 -1
  145. package/dist/test/daemon-generation-transaction.test.js +66 -2
  146. package/dist/test/daemon-runtime-state.test.js +28 -1
  147. package/dist/test/effect-daemon.test.js +38 -0
  148. package/dist/test/eval-routing-application-service.test.js +6 -6
  149. package/dist/test/eval-session-execution.test.d.ts +1 -0
  150. package/dist/test/eval-session-execution.test.js +356 -0
  151. package/dist/test/eval-session-service.test.js +70 -1
  152. package/dist/test/host-worker-session.test.js +1 -0
  153. package/dist/test/launcher-session.test.d.ts +1 -0
  154. package/dist/test/launcher-session.test.js +87 -0
  155. package/dist/test/leaderboard.test.js +25 -1
  156. package/dist/test/provider-modules.test.d.ts +1 -0
  157. package/dist/test/provider-modules.test.js +65 -0
  158. package/dist/test/routekit-upstream-sources.test.d.ts +1 -0
  159. package/dist/test/routekit-upstream-sources.test.js +40 -0
  160. package/dist/test/runtime-composition-types.test.js +11 -0
  161. package/dist/token-application-service.d.ts +1 -3
  162. package/dist/token-application-service.js +38 -44
  163. package/dist/worker.js +5 -3
  164. package/package.json +35 -11
  165. package/dist/application-services.d.ts +0 -10
  166. package/dist/application-services.js +0 -22
  167. package/dist/daemon-lifecycle.d.ts +0 -54
  168. package/dist/daemon-lifecycle.js +0 -177
  169. package/dist/test/application-services.test.js +0 -135
  170. package/dist/test/daemon-lifecycle.test.js +0 -182
  171. /package/dist/{test/application-services.test.d.ts → internal-providers/provider-anthropic/test/provider.test.d.ts} +0 -0
  172. /package/dist/{test/daemon-lifecycle.test.d.ts → internal-providers/provider-azure/test/provider.test.d.ts} +0 -0
@@ -1,61 +1,37 @@
1
1
  import type { AccountStoreEntry } from "@velum-labs/routekit-accounts";
2
- import { type RouterConfig } from "@velum-labs/routekit-config";
2
+ import { type RouterConfig, type SourceConfig } from "@velum-labs/routekit-config";
3
3
  import { ControlError } from "@velum-labs/routekit-runtime/control";
4
4
  import { Effect } from "effect";
5
5
  export declare function canonicalConfigDocument(path?: string): string;
6
- export declare function canonicalConfigDocumentEffect(path?: string): Effect.Effect<string, import("@velum-labs/routekit-runtime/effect").RouteKitFailure | ControlError, never>;
6
+ export declare function canonicalConfigDocumentEffect(path?: string): Effect.Effect<string, ControlError | import("@velum-labs/routekit-runtime/effect").RouteKitFailure, never>;
7
7
  export declare function parseConfigDocument(document: string): RouterConfig;
8
8
  export declare function parseConfigDocumentEffect(document: string): Effect.Effect<{
9
- providers: {
10
- openai?: {
9
+ sources: Record<string, {
10
+ pool?: "sticky" | "round_robin" | "capacity_weighted" | {
11
11
  strategy: "sticky" | "round_robin" | "capacity_weighted";
12
12
  switchThreshold: number;
13
13
  probeIntervalMs?: number | undefined;
14
14
  fallbackCooldownSeconds?: number | undefined;
15
15
  } | undefined;
16
- anthropic?: {
17
- strategy: "sticky" | "round_robin" | "capacity_weighted";
18
- switchThreshold: number;
19
- probeIntervalMs?: number | undefined;
20
- fallbackCooldownSeconds?: number | undefined;
21
- } | undefined;
22
- bedrock?: {
23
- strategy: "sticky" | "round_robin" | "capacity_weighted";
24
- switchThreshold: number;
25
- probeIntervalMs?: number | undefined;
26
- fallbackCooldownSeconds?: number | undefined;
27
- } | undefined;
28
- google?: {
29
- strategy: "sticky" | "round_robin" | "capacity_weighted";
30
- switchThreshold: number;
31
- probeIntervalMs?: number | undefined;
32
- fallbackCooldownSeconds?: number | undefined;
33
- } | undefined;
34
- openrouter?: {
35
- strategy: "sticky" | "round_robin" | "capacity_weighted";
36
- switchThreshold: number;
37
- probeIntervalMs?: number | undefined;
38
- fallbackCooldownSeconds?: number | undefined;
39
- } | undefined;
40
- cliproxy?: {
41
- strategy: "sticky" | "round_robin" | "capacity_weighted";
42
- switchThreshold: number;
43
- probeIntervalMs?: number | undefined;
44
- fallbackCooldownSeconds?: number | undefined;
45
- } | undefined;
46
- codex?: {
47
- strategy: "sticky" | "round_robin" | "capacity_weighted";
48
- switchThreshold: number;
49
- probeIntervalMs?: number | undefined;
50
- fallbackCooldownSeconds?: number | undefined;
51
- } | undefined;
52
- "claude-code"?: {
53
- strategy: "sticky" | "round_robin" | "capacity_weighted";
54
- switchThreshold: number;
55
- probeIntervalMs?: number | undefined;
56
- fallbackCooldownSeconds?: number | undefined;
16
+ use: string;
17
+ auth?: {
18
+ kind: "env-bearer";
19
+ env: string;
20
+ } | {
21
+ kind: "env-header";
22
+ env: string;
23
+ header: string;
24
+ } | {
25
+ kind: "aws-sdk";
26
+ } | {
27
+ kind: "adc";
28
+ } | {
29
+ kind: "oauth-file";
30
+ path?: string | undefined;
57
31
  } | undefined;
58
- };
32
+ baseUrl?: string | undefined;
33
+ options?: Record<string, unknown> | undefined;
34
+ }>;
59
35
  defaultModel?: string | undefined;
60
36
  classifierModel?: string | undefined;
61
37
  compositionalRouting?: {
@@ -96,16 +72,18 @@ export declare function parseConfigDocumentEffect(document: string): Effect.Effe
96
72
  durable: boolean;
97
73
  durableRetentionDays: number;
98
74
  } | undefined;
99
- }, import("@velum-labs/routekit-runtime/effect").RouteKitFailure | ControlError, never>;
75
+ } & {
76
+ readonly providers: Record<import("@velum-labs/routekit-config").SourceId, SourceConfig>;
77
+ }, ControlError | import("@velum-labs/routekit-runtime/effect").RouteKitFailure, never>;
100
78
  export declare function revisionConflict(expected: number, actual: number): never;
101
79
  type WithoutPath<T> = T extends {
102
80
  path: string;
103
81
  } ? Omit<T, "path"> : never;
104
82
  export type AccountEntry = WithoutPath<AccountStoreEntry>;
105
83
  export declare function accountEntries(env: NodeJS.ProcessEnv): AccountEntry[];
106
- export declare function accountEntriesEffect(env: NodeJS.ProcessEnv): Effect.Effect<AccountEntry[], import("@velum-labs/routekit-runtime/effect").RouteKitFailure | ControlError, never>;
84
+ export declare function accountEntriesEffect(env: NodeJS.ProcessEnv): Effect.Effect<AccountEntry[], ControlError | import("@velum-labs/routekit-runtime/effect").RouteKitFailure, never>;
107
85
  export declare function accountEntriesWithPaths(env: NodeJS.ProcessEnv): AccountStoreEntry[];
108
- export declare function providerCredentialAvailable(provider: string, accounts: readonly AccountEntry[], env: NodeJS.ProcessEnv): boolean;
86
+ export declare function providerCredentialAvailable(source: SourceConfig, accounts: readonly AccountEntry[], env: NodeJS.ProcessEnv): boolean;
109
87
  export declare function safeCredentialBlob(kind: "claude-code" | "codex", value: unknown): Record<string, unknown>;
110
88
  export declare function safeCliproxyCredentialBlob(kind: string, value: unknown): Record<string, unknown>;
111
89
  export declare function safeCliproxyLabel(label: string): string;
@@ -59,13 +59,17 @@ export function accountEntriesEffect(env) {
59
59
  export function accountEntriesWithPaths(env) {
60
60
  return accountStoreEntries(env);
61
61
  }
62
- export function providerCredentialAvailable(provider, accounts, env) {
62
+ export function providerCredentialAvailable(source, accounts, env) {
63
+ const provider = source.use;
63
64
  if (provider === "claude-code" || provider === "codex") {
64
65
  return accounts.some((entry) => entry.subscriptionKind === provider);
65
66
  }
66
67
  if (provider === "cliproxy") {
67
68
  return (env[CLIPROXY_API_KEY_ENV] ?? "").length > 0 || cliproxyApiKey(env) !== undefined;
68
69
  }
70
+ if (source.auth?.kind === "env-bearer" || source.auth?.kind === "env-header") {
71
+ return (env[source.auth.env] ?? "").length > 0;
72
+ }
69
73
  const info = PROVIDERS[provider];
70
74
  if (info?.keyEnv === undefined)
71
75
  return true;
@@ -1,10 +1,11 @@
1
1
  import type { RouteKitControlParams, RouteKitControlResults } from "@velum-labs/routekit-control";
2
2
  import type { WorkloadJwtVerifierOptions } from "@velum-labs/routekit-gateway";
3
3
  import type { DaemonBootstrapHostedOptions } from "./daemon-bootstrap-preflight.js";
4
- import type { DaemonGenerationManagerOptions } from "./daemon-generations.js";
4
+ import type { DaemonGenerationSettings } from "./daemon-generations.js";
5
5
  import type { TelemetryTransportFactory } from "./telemetry.js";
6
6
  export type RouteKitDaemonOptions = {
7
7
  packageVersion: string;
8
+ sourceBuildId?: string;
8
9
  env?: NodeJS.ProcessEnv;
9
10
  stateHome?: string;
10
11
  configPath?: string;
@@ -22,5 +23,5 @@ export type RouteKitDaemonOptions = {
22
23
  telemetryTransportFactory?: TelemetryTransportFactory;
23
24
  telemetryFlushIntervalMs?: number;
24
25
  onAccountTransactionPhase?: (phase: "prepared" | "credentials-written" | "router-swapped" | "committed") => void;
25
- onGenerationStage?: DaemonGenerationManagerOptions["onStage"];
26
+ onGenerationStage?: DaemonGenerationSettings["onStage"];
26
27
  };
@@ -6,4 +6,5 @@ export type DaemonPolicyValue = {
6
6
  declare const DaemonPolicy_base: Context.ServiceClass<DaemonPolicy, "@velum-labs/routekit-daemon/DaemonPolicy", DaemonPolicyValue>;
7
7
  export declare class DaemonPolicy extends DaemonPolicy_base {
8
8
  }
9
+ export declare const wantsCliproxySidecar: (config: RouterConfig) => boolean;
9
10
  export {};
@@ -1,3 +1,4 @@
1
1
  import { Context } from "effect";
2
2
  export class DaemonPolicy extends Context.Service()("@velum-labs/routekit-daemon/DaemonPolicy") {
3
3
  }
4
+ export const wantsCliproxySidecar = (config) => Object.values(config.sources).some((source) => source.use === "cliproxy");
@@ -30,7 +30,7 @@ export declare class DaemonRuntimeState {
30
30
  markClosed(): void;
31
31
  pause(): void;
32
32
  resume(): void;
33
- awaitMutations(): Effect.Effect<void>;
33
+ get awaitMutations(): Effect.Effect<void>;
34
34
  serializeEffect<T, E = never, R = never>(operation: Effect.Effect<T, E, R>): Effect.Effect<T, E | Error, R>;
35
35
  snapshot(): DaemonRuntimeSnapshot;
36
36
  }
@@ -74,9 +74,8 @@ export class DaemonRuntimeState {
74
74
  if (this.#lifecycle === "paused")
75
75
  this.#lifecycle = "running";
76
76
  }
77
- awaitMutations() {
78
- const self = this;
79
- return Effect.suspend(() => self.#mutationTail);
77
+ get awaitMutations() {
78
+ return Effect.suspend(() => this.#mutationTail);
80
79
  }
81
80
  serializeEffect(operation) {
82
81
  const self = this;
@@ -1,7 +1,7 @@
1
1
  import { Context, Layer } from "effect";
2
2
  import type { DaemonRuntimeState } from "./daemon-runtime-state.js";
3
3
  export type DaemonStateService = Omit<DaemonRuntimeState, "awaitMutations"> & {
4
- readonly awaitMutations: ReturnType<DaemonRuntimeState["awaitMutations"]>;
4
+ readonly awaitMutations: DaemonRuntimeState["awaitMutations"];
5
5
  };
6
6
  declare const DaemonState_base: Context.ServiceClass<DaemonState, "@velum-labs/routekit-daemon/DaemonState", DaemonStateService>;
7
7
  export declare class DaemonState extends DaemonState_base {
@@ -1,43 +1,6 @@
1
1
  import { Context, Layer } from "effect";
2
2
  export class DaemonState extends Context.Service()("@velum-labs/routekit-daemon/DaemonState") {
3
3
  static layer(state) {
4
- return Layer.succeed(DaemonState, DaemonState.of({
5
- get config() {
6
- return state.config;
7
- },
8
- set config(config) {
9
- state.config = config;
10
- },
11
- get document() {
12
- return state.document;
13
- },
14
- set document(document) {
15
- state.document = document;
16
- },
17
- get revisions() {
18
- return state.revisions;
19
- },
20
- set revisions(revisions) {
21
- state.revisions = revisions;
22
- },
23
- get lifecycle() {
24
- return state.lifecycle;
25
- },
26
- get draining() {
27
- return state.draining;
28
- },
29
- get closed() {
30
- return state.closed;
31
- },
32
- beginShutdown: state.beginShutdown.bind(state),
33
- beginRetire: state.beginRetire.bind(state),
34
- markDraining: state.markDraining.bind(state),
35
- markClosed: state.markClosed.bind(state),
36
- pause: state.pause.bind(state),
37
- resume: state.resume.bind(state),
38
- awaitMutations: state.awaitMutations(),
39
- serializeEffect: state.serializeEffect.bind(state),
40
- snapshot: state.snapshot.bind(state)
41
- }));
4
+ return Layer.succeed(DaemonState, state);
42
5
  }
43
6
  }
@@ -1,7 +1,5 @@
1
1
  import type { EffectRouteKitControlHandlers } from "@velum-labs/routekit-control/effect";
2
2
  type DoctorHandlers = Pick<EffectRouteKitControlHandlers, "doctor.run">;
3
3
  /** Owns daemon diagnostic checks for local configuration and live providers. */
4
- export declare class DoctorApplicationService {
5
- handlers(): DoctorHandlers;
6
- }
4
+ export declare const doctorHandlers: DoctorHandlers;
7
5
  export {};
@@ -5,99 +5,95 @@ import { accountEntries } from "./daemon-maintenance.js";
5
5
  import { AccountRecovery } from "./account-recovery-context.js";
6
6
  import { ActiveGateway } from "./services/active-gateway/service.js";
7
7
  import { DaemonEnv } from "./daemon-env-context.js";
8
- import { DaemonPolicy } from "./daemon-policy-context.js";
8
+ import { wantsCliproxySidecar } from "./daemon-policy-context.js";
9
9
  import { DaemonState } from "./daemon-state-context.js";
10
10
  import { Sidecar } from "./sidecar-context.js";
11
11
  /** Owns daemon diagnostic checks for local configuration and live providers. */
12
- export class DoctorApplicationService {
13
- handlers() {
14
- return {
15
- "doctor.run": (_params, context) => Effect.gen(function* () {
16
- const env = yield* DaemonEnv;
17
- const state = yield* DaemonState;
18
- const sidecar = yield* Sidecar;
19
- const gateway = yield* ActiveGateway;
20
- const recovery = yield* AccountRecovery;
21
- const policy = yield* DaemonPolicy;
22
- const providers = yield* gateway.router().providerStatuses(context.signal);
23
- const configuredProviders = configuredProviderIds(state.config);
24
- const accounts = accountEntries(env.env);
25
- const missingProviders = [
26
- ...new Set(accounts
27
- .filter((entry) => {
28
- const provider = entry.connector === "cliproxy" ? "cliproxy" : entry.subscriptionKind;
29
- return state.config.providers[provider] === undefined;
30
- })
31
- .map((entry) => entry.subscriptionKind))
32
- ];
33
- const providerOnly = ["claude-code", "codex", "cliproxy"].filter((provider) => state.config.providers[provider] !== undefined &&
34
- !accounts.some((entry) => provider === "cliproxy"
35
- ? entry.connector === "cliproxy"
36
- : entry.subscriptionKind === provider));
37
- const consistent = missingProviders.length === 0 && providerOnly.length === 0;
38
- const cliproxyCheck = policy.wantsCliproxySidecar(state.config)
39
- ? [
40
- {
41
- name: "cliproxy sidecar",
42
- ok: yield* sidecar.reachable(),
43
- detail: sidecar.managed()
44
- ? sidecar.running()
45
- ? "managed; running"
46
- : "managed; not running"
47
- : "external"
48
- }
49
- ]
50
- : [];
51
- return {
52
- checks: [
53
- {
54
- name: "canonical config",
55
- ok: existsSync(env.configPath),
56
- detail: env.configPath
57
- },
58
- { name: "control plane", ok: gateway.control() !== undefined },
59
- {
60
- name: "model gateway",
61
- ok: gateway.proxy() !== undefined,
62
- detail: gateway.dataUrl()
63
- },
64
- {
65
- name: "provider configuration",
66
- ok: configuredProviders.length > 0,
67
- detail: configuredProviders.length > 0
68
- ? `${configuredProviders.length} provider(s) configured`
69
- : "no providers configured; run `routekit providers add <provider>`"
70
- },
71
- {
72
- name: "account activation recovery",
73
- ok: true,
74
- detail: recovery.recovered > 0
75
- ? `recovered ${recovery.recovered} interrupted operation(s)`
76
- : "clean"
77
- },
78
- {
79
- name: "account/provider consistency",
80
- ok: consistent,
81
- detail: consistent
82
- ? "consistent"
83
- : [
84
- ...(missingProviders.length > 0
85
- ? [`routing disabled: ${missingProviders.join(", ")}`]
86
- : []),
87
- ...(providerOnly.length > 0
88
- ? [`credential missing: ${providerOnly.join(", ")}`]
89
- : [])
90
- ].join("; ")
91
- },
92
- ...cliproxyCheck,
93
- ...providers.map((provider) => ({
94
- name: `${provider.provider} live discovery`,
95
- ok: provider.ok,
96
- detail: provider.error ?? `${provider.models.length} model(s)`
97
- }))
98
- ]
99
- };
12
+ export const doctorHandlers = {
13
+ "doctor.run": (_params, context) => Effect.gen(function* () {
14
+ const env = yield* DaemonEnv;
15
+ const state = yield* DaemonState;
16
+ const sidecar = yield* Sidecar;
17
+ const gateway = yield* ActiveGateway;
18
+ const recovery = yield* AccountRecovery;
19
+ const providers = yield* gateway.router().providerStatuses(context.signal);
20
+ const configuredProviders = configuredProviderIds(state.config);
21
+ const configuredModules = new Set(Object.values(state.config.sources).map((source) => source.use));
22
+ const accounts = accountEntries(env.env);
23
+ const missingProviders = [
24
+ ...new Set(accounts
25
+ .filter((entry) => {
26
+ const provider = entry.connector === "cliproxy" ? "cliproxy" : entry.subscriptionKind;
27
+ return !configuredModules.has(provider);
100
28
  })
29
+ .map((entry) => entry.subscriptionKind))
30
+ ];
31
+ const providerOnly = ["claude-code", "codex", "cliproxy"].filter((provider) => configuredModules.has(provider) &&
32
+ !accounts.some((entry) => provider === "cliproxy"
33
+ ? entry.connector === "cliproxy"
34
+ : entry.subscriptionKind === provider));
35
+ const consistent = missingProviders.length === 0 && providerOnly.length === 0;
36
+ const cliproxyCheck = wantsCliproxySidecar(state.config)
37
+ ? [
38
+ {
39
+ name: "cliproxy sidecar",
40
+ ok: yield* sidecar.reachable(),
41
+ detail: sidecar.managed()
42
+ ? sidecar.running()
43
+ ? "managed; running"
44
+ : "managed; not running"
45
+ : "external"
46
+ }
47
+ ]
48
+ : [];
49
+ return {
50
+ checks: [
51
+ {
52
+ name: "canonical config",
53
+ ok: existsSync(env.configPath),
54
+ detail: env.configPath
55
+ },
56
+ { name: "control plane", ok: gateway.control() !== undefined },
57
+ {
58
+ name: "model gateway",
59
+ ok: gateway.proxy() !== undefined,
60
+ detail: gateway.dataUrl()
61
+ },
62
+ {
63
+ name: "provider configuration",
64
+ ok: configuredProviders.length > 0,
65
+ detail: configuredProviders.length > 0
66
+ ? `${configuredProviders.length} provider(s) configured`
67
+ : "no providers configured; run `routekit providers add <provider>`"
68
+ },
69
+ {
70
+ name: "account activation recovery",
71
+ ok: true,
72
+ detail: recovery.recovered > 0
73
+ ? `recovered ${recovery.recovered} interrupted operation(s)`
74
+ : "clean"
75
+ },
76
+ {
77
+ name: "account/provider consistency",
78
+ ok: consistent,
79
+ detail: consistent
80
+ ? "consistent"
81
+ : [
82
+ ...(missingProviders.length > 0
83
+ ? [`routing disabled: ${missingProviders.join(", ")}`]
84
+ : []),
85
+ ...(providerOnly.length > 0
86
+ ? [`credential missing: ${providerOnly.join(", ")}`]
87
+ : [])
88
+ ].join("; ")
89
+ },
90
+ ...cliproxyCheck,
91
+ ...providers.map((provider) => ({
92
+ name: `${provider.provider} live discovery`,
93
+ ok: provider.ok,
94
+ detail: provider.error ?? `${provider.models.length} model(s)`
95
+ }))
96
+ ]
101
97
  };
102
- }
103
- }
98
+ })
99
+ };
@@ -1,22 +1,23 @@
1
1
  import { AccountActivity, AccountAuth } from "@velum-labs/routekit-accounts/effect";
2
2
  import { Layer } from "effect";
3
- import type { RouteKitDaemonOptions } from "../daemon-options.js";
4
3
  import { AccountRecovery } from "../account-recovery-context.js";
5
- import { ActiveGateway } from "../services/active-gateway/service.js";
6
- import { CallAttributions } from "../services/call-attributions/service.js";
7
4
  import { DaemonEnv } from "../daemon-env-context.js";
8
5
  import { DaemonHost } from "../daemon-host-context.js";
6
+ import type { RouteKitDaemonOptions } from "../daemon-options.js";
9
7
  import { DaemonPolicy } from "../daemon-policy-context.js";
10
- import { DaemonRuntime } from "../services/daemon-runtime/service.js";
11
8
  import { DaemonState } from "../daemon-state-context.js";
12
9
  import { DataPlane } from "../data-plane-context.js";
10
+ import { Leaderboard } from "../leaderboard-context.js";
11
+ import { ActiveGateway } from "../services/active-gateway/service.js";
12
+ import { CallAttributions } from "../services/call-attributions/service.js";
13
+ import { DaemonRuntime } from "../services/daemon-runtime/service.js";
13
14
  import { EvalSessions } from "../services/eval-session/service.js";
14
15
  import { Generations } from "../services/generations/service.js";
15
- import { Leaderboard } from "../leaderboard-context.js";
16
- import { Sidecar } from "../sidecar-context.js";
17
16
  import { Telemetry } from "../services/telemetry/service.js";
18
17
  import { Tokens } from "../services/tokens/service.js";
18
+ import { Sidecar } from "../sidecar-context.js";
19
19
  export type DaemonLiveOptions = RouteKitDaemonOptions;
20
+ /** Published daemon Effect services; private construction services stay internal. */
20
21
  export type DaemonLive = DaemonRuntime | DaemonEnv | DaemonState | Sidecar | Tokens | EvalSessions | Telemetry | ActiveGateway | AccountActivity | AccountAuth | Generations | DataPlane | AccountRecovery | CallAttributions | Leaderboard | DaemonPolicy | DaemonHost;
21
22
  /** Construct and own the complete daemon worker lifetime. */
22
23
  export declare function daemonLive(options: DaemonLiveOptions): Layer.Layer<DaemonLive, Error>;