aicodeswitch 1.10.2 → 2.0.1

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.
@@ -39,12 +39,6 @@ class DatabaseManager {
39
39
  writable: true,
40
40
  value: void 0
41
41
  });
42
- Object.defineProperty(this, "accessLogDb", {
43
- enumerable: true,
44
- configurable: true,
45
- writable: true,
46
- value: void 0
47
- });
48
42
  Object.defineProperty(this, "errorLogDb", {
49
43
  enumerable: true,
50
44
  configurable: true,
@@ -64,12 +58,6 @@ class DatabaseManager {
64
58
  writable: true,
65
59
  value: null
66
60
  });
67
- Object.defineProperty(this, "accessLogsCountCache", {
68
- enumerable: true,
69
- configurable: true,
70
- writable: true,
71
- value: null
72
- });
73
61
  Object.defineProperty(this, "errorLogsCountCache", {
74
62
  enumerable: true,
75
63
  configurable: true,
@@ -94,7 +82,6 @@ class DatabaseManager {
94
82
  // 设置 read_uncommitted = 0 确保读取最新提交的数据
95
83
  this.db.pragma('read_uncommitted = 0');
96
84
  this.logDb = new level_1.Level(path_1.default.join(dataPath, 'logs'), { valueEncoding: 'json' });
97
- this.accessLogDb = new level_1.Level(path_1.default.join(dataPath, 'access-logs'), { valueEncoding: 'json' });
98
85
  this.errorLogDb = new level_1.Level(path_1.default.join(dataPath, 'error-logs'), { valueEncoding: 'json' });
99
86
  this.blacklistDb = new level_1.Level(path_1.default.join(dataPath, 'service-blacklist'), { valueEncoding: 'json' });
100
87
  }
@@ -270,6 +257,13 @@ class DatabaseManager {
270
257
  this.db.exec('ALTER TABLE api_services ADD COLUMN request_reset_base_time INTEGER;');
271
258
  console.log('[DB] Migration completed: request_reset_base_time column added');
272
259
  }
260
+ // 检查api_services表是否有auth_type字段
261
+ const hasAuthType = columns.some((col) => col.name === 'auth_type');
262
+ if (!hasAuthType) {
263
+ console.log('[DB] Running migration: Adding auth_type column to api_services table');
264
+ this.db.exec('ALTER TABLE api_services ADD COLUMN auth_type TEXT DEFAULT NULL;');
265
+ console.log('[DB] Migration completed: auth_type column added');
266
+ }
273
267
  });
274
268
  }
275
269
  migrateMaxOutputTokensToModelLimits() {
@@ -398,6 +392,21 @@ class DatabaseManager {
398
392
  key TEXT PRIMARY KEY,
399
393
  value TEXT NOT NULL
400
394
  );
395
+
396
+ CREATE TABLE IF NOT EXISTS sessions (
397
+ id TEXT PRIMARY KEY,
398
+ target_type TEXT NOT NULL CHECK(target_type IN ('claude-code', 'codex')),
399
+ title TEXT,
400
+ first_request_at INTEGER NOT NULL,
401
+ last_request_at INTEGER NOT NULL,
402
+ request_count INTEGER DEFAULT 1,
403
+ total_tokens INTEGER DEFAULT 0,
404
+ vendor_id TEXT,
405
+ vendor_name TEXT,
406
+ service_id TEXT,
407
+ service_name TEXT,
408
+ model TEXT
409
+ );
401
410
  `);
402
411
  }
403
412
  ensureDefaultConfig() {
@@ -466,6 +475,7 @@ class DatabaseManager {
466
475
  apiUrl: row.api_url,
467
476
  apiKey: row.api_key,
468
477
  sourceType: row.source_type,
478
+ authType: row.auth_type,
469
479
  supportedModels: row.supported_models ? row.supported_models.split(',').map((model) => model.trim()).filter((model) => model.length > 0) : undefined,
470
480
  modelLimits: row.model_limits ? JSON.parse(row.model_limits) : undefined,
471
481
  enableProxy: row.enable_proxy === 1,
@@ -492,15 +502,15 @@ class DatabaseManager {
492
502
  const id = crypto_1.default.randomUUID();
493
503
  const now = Date.now();
494
504
  this.db
495
- .prepare('INSERT INTO api_services (id, vendor_id, name, api_url, api_key, source_type, supported_models, model_limits, enable_proxy, enable_token_limit, token_limit, token_reset_interval, token_reset_base_time, enable_request_limit, request_count_limit, request_reset_interval, request_reset_base_time, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)')
496
- .run(id, service.vendorId, service.name, service.apiUrl, service.apiKey, service.sourceType || null, service.supportedModels ? service.supportedModels.join(',') : null, service.modelLimits ? JSON.stringify(service.modelLimits) : null, service.enableProxy ? 1 : 0, service.enableTokenLimit ? 1 : 0, service.tokenLimit || null, service.tokenResetInterval || null, service.tokenResetBaseTime || null, service.enableRequestLimit ? 1 : 0, service.requestCountLimit || null, service.requestResetInterval || null, service.requestResetBaseTime || null, now, now);
505
+ .prepare('INSERT INTO api_services (id, vendor_id, name, api_url, api_key, source_type, auth_type, supported_models, model_limits, enable_proxy, enable_token_limit, token_limit, token_reset_interval, token_reset_base_time, enable_request_limit, request_count_limit, request_reset_interval, request_reset_base_time, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)')
506
+ .run(id, service.vendorId, service.name, service.apiUrl, service.apiKey, service.sourceType || null, service.authType || null, service.supportedModels ? service.supportedModels.join(',') : null, service.modelLimits ? JSON.stringify(service.modelLimits) : null, service.enableProxy ? 1 : 0, service.enableTokenLimit ? 1 : 0, service.tokenLimit || null, service.tokenResetInterval || null, service.tokenResetBaseTime || null, service.enableRequestLimit ? 1 : 0, service.requestCountLimit || null, service.requestResetInterval || null, service.requestResetBaseTime || null, now, now);
497
507
  return Object.assign(Object.assign({}, service), { id, createdAt: now, updatedAt: now });
498
508
  }
499
509
  updateAPIService(id, service) {
500
510
  const now = Date.now();
501
511
  const result = this.db
502
- .prepare('UPDATE api_services SET vendor_id = ?, name = ?, api_url = ?, api_key = ?, source_type = ?, supported_models = ?, model_limits = ?, enable_proxy = ?, enable_token_limit = ?, token_limit = ?, token_reset_interval = ?, token_reset_base_time = ?, enable_request_limit = ?, request_count_limit = ?, request_reset_interval = ?, request_reset_base_time = ?, updated_at = ? WHERE id = ?')
503
- .run(service.vendorId, service.name, service.apiUrl, service.apiKey, service.sourceType || null, service.supportedModels ? service.supportedModels.join(',') : null, service.modelLimits ? JSON.stringify(service.modelLimits) : null, service.enableProxy !== undefined ? (service.enableProxy ? 1 : 0) : null, service.enableTokenLimit !== undefined ? (service.enableTokenLimit ? 1 : 0) : null, service.tokenLimit !== undefined ? service.tokenLimit : null, service.tokenResetInterval !== undefined ? service.tokenResetInterval : null, service.tokenResetBaseTime !== undefined ? service.tokenResetBaseTime : null, service.enableRequestLimit !== undefined ? (service.enableRequestLimit ? 1 : 0) : null, service.requestCountLimit !== undefined ? service.requestCountLimit : null, service.requestResetInterval !== undefined ? service.requestResetInterval : null, service.requestResetBaseTime !== undefined ? service.requestResetBaseTime : null, now, id);
512
+ .prepare('UPDATE api_services SET vendor_id = ?, name = ?, api_url = ?, api_key = ?, source_type = ?, auth_type = ?, supported_models = ?, model_limits = ?, enable_proxy = ?, enable_token_limit = ?, token_limit = ?, token_reset_interval = ?, token_reset_base_time = ?, enable_request_limit = ?, request_count_limit = ?, request_reset_interval = ?, request_reset_base_time = ?, updated_at = ? WHERE id = ?')
513
+ .run(service.vendorId, service.name, service.apiUrl, service.apiKey, service.sourceType || null, service.authType || null, service.supportedModels ? service.supportedModels.join(',') : null, service.modelLimits ? JSON.stringify(service.modelLimits) : null, service.enableProxy !== undefined ? (service.enableProxy ? 1 : 0) : null, service.enableTokenLimit !== undefined ? (service.enableTokenLimit ? 1 : 0) : null, service.tokenLimit !== undefined ? service.tokenLimit : null, service.tokenResetInterval !== undefined ? service.tokenResetInterval : null, service.tokenResetBaseTime !== undefined ? service.tokenResetBaseTime : null, service.enableRequestLimit !== undefined ? (service.enableRequestLimit ? 1 : 0) : null, service.requestCountLimit !== undefined ? service.requestCountLimit : null, service.requestResetInterval !== undefined ? service.requestResetInterval : null, service.requestResetBaseTime !== undefined ? service.requestResetBaseTime : null, now, id);
504
514
  // 调试日志: 记录更新操作
505
515
  if (result.changes > 0 && process.env.NODE_ENV === 'development') {
506
516
  console.log(`[DB] Updated service ${id}: ${service.name} -> ${service.apiUrl}`);
@@ -829,55 +839,6 @@ class DatabaseManager {
829
839
  this.logsCountCache = null;
830
840
  });
831
841
  }
832
- // Access log operations
833
- addAccessLog(log) {
834
- return __awaiter(this, void 0, void 0, function* () {
835
- const id = crypto_1.default.randomUUID();
836
- yield this.accessLogDb.put(id, JSON.stringify(Object.assign(Object.assign({}, log), { id })));
837
- // 清除缓存
838
- this.accessLogsCountCache = null;
839
- return id;
840
- });
841
- }
842
- updateAccessLog(id, data) {
843
- return __awaiter(this, void 0, void 0, function* () {
844
- const log = yield this.accessLogDb.get(id);
845
- const updatedLog = Object.assign(Object.assign({}, JSON.parse(log)), data);
846
- yield this.accessLogDb.put(id, JSON.stringify(updatedLog));
847
- });
848
- }
849
- getAccessLogs() {
850
- return __awaiter(this, arguments, void 0, function* (limit = 100, offset = 0) {
851
- var _a, e_2, _b, _c;
852
- const allLogs = [];
853
- try {
854
- for (var _d = true, _e = __asyncValues(this.accessLogDb.iterator()), _f; _f = yield _e.next(), _a = _f.done, !_a; _d = true) {
855
- _c = _f.value;
856
- _d = false;
857
- const [, value] = _c;
858
- allLogs.push(JSON.parse(value));
859
- }
860
- }
861
- catch (e_2_1) { e_2 = { error: e_2_1 }; }
862
- finally {
863
- try {
864
- if (!_d && !_a && (_b = _e.return)) yield _b.call(_e);
865
- }
866
- finally { if (e_2) throw e_2.error; }
867
- }
868
- // Sort by timestamp in descending order (newest first)
869
- allLogs.sort((a, b) => b.timestamp - a.timestamp);
870
- // Apply offset and limit
871
- return allLogs.slice(offset, offset + limit);
872
- });
873
- }
874
- clearAccessLogs() {
875
- return __awaiter(this, void 0, void 0, function* () {
876
- yield this.accessLogDb.clear();
877
- // 清除缓存
878
- this.accessLogsCountCache = null;
879
- });
880
- }
881
842
  // Error log operations
882
843
  addErrorLog(log) {
883
844
  return __awaiter(this, void 0, void 0, function* () {
@@ -889,7 +850,7 @@ class DatabaseManager {
889
850
  }
890
851
  getErrorLogs() {
891
852
  return __awaiter(this, arguments, void 0, function* (limit = 100, offset = 0) {
892
- var _a, e_3, _b, _c;
853
+ var _a, e_2, _b, _c;
893
854
  const allLogs = [];
894
855
  try {
895
856
  for (var _d = true, _e = __asyncValues(this.errorLogDb.iterator()), _f; _f = yield _e.next(), _a = _f.done, !_a; _d = true) {
@@ -899,12 +860,12 @@ class DatabaseManager {
899
860
  allLogs.push(JSON.parse(value));
900
861
  }
901
862
  }
902
- catch (e_3_1) { e_3 = { error: e_3_1 }; }
863
+ catch (e_2_1) { e_2 = { error: e_2_1 }; }
903
864
  finally {
904
865
  try {
905
866
  if (!_d && !_a && (_b = _e.return)) yield _b.call(_e);
906
867
  }
907
- finally { if (e_3) throw e_3.error; }
868
+ finally { if (e_2) throw e_2.error; }
908
869
  }
909
870
  // Sort by timestamp in descending order (newest first)
910
871
  allLogs.sort((a, b) => b.timestamp - a.timestamp);
@@ -924,7 +885,7 @@ class DatabaseManager {
924
885
  */
925
886
  getLogsCount() {
926
887
  return __awaiter(this, void 0, void 0, function* () {
927
- var _a, e_4, _b, _c;
888
+ var _a, e_3, _b, _c;
928
889
  const now = Date.now();
929
890
  if (this.logsCountCache && now - this.logsCountCache.timestamp < this.CACHE_TTL) {
930
891
  return this.logsCountCache.count;
@@ -938,53 +899,23 @@ class DatabaseManager {
938
899
  count++;
939
900
  }
940
901
  }
941
- catch (e_4_1) { e_4 = { error: e_4_1 }; }
902
+ catch (e_3_1) { e_3 = { error: e_3_1 }; }
942
903
  finally {
943
904
  try {
944
905
  if (!_d && !_a && (_b = _e.return)) yield _b.call(_e);
945
906
  }
946
- finally { if (e_4) throw e_4.error; }
907
+ finally { if (e_3) throw e_3.error; }
947
908
  }
948
909
  this.logsCountCache = { count, timestamp: now };
949
910
  return count;
950
911
  });
951
912
  }
952
- /**
953
- * 获取访问日志总数(带缓存)
954
- */
955
- getAccessLogsCount() {
956
- return __awaiter(this, void 0, void 0, function* () {
957
- var _a, e_5, _b, _c;
958
- const now = Date.now();
959
- if (this.accessLogsCountCache && now - this.accessLogsCountCache.timestamp < this.CACHE_TTL) {
960
- return this.accessLogsCountCache.count;
961
- }
962
- let count = 0;
963
- try {
964
- for (var _d = true, _e = __asyncValues(this.accessLogDb.iterator()), _f; _f = yield _e.next(), _a = _f.done, !_a; _d = true) {
965
- _c = _f.value;
966
- _d = false;
967
- const _ = _c;
968
- count++;
969
- }
970
- }
971
- catch (e_5_1) { e_5 = { error: e_5_1 }; }
972
- finally {
973
- try {
974
- if (!_d && !_a && (_b = _e.return)) yield _b.call(_e);
975
- }
976
- finally { if (e_5) throw e_5.error; }
977
- }
978
- this.accessLogsCountCache = { count, timestamp: now };
979
- return count;
980
- });
981
- }
982
913
  /**
983
914
  * 获取错误日志总数(带缓存)
984
915
  */
985
916
  getErrorLogsCount() {
986
917
  return __awaiter(this, void 0, void 0, function* () {
987
- var _a, e_6, _b, _c;
918
+ var _a, e_4, _b, _c;
988
919
  const now = Date.now();
989
920
  if (this.errorLogsCountCache && now - this.errorLogsCountCache.timestamp < this.CACHE_TTL) {
990
921
  return this.errorLogsCountCache.count;
@@ -998,12 +929,12 @@ class DatabaseManager {
998
929
  count++;
999
930
  }
1000
931
  }
1001
- catch (e_6_1) { e_6 = { error: e_6_1 }; }
932
+ catch (e_4_1) { e_4 = { error: e_4_1 }; }
1002
933
  finally {
1003
934
  try {
1004
935
  if (!_d && !_a && (_b = _e.return)) yield _b.call(_e);
1005
936
  }
1006
- finally { if (e_6) throw e_6.error; }
937
+ finally { if (e_4) throw e_4.error; }
1007
938
  }
1008
939
  this.errorLogsCountCache = { count, timestamp: now };
1009
940
  return count;
@@ -1079,7 +1010,7 @@ class DatabaseManager {
1079
1010
  }
1080
1011
  cleanupExpiredBlacklist() {
1081
1012
  return __awaiter(this, void 0, void 0, function* () {
1082
- var _a, e_7, _b, _c;
1013
+ var _a, e_5, _b, _c;
1083
1014
  const now = Date.now();
1084
1015
  let count = 0;
1085
1016
  try {
@@ -1094,12 +1025,12 @@ class DatabaseManager {
1094
1025
  }
1095
1026
  }
1096
1027
  }
1097
- catch (e_7_1) { e_7 = { error: e_7_1 }; }
1028
+ catch (e_5_1) { e_5 = { error: e_5_1 }; }
1098
1029
  finally {
1099
1030
  try {
1100
1031
  if (!_d && !_a && (_b = _e.return)) yield _b.call(_e);
1101
1032
  }
1102
- finally { if (e_7) throw e_7.error; }
1033
+ finally { if (e_5) throw e_5.error; }
1103
1034
  }
1104
1035
  return count;
1105
1036
  });
@@ -1152,8 +1083,8 @@ class DatabaseManager {
1152
1083
  // Import API services
1153
1084
  for (const service of importData.apiServices) {
1154
1085
  this.db
1155
- .prepare('INSERT INTO api_services (id, vendor_id, name, api_url, api_key, source_type, supported_models, model_limits, enable_proxy, enable_token_limit, token_limit, token_reset_interval, token_reset_base_time, enable_request_limit, request_count_limit, request_reset_interval, request_reset_base_time, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)')
1156
- .run(service.id, service.vendorId, service.name, service.apiUrl, service.apiKey, service.sourceType || null, service.supportedModels ? service.supportedModels.join(',') : null, service.modelLimits ? JSON.stringify(service.modelLimits) : null, service.enableProxy ? 1 : 0, service.enableTokenLimit ? 1 : 0, service.tokenLimit || null, service.tokenResetInterval || null, service.tokenResetBaseTime || null, service.enableRequestLimit ? 1 : 0, service.requestCountLimit || null, service.requestResetInterval || null, service.requestResetBaseTime || null, service.createdAt, service.updatedAt);
1086
+ .prepare('INSERT INTO api_services (id, vendor_id, name, api_url, api_key, source_type, auth_type, supported_models, model_limits, enable_proxy, enable_token_limit, token_limit, token_reset_interval, token_reset_base_time, enable_request_limit, request_count_limit, request_reset_interval, request_reset_base_time, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)')
1087
+ .run(service.id, service.vendorId, service.name, service.apiUrl, service.apiKey, service.sourceType || null, service.authType || null, service.supportedModels ? service.supportedModels.join(',') : null, service.modelLimits ? JSON.stringify(service.modelLimits) : null, service.enableProxy ? 1 : 0, service.enableTokenLimit ? 1 : 0, service.tokenLimit || null, service.tokenResetInterval || null, service.tokenResetBaseTime || null, service.enableRequestLimit ? 1 : 0, service.requestCountLimit || null, service.requestResetInterval || null, service.requestResetBaseTime || null, service.createdAt, service.updatedAt);
1157
1088
  }
1158
1089
  // Import routes
1159
1090
  for (const route of importData.routes) {
@@ -1180,7 +1111,7 @@ class DatabaseManager {
1180
1111
  // Statistics operations
1181
1112
  getStatistics() {
1182
1113
  return __awaiter(this, arguments, void 0, function* (days = 30) {
1183
- var _a, e_8, _b, _c, _d, e_9, _e, _f;
1114
+ var _a, e_6, _b, _c, _d, e_7, _e, _f;
1184
1115
  var _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y;
1185
1116
  const now = Date.now();
1186
1117
  const startTime = now - days * 24 * 60 * 60 * 1000;
@@ -1197,12 +1128,12 @@ class DatabaseManager {
1197
1128
  }
1198
1129
  }
1199
1130
  }
1200
- catch (e_8_1) { e_8 = { error: e_8_1 }; }
1131
+ catch (e_6_1) { e_6 = { error: e_6_1 }; }
1201
1132
  finally {
1202
1133
  try {
1203
1134
  if (!_z && !_a && (_b = _0.return)) yield _b.call(_0);
1204
1135
  }
1205
- finally { if (e_8) throw e_8.error; }
1136
+ finally { if (e_6) throw e_6.error; }
1206
1137
  }
1207
1138
  // Get all error logs
1208
1139
  const errorLogs = [];
@@ -1220,12 +1151,12 @@ class DatabaseManager {
1220
1151
  }
1221
1152
  }
1222
1153
  }
1223
- catch (e_9_1) { e_9 = { error: e_9_1 }; }
1154
+ catch (e_7_1) { e_7 = { error: e_7_1 }; }
1224
1155
  finally {
1225
1156
  try {
1226
1157
  if (!_2 && !_d && (_e = _3.return)) yield _e.call(_3);
1227
1158
  }
1228
- finally { if (e_9) throw e_9.error; }
1159
+ finally { if (e_7) throw e_7.error; }
1229
1160
  }
1230
1161
  // Get vendors and services for mapping
1231
1162
  const vendors = this.getVendors();
@@ -1421,10 +1352,159 @@ class DatabaseManager {
1421
1352
  }
1422
1353
  });
1423
1354
  }
1355
+ // Session operations
1356
+ /**
1357
+ * 创建或更新 session
1358
+ * 当有新的请求日志时调用此方法来更新 session 信息
1359
+ */
1360
+ upsertSession(session) {
1361
+ const now = Date.now();
1362
+ const existing = this.db.prepare('SELECT * FROM sessions WHERE id = ?').get(session.id);
1363
+ if (existing) {
1364
+ // 更新现有 session
1365
+ this.db.prepare(`
1366
+ UPDATE sessions SET
1367
+ last_request_at = ?,
1368
+ request_count = request_count + 1,
1369
+ total_tokens = total_tokens + ?,
1370
+ vendor_id = ?,
1371
+ vendor_name = ?,
1372
+ service_id = ?,
1373
+ service_name = ?,
1374
+ model = ?
1375
+ WHERE id = ?
1376
+ `).run(now, session.totalTokens || 0, session.vendorId || null, session.vendorName || null, session.serviceId || null, session.serviceName || null, session.model || null, session.id);
1377
+ }
1378
+ else {
1379
+ // 创建新 session
1380
+ this.db.prepare(`
1381
+ INSERT INTO sessions (id, target_type, title, first_request_at, last_request_at, request_count, total_tokens, vendor_id, vendor_name, service_id, service_name, model)
1382
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
1383
+ `).run(session.id, session.targetType, session.title || null, session.firstRequestAt, now, 1, session.totalTokens || 0, session.vendorId || null, session.vendorName || null, session.serviceId || null, session.serviceName || null, session.model || null);
1384
+ }
1385
+ }
1386
+ /**
1387
+ * 获取所有 sessions
1388
+ */
1389
+ getSessions(limit = 100, offset = 0) {
1390
+ const rows = this.db.prepare('SELECT * FROM sessions ORDER BY last_request_at DESC LIMIT ? OFFSET ?').all(limit, offset);
1391
+ return rows.map((row) => ({
1392
+ id: row.id,
1393
+ targetType: row.target_type,
1394
+ title: row.title,
1395
+ firstRequestAt: row.first_request_at,
1396
+ lastRequestAt: row.last_request_at,
1397
+ requestCount: row.request_count,
1398
+ totalTokens: row.total_tokens,
1399
+ vendorId: row.vendor_id,
1400
+ vendorName: row.vendor_name,
1401
+ serviceId: row.service_id,
1402
+ serviceName: row.service_name,
1403
+ model: row.model,
1404
+ }));
1405
+ }
1406
+ /**
1407
+ * 根据 session ID 获取 session
1408
+ */
1409
+ getSession(id) {
1410
+ const row = this.db.prepare('SELECT * FROM sessions WHERE id = ?').get(id);
1411
+ if (!row)
1412
+ return null;
1413
+ return {
1414
+ id: row.id,
1415
+ targetType: row.target_type,
1416
+ title: row.title,
1417
+ firstRequestAt: row.first_request_at,
1418
+ lastRequestAt: row.last_request_at,
1419
+ requestCount: row.request_count,
1420
+ totalTokens: row.total_tokens,
1421
+ vendorId: row.vendor_id,
1422
+ vendorName: row.vendor_name,
1423
+ serviceId: row.service_id,
1424
+ serviceName: row.service_name,
1425
+ model: row.model,
1426
+ };
1427
+ }
1428
+ /**
1429
+ * 获取 sessions 总数
1430
+ */
1431
+ getSessionsCount() {
1432
+ const result = this.db.prepare('SELECT COUNT(*) as count FROM sessions').get();
1433
+ return result.count;
1434
+ }
1435
+ /**
1436
+ * 删除指定 session
1437
+ */
1438
+ deleteSession(id) {
1439
+ const result = this.db.prepare('DELETE FROM sessions WHERE id = ?').run(id);
1440
+ return result.changes > 0;
1441
+ }
1442
+ /**
1443
+ * 清空所有 sessions
1444
+ */
1445
+ clearSessions() {
1446
+ this.db.prepare('DELETE FROM sessions').run();
1447
+ }
1448
+ /**
1449
+ * 获取指定 session 的请求日志
1450
+ * @param sessionId session ID
1451
+ * @param limit 限制数量
1452
+ */
1453
+ getLogsBySessionId(sessionId_1) {
1454
+ return __awaiter(this, arguments, void 0, function* (sessionId, limit = 100) {
1455
+ var _a, e_8, _b, _c;
1456
+ // 从 LevelDB 中读取所有日志
1457
+ const allLogs = [];
1458
+ try {
1459
+ for (var _d = true, _e = __asyncValues(this.logDb.iterator()), _f; _f = yield _e.next(), _a = _f.done, !_a; _d = true) {
1460
+ _c = _f.value;
1461
+ _d = false;
1462
+ const [, value] = _c;
1463
+ const log = JSON.parse(value);
1464
+ // 检查日志是否属于该 session(通过 headers 中的 session_id 或 body 中的 metadata.user_id)
1465
+ if (this.isLogBelongsToSession(log, sessionId)) {
1466
+ allLogs.push(log);
1467
+ }
1468
+ }
1469
+ }
1470
+ catch (e_8_1) { e_8 = { error: e_8_1 }; }
1471
+ finally {
1472
+ try {
1473
+ if (!_d && !_a && (_b = _e.return)) yield _b.call(_e);
1474
+ }
1475
+ finally { if (e_8) throw e_8.error; }
1476
+ }
1477
+ // 按时间倒序排序并限制数量
1478
+ allLogs.sort((a, b) => b.timestamp - a.timestamp);
1479
+ return allLogs.slice(0, limit);
1480
+ });
1481
+ }
1482
+ /**
1483
+ * 检查日志是否属于指定 session
1484
+ */
1485
+ isLogBelongsToSession(log, sessionId) {
1486
+ var _a, _b;
1487
+ // 检查 headers 中的 session_id(Codex)
1488
+ if (((_a = log.headers) === null || _a === void 0 ? void 0 : _a['session_id']) === sessionId) {
1489
+ return true;
1490
+ }
1491
+ // 检查 body 中的 metadata.user_id(Claude Code)
1492
+ if (log.body) {
1493
+ try {
1494
+ const body = JSON.parse(log.body);
1495
+ if (((_b = body.metadata) === null || _b === void 0 ? void 0 : _b.user_id) === sessionId) {
1496
+ return true;
1497
+ }
1498
+ }
1499
+ catch (_c) {
1500
+ // 忽略解析错误
1501
+ }
1502
+ }
1503
+ return false;
1504
+ }
1424
1505
  close() {
1425
1506
  this.db.close();
1426
1507
  this.logDb.close();
1427
- this.accessLogDb.close();
1428
1508
  this.errorLogDb.close();
1429
1509
  this.blacklistDb.close();
1430
1510
  }