From 2463781e00908ec28dfb1e9cdb1fd45d6f3c090f Mon Sep 17 00:00:00 2001 From: Webman Date: Sun, 30 Aug 2026 00:27:25 -0500 Subject: [PATCH] fix(barrel): migrate src/lib/ off the localDb barrel to direct db imports (#59) (#12052) Boarded together with Phases 2, 4, 5 (#12051, #12053, #12055) and validated in one combined worktree: typecheck:core, check:file-size, check:changelog-integrity, check:complexity, check:cognitive-complexity, check:cycles, check-db-rules all green. Mechanical import-path migration only, no behavior change. Thanks for the phased, well-tested cleanup. --- config/quality/eslint-suppressions.json | 160 ------------------ src/lib/a2a/skills/providerDiscovery.ts | 2 +- src/lib/api/proxyRegistryRouteHandlers.ts | 2 +- src/lib/cloudSync.ts | 2 +- src/lib/combos/builderOptions.ts | 13 +- src/lib/container.ts | 2 +- src/lib/credentialHealth/scheduler.ts | 2 +- src/lib/evals/runtime.ts | 3 +- src/lib/freeProxyProviders/scheduler.ts | 2 +- src/lib/freeProxyProviders/syncCycle.ts | 2 +- src/lib/guardrails/visionBridge.ts | 2 +- src/lib/idempotencyLayer.ts | 2 +- src/lib/images/imageRouteModel.ts | 2 +- src/lib/localHealthCheck.ts | 3 +- src/lib/memory/embedding/index.ts | 2 +- src/lib/memory/reindex.ts | 6 +- src/lib/memory/store.ts | 2 +- src/lib/memory/vectorStore.ts | 61 +++---- src/lib/modelsDevSync.ts | 2 +- src/lib/monitoring/providerHealthAutopilot.ts | 2 +- src/lib/oauth/utils/agyAuthImport.ts | 2 +- src/lib/oauth/utils/claudeAuthFile.ts | 6 +- src/lib/oauth/utils/claudeAuthImport.ts | 2 +- src/lib/oauth/utils/codexAuthFile.ts | 12 +- src/lib/oauth/utils/codexAuthImport.ts | 2 +- .../providerModels/managedAvailableModels.ts | 4 +- src/lib/proxyEgress.ts | 2 +- src/lib/proxyHealth/scheduler.ts | 2 +- src/lib/quota/connectionProvider.ts | 2 +- src/lib/quota/planResolver.ts | 2 +- src/lib/quota/quotaCombos.ts | 2 +- src/lib/quota/quotaKey.ts | 6 +- src/lib/quota/redisQuotaStore.ts | 5 +- src/lib/quota/saturationSignals.ts | 42 ++--- src/lib/quota/sqliteQuotaStore.ts | 3 +- src/lib/services/quotaAutoPing.ts | 42 ++--- src/lib/sync/bundle.ts | 16 +- src/lib/tokenHealthCheck.ts | 10 +- src/lib/tokenHealthCheckCopilot.ts | 25 ++- src/lib/usage/apiKeySelfService.ts | 13 +- src/lib/usage/callLogs.ts | 4 +- src/lib/usage/codexResetCredits.ts | 3 +- src/lib/usage/costCalculator.ts | 4 +- src/lib/usage/internalUsageCommand.ts | 17 +- src/lib/usage/usageStats.ts | 2 +- src/lib/usageAnalytics.ts | 2 +- src/lib/ws/handshake.ts | 2 +- 47 files changed, 173 insertions(+), 335 deletions(-) diff --git a/config/quality/eslint-suppressions.json b/config/quality/eslint-suppressions.json index e234b3973d..74a52b6a55 100644 --- a/config/quality/eslint-suppressions.json +++ b/config/quality/eslint-suppressions.json @@ -1539,11 +1539,6 @@ "count": 1 } }, - "src/lib/api/proxyRegistryRouteHandlers.ts": { - "no-restricted-imports": { - "count": 1 - } - }, "src/lib/cli-helper/config-generator/claude.ts": { "@typescript-eslint/no-unused-vars": { "count": 1 @@ -1584,16 +1579,6 @@ "count": 2 } }, - "src/lib/cloudSync.ts": { - "no-restricted-imports": { - "count": 1 - } - }, - "src/lib/combos/builderOptions.ts": { - "no-restricted-imports": { - "count": 1 - } - }, "src/lib/combos/controlCenter.ts": { "no-restricted-syntax": { "count": 1 @@ -1604,11 +1589,6 @@ "count": 1 } }, - "src/lib/container.ts": { - "no-restricted-imports": { - "count": 1 - } - }, "src/lib/copilot/engine.ts": { "@typescript-eslint/no-unused-vars": { "count": 2 @@ -1622,9 +1602,6 @@ "src/lib/credentialHealth/scheduler.ts": { "@typescript-eslint/no-unused-vars": { "count": 1 - }, - "no-restricted-imports": { - "count": 1 } }, "src/lib/db/apiKeys.ts": { @@ -1747,21 +1724,6 @@ "count": 1 } }, - "src/lib/evals/runtime.ts": { - "no-restricted-imports": { - "count": 1 - } - }, - "src/lib/freeProxyProviders/scheduler.ts": { - "no-restricted-imports": { - "count": 1 - } - }, - "src/lib/freeProxyProviders/syncCycle.ts": { - "no-restricted-imports": { - "count": 1 - } - }, "src/lib/guardrails/promptInjection.ts": { "@typescript-eslint/no-unused-vars": { "count": 2 @@ -1772,26 +1734,11 @@ "count": 1 } }, - "src/lib/idempotencyLayer.ts": { - "no-restricted-imports": { - "count": 1 - } - }, - "src/lib/images/imageRouteModel.ts": { - "no-restricted-imports": { - "count": 1 - } - }, "src/lib/jobRegistry/index.ts": { "@typescript-eslint/no-unused-vars": { "count": 1 } }, - "src/lib/localHealthCheck.ts": { - "no-restricted-imports": { - "count": 1 - } - }, "src/lib/memory/__tests__/generic-backend.test.ts": { "@typescript-eslint/no-unused-vars": { "count": 4 @@ -1802,21 +1749,11 @@ "count": 1 } }, - "src/lib/memory/embedding/index.ts": { - "no-restricted-imports": { - "count": 1 - } - }, "src/lib/memory/genericBackend.ts": { "@typescript-eslint/no-unused-vars": { "count": 1 } }, - "src/lib/memory/reindex.ts": { - "no-restricted-imports": { - "count": 1 - } - }, "src/lib/memory/retrieval.ts": { "@typescript-eslint/no-unused-vars": { "count": 1 @@ -1827,16 +1764,6 @@ "count": 2 } }, - "src/lib/memory/store.ts": { - "no-restricted-imports": { - "count": 1 - } - }, - "src/lib/memory/vectorStore.ts": { - "no-restricted-imports": { - "count": 1 - } - }, "src/lib/middleware/registry.ts": { "@typescript-eslint/no-unused-vars": { "count": 2 @@ -1851,9 +1778,6 @@ "@typescript-eslint/no-unused-vars": { "count": 1 }, - "no-restricted-imports": { - "count": 1 - }, "no-restricted-syntax": { "count": 1 } @@ -1913,32 +1837,9 @@ "count": 3 } }, - "src/lib/oauth/utils/agyAuthImport.ts": { - "no-restricted-imports": { - "count": 1 - } - }, - "src/lib/oauth/utils/claudeAuthFile.ts": { - "no-restricted-imports": { - "count": 1 - } - }, "src/lib/oauth/utils/claudeAuthImport.ts": { "@typescript-eslint/no-unused-vars": { "count": 1 - }, - "no-restricted-imports": { - "count": 1 - } - }, - "src/lib/oauth/utils/codexAuthFile.ts": { - "no-restricted-imports": { - "count": 1 - } - }, - "src/lib/oauth/utils/codexAuthImport.ts": { - "no-restricted-imports": { - "count": 1 } }, "src/lib/obsidian/api.ts": { @@ -1966,11 +1867,6 @@ "count": 2 } }, - "src/lib/providerModels/managedAvailableModels.ts": { - "no-restricted-imports": { - "count": 1 - } - }, "src/lib/providers/validation.ts": { "@typescript-eslint/no-unused-vars": { "count": 1 @@ -1986,45 +1882,19 @@ "count": 1 } }, - "src/lib/proxyHealth/scheduler.ts": { - "no-restricted-imports": { - "count": 1 - } - }, - "src/lib/quota/planResolver.ts": { - "no-restricted-imports": { - "count": 1 - } - }, "src/lib/quota/quotaAdapters.ts": { "@typescript-eslint/no-unused-vars": { "count": 1 } }, - "src/lib/quota/quotaCombos.ts": { - "no-restricted-imports": { - "count": 1 - } - }, - "src/lib/quota/quotaKey.ts": { - "no-restricted-imports": { - "count": 1 - } - }, "src/lib/quota/redisQuotaStore.ts": { "@typescript-eslint/no-unused-vars": { "count": 1 - }, - "no-restricted-imports": { - "count": 1 } }, "src/lib/quota/sqliteQuotaStore.ts": { "@typescript-eslint/no-unused-vars": { "count": 1 - }, - "no-restricted-imports": { - "count": 1 } }, "src/lib/semanticCache.ts": { @@ -2037,11 +1907,6 @@ "count": 1 } }, - "src/lib/services/quotaAutoPing.ts": { - "no-restricted-imports": { - "count": 1 - } - }, "src/lib/skills/a2a.ts": { "@typescript-eslint/no-unused-vars": { "count": 2 @@ -2082,11 +1947,6 @@ "count": 1 } }, - "src/lib/sync/bundle.ts": { - "no-restricted-imports": { - "count": 1 - } - }, "src/lib/tailscaleTunnel.ts": { "@typescript-eslint/no-unused-vars": { "count": 1 @@ -2097,16 +1957,6 @@ "count": 1 } }, - "src/lib/tokenHealthCheck.ts": { - "no-restricted-imports": { - "count": 1 - } - }, - "src/lib/tokenHealthCheckCopilot.ts": { - "no-restricted-imports": { - "count": 1 - } - }, "src/lib/usage/apiKeySelfService.ts": { "no-restricted-syntax": { "count": 1 @@ -2122,11 +1972,6 @@ "count": 1 } }, - "src/lib/usage/codexResetCredits.ts": { - "no-restricted-imports": { - "count": 1 - } - }, "src/lib/usage/costCalculator.ts": { "no-restricted-syntax": { "count": 1 @@ -2170,11 +2015,6 @@ "count": 1 } }, - "src/lib/ws/handshake.ts": { - "no-restricted-imports": { - "count": 1 - } - }, "src/lib/zed-oauth/keychain-reader.ts": { "@typescript-eslint/no-unused-vars": { "count": 1 diff --git a/src/lib/a2a/skills/providerDiscovery.ts b/src/lib/a2a/skills/providerDiscovery.ts index bec8a116ac..75c22dc7c2 100644 --- a/src/lib/a2a/skills/providerDiscovery.ts +++ b/src/lib/a2a/skills/providerDiscovery.ts @@ -120,7 +120,7 @@ export interface ProviderDiscoveryResult { export async function executeProviderDiscovery(task: A2ATask): Promise { const [{ getProviderConnections }, { getAllCircuitBreakerStatuses }] = await Promise.all([ - import("@/lib/localDb"), + import("@/lib/db/providers"), import("@/shared/utils/circuitBreaker"), ]); diff --git a/src/lib/api/proxyRegistryRouteHandlers.ts b/src/lib/api/proxyRegistryRouteHandlers.ts index b5b2e9bf4e..c6d3c7ea23 100644 --- a/src/lib/api/proxyRegistryRouteHandlers.ts +++ b/src/lib/api/proxyRegistryRouteHandlers.ts @@ -6,7 +6,7 @@ import { getProxyWhereUsed, updateProxy, updateProxyAndAssign, -} from "@/lib/localDb"; +} from "@/lib/db/proxies"; import { createErrorResponse, createErrorResponseFromUnknown } from "@/lib/api/errorResponse"; import { createProxyRegistrySchema, updateProxyRegistrySchema } from "@/shared/validation/schemas"; import { isValidationFailure, validateBody } from "@/shared/validation/helpers"; diff --git a/src/lib/cloudSync.ts b/src/lib/cloudSync.ts index c26459f71d..48084d0025 100644 --- a/src/lib/cloudSync.ts +++ b/src/lib/cloudSync.ts @@ -1,5 +1,5 @@ import crypto from "crypto"; -import { getProviderConnections, updateProviderConnection } from "@/lib/localDb"; +import { getProviderConnections, updateProviderConnection } from "@/lib/db/providers"; import { buildConfigSyncEnvelope, toLegacyCloudSyncPayload } from "@/lib/sync/bundle"; const CLOUD_URL = process.env.CLOUD_URL || process.env.NEXT_PUBLIC_CLOUD_URL; diff --git a/src/lib/combos/builderOptions.ts b/src/lib/combos/builderOptions.ts index 625356ab70..0f1cb529cc 100644 --- a/src/lib/combos/builderOptions.ts +++ b/src/lib/combos/builderOptions.ts @@ -1,12 +1,7 @@ -import { - getAllCustomModels, - getAllSyncedAvailableModels, - getCombos, - getModelIsHidden, - getProviderConnections, - getProviderNodes, - getSettings, -} from "@/lib/localDb"; +import { getAllCustomModels, getAllSyncedAvailableModels, getModelIsHidden } from "@/lib/db/models"; +import { getCombos } from "@/lib/db/combos"; +import { getProviderConnections, getProviderNodes } from "@/lib/db/providers"; +import { getSettings } from "@/lib/db/settings"; import { getAccountDisplayName, getProviderDisplayName } from "@/lib/display/names"; import { getCompatibleFallbackModels } from "@/lib/providers/managedAvailableModels"; import { getResolvedModelCapabilities } from "@/lib/modelCapabilities"; diff --git a/src/lib/container.ts b/src/lib/container.ts index f3aa1af3f8..2f59af30e5 100644 --- a/src/lib/container.ts +++ b/src/lib/container.ts @@ -23,7 +23,7 @@ import { encrypt, encryptConnectionFields, } from "./db/encryption.ts"; -import { getSettings } from "./localDb.ts"; +import { getSettings } from "@/lib/db/settings"; import { getCircuitBreaker } from "../shared/utils/circuitBreaker.ts"; import { recordTelemetry, RequestTelemetry } from "../shared/utils/requestTelemetry.ts"; diff --git a/src/lib/credentialHealth/scheduler.ts b/src/lib/credentialHealth/scheduler.ts index 62b2d41f4a..15fb56c876 100644 --- a/src/lib/credentialHealth/scheduler.ts +++ b/src/lib/credentialHealth/scheduler.ts @@ -18,7 +18,7 @@ */ import { testSingleConnection } from "@/app/api/providers/[id]/test/route"; -import { getProviderConnections } from "@/lib/localDb"; +import { getProviderConnections } from "@/lib/db/providers"; import { setCredentialHealth, removeCredentialHealth, diff --git a/src/lib/evals/runtime.ts b/src/lib/evals/runtime.ts index 9dc728f16f..d3ba6b0a5b 100644 --- a/src/lib/evals/runtime.ts +++ b/src/lib/evals/runtime.ts @@ -1,7 +1,8 @@ import { POST as postChatCompletion } from "@/app/api/v1/chat/completions/route"; import type { PersistedEvalRun, EvalTargetType } from "@/lib/db/evals"; import { saveEvalRun } from "@/lib/db/evals"; -import { getApiKeyById, getCombos } from "@/lib/localDb"; +import { getApiKeyById } from "@/lib/db/apiKeys"; +import { getCombos } from "@/lib/db/combos"; import { getSuite, listSuites, runSuite } from "./evalRunner"; export interface EvalTargetInput { diff --git a/src/lib/freeProxyProviders/scheduler.ts b/src/lib/freeProxyProviders/scheduler.ts index 36e38ba647..634cfb8d92 100644 --- a/src/lib/freeProxyProviders/scheduler.ts +++ b/src/lib/freeProxyProviders/scheduler.ts @@ -22,7 +22,7 @@ */ import { getEnabledProviders } from "@/lib/freeProxyProviders"; -import { getFreeProxyStats } from "@/lib/localDb"; +import { getFreeProxyStats } from "@/lib/db/freeProxies"; import { runFreeProxySyncCycle, type FreeProxySyncCycleResult } from "./syncCycle"; const STARTUP_DELAY_MS = 5_000; diff --git a/src/lib/freeProxyProviders/syncCycle.ts b/src/lib/freeProxyProviders/syncCycle.ts index 666b6234e5..d194091b0c 100644 --- a/src/lib/freeProxyProviders/syncCycle.ts +++ b/src/lib/freeProxyProviders/syncCycle.ts @@ -3,7 +3,7 @@ import { recordFreeProxySync, clearFreeProxySyncErrors, recordFreeProxySyncErrors, -} from "@/lib/localDb"; +} from "@/lib/db/freeProxies"; import type { FreeProxyProvider } from "@/lib/freeProxyProviders/types"; export interface FreeProxySyncCycleResult { diff --git a/src/lib/guardrails/visionBridge.ts b/src/lib/guardrails/visionBridge.ts index db56035386..c24729a3c9 100644 --- a/src/lib/guardrails/visionBridge.ts +++ b/src/lib/guardrails/visionBridge.ts @@ -53,7 +53,7 @@ export async function getComboVisionBridgeDecision( model: string ): Promise { try { - const { getComboByName } = await import("@/lib/localDb"); + const { getComboByName } = await import("@/lib/db/combos"); const { resolveComboForModel } = await import("@/lib/db/modelComboMappings"); // 1. Try to find combo by exact name match diff --git a/src/lib/idempotencyLayer.ts b/src/lib/idempotencyLayer.ts index 628541cb80..da997c0016 100644 --- a/src/lib/idempotencyLayer.ts +++ b/src/lib/idempotencyLayer.ts @@ -10,7 +10,7 @@ * @module lib/idempotencyLayer */ -import { getSettings } from "@/lib/localDb"; +import { getSettings } from "@/lib/db/settings"; const DEFAULT_WINDOW_MS = 5000; diff --git a/src/lib/images/imageRouteModel.ts b/src/lib/images/imageRouteModel.ts index 2c7f0ab3e5..41f414e0ef 100644 --- a/src/lib/images/imageRouteModel.ts +++ b/src/lib/images/imageRouteModel.ts @@ -18,7 +18,7 @@ import { parseImageModel } from "@omniroute/open-sse/config/imageRegistry.ts"; import { resolveComboTargets } from "@omniroute/open-sse/services/combo.ts"; import { getComboByName, getCombos } from "@/lib/db/combos"; -import { getCachedProviderNodes } from "@/lib/localDb"; +import { getCachedProviderNodes } from "@/lib/db/readCache"; import { assertMicrosoftDesignerWebProviderAvailable } from "@/shared/constants/designerWebRetirement"; import { assertCommonChatGptWebModelAvailable } from "@/shared/constants/chatgptWebRetirement"; diff --git a/src/lib/localHealthCheck.ts b/src/lib/localHealthCheck.ts index a496d40399..1853fc910c 100644 --- a/src/lib/localHealthCheck.ts +++ b/src/lib/localHealthCheck.ts @@ -11,7 +11,7 @@ * Uses Promise.allSettled so one slow/down node doesn't block others. */ -import { getCachedProviderNodes } from "@/lib/localDb"; +import { getCachedProviderNodes } from "@/lib/db/readCache"; import { isAutomatedTestProcess } from "@/shared/utils/testProcess"; // ── Types ──────────────────────────────────────────────────────────────── @@ -38,7 +38,6 @@ function isBuildProcess(): boolean { return typeof process !== "undefined" && process.env.NEXT_PHASE === "phase-production-build"; } - // ── State (globalThis survives HMR re-evaluation) ─────────────────────── declare global { diff --git a/src/lib/memory/embedding/index.ts b/src/lib/memory/embedding/index.ts index 9adf55f69e..8205b75524 100644 --- a/src/lib/memory/embedding/index.ts +++ b/src/lib/memory/embedding/index.ts @@ -5,7 +5,7 @@ import { type EmbeddingProviderNodeRow, } from "@omniroute/open-sse/config/embeddingRegistry.ts"; import { getProviderCredentials } from "@/sse/services/auth"; -import { getCachedProviderNodes } from "@/lib/localDb"; +import { getCachedProviderNodes } from "@/lib/db/readCache"; import type { MemorySettingsExtended } from "@/shared/schemas/memory"; import type { EmbeddingResolution, diff --git a/src/lib/memory/reindex.ts b/src/lib/memory/reindex.ts index da7317b10a..8d459edaa7 100644 --- a/src/lib/memory/reindex.ts +++ b/src/lib/memory/reindex.ts @@ -7,7 +7,7 @@ import { getMemoryReindexQueue, countMemoryReindexPending, markMemoryNeedsReindex, -} from "@/lib/localDb"; +} from "@/lib/db/memoryVec"; import { resolveEmbeddingSource, embed } from "./embedding"; import { getVectorStore } from "./vectorStore"; import { getMemorySettings } from "./settings"; @@ -23,9 +23,7 @@ const log = logger("MEMORY_REINDEX"); * * @returns { processed: number; errors: number } */ -export async function runReindexBatch( - limit = 100 -): Promise<{ processed: number; errors: number }> { +export async function runReindexBatch(limit = 100): Promise<{ processed: number; errors: number }> { const queue = getMemoryReindexQueue(limit); if (queue.length === 0) { diff --git a/src/lib/memory/store.ts b/src/lib/memory/store.ts index 8f95b84776..e0441eb3b2 100644 --- a/src/lib/memory/store.ts +++ b/src/lib/memory/store.ts @@ -10,7 +10,7 @@ import { sanitizeErrorMessage } from "../../../open-sse/utils/error.ts"; import { resolveEmbeddingSource, embed } from "./embedding"; import { getVectorStore } from "./vectorStore"; import { getMemorySettings } from "./settings"; -import { markMemoryNeedsReindex } from "@/lib/localDb"; +import { markMemoryNeedsReindex } from "@/lib/db/memoryVec"; const log = logger("MEMORY_STORE"); diff --git a/src/lib/memory/vectorStore.ts b/src/lib/memory/vectorStore.ts index 92f706a3d4..6996b84024 100644 --- a/src/lib/memory/vectorStore.ts +++ b/src/lib/memory/vectorStore.ts @@ -14,7 +14,7 @@ import { setMemoryVecMeta, markAllMemoriesNeedReindex, countMemoryReindexPending, -} from "../localDb"; +} from "@/lib/db/memoryVec"; import { getDbInstance } from "../db/core"; import { logger } from "../../../open-sse/utils/logger.ts"; import { sanitizeErrorMessage } from "../../../open-sse/utils/error.ts"; @@ -54,7 +54,7 @@ export interface VectorStore { vector: Float32Array, queryText: string, topK: number, - apiKeyId?: string, + apiKeyId?: string ): Promise; /** Stats for UI Engine status. */ stats(): Promise<{ @@ -151,7 +151,7 @@ function recreateFromMeta(): boolean { const db = getDbInstance(); const q = storedVecQuantization(meta.embeddingSignature); db.exec( - `CREATE VIRTUAL TABLE IF NOT EXISTS vec_memories USING vec0(embedding ${vecColumnType(meta.activeDim, q)})`, + `CREATE VIRTUAL TABLE IF NOT EXISTS vec_memories USING vec0(embedding ${vecColumnType(meta.activeDim, q)})` ); return true; } @@ -189,7 +189,7 @@ class VectorStoreImpl implements VectorStore { const q = storedVecQuantization(meta.embeddingSignature); try { db.exec( - `CREATE VIRTUAL TABLE IF NOT EXISTS vec_memories USING vec0(embedding ${vecColumnType(dim, q)})`, + `CREATE VIRTUAL TABLE IF NOT EXISTS vec_memories USING vec0(embedding ${vecColumnType(dim, q)})` ); setMemoryVecMeta({ vecLoaded: true, activeDim: dim }); return { ready: true, reason: `vec_memories created with dim=${dim} (${q})` }; @@ -207,8 +207,7 @@ class VectorStoreImpl implements VectorStore { // Map UUID memoryId → INTEGER rowid (the rowid is used as the FK into vec_memories). const row = db.prepare("SELECT rowid FROM memories WHERE id = ?").get(memoryId) as - | { rowid: number } - | undefined; + { rowid: number } | undefined; if (!row) { throw new Error(`memory not found: ${memoryId}`); @@ -222,7 +221,7 @@ class VectorStoreImpl implements VectorStore { db.prepare("DELETE FROM vec_memories WHERE rowid = ?").run(BigInt(row.rowid)); db.prepare(`INSERT INTO vec_memories(rowid, embedding) VALUES (?, ${vecValueExpr(q)})`).run( BigInt(row.rowid), - encodeVector(vector), + encodeVector(vector) ); } catch (err: unknown) { // Self-heal: a concurrent ensureReady()'s reset raced ahead of us and @@ -232,7 +231,7 @@ class VectorStoreImpl implements VectorStore { db.prepare("DELETE FROM vec_memories WHERE rowid = ?").run(BigInt(row.rowid)); db.prepare(`INSERT INTO vec_memories(rowid, embedding) VALUES (?, ${vecValueExpr(q)})`).run( BigInt(row.rowid), - encodeVector(vector), + encodeVector(vector) ); } } @@ -241,7 +240,7 @@ class VectorStoreImpl implements VectorStore { const db = getDbInstance(); try { db.prepare( - "DELETE FROM vec_memories WHERE rowid = (SELECT rowid FROM memories WHERE id = ?)", + "DELETE FROM vec_memories WHERE rowid = (SELECT rowid FROM memories WHERE id = ?)" ).run(memoryId); } catch (err: unknown) { if (!isMissingVecTableError(err)) throw err; @@ -254,7 +253,7 @@ class VectorStoreImpl implements VectorStore { async searchVector( vector: Float32Array, topK: number, - apiKeyId?: string, + apiKeyId?: string ): Promise { const db = getDbInstance(); const k = topK > 0 ? topK : TOP_K_DEFAULT; @@ -268,12 +267,12 @@ class VectorStoreImpl implements VectorStore { WHERE v.embedding MATCH ${vecValueExpr(q)} AND ($apiKeyId IS NULL OR m.api_key_id = $apiKeyId) AND k = ? - ORDER BY v.distance ASC`, + ORDER BY v.distance ASC` ) .all(encodeVector(vector), { apiKeyId: apiKeyId ?? null }, k) as Array<{ - memory_id: string; - distance: number; - }>; + memory_id: string; + distance: number; + }>; return rows.map((r) => ({ memoryId: r.memory_id, @@ -286,7 +285,7 @@ class VectorStoreImpl implements VectorStore { vector: Float32Array, queryText: string, topK: number, - apiKeyId?: string, + apiKeyId?: string ): Promise { const db = getDbInstance(); const k = topK > 0 ? topK : TOP_K_DEFAULT; @@ -338,23 +337,16 @@ class VectorStoreImpl implements VectorStore { SELECT memory_id, vec_rank, fts_rank, vec_distance, fts_score, rrf_score FROM fused ORDER BY rrf_score DESC - LIMIT ?`, + LIMIT ?` ) - .all( - encodeVector(vector), - { apiKeyId: apiKeyId ?? null }, - k, - queryText, - k, - k, - ) as Array<{ - memory_id: string; - vec_rank: number | null; - fts_rank: number | null; - vec_distance: number | null; - fts_score: number | null; - rrf_score: number; - }>; + .all(encodeVector(vector), { apiKeyId: apiKeyId ?? null }, k, queryText, k, k) as Array<{ + memory_id: string; + vec_rank: number | null; + fts_rank: number | null; + vec_distance: number | null; + fts_score: number | null; + rrf_score: number; + }>; return rows.map((r) => ({ memoryId: r.memory_id, @@ -376,8 +368,7 @@ class VectorStoreImpl implements VectorStore { try { const db = getDbInstance(); const row = db.prepare("SELECT COUNT(*) AS cnt FROM vec_memories").get() as - | { cnt: number } - | undefined; + { cnt: number } | undefined; rowCount = row?.cnt ?? 0; } catch { // vec_memories may not exist yet — not an error, just 0 rows. @@ -431,7 +422,7 @@ export function getVectorStore(): VectorStore | null { // Test seam: VECTOR_STORE_DISABLE_VEC=true forces null (simulates cloud/WASM environment). if (process.env["VECTOR_STORE_DISABLE_VEC"] === "true") { log.warn( - "VECTOR_STORE_DISABLE_VEC is set — sqlite-vec disabled. Degrading to FTS5 keyword search.", + "VECTOR_STORE_DISABLE_VEC is set — sqlite-vec disabled. Degrading to FTS5 keyword search." ); _instance = null; return null; @@ -445,7 +436,7 @@ export function getVectorStore(): VectorStore | null { if (!raw || typeof raw.loadExtension !== "function") { log.warn( "sqlite-vec not loaded: db driver does not support loadExtension (cloud/WASM backend). " + - "Degrading to FTS5 keyword search.", + "Degrading to FTS5 keyword search." ); _instance = null; return null; diff --git a/src/lib/modelsDevSync.ts b/src/lib/modelsDevSync.ts index c4c0f2f273..1400ad7ed4 100644 --- a/src/lib/modelsDevSync.ts +++ b/src/lib/modelsDevSync.ts @@ -770,7 +770,7 @@ export async function initModelsDevSync(): Promise { return; } - const { getSettings } = await import("./localDb"); + const { getSettings } = await import("@/lib/db/settings"); const settings = await getSettings(); if (!isModelsDevSyncEnvForcedOn() && settings.modelsDevSyncEnabled !== true) { diff --git a/src/lib/monitoring/providerHealthAutopilot.ts b/src/lib/monitoring/providerHealthAutopilot.ts index e29844da36..b5fed7d413 100644 --- a/src/lib/monitoring/providerHealthAutopilot.ts +++ b/src/lib/monitoring/providerHealthAutopilot.ts @@ -1,7 +1,7 @@ import { createHash } from "crypto"; import { getProviderConnections, updateProviderConnection } from "@/lib/db/providers"; -import { getCachedProviderConnectionById } from "@/lib/localDb"; +import { getCachedProviderConnectionById } from "@/lib/db/readCache"; import { clearProviderFailure, clearModelLock } from "@omniroute/open-sse/services/accountFallback"; import { resolveProviderAlias } from "@omniroute/open-sse/services/model"; diff --git a/src/lib/oauth/utils/agyAuthImport.ts b/src/lib/oauth/utils/agyAuthImport.ts index d0a526eb23..c7c4e42a3c 100644 --- a/src/lib/oauth/utils/agyAuthImport.ts +++ b/src/lib/oauth/utils/agyAuthImport.ts @@ -2,7 +2,7 @@ import { getProviderConnections, createProviderConnection, updateProviderConnection, -} from "@/lib/localDb"; +} from "@/lib/db/providers"; import { AGY_CONFIG } from "@/lib/oauth/constants/oauth"; import { getAntigravityContentHeaders, diff --git a/src/lib/oauth/utils/claudeAuthFile.ts b/src/lib/oauth/utils/claudeAuthFile.ts index 681c0eaab0..0f265e9039 100644 --- a/src/lib/oauth/utils/claudeAuthFile.ts +++ b/src/lib/oauth/utils/claudeAuthFile.ts @@ -1,6 +1,6 @@ import fs from "fs/promises"; import path from "path"; -import { getCachedProviderConnectionById } from "@/lib/localDb"; +import { getCachedProviderConnectionById } from "@/lib/db/readCache"; import { createBackup } from "@/shared/services/backupService"; import { getCliConfigPaths } from "@/shared/services/cliRuntime"; import { @@ -172,7 +172,9 @@ export function buildClaudeAuthPayload(connection: ClaudeConnectionLike): Claude } async function resolveFreshClaudeConnection(connectionId: string): Promise { - const connection = (await getCachedProviderConnectionById(connectionId)) as ClaudeConnectionLike | null; + const connection = (await getCachedProviderConnectionById( + connectionId + )) as ClaudeConnectionLike | null; if (!connection) { throw new ClaudeAuthFileError("Connection not found", 404, "not_found"); } diff --git a/src/lib/oauth/utils/claudeAuthImport.ts b/src/lib/oauth/utils/claudeAuthImport.ts index fb0a6aa000..2a5a444436 100644 --- a/src/lib/oauth/utils/claudeAuthImport.ts +++ b/src/lib/oauth/utils/claudeAuthImport.ts @@ -3,7 +3,7 @@ import { getProviderConnections, createProviderConnection, updateProviderConnection, -} from "@/lib/localDb"; +} from "@/lib/db/providers"; import { getClaudeCodeUserAgent } from "@/shared/constants/claudeCodeClient"; import { ClaudeAuthFileError } from "@/lib/oauth/utils/claudeAuthFile"; diff --git a/src/lib/oauth/utils/codexAuthFile.ts b/src/lib/oauth/utils/codexAuthFile.ts index e17875766e..8b505d7b38 100644 --- a/src/lib/oauth/utils/codexAuthFile.ts +++ b/src/lib/oauth/utils/codexAuthFile.ts @@ -1,6 +1,6 @@ import fs from "fs/promises"; import path from "path"; -import { getCachedProviderConnectionById } from "@/lib/localDb"; +import { getCachedProviderConnectionById } from "@/lib/db/readCache"; import { createBackup } from "@/shared/services/backupService"; import { getCliConfigPaths } from "@/shared/services/cliRuntime"; import { @@ -197,7 +197,9 @@ function buildCodexAuthPayload(connection: CodexConnectionLike): CodexAuthFilePa } async function resolveFreshCodexConnection(connectionId: string): Promise { - const connection = (await getCachedProviderConnectionById(connectionId)) as CodexConnectionLike | null; + const connection = (await getCachedProviderConnectionById( + connectionId + )) as CodexConnectionLike | null; if (!connection) { throw new CodexAuthFileError("Connection not found", 404, "not_found"); } @@ -377,7 +379,11 @@ export type CodexAuthWriteDecision = export async function writeCodexAuthFileToLocalCliIfNeeded( connectionId: string, options: { force?: boolean } = {} -): Promise<{ decision: CodexAuthWriteDecision; authPath: string | null; result?: Awaited> }> { +): Promise<{ + decision: CodexAuthWriteDecision; + authPath: string | null; + result?: Awaited>; +}> { const paths = getCliConfigPaths("codex"); const authPath = paths?.auth ?? null; diff --git a/src/lib/oauth/utils/codexAuthImport.ts b/src/lib/oauth/utils/codexAuthImport.ts index 3ac22e09ca..4d16a3d1e6 100644 --- a/src/lib/oauth/utils/codexAuthImport.ts +++ b/src/lib/oauth/utils/codexAuthImport.ts @@ -2,7 +2,7 @@ import { getProviderConnections, createProviderConnection, updateProviderConnection, -} from "@/lib/localDb"; +} from "@/lib/db/providers"; import { CodexAuthFileError } from "@/lib/oauth/utils/codexAuthFile"; import { pickCodexConnectionForUser } from "@/lib/oauth/utils/codexConnectionSelection"; diff --git a/src/lib/providerModels/managedAvailableModels.ts b/src/lib/providerModels/managedAvailableModels.ts index b193fa4066..407022644c 100644 --- a/src/lib/providerModels/managedAvailableModels.ts +++ b/src/lib/providerModels/managedAvailableModels.ts @@ -2,9 +2,9 @@ import { deleteModelAlias, getModelAliases, getModelIsHidden, - getProviderNodeById, setModelAlias, -} from "@/lib/localDb"; +} from "@/lib/db/models"; +import { getProviderNodeById } from "@/lib/db/providers"; import { getProviderAlias, isAnthropicCompatibleProvider, diff --git a/src/lib/proxyEgress.ts b/src/lib/proxyEgress.ts index 1996bec763..af7ab5ded5 100644 --- a/src/lib/proxyEgress.ts +++ b/src/lib/proxyEgress.ts @@ -313,7 +313,7 @@ export async function diagnoseAllEgressIps(deps?: { const getConnections = deps?.getConnections ?? (async () => { - const { getProviderConnections } = await import("./localDb"); + const { getProviderConnections } = await import("@/lib/db/providers"); return (await getProviderConnections({ authType: "oauth" })) as Array<{ id: string; provider: string; diff --git a/src/lib/proxyHealth/scheduler.ts b/src/lib/proxyHealth/scheduler.ts index dc30453a34..8bf026ac33 100644 --- a/src/lib/proxyHealth/scheduler.ts +++ b/src/lib/proxyHealth/scheduler.ts @@ -22,7 +22,7 @@ * same threshold, not independently tunable. */ -import { deleteProxyById, listProxies, updateProxy } from "@/lib/localDb"; +import { deleteProxyById, listProxies, updateProxy } from "@/lib/db/proxies"; import { isProxyLogIncludeIps } from "@/lib/proxyLogger"; import { getRecentEgressSharingSummary, diff --git a/src/lib/quota/connectionProvider.ts b/src/lib/quota/connectionProvider.ts index 3255bffad6..df81842aa7 100644 --- a/src/lib/quota/connectionProvider.ts +++ b/src/lib/quota/connectionProvider.ts @@ -18,7 +18,7 @@ export async function resolveConnectionProvider(connectionId: string): Promise { try { // Lazy import — avoids circular deps and keeps the module loadable without a full DB. - const { getCachedProviderConnectionById } = await import("@/lib/localDb"); + const { getCachedProviderConnectionById } = await import("@/lib/db/readCache"); if (typeof getCachedProviderConnectionById === "function") { const conn = await getCachedProviderConnectionById(connectionId); if (conn && typeof (conn as { provider?: string }).provider === "string") { diff --git a/src/lib/quota/planResolver.ts b/src/lib/quota/planResolver.ts index a8a02647a7..aa04f3199b 100644 --- a/src/lib/quota/planResolver.ts +++ b/src/lib/quota/planResolver.ts @@ -12,7 +12,7 @@ * Part of: Group B — Quota Sharing Engine (plan 22, frente F6). */ -import { getProviderPlan } from "@/lib/localDb"; +import { getPlan as getProviderPlan } from "@/lib/db/providerPlans"; import { getKnownPlan } from "./planRegistry"; import type { ProviderPlan } from "./dimensions"; diff --git a/src/lib/quota/quotaCombos.ts b/src/lib/quota/quotaCombos.ts index 39dbe75a4a..07b7e12a28 100644 --- a/src/lib/quota/quotaCombos.ts +++ b/src/lib/quota/quotaCombos.ts @@ -12,7 +12,7 @@ import { getPool } from "@/lib/db/quotaPools"; import { getGroupName } from "@/lib/db/quotaGroups"; -import { getCachedProviderConnectionById } from "@/lib/localDb"; +import { getCachedProviderConnectionById } from "@/lib/db/readCache"; import { getCombos, createCombo, diff --git a/src/lib/quota/quotaKey.ts b/src/lib/quota/quotaKey.ts index 7207798bcc..9f80068120 100644 --- a/src/lib/quota/quotaKey.ts +++ b/src/lib/quota/quotaKey.ts @@ -8,7 +8,7 @@ */ import { getPool, getPoolsByGroup } from "@/lib/db/quotaPools"; -import { getCachedProviderConnectionById } from "@/lib/localDb"; +import { getCachedProviderConnectionById } from "@/lib/db/readCache"; import { getApiKeyById, updateApiKeyPermissions } from "@/lib/db/apiKeys"; import { quotaGroupSlug } from "./quotaModelNaming"; import { getGroupName } from "@/lib/db/quotaGroups"; @@ -163,7 +163,7 @@ export async function reconcilePoolExclusivity( poolId: string, prevApiKeyIds: string[], nextApiKeyIds: string[], - exclusive: boolean, + exclusive: boolean ): Promise { const affectedIds = new Set([...prevApiKeyIds, ...nextApiKeyIds]); @@ -173,7 +173,7 @@ export async function reconcilePoolExclusivity( if (!keyRow) continue; const currentQuotas: string[] = Array.isArray( - (keyRow as Record).allowedQuotas, + (keyRow as Record).allowedQuotas ) ? ((keyRow as Record).allowedQuotas as string[]) : []; diff --git a/src/lib/quota/redisQuotaStore.ts b/src/lib/quota/redisQuotaStore.ts index d9d17309ed..7ff3588a1e 100644 --- a/src/lib/quota/redisQuotaStore.ts +++ b/src/lib/quota/redisQuotaStore.ts @@ -16,10 +16,7 @@ * Part of: Group B — Quota Sharing Engine (plan 22, frente F6). */ -import { - getPool, - listAllocationsForApiKey, -} from "@/lib/localDb"; +import { getPool, listAllocationsForApiKey } from "@/lib/db/quotaPools"; import { WINDOW_MS, dimensionKeyToString } from "./dimensions"; import type { DimensionKey } from "./dimensions"; import type { QuotaStore, PoolUsageSnapshot } from "./types"; diff --git a/src/lib/quota/saturationSignals.ts b/src/lib/quota/saturationSignals.ts index 93d3d42690..0eee4331dc 100644 --- a/src/lib/quota/saturationSignals.ts +++ b/src/lib/quota/saturationSignals.ts @@ -306,10 +306,7 @@ async function fetchCodexSaturation( return Math.min(1, Math.max(0, quota.percentUsed ?? 0)); } -async function fetchBailianSaturation( - connectionId: string, - dim: DimensionSpec -): Promise { +async function fetchBailianSaturation(connectionId: string, dim: DimensionSpec): Promise { const mod = await import("@omniroute/open-sse/services/bailianQuotaFetcher"); const quota = await mod.fetchBailianQuota(connectionId); if (!quota) return 0; @@ -318,13 +315,13 @@ async function fetchBailianSaturation( let pct = 0; switch (dim.window) { case "5h": - pct = (q.window5h as Record)?.percentUsed as number ?? 0; + pct = ((q.window5h as Record)?.percentUsed as number) ?? 0; break; case "weekly": - pct = (q.windowWeekly as Record)?.percentUsed as number ?? 0; + pct = ((q.windowWeekly as Record)?.percentUsed as number) ?? 0; break; case "monthly": - pct = (q.windowMonthly as Record)?.percentUsed as number ?? 0; + pct = ((q.windowMonthly as Record)?.percentUsed as number) ?? 0; break; default: pct = (q.percentUsed as number) ?? 0; @@ -361,15 +358,13 @@ interface AnthropicSaturationDeps { let _anthropicDepsOverride: AnthropicSaturationDeps | null = null; /** Test-only: inject ({loadConnection, fetchUsage}); pass null to restore. */ -export function __setAnthropicSaturationDepsForTests( - deps: AnthropicSaturationDeps | null -): void { +export function __setAnthropicSaturationDepsForTests(deps: AnthropicSaturationDeps | null): void { _anthropicDepsOverride = deps; } async function defaultAnthropicDeps(): Promise { const [localDbMod, usageMod] = await Promise.all([ - import("@/lib/localDb"), + import("@/lib/db/readCache"), import("@omniroute/open-sse/services/usage"), ]); return { @@ -423,10 +418,7 @@ function planUtilizationFromUsage(usage: unknown, window: QuotaWindow): number | return Math.min(1, Math.max(0, used / 100)); } -async function fetchAnthropicSaturation( - connectionId: string, - dim: DimensionSpec -): Promise { +async function fetchAnthropicSaturation(connectionId: string, dim: DimensionSpec): Promise { // Try the REAL plan-window utilization first (5h / weekly), via the same // /api/oauth/usage path usage.ts already uses. This is the signal fairShare // actually needs for Claude Pro/Max — the per-minute request headers do not @@ -478,19 +470,13 @@ export function __setGenericUsageFetcherForTests(fetcher: GenericUsageFetcher | _genericUsageFetcherOverride = fetcher; } -async function defaultGenericUsageFetch( - connectionId: string, - provider: string -): Promise { +async function defaultGenericUsageFetch(connectionId: string, provider: string): Promise { const mod = await import("@omniroute/open-sse/services/usage"); const conn = { id: connectionId, provider } as Parameters[0]; return mod.getUsageForProvider(conn); } -async function fetchGenericSaturation( - connectionId: string, - provider: string -): Promise { +async function fetchGenericSaturation(connectionId: string, provider: string): Promise { // 1. Real usage percent is authoritative when present (a provider that // actually reports utilization beats the burst-window token headers). try { @@ -501,9 +487,8 @@ async function fetchGenericSaturation( // Prefer the normalized quota shape (handles nested `quotas` map for // Antigravity / Claude / etc.). Fall back to legacy top-level fields. - const { convertUsageToQuotaInfo } = await import( - "@omniroute/open-sse/services/genericQuotaFetcher" - ); + const { convertUsageToQuotaInfo } = + await import("@omniroute/open-sse/services/genericQuotaFetcher"); const quota = convertUsageToQuotaInfo(result); if (quota && Number.isFinite(quota.percentUsed)) { return Math.min(1, Math.max(0, quota.percentUsed)); @@ -570,7 +555,10 @@ export async function getSaturation( break; } } catch (err) { - log.warn({ err: (err as Error)?.message, connectionId, provider }, "saturation fetch failed — failing open with 0"); + log.warn( + { err: (err as Error)?.message, connectionId, provider }, + "saturation fetch failed — failing open with 0" + ); value = 0; } diff --git a/src/lib/quota/sqliteQuotaStore.ts b/src/lib/quota/sqliteQuotaStore.ts index dab40da91f..8685e68c85 100644 --- a/src/lib/quota/sqliteQuotaStore.ts +++ b/src/lib/quota/sqliteQuotaStore.ts @@ -15,7 +15,8 @@ * Part of: Group B — Quota Sharing Engine (plan 22, frente F6). */ -import { getPool, getBucket, incrementBucket, getPair, sumPoolDimension } from "@/lib/localDb"; +import { getPool } from "@/lib/db/quotaPools"; +import { getBucket, incrementBucket, getPair, sumPoolDimension } from "@/lib/db/quotaConsumption"; import { WINDOW_MS, dimensionKeyToString } from "./dimensions"; import type { DimensionKey } from "./dimensions"; import type { QuotaStore, PoolUsageSnapshot } from "./types"; diff --git a/src/lib/services/quotaAutoPing.ts b/src/lib/services/quotaAutoPing.ts index 4a9ce8fe3e..21c6466b52 100644 --- a/src/lib/services/quotaAutoPing.ts +++ b/src/lib/services/quotaAutoPing.ts @@ -25,7 +25,8 @@ import { sanitizeErrorMessage } from "@omniroute/open-sse/utils/error.ts"; import { getExecutor } from "@omniroute/open-sse/executors/index.ts"; import type { BaseExecutor } from "@omniroute/open-sse/executors/base"; import { getCodexUsage } from "@omniroute/open-sse/services/usage/codex.ts"; -import { getSettings, getProviderConnections, updateProviderConnection } from "@/lib/localDb"; +import { getSettings } from "@/lib/db/settings"; +import { getProviderConnections, updateProviderConnection } from "@/lib/db/providers"; import { isConnectionUnavailableToAuxiliaryActivity } from "@/lib/exclusiveLeaseIsolation"; import { refreshAndUpdateCredentials } from "@/lib/usage/providerLimits"; import { getCircuitBreaker } from "@/shared/utils/circuitBreaker"; @@ -57,17 +58,12 @@ export interface QuotaAutoPingConnection { export interface QuotaAutoPingDeps { getSettings: () => Promise; - getProviderConnections: ( - filter: JsonRecord - ) => Promise; + getProviderConnections: (filter: JsonRecord) => Promise; updateProviderConnection: (id: string, data: JsonRecord) => Promise; refreshAndUpdateCredentials: ( connection: QuotaAutoPingConnection ) => Promise<{ connection: QuotaAutoPingConnection }>; - getCodexUsage: ( - accessToken?: string, - providerSpecificData?: JsonRecord - ) => Promise; + getCodexUsage: (accessToken?: string, providerSpecificData?: JsonRecord) => Promise; getExecutor: (provider: string) => Promise; canExecuteProvider: (provider: string) => boolean; isConnectionUnavailableToAuxiliaryActivity: (connectionId: string) => Promise; @@ -152,11 +148,7 @@ function wasPingedRecently( return Number.isFinite(lastPingAtMs) && nowMs - lastPingAtMs < intervalMs; } -function shouldSkipAfterFailure( - state: QuotaAutoPingState, - key: string, - nowMs: number -): boolean { +function shouldSkipAfterFailure(state: QuotaAutoPingState, key: string, nowMs: number): boolean { const failedAt = state.failureCache[key]; return Boolean(failedAt) && nowMs - failedAt < QUOTA_AUTOPING_FAILURE_COOLDOWN_MS; } @@ -272,8 +264,8 @@ async function isPingCandidateBlocked( // resetAt — the guard is preserved here for that case. return Boolean( !providerConfig.pingWhenResetAtSlides && - cachedReset && - nowMs < new Date(cachedReset).getTime() - QUOTA_AUTOPING_REFRESH_AHEAD_MS + cachedReset && + nowMs < new Date(cachedReset).getTime() - QUOTA_AUTOPING_REFRESH_AHEAD_MS ); } @@ -331,7 +323,18 @@ async function pingConnection( ): Promise { const key = cacheKey(provider, connection.id); const cachedReset = state.resetCache[key]; - if (await isPingCandidateBlocked(connection, provider, providerConfig, deps, state, key, cachedReset, nowMs)) { + if ( + await isPingCandidateBlocked( + connection, + provider, + providerConfig, + deps, + state, + key, + cachedReset, + nowMs + ) + ) { return; } @@ -346,7 +349,9 @@ async function pingConnection( state.resetCache[key] = resetAt; const resetKey = normalizeResetKey(resetAt); - if (!shouldSendPing(providerConfig, quotas, quota, cachedReset, resetAt, current, resetKey, nowMs)) { + if ( + !shouldSendPing(providerConfig, quotas, quota, cachedReset, resetAt, current, resetKey, nowMs) + ) { return; } @@ -371,8 +376,7 @@ function getEnabledConnectionIds( ): Record { return ( ((settings[providerConfig.settingsKey] as JsonRecord | undefined)?.connections as - | Record - | undefined) || {} + Record | undefined) || {} ); } diff --git a/src/lib/sync/bundle.ts b/src/lib/sync/bundle.ts index 3f13edf8fa..46e5100b3a 100644 --- a/src/lib/sync/bundle.ts +++ b/src/lib/sync/bundle.ts @@ -1,13 +1,11 @@ import { createHash } from "crypto"; -import { - getApiKeys, - getCombos, - getModelAliases, - getProviderConnections, - getCachedProviderNodes, - getSettings, - getReasoningRoutingRules, -} from "@/lib/localDb"; +import { getApiKeys } from "@/lib/db/apiKeys"; +import { getCombos } from "@/lib/db/combos"; +import { getModelAliases } from "@/lib/db/models"; +import { getProviderConnections } from "@/lib/db/providers"; +import { getCachedProviderNodes } from "@/lib/db/readCache"; +import { getSettings } from "@/lib/db/settings"; +import { getReasoningRoutingRules } from "@/lib/db/reasoningRoutingRules"; type JsonRecord = Record; diff --git a/src/lib/tokenHealthCheck.ts b/src/lib/tokenHealthCheck.ts index b3a4e2e074..2820a28e23 100644 --- a/src/lib/tokenHealthCheck.ts +++ b/src/lib/tokenHealthCheck.ts @@ -11,13 +11,9 @@ * updates the DB, and logs the result. */ -import { - getProviderConnections, - getCachedProviderConnectionById, - updateProviderConnection, - getSettings, - resolveProxyForConnection, -} from "@/lib/localDb"; +import { getProviderConnections, updateProviderConnection } from "@/lib/db/providers"; +import { getCachedProviderConnectionById } from "@/lib/db/readCache"; +import { getSettings, resolveProxyForConnection } from "@/lib/db/settings"; import { getAccessToken, getDeprecationNotice, diff --git a/src/lib/tokenHealthCheckCopilot.ts b/src/lib/tokenHealthCheckCopilot.ts index f2c58ef362..bd1a9ea078 100644 --- a/src/lib/tokenHealthCheckCopilot.ts +++ b/src/lib/tokenHealthCheckCopilot.ts @@ -10,7 +10,7 @@ * frozen file-size budget (see config/quality/file-size-baseline.json). */ -import { getProviderConnectionById, updateProviderConnection } from "@/lib/localDb"; +import { getProviderConnectionById, updateProviderConnection } from "@/lib/db/providers"; import { refreshCopilotToken } from "@omniroute/open-sse/services/tokenRefresh.ts"; type HealthCheckLogger = { @@ -30,8 +30,17 @@ export async function refreshGithubCopilotSubTokenIfNeeded(params: { getConnectionLogLabel: (conn: { name?: string; email?: string; id?: string }) => string; logPrefix: string; }): Promise { - const { conn, result, proxyConfig, healthCheckLog, log, logWarn, logError, getConnectionLogLabel, logPrefix } = - params; + const { + conn, + result, + proxyConfig, + healthCheckLog, + log, + logWarn, + logError, + getConnectionLogLabel, + logPrefix, + } = params; if (String(conn.provider || "").toLowerCase() !== "github") return; @@ -58,7 +67,11 @@ export async function refreshGithubCopilotSubTokenIfNeeded(params: { log(`${logPrefix} Refreshing GitHub Copilot sub-token for ${getConnectionLogLabel(conn)}`); try { - const copilotResult = await refreshCopilotToken(accessTokenForCopilot, healthCheckLog, proxyConfig); + const copilotResult = await refreshCopilotToken( + accessTokenForCopilot, + healthCheckLog, + proxyConfig + ); if (copilotResult?.token) { await updateProviderConnection(conn.id, { providerSpecificData: { @@ -69,7 +82,9 @@ export async function refreshGithubCopilotSubTokenIfNeeded(params: { }); log(`${logPrefix} ✓ GitHub Copilot sub-token refreshed for ${getConnectionLogLabel(conn)}`); } else { - logWarn(`${logPrefix} ✗ GitHub Copilot sub-token refresh failed for ${getConnectionLogLabel(conn)}`); + logWarn( + `${logPrefix} ✗ GitHub Copilot sub-token refresh failed for ${getConnectionLogLabel(conn)}` + ); } } catch (copilotErr) { logError(`${logPrefix} Error refreshing Copilot sub-token:`, copilotErr?.message || copilotErr); diff --git a/src/lib/usage/apiKeySelfService.ts b/src/lib/usage/apiKeySelfService.ts index 1e7237e12c..2e9dc9ffa7 100644 --- a/src/lib/usage/apiKeySelfService.ts +++ b/src/lib/usage/apiKeySelfService.ts @@ -1,7 +1,4 @@ -import { - hasSelfAccountQuotaScope, - hasSelfUsageScope, -} from "@/shared/constants/selfServiceScopes"; +import { hasSelfAccountQuotaScope, hasSelfUsageScope } from "@/shared/constants/selfServiceScopes"; import { USAGE_SUPPORTED_PROVIDERS } from "@/shared/constants/providers"; type JsonRecord = Record; @@ -363,7 +360,7 @@ async function normalizeDeps(deps: ApiKeySelfServiceDeps): Promise const localDb = deps.getProviderConnectionById && deps.getProviderConnections ? null - : await import("@/lib/localDb"); + : await import("@/lib/db/providers"); const providerLimits = deps.fetchAndPersistProviderLimits ? null : await import("@/lib/usage/providerLimits"); @@ -396,11 +393,11 @@ export async function buildApiKeySelfServiceStatus( const tokens = aggregateTokens( resolvedDeps.getDbInstance() as DbLike, metadata.id, - cost.periodStartAt ?? new Date(getCurrentMonthWindow(resolvedDeps.now()).periodStartAt).toISOString() + cost.periodStartAt ?? + new Date(getCurrentMonthWindow(resolvedDeps.now()).periodStartAt).toISOString() ); const accountQuotas = await resolveAccountQuotas(metadata, resolvedDeps); - const accountQuota = - accountQuotas && accountQuotas.length === 1 ? accountQuotas[0] : undefined; + const accountQuota = accountQuotas && accountQuotas.length === 1 ? accountQuotas[0] : undefined; return { apiKey: { diff --git a/src/lib/usage/callLogs.ts b/src/lib/usage/callLogs.ts index 5e3c878c0c..029bc7ee2f 100644 --- a/src/lib/usage/callLogs.ts +++ b/src/lib/usage/callLogs.ts @@ -140,7 +140,7 @@ async function resolveAccountName(connectionId: string | null | undefined) { } try { - const { getProviderConnections } = await import("@/lib/localDb"); + const { getProviderConnections } = await import("@/lib/db/providers"); const connections = await getProviderConnections(); const conn = connections.find((item) => item.id === connectionId); if (conn) { @@ -160,7 +160,7 @@ async function resolveAccountName(connectionId: string | null | undefined) { async function resolveProviderPrefix(providerId: string): Promise { if (!providerId) return null; try { - const { getProviderNodeById } = await import("@/lib/localDb"); + const { getProviderNodeById } = await import("@/lib/db/providers"); const node = await getProviderNodeById(providerId); if (node && typeof node.prefix === "string" && node.prefix.trim().length > 0) { return node.prefix.trim(); diff --git a/src/lib/usage/codexResetCredits.ts b/src/lib/usage/codexResetCredits.ts index ab54b40a9d..9a341101b4 100644 --- a/src/lib/usage/codexResetCredits.ts +++ b/src/lib/usage/codexResetCredits.ts @@ -1,4 +1,5 @@ -import { getProviderConnectionById, resolveProxyForConnection } from "@/lib/localDb"; +import { getProviderConnectionById } from "@/lib/db/providers"; +import { resolveProxyForConnection } from "@/lib/db/settings"; import { isConnectionUnavailableToAuxiliaryActivity } from "@/lib/exclusiveLeaseIsolation"; import { fetchAndPersistProviderLimits, diff --git a/src/lib/usage/costCalculator.ts b/src/lib/usage/costCalculator.ts index 08151ac1aa..106b7f8c4c 100644 --- a/src/lib/usage/costCalculator.ts +++ b/src/lib/usage/costCalculator.ts @@ -187,7 +187,7 @@ export async function calculateCost( if (exactCostUsd !== null) return exactCostUsd; try { - const { getPricingForModel } = await import("@/lib/localDb"); + const { getPricingForModel } = await import("@/lib/db/settings"); // Try exact match first, then normalized model name let pricing = await getPricingForModel(provider, model); @@ -303,7 +303,7 @@ export async function calculateModalCost( ): Promise { if (!provider || !model) return 0; try { - const { getPricingForModel } = await import("@/lib/localDb"); + const { getPricingForModel } = await import("@/lib/db/settings"); let pricing = await getPricingForModel(provider, model); if (!pricing) { const normalized = normalizeModelName(model); diff --git a/src/lib/usage/internalUsageCommand.ts b/src/lib/usage/internalUsageCommand.ts index 37f5f009d1..e106cced51 100644 --- a/src/lib/usage/internalUsageCommand.ts +++ b/src/lib/usage/internalUsageCommand.ts @@ -99,7 +99,7 @@ async function normalizeDeps(deps: InternalUsageCommandDeps = {}): Promise { const [{ getCachedSettings }, { resolveResilienceSettings }] = await Promise.all([ - import("@/lib/localDb"), + import("@/lib/db/readCache"), import("@/lib/resilience/settings"), ]); const resilience = resolveResilienceSettings(await getCachedSettings()); @@ -829,7 +829,10 @@ export async function handleInternalUsageCommandHttpRequest( if (!apiKey || !(await resolvedDeps.isValidApiKey(apiKey))) { if (json) { return Response.json( - { allowed: false, error: { message: USAGE_COMMAND_AUTH_REQUIRED_MESSAGE } } satisfies UsageCommandJson, + { + allowed: false, + error: { message: USAGE_COMMAND_AUTH_REQUIRED_MESSAGE }, + } satisfies UsageCommandJson, { status: 401 } ); } @@ -840,7 +843,10 @@ export async function handleInternalUsageCommandHttpRequest( if (!metadata?.id) { if (json) { return Response.json( - { allowed: false, error: { message: USAGE_COMMAND_AUTH_REQUIRED_MESSAGE } } satisfies UsageCommandJson, + { + allowed: false, + error: { message: USAGE_COMMAND_AUTH_REQUIRED_MESSAGE }, + } satisfies UsageCommandJson, { status: 401 } ); } @@ -850,7 +856,10 @@ export async function handleInternalUsageCommandHttpRequest( if (metadata.allowUsageCommand !== true) { if (json) { return Response.json( - { allowed: false, error: { message: USAGE_COMMAND_DISABLED_MESSAGE } } satisfies UsageCommandJson, + { + allowed: false, + error: { message: USAGE_COMMAND_DISABLED_MESSAGE }, + } satisfies UsageCommandJson, { status: 403 } ); } diff --git a/src/lib/usage/usageStats.ts b/src/lib/usage/usageStats.ts index b4be4d1967..573f66b2c0 100644 --- a/src/lib/usage/usageStats.ts +++ b/src/lib/usage/usageStats.ts @@ -285,7 +285,7 @@ export async function getUsageStats() { const sourceSql = buildUsageSourceSql(aggregationEnabled); const sourceParams = aggregationEnabled && cutoffDate ? [cutoffDate, cutoffDate] : []; - const { getProviderConnections } = await import("@/lib/localDb"); + const { getProviderConnections } = await import("@/lib/db/providers"); let allConnections: unknown[] = []; try { const loadedConnections = await getProviderConnections(); diff --git a/src/lib/usageAnalytics.ts b/src/lib/usageAnalytics.ts index 386a3d6e34..459d8e1895 100644 --- a/src/lib/usageAnalytics.ts +++ b/src/lib/usageAnalytics.ts @@ -149,7 +149,7 @@ export async function computeAnalytics( // Pre-fetch pricing for all unique (provider, model) pairs — one DB round-trip // per unique pair instead of one per entry, then compute costs synchronously. - const { getPricingForModel } = await import("@/lib/localDb"); + const { getPricingForModel } = await import("@/lib/db/settings"); const pricingCache = new Map | null>(); const uniquePairs = new Set(entries.map((e) => `${e.provider}|||${e.model}`)); await Promise.all( diff --git a/src/lib/ws/handshake.ts b/src/lib/ws/handshake.ts index 8fafc39b53..454fbe9457 100644 --- a/src/lib/ws/handshake.ts +++ b/src/lib/ws/handshake.ts @@ -1,5 +1,5 @@ import { jwtVerify } from "jose"; -import { getSettings } from "@/lib/localDb"; +import { getSettings } from "@/lib/db/settings"; import { validateApiKey } from "@/lib/db/apiKeys"; export const DEFAULT_WS_PATH = "/v1/ws";