@nick3/copilot-api 1.6.0 → 1.6.3
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/dist/{account-B2tSWtVS.js → account-Db80RUHX.js} +2 -2
- package/dist/{account-B2tSWtVS.js.map → account-Db80RUHX.js.map} +1 -1
- package/dist/{accounts-manager-CAyZJSn8.js → accounts-manager-B4eOuKSK.js} +225 -293
- package/dist/accounts-manager-B4eOuKSK.js.map +1 -0
- package/dist/admin/assets/index-B2qj1asn.css +1 -0
- package/dist/admin/assets/index-CH72K8cb.js +107 -0
- package/dist/admin/assets/sse-BHNhW__Y.js +9 -0
- package/dist/admin/index.html +2 -2
- package/dist/{auth-BXCeDjRG.js → auth-Ba8K-1aX.js} +3 -3
- package/dist/{auth-BXCeDjRG.js.map → auth-Ba8K-1aX.js.map} +1 -1
- package/dist/{check-usage-CQxXYfUx.js → check-usage-ChbkyMqB.js} +3 -3
- package/dist/{check-usage-CQxXYfUx.js.map → check-usage-ChbkyMqB.js.map} +1 -1
- package/dist/{get-copilot-token-p17sJyPU.js → get-copilot-token-Buo3CA1x.js} +2 -2
- package/dist/{get-copilot-token-p17sJyPU.js.map → get-copilot-token-Buo3CA1x.js.map} +1 -1
- package/dist/main.js +3 -3
- package/dist/{poll-access-token-Bc6VwWab.js → poll-access-token-tKPQmH_6.js} +2 -2
- package/dist/{poll-access-token-Bc6VwWab.js.map → poll-access-token-tKPQmH_6.js.map} +1 -1
- package/dist/request-outbound-C0g49Ab6.js +505 -0
- package/dist/request-outbound-C0g49Ab6.js.map +1 -0
- package/dist/request-outbound-IimJTlvY.js +4 -0
- package/dist/{server-CFijvv3C.js → server-Dw9SIlHL.js} +3835 -3350
- package/dist/server-Dw9SIlHL.js.map +1 -0
- package/dist/{start-DQlnH71A.js → start-BI0sDz7p.js} +7 -6
- package/dist/{start-DQlnH71A.js.map → start-BI0sDz7p.js.map} +1 -1
- package/package.json +1 -1
- package/dist/accounts-manager-CAyZJSn8.js.map +0 -1
- package/dist/admin/assets/index-BESw8Vvd.css +0 -1
- package/dist/admin/assets/index-Ddo9RHg-.js +0 -101
- package/dist/server-CFijvv3C.js.map +0 -1
|
@@ -1,12 +1,11 @@
|
|
|
1
|
-
import { O as accountFromState, _ as HTTPError, g as getCopilotUsage, j as consumeOutboundHeadersSnapshot, m as getGitHubUser, x as copilotModelsHeaders, y as copilotBaseUrl } from "./poll-access-token-
|
|
2
|
-
import { b as getCurrentIdentityEnvironment, c as isAccountEnabled, f as readLegacyToken, h as saveAccountToken, i as ensureAccountClientIdentity, l as listAccountsFromRegistry, o as hasLegacyToken, r as addAccountToRegistry, s as hasRegistry, u as loadAccountToken, v as buildIdentityKey, y as createAccountSessionId } from "./account-
|
|
1
|
+
import { O as accountFromState, _ as HTTPError, g as getCopilotUsage, j as consumeOutboundHeadersSnapshot, m as getGitHubUser, x as copilotModelsHeaders, y as copilotBaseUrl } from "./poll-access-token-tKPQmH_6.js";
|
|
2
|
+
import { b as getCurrentIdentityEnvironment, c as isAccountEnabled, f as readLegacyToken, h as saveAccountToken, i as ensureAccountClientIdentity, l as listAccountsFromRegistry, o as hasLegacyToken, r as addAccountToRegistry, s as hasRegistry, u as loadAccountToken, v as buildIdentityKey, y as createAccountSessionId } from "./account-Db80RUHX.js";
|
|
3
3
|
import { t as PATHS } from "./paths-DGlr310R.js";
|
|
4
|
-
import { t as getCopilotToken } from "./get-copilot-token-
|
|
4
|
+
import { t as getCopilotToken } from "./get-copilot-token-Buo3CA1x.js";
|
|
5
|
+
import { c as getAdminDbUserVersion, i as getRequestOutboundStore, o as getAdminDb, s as getAdminDbPath } from "./request-outbound-C0g49Ab6.js";
|
|
5
6
|
import consola, { consola as consola$1 } from "consola";
|
|
6
7
|
import fs from "node:fs/promises";
|
|
7
|
-
import path from "node:path";
|
|
8
8
|
import fs$1 from "node:fs";
|
|
9
|
-
import { Database } from "bun:sqlite";
|
|
10
9
|
|
|
11
10
|
//#region src/lib/config.ts
|
|
12
11
|
const PROVIDER_TYPE_ANTHROPIC = "anthropic";
|
|
@@ -62,7 +61,13 @@ const defaultConfig = {
|
|
|
62
61
|
sessionAffinityRetentionDays: 7,
|
|
63
62
|
useMessagesApi: true,
|
|
64
63
|
useResponsesApiWebSearch: true,
|
|
65
|
-
logLevel: "info"
|
|
64
|
+
logLevel: "info",
|
|
65
|
+
devMode: {
|
|
66
|
+
enabled: false,
|
|
67
|
+
capture4xx: false,
|
|
68
|
+
capture5xx: false,
|
|
69
|
+
captureOther: false
|
|
70
|
+
}
|
|
66
71
|
};
|
|
67
72
|
let cachedConfig = null;
|
|
68
73
|
function isPlainObject(value) {
|
|
@@ -225,6 +230,25 @@ function mergeDefaultLogLevel(config) {
|
|
|
225
230
|
changed: true
|
|
226
231
|
};
|
|
227
232
|
}
|
|
233
|
+
function mergeDefaultDevMode(config) {
|
|
234
|
+
const current = config.devMode;
|
|
235
|
+
if (current && typeof current.enabled === "boolean" && typeof current.capture4xx === "boolean" && typeof current.capture5xx === "boolean" && typeof current.captureOther === "boolean") return {
|
|
236
|
+
mergedConfig: config,
|
|
237
|
+
changed: false
|
|
238
|
+
};
|
|
239
|
+
return {
|
|
240
|
+
mergedConfig: {
|
|
241
|
+
...config,
|
|
242
|
+
devMode: {
|
|
243
|
+
enabled: current?.enabled === true,
|
|
244
|
+
capture4xx: current?.capture4xx === true,
|
|
245
|
+
capture5xx: current?.capture5xx === true,
|
|
246
|
+
captureOther: current?.captureOther === true
|
|
247
|
+
}
|
|
248
|
+
},
|
|
249
|
+
changed: true
|
|
250
|
+
};
|
|
251
|
+
}
|
|
228
252
|
function applyConfigMerges(config, mergeFns) {
|
|
229
253
|
return mergeFns.reduce((acc, mergeFn) => {
|
|
230
254
|
const result = mergeFn(acc.mergedConfig);
|
|
@@ -244,7 +268,8 @@ function mergeConfigWithDefaults() {
|
|
|
244
268
|
mergeDefaultAccountAffinity,
|
|
245
269
|
mergeDefaultModelRefreshInterval,
|
|
246
270
|
mergeDefaultSessionAffinityRetention,
|
|
247
|
-
mergeDefaultLogLevel
|
|
271
|
+
mergeDefaultLogLevel,
|
|
272
|
+
mergeDefaultDevMode
|
|
248
273
|
]);
|
|
249
274
|
if (changed) try {
|
|
250
275
|
fs$1.writeFileSync(PATHS.CONFIG_PATH, `${JSON.stringify(mergedConfig, null, 2)}\n`, "utf8");
|
|
@@ -601,11 +626,189 @@ function isAffinityAccountUsable(accountId, accounts) {
|
|
|
601
626
|
return account;
|
|
602
627
|
}
|
|
603
628
|
|
|
629
|
+
//#endregion
|
|
630
|
+
//#region src/lib/dev-mode.ts
|
|
631
|
+
function isDevModeEnabled() {
|
|
632
|
+
return getConfig().devMode?.enabled === true;
|
|
633
|
+
}
|
|
634
|
+
function isCapture4xxEnabled() {
|
|
635
|
+
return getConfig().devMode?.capture4xx === true;
|
|
636
|
+
}
|
|
637
|
+
function isCapture5xxEnabled() {
|
|
638
|
+
return getConfig().devMode?.capture5xx === true;
|
|
639
|
+
}
|
|
640
|
+
function isCaptureOtherEnabled() {
|
|
641
|
+
return getConfig().devMode?.captureOther === true;
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
//#endregion
|
|
645
|
+
//#region src/services/copilot/copilot-fetch.ts
|
|
646
|
+
const pendingCaptures = /* @__PURE__ */ new Map();
|
|
647
|
+
const pendingCapturePromises = /* @__PURE__ */ new Map();
|
|
648
|
+
async function flushPendingCapture(requestId) {
|
|
649
|
+
const pending = pendingCaptures.get(requestId);
|
|
650
|
+
if (pending) {
|
|
651
|
+
pendingCaptures.delete(requestId);
|
|
652
|
+
pendingCapturePromises.delete(requestId);
|
|
653
|
+
persistNow(pending);
|
|
654
|
+
return;
|
|
655
|
+
}
|
|
656
|
+
const promise = pendingCapturePromises.get(requestId);
|
|
657
|
+
if (promise) {
|
|
658
|
+
await promise;
|
|
659
|
+
const deferred = pendingCaptures.get(requestId);
|
|
660
|
+
if (deferred) {
|
|
661
|
+
pendingCaptures.delete(requestId);
|
|
662
|
+
persistNow(deferred);
|
|
663
|
+
}
|
|
664
|
+
pendingCapturePromises.delete(requestId);
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
function snapshotHeaders(init) {
|
|
668
|
+
const headers = init.headers;
|
|
669
|
+
if (headers instanceof Headers) {
|
|
670
|
+
const out$1 = {};
|
|
671
|
+
for (const [key, value] of headers.entries()) out$1[key] = value;
|
|
672
|
+
return out$1;
|
|
673
|
+
}
|
|
674
|
+
if (Array.isArray(headers)) {
|
|
675
|
+
const out$1 = {};
|
|
676
|
+
for (const [key, value] of headers) out$1[key] = value;
|
|
677
|
+
return out$1;
|
|
678
|
+
}
|
|
679
|
+
const out = {};
|
|
680
|
+
for (const [key, value] of Object.entries(headers ?? {})) out[key] = value;
|
|
681
|
+
return out;
|
|
682
|
+
}
|
|
683
|
+
function snapshotBody(init) {
|
|
684
|
+
const body = init.body;
|
|
685
|
+
if (body === null || body === void 0) return {
|
|
686
|
+
body: null,
|
|
687
|
+
bodyKind: "text"
|
|
688
|
+
};
|
|
689
|
+
if (typeof body === "string") try {
|
|
690
|
+
JSON.parse(body);
|
|
691
|
+
return {
|
|
692
|
+
body,
|
|
693
|
+
bodyKind: "json"
|
|
694
|
+
};
|
|
695
|
+
} catch {
|
|
696
|
+
return {
|
|
697
|
+
body,
|
|
698
|
+
bodyKind: "text"
|
|
699
|
+
};
|
|
700
|
+
}
|
|
701
|
+
if (body instanceof Uint8Array) return {
|
|
702
|
+
body: Buffer.from(body).toString("base64"),
|
|
703
|
+
bodyKind: "binary"
|
|
704
|
+
};
|
|
705
|
+
if (body instanceof ArrayBuffer) return {
|
|
706
|
+
body: Buffer.from(new Uint8Array(body)).toString("base64"),
|
|
707
|
+
bodyKind: "binary"
|
|
708
|
+
};
|
|
709
|
+
return {
|
|
710
|
+
body: null,
|
|
711
|
+
bodyKind: "text"
|
|
712
|
+
};
|
|
713
|
+
}
|
|
714
|
+
function shouldCaptureStatus(status) {
|
|
715
|
+
if (status >= 400 && status < 500) return isCapture4xxEnabled();
|
|
716
|
+
if (status >= 500) return isCapture5xxEnabled();
|
|
717
|
+
return isCaptureOtherEnabled();
|
|
718
|
+
}
|
|
719
|
+
async function copilotFetch(input, init, ctx) {
|
|
720
|
+
const requestSnapshot = {
|
|
721
|
+
url: typeof input === "string" ? input : input.toString(),
|
|
722
|
+
method: (init.method ?? "GET").toUpperCase(),
|
|
723
|
+
headers: snapshotHeaders(init),
|
|
724
|
+
...snapshotBody(init)
|
|
725
|
+
};
|
|
726
|
+
const response = await fetch(input, init);
|
|
727
|
+
if (!(ctx.requestId !== void 0 && ctx.capturable !== false && shouldCaptureStatus(response.status))) return response;
|
|
728
|
+
const contentType = response.headers.get("content-type") ?? "";
|
|
729
|
+
const isSSE = contentType.includes("text/event-stream");
|
|
730
|
+
const responseHeaders = {};
|
|
731
|
+
for (const [key, value] of response.headers.entries()) responseHeaders[key] = value;
|
|
732
|
+
if (!response.body) {
|
|
733
|
+
storePending({
|
|
734
|
+
requestSnapshot,
|
|
735
|
+
status: response.status,
|
|
736
|
+
responseBody: "",
|
|
737
|
+
responseBodyKind: isSSE ? "sse" : "json",
|
|
738
|
+
responseHeaders,
|
|
739
|
+
ctx
|
|
740
|
+
});
|
|
741
|
+
return response;
|
|
742
|
+
}
|
|
743
|
+
const [forClient, forCapture] = response.body.tee();
|
|
744
|
+
const capturePromise = (async () => {
|
|
745
|
+
const chunks = [];
|
|
746
|
+
const reader = forCapture.getReader();
|
|
747
|
+
try {
|
|
748
|
+
for (;;) {
|
|
749
|
+
const result = await reader.read();
|
|
750
|
+
if (result.done) break;
|
|
751
|
+
const value = result.value;
|
|
752
|
+
if (value instanceof Uint8Array) chunks.push(value);
|
|
753
|
+
}
|
|
754
|
+
const text = Buffer.concat(chunks.map((chunk) => Buffer.from(chunk))).toString("utf8");
|
|
755
|
+
let responseBodyKind = "text";
|
|
756
|
+
if (isSSE) responseBodyKind = "sse";
|
|
757
|
+
else if (contentType.includes("application/json")) responseBodyKind = "json";
|
|
758
|
+
storePending({
|
|
759
|
+
requestSnapshot,
|
|
760
|
+
status: response.status,
|
|
761
|
+
responseBody: text,
|
|
762
|
+
responseBodyKind,
|
|
763
|
+
responseHeaders,
|
|
764
|
+
ctx
|
|
765
|
+
});
|
|
766
|
+
} catch (error) {
|
|
767
|
+
consola.debug("copilotFetch capture stream failed", error);
|
|
768
|
+
}
|
|
769
|
+
})();
|
|
770
|
+
if (ctx.requestId) pendingCapturePromises.set(ctx.requestId, capturePromise);
|
|
771
|
+
return new Response(forClient, {
|
|
772
|
+
status: response.status,
|
|
773
|
+
statusText: response.statusText,
|
|
774
|
+
headers: response.headers
|
|
775
|
+
});
|
|
776
|
+
}
|
|
777
|
+
function storePending(input) {
|
|
778
|
+
const id = input.ctx.requestId;
|
|
779
|
+
if (!id) return;
|
|
780
|
+
pendingCaptures.set(id, input);
|
|
781
|
+
}
|
|
782
|
+
function persistNow({ requestSnapshot, status, responseBody, responseBodyKind, responseHeaders, ctx }) {
|
|
783
|
+
if (!ctx.requestId) return;
|
|
784
|
+
try {
|
|
785
|
+
getRequestOutboundStore().insert({
|
|
786
|
+
requestId: ctx.requestId,
|
|
787
|
+
httpStatus: status,
|
|
788
|
+
upstreamUrl: requestSnapshot.url,
|
|
789
|
+
upstreamMethod: requestSnapshot.method,
|
|
790
|
+
requestHeaders: requestSnapshot.headers,
|
|
791
|
+
requestBody: requestSnapshot.body,
|
|
792
|
+
requestBodyKind: requestSnapshot.bodyKind,
|
|
793
|
+
responseStatus: status,
|
|
794
|
+
responseHeaders,
|
|
795
|
+
responseBody,
|
|
796
|
+
responseBodyKind
|
|
797
|
+
});
|
|
798
|
+
} catch (error) {
|
|
799
|
+
consola.debug("copilotFetch persist failed", error);
|
|
800
|
+
}
|
|
801
|
+
}
|
|
802
|
+
|
|
604
803
|
//#endregion
|
|
605
804
|
//#region src/services/copilot/get-models.ts
|
|
606
|
-
const getModels = async (account) => {
|
|
805
|
+
const getModels = async (account, options) => {
|
|
607
806
|
const ctx = account ?? accountFromState();
|
|
608
|
-
const response = await
|
|
807
|
+
const response = await copilotFetch(`${copilotBaseUrl(ctx)}/models`, { headers: copilotModelsHeaders(ctx) }, {
|
|
808
|
+
requestId: options?.requestId,
|
|
809
|
+
callSite: "models",
|
|
810
|
+
capturable: false
|
|
811
|
+
});
|
|
609
812
|
if (!response.ok) {
|
|
610
813
|
const errorText = await response.clone().text();
|
|
611
814
|
consola.error("Failed to get models response body", errorText);
|
|
@@ -726,288 +929,6 @@ const releasePremiumReservation = (account, reservation) => {
|
|
|
726
929
|
if (reservations.size === 0) account.premiumReservations = void 0;
|
|
727
930
|
};
|
|
728
931
|
|
|
729
|
-
//#endregion
|
|
730
|
-
//#region src/lib/admin-db.ts
|
|
731
|
-
const DEFAULT_DB_PATH = path.join(PATHS.APP_DIR, "admin.sqlite");
|
|
732
|
-
let sharedDb = null;
|
|
733
|
-
let initialized = false;
|
|
734
|
-
const INIT_WARN_THROTTLE_MS = 3e4;
|
|
735
|
-
let lastInitWarnAtMs = 0;
|
|
736
|
-
let suppressedInitWarnCount = 0;
|
|
737
|
-
function warnAdminDbInitFailure(error) {
|
|
738
|
-
const now = Date.now();
|
|
739
|
-
if (now - lastInitWarnAtMs < INIT_WARN_THROTTLE_MS) {
|
|
740
|
-
suppressedInitWarnCount++;
|
|
741
|
-
return;
|
|
742
|
-
}
|
|
743
|
-
const suppressed = suppressedInitWarnCount;
|
|
744
|
-
suppressedInitWarnCount = 0;
|
|
745
|
-
lastInitWarnAtMs = now;
|
|
746
|
-
const suffix = suppressed > 0 ? ` (suppressed ${suppressed} similar errors)` : "";
|
|
747
|
-
consola.warn(`Failed to initialize admin DB; admin features disabled${suffix}`, error);
|
|
748
|
-
}
|
|
749
|
-
function getAdminDbPath() {
|
|
750
|
-
return DEFAULT_DB_PATH;
|
|
751
|
-
}
|
|
752
|
-
function openAdminDb(filePath = DEFAULT_DB_PATH) {
|
|
753
|
-
return new Database(filePath);
|
|
754
|
-
}
|
|
755
|
-
function initAdminDb(db) {
|
|
756
|
-
db.run("PRAGMA journal_mode = WAL;");
|
|
757
|
-
db.run("PRAGMA synchronous = NORMAL;");
|
|
758
|
-
db.run("PRAGMA busy_timeout = 3000;");
|
|
759
|
-
db.run("PRAGMA foreign_keys = ON;");
|
|
760
|
-
migrateAdminDb(db);
|
|
761
|
-
}
|
|
762
|
-
function getAdminDb() {
|
|
763
|
-
if (!sharedDb) sharedDb = openAdminDb();
|
|
764
|
-
if (!initialized) try {
|
|
765
|
-
initAdminDb(sharedDb);
|
|
766
|
-
initialized = true;
|
|
767
|
-
} catch (error) {
|
|
768
|
-
warnAdminDbInitFailure(error);
|
|
769
|
-
}
|
|
770
|
-
return sharedDb;
|
|
771
|
-
}
|
|
772
|
-
function getAdminDbUserVersion(db = getAdminDb()) {
|
|
773
|
-
try {
|
|
774
|
-
return db.query("PRAGMA user_version;").get()?.user_version ?? 0;
|
|
775
|
-
} catch {
|
|
776
|
-
return 0;
|
|
777
|
-
}
|
|
778
|
-
}
|
|
779
|
-
function hasRequestLogColumn(db, columnName) {
|
|
780
|
-
return db.query("PRAGMA table_info(request_log);").all().some((row) => row.name === columnName);
|
|
781
|
-
}
|
|
782
|
-
function migrateV1(db) {
|
|
783
|
-
db.run(`
|
|
784
|
-
CREATE TABLE IF NOT EXISTS request_log (
|
|
785
|
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
786
|
-
request_id TEXT NOT NULL UNIQUE,
|
|
787
|
-
|
|
788
|
-
started_at_ms INTEGER NOT NULL,
|
|
789
|
-
finished_at_ms INTEGER,
|
|
790
|
-
duration_ms INTEGER,
|
|
791
|
-
ttfb_ms INTEGER,
|
|
792
|
-
|
|
793
|
-
method TEXT NOT NULL,
|
|
794
|
-
path TEXT NOT NULL,
|
|
795
|
-
upstream_endpoint TEXT,
|
|
796
|
-
stream INTEGER NOT NULL DEFAULT 0,
|
|
797
|
-
|
|
798
|
-
account_id TEXT,
|
|
799
|
-
account_type TEXT,
|
|
800
|
-
cost_units REAL,
|
|
801
|
-
client_model TEXT,
|
|
802
|
-
upstream_model TEXT,
|
|
803
|
-
|
|
804
|
-
client_ip TEXT,
|
|
805
|
-
client_ip_source TEXT,
|
|
806
|
-
user_agent TEXT,
|
|
807
|
-
|
|
808
|
-
tokens_input INTEGER,
|
|
809
|
-
tokens_output INTEGER,
|
|
810
|
-
tokens_total INTEGER,
|
|
811
|
-
tokens_cached_input INTEGER,
|
|
812
|
-
usage_json TEXT,
|
|
813
|
-
|
|
814
|
-
premium_remaining_before REAL,
|
|
815
|
-
premium_remaining_after REAL,
|
|
816
|
-
premium_remaining_diff REAL,
|
|
817
|
-
premium_unlimited_before INTEGER,
|
|
818
|
-
premium_unlimited_after INTEGER,
|
|
819
|
-
|
|
820
|
-
http_status INTEGER,
|
|
821
|
-
error_name TEXT,
|
|
822
|
-
error_status INTEGER,
|
|
823
|
-
error_message TEXT,
|
|
824
|
-
selection_failure_reason TEXT
|
|
825
|
-
);
|
|
826
|
-
|
|
827
|
-
CREATE INDEX IF NOT EXISTS idx_request_log_started_at
|
|
828
|
-
ON request_log(started_at_ms DESC);
|
|
829
|
-
CREATE INDEX IF NOT EXISTS idx_request_log_account_started_at
|
|
830
|
-
ON request_log(account_id, started_at_ms DESC);
|
|
831
|
-
CREATE INDEX IF NOT EXISTS idx_request_log_model_started_at
|
|
832
|
-
ON request_log(upstream_model, started_at_ms DESC);
|
|
833
|
-
CREATE INDEX IF NOT EXISTS idx_request_log_endpoint_started_at
|
|
834
|
-
ON request_log(upstream_endpoint, started_at_ms DESC);
|
|
835
|
-
CREATE INDEX IF NOT EXISTS idx_request_log_status_started_at
|
|
836
|
-
ON request_log(http_status, started_at_ms DESC);
|
|
837
|
-
|
|
838
|
-
PRAGMA user_version = 1;
|
|
839
|
-
`);
|
|
840
|
-
}
|
|
841
|
-
function migrateV9(db) {
|
|
842
|
-
db.run(`
|
|
843
|
-
CREATE TABLE IF NOT EXISTS daily_premium_stats (
|
|
844
|
-
date TEXT NOT NULL,
|
|
845
|
-
account_id TEXT NOT NULL,
|
|
846
|
-
request_count INTEGER NOT NULL DEFAULT 0,
|
|
847
|
-
cost_units_sum REAL NOT NULL DEFAULT 0,
|
|
848
|
-
tokens_total INTEGER NOT NULL DEFAULT 0,
|
|
849
|
-
error_count INTEGER NOT NULL DEFAULT 0,
|
|
850
|
-
updated_at_ms INTEGER NOT NULL,
|
|
851
|
-
PRIMARY KEY (date, account_id)
|
|
852
|
-
);
|
|
853
|
-
|
|
854
|
-
CREATE INDEX IF NOT EXISTS idx_daily_premium_stats_date
|
|
855
|
-
ON daily_premium_stats(date);
|
|
856
|
-
`);
|
|
857
|
-
if (db.query("SELECT name FROM sqlite_master WHERE type = 'table' AND name = 'request_log' LIMIT 1;").get()) {
|
|
858
|
-
const nowMs = Date.now();
|
|
859
|
-
db.run(`INSERT INTO daily_premium_stats
|
|
860
|
-
(date, account_id, request_count, cost_units_sum, tokens_total, error_count, updated_at_ms)
|
|
861
|
-
SELECT
|
|
862
|
-
date(started_at_ms / 1000, 'unixepoch', 'localtime') AS date,
|
|
863
|
-
account_id,
|
|
864
|
-
COUNT(*) AS request_count,
|
|
865
|
-
SUM(cost_units) AS cost_units_sum,
|
|
866
|
-
COALESCE(SUM(tokens_total), 0) AS tokens_total,
|
|
867
|
-
SUM(CASE WHEN error_name IS NOT NULL THEN 1 ELSE 0 END) AS error_count,
|
|
868
|
-
? AS updated_at_ms
|
|
869
|
-
FROM request_log
|
|
870
|
-
WHERE cost_units > 0
|
|
871
|
-
AND account_id IS NOT NULL
|
|
872
|
-
GROUP BY 1, 2
|
|
873
|
-
ON CONFLICT(date, account_id) DO UPDATE SET
|
|
874
|
-
request_count = excluded.request_count,
|
|
875
|
-
cost_units_sum = excluded.cost_units_sum,
|
|
876
|
-
tokens_total = excluded.tokens_total,
|
|
877
|
-
error_count = excluded.error_count,
|
|
878
|
-
updated_at_ms = excluded.updated_at_ms;`, [nowMs]);
|
|
879
|
-
}
|
|
880
|
-
db.run("PRAGMA user_version = 9;");
|
|
881
|
-
}
|
|
882
|
-
function migrateV8(db) {
|
|
883
|
-
db.run(`
|
|
884
|
-
CREATE TABLE IF NOT EXISTS session_affinity (
|
|
885
|
-
cache_key TEXT PRIMARY KEY,
|
|
886
|
-
account_id TEXT NOT NULL,
|
|
887
|
-
created_at_ms INTEGER NOT NULL,
|
|
888
|
-
last_confirmed_at_ms INTEGER NOT NULL,
|
|
889
|
-
last_used_at_ms INTEGER NOT NULL
|
|
890
|
-
);
|
|
891
|
-
|
|
892
|
-
CREATE INDEX IF NOT EXISTS idx_session_affinity_last_used
|
|
893
|
-
ON session_affinity(last_used_at_ms);
|
|
894
|
-
|
|
895
|
-
CREATE INDEX IF NOT EXISTS idx_session_affinity_account
|
|
896
|
-
ON session_affinity(account_id);
|
|
897
|
-
|
|
898
|
-
PRAGMA user_version = 8;
|
|
899
|
-
`);
|
|
900
|
-
}
|
|
901
|
-
function migrateV10(db) {
|
|
902
|
-
db.run(`
|
|
903
|
-
CREATE TABLE IF NOT EXISTS quota_snapshots (
|
|
904
|
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
905
|
-
account_id TEXT NOT NULL,
|
|
906
|
-
snapshot_at_ms INTEGER NOT NULL,
|
|
907
|
-
remaining INTEGER NOT NULL,
|
|
908
|
-
entitlement INTEGER NOT NULL,
|
|
909
|
-
unlimited INTEGER NOT NULL DEFAULT 0,
|
|
910
|
-
source TEXT NOT NULL DEFAULT 'refresh'
|
|
911
|
-
);
|
|
912
|
-
|
|
913
|
-
CREATE INDEX IF NOT EXISTS idx_quota_snapshots_account_time
|
|
914
|
-
ON quota_snapshots(account_id, snapshot_at_ms);
|
|
915
|
-
|
|
916
|
-
CREATE INDEX IF NOT EXISTS idx_quota_snapshots_time
|
|
917
|
-
ON quota_snapshots(snapshot_at_ms);
|
|
918
|
-
`);
|
|
919
|
-
if (db.query("SELECT name FROM sqlite_master WHERE type = 'table' AND name = 'request_log' LIMIT 1;").get()) db.run(`
|
|
920
|
-
INSERT INTO quota_snapshots
|
|
921
|
-
(account_id, snapshot_at_ms, remaining, entitlement, unlimited, source)
|
|
922
|
-
SELECT
|
|
923
|
-
account_id,
|
|
924
|
-
finished_at_ms,
|
|
925
|
-
CAST(premium_remaining_after AS INTEGER),
|
|
926
|
-
0,
|
|
927
|
-
COALESCE(premium_unlimited_after, 0),
|
|
928
|
-
'backfill'
|
|
929
|
-
FROM request_log
|
|
930
|
-
WHERE premium_remaining_after IS NOT NULL
|
|
931
|
-
AND account_id IS NOT NULL
|
|
932
|
-
AND finished_at_ms IS NOT NULL
|
|
933
|
-
ORDER BY finished_at_ms;
|
|
934
|
-
`);
|
|
935
|
-
db.run("PRAGMA user_version = 10;");
|
|
936
|
-
}
|
|
937
|
-
function migrateV11(db) {
|
|
938
|
-
for (const columnName of [
|
|
939
|
-
"outbound_x_request_id",
|
|
940
|
-
"outbound_x_agent_task_id",
|
|
941
|
-
"outbound_x_interaction_type",
|
|
942
|
-
"outbound_openai_intent",
|
|
943
|
-
"outbound_user_agent"
|
|
944
|
-
]) if (!hasRequestLogColumn(db, columnName)) db.run(`ALTER TABLE request_log ADD COLUMN ${columnName} TEXT;`);
|
|
945
|
-
db.run("PRAGMA user_version = 11;");
|
|
946
|
-
}
|
|
947
|
-
function migrateV8ToV11(db, current) {
|
|
948
|
-
if (current < 8) migrateV8(db);
|
|
949
|
-
if (current < 9) migrateV9(db);
|
|
950
|
-
if (current < 10) migrateV10(db);
|
|
951
|
-
if (current < 11) migrateV11(db);
|
|
952
|
-
}
|
|
953
|
-
function migrateAdminDb(db) {
|
|
954
|
-
const current = db.query("PRAGMA user_version;").get()?.user_version ?? 0;
|
|
955
|
-
if (current >= 11) return;
|
|
956
|
-
if (current < 1) migrateV1(db);
|
|
957
|
-
if (current < 2) db.run(`
|
|
958
|
-
ALTER TABLE request_log ADD COLUMN user_id TEXT;
|
|
959
|
-
ALTER TABLE request_log ADD COLUMN safety_identifier TEXT;
|
|
960
|
-
ALTER TABLE request_log ADD COLUMN prompt_cache_key TEXT;
|
|
961
|
-
ALTER TABLE request_log ADD COLUMN initiator TEXT;
|
|
962
|
-
ALTER TABLE request_log ADD COLUMN upstream_request_id TEXT;
|
|
963
|
-
|
|
964
|
-
PRAGMA user_version = 2;
|
|
965
|
-
`);
|
|
966
|
-
if (current < 3) db.run(`
|
|
967
|
-
CREATE INDEX IF NOT EXISTS idx_request_log_session_finished
|
|
968
|
-
ON request_log(
|
|
969
|
-
prompt_cache_key,
|
|
970
|
-
safety_identifier,
|
|
971
|
-
finished_at_ms DESC
|
|
972
|
-
)
|
|
973
|
-
WHERE finished_at_ms IS NOT NULL
|
|
974
|
-
AND tokens_input IS NOT NULL;
|
|
975
|
-
|
|
976
|
-
PRAGMA user_version = 3;
|
|
977
|
-
`);
|
|
978
|
-
if (current < 4) db.run(`
|
|
979
|
-
CREATE INDEX IF NOT EXISTS idx_request_log_session_finished_by_client_model
|
|
980
|
-
ON request_log(
|
|
981
|
-
prompt_cache_key,
|
|
982
|
-
safety_identifier,
|
|
983
|
-
client_model,
|
|
984
|
-
finished_at_ms DESC
|
|
985
|
-
)
|
|
986
|
-
WHERE finished_at_ms IS NOT NULL
|
|
987
|
-
AND tokens_input IS NOT NULL;
|
|
988
|
-
|
|
989
|
-
PRAGMA user_version = 4;
|
|
990
|
-
`);
|
|
991
|
-
if (current < 5) db.run(`
|
|
992
|
-
ALTER TABLE request_log ADD COLUMN affinity_hit INTEGER;
|
|
993
|
-
ALTER TABLE request_log ADD COLUMN affinity_cache_key TEXT;
|
|
994
|
-
|
|
995
|
-
PRAGMA user_version = 5;
|
|
996
|
-
`);
|
|
997
|
-
if (current < 6) {
|
|
998
|
-
if (!hasRequestLogColumn(db, "is_subagent")) db.run("ALTER TABLE request_log ADD COLUMN is_subagent INTEGER;");
|
|
999
|
-
db.run("PRAGMA user_version = 6;");
|
|
1000
|
-
}
|
|
1001
|
-
if (current < 7) {
|
|
1002
|
-
if (!hasRequestLogColumn(db, "affinity_key_used")) db.run("ALTER TABLE request_log ADD COLUMN affinity_key_used TEXT;");
|
|
1003
|
-
if (!hasRequestLogColumn(db, "affinity_key_source")) db.run("ALTER TABLE request_log ADD COLUMN affinity_key_source TEXT;");
|
|
1004
|
-
if (!hasRequestLogColumn(db, "selection_reason")) db.run("ALTER TABLE request_log ADD COLUMN selection_reason TEXT;");
|
|
1005
|
-
if (!hasRequestLogColumn(db, "upstream_error_message_raw")) db.run("ALTER TABLE request_log ADD COLUMN upstream_error_message_raw TEXT;");
|
|
1006
|
-
db.run("PRAGMA user_version = 7;");
|
|
1007
|
-
}
|
|
1008
|
-
migrateV8ToV11(db, current);
|
|
1009
|
-
}
|
|
1010
|
-
|
|
1011
932
|
//#endregion
|
|
1012
933
|
//#region src/lib/stats-store.ts
|
|
1013
934
|
const DEFAULT_STATS_RETENTION_DAYS = 180;
|
|
@@ -1609,6 +1530,7 @@ var RequestHistoryStore = class {
|
|
|
1609
1530
|
} catch (error) {
|
|
1610
1531
|
consola.debug("Failed to cleanup request_log retention", error);
|
|
1611
1532
|
}
|
|
1533
|
+
import("./request-outbound-IimJTlvY.js").then((m) => m.getRequestOutboundStore().cleanupOrphans()).catch(() => {});
|
|
1612
1534
|
}
|
|
1613
1535
|
meta() {
|
|
1614
1536
|
return {
|
|
@@ -2693,6 +2615,16 @@ var AccountsManager = class {
|
|
|
2693
2615
|
}
|
|
2694
2616
|
}
|
|
2695
2617
|
/**
|
|
2618
|
+
* Get account context by account ID.
|
|
2619
|
+
* Returns null if no account with the given ID exists.
|
|
2620
|
+
*/
|
|
2621
|
+
getAccountContextById(id) {
|
|
2622
|
+
if (this.temporaryAccount && this.temporaryAccount.id === id) return this.toAccountContext(this.temporaryAccount);
|
|
2623
|
+
const account = this.accounts.get(id);
|
|
2624
|
+
if (account) return this.toAccountContext(account);
|
|
2625
|
+
return null;
|
|
2626
|
+
}
|
|
2627
|
+
/**
|
|
2696
2628
|
* Get account context by index.
|
|
2697
2629
|
* Index 0 is the temporary account (if exists), otherwise the first registered account.
|
|
2698
2630
|
* Returns null if index is out of bounds.
|
|
@@ -2928,5 +2860,5 @@ var AccountsManager = class {
|
|
|
2928
2860
|
const accountsManager = new AccountsManager({ persistentAffinityStore: getSharedSessionAffinityStore });
|
|
2929
2861
|
|
|
2930
2862
|
//#endregion
|
|
2931
|
-
export {
|
|
2932
|
-
//# sourceMappingURL=accounts-manager-
|
|
2863
|
+
export { isMessageStartInputTokensFallbackEnabled as A, getModelAliasesInfo as C, getSmallModel as D, getReasoningEffortForModel as E, resolveModelAlias as F, shouldCompactUseSmallModel as I, isResponsesApiContextManagementModel as M, isResponsesApiWebSearchEnabled as N, isAccountAffinityEnabled as O, mergeConfigWithDefaults as P, getModelAliases as S, getProviderConfig as T, getAnthropicApiKey as _, getClientIpInfo as a, getExtraPromptForModel as b, normalizeChatCompletionsUsage as c, toLocalDateString as d, copilotFetch as f, getAliasTargetSet as g, PROVIDER_TYPE_ANTHROPIC as h, extractResponsesUsageFromStreamEvent as i, isMessagesApiEnabled as j, isForceAgentEnabled as k, normalizeEmbeddingsUsage as l, isDevModeEnabled as m, applySharedSessionAffinityRetention as n, getRequestHistoryStore as o, flushPendingCapture as p, extractResponsesUsageFromResult as r, getStatsStore as s, accountsManager as t, normalizeMessagesUsage as u, getClaudeTokenMultiplier as v, getModelRefreshIntervalMs as w, getLogLevel as x, getConfig as y };
|
|
2864
|
+
//# sourceMappingURL=accounts-manager-B4eOuKSK.js.map
|