diff --git a/next.config.mjs b/next.config.mjs index ef7c9fb770..f066f1c8ad 100644 --- a/next.config.mjs +++ b/next.config.mjs @@ -6,7 +6,7 @@ const withNextIntl = createNextIntlPlugin("./src/i18n/request.ts"); const nextConfig = { turbopack: {}, output: "standalone", - serverExternalPackages: ["better-sqlite3"], + serverExternalPackages: ["better-sqlite3", "zod"], transpilePackages: ["@omniroute/open-sse"], allowedDevOrigins: ["192.168.*"], typescript: { diff --git a/package-lock.json b/package-lock.json index d7d686ce73..36e120b546 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "omniroute", - "version": "2.0.1", + "version": "2.0.3", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "omniroute", - "version": "2.0.1", + "version": "2.0.3", "hasInstallScript": true, "license": "MIT", "workspaces": [ diff --git a/src/lib/db/core.ts b/src/lib/db/core.ts index 4a86d91be7..7a433f3fff 100644 --- a/src/lib/db/core.ts +++ b/src/lib/db/core.ts @@ -79,6 +79,7 @@ const SCHEMA_SQL = ` token_type TEXT, consecutive_use_count INTEGER DEFAULT 0, rate_limit_protection INTEGER DEFAULT 0, + last_used_at TEXT, created_at TEXT NOT NULL, updated_at TEXT NOT NULL ); @@ -311,6 +312,10 @@ function ensureProviderConnectionsColumns(db: SqliteDatabase) { ); console.log("[DB] Added provider_connections.rate_limit_protection column"); } + if (!columnNames.has("last_used_at")) { + db.exec("ALTER TABLE provider_connections ADD COLUMN last_used_at TEXT"); + console.log("[DB] Added provider_connections.last_used_at column"); + } } catch (error: unknown) { const message = error instanceof Error ? error.message : String(error); console.warn("[DB] Failed to verify provider_connections schema:", message); @@ -483,7 +488,7 @@ function migrateFromJson(db: SqliteDatabase, jsonPath: string) { rate_limited_until, health_check_interval, last_health_check_at, last_tested, api_key, id_token, provider_specific_data, expires_in, display_name, global_priority, default_model, - token_type, consecutive_use_count, rate_limit_protection, created_at, updated_at + token_type, consecutive_use_count, rate_limit_protection, last_used_at, created_at, updated_at ) VALUES ( @id, @provider, @authType, @name, @email, @priority, @isActive, @accessToken, @refreshToken, @expiresAt, @tokenExpiresAt, @@ -492,7 +497,7 @@ function migrateFromJson(db: SqliteDatabase, jsonPath: string) { @rateLimitedUntil, @healthCheckInterval, @lastHealthCheckAt, @lastTested, @apiKey, @idToken, @providerSpecificData, @expiresIn, @displayName, @globalPriority, @defaultModel, - @tokenType, @consecutiveUseCount, @rateLimitProtection, @createdAt, @updatedAt + @tokenType, @consecutiveUseCount, @rateLimitProtection, @lastUsedAt, @createdAt, @updatedAt ) `); @@ -533,6 +538,7 @@ function migrateFromJson(db: SqliteDatabase, jsonPath: string) { defaultModel: conn.defaultModel || null, tokenType: conn.tokenType || null, consecutiveUseCount: conn.consecutiveUseCount || 0, + lastUsedAt: conn.lastUsedAt || null, rateLimitProtection: conn.rateLimitProtection === true || conn.rateLimitProtection === 1 ? 1 : 0, createdAt: conn.createdAt || new Date().toISOString(), diff --git a/src/lib/db/providers.ts b/src/lib/db/providers.ts index a697f2c6d5..40491b1e28 100644 --- a/src/lib/db/providers.ts +++ b/src/lib/db/providers.ts @@ -217,7 +217,7 @@ function _insertConnectionRow(db: DbLike, conn: JsonRecord) { rate_limited_until, health_check_interval, last_health_check_at, last_tested, api_key, id_token, provider_specific_data, expires_in, display_name, global_priority, default_model, - token_type, consecutive_use_count, rate_limit_protection, created_at, updated_at + token_type, consecutive_use_count, rate_limit_protection, last_used_at, created_at, updated_at ) VALUES ( @id, @provider, @authType, @name, @email, @priority, @isActive, @accessToken, @refreshToken, @expiresAt, @tokenExpiresAt, @@ -226,7 +226,7 @@ function _insertConnectionRow(db: DbLike, conn: JsonRecord) { @rateLimitedUntil, @healthCheckInterval, @lastHealthCheckAt, @lastTested, @apiKey, @idToken, @providerSpecificData, @expiresIn, @displayName, @globalPriority, @defaultModel, - @tokenType, @consecutiveUseCount, @rateLimitProtection, @createdAt, @updatedAt + @tokenType, @consecutiveUseCount, @rateLimitProtection, @lastUsedAt, @createdAt, @updatedAt ) ` ).run({ @@ -267,6 +267,7 @@ function _insertConnectionRow(db: DbLike, conn: JsonRecord) { consecutiveUseCount: conn.consecutiveUseCount || 0, rateLimitProtection: conn.rateLimitProtection === true || conn.rateLimitProtection === 1 ? 1 : 0, + lastUsedAt: conn.lastUsedAt || null, createdAt: conn.createdAt, updatedAt: conn.updatedAt, }); @@ -290,6 +291,7 @@ function _updateConnectionRow(db: DbLike, id: string, data: JsonRecord) { default_model = @defaultModel, token_type = @tokenType, consecutive_use_count = @consecutiveUseCount, rate_limit_protection = @rateLimitProtection, + last_used_at = @lastUsedAt, updated_at = @updatedAt WHERE id = @id ` @@ -331,6 +333,7 @@ function _updateConnectionRow(db: DbLike, id: string, data: JsonRecord) { consecutiveUseCount: data.consecutiveUseCount || 0, rateLimitProtection: data.rateLimitProtection === true || data.rateLimitProtection === 1 ? 1 : 0, + lastUsedAt: data.lastUsedAt || null, updatedAt: now, }); }