@thelioo/opencode-balancer 0.1.8 → 0.2.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.
Files changed (176) hide show
  1. package/INSTALL.txt +53 -25
  2. package/README.md +95 -51
  3. package/dist/core/accounts.ts +404 -0
  4. package/dist/core/database.ts +67 -0
  5. package/dist/core/events.ts +75 -0
  6. package/dist/core/native-auth-suppression.ts +36 -0
  7. package/dist/core/native-connect.ts +31 -0
  8. package/dist/core/path.ts +34 -0
  9. package/dist/core/pending.ts +351 -0
  10. package/dist/core/priority.ts +193 -0
  11. package/dist/core/schema.ts +439 -0
  12. package/dist/core/time.ts +3 -0
  13. package/dist/core/types.ts +72 -0
  14. package/dist/core/usage/index.ts +23 -0
  15. package/dist/core/usage/providers/copilot.ts +243 -0
  16. package/dist/core/usage/providers/openai.ts +179 -0
  17. package/dist/core/usage/redact.ts +80 -0
  18. package/dist/core/usage/store.ts +66 -0
  19. package/dist/core/usage/types.ts +24 -0
  20. package/dist/index.js +173 -4
  21. package/dist/index.js.map +1 -1
  22. package/dist/server/auth-watcher.ts +318 -0
  23. package/dist/server/commands.ts +58 -0
  24. package/dist/server/fetch-patch.ts +162 -0
  25. package/dist/server/index.ts +134 -0
  26. package/dist/server/native.ts +49 -0
  27. package/dist/server/request-balancer.ts +67 -0
  28. package/dist/tui/actions.ts +176 -112
  29. package/dist/tui/balancer-bar-sync.ts +55 -45
  30. package/dist/tui/components/alias-dialog.tsx +71 -56
  31. package/dist/tui/components/dashboard.tsx +530 -358
  32. package/dist/tui/components/priority-screen.tsx +389 -267
  33. package/dist/tui/components/provider-model-dialog.tsx +71 -64
  34. package/dist/tui/components/rename-dialog.tsx +35 -28
  35. package/dist/tui/components/sidebar.tsx +103 -79
  36. package/dist/tui/components/status-indicator.tsx +78 -59
  37. package/dist/tui/components/usage-bar.tsx +18 -7
  38. package/dist/tui/components/usage-display.tsx +32 -16
  39. package/dist/tui/connect.ts +104 -73
  40. package/dist/tui/dashboard-keys.ts +53 -41
  41. package/dist/tui/native-model-apply.ts +45 -36
  42. package/dist/tui/priority-keys.ts +44 -36
  43. package/dist/tui/provider-models.ts +32 -25
  44. package/dist/tui/responsive.ts +10 -7
  45. package/dist/tui/selected-account-bar-sync.ts +23 -23
  46. package/dist/tui/selection-colors.ts +38 -30
  47. package/dist/tui/state.ts +61 -44
  48. package/dist/tui/status-format.ts +24 -20
  49. package/dist/tui/tui.js +165 -153
  50. package/dist/tui/tui.js.map +1 -1
  51. package/dist/tui/tui.tsx +194 -144
  52. package/dist/tui/usage-auto-refresh.ts +52 -45
  53. package/dist/tui/usage-format.ts +9 -9
  54. package/package.json +61 -52
  55. package/dist/core/accounts.d.ts +0 -14
  56. package/dist/core/accounts.js +0 -260
  57. package/dist/core/accounts.js.map +0 -1
  58. package/dist/core/database.d.ts +0 -4
  59. package/dist/core/database.js +0 -69
  60. package/dist/core/database.js.map +0 -1
  61. package/dist/core/events.d.ts +0 -18
  62. package/dist/core/events.js +0 -39
  63. package/dist/core/events.js.map +0 -1
  64. package/dist/core/native-auth-suppression.d.ts +0 -3
  65. package/dist/core/native-auth-suppression.js +0 -19
  66. package/dist/core/native-auth-suppression.js.map +0 -1
  67. package/dist/core/native-connect.d.ts +0 -4
  68. package/dist/core/native-connect.js +0 -19
  69. package/dist/core/native-connect.js.map +0 -1
  70. package/dist/core/path.d.ts +0 -4
  71. package/dist/core/path.js +0 -26
  72. package/dist/core/path.js.map +0 -1
  73. package/dist/core/pending.d.ts +0 -9
  74. package/dist/core/pending.js +0 -237
  75. package/dist/core/pending.js.map +0 -1
  76. package/dist/core/priority.d.ts +0 -20
  77. package/dist/core/priority.js +0 -120
  78. package/dist/core/priority.js.map +0 -1
  79. package/dist/core/schema.d.ts +0 -2
  80. package/dist/core/schema.js +0 -265
  81. package/dist/core/schema.js.map +0 -1
  82. package/dist/core/time.d.ts +0 -1
  83. package/dist/core/time.js +0 -4
  84. package/dist/core/time.js.map +0 -1
  85. package/dist/core/types.d.ts +0 -59
  86. package/dist/core/types.js +0 -2
  87. package/dist/core/types.js.map +0 -1
  88. package/dist/core/usage/index.d.ts +0 -4
  89. package/dist/core/usage/index.js +0 -16
  90. package/dist/core/usage/index.js.map +0 -1
  91. package/dist/core/usage/providers/copilot.d.ts +0 -2
  92. package/dist/core/usage/providers/copilot.js +0 -169
  93. package/dist/core/usage/providers/copilot.js.map +0 -1
  94. package/dist/core/usage/providers/openai.d.ts +0 -2
  95. package/dist/core/usage/providers/openai.js +0 -133
  96. package/dist/core/usage/providers/openai.js.map +0 -1
  97. package/dist/core/usage/redact.d.ts +0 -3
  98. package/dist/core/usage/redact.js +0 -67
  99. package/dist/core/usage/redact.js.map +0 -1
  100. package/dist/core/usage/store.d.ts +0 -4
  101. package/dist/core/usage/store.js +0 -31
  102. package/dist/core/usage/store.js.map +0 -1
  103. package/dist/core/usage/types.d.ts +0 -21
  104. package/dist/core/usage/types.js +0 -2
  105. package/dist/core/usage/types.js.map +0 -1
  106. package/dist/index.d.ts +0 -5
  107. package/dist/server/auth-watcher.d.ts +0 -32
  108. package/dist/server/auth-watcher.js +0 -227
  109. package/dist/server/auth-watcher.js.map +0 -1
  110. package/dist/server/commands.d.ts +0 -2
  111. package/dist/server/commands.js +0 -46
  112. package/dist/server/commands.js.map +0 -1
  113. package/dist/server/fetch-patch.d.ts +0 -3
  114. package/dist/server/fetch-patch.js +0 -118
  115. package/dist/server/fetch-patch.js.map +0 -1
  116. package/dist/server/index.d.ts +0 -8
  117. package/dist/server/index.js +0 -94
  118. package/dist/server/index.js.map +0 -1
  119. package/dist/server/native.d.ts +0 -6
  120. package/dist/server/native.js +0 -35
  121. package/dist/server/native.js.map +0 -1
  122. package/dist/server/request-balancer.d.ts +0 -16
  123. package/dist/server/request-balancer.js +0 -43
  124. package/dist/server/request-balancer.js.map +0 -1
  125. package/dist/tui/actions.d.ts +0 -41
  126. package/dist/tui/actions.js +0 -92
  127. package/dist/tui/actions.js.map +0 -1
  128. package/dist/tui/balancer-bar-sync.d.ts +0 -19
  129. package/dist/tui/balancer-bar-sync.js +0 -45
  130. package/dist/tui/balancer-bar-sync.js.map +0 -1
  131. package/dist/tui/components/alias-dialog.d.ts +0 -4
  132. package/dist/tui/components/dashboard.d.ts +0 -12
  133. package/dist/tui/components/priority-screen.d.ts +0 -9
  134. package/dist/tui/components/provider-model-dialog.d.ts +0 -14
  135. package/dist/tui/components/rename-dialog.d.ts +0 -4
  136. package/dist/tui/components/sidebar.d.ts +0 -10
  137. package/dist/tui/components/status-indicator.d.ts +0 -9
  138. package/dist/tui/components/usage-bar.d.ts +0 -8
  139. package/dist/tui/components/usage-display.d.ts +0 -10
  140. package/dist/tui/connect.d.ts +0 -30
  141. package/dist/tui/connect.js +0 -75
  142. package/dist/tui/connect.js.map +0 -1
  143. package/dist/tui/dashboard-keys.d.ts +0 -45
  144. package/dist/tui/dashboard-keys.js +0 -44
  145. package/dist/tui/dashboard-keys.js.map +0 -1
  146. package/dist/tui/native-model-apply.d.ts +0 -21
  147. package/dist/tui/native-model-apply.js +0 -53
  148. package/dist/tui/native-model-apply.js.map +0 -1
  149. package/dist/tui/priority-keys.d.ts +0 -40
  150. package/dist/tui/priority-keys.js +0 -38
  151. package/dist/tui/priority-keys.js.map +0 -1
  152. package/dist/tui/provider-models.d.ts +0 -19
  153. package/dist/tui/provider-models.js +0 -17
  154. package/dist/tui/provider-models.js.map +0 -1
  155. package/dist/tui/responsive.d.ts +0 -9
  156. package/dist/tui/responsive.js +0 -13
  157. package/dist/tui/responsive.js.map +0 -1
  158. package/dist/tui/selected-account-bar-sync.d.ts +0 -10
  159. package/dist/tui/selected-account-bar-sync.js +0 -26
  160. package/dist/tui/selected-account-bar-sync.js.map +0 -1
  161. package/dist/tui/selection-colors.d.ts +0 -10
  162. package/dist/tui/selection-colors.js +0 -38
  163. package/dist/tui/selection-colors.js.map +0 -1
  164. package/dist/tui/state.d.ts +0 -14
  165. package/dist/tui/state.js +0 -46
  166. package/dist/tui/state.js.map +0 -1
  167. package/dist/tui/status-format.d.ts +0 -15
  168. package/dist/tui/status-format.js +0 -17
  169. package/dist/tui/status-format.js.map +0 -1
  170. package/dist/tui/tui.d.ts +0 -7
  171. package/dist/tui/usage-auto-refresh.d.ts +0 -16
  172. package/dist/tui/usage-auto-refresh.js +0 -46
  173. package/dist/tui/usage-auto-refresh.js.map +0 -1
  174. package/dist/tui/usage-format.d.ts +0 -2
  175. package/dist/tui/usage-format.js +0 -17
  176. package/dist/tui/usage-format.js.map +0 -1
@@ -1,237 +0,0 @@
1
- import { createHash } from "node:crypto";
2
- import { saveAccount } from "./accounts";
3
- import { now } from "./time";
4
- const pendingSources = ["auth-file", "http", "oauth-callback"];
5
- const promptStatuses = ["new", "prompted", "dismissed"];
6
- const authTypes = ["api", "oauth", "wellknown"];
7
- function isAuthType(value) {
8
- return authTypes.includes(value);
9
- }
10
- function parsePendingAuth(row) {
11
- let auth;
12
- try {
13
- auth = JSON.parse(row.auth_json);
14
- }
15
- catch {
16
- throw new Error(`Invalid pending connection row ${row.id}: auth_json is invalid`);
17
- }
18
- if (!auth || typeof auth !== "object" || !("type" in auth) || typeof auth.type !== "string") {
19
- throw new Error(`Invalid pending connection row ${row.id}: auth_json type is invalid`);
20
- }
21
- if (!isAuthType(auth.type)) {
22
- throw new Error(`Invalid pending connection row ${row.id}: auth_json type ${auth.type} is invalid`);
23
- }
24
- return auth;
25
- }
26
- function validatePendingAuthType(row) {
27
- if (!isAuthType(row.auth_type)) {
28
- throw new Error(`Invalid pending connection row ${row.id}: auth_type ${row.auth_type} is invalid`);
29
- }
30
- return row.auth_type;
31
- }
32
- function validatePendingSource(row) {
33
- if (!pendingSources.includes(row.source)) {
34
- throw new Error(`Invalid pending connection row ${row.id}: source ${row.source} is invalid`);
35
- }
36
- return row.source;
37
- }
38
- function validatePromptStatus(row) {
39
- if (!promptStatuses.includes(row.prompt_status)) {
40
- throw new Error(`Invalid pending connection row ${row.id}: prompt_status ${row.prompt_status} is invalid`);
41
- }
42
- return row.prompt_status;
43
- }
44
- function pendingConnectionFromRow(row) {
45
- const auth = parsePendingAuth(row);
46
- const authType = validatePendingAuthType(row);
47
- if (auth.type !== authType) {
48
- throw new Error(`Invalid pending connection row ${row.id}: auth_type ${authType} does not match auth_json type ${auth.type}`);
49
- }
50
- return {
51
- id: row.id,
52
- providerID: row.provider_id,
53
- auth,
54
- authType,
55
- source: validatePendingSource(row),
56
- capturedAt: row.captured_at,
57
- promptStatus: validatePromptStatus(row),
58
- };
59
- }
60
- function authIdentityKey(auth) {
61
- if (auth.type === "api")
62
- return `api\0${auth.key}`;
63
- if (auth.type === "wellknown")
64
- return `wellknown\0${auth.key}\0${auth.token}`;
65
- const accountID = oauthAccountID(auth);
66
- return accountID ? `oauth-account\0${accountID}` : `oauth-refresh\0${auth.refresh}`;
67
- }
68
- function decodeJwtPayload(token) {
69
- const payload = token.split(".")[1];
70
- if (!payload)
71
- return undefined;
72
- try {
73
- const decoded = JSON.parse(Buffer.from(payload, "base64url").toString("utf8"));
74
- return decoded && typeof decoded === "object" && !Array.isArray(decoded) ? decoded : undefined;
75
- }
76
- catch {
77
- return undefined;
78
- }
79
- }
80
- function oauthAccountID(auth) {
81
- if (auth.accountId)
82
- return auth.accountId;
83
- const claim = decodeJwtPayload(auth.access)?.["https://api.openai.com/auth"];
84
- if (!claim || typeof claim !== "object" || Array.isArray(claim))
85
- return undefined;
86
- const accountID = claim.chatgpt_account_id;
87
- return typeof accountID === "string" && accountID.length > 0 ? accountID : undefined;
88
- }
89
- function samePendingIdentity(auth, other) {
90
- return authIdentityKey(auth) === authIdentityKey(other);
91
- }
92
- function pendingID(providerID, auth, source) {
93
- const hash = createHash("sha256")
94
- .update(`${providerID}\0${source}\0${authIdentityKey(auth)}`)
95
- .digest("hex")
96
- .slice(0, 32);
97
- return `pending-${hash}`;
98
- }
99
- export function pendingPromptGroupID(db, id) {
100
- const row = selectPendingRow(db, id);
101
- if (!row)
102
- return undefined;
103
- const identity = pendingIdentity(row);
104
- return `${identity.providerID}\0${identity.source}\0${authIdentityKey(identity.auth)}`;
105
- }
106
- function selectPendingRow(db, id) {
107
- return db
108
- .query(`SELECT id, provider_id, auth_json, auth_type, source, captured_at, prompt_status
109
- FROM pending_connections
110
- WHERE id = ?`)
111
- .get(id);
112
- }
113
- function pendingIdentity(row) {
114
- return {
115
- providerID: row.provider_id,
116
- auth: parsePendingAuth(row),
117
- source: validatePendingSource(row),
118
- };
119
- }
120
- function equivalentPendingRows(db, identity) {
121
- return db
122
- .query(`SELECT id, provider_id, auth_json, auth_type, source, captured_at, prompt_status
123
- FROM pending_connections
124
- WHERE provider_id = ? AND source = ? AND auth_type = ?`)
125
- .all(identity.providerID, identity.source, identity.auth.type)
126
- .filter((row) => samePendingIdentity(parsePendingAuth(row), identity.auth));
127
- }
128
- export function createPendingConnection(db, providerID, auth, source) {
129
- const authJSON = JSON.stringify(auth);
130
- const identity = { providerID, auth, source };
131
- const existing = equivalentPendingRows(db, identity)[0];
132
- if (existing)
133
- return pendingConnectionFromRow(existing);
134
- const pending = {
135
- id: pendingID(providerID, auth, source),
136
- providerID,
137
- auth,
138
- authType: auth.type,
139
- source,
140
- capturedAt: now(),
141
- promptStatus: "new",
142
- };
143
- db.query(`INSERT INTO pending_connections (
144
- id,
145
- provider_id,
146
- auth_json,
147
- auth_type,
148
- source,
149
- captured_at,
150
- prompt_status
151
- ) VALUES (?, ?, ?, ?, ?, ?, ?)
152
- ON CONFLICT(id) DO NOTHING`).run(pending.id, pending.providerID, authJSON, pending.authType, pending.source, pending.capturedAt, pending.promptStatus);
153
- const row = selectPendingRow(db, pending.id);
154
- return row ? pendingConnectionFromRow(row) : pending;
155
- }
156
- export function claimPendingPrompt(db, id) {
157
- const claim = db.transaction(() => {
158
- const row = selectPendingRow(db, id);
159
- if (!row)
160
- return undefined;
161
- const identity = pendingIdentity(row);
162
- const equivalent = equivalentPendingRows(db, identity);
163
- const ids = equivalent.map((pending) => pending.id);
164
- const result = db
165
- .query(`UPDATE pending_connections
166
- SET prompt_status = 'prompted'
167
- WHERE id IN (${ids.map(() => "?").join(", ")})
168
- AND prompt_status = 'new'`)
169
- .run(...ids);
170
- if (result.changes === 0)
171
- return undefined;
172
- return pendingConnectionFromRow({ ...row, prompt_status: "prompted" });
173
- });
174
- return claim();
175
- }
176
- export function releasePendingPrompt(db, id) {
177
- const release = db.transaction(() => {
178
- const row = selectPendingRow(db, id);
179
- if (!row)
180
- return false;
181
- const identity = pendingIdentity(row);
182
- const ids = equivalentPendingRows(db, identity).map((pending) => pending.id);
183
- if (ids.length === 0)
184
- return false;
185
- const result = db
186
- .query(`UPDATE pending_connections
187
- SET prompt_status = 'new'
188
- WHERE id IN (${ids.map(() => "?").join(", ")})
189
- AND prompt_status = 'prompted'`)
190
- .run(...ids);
191
- return result.changes > 0;
192
- });
193
- return release();
194
- }
195
- export function listPendingConnections(db) {
196
- const rows = db
197
- .query(`SELECT id, provider_id, auth_json, auth_type, source, captured_at, prompt_status
198
- FROM pending_connections
199
- ORDER BY captured_at DESC, id DESC`)
200
- .all();
201
- return rows.map(pendingConnectionFromRow);
202
- }
203
- export function completePendingConnection(db, id, alias) {
204
- const complete = db.transaction(() => {
205
- const row = selectPendingRow(db, id);
206
- if (!row)
207
- throw new Error(`Pending connection not found: ${id}`);
208
- const pending = pendingConnectionFromRow(row);
209
- const account = saveAccount(db, pending.providerID, alias, pending.auth);
210
- const identity = pendingIdentity(row);
211
- const ids = equivalentPendingRows(db, identity).map((pending) => pending.id);
212
- db.query(`DELETE FROM pending_connections
213
- WHERE id IN (${ids.map(() => "?").join(", ")})`).run(...ids);
214
- return account;
215
- });
216
- return complete();
217
- }
218
- export function removePendingConnection(db, id) {
219
- const remove = db.transaction(() => {
220
- const row = selectPendingRow(db, id);
221
- if (!row)
222
- return false;
223
- const identity = pendingIdentity(row);
224
- const ids = equivalentPendingRows(db, identity).map((pending) => pending.id);
225
- if (ids.length === 0)
226
- return false;
227
- const result = db
228
- .query(`UPDATE pending_connections
229
- SET prompt_status = 'dismissed'
230
- WHERE id IN (${ids.map(() => "?").join(", ")})
231
- AND prompt_status != 'dismissed'`)
232
- .run(...ids);
233
- return result.changes > 0;
234
- });
235
- return remove();
236
- }
237
- //# sourceMappingURL=pending.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"pending.js","sourceRoot":"","sources":["../../src/core/pending.ts"],"names":[],"mappings":"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"}
@@ -1,20 +0,0 @@
1
- import type { Database } from "bun:sqlite";
2
- import type { Account } from "./types";
3
- export type PriorityEntry = {
4
- providerID: string;
5
- position: number;
6
- modelID?: string;
7
- enabled: boolean;
8
- };
9
- export type ActiveSelection = {
10
- providerID: string;
11
- modelID: string;
12
- account: Account;
13
- };
14
- export declare function listProviderPriority(db: Database): PriorityEntry[];
15
- export declare function setProviderModel(db: Database, providerID: string, modelID: string): void;
16
- export declare function setProviderEnabled(db: Database, providerID: string, enabled: boolean): void;
17
- export declare function moveProvider(db: Database, providerID: string, direction: -1 | 1): void;
18
- export declare function getBalancingEnabled(db: Database): boolean;
19
- export declare function setBalancingEnabled(db: Database, enabled: boolean): void;
20
- export declare function resolveActiveSelection(db: Database, nowMs?: number, preferredProviderID?: string): ActiveSelection | undefined;
@@ -1,120 +0,0 @@
1
- import { getActiveAccount, listAccounts } from "./accounts";
2
- import { now } from "./time";
3
- function storedRows(db) {
4
- const rows = db
5
- .query("SELECT provider_id, position, model_id, enabled FROM provider_priority")
6
- .all();
7
- return new Map(rows.map((row) => [row.provider_id, row]));
8
- }
9
- function providersWithAccounts(db) {
10
- return [...new Set(listAccounts(db).map((account) => account.providerID))];
11
- }
12
- function nextPosition(stored) {
13
- let max = -1;
14
- for (const row of stored.values())
15
- max = Math.max(max, row.position);
16
- return max + 1;
17
- }
18
- function upsert(db, providerID, patch) {
19
- const stored = storedRows(db);
20
- const existing = stored.get(providerID);
21
- const position = patch.position ?? existing?.position ?? nextPosition(stored);
22
- const modelID = patch.modelID !== undefined ? patch.modelID : (existing?.model_id ?? null);
23
- const enabled = patch.enabled !== undefined ? (patch.enabled ? 1 : 0) : (existing?.enabled ?? 1);
24
- db.query(`INSERT INTO provider_priority (provider_id, position, model_id, enabled, updated_at)
25
- VALUES (?, ?, ?, ?, ?)
26
- ON CONFLICT(provider_id) DO UPDATE SET
27
- position = excluded.position,
28
- model_id = excluded.model_id,
29
- enabled = excluded.enabled,
30
- updated_at = excluded.updated_at`).run(providerID, position, modelID, enabled, now());
31
- }
32
- export function listProviderPriority(db) {
33
- const stored = storedRows(db);
34
- const providers = providersWithAccounts(db);
35
- const ordered = providers.slice().sort((a, b) => {
36
- const ra = stored.get(a);
37
- const rb = stored.get(b);
38
- if (ra && rb)
39
- return ra.position - rb.position || a.localeCompare(b);
40
- if (ra)
41
- return -1;
42
- if (rb)
43
- return 1;
44
- return a.localeCompare(b);
45
- });
46
- return ordered.map((providerID, index) => {
47
- const row = stored.get(providerID);
48
- return {
49
- providerID,
50
- position: index,
51
- modelID: row?.model_id ?? undefined,
52
- enabled: row ? row.enabled === 1 : true,
53
- };
54
- });
55
- }
56
- export function setProviderModel(db, providerID, modelID) {
57
- upsert(db, providerID, { modelID });
58
- }
59
- export function setProviderEnabled(db, providerID, enabled) {
60
- upsert(db, providerID, { enabled });
61
- }
62
- export function moveProvider(db, providerID, direction) {
63
- const list = listProviderPriority(db);
64
- const index = list.findIndex((entry) => entry.providerID === providerID);
65
- if (index === -1)
66
- return;
67
- const target = index + direction;
68
- if (target < 0 || target >= list.length)
69
- return;
70
- const reordered = list.slice();
71
- const [moved] = reordered.splice(index, 1);
72
- reordered.splice(target, 0, moved);
73
- const persist = db.transaction(() => {
74
- reordered.forEach((entry, position) => upsert(db, entry.providerID, { position }));
75
- });
76
- persist();
77
- }
78
- export function getBalancingEnabled(db) {
79
- const row = db
80
- .query("SELECT value FROM settings WHERE key = ?")
81
- .get("balancing_enabled");
82
- return row?.value === "1";
83
- }
84
- export function setBalancingEnabled(db, enabled) {
85
- db.query(`INSERT INTO settings (key, value) VALUES ('balancing_enabled', ?)
86
- ON CONFLICT(key) DO UPDATE SET value = excluded.value`).run(enabled ? "1" : "0");
87
- }
88
- function chooseHealthyAccount(db, providerID, nowMs) {
89
- const healthy = listAccounts(db, providerID).filter((account) => !account.disabled && (!account.rateLimitedUntil || account.rateLimitedUntil <= nowMs));
90
- if (healthy.length === 0)
91
- return undefined;
92
- const active = getActiveAccount(db, providerID);
93
- if (active && healthy.some((account) => account.alias === active.alias))
94
- return active;
95
- return healthy[0];
96
- }
97
- export function resolveActiveSelection(db, nowMs = now(), preferredProviderID) {
98
- const entries = listProviderPriority(db);
99
- const ordered = preferredProviderID
100
- ? entries.slice().sort((a, b) => {
101
- if (a.providerID === preferredProviderID)
102
- return -1;
103
- if (b.providerID === preferredProviderID)
104
- return 1;
105
- return a.position - b.position;
106
- })
107
- : entries;
108
- for (const entry of ordered) {
109
- if (!entry.enabled)
110
- continue;
111
- if (!entry.modelID)
112
- continue;
113
- const account = chooseHealthyAccount(db, entry.providerID, nowMs);
114
- if (!account)
115
- continue;
116
- return { providerID: entry.providerID, modelID: entry.modelID, account };
117
- }
118
- return undefined;
119
- }
120
- //# sourceMappingURL=priority.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"priority.js","sourceRoot":"","sources":["../../src/core/priority.ts"],"names":[],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- import type { Database } from "bun:sqlite";
2
- export declare function migrate(db: Database): void;
@@ -1,265 +0,0 @@
1
- const authTypes = new Set(["api", "oauth", "wellknown"]);
2
- function hasMigration(db, version) {
3
- const row = db
4
- .query("SELECT version FROM schema_migrations WHERE version = ?")
5
- .get(version);
6
- return Boolean(row);
7
- }
8
- function hasTable(db, table) {
9
- const row = db.query("SELECT name FROM sqlite_master WHERE type = 'table' AND name = ?").get(table);
10
- return Boolean(row);
11
- }
12
- function tableColumns(db, table) {
13
- if (!hasTable(db, table))
14
- return new Set();
15
- return new Set(db.query(`PRAGMA table_info(${table})`).all().map((row) => row.name));
16
- }
17
- function inferAuthType(authJSON) {
18
- try {
19
- const parsed = JSON.parse(authJSON);
20
- if (typeof parsed.type === "string" && authTypes.has(parsed.type))
21
- return parsed.type;
22
- }
23
- catch {
24
- // Invalid legacy rows will be rejected by row validation when read.
25
- }
26
- return "api";
27
- }
28
- function selectExisting(db, table, columns) {
29
- const existing = tableColumns(db, table);
30
- const selected = columns.filter((column) => existing.has(column));
31
- if (selected.length === 0)
32
- return [];
33
- return db.query(`SELECT ${selected.join(", ")} FROM ${table}`).all();
34
- }
35
- function recreateAccounts(db) {
36
- const rows = selectExisting(db, "accounts", [
37
- "provider_id",
38
- "alias",
39
- "auth_json",
40
- "auth_type",
41
- "created_at",
42
- "updated_at",
43
- "last_used_at",
44
- "rate_limited_until",
45
- "failures",
46
- "disabled",
47
- ]);
48
- db.exec(`
49
- DROP TABLE IF EXISTS accounts_new;
50
- CREATE TABLE accounts_new (
51
- provider_id TEXT NOT NULL,
52
- alias TEXT NOT NULL,
53
- auth_json TEXT NOT NULL,
54
- auth_type TEXT NOT NULL,
55
- created_at INTEGER NOT NULL,
56
- updated_at INTEGER NOT NULL,
57
- last_used_at INTEGER,
58
- rate_limited_until INTEGER,
59
- failures INTEGER NOT NULL DEFAULT 0,
60
- disabled INTEGER NOT NULL DEFAULT 0,
61
- PRIMARY KEY (provider_id, alias)
62
- );
63
- `);
64
- const insert = db.query(`INSERT OR REPLACE INTO accounts_new (
65
- provider_id, alias, auth_json, auth_type, created_at, updated_at,
66
- last_used_at, rate_limited_until, failures, disabled
67
- ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`);
68
- for (const row of rows) {
69
- if (typeof row.provider_id !== "string" || typeof row.alias !== "string" || typeof row.auth_json !== "string")
70
- continue;
71
- const authType = typeof row.auth_type === "string" && authTypes.has(row.auth_type) ? row.auth_type : inferAuthType(row.auth_json);
72
- insert.run(row.provider_id, row.alias, row.auth_json, authType, typeof row.created_at === "number" ? row.created_at : Date.now(), typeof row.updated_at === "number" ? row.updated_at : Date.now(), typeof row.last_used_at === "number" ? row.last_used_at : null, typeof row.rate_limited_until === "number" ? row.rate_limited_until : null, typeof row.failures === "number" ? row.failures : 0, row.disabled === 1 ? 1 : 0);
73
- }
74
- db.exec(`
75
- DROP TABLE IF EXISTS accounts;
76
- ALTER TABLE accounts_new RENAME TO accounts;
77
- `);
78
- }
79
- function recreateProviderState(db) {
80
- const rows = selectExisting(db, "provider_state", ["provider_id", "active_alias", "updated_at", "metadata_json"]);
81
- db.exec(`
82
- DROP TABLE IF EXISTS provider_state_new;
83
- CREATE TABLE provider_state_new (
84
- provider_id TEXT PRIMARY KEY,
85
- active_alias TEXT,
86
- updated_at INTEGER NOT NULL,
87
- metadata_json TEXT NOT NULL DEFAULT '{}'
88
- );
89
- `);
90
- const insert = db.query(`INSERT OR REPLACE INTO provider_state_new (provider_id, active_alias, updated_at, metadata_json)
91
- VALUES (?, ?, ?, ?)`);
92
- for (const row of rows) {
93
- if (typeof row.provider_id !== "string")
94
- continue;
95
- insert.run(row.provider_id, typeof row.active_alias === "string" ? row.active_alias : null, typeof row.updated_at === "number" ? row.updated_at : Date.now(), typeof row.metadata_json === "string" ? row.metadata_json : "{}");
96
- }
97
- db.exec(`
98
- DROP TABLE IF EXISTS provider_state;
99
- ALTER TABLE provider_state_new RENAME TO provider_state;
100
- `);
101
- }
102
- function recreatePendingConnections(db) {
103
- const rows = selectExisting(db, "pending_connections", [
104
- "id",
105
- "provider_id",
106
- "auth_json",
107
- "auth_type",
108
- "source",
109
- "captured_at",
110
- "prompt_status",
111
- ]);
112
- db.exec(`
113
- DROP TABLE IF EXISTS pending_connections_new;
114
- CREATE TABLE pending_connections_new (
115
- id TEXT PRIMARY KEY,
116
- provider_id TEXT NOT NULL,
117
- auth_json TEXT NOT NULL,
118
- auth_type TEXT NOT NULL,
119
- source TEXT NOT NULL,
120
- captured_at INTEGER NOT NULL,
121
- prompt_status TEXT NOT NULL
122
- );
123
- `);
124
- const insert = db.query(`INSERT OR REPLACE INTO pending_connections_new (
125
- id, provider_id, auth_json, auth_type, source, captured_at, prompt_status
126
- ) VALUES (?, ?, ?, ?, ?, ?, ?)`);
127
- for (const row of rows) {
128
- if (typeof row.id !== "string" || typeof row.provider_id !== "string" || typeof row.auth_json !== "string")
129
- continue;
130
- const authType = typeof row.auth_type === "string" && authTypes.has(row.auth_type) ? row.auth_type : inferAuthType(row.auth_json);
131
- insert.run(row.id, row.provider_id, row.auth_json, authType, typeof row.source === "string" ? row.source : "auth-file", typeof row.captured_at === "number" ? row.captured_at : Date.now(), typeof row.prompt_status === "string" ? row.prompt_status : "new");
132
- }
133
- db.exec(`
134
- DROP TABLE IF EXISTS pending_connections;
135
- ALTER TABLE pending_connections_new RENAME TO pending_connections;
136
- `);
137
- }
138
- function recreateUsageSnapshots(db) {
139
- const rows = selectExisting(db, "usage_snapshots", [
140
- "provider_id",
141
- "alias",
142
- "fetched_at",
143
- "confidence",
144
- "normalized_json",
145
- "raw_redacted_json",
146
- "error",
147
- ]);
148
- db.exec(`
149
- DROP TABLE IF EXISTS usage_snapshots_new;
150
- CREATE TABLE usage_snapshots_new (
151
- provider_id TEXT NOT NULL,
152
- alias TEXT NOT NULL,
153
- fetched_at INTEGER NOT NULL,
154
- confidence TEXT NOT NULL,
155
- normalized_json TEXT NOT NULL,
156
- raw_redacted_json TEXT,
157
- error TEXT,
158
- PRIMARY KEY (provider_id, alias)
159
- );
160
- `);
161
- const insert = db.query(`INSERT OR REPLACE INTO usage_snapshots_new (
162
- provider_id, alias, fetched_at, confidence, normalized_json, raw_redacted_json, error
163
- ) VALUES (?, ?, ?, ?, ?, ?, ?)`);
164
- for (const row of rows) {
165
- if (typeof row.provider_id !== "string" || typeof row.alias !== "string")
166
- continue;
167
- insert.run(row.provider_id, row.alias, typeof row.fetched_at === "number" ? row.fetched_at : Date.now(), typeof row.confidence === "string" ? row.confidence : "unavailable", typeof row.normalized_json === "string" ? row.normalized_json : "{}", typeof row.raw_redacted_json === "string" ? row.raw_redacted_json : null, typeof row.error === "string" ? row.error : null);
168
- }
169
- db.exec(`
170
- DROP TABLE IF EXISTS usage_snapshots;
171
- ALTER TABLE usage_snapshots_new RENAME TO usage_snapshots;
172
- `);
173
- }
174
- function recreateEvents(db) {
175
- const rows = selectExisting(db, "events", ["id", "type", "provider_id", "alias", "message", "created_at", "metadata_json"]);
176
- db.exec(`
177
- DROP TABLE IF EXISTS events_new;
178
- CREATE TABLE events_new (
179
- id TEXT PRIMARY KEY,
180
- type TEXT NOT NULL,
181
- provider_id TEXT,
182
- alias TEXT,
183
- message TEXT NOT NULL,
184
- created_at INTEGER NOT NULL,
185
- metadata_json TEXT NOT NULL DEFAULT '{}'
186
- );
187
- `);
188
- const insert = db.query(`INSERT OR REPLACE INTO events_new (id, type, provider_id, alias, message, created_at, metadata_json)
189
- VALUES (?, ?, ?, ?, ?, ?, ?)`);
190
- for (const row of rows) {
191
- if (typeof row.id !== "string" || typeof row.type !== "string" || typeof row.message !== "string")
192
- continue;
193
- insert.run(row.id, row.type, typeof row.provider_id === "string" ? row.provider_id : null, typeof row.alias === "string" ? row.alias : null, row.message, typeof row.created_at === "number" ? row.created_at : Date.now(), typeof row.metadata_json === "string" ? row.metadata_json : "{}");
194
- }
195
- db.exec(`
196
- DROP TABLE IF EXISTS events;
197
- ALTER TABLE events_new RENAME TO events;
198
- `);
199
- }
200
- function recreateProviderPriority(db) {
201
- const rows = selectExisting(db, "provider_priority", ["provider_id", "position", "model_id", "enabled", "updated_at"]);
202
- db.exec(`
203
- DROP TABLE IF EXISTS provider_priority_new;
204
- CREATE TABLE provider_priority_new (
205
- provider_id TEXT PRIMARY KEY,
206
- position INTEGER NOT NULL,
207
- model_id TEXT,
208
- enabled INTEGER NOT NULL DEFAULT 1,
209
- updated_at INTEGER NOT NULL
210
- );
211
- `);
212
- const insert = db.query(`INSERT OR REPLACE INTO provider_priority_new (provider_id, position, model_id, enabled, updated_at)
213
- VALUES (?, ?, ?, ?, ?)`);
214
- for (const row of rows) {
215
- if (typeof row.provider_id !== "string")
216
- continue;
217
- insert.run(row.provider_id, typeof row.position === "number" ? row.position : 0, typeof row.model_id === "string" ? row.model_id : null, row.enabled === 0 ? 0 : 1, typeof row.updated_at === "number" ? row.updated_at : Date.now());
218
- }
219
- db.exec(`
220
- DROP TABLE IF EXISTS provider_priority;
221
- ALTER TABLE provider_priority_new RENAME TO provider_priority;
222
- `);
223
- }
224
- function recreateSettings(db) {
225
- const rows = selectExisting(db, "settings", ["key", "value"]);
226
- db.exec(`
227
- DROP TABLE IF EXISTS settings_new;
228
- CREATE TABLE settings_new (
229
- key TEXT PRIMARY KEY,
230
- value TEXT NOT NULL
231
- );
232
- `);
233
- const insert = db.query(`INSERT OR REPLACE INTO settings_new (key, value) VALUES (?, ?)`);
234
- for (const row of rows) {
235
- if (typeof row.key !== "string" || typeof row.value !== "string")
236
- continue;
237
- insert.run(row.key, row.value);
238
- }
239
- db.exec(`
240
- DROP TABLE IF EXISTS settings;
241
- ALTER TABLE settings_new RENAME TO settings;
242
- `);
243
- }
244
- export function migrate(db) {
245
- db.exec(`
246
- CREATE TABLE IF NOT EXISTS schema_migrations (
247
- version INTEGER PRIMARY KEY,
248
- applied_at INTEGER NOT NULL
249
- );
250
- `);
251
- const apply = db.transaction(() => {
252
- recreateAccounts(db);
253
- recreateProviderState(db);
254
- recreatePendingConnections(db);
255
- recreateUsageSnapshots(db);
256
- recreateEvents(db);
257
- recreateProviderPriority(db);
258
- recreateSettings(db);
259
- if (!hasMigration(db, 1)) {
260
- db.query("INSERT INTO schema_migrations (version, applied_at) VALUES (?, ?)").run(1, Date.now());
261
- }
262
- });
263
- apply();
264
- }
265
- //# sourceMappingURL=schema.js.map