diff --git a/app/schemas/com.aicode.feature.agent.data.local.database.AgentDatabase/54.json b/app/schemas/com.aicode.feature.agent.data.local.database.AgentDatabase/54.json new file mode 100644 index 00000000..dbe66f61 --- /dev/null +++ b/app/schemas/com.aicode.feature.agent.data.local.database.AgentDatabase/54.json @@ -0,0 +1,903 @@ +{ + "formatVersion": 1, + "database": { + "version": 54, + "identityHash": "5072e48234836707b494d836c695b846", + "entities": [ + { + "tableName": "agent_messages", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `sessionId` TEXT NOT NULL, `role` TEXT NOT NULL, `content` TEXT NOT NULL, `timestamp` INTEGER NOT NULL, `toolCallsJson` TEXT, `toolCallId` TEXT, `toolName` TEXT, `toolArgs` TEXT, `isError` INTEGER NOT NULL, `reasoning` TEXT, `signature` TEXT, `attachmentsJson` TEXT, `isCompacted` INTEGER NOT NULL, `isContextSummary` INTEGER NOT NULL, `isCompactionMarker` INTEGER NOT NULL, `inputTokens` INTEGER NOT NULL, `outputTokens` INTEGER NOT NULL, `thinkingBlocksJson` TEXT, `cachedInputTokens` INTEGER NOT NULL, PRIMARY KEY(`id`))", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "sessionId", + "columnName": "sessionId", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "role", + "columnName": "role", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "content", + "columnName": "content", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "timestamp", + "columnName": "timestamp", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "toolCallsJson", + "columnName": "toolCallsJson", + "affinity": "TEXT" + }, + { + "fieldPath": "toolCallId", + "columnName": "toolCallId", + "affinity": "TEXT" + }, + { + "fieldPath": "toolName", + "columnName": "toolName", + "affinity": "TEXT" + }, + { + "fieldPath": "toolArgs", + "columnName": "toolArgs", + "affinity": "TEXT" + }, + { + "fieldPath": "isError", + "columnName": "isError", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "reasoning", + "columnName": "reasoning", + "affinity": "TEXT" + }, + { + "fieldPath": "signature", + "columnName": "signature", + "affinity": "TEXT" + }, + { + "fieldPath": "attachmentsJson", + "columnName": "attachmentsJson", + "affinity": "TEXT" + }, + { + "fieldPath": "isCompacted", + "columnName": "isCompacted", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "isContextSummary", + "columnName": "isContextSummary", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "isCompactionMarker", + "columnName": "isCompactionMarker", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "inputTokens", + "columnName": "inputTokens", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "outputTokens", + "columnName": "outputTokens", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "thinkingBlocksJson", + "columnName": "thinkingBlocksJson", + "affinity": "TEXT" + }, + { + "fieldPath": "cachedInputTokens", + "columnName": "cachedInputTokens", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "id" + ] + }, + "indices": [ + { + "name": "index_agent_messages_sessionId", + "unique": false, + "columnNames": [ + "sessionId" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_agent_messages_sessionId` ON `${TABLE_NAME}` (`sessionId`)" + } + ] + }, + { + "tableName": "chat_sessions", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `title` TEXT NOT NULL, `createdAt` INTEGER NOT NULL, `updatedAt` INTEGER NOT NULL, `workspacePath` TEXT NOT NULL, `mode` TEXT NOT NULL, `reasoningEffort` TEXT NOT NULL, `providerId` TEXT, `model` TEXT, `totalInputTokens` INTEGER NOT NULL, `totalOutputTokens` INTEGER NOT NULL, `lastInputTokens` INTEGER NOT NULL, `isPinned` INTEGER NOT NULL, `parentId` TEXT, `subagentType` TEXT, PRIMARY KEY(`id`))", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "title", + "columnName": "title", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "createdAt", + "columnName": "createdAt", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "updatedAt", + "columnName": "updatedAt", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "workspacePath", + "columnName": "workspacePath", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "mode", + "columnName": "mode", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "reasoningEffort", + "columnName": "reasoningEffort", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "providerId", + "columnName": "providerId", + "affinity": "TEXT" + }, + { + "fieldPath": "model", + "columnName": "model", + "affinity": "TEXT" + }, + { + "fieldPath": "totalInputTokens", + "columnName": "totalInputTokens", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "totalOutputTokens", + "columnName": "totalOutputTokens", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "lastInputTokens", + "columnName": "lastInputTokens", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "isPinned", + "columnName": "isPinned", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "parentId", + "columnName": "parentId", + "affinity": "TEXT" + }, + { + "fieldPath": "subagentType", + "columnName": "subagentType", + "affinity": "TEXT" + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "id" + ] + }, + "indices": [ + { + "name": "index_chat_sessions_workspacePath", + "unique": false, + "columnNames": [ + "workspacePath" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_chat_sessions_workspacePath` ON `${TABLE_NAME}` (`workspacePath`)" + } + ] + }, + { + "tableName": "ai_providers", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `name` TEXT NOT NULL, `type` TEXT NOT NULL, `apiKey` TEXT NOT NULL, `multiKeyEnabled` INTEGER NOT NULL, `apiKeys` TEXT NOT NULL, `keyRotationStrategy` TEXT NOT NULL, `keyFailoverThreshold` INTEGER NOT NULL, `keyCooldownMinutes` INTEGER NOT NULL, `keySwitchStatusCodes` TEXT NOT NULL, `baseUrl` TEXT NOT NULL, `defaultModel` TEXT NOT NULL, `models` TEXT NOT NULL, `selectedModel` TEXT NOT NULL, `isEnabled` INTEGER NOT NULL, `useFullUrl` INTEGER NOT NULL, `useResponseApi` INTEGER NOT NULL, `anthropicCacheBreakpoints` INTEGER NOT NULL, `openaiChatCacheKey` INTEGER NOT NULL, `balanceScriptPath` TEXT NOT NULL, `balanceRefreshInterval` INTEGER NOT NULL, `customHeaders` TEXT NOT NULL, `sortOrder` INTEGER NOT NULL, `proxyEnabled` INTEGER NOT NULL, `proxyType` TEXT NOT NULL, `proxyHost` TEXT NOT NULL, `proxyPort` INTEGER NOT NULL, `proxyUsername` TEXT NOT NULL, `proxyPassword` TEXT NOT NULL, `scriptParams` TEXT NOT NULL, PRIMARY KEY(`id`))", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "type", + "columnName": "type", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "apiKey", + "columnName": "apiKey", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "multiKeyEnabled", + "columnName": "multiKeyEnabled", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "apiKeys", + "columnName": "apiKeys", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "keyRotationStrategy", + "columnName": "keyRotationStrategy", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "keyFailoverThreshold", + "columnName": "keyFailoverThreshold", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "keyCooldownMinutes", + "columnName": "keyCooldownMinutes", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "keySwitchStatusCodes", + "columnName": "keySwitchStatusCodes", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "baseUrl", + "columnName": "baseUrl", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "defaultModel", + "columnName": "defaultModel", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "models", + "columnName": "models", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "selectedModel", + "columnName": "selectedModel", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "isEnabled", + "columnName": "isEnabled", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "useFullUrl", + "columnName": "useFullUrl", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "useResponseApi", + "columnName": "useResponseApi", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "anthropicCacheBreakpoints", + "columnName": "anthropicCacheBreakpoints", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "openaiChatCacheKey", + "columnName": "openaiChatCacheKey", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "balanceScriptPath", + "columnName": "balanceScriptPath", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "balanceRefreshInterval", + "columnName": "balanceRefreshInterval", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "customHeaders", + "columnName": "customHeaders", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "sortOrder", + "columnName": "sortOrder", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "proxyEnabled", + "columnName": "proxyEnabled", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "proxyType", + "columnName": "proxyType", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "proxyHost", + "columnName": "proxyHost", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "proxyPort", + "columnName": "proxyPort", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "proxyUsername", + "columnName": "proxyUsername", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "proxyPassword", + "columnName": "proxyPassword", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "scriptParams", + "columnName": "scriptParams", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "id" + ] + } + }, + { + "tableName": "remote_connections", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `name` TEXT NOT NULL, `protocol` TEXT NOT NULL, `host` TEXT NOT NULL, `port` INTEGER NOT NULL, `username` TEXT NOT NULL, `authType` TEXT NOT NULL, `authData` TEXT NOT NULL, `passphrase` TEXT, `created_at` INTEGER NOT NULL, PRIMARY KEY(`id`))", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "protocol", + "columnName": "protocol", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "host", + "columnName": "host", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "port", + "columnName": "port", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "username", + "columnName": "username", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "authType", + "columnName": "authType", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "authData", + "columnName": "authData", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "passphrase", + "columnName": "passphrase", + "affinity": "TEXT" + }, + { + "fieldPath": "createdAt", + "columnName": "created_at", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "id" + ] + } + }, + { + "tableName": "remote_mounts", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `connectionId` TEXT NOT NULL, `remotePath` TEXT NOT NULL, `localMountPath` TEXT NOT NULL, `isActive` INTEGER NOT NULL, `autoConnect` INTEGER NOT NULL, `created_at` INTEGER NOT NULL, PRIMARY KEY(`id`), FOREIGN KEY(`connectionId`) REFERENCES `remote_connections`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE )", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "connectionId", + "columnName": "connectionId", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "remotePath", + "columnName": "remotePath", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "localMountPath", + "columnName": "localMountPath", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "isActive", + "columnName": "isActive", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "autoConnect", + "columnName": "autoConnect", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "createdAt", + "columnName": "created_at", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "id" + ] + }, + "indices": [ + { + "name": "index_remote_mounts_connectionId", + "unique": false, + "columnNames": [ + "connectionId" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_remote_mounts_connectionId` ON `${TABLE_NAME}` (`connectionId`)" + } + ], + "foreignKeys": [ + { + "table": "remote_connections", + "onDelete": "CASCADE", + "onUpdate": "NO ACTION", + "columns": [ + "connectionId" + ], + "referencedColumns": [ + "id" + ] + } + ] + }, + { + "tableName": "todo_items", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `sessionId` TEXT NOT NULL, `subject` TEXT NOT NULL, `description` TEXT NOT NULL, `status` TEXT NOT NULL, `priority` INTEGER NOT NULL, `order` INTEGER NOT NULL, `createdAt` INTEGER NOT NULL, `updatedAt` INTEGER NOT NULL, PRIMARY KEY(`id`))", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "sessionId", + "columnName": "sessionId", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "subject", + "columnName": "subject", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "description", + "columnName": "description", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "status", + "columnName": "status", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "priority", + "columnName": "priority", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "order", + "columnName": "order", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "createdAt", + "columnName": "createdAt", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "updatedAt", + "columnName": "updatedAt", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "id" + ] + } + }, + { + "tableName": "session_checkpoints", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `sessionId` TEXT NOT NULL, `userMessageId` TEXT NOT NULL, `promptSnippet` TEXT NOT NULL, `createdAt` INTEGER NOT NULL, PRIMARY KEY(`id`))", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "sessionId", + "columnName": "sessionId", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "userMessageId", + "columnName": "userMessageId", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "promptSnippet", + "columnName": "promptSnippet", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "createdAt", + "columnName": "createdAt", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "id" + ] + }, + "indices": [ + { + "name": "index_session_checkpoints_sessionId", + "unique": false, + "columnNames": [ + "sessionId" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_session_checkpoints_sessionId` ON `${TABLE_NAME}` (`sessionId`)" + } + ] + }, + { + "tableName": "checkpoint_file_snapshots", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `checkpointId` TEXT NOT NULL, `filePath` TEXT NOT NULL, `snapshotRelativePath` TEXT NOT NULL, `changeType` TEXT NOT NULL, `createdAt` INTEGER NOT NULL, PRIMARY KEY(`id`))", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "checkpointId", + "columnName": "checkpointId", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "filePath", + "columnName": "filePath", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "snapshotRelativePath", + "columnName": "snapshotRelativePath", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "changeType", + "columnName": "changeType", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "createdAt", + "columnName": "createdAt", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "id" + ] + }, + "indices": [ + { + "name": "index_checkpoint_file_snapshots_checkpointId", + "unique": false, + "columnNames": [ + "checkpointId" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_checkpoint_file_snapshots_checkpointId` ON `${TABLE_NAME}` (`checkpointId`)" + } + ] + }, + { + "tableName": "llm_call_records", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `sessionId` TEXT, `providerId` TEXT, `model` TEXT, `reasoningEffort` TEXT, `kind` TEXT NOT NULL, `inputTokens` INTEGER NOT NULL, `outputTokens` INTEGER NOT NULL, `cachedInputTokens` INTEGER NOT NULL, `cacheCreationTokens` INTEGER NOT NULL, `ttfbMillis` INTEGER, `durationMillis` INTEGER, `status` TEXT NOT NULL, `errorMessage` TEXT, `stopReason` TEXT, `retryCount` INTEGER NOT NULL, `createdAt` INTEGER NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "sessionId", + "columnName": "sessionId", + "affinity": "TEXT" + }, + { + "fieldPath": "providerId", + "columnName": "providerId", + "affinity": "TEXT" + }, + { + "fieldPath": "model", + "columnName": "model", + "affinity": "TEXT" + }, + { + "fieldPath": "reasoningEffort", + "columnName": "reasoningEffort", + "affinity": "TEXT" + }, + { + "fieldPath": "kind", + "columnName": "kind", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "inputTokens", + "columnName": "inputTokens", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "outputTokens", + "columnName": "outputTokens", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "cachedInputTokens", + "columnName": "cachedInputTokens", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "cacheCreationTokens", + "columnName": "cacheCreationTokens", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "ttfbMillis", + "columnName": "ttfbMillis", + "affinity": "INTEGER" + }, + { + "fieldPath": "durationMillis", + "columnName": "durationMillis", + "affinity": "INTEGER" + }, + { + "fieldPath": "status", + "columnName": "status", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "errorMessage", + "columnName": "errorMessage", + "affinity": "TEXT" + }, + { + "fieldPath": "stopReason", + "columnName": "stopReason", + "affinity": "TEXT" + }, + { + "fieldPath": "retryCount", + "columnName": "retryCount", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "createdAt", + "columnName": "createdAt", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": true, + "columnNames": [ + "id" + ] + }, + "indices": [ + { + "name": "index_llm_call_records_createdAt", + "unique": false, + "columnNames": [ + "createdAt" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_llm_call_records_createdAt` ON `${TABLE_NAME}` (`createdAt`)" + }, + { + "name": "index_llm_call_records_provider_model", + "unique": false, + "columnNames": [ + "providerId", + "model" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_llm_call_records_provider_model` ON `${TABLE_NAME}` (`providerId`, `model`)" + } + ] + } + ], + "setupQueries": [ + "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", + "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '5072e48234836707b494d836c695b846')" + ] + } +} \ No newline at end of file diff --git a/app/src/main/assets/migrations/54_drop_provider_user_agent.sql b/app/src/main/assets/migrations/54_drop_provider_user_agent.sql new file mode 100644 index 00000000..eea2aba5 --- /dev/null +++ b/app/src/main/assets/migrations/54_drop_provider_user_agent.sql @@ -0,0 +1,66 @@ +-- 移除已废弃的 userAgent 列。 +-- +-- 该列由迁移 40 引入,但提交 04385620(「提供商支持自定义请求头与脚本参数」)用 +-- customHeaders + scriptParams 取代它时只改了 Entity、没有写迁移删除列。结果: +-- 从 rc7~rc10 等已发布版本升级的用户,库里 userAgent 物理存在而 Entity 不认, +-- Room 校验「表里多出 userAgent」失败、onUpgrade 抛异常,App 启动即崩 +-- (IllegalStateException: Migration didn't properly handle: ai_providers)。 +-- +-- minSdk 26 对应用户态 SQLite 3.18,无 ALTER TABLE ... DROP COLUMN, +-- 故按迁移 25/32 的先例重建表。 +-- +-- 注意:INSERT ... SELECT 的列清单不含 userAgent,因而本迁移对两种源状态都成立—— +-- 无论旧表有没有 userAgent(老用户有、全新安装的 53 库没有),结果都收敛到目标列集, +-- 重复执行也不会报 duplicate column。 +CREATE TABLE ai_providers_new ( + id TEXT NOT NULL PRIMARY KEY, + name TEXT NOT NULL, + type TEXT NOT NULL, + apiKey TEXT NOT NULL, + multiKeyEnabled INTEGER NOT NULL, + apiKeys TEXT NOT NULL, + keyRotationStrategy TEXT NOT NULL, + keyFailoverThreshold INTEGER NOT NULL, + keyCooldownMinutes INTEGER NOT NULL, + keySwitchStatusCodes TEXT NOT NULL, + baseUrl TEXT NOT NULL, + defaultModel TEXT NOT NULL, + models TEXT NOT NULL, + selectedModel TEXT NOT NULL, + isEnabled INTEGER NOT NULL, + useFullUrl INTEGER NOT NULL, + useResponseApi INTEGER NOT NULL, + anthropicCacheBreakpoints INTEGER NOT NULL, + openaiChatCacheKey INTEGER NOT NULL, + balanceScriptPath TEXT NOT NULL, + balanceRefreshInterval INTEGER NOT NULL, + customHeaders TEXT NOT NULL, + sortOrder INTEGER NOT NULL, + proxyEnabled INTEGER NOT NULL, + proxyType TEXT NOT NULL, + proxyHost TEXT NOT NULL, + proxyPort INTEGER NOT NULL, + proxyUsername TEXT NOT NULL, + proxyPassword TEXT NOT NULL, + scriptParams TEXT NOT NULL +); + +INSERT INTO ai_providers_new ( + id, name, type, apiKey, multiKeyEnabled, apiKeys, keyRotationStrategy, + keyFailoverThreshold, keyCooldownMinutes, keySwitchStatusCodes, baseUrl, + defaultModel, models, selectedModel, isEnabled, useFullUrl, useResponseApi, + anthropicCacheBreakpoints, openaiChatCacheKey, balanceScriptPath, + balanceRefreshInterval, customHeaders, sortOrder, proxyEnabled, proxyType, + proxyHost, proxyPort, proxyUsername, proxyPassword, scriptParams +) +SELECT + id, name, type, apiKey, multiKeyEnabled, apiKeys, keyRotationStrategy, + keyFailoverThreshold, keyCooldownMinutes, keySwitchStatusCodes, baseUrl, + defaultModel, models, selectedModel, isEnabled, useFullUrl, useResponseApi, + anthropicCacheBreakpoints, openaiChatCacheKey, balanceScriptPath, + balanceRefreshInterval, customHeaders, sortOrder, proxyEnabled, proxyType, + proxyHost, proxyPort, proxyUsername, proxyPassword, scriptParams +FROM ai_providers; + +DROP TABLE ai_providers; +ALTER TABLE ai_providers_new RENAME TO ai_providers; diff --git a/app/src/main/java/com/aicode/feature/agent/data/local/database/AgentDatabase.kt b/app/src/main/java/com/aicode/feature/agent/data/local/database/AgentDatabase.kt index 21507d43..ea5bd161 100644 --- a/app/src/main/java/com/aicode/feature/agent/data/local/database/AgentDatabase.kt +++ b/app/src/main/java/com/aicode/feature/agent/data/local/database/AgentDatabase.kt @@ -34,7 +34,7 @@ abstract class AgentDatabase : RoomDatabase() { abstract fun llmCallRecordDao(): LlmCallRecordDao companion object { - const val SCHEMA_VERSION = 53 + const val SCHEMA_VERSION = 54 /** 数据库文件名(落在 `databases/` 下,另有 Room 默认 WAL 模式产生的 `-wal`/`-shm`)。 */ const val DATABASE_NAME = "aicode_agent_db"