aicodeswitch 1.10.1 → 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
  }
@@ -180,6 +167,103 @@ class DatabaseManager {
180
167
  this.db.exec('ALTER TABLE api_services ADD COLUMN enable_proxy INTEGER DEFAULT 0;');
181
168
  console.log('[DB] Migration completed: enable_proxy column added');
182
169
  }
170
+ // 检查rules表是否有请求次数相关字段
171
+ const hasRequestCountLimit = rulesColumns.some((col) => col.name === 'request_count_limit');
172
+ const hasTotalRequestsUsed = rulesColumns.some((col) => col.name === 'total_requests_used');
173
+ const hasRequestResetInterval = rulesColumns.some((col) => col.name === 'request_reset_interval');
174
+ const hasRequestLastResetAt = rulesColumns.some((col) => col.name === 'request_last_reset_at');
175
+ if (!hasRequestCountLimit) {
176
+ console.log('[DB] Running migration: Adding request_count_limit column to rules table');
177
+ this.db.exec('ALTER TABLE rules ADD COLUMN request_count_limit INTEGER;');
178
+ console.log('[DB] Migration completed: request_count_limit column added');
179
+ }
180
+ if (!hasTotalRequestsUsed) {
181
+ console.log('[DB] Running migration: Adding total_requests_used column to rules table');
182
+ this.db.exec('ALTER TABLE rules ADD COLUMN total_requests_used INTEGER DEFAULT 0;');
183
+ console.log('[DB] Migration completed: total_requests_used column added');
184
+ }
185
+ if (!hasRequestResetInterval) {
186
+ console.log('[DB] Running migration: Adding request_reset_interval column to rules table');
187
+ this.db.exec('ALTER TABLE rules ADD COLUMN request_reset_interval INTEGER;');
188
+ console.log('[DB] Migration completed: request_reset_interval column added');
189
+ }
190
+ if (!hasRequestLastResetAt) {
191
+ console.log('[DB] Running migration: Adding request_last_reset_at column to rules table');
192
+ this.db.exec('ALTER TABLE rules ADD COLUMN request_last_reset_at INTEGER;');
193
+ console.log('[DB] Migration completed: request_last_reset_at column added');
194
+ }
195
+ // 检查rules表是否有request_reset_base_time字段
196
+ const hasRequestResetBaseTime = rulesColumns.some((col) => col.name === 'request_reset_base_time');
197
+ if (!hasRequestResetBaseTime) {
198
+ console.log('[DB] Running migration: Adding request_reset_base_time column to rules table');
199
+ this.db.exec('ALTER TABLE rules ADD COLUMN request_reset_base_time INTEGER;');
200
+ console.log('[DB] Migration completed: request_reset_base_time column added');
201
+ }
202
+ // 检查rules表是否有token_reset_base_time字段
203
+ const hasTokenResetBaseTime = rulesColumns.some((col) => col.name === 'token_reset_base_time');
204
+ if (!hasTokenResetBaseTime) {
205
+ console.log('[DB] Running migration: Adding token_reset_base_time column to rules table');
206
+ this.db.exec('ALTER TABLE rules ADD COLUMN token_reset_base_time INTEGER;');
207
+ console.log('[DB] Migration completed: token_reset_base_time column added');
208
+ }
209
+ // 检查api_services表是否有超量配置相关字段
210
+ // Token超量配置
211
+ const hasEnableTokenLimit = columns.some((col) => col.name === 'enable_token_limit');
212
+ if (!hasEnableTokenLimit) {
213
+ console.log('[DB] Running migration: Adding enable_token_limit column to api_services table');
214
+ this.db.exec('ALTER TABLE api_services ADD COLUMN enable_token_limit INTEGER DEFAULT 0;');
215
+ console.log('[DB] Migration completed: enable_token_limit column added');
216
+ }
217
+ const hasServiceTokenLimit = columns.some((col) => col.name === 'token_limit');
218
+ if (!hasServiceTokenLimit) {
219
+ console.log('[DB] Running migration: Adding token_limit column to api_services table');
220
+ this.db.exec('ALTER TABLE api_services ADD COLUMN token_limit INTEGER;');
221
+ console.log('[DB] Migration completed: token_limit column added');
222
+ }
223
+ const hasTokenResetInterval = columns.some((col) => col.name === 'token_reset_interval');
224
+ if (!hasTokenResetInterval) {
225
+ console.log('[DB] Running migration: Adding token_reset_interval column to api_services table');
226
+ this.db.exec('ALTER TABLE api_services ADD COLUMN token_reset_interval INTEGER;');
227
+ console.log('[DB] Migration completed: token_reset_interval column added');
228
+ }
229
+ const hasServiceTokenResetBaseTime = columns.some((col) => col.name === 'token_reset_base_time');
230
+ if (!hasServiceTokenResetBaseTime) {
231
+ console.log('[DB] Running migration: Adding token_reset_base_time column to api_services table');
232
+ this.db.exec('ALTER TABLE api_services ADD COLUMN token_reset_base_time INTEGER;');
233
+ console.log('[DB] Migration completed: token_reset_base_time column added');
234
+ }
235
+ // 请求次数超量配置
236
+ const hasEnableRequestLimit = columns.some((col) => col.name === 'enable_request_limit');
237
+ if (!hasEnableRequestLimit) {
238
+ console.log('[DB] Running migration: Adding enable_request_limit column to api_services table');
239
+ this.db.exec('ALTER TABLE api_services ADD COLUMN enable_request_limit INTEGER DEFAULT 0;');
240
+ console.log('[DB] Migration completed: enable_request_limit column added');
241
+ }
242
+ const hasServiceRequestCountLimit = columns.some((col) => col.name === 'request_count_limit');
243
+ if (!hasServiceRequestCountLimit) {
244
+ console.log('[DB] Running migration: Adding request_count_limit column to api_services table');
245
+ this.db.exec('ALTER TABLE api_services ADD COLUMN request_count_limit INTEGER;');
246
+ console.log('[DB] Migration completed: request_count_limit column added');
247
+ }
248
+ const hasServiceRequestResetInterval = columns.some((col) => col.name === 'request_reset_interval');
249
+ if (!hasServiceRequestResetInterval) {
250
+ console.log('[DB] Running migration: Adding request_reset_interval column to api_services table');
251
+ this.db.exec('ALTER TABLE api_services ADD COLUMN request_reset_interval INTEGER;');
252
+ console.log('[DB] Migration completed: request_reset_interval column added');
253
+ }
254
+ const hasServiceRequestResetBaseTime = columns.some((col) => col.name === 'request_reset_base_time');
255
+ if (!hasServiceRequestResetBaseTime) {
256
+ console.log('[DB] Running migration: Adding request_reset_base_time column to api_services table');
257
+ this.db.exec('ALTER TABLE api_services ADD COLUMN request_reset_base_time INTEGER;');
258
+ console.log('[DB] Migration completed: request_reset_base_time column added');
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
+ }
183
267
  });
184
268
  }
185
269
  migrateMaxOutputTokensToModelLimits() {
@@ -294,6 +378,10 @@ class DatabaseManager {
294
378
  total_tokens_used INTEGER DEFAULT 0,
295
379
  reset_interval INTEGER,
296
380
  last_reset_at INTEGER,
381
+ request_count_limit INTEGER,
382
+ total_requests_used INTEGER DEFAULT 0,
383
+ request_reset_interval INTEGER,
384
+ request_last_reset_at INTEGER,
297
385
  created_at INTEGER NOT NULL,
298
386
  updated_at INTEGER NOT NULL,
299
387
  FOREIGN KEY (route_id) REFERENCES routes(id) ON DELETE CASCADE,
@@ -304,6 +392,21 @@ class DatabaseManager {
304
392
  key TEXT PRIMARY KEY,
305
393
  value TEXT NOT NULL
306
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
+ );
307
410
  `);
308
411
  }
309
412
  ensureDefaultConfig() {
@@ -372,9 +475,20 @@ class DatabaseManager {
372
475
  apiUrl: row.api_url,
373
476
  apiKey: row.api_key,
374
477
  sourceType: row.source_type,
478
+ authType: row.auth_type,
375
479
  supportedModels: row.supported_models ? row.supported_models.split(',').map((model) => model.trim()).filter((model) => model.length > 0) : undefined,
376
480
  modelLimits: row.model_limits ? JSON.parse(row.model_limits) : undefined,
377
481
  enableProxy: row.enable_proxy === 1,
482
+ // Token超量配置
483
+ enableTokenLimit: row.enable_token_limit === 1,
484
+ tokenLimit: row.token_limit,
485
+ tokenResetInterval: row.token_reset_interval,
486
+ tokenResetBaseTime: row.token_reset_base_time,
487
+ // 请求次数超量配置
488
+ enableRequestLimit: row.enable_request_limit === 1,
489
+ requestCountLimit: row.request_count_limit,
490
+ requestResetInterval: row.request_reset_interval,
491
+ requestResetBaseTime: row.request_reset_base_time,
378
492
  createdAt: row.created_at,
379
493
  updatedAt: row.updated_at,
380
494
  }));
@@ -388,15 +502,15 @@ class DatabaseManager {
388
502
  const id = crypto_1.default.randomUUID();
389
503
  const now = Date.now();
390
504
  this.db
391
- .prepare('INSERT INTO api_services (id, vendor_id, name, api_url, api_key, source_type, supported_models, model_limits, enable_proxy, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)')
392
- .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, 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);
393
507
  return Object.assign(Object.assign({}, service), { id, createdAt: now, updatedAt: now });
394
508
  }
395
509
  updateAPIService(id, service) {
396
510
  const now = Date.now();
397
511
  const result = this.db
398
- .prepare('UPDATE api_services SET name = ?, api_url = ?, api_key = ?, source_type = ?, supported_models = ?, model_limits = ?, enable_proxy = ?, updated_at = ? WHERE id = ?')
399
- .run(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, 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);
400
514
  // 调试日志: 记录更新操作
401
515
  if (result.changes > 0 && process.env.NODE_ENV === 'development') {
402
516
  console.log(`[DB] Updated service ${id}: ${service.name} -> ${service.apiUrl}`);
@@ -472,23 +586,56 @@ class DatabaseManager {
472
586
  totalTokensUsed: row.total_tokens_used,
473
587
  resetInterval: row.reset_interval,
474
588
  lastResetAt: row.last_reset_at,
589
+ tokenResetBaseTime: row.token_reset_base_time,
590
+ requestCountLimit: row.request_count_limit,
591
+ totalRequestsUsed: row.total_requests_used,
592
+ requestResetInterval: row.request_reset_interval,
593
+ requestLastResetAt: row.request_last_reset_at,
594
+ requestResetBaseTime: row.request_reset_base_time,
475
595
  createdAt: row.created_at,
476
596
  updatedAt: row.updated_at,
477
597
  }));
478
598
  }
599
+ getRule(id) {
600
+ const row = this.db.prepare('SELECT * FROM rules WHERE id = ?').get(id);
601
+ if (!row)
602
+ return undefined;
603
+ return {
604
+ id: row.id,
605
+ routeId: row.route_id,
606
+ contentType: row.content_type,
607
+ targetServiceId: row.target_service_id,
608
+ targetModel: row.target_model,
609
+ replacedModel: row.replaced_model,
610
+ sortOrder: row.sort_order,
611
+ timeout: row.timeout,
612
+ tokenLimit: row.token_limit,
613
+ totalTokensUsed: row.total_tokens_used,
614
+ resetInterval: row.reset_interval,
615
+ lastResetAt: row.last_reset_at,
616
+ tokenResetBaseTime: row.token_reset_base_time,
617
+ requestCountLimit: row.request_count_limit,
618
+ totalRequestsUsed: row.total_requests_used,
619
+ requestResetInterval: row.request_reset_interval,
620
+ requestLastResetAt: row.request_last_reset_at,
621
+ requestResetBaseTime: row.request_reset_base_time,
622
+ createdAt: row.created_at,
623
+ updatedAt: row.updated_at,
624
+ };
625
+ }
479
626
  createRule(route) {
480
627
  const id = crypto_1.default.randomUUID();
481
628
  const now = Date.now();
482
629
  this.db
483
- .prepare('INSERT INTO rules (id, route_id, content_type, target_service_id, target_model, replaced_model, sort_order, timeout, token_limit, total_tokens_used, reset_interval, last_reset_at, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)')
484
- .run(id, route.routeId, route.contentType, route.targetServiceId, route.targetModel || null, route.replacedModel || null, route.sortOrder || 0, route.timeout || null, route.tokenLimit || null, route.totalTokensUsed || 0, route.resetInterval || null, route.lastResetAt || null, now, now);
630
+ .prepare('INSERT INTO rules (id, route_id, content_type, target_service_id, target_model, replaced_model, sort_order, timeout, token_limit, total_tokens_used, reset_interval, last_reset_at, token_reset_base_time, request_count_limit, total_requests_used, request_reset_interval, request_last_reset_at, request_reset_base_time, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)')
631
+ .run(id, route.routeId, route.contentType, route.targetServiceId, route.targetModel || null, route.replacedModel || null, route.sortOrder || 0, route.timeout || null, route.tokenLimit || null, route.totalTokensUsed || 0, route.resetInterval || null, route.lastResetAt || null, route.tokenResetBaseTime || null, route.requestCountLimit || null, route.totalRequestsUsed || 0, route.requestResetInterval || null, route.requestLastResetAt || null, route.requestResetBaseTime || null, now, now);
485
632
  return Object.assign(Object.assign({}, route), { id, createdAt: now, updatedAt: now });
486
633
  }
487
634
  updateRule(id, route) {
488
635
  const now = Date.now();
489
636
  const result = this.db
490
- .prepare('UPDATE rules SET content_type = ?, target_service_id = ?, target_model = ?, replaced_model = ?, sort_order = ?, timeout = ?, token_limit = ?, reset_interval = ?, updated_at = ? WHERE id = ?')
491
- .run(route.contentType, route.targetServiceId, route.targetModel || null, route.replacedModel || null, route.sortOrder || 0, route.timeout !== undefined ? route.timeout : null, route.tokenLimit !== undefined ? route.tokenLimit : null, route.resetInterval !== undefined ? route.resetInterval : null, now, id);
637
+ .prepare('UPDATE rules SET content_type = ?, target_service_id = ?, target_model = ?, replaced_model = ?, sort_order = ?, timeout = ?, token_limit = ?, reset_interval = ?, token_reset_base_time = ?, request_count_limit = ?, request_reset_interval = ?, request_reset_base_time = ?, updated_at = ? WHERE id = ?')
638
+ .run(route.contentType, route.targetServiceId, route.targetModel || null, route.replacedModel || null, route.sortOrder || 0, route.timeout !== undefined ? route.timeout : null, route.tokenLimit !== undefined ? route.tokenLimit : null, route.resetInterval !== undefined ? route.resetInterval : null, route.tokenResetBaseTime !== undefined ? route.tokenResetBaseTime : null, route.requestCountLimit !== undefined ? route.requestCountLimit : null, route.requestResetInterval !== undefined ? route.requestResetInterval : null, route.requestResetBaseTime !== undefined ? route.requestResetBaseTime : null, now, id);
492
639
  return result.changes > 0;
493
640
  }
494
641
  deleteRule(id) {
@@ -527,28 +674,133 @@ class DatabaseManager {
527
674
  */
528
675
  checkAndResetRuleIfNeeded(ruleId) {
529
676
  const rule = this.db
530
- .prepare('SELECT reset_interval, last_reset_at FROM rules WHERE id = ?')
677
+ .prepare('SELECT reset_interval, last_reset_at, token_reset_base_time FROM rules WHERE id = ?')
531
678
  .get(ruleId);
532
679
  if (!rule || !rule.reset_interval) {
533
680
  return false; // 没有设置重置间隔
534
681
  }
535
682
  const now = Date.now();
536
683
  const resetIntervalMs = rule.reset_interval * 60 * 60 * 1000; // 小时转毫秒
684
+ const baseTime = rule.token_reset_base_time;
537
685
  const lastResetAt = rule.last_reset_at || 0;
538
- // 检查是否已经到了重置时间
686
+ // 场景1: 设置了时间基点
687
+ if (baseTime) {
688
+ if (now >= baseTime) {
689
+ this.resetRuleTokenUsageWithBaseTime(ruleId, baseTime);
690
+ return true;
691
+ }
692
+ return false;
693
+ }
694
+ // 场景2: 未设置时间基点,使用原始逻辑(向后兼容)
539
695
  if (now - lastResetAt >= resetIntervalMs) {
540
696
  this.resetRuleTokenUsage(ruleId);
541
697
  return true;
542
698
  }
543
699
  return false;
544
700
  }
701
+ /**
702
+ * 重置规则的Token使用量(带时间基点更新)
703
+ */
704
+ resetRuleTokenUsageWithBaseTime(ruleId, currentBaseTime) {
705
+ const now = Date.now();
706
+ const rule = this.db
707
+ .prepare('SELECT reset_interval FROM rules WHERE id = ?')
708
+ .get(ruleId);
709
+ if (!rule || !rule.reset_interval) {
710
+ return false;
711
+ }
712
+ const resetIntervalMs = rule.reset_interval * 60 * 60 * 1000;
713
+ // 计算下一个时间基点
714
+ let nextBaseTime = currentBaseTime;
715
+ while (nextBaseTime <= now) {
716
+ nextBaseTime += resetIntervalMs;
717
+ }
718
+ const result = this.db
719
+ .prepare('UPDATE rules SET total_tokens_used = 0, last_reset_at = ?, token_reset_base_time = ? WHERE id = ?')
720
+ .run(now, nextBaseTime, ruleId);
721
+ return result.changes > 0;
722
+ }
723
+ /**
724
+ * 增加规则的请求次数
725
+ * @param ruleId 规则ID
726
+ * @param count 增加的次数
727
+ * @returns 是否成功
728
+ */
729
+ incrementRuleRequestCount(ruleId, count) {
730
+ const result = this.db
731
+ .prepare('UPDATE rules SET total_requests_used = total_requests_used + ? WHERE id = ?')
732
+ .run(count, ruleId);
733
+ return result.changes > 0;
734
+ }
735
+ /**
736
+ * 重置规则的请求次数
737
+ * @param ruleId 规则ID
738
+ * @returns 是否成功
739
+ */
740
+ resetRuleRequestCount(ruleId) {
741
+ const now = Date.now();
742
+ const result = this.db
743
+ .prepare('UPDATE rules SET total_requests_used = 0, request_last_reset_at = ? WHERE id = ?')
744
+ .run(now, ruleId);
745
+ return result.changes > 0;
746
+ }
747
+ /**
748
+ * 检查并重置到期的规则(请求次数)
749
+ * 如果规则设置了request_reset_interval且已经到了重置时间,则自动重置请求次数
750
+ * @param ruleId 规则ID
751
+ * @returns 是否进行了重置
752
+ */
753
+ checkAndResetRequestCountIfNeeded(ruleId) {
754
+ const rule = this.db
755
+ .prepare('SELECT request_reset_interval, request_last_reset_at, request_reset_base_time FROM rules WHERE id = ?')
756
+ .get(ruleId);
757
+ if (!rule || !rule.request_reset_interval) {
758
+ return false; // 没有设置重置间隔
759
+ }
760
+ const now = Date.now();
761
+ const resetIntervalMs = rule.request_reset_interval * 60 * 60 * 1000; // 小时转毫秒
762
+ const baseTime = rule.request_reset_base_time;
763
+ const lastResetAt = rule.request_last_reset_at || 0;
764
+ // 场景1: 设置了时间基点
765
+ if (baseTime) {
766
+ if (now >= baseTime) {
767
+ this.resetRuleRequestCountWithBaseTime(ruleId, baseTime);
768
+ return true;
769
+ }
770
+ return false;
771
+ }
772
+ // 场景2: 未设置时间基点,使用原始逻辑(向后兼容)
773
+ if (now - lastResetAt >= resetIntervalMs) {
774
+ this.resetRuleRequestCount(ruleId);
775
+ return true;
776
+ }
777
+ return false;
778
+ }
779
+ /**
780
+ * 重置规则的请求次数(带时间基点更新)
781
+ */
782
+ resetRuleRequestCountWithBaseTime(ruleId, currentBaseTime) {
783
+ const now = Date.now();
784
+ const rule = this.db
785
+ .prepare('SELECT request_reset_interval FROM rules WHERE id = ?')
786
+ .get(ruleId);
787
+ if (!rule || !rule.request_reset_interval) {
788
+ return false;
789
+ }
790
+ const resetIntervalMs = rule.request_reset_interval * 60 * 60 * 1000;
791
+ // 计算下一个时间基点
792
+ let nextBaseTime = currentBaseTime;
793
+ while (nextBaseTime <= now) {
794
+ nextBaseTime += resetIntervalMs;
795
+ }
796
+ const result = this.db
797
+ .prepare('UPDATE rules SET total_requests_used = 0, request_last_reset_at = ?, request_reset_base_time = ? WHERE id = ?')
798
+ .run(now, nextBaseTime, ruleId);
799
+ return result.changes > 0;
800
+ }
545
801
  // Log operations
546
802
  addLog(log) {
547
803
  return __awaiter(this, void 0, void 0, function* () {
548
- const { path } = log;
549
- if (!path.startsWith('/v1/')) {
550
- return;
551
- }
552
804
  const id = crypto_1.default.randomUUID();
553
805
  yield this.logDb.put(id, JSON.stringify(Object.assign(Object.assign({}, log), { id })));
554
806
  // 清除缓存
@@ -587,55 +839,6 @@ class DatabaseManager {
587
839
  this.logsCountCache = null;
588
840
  });
589
841
  }
590
- // Access log operations
591
- addAccessLog(log) {
592
- return __awaiter(this, void 0, void 0, function* () {
593
- const id = crypto_1.default.randomUUID();
594
- yield this.accessLogDb.put(id, JSON.stringify(Object.assign(Object.assign({}, log), { id })));
595
- // 清除缓存
596
- this.accessLogsCountCache = null;
597
- return id;
598
- });
599
- }
600
- updateAccessLog(id, data) {
601
- return __awaiter(this, void 0, void 0, function* () {
602
- const log = yield this.accessLogDb.get(id);
603
- const updatedLog = Object.assign(Object.assign({}, JSON.parse(log)), data);
604
- yield this.accessLogDb.put(id, JSON.stringify(updatedLog));
605
- });
606
- }
607
- getAccessLogs() {
608
- return __awaiter(this, arguments, void 0, function* (limit = 100, offset = 0) {
609
- var _a, e_2, _b, _c;
610
- const allLogs = [];
611
- try {
612
- for (var _d = true, _e = __asyncValues(this.accessLogDb.iterator()), _f; _f = yield _e.next(), _a = _f.done, !_a; _d = true) {
613
- _c = _f.value;
614
- _d = false;
615
- const [, value] = _c;
616
- allLogs.push(JSON.parse(value));
617
- }
618
- }
619
- catch (e_2_1) { e_2 = { error: e_2_1 }; }
620
- finally {
621
- try {
622
- if (!_d && !_a && (_b = _e.return)) yield _b.call(_e);
623
- }
624
- finally { if (e_2) throw e_2.error; }
625
- }
626
- // Sort by timestamp in descending order (newest first)
627
- allLogs.sort((a, b) => b.timestamp - a.timestamp);
628
- // Apply offset and limit
629
- return allLogs.slice(offset, offset + limit);
630
- });
631
- }
632
- clearAccessLogs() {
633
- return __awaiter(this, void 0, void 0, function* () {
634
- yield this.accessLogDb.clear();
635
- // 清除缓存
636
- this.accessLogsCountCache = null;
637
- });
638
- }
639
842
  // Error log operations
640
843
  addErrorLog(log) {
641
844
  return __awaiter(this, void 0, void 0, function* () {
@@ -647,7 +850,7 @@ class DatabaseManager {
647
850
  }
648
851
  getErrorLogs() {
649
852
  return __awaiter(this, arguments, void 0, function* (limit = 100, offset = 0) {
650
- var _a, e_3, _b, _c;
853
+ var _a, e_2, _b, _c;
651
854
  const allLogs = [];
652
855
  try {
653
856
  for (var _d = true, _e = __asyncValues(this.errorLogDb.iterator()), _f; _f = yield _e.next(), _a = _f.done, !_a; _d = true) {
@@ -657,12 +860,12 @@ class DatabaseManager {
657
860
  allLogs.push(JSON.parse(value));
658
861
  }
659
862
  }
660
- catch (e_3_1) { e_3 = { error: e_3_1 }; }
863
+ catch (e_2_1) { e_2 = { error: e_2_1 }; }
661
864
  finally {
662
865
  try {
663
866
  if (!_d && !_a && (_b = _e.return)) yield _b.call(_e);
664
867
  }
665
- finally { if (e_3) throw e_3.error; }
868
+ finally { if (e_2) throw e_2.error; }
666
869
  }
667
870
  // Sort by timestamp in descending order (newest first)
668
871
  allLogs.sort((a, b) => b.timestamp - a.timestamp);
@@ -682,7 +885,7 @@ class DatabaseManager {
682
885
  */
683
886
  getLogsCount() {
684
887
  return __awaiter(this, void 0, void 0, function* () {
685
- var _a, e_4, _b, _c;
888
+ var _a, e_3, _b, _c;
686
889
  const now = Date.now();
687
890
  if (this.logsCountCache && now - this.logsCountCache.timestamp < this.CACHE_TTL) {
688
891
  return this.logsCountCache.count;
@@ -696,53 +899,23 @@ class DatabaseManager {
696
899
  count++;
697
900
  }
698
901
  }
699
- catch (e_4_1) { e_4 = { error: e_4_1 }; }
902
+ catch (e_3_1) { e_3 = { error: e_3_1 }; }
700
903
  finally {
701
904
  try {
702
905
  if (!_d && !_a && (_b = _e.return)) yield _b.call(_e);
703
906
  }
704
- finally { if (e_4) throw e_4.error; }
907
+ finally { if (e_3) throw e_3.error; }
705
908
  }
706
909
  this.logsCountCache = { count, timestamp: now };
707
910
  return count;
708
911
  });
709
912
  }
710
- /**
711
- * 获取访问日志总数(带缓存)
712
- */
713
- getAccessLogsCount() {
714
- return __awaiter(this, void 0, void 0, function* () {
715
- var _a, e_5, _b, _c;
716
- const now = Date.now();
717
- if (this.accessLogsCountCache && now - this.accessLogsCountCache.timestamp < this.CACHE_TTL) {
718
- return this.accessLogsCountCache.count;
719
- }
720
- let count = 0;
721
- try {
722
- for (var _d = true, _e = __asyncValues(this.accessLogDb.iterator()), _f; _f = yield _e.next(), _a = _f.done, !_a; _d = true) {
723
- _c = _f.value;
724
- _d = false;
725
- const _ = _c;
726
- count++;
727
- }
728
- }
729
- catch (e_5_1) { e_5 = { error: e_5_1 }; }
730
- finally {
731
- try {
732
- if (!_d && !_a && (_b = _e.return)) yield _b.call(_e);
733
- }
734
- finally { if (e_5) throw e_5.error; }
735
- }
736
- this.accessLogsCountCache = { count, timestamp: now };
737
- return count;
738
- });
739
- }
740
913
  /**
741
914
  * 获取错误日志总数(带缓存)
742
915
  */
743
916
  getErrorLogsCount() {
744
917
  return __awaiter(this, void 0, void 0, function* () {
745
- var _a, e_6, _b, _c;
918
+ var _a, e_4, _b, _c;
746
919
  const now = Date.now();
747
920
  if (this.errorLogsCountCache && now - this.errorLogsCountCache.timestamp < this.CACHE_TTL) {
748
921
  return this.errorLogsCountCache.count;
@@ -756,12 +929,12 @@ class DatabaseManager {
756
929
  count++;
757
930
  }
758
931
  }
759
- catch (e_6_1) { e_6 = { error: e_6_1 }; }
932
+ catch (e_4_1) { e_4 = { error: e_4_1 }; }
760
933
  finally {
761
934
  try {
762
935
  if (!_d && !_a && (_b = _e.return)) yield _b.call(_e);
763
936
  }
764
- finally { if (e_6) throw e_6.error; }
937
+ finally { if (e_4) throw e_4.error; }
765
938
  }
766
939
  this.errorLogsCountCache = { count, timestamp: now };
767
940
  return count;
@@ -790,7 +963,7 @@ class DatabaseManager {
790
963
  }
791
964
  });
792
965
  }
793
- addToBlacklist(serviceId, routeId, contentType, errorMessage, statusCode) {
966
+ addToBlacklist(serviceId, routeId, contentType, errorMessage, statusCode, errorType) {
794
967
  return __awaiter(this, void 0, void 0, function* () {
795
968
  const key = `${routeId}:${contentType}:${serviceId}`;
796
969
  const now = Date.now();
@@ -804,6 +977,7 @@ class DatabaseManager {
804
977
  entry.errorCount++;
805
978
  entry.lastError = errorMessage;
806
979
  entry.lastStatusCode = statusCode;
980
+ entry.errorType = errorType;
807
981
  yield this.blacklistDb.put(key, JSON.stringify(entry));
808
982
  }
809
983
  catch (error) {
@@ -818,6 +992,7 @@ class DatabaseManager {
818
992
  errorCount: 1,
819
993
  lastError: errorMessage,
820
994
  lastStatusCode: statusCode,
995
+ errorType,
821
996
  };
822
997
  yield this.blacklistDb.put(key, JSON.stringify(entry));
823
998
  }
@@ -827,9 +1002,15 @@ class DatabaseManager {
827
1002
  }
828
1003
  });
829
1004
  }
1005
+ removeFromBlacklist(serviceId, routeId, contentType) {
1006
+ return __awaiter(this, void 0, void 0, function* () {
1007
+ const key = `${routeId}:${contentType}:${serviceId}`;
1008
+ yield this.blacklistDb.del(key);
1009
+ });
1010
+ }
830
1011
  cleanupExpiredBlacklist() {
831
1012
  return __awaiter(this, void 0, void 0, function* () {
832
- var _a, e_7, _b, _c;
1013
+ var _a, e_5, _b, _c;
833
1014
  const now = Date.now();
834
1015
  let count = 0;
835
1016
  try {
@@ -844,12 +1025,12 @@ class DatabaseManager {
844
1025
  }
845
1026
  }
846
1027
  }
847
- catch (e_7_1) { e_7 = { error: e_7_1 }; }
1028
+ catch (e_5_1) { e_5 = { error: e_5_1 }; }
848
1029
  finally {
849
1030
  try {
850
1031
  if (!_d && !_a && (_b = _e.return)) yield _b.call(_e);
851
1032
  }
852
- finally { if (e_7) throw e_7.error; }
1033
+ finally { if (e_5) throw e_5.error; }
853
1034
  }
854
1035
  return count;
855
1036
  });
@@ -902,8 +1083,8 @@ class DatabaseManager {
902
1083
  // Import API services
903
1084
  for (const service of importData.apiServices) {
904
1085
  this.db
905
- .prepare('INSERT INTO api_services (id, vendor_id, name, api_url, api_key, source_type, supported_models, model_limits, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)')
906
- .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.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);
907
1088
  }
908
1089
  // Import routes
909
1090
  for (const route of importData.routes) {
@@ -914,8 +1095,8 @@ class DatabaseManager {
914
1095
  // Import rules
915
1096
  for (const rule of importData.rules) {
916
1097
  this.db
917
- .prepare('INSERT INTO rules (id, route_id, content_type, target_service_id, target_model, replaced_model, sort_order, timeout, token_limit, total_tokens_used, reset_interval, last_reset_at, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)')
918
- .run(rule.id, rule.routeId, rule.contentType || 'default', rule.targetServiceId, rule.targetModel || null, rule.replacedModel || null, rule.sortOrder || 0, rule.timeout || null, rule.tokenLimit || null, rule.totalTokensUsed || 0, rule.resetInterval || null, rule.lastResetAt || null, rule.createdAt, rule.updatedAt);
1098
+ .prepare('INSERT INTO rules (id, route_id, content_type, target_service_id, target_model, replaced_model, sort_order, timeout, token_limit, total_tokens_used, reset_interval, last_reset_at, token_reset_base_time, request_count_limit, total_requests_used, request_reset_interval, request_last_reset_at, request_reset_base_time, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)')
1099
+ .run(rule.id, rule.routeId, rule.contentType || 'default', rule.targetServiceId, rule.targetModel || null, rule.replacedModel || null, rule.sortOrder || 0, rule.timeout || null, rule.tokenLimit || null, rule.totalTokensUsed || 0, rule.resetInterval || null, rule.lastResetAt || null, rule.tokenResetBaseTime || null, rule.requestCountLimit || null, rule.totalRequestsUsed || 0, rule.requestResetInterval || null, rule.requestLastResetAt || null, rule.requestResetBaseTime || null, rule.createdAt, rule.updatedAt);
919
1100
  }
920
1101
  // Update config
921
1102
  this.updateConfig(importData.config);
@@ -930,7 +1111,7 @@ class DatabaseManager {
930
1111
  // Statistics operations
931
1112
  getStatistics() {
932
1113
  return __awaiter(this, arguments, void 0, function* (days = 30) {
933
- var _a, e_8, _b, _c, _d, e_9, _e, _f;
1114
+ var _a, e_6, _b, _c, _d, e_7, _e, _f;
934
1115
  var _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y;
935
1116
  const now = Date.now();
936
1117
  const startTime = now - days * 24 * 60 * 60 * 1000;
@@ -947,12 +1128,12 @@ class DatabaseManager {
947
1128
  }
948
1129
  }
949
1130
  }
950
- catch (e_8_1) { e_8 = { error: e_8_1 }; }
1131
+ catch (e_6_1) { e_6 = { error: e_6_1 }; }
951
1132
  finally {
952
1133
  try {
953
1134
  if (!_z && !_a && (_b = _0.return)) yield _b.call(_0);
954
1135
  }
955
- finally { if (e_8) throw e_8.error; }
1136
+ finally { if (e_6) throw e_6.error; }
956
1137
  }
957
1138
  // Get all error logs
958
1139
  const errorLogs = [];
@@ -970,12 +1151,12 @@ class DatabaseManager {
970
1151
  }
971
1152
  }
972
1153
  }
973
- catch (e_9_1) { e_9 = { error: e_9_1 }; }
1154
+ catch (e_7_1) { e_7 = { error: e_7_1 }; }
974
1155
  finally {
975
1156
  try {
976
1157
  if (!_2 && !_d && (_e = _3.return)) yield _e.call(_3);
977
1158
  }
978
- finally { if (e_9) throw e_9.error; }
1159
+ finally { if (e_7) throw e_7.error; }
979
1160
  }
980
1161
  // Get vendors and services for mapping
981
1162
  const vendors = this.getVendors();
@@ -1150,10 +1331,180 @@ class DatabaseManager {
1150
1331
  };
1151
1332
  });
1152
1333
  }
1334
+ getRuleBlacklistStatus(serviceId, routeId, contentType) {
1335
+ return __awaiter(this, void 0, void 0, function* () {
1336
+ const key = `${routeId}:${contentType}:${serviceId}`;
1337
+ try {
1338
+ const value = yield this.blacklistDb.get(key);
1339
+ const entry = JSON.parse(value);
1340
+ // 检查是否过期
1341
+ if (Date.now() > entry.expiresAt) {
1342
+ yield this.blacklistDb.del(key);
1343
+ return null;
1344
+ }
1345
+ return entry;
1346
+ }
1347
+ catch (error) {
1348
+ if (error.code === 'LEVEL_NOT_FOUND') {
1349
+ return null;
1350
+ }
1351
+ throw error;
1352
+ }
1353
+ });
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
+ }
1153
1505
  close() {
1154
1506
  this.db.close();
1155
1507
  this.logDb.close();
1156
- this.accessLogDb.close();
1157
1508
  this.errorLogDb.close();
1158
1509
  this.blacklistDb.close();
1159
1510
  }