@pikoloo/codex-proxy 1.0.6 → 1.1.0
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.
- package/README.md +12 -5
- package/docs/API.md +0 -15
- package/images/dashboard-screenshot.png +0 -0
- package/images/readme-cover.png +0 -0
- package/images/settings-screenshot.png +0 -0
- package/package.json +11 -3
- package/public/css/style.css +1097 -40
- package/public/index.html +439 -184
- package/public/js/app.js +384 -66
- package/src/account-rotation/index.js +64 -27
- package/src/format-converter.js +5 -1
- package/src/index.js +1 -1
- package/src/model-mapper.js +145 -22
- package/src/routes/api-routes.js +19 -3
- package/src/routes/chat-route.js +77 -4
- package/src/routes/messages-route.js +189 -21
- package/src/routes/metrics-route.js +43 -0
- package/src/routes/settings-route.js +127 -21
- package/src/security.js +2 -1
- package/src/server-settings.js +40 -5
- package/src/server.js +27 -2
- package/src/usage-metrics.js +472 -0
- package/src/utils/logger.js +14 -1
- package/images/demo-screenshot.png +0 -0
- package/images/f757093f-507b-4453-994e-f8275f8b07a9.png +0 -0
- package/src/account-rotation/strategies/base-strategy.js +0 -48
- package/src/account-rotation/strategies/index.js +0 -31
- package/src/account-rotation/strategies/round-robin-strategy.js +0 -42
- package/src/account-rotation/strategies/sticky-strategy.js +0 -97
|
@@ -1,97 +0,0 @@
|
|
|
1
|
-
import { BaseStrategy } from './base-strategy.js';
|
|
2
|
-
import { logger } from '../../utils/logger.js';
|
|
3
|
-
|
|
4
|
-
const MAX_WAIT_BEFORE_ERROR_MS = 120000;
|
|
5
|
-
|
|
6
|
-
export class StickyStrategy extends BaseStrategy {
|
|
7
|
-
constructor(config) {
|
|
8
|
-
super(config, 'sticky');
|
|
9
|
-
this.currentIndex = 0;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
selectAccount(accounts, modelId, options = {}) {
|
|
13
|
-
const { currentIndex = 0, onSave } = options;
|
|
14
|
-
|
|
15
|
-
if (!accounts || accounts.length === 0) {
|
|
16
|
-
return { account: null, index: currentIndex, waitMs: 0 };
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
const clampedIndex = Math.max(0, Math.min(currentIndex, accounts.length - 1));
|
|
20
|
-
const currentAccount = accounts[clampedIndex];
|
|
21
|
-
|
|
22
|
-
if (this.isAccountUsable(currentAccount, modelId)) {
|
|
23
|
-
currentAccount.lastUsed = Date.now();
|
|
24
|
-
if (onSave) onSave();
|
|
25
|
-
logger.debug(`StickyStrategy: Using sticky account at index ${clampedIndex}`);
|
|
26
|
-
return { account: currentAccount, index: clampedIndex, waitMs: 0 };
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
// Try to find another usable account
|
|
30
|
-
const usableAccounts = this.getUsableAccounts(accounts, modelId);
|
|
31
|
-
|
|
32
|
-
if (usableAccounts.length > 0) {
|
|
33
|
-
const nextResult = this.#pickNext(accounts, clampedIndex, modelId, onSave);
|
|
34
|
-
if (nextResult) {
|
|
35
|
-
this.currentIndex = nextResult.index;
|
|
36
|
-
return nextResult;
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
// Check if we should wait for the current account
|
|
41
|
-
const { shouldWait, waitMs } = this.#shouldWaitForAccount(currentAccount, modelId);
|
|
42
|
-
if (shouldWait && waitMs <= MAX_WAIT_BEFORE_ERROR_MS) {
|
|
43
|
-
logger.debug(`StickyStrategy: Waiting ${waitMs}ms for sticky account`);
|
|
44
|
-
return { account: null, index: clampedIndex, waitMs };
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
// No usable accounts, return null
|
|
48
|
-
return { account: null, index: clampedIndex, waitMs: 0 };
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
#shouldWaitForAccount(account, modelId) {
|
|
52
|
-
if (!account) {
|
|
53
|
-
return { shouldWait: false, waitMs: 0 };
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
if (account.isInvalid) {
|
|
57
|
-
return { shouldWait: false, waitMs: 0 };
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
if (account.enabled === false) {
|
|
61
|
-
return { shouldWait: false, waitMs: 0 };
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
// Check model-specific rate limit
|
|
65
|
-
if (modelId && account.modelRateLimits && account.modelRateLimits[modelId]) {
|
|
66
|
-
const limit = account.modelRateLimits[modelId];
|
|
67
|
-
if (limit.isRateLimited && limit.resetTime > Date.now()) {
|
|
68
|
-
const waitMs = limit.resetTime - Date.now();
|
|
69
|
-
if (waitMs <= MAX_WAIT_BEFORE_ERROR_MS) {
|
|
70
|
-
return { shouldWait: true, waitMs };
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
return { shouldWait: false, waitMs: 0 };
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
#pickNext(accounts, currentIndex, modelId, onSave) {
|
|
79
|
-
const startIndex = (currentIndex + 1) % accounts.length;
|
|
80
|
-
|
|
81
|
-
for (let i = 0; i < accounts.length; i++) {
|
|
82
|
-
const checkIndex = (startIndex + i) % accounts.length;
|
|
83
|
-
const account = accounts[checkIndex];
|
|
84
|
-
|
|
85
|
-
if (checkIndex === currentIndex) continue;
|
|
86
|
-
|
|
87
|
-
if (this.isAccountUsable(account, modelId)) {
|
|
88
|
-
account.lastUsed = Date.now();
|
|
89
|
-
if (onSave) onSave();
|
|
90
|
-
logger.debug(`StickyStrategy: Switched to account at index ${checkIndex}`);
|
|
91
|
-
return { account, index: checkIndex, waitMs: 0 };
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
return null;
|
|
96
|
-
}
|
|
97
|
-
}
|