@omnicross/core 0.1.5 → 0.1.7
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/ApiConverter.cjs +2 -2
- package/dist/ApiConverter.js +1 -1
- package/dist/{CompletionService-DdWaAxq0.d.ts → CompletionService-C3BX0Ovy.d.ts} +4 -3
- package/dist/{CompletionService-D3a47vdU.d.cts → CompletionService-kNA17cfI.d.cts} +4 -3
- package/dist/auth/GeminiCodeAssistProjectResolver.cjs +8 -6
- package/dist/auth/GeminiCodeAssistProjectResolver.js +6 -4
- package/dist/{chunk-3Z5BQZFM.cjs → chunk-235MXAGX.cjs} +3 -1
- package/dist/{chunk-HRRYG2AX.js → chunk-23S5OPIO.js} +10 -1
- package/dist/chunk-25GXJCEZ.cjs +40 -0
- package/dist/chunk-2E42SAW3.cjs +323 -0
- package/dist/chunk-2JYRIADS.js +40 -0
- package/dist/chunk-2Z4XM3H5.cjs +44 -0
- package/dist/{chunk-BODMAL6G.js → chunk-32O35CIF.js} +271 -91
- package/dist/chunk-3SCOLIPT.cjs +63 -0
- package/dist/{chunk-SYQF7OIR.js → chunk-3WD4HTR2.js} +2 -0
- package/dist/{chunk-CGKLE6IW.cjs → chunk-4BB343BI.cjs} +1489 -520
- package/dist/{chunk-VACWOIRE.cjs → chunk-4VZX5F4T.cjs} +39 -15
- package/dist/{chunk-5ZQBEOMD.js → chunk-5NJLQ6T6.js} +46 -12
- package/dist/chunk-5RSZYQJH.cjs +62 -0
- package/dist/chunk-6QQG7YG3.cjs +153 -0
- package/dist/{chunk-IFXJ2BG7.js → chunk-7C7DET6S.js} +51 -6
- package/dist/{chunk-IK3KE3AU.js → chunk-DE2SRBFZ.js} +1 -1
- package/dist/{chunk-FH2P4OCD.js → chunk-E3COOKUP.js} +1240 -271
- package/dist/{chunk-UHGVBFU3.js → chunk-EBLFCNPY.js} +38 -14
- package/dist/chunk-FU7EAR73.js +62 -0
- package/dist/chunk-FXR6N3SR.js +323 -0
- package/dist/{chunk-SUEGJ75D.cjs → chunk-GDIXXKF2.cjs} +46 -12
- package/dist/chunk-GFIZ6LQI.js +170 -0
- package/dist/chunk-GL6XM527.js +61 -0
- package/dist/chunk-HVBBDBS3.cjs +350 -0
- package/dist/{chunk-46ZIFWYG.cjs → chunk-IIRPUVPH.cjs} +7 -1
- package/dist/chunk-J3QQ6JS5.cjs +170 -0
- package/dist/{chunk-JWVTXXPX.cjs → chunk-KBM2W6UY.cjs} +8 -4
- package/dist/chunk-LB6EBS6Y.js +69 -0
- package/dist/{chunk-IWQAX3CS.js → chunk-LVUCAWMK.js} +1 -1
- package/dist/chunk-MKF46GNZ.js +350 -0
- package/dist/{chunk-HYN75H6G.cjs → chunk-MUHWHQVM.cjs} +1 -1
- package/dist/chunk-MYYR3HZL.js +44 -0
- package/dist/{chunk-MFZ5437A.js → chunk-N5T4M4GU.js} +1 -1
- package/dist/{chunk-5ENKBSWO.js → chunk-N7OOJI5V.js} +88 -8
- package/dist/chunk-NKVZ6Z3Y.cjs +61 -0
- package/dist/chunk-OF3BECU2.cjs +69 -0
- package/dist/{chunk-SNYBEXLB.cjs → chunk-OJGQKHN5.cjs} +3 -1
- package/dist/{chunk-DDMRUL76.cjs → chunk-OKMJLEXX.cjs} +5 -5
- package/dist/chunk-OPRS4IQZ.js +153 -0
- package/dist/chunk-OTZC4TNH.cjs +79 -0
- package/dist/{chunk-3Q6Z6JTO.cjs → chunk-OVQBNVSV.cjs} +287 -107
- package/dist/{chunk-4XMYPW46.cjs → chunk-OXHNSZ53.cjs} +84 -44
- package/dist/{chunk-C6OV7GCC.js → chunk-PEGTIPB3.js} +52 -12
- package/dist/chunk-PO3XB56Z.js +79 -0
- package/dist/{chunk-D3TDKWRP.js → chunk-RJ5ZGNI3.js} +54 -5
- package/dist/{chunk-PG7PS2NN.cjs → chunk-RJUONLUQ.cjs} +59 -10
- package/dist/{chunk-BPKCU575.js → chunk-SOO562NM.js} +3 -1
- package/dist/{chunk-6QZGDLL4.js → chunk-TOVPMMHM.js} +5 -1
- package/dist/{chunk-K52THW2C.cjs → chunk-V4TXMEJS.cjs} +5 -5
- package/dist/{chunk-G2UTNSGU.js → chunk-WNKWAEUR.js} +7 -1
- package/dist/{chunk-UNWKG6EI.cjs → chunk-XPIOJQS2.cjs} +51 -6
- package/dist/chunk-XXFYLL7R.js +63 -0
- package/dist/{chunk-KFI44N2R.cjs → chunk-YNJNTCSQ.cjs} +10 -1
- package/dist/{chunk-VQY5W4YW.cjs → chunk-YWL7YZWS.cjs} +90 -10
- package/dist/completion/ApiKeyPoolService.cjs +12 -0
- package/dist/completion/ApiKeyPoolService.d.cts +6 -0
- package/dist/completion/ApiKeyPoolService.d.ts +6 -0
- package/dist/completion/ApiKeyPoolService.js +12 -0
- package/dist/completion/CompletionService.cjs +30 -24
- package/dist/completion/CompletionService.d.cts +3 -1
- package/dist/completion/CompletionService.d.ts +3 -1
- package/dist/completion/CompletionService.js +29 -23
- package/dist/completion.cjs +32 -26
- package/dist/completion.d.cts +3 -1
- package/dist/completion.d.ts +3 -1
- package/dist/completion.js +31 -25
- package/dist/index.cjs +56 -29
- package/dist/index.d.cts +8 -8
- package/dist/index.d.ts +8 -8
- package/dist/index.js +61 -34
- package/dist/{keyPolicy-Cp0FntZl.d.cts → keyPolicy-zdWTu3CQ.d.cts} +1 -1
- package/dist/{keyPolicy-Cp0FntZl.d.ts → keyPolicy-zdWTu3CQ.d.ts} +1 -1
- package/dist/outbound-api/auditCapture.cjs +2 -2
- package/dist/outbound-api/auditCapture.d.cts +3 -4
- package/dist/outbound-api/auditCapture.d.ts +3 -4
- package/dist/outbound-api/auditCapture.js +1 -1
- package/dist/outbound-api/quotaWarn.d.cts +1 -1
- package/dist/outbound-api/quotaWarn.d.ts +1 -1
- package/dist/outbound-api/routeResolver.cjs +2 -2
- package/dist/outbound-api/routeResolver.d.cts +5 -3
- package/dist/outbound-api/routeResolver.d.ts +5 -3
- package/dist/outbound-api/routeResolver.js +1 -1
- package/dist/outbound-api/subscriptionRegistryPort.d.cts +2 -0
- package/dist/outbound-api/subscriptionRegistryPort.d.ts +2 -0
- package/dist/outbound-api/types.d.cts +4 -2
- package/dist/outbound-api/types.d.ts +4 -2
- package/dist/outbound-api.cjs +52 -25
- package/dist/outbound-api.d.cts +131 -87
- package/dist/outbound-api.d.ts +131 -87
- package/dist/outbound-api.js +55 -28
- package/dist/pipeline/AccountAllowanceScheduling.cjs +15 -0
- package/dist/pipeline/AccountAllowanceScheduling.d.cts +91 -0
- package/dist/pipeline/AccountAllowanceScheduling.d.ts +91 -0
- package/dist/pipeline/AccountAllowanceScheduling.js +15 -0
- package/dist/pipeline/AccountAllowanceStore.cjs +20 -0
- package/dist/pipeline/AccountAllowanceStore.d.cts +77 -0
- package/dist/pipeline/AccountAllowanceStore.d.ts +77 -0
- package/dist/pipeline/AccountAllowanceStore.js +20 -0
- package/dist/pipeline/AccountRouteActivity.cjs +10 -0
- package/dist/pipeline/AccountRouteActivity.d.cts +61 -0
- package/dist/pipeline/AccountRouteActivity.d.ts +61 -0
- package/dist/pipeline/AccountRouteActivity.js +10 -0
- package/dist/pipeline/AuthSource.d.cts +11 -2
- package/dist/pipeline/AuthSource.d.ts +11 -2
- package/dist/pipeline/BoundAccountSelectionError.cjs +10 -0
- package/dist/pipeline/BoundAccountSelectionError.d.cts +28 -0
- package/dist/pipeline/BoundAccountSelectionError.d.ts +28 -0
- package/dist/pipeline/BoundAccountSelectionError.js +10 -0
- package/dist/pipeline/LlmConfigProviderAuth.d.cts +1 -0
- package/dist/pipeline/LlmConfigProviderAuth.d.ts +1 -0
- package/dist/pipeline/ServerOverloadCounter.cjs +16 -0
- package/dist/pipeline/ServerOverloadCounter.d.cts +77 -0
- package/dist/pipeline/ServerOverloadCounter.d.ts +77 -0
- package/dist/pipeline/ServerOverloadCounter.js +16 -0
- package/dist/pipeline/SubscriptionAccountHealth.cjs +6 -2
- package/dist/pipeline/SubscriptionAccountHealth.d.cts +65 -8
- package/dist/pipeline/SubscriptionAccountHealth.d.ts +65 -8
- package/dist/pipeline/SubscriptionAccountHealth.js +5 -1
- package/dist/pipeline/SubscriptionAuthSource.cjs +5 -2
- package/dist/pipeline/SubscriptionAuthSource.d.cts +1 -0
- package/dist/pipeline/SubscriptionAuthSource.d.ts +1 -0
- package/dist/pipeline/SubscriptionAuthSource.js +4 -1
- package/dist/pipeline/SubscriptionAuthStrategy.d.cts +8 -3
- package/dist/pipeline/SubscriptionAuthStrategy.d.ts +8 -3
- package/dist/pipeline/executeProviderCall.cjs +2 -2
- package/dist/pipeline/executeProviderCall.d.cts +8 -3
- package/dist/pipeline/executeProviderCall.d.ts +8 -3
- package/dist/pipeline/executeProviderCall.js +1 -1
- package/dist/pipeline/resolveProviderChain.d.cts +2 -3
- package/dist/pipeline/resolveProviderChain.d.ts +2 -3
- package/dist/pipeline/resolveSubscriptionChain.d.cts +1 -0
- package/dist/pipeline/resolveSubscriptionChain.d.ts +1 -0
- package/dist/pipeline/upstreamFetch.cjs +5 -3
- package/dist/pipeline/upstreamFetch.d.cts +35 -6
- package/dist/pipeline/upstreamFetch.d.ts +35 -6
- package/dist/pipeline/upstreamFetch.js +4 -2
- package/dist/pipeline/upstreamTrace.cjs +4 -2
- package/dist/pipeline/upstreamTrace.d.cts +22 -8
- package/dist/pipeline/upstreamTrace.d.ts +22 -8
- package/dist/pipeline/upstreamTrace.js +3 -1
- package/dist/ports/pricing-store.d.cts +4 -3
- package/dist/ports/pricing-store.d.ts +4 -3
- package/dist/ports.d.cts +4 -3
- package/dist/ports.d.ts +4 -3
- package/dist/provider-proxy/ProviderProxy.cjs +30 -24
- package/dist/provider-proxy/ProviderProxy.d.cts +2 -0
- package/dist/provider-proxy/ProviderProxy.d.ts +2 -0
- package/dist/provider-proxy/ProviderProxy.js +29 -23
- package/dist/provider-proxy/identity/codexCliHeaders.cjs +10 -0
- package/dist/provider-proxy/identity/codexCliHeaders.d.cts +45 -0
- package/dist/provider-proxy/identity/codexCliHeaders.d.ts +45 -0
- package/dist/provider-proxy/identity/codexCliHeaders.js +10 -0
- package/dist/provider-proxy/ingress/providerProxyShared.cjs +32 -24
- package/dist/provider-proxy/ingress/providerProxyShared.d.cts +44 -5
- package/dist/provider-proxy/ingress/providerProxyShared.d.ts +44 -5
- package/dist/provider-proxy/ingress/providerProxyShared.js +31 -23
- package/dist/provider-proxy/matchText.cjs +4 -2
- package/dist/provider-proxy/matchText.d.cts +39 -6
- package/dist/provider-proxy/matchText.d.ts +39 -6
- package/dist/provider-proxy/matchText.js +3 -1
- package/dist/provider-proxy/types.d.cts +35 -2
- package/dist/provider-proxy/types.d.ts +35 -2
- package/dist/provider-proxy.cjs +30 -24
- package/dist/provider-proxy.d.cts +2 -0
- package/dist/provider-proxy.d.ts +2 -0
- package/dist/provider-proxy.js +29 -23
- package/dist/{routeResolver-C4T7yClx.d.ts → routeResolver-BxOfunbm.d.ts} +1 -1
- package/dist/{routeResolver-CB3tvJKy.d.cts → routeResolver-D5OzD0iM.d.cts} +1 -1
- package/dist/transformer/TransformerChainExecutor.cjs +2 -2
- package/dist/transformer/TransformerChainExecutor.js +1 -1
- package/dist/transformer/transformers/AnthropicTransformer.cjs +3 -2
- package/dist/transformer/transformers/AnthropicTransformer.js +2 -1
- package/dist/transformer/transformers/GeminiCodeAssistTransformer.cjs +3 -3
- package/dist/transformer/transformers/GeminiCodeAssistTransformer.js +2 -2
- package/dist/transformer/transformers/GeminiTransformer.cjs +3 -3
- package/dist/transformer/transformers/GeminiTransformer.js +2 -2
- package/dist/transformer/transformers/OpenAIResponseTransformer.cjs +3 -2
- package/dist/transformer/transformers/OpenAIResponseTransformer.d.cts +1 -1
- package/dist/transformer/transformers/OpenAIResponseTransformer.d.ts +1 -1
- package/dist/transformer/transformers/OpenAIResponseTransformer.js +2 -1
- package/dist/transformer/transformers/OpenAITransformer.cjs +6 -0
- package/dist/transformer/transformers/OpenAITransformer.d.cts +68 -0
- package/dist/transformer/transformers/OpenAITransformer.d.ts +68 -0
- package/dist/transformer/transformers/OpenAITransformer.js +6 -0
- package/dist/transformer/transformers.cjs +9 -14
- package/dist/transformer/transformers.d.cts +12 -48
- package/dist/transformer/transformers.d.ts +12 -48
- package/dist/transformer/transformers.js +11 -16
- package/dist/transformer/types.d.cts +17 -0
- package/dist/transformer/types.d.ts +17 -0
- package/dist/transformer.cjs +12 -12
- package/dist/transformer.d.cts +1 -2
- package/dist/transformer.d.ts +1 -2
- package/dist/transformer.js +12 -12
- package/dist/{types-lgPYQuZS.d.ts → types-CqZD77rS.d.ts} +173 -7
- package/dist/{types-B8Arpxn0.d.cts → types-gjJ5lJ5n.d.cts} +173 -7
- package/dist/usage/pricing-engine.cjs +2 -2
- package/dist/usage/pricing-engine.d.cts +29 -1
- package/dist/usage/pricing-engine.d.ts +29 -1
- package/dist/usage/pricing-engine.js +1 -1
- package/dist/usage/usage-recorder.cjs +2 -2
- package/dist/usage/usage-recorder.d.cts +5 -1
- package/dist/usage/usage-recorder.d.ts +5 -1
- package/dist/usage/usage-recorder.js +1 -1
- package/dist/usage.cjs +3 -3
- package/dist/usage.js +2 -2
- package/package.json +1 -1
- package/dist/chunk-7FEBOPJO.cjs +0 -50
- package/dist/chunk-DWKQZ2SK.cjs +0 -254
- package/dist/chunk-IAXWICZU.js +0 -69
- package/dist/chunk-IB3FDI4O.js +0 -50
- package/dist/chunk-OQWKZCXP.js +0 -242
- package/dist/chunk-QWBWGODS.cjs +0 -69
- package/dist/chunk-YMFAJFQT.cjs +0 -173
- package/dist/chunk-ZCIQ3L3R.cjs +0 -242
- package/dist/chunk-ZJZAOKI7.js +0 -254
- package/dist/chunk-ZLX3KGXX.js +0 -173
- package/dist/transformer/transformers/OpenCodeGoTransformer.cjs +0 -6
- package/dist/transformer/transformers/OpenCodeGoTransformer.d.cts +0 -51
- package/dist/transformer/transformers/OpenCodeGoTransformer.d.ts +0 -51
- package/dist/transformer/transformers/OpenCodeGoTransformer.js +0 -6
- package/dist/transformer/transformers/ReasoningTransformer.cjs +0 -6
- package/dist/transformer/transformers/ReasoningTransformer.d.cts +0 -47
- package/dist/transformer/transformers/ReasoningTransformer.d.ts +0 -47
- package/dist/transformer/transformers/ReasoningTransformer.js +0 -6
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
// src/provider-proxy/matchText.ts
|
|
2
|
+
import { createHash } from "crypto";
|
|
3
|
+
var MATCH_TEXT_PER_MESSAGE_CAP = 8192;
|
|
4
|
+
var MATCH_TEXT_RECENT_MESSAGES = 6;
|
|
5
|
+
function flattenMatchText(value) {
|
|
6
|
+
if (typeof value === "string") return value;
|
|
7
|
+
if (Array.isArray(value)) {
|
|
8
|
+
const parts = [];
|
|
9
|
+
for (const item of value) {
|
|
10
|
+
const text = flattenMatchText(item);
|
|
11
|
+
if (text) parts.push(text);
|
|
12
|
+
}
|
|
13
|
+
return parts.join("\n");
|
|
14
|
+
}
|
|
15
|
+
if (value && typeof value === "object") {
|
|
16
|
+
const obj = value;
|
|
17
|
+
if (obj.type === "tool_result" && obj.content !== void 0) {
|
|
18
|
+
return flattenMatchText(obj.content);
|
|
19
|
+
}
|
|
20
|
+
if (typeof obj.text === "string") return obj.text;
|
|
21
|
+
}
|
|
22
|
+
return "";
|
|
23
|
+
}
|
|
24
|
+
function collectMatchText(anthropicBody) {
|
|
25
|
+
const messages = Array.isArray(anthropicBody.messages) ? anthropicBody.messages : [];
|
|
26
|
+
const slices = [];
|
|
27
|
+
const sys = flattenMatchText(anthropicBody.system).trim();
|
|
28
|
+
if (sys) slices.push(sys.slice(0, MATCH_TEXT_PER_MESSAGE_CAP));
|
|
29
|
+
const recent = [];
|
|
30
|
+
for (let i = messages.length - 1; i >= 0 && recent.length < MATCH_TEXT_RECENT_MESSAGES; i--) {
|
|
31
|
+
const message = messages[i];
|
|
32
|
+
if (!message || typeof message !== "object") continue;
|
|
33
|
+
const role = message.role;
|
|
34
|
+
if (role !== "user" && role !== "system") continue;
|
|
35
|
+
const text = flattenMatchText(message.content).trim();
|
|
36
|
+
if (text) recent.push(text.slice(0, MATCH_TEXT_PER_MESSAGE_CAP));
|
|
37
|
+
}
|
|
38
|
+
for (let i = recent.length - 1; i >= 0; i--) slices.push(recent[i]);
|
|
39
|
+
return slices;
|
|
40
|
+
}
|
|
41
|
+
function deriveSubscriptionSessionKey(anthropicBody) {
|
|
42
|
+
const system = flattenMatchText(anthropicBody.system).trim().slice(0, MATCH_TEXT_PER_MESSAGE_CAP);
|
|
43
|
+
const messages = Array.isArray(anthropicBody.messages) ? anthropicBody.messages : [];
|
|
44
|
+
let firstUser = "";
|
|
45
|
+
for (const message of messages) {
|
|
46
|
+
if (message && typeof message === "object" && message.role === "user") {
|
|
47
|
+
firstUser = flattenMatchText(message.content).trim().slice(0, MATCH_TEXT_PER_MESSAGE_CAP);
|
|
48
|
+
break;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
const anchor = `${system}\0${firstUser}`;
|
|
52
|
+
if (!system && !firstUser) return void 0;
|
|
53
|
+
return fnv1a(anchor);
|
|
54
|
+
}
|
|
55
|
+
var SESSION_ID_CAP = 1024;
|
|
56
|
+
function deriveGatewaySessionKey(body, headers = {}, options = {}) {
|
|
57
|
+
const sessionHeader = firstHeaderValue(headers, ["session-id", "session_id", "x-session-id"]);
|
|
58
|
+
if (sessionHeader) {
|
|
59
|
+
return { key: stableSessionDigest(sessionHeader), source: "session-header" };
|
|
60
|
+
}
|
|
61
|
+
const threadHeader = firstHeaderValue(headers, ["thread-id", "thread_id", "x-thread-id"]);
|
|
62
|
+
if (threadHeader) {
|
|
63
|
+
return { key: stableSessionDigest(threadHeader), source: "thread-header" };
|
|
64
|
+
}
|
|
65
|
+
const bodySessionId = scalarSessionValue(body.session_id);
|
|
66
|
+
if (bodySessionId) {
|
|
67
|
+
return { key: stableSessionDigest(bodySessionId), source: "body-session-id" };
|
|
68
|
+
}
|
|
69
|
+
const bodyThreadId = scalarSessionValue(body.thread_id ?? body.threadId);
|
|
70
|
+
if (bodyThreadId) {
|
|
71
|
+
return { key: stableSessionDigest(bodyThreadId), source: "body-thread-id" };
|
|
72
|
+
}
|
|
73
|
+
const conversationId = scalarSessionValue(body.conversation_id);
|
|
74
|
+
if (conversationId) {
|
|
75
|
+
return { key: stableSessionDigest(conversationId), source: "body-session-id" };
|
|
76
|
+
}
|
|
77
|
+
const promptCacheKey = scalarSessionValue(body.prompt_cache_key);
|
|
78
|
+
if (promptCacheKey) {
|
|
79
|
+
return { key: stableSessionDigest(promptCacheKey), source: "prompt-cache-key" };
|
|
80
|
+
}
|
|
81
|
+
const fingerprint = deriveResponsesContentFingerprint(body);
|
|
82
|
+
if (fingerprint) {
|
|
83
|
+
return { key: stableSessionDigest(fingerprint), source: "content-fingerprint" };
|
|
84
|
+
}
|
|
85
|
+
const endpoint = options.endpoint?.trim() || "responses";
|
|
86
|
+
const fallback = options.fallbackKey?.trim() || "anonymous";
|
|
87
|
+
return {
|
|
88
|
+
key: stableSessionDigest(`${endpoint}\0${fallback}`),
|
|
89
|
+
source: "api-key-fallback"
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
function stableSessionDigest(value) {
|
|
93
|
+
return createHash("sha256").update(value, "utf8").digest("hex").slice(0, 32);
|
|
94
|
+
}
|
|
95
|
+
function firstHeaderValue(headers, names) {
|
|
96
|
+
const byLower = /* @__PURE__ */ new Map();
|
|
97
|
+
for (const [name, value] of Object.entries(headers)) {
|
|
98
|
+
if (typeof value === "string" || Array.isArray(value)) {
|
|
99
|
+
const lower = name.toLowerCase();
|
|
100
|
+
if (!byLower.has(lower)) byLower.set(lower, value);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
for (const name of names) {
|
|
104
|
+
const value = byLower.get(name);
|
|
105
|
+
const values = Array.isArray(value) ? value : [value];
|
|
106
|
+
for (const item of values) {
|
|
107
|
+
if (typeof item !== "string") continue;
|
|
108
|
+
const trimmed = item.trim();
|
|
109
|
+
if (trimmed) return trimmed.slice(0, SESSION_ID_CAP);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
return void 0;
|
|
113
|
+
}
|
|
114
|
+
function scalarSessionValue(value) {
|
|
115
|
+
if (typeof value !== "string" && typeof value !== "number") return void 0;
|
|
116
|
+
const trimmed = String(value).trim();
|
|
117
|
+
return trimmed ? trimmed.slice(0, SESSION_ID_CAP) : void 0;
|
|
118
|
+
}
|
|
119
|
+
function deriveResponsesContentFingerprint(body) {
|
|
120
|
+
const stable = [];
|
|
121
|
+
const instructions = flattenMatchText(body.instructions).trim();
|
|
122
|
+
if (instructions) stable.push(instructions.slice(0, MATCH_TEXT_PER_MESSAGE_CAP));
|
|
123
|
+
const input = body.input;
|
|
124
|
+
let firstUser = "";
|
|
125
|
+
const visitItem = (item) => {
|
|
126
|
+
if (typeof item === "string") {
|
|
127
|
+
if (!firstUser) firstUser = item.trim().slice(0, MATCH_TEXT_PER_MESSAGE_CAP);
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
if (!item || typeof item !== "object") return;
|
|
131
|
+
const record = item;
|
|
132
|
+
const role = typeof record.role === "string" ? record.role.toLowerCase() : "";
|
|
133
|
+
const content = record.content ?? record.text ?? record.input;
|
|
134
|
+
const text = flattenMatchText(content !== void 0 ? content : record).trim();
|
|
135
|
+
if (!text) return;
|
|
136
|
+
if (role === "developer" || role === "system") {
|
|
137
|
+
stable.push(text.slice(0, MATCH_TEXT_PER_MESSAGE_CAP));
|
|
138
|
+
} else if (role === "user" || !role) {
|
|
139
|
+
if (!firstUser) firstUser = text.slice(0, MATCH_TEXT_PER_MESSAGE_CAP);
|
|
140
|
+
}
|
|
141
|
+
};
|
|
142
|
+
if (Array.isArray(input)) {
|
|
143
|
+
for (const item of input) visitItem(item);
|
|
144
|
+
} else if (input !== void 0) {
|
|
145
|
+
visitItem(input);
|
|
146
|
+
}
|
|
147
|
+
if (stable.length === 0) {
|
|
148
|
+
const legacySystem = flattenMatchText(body.system).trim();
|
|
149
|
+
if (legacySystem) stable.push(legacySystem.slice(0, MATCH_TEXT_PER_MESSAGE_CAP));
|
|
150
|
+
}
|
|
151
|
+
if (stable.length === 0 && !firstUser) return void 0;
|
|
152
|
+
return `${stable.join("\0")}\0${firstUser}`;
|
|
153
|
+
}
|
|
154
|
+
function fnv1a(str) {
|
|
155
|
+
let h = 2166136261;
|
|
156
|
+
for (let i = 0; i < str.length; i++) {
|
|
157
|
+
h ^= str.charCodeAt(i);
|
|
158
|
+
h = Math.imul(h, 16777619);
|
|
159
|
+
}
|
|
160
|
+
return (h >>> 0).toString(16).padStart(8, "0");
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
export {
|
|
164
|
+
MATCH_TEXT_PER_MESSAGE_CAP,
|
|
165
|
+
MATCH_TEXT_RECENT_MESSAGES,
|
|
166
|
+
flattenMatchText,
|
|
167
|
+
collectMatchText,
|
|
168
|
+
deriveSubscriptionSessionKey,
|
|
169
|
+
deriveGatewaySessionKey
|
|
170
|
+
};
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
// src/pipeline/AccountRouteActivity.ts
|
|
2
|
+
var ACCOUNT_ROUTE_ACTIVITY_LIMIT = 300;
|
|
3
|
+
function boundedLimit(value) {
|
|
4
|
+
if (!Number.isFinite(value)) return 100;
|
|
5
|
+
return Math.max(1, Math.min(ACCOUNT_ROUTE_ACTIVITY_LIMIT, Math.trunc(value)));
|
|
6
|
+
}
|
|
7
|
+
var AccountRouteActivityStore = class {
|
|
8
|
+
records = [];
|
|
9
|
+
sequence = 0;
|
|
10
|
+
record(input) {
|
|
11
|
+
const ts = input.ts ?? Date.now();
|
|
12
|
+
const sessionKey = input.sessionKey?.trim() || void 0;
|
|
13
|
+
const previous = sessionKey ? this.records.find((record2) => record2.providerId === input.providerId && record2.endpoint === input.endpoint && record2.sessionKey === sessionKey) : void 0;
|
|
14
|
+
const affinity = !sessionKey ? "untracked" : !previous ? "new" : previous.accountId === input.accountId ? "sticky" : "switched";
|
|
15
|
+
const record = {
|
|
16
|
+
...input,
|
|
17
|
+
id: `${ts.toString(36)}-${(this.sequence++).toString(36)}`,
|
|
18
|
+
ts,
|
|
19
|
+
sessionKey,
|
|
20
|
+
affinity,
|
|
21
|
+
...affinity === "switched" && previous ? { previousAccountId: previous.accountId } : {}
|
|
22
|
+
};
|
|
23
|
+
this.records.unshift(record);
|
|
24
|
+
if (this.records.length > ACCOUNT_ROUTE_ACTIVITY_LIMIT) {
|
|
25
|
+
this.records.length = ACCOUNT_ROUTE_ACTIVITY_LIMIT;
|
|
26
|
+
}
|
|
27
|
+
return { ...record };
|
|
28
|
+
}
|
|
29
|
+
list(query = {}) {
|
|
30
|
+
const providerId = query.providerId?.trim();
|
|
31
|
+
const accountId = query.accountId?.trim();
|
|
32
|
+
const sessionKey = query.sessionKey?.trim();
|
|
33
|
+
return this.records.filter((record) => !providerId || record.providerId === providerId).filter((record) => !accountId || record.accountId === accountId).filter((record) => !sessionKey || record.sessionKey === sessionKey).slice(0, boundedLimit(query.limit)).map((record) => ({ ...record }));
|
|
34
|
+
}
|
|
35
|
+
clear() {
|
|
36
|
+
this.records.length = 0;
|
|
37
|
+
this.sequence = 0;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Backfill a field on an already-recorded entry. Used to annotate a record
|
|
41
|
+
* AFTER the upstream body streams — e.g. a `200` whose SSE body carries a
|
|
42
|
+
* `response.failed` overload event is only detectable mid-relay, long after
|
|
43
|
+
* `record()` stamped the 200 status. `patch` is intentionally narrow: only
|
|
44
|
+
* post-hoc-observable fields belong here, never the routing-decision fields.
|
|
45
|
+
* No-op when the id has already aged out of the bounded ring.
|
|
46
|
+
*/
|
|
47
|
+
amend(id, patch) {
|
|
48
|
+
const record = this.records.find((r) => r.id === id);
|
|
49
|
+
if (record) Object.assign(record, patch);
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
var sharedAccountRouteActivity = new AccountRouteActivityStore();
|
|
53
|
+
function getSharedAccountRouteActivity() {
|
|
54
|
+
return sharedAccountRouteActivity;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export {
|
|
58
|
+
ACCOUNT_ROUTE_ACTIVITY_LIMIT,
|
|
59
|
+
AccountRouteActivityStore,
|
|
60
|
+
getSharedAccountRouteActivity
|
|
61
|
+
};
|
|
@@ -0,0 +1,350 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; } var _class;// src/pipeline/AccountAllowanceStore.ts
|
|
2
|
+
var DEFAULT_CODEX_ALLOWANCE_FRESH_MS = 15 * 6e4;
|
|
3
|
+
var DEFAULT_ALLOWANCE_MAX_SNAPSHOTS = 256;
|
|
4
|
+
var MAX_WINDOWS_PER_SNAPSHOT = 8;
|
|
5
|
+
var MAX_TEXT_LENGTH = 200;
|
|
6
|
+
function snapshotKey(providerId, accountId) {
|
|
7
|
+
return `${providerId}\0${accountId}`;
|
|
8
|
+
}
|
|
9
|
+
function cloneWindow(window) {
|
|
10
|
+
return {
|
|
11
|
+
id: window.id,
|
|
12
|
+
label: window.label,
|
|
13
|
+
scope: window.scope,
|
|
14
|
+
...window.modelFamily === void 0 ? {} : { modelFamily: window.modelFamily },
|
|
15
|
+
usedPercent: window.usedPercent,
|
|
16
|
+
...window.windowMinutes === void 0 ? {} : { windowMinutes: window.windowMinutes },
|
|
17
|
+
...window.resetsAt === void 0 ? {} : { resetsAt: window.resetsAt },
|
|
18
|
+
...window.remainingSeconds === void 0 ? {} : { remainingSeconds: window.remainingSeconds },
|
|
19
|
+
state: window.state
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
function cloneSnapshot(snapshot) {
|
|
23
|
+
return {
|
|
24
|
+
providerId: snapshot.providerId,
|
|
25
|
+
accountId: snapshot.accountId,
|
|
26
|
+
source: snapshot.source,
|
|
27
|
+
observedAt: snapshot.observedAt,
|
|
28
|
+
...snapshot.expiresAt === void 0 ? {} : { expiresAt: snapshot.expiresAt },
|
|
29
|
+
windows: snapshot.windows.map(cloneWindow),
|
|
30
|
+
...snapshot.lastErrorCode === void 0 ? {} : { lastErrorCode: snapshot.lastErrorCode },
|
|
31
|
+
...snapshot.primaryOverSecondaryLimitPercent === void 0 ? {} : { primaryOverSecondaryLimitPercent: snapshot.primaryOverSecondaryLimitPercent }
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
function finiteNumber(value) {
|
|
35
|
+
if (value === null || value === void 0 || value === "") return void 0;
|
|
36
|
+
const parsed = typeof value === "number" ? value : Number(value);
|
|
37
|
+
return Number.isFinite(parsed) && parsed >= 0 ? parsed : void 0;
|
|
38
|
+
}
|
|
39
|
+
function boundedText(value, max = MAX_TEXT_LENGTH) {
|
|
40
|
+
return typeof value === "string" && value.length > 0 && value.length <= max ? value : void 0;
|
|
41
|
+
}
|
|
42
|
+
function finitePercent(value) {
|
|
43
|
+
if (value === null) return null;
|
|
44
|
+
if (value === void 0 || value === "") return void 0;
|
|
45
|
+
const parsed = typeof value === "number" ? value : Number(value);
|
|
46
|
+
return Number.isFinite(parsed) && parsed >= 0 && parsed <= 100 ? parsed : void 0;
|
|
47
|
+
}
|
|
48
|
+
function finiteNonNegativeInteger(value) {
|
|
49
|
+
const parsed = finiteNumber(value);
|
|
50
|
+
return parsed === void 0 ? void 0 : Math.floor(parsed);
|
|
51
|
+
}
|
|
52
|
+
function normalizedInstant(value) {
|
|
53
|
+
if (typeof value !== "string" || !value.trim()) return void 0;
|
|
54
|
+
const parsed = Date.parse(value);
|
|
55
|
+
return Number.isFinite(parsed) ? new Date(parsed).toISOString() : void 0;
|
|
56
|
+
}
|
|
57
|
+
function isAllowanceProvider(value) {
|
|
58
|
+
return value === "claude" || value === "codex" || value === "gemini" || value === "opencodego";
|
|
59
|
+
}
|
|
60
|
+
function isWindowState(value) {
|
|
61
|
+
return value === "fresh" || value === "stale" || value === "unavailable" || value === "unsupported";
|
|
62
|
+
}
|
|
63
|
+
function normalizeAccountAllowanceSnapshot(value) {
|
|
64
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return null;
|
|
65
|
+
const raw = value;
|
|
66
|
+
const providerId = raw.providerId;
|
|
67
|
+
const accountId = boundedText(raw.accountId);
|
|
68
|
+
const source = raw.source;
|
|
69
|
+
const observedAt = normalizedInstant(raw.observedAt);
|
|
70
|
+
if (!isAllowanceProvider(providerId) || !accountId || source !== "oauth-usage-api" && source !== "response-headers" || !observedAt || !Array.isArray(raw.windows) || raw.windows.length > MAX_WINDOWS_PER_SNAPSHOT) return null;
|
|
71
|
+
const windows = [];
|
|
72
|
+
for (const item of raw.windows) {
|
|
73
|
+
if (!item || typeof item !== "object" || Array.isArray(item)) return null;
|
|
74
|
+
const window = item;
|
|
75
|
+
const id = boundedText(window.id);
|
|
76
|
+
const label = boundedText(window.label);
|
|
77
|
+
const scope = window.scope;
|
|
78
|
+
const state = window.state;
|
|
79
|
+
const usedPercent = finitePercent(window.usedPercent);
|
|
80
|
+
if (!id || !label || scope !== "all" && scope !== "model-family" || !isWindowState(state) || window.usedPercent !== void 0 && usedPercent === void 0) return null;
|
|
81
|
+
const modelFamily = boundedText(window.modelFamily, 80);
|
|
82
|
+
if (scope === "model-family" && !modelFamily) return null;
|
|
83
|
+
const windowMinutes = window.windowMinutes === void 0 ? void 0 : finiteNonNegativeInteger(window.windowMinutes);
|
|
84
|
+
const remainingSeconds2 = window.remainingSeconds === void 0 ? void 0 : finiteNonNegativeInteger(window.remainingSeconds);
|
|
85
|
+
if (window.windowMinutes !== void 0 && windowMinutes === void 0 || window.remainingSeconds !== void 0 && remainingSeconds2 === void 0) return null;
|
|
86
|
+
const resetsAt = window.resetsAt === void 0 ? void 0 : normalizedInstant(window.resetsAt);
|
|
87
|
+
if (window.resetsAt !== void 0 && !resetsAt) return null;
|
|
88
|
+
windows.push({
|
|
89
|
+
id,
|
|
90
|
+
label,
|
|
91
|
+
scope,
|
|
92
|
+
...scope === "model-family" ? { modelFamily } : {},
|
|
93
|
+
usedPercent: _nullishCoalesce(usedPercent, () => ( null)),
|
|
94
|
+
...windowMinutes === void 0 ? {} : { windowMinutes },
|
|
95
|
+
...resetsAt === void 0 ? {} : { resetsAt },
|
|
96
|
+
...remainingSeconds2 === void 0 ? {} : { remainingSeconds: remainingSeconds2 },
|
|
97
|
+
state
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
const expiresAt = raw.expiresAt === void 0 ? void 0 : normalizedInstant(raw.expiresAt);
|
|
101
|
+
if (raw.expiresAt !== void 0 && !expiresAt) return null;
|
|
102
|
+
const lastErrorCode = raw.lastErrorCode === void 0 ? void 0 : typeof raw.lastErrorCode === "string" && /^[a-z0-9][a-z0-9_.-]{0,63}$/.test(raw.lastErrorCode) ? raw.lastErrorCode : void 0;
|
|
103
|
+
if (raw.lastErrorCode !== void 0 && lastErrorCode === void 0) return null;
|
|
104
|
+
let primaryOverSecondaryLimitPercent;
|
|
105
|
+
if (raw.primaryOverSecondaryLimitPercent !== void 0) {
|
|
106
|
+
if (raw.primaryOverSecondaryLimitPercent === null) return null;
|
|
107
|
+
const parsed = finitePercent(raw.primaryOverSecondaryLimitPercent);
|
|
108
|
+
if (parsed === void 0 || parsed === null) return null;
|
|
109
|
+
primaryOverSecondaryLimitPercent = parsed;
|
|
110
|
+
}
|
|
111
|
+
return {
|
|
112
|
+
providerId,
|
|
113
|
+
accountId,
|
|
114
|
+
source,
|
|
115
|
+
observedAt,
|
|
116
|
+
...expiresAt === void 0 ? {} : { expiresAt },
|
|
117
|
+
windows,
|
|
118
|
+
...lastErrorCode === void 0 ? {} : { lastErrorCode },
|
|
119
|
+
...primaryOverSecondaryLimitPercent === void 0 ? {} : { primaryOverSecondaryLimitPercent }
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
function headerValue(headers, name) {
|
|
123
|
+
const getter = headers.get;
|
|
124
|
+
if (typeof getter === "function") return getter.call(headers, name);
|
|
125
|
+
const record = headers;
|
|
126
|
+
const wanted = name.toLowerCase();
|
|
127
|
+
for (const [key, value] of Object.entries(record)) {
|
|
128
|
+
if (key.toLowerCase() !== wanted) continue;
|
|
129
|
+
return Array.isArray(value) ? value[0] : value;
|
|
130
|
+
}
|
|
131
|
+
return void 0;
|
|
132
|
+
}
|
|
133
|
+
function parseWindow(headers, prefix) {
|
|
134
|
+
const usedPercent = _nullishCoalesce(finitePercent(headerValue(headers, `x-codex-${prefix}-used-percent`)), () => ( void 0));
|
|
135
|
+
const resetAfterSeconds = finiteNumber(
|
|
136
|
+
headerValue(headers, `x-codex-${prefix}-reset-after-seconds`)
|
|
137
|
+
);
|
|
138
|
+
const windowMinutes = finiteNumber(headerValue(headers, `x-codex-${prefix}-window-minutes`));
|
|
139
|
+
if (usedPercent === void 0 && resetAfterSeconds === void 0 && windowMinutes === void 0) {
|
|
140
|
+
return void 0;
|
|
141
|
+
}
|
|
142
|
+
return { usedPercent, resetAfterSeconds, windowMinutes };
|
|
143
|
+
}
|
|
144
|
+
function parseCodexAllowanceHeaders(headers) {
|
|
145
|
+
const primary = parseWindow(headers, "primary");
|
|
146
|
+
const secondary = parseWindow(headers, "secondary");
|
|
147
|
+
const primaryOverSecondaryLimitPercent = _nullishCoalesce(finitePercent(
|
|
148
|
+
headerValue(headers, "x-codex-primary-over-secondary-limit-percent")
|
|
149
|
+
), () => ( void 0));
|
|
150
|
+
if (!primary && !secondary && primaryOverSecondaryLimitPercent === void 0) return null;
|
|
151
|
+
return { primary, secondary, primaryOverSecondaryLimitPercent };
|
|
152
|
+
}
|
|
153
|
+
function durationLabel(minutes) {
|
|
154
|
+
if (minutes === void 0) return void 0;
|
|
155
|
+
if (minutes % (7 * 24 * 60) === 0) {
|
|
156
|
+
const weeks = minutes / (7 * 24 * 60);
|
|
157
|
+
return `${weeks} week${weeks === 1 ? "" : "s"}`;
|
|
158
|
+
}
|
|
159
|
+
if (minutes % (24 * 60) === 0) {
|
|
160
|
+
const days = minutes / (24 * 60);
|
|
161
|
+
return `${days} day${days === 1 ? "" : "s"}`;
|
|
162
|
+
}
|
|
163
|
+
if (minutes % 60 === 0) {
|
|
164
|
+
const hours = minutes / 60;
|
|
165
|
+
return `${hours} hour${hours === 1 ? "" : "s"}`;
|
|
166
|
+
}
|
|
167
|
+
return `${minutes} minutes`;
|
|
168
|
+
}
|
|
169
|
+
function codexLabel(id, minutes) {
|
|
170
|
+
const base = id === "primary" ? "Primary" : "Secondary";
|
|
171
|
+
const duration = durationLabel(minutes);
|
|
172
|
+
return duration ? `${base} \xB7 ${duration}` : base;
|
|
173
|
+
}
|
|
174
|
+
function resetAt(observedMs, seconds) {
|
|
175
|
+
if (seconds === void 0) return void 0;
|
|
176
|
+
return new Date(observedMs + seconds * 1e3).toISOString();
|
|
177
|
+
}
|
|
178
|
+
function remainingSeconds(resetsAt, now) {
|
|
179
|
+
if (!resetsAt) return void 0;
|
|
180
|
+
const resetMs = Date.parse(resetsAt);
|
|
181
|
+
if (!Number.isFinite(resetMs)) return void 0;
|
|
182
|
+
return Math.max(0, Math.floor((resetMs - now) / 1e3));
|
|
183
|
+
}
|
|
184
|
+
function mergeCodexWindow(id, observation, existing, observedMs) {
|
|
185
|
+
const windowMinutes = _nullishCoalesce(_optionalChain([observation, 'optionalAccess', _ => _.windowMinutes]), () => ( _optionalChain([existing, 'optionalAccess', _2 => _2.windowMinutes])));
|
|
186
|
+
const nextResetAt = _optionalChain([observation, 'optionalAccess', _3 => _3.resetAfterSeconds]) !== void 0 ? resetAt(observedMs, observation.resetAfterSeconds) : _optionalChain([existing, 'optionalAccess', _4 => _4.resetsAt]);
|
|
187
|
+
const hasExistingData = !!existing && (existing.usedPercent !== null || existing.windowMinutes !== void 0 || existing.resetsAt !== void 0);
|
|
188
|
+
return {
|
|
189
|
+
id,
|
|
190
|
+
label: codexLabel(id, windowMinutes),
|
|
191
|
+
scope: "all",
|
|
192
|
+
usedPercent: _nullishCoalesce(_nullishCoalesce(_optionalChain([observation, 'optionalAccess', _5 => _5.usedPercent]), () => ( _optionalChain([existing, 'optionalAccess', _6 => _6.usedPercent]))), () => ( null)),
|
|
193
|
+
windowMinutes,
|
|
194
|
+
resetsAt: nextResetAt,
|
|
195
|
+
remainingSeconds: remainingSeconds(nextResetAt, observedMs),
|
|
196
|
+
state: observation ? "fresh" : hasExistingData ? "stale" : "unavailable"
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
function projectSnapshot(snapshot, now) {
|
|
200
|
+
const expiredAt = snapshot.expiresAt ? Date.parse(snapshot.expiresAt) : Number.POSITIVE_INFINITY;
|
|
201
|
+
const expired = Number.isFinite(expiredAt) && expiredAt <= now;
|
|
202
|
+
return {
|
|
203
|
+
...snapshot,
|
|
204
|
+
windows: snapshot.windows.map((window) => ({
|
|
205
|
+
...window,
|
|
206
|
+
state: expired && window.state === "fresh" ? "stale" : window.state,
|
|
207
|
+
remainingSeconds: remainingSeconds(window.resetsAt, now)
|
|
208
|
+
}))
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
var AccountAllowanceStore = (_class = class {
|
|
212
|
+
constructor(now = Date.now, codexFreshMs = DEFAULT_CODEX_ALLOWANCE_FRESH_MS, persistence, maxSnapshots = DEFAULT_ALLOWANCE_MAX_SNAPSHOTS) {;_class.prototype.__init.call(this);
|
|
213
|
+
this.now = now;
|
|
214
|
+
this.codexFreshMs = codexFreshMs;
|
|
215
|
+
this.persistence = persistence;
|
|
216
|
+
this.maxSnapshots = Number.isFinite(maxSnapshots) && maxSnapshots > 0 ? Math.floor(maxSnapshots) : DEFAULT_ALLOWANCE_MAX_SNAPSHOTS;
|
|
217
|
+
this.loadPersisted();
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+
__init() {this.snapshots = /* @__PURE__ */ new Map()}
|
|
223
|
+
|
|
224
|
+
set(snapshot) {
|
|
225
|
+
const normalized = normalizeAccountAllowanceSnapshot(snapshot);
|
|
226
|
+
if (!normalized) return;
|
|
227
|
+
this.snapshots.set(
|
|
228
|
+
snapshotKey(normalized.providerId, normalized.accountId),
|
|
229
|
+
normalized
|
|
230
|
+
);
|
|
231
|
+
while (this.snapshots.size > this.maxSnapshots) {
|
|
232
|
+
const oldest = this.snapshots.keys().next().value;
|
|
233
|
+
if (oldest === void 0) break;
|
|
234
|
+
this.snapshots.delete(oldest);
|
|
235
|
+
}
|
|
236
|
+
this.persist();
|
|
237
|
+
}
|
|
238
|
+
delete(providerId, accountId) {
|
|
239
|
+
if (this.snapshots.delete(snapshotKey(providerId, accountId))) this.persist();
|
|
240
|
+
}
|
|
241
|
+
/** Remove rows that no longer correspond to a configured account. */
|
|
242
|
+
pruneToKnownAccounts(accounts) {
|
|
243
|
+
const known = /* @__PURE__ */ new Set();
|
|
244
|
+
for (const account of accounts) {
|
|
245
|
+
if (account.accountId) known.add(snapshotKey(account.providerId, account.accountId));
|
|
246
|
+
}
|
|
247
|
+
let removed = 0;
|
|
248
|
+
for (const key of this.snapshots.keys()) {
|
|
249
|
+
if (!known.has(key)) {
|
|
250
|
+
this.snapshots.delete(key);
|
|
251
|
+
removed += 1;
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
if (removed > 0) this.persist();
|
|
255
|
+
return removed;
|
|
256
|
+
}
|
|
257
|
+
get(providerId, accountId, now = this.now()) {
|
|
258
|
+
const snapshot = this.snapshots.get(snapshotKey(providerId, accountId));
|
|
259
|
+
return snapshot ? projectSnapshot(cloneSnapshot(snapshot), now) : null;
|
|
260
|
+
}
|
|
261
|
+
list(filter = {}, now = this.now()) {
|
|
262
|
+
const out = [];
|
|
263
|
+
for (const snapshot of this.snapshots.values()) {
|
|
264
|
+
if (filter.providerId && snapshot.providerId !== filter.providerId) continue;
|
|
265
|
+
if (filter.accountId && snapshot.accountId !== filter.accountId) continue;
|
|
266
|
+
out.push(projectSnapshot(cloneSnapshot(snapshot), now));
|
|
267
|
+
}
|
|
268
|
+
return out.sort(
|
|
269
|
+
(a, b) => a.providerId.localeCompare(b.providerId) || a.accountId.localeCompare(b.accountId)
|
|
270
|
+
);
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
273
|
+
* Merge one real Codex upstream response into the selected account's snapshot.
|
|
274
|
+
* A response with no recognized headers is a strict no-op, and a partial header
|
|
275
|
+
* set preserves previous values while marking untouched windows stale.
|
|
276
|
+
*/
|
|
277
|
+
recordCodexHeaders(accountId, headers, observedMs = this.now()) {
|
|
278
|
+
if (!accountId) return null;
|
|
279
|
+
const observation = parseCodexAllowanceHeaders(headers);
|
|
280
|
+
if (!observation) return this.get("codex", accountId, observedMs);
|
|
281
|
+
const previous = this.snapshots.get(snapshotKey("codex", accountId));
|
|
282
|
+
const previousPrimary = _optionalChain([previous, 'optionalAccess', _7 => _7.source]) === "response-headers" ? previous.windows.find((window) => window.id === "primary") : void 0;
|
|
283
|
+
const previousSecondary = _optionalChain([previous, 'optionalAccess', _8 => _8.source]) === "response-headers" ? previous.windows.find((window) => window.id === "secondary") : void 0;
|
|
284
|
+
const observedAt = new Date(observedMs).toISOString();
|
|
285
|
+
const snapshot = {
|
|
286
|
+
providerId: "codex",
|
|
287
|
+
accountId,
|
|
288
|
+
source: "response-headers",
|
|
289
|
+
observedAt,
|
|
290
|
+
expiresAt: new Date(observedMs + this.codexFreshMs).toISOString(),
|
|
291
|
+
windows: [
|
|
292
|
+
mergeCodexWindow("primary", observation.primary, previousPrimary, observedMs),
|
|
293
|
+
mergeCodexWindow("secondary", observation.secondary, previousSecondary, observedMs)
|
|
294
|
+
],
|
|
295
|
+
primaryOverSecondaryLimitPercent: _nullishCoalesce(observation.primaryOverSecondaryLimitPercent, () => ( _optionalChain([previous, 'optionalAccess', _9 => _9.primaryOverSecondaryLimitPercent])))
|
|
296
|
+
};
|
|
297
|
+
this.set(snapshot);
|
|
298
|
+
return this.get("codex", accountId, observedMs);
|
|
299
|
+
}
|
|
300
|
+
clear() {
|
|
301
|
+
if (this.snapshots.size === 0) return;
|
|
302
|
+
this.snapshots.clear();
|
|
303
|
+
this.persist();
|
|
304
|
+
}
|
|
305
|
+
loadPersisted() {
|
|
306
|
+
if (!this.persistence) return;
|
|
307
|
+
let payload;
|
|
308
|
+
try {
|
|
309
|
+
payload = this.persistence.load();
|
|
310
|
+
} catch (e) {
|
|
311
|
+
return;
|
|
312
|
+
}
|
|
313
|
+
if (!Array.isArray(payload)) return;
|
|
314
|
+
for (const value of payload) {
|
|
315
|
+
const snapshot = normalizeAccountAllowanceSnapshot(value);
|
|
316
|
+
if (!snapshot) continue;
|
|
317
|
+
this.snapshots.set(snapshotKey(snapshot.providerId, snapshot.accountId), snapshot);
|
|
318
|
+
if (this.snapshots.size >= this.maxSnapshots) break;
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
persist() {
|
|
322
|
+
if (!this.persistence) return;
|
|
323
|
+
try {
|
|
324
|
+
this.persistence.save(Array.from(this.snapshots.values(), cloneSnapshot));
|
|
325
|
+
} catch (e2) {
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
}, _class);
|
|
329
|
+
var sharedAllowanceStore = null;
|
|
330
|
+
function getSharedAccountAllowanceStore() {
|
|
331
|
+
if (!sharedAllowanceStore) sharedAllowanceStore = new AccountAllowanceStore();
|
|
332
|
+
return sharedAllowanceStore;
|
|
333
|
+
}
|
|
334
|
+
function setSharedAccountAllowanceStore(store) {
|
|
335
|
+
sharedAllowanceStore = store;
|
|
336
|
+
}
|
|
337
|
+
function __resetSharedAccountAllowanceStoreForTests() {
|
|
338
|
+
sharedAllowanceStore = null;
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
|
|
342
|
+
|
|
343
|
+
|
|
344
|
+
|
|
345
|
+
|
|
346
|
+
|
|
347
|
+
|
|
348
|
+
|
|
349
|
+
|
|
350
|
+
exports.DEFAULT_CODEX_ALLOWANCE_FRESH_MS = DEFAULT_CODEX_ALLOWANCE_FRESH_MS; exports.DEFAULT_ALLOWANCE_MAX_SNAPSHOTS = DEFAULT_ALLOWANCE_MAX_SNAPSHOTS; exports.normalizeAccountAllowanceSnapshot = normalizeAccountAllowanceSnapshot; exports.parseCodexAllowanceHeaders = parseCodexAllowanceHeaders; exports.AccountAllowanceStore = AccountAllowanceStore; exports.getSharedAccountAllowanceStore = getSharedAccountAllowanceStore; exports.setSharedAccountAllowanceStore = setSharedAccountAllowanceStore; exports.__resetSharedAccountAllowanceStoreForTests = __resetSharedAccountAllowanceStoreForTests;
|
|
@@ -134,7 +134,13 @@ var TransformerChainExecutor = class {
|
|
|
134
134
|
const { endpointTransformer } = options;
|
|
135
135
|
const context = {
|
|
136
136
|
logger: this.logger,
|
|
137
|
-
providerName: provider.name
|
|
137
|
+
providerName: provider.name,
|
|
138
|
+
// The unified REQUEST this response answers. Response encoders need it to
|
|
139
|
+
// restore request-scoped protocol state that the chat wire cannot carry —
|
|
140
|
+
// e.g. which codex tools were declared `custom` (see
|
|
141
|
+
// `UnifiedChatRequestMeta.codexTools`), which decides whether a tool call
|
|
142
|
+
// is encoded back as a `function_call` or a `custom_tool_call` item.
|
|
143
|
+
req: request
|
|
138
144
|
};
|
|
139
145
|
let finalResponse = response;
|
|
140
146
|
const bypass = this.shouldBypassTransformers(chain, endpointTransformer, request);
|