@omnicross/core 0.1.6 → 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/auth/GeminiCodeAssistProjectResolver.cjs +4 -3
- package/dist/auth/GeminiCodeAssistProjectResolver.js +3 -2
- package/dist/{chunk-3Z5BQZFM.cjs → chunk-235MXAGX.cjs} +3 -1
- package/dist/{chunk-DLXZEZWO.cjs → chunk-2E42SAW3.cjs} +42 -4
- package/dist/{chunk-7AK7B36B.cjs → chunk-2Z4XM3H5.cjs} +6 -6
- package/dist/{chunk-OEWZUX4G.js → chunk-32O35CIF.js} +9 -20
- package/dist/chunk-3SCOLIPT.cjs +63 -0
- package/dist/{chunk-SYQF7OIR.js → chunk-3WD4HTR2.js} +2 -0
- package/dist/{chunk-SQYVORNP.cjs → chunk-4BB343BI.cjs} +527 -267
- package/dist/{chunk-AT7B7SOZ.js → chunk-5NJLQ6T6.js} +21 -10
- package/dist/chunk-5RSZYQJH.cjs +62 -0
- package/dist/{chunk-IFXJ2BG7.js → chunk-7C7DET6S.js} +51 -6
- package/dist/{chunk-UDCC7EMR.js → chunk-E3COOKUP.js} +307 -47
- package/dist/chunk-FU7EAR73.js +62 -0
- package/dist/{chunk-UX7VWA46.js → chunk-FXR6N3SR.js} +39 -1
- package/dist/{chunk-WYTEQ4Q5.cjs → chunk-GDIXXKF2.cjs} +21 -10
- package/dist/{chunk-WB6PH56J.js → chunk-GFIZ6LQI.js} +12 -8
- package/dist/chunk-GL6XM527.js +61 -0
- package/dist/{chunk-EJLH6NFT.cjs → chunk-J3QQ6JS5.cjs} +12 -8
- package/dist/{chunk-VRFBB5DB.js → chunk-MYYR3HZL.js} +4 -4
- package/dist/{chunk-YJVHCHQX.js → chunk-N7OOJI5V.js} +46 -2
- package/dist/chunk-NKVZ6Z3Y.cjs +61 -0
- package/dist/{chunk-SNYBEXLB.cjs → chunk-OJGQKHN5.cjs} +3 -1
- package/dist/chunk-OTZC4TNH.cjs +79 -0
- package/dist/{chunk-6VUQPOV3.cjs → chunk-OVQBNVSV.cjs} +10 -21
- package/dist/{chunk-4VLRHHFE.cjs → chunk-OXHNSZ53.cjs} +9 -11
- package/dist/{chunk-6CL5HTPQ.js → chunk-PEGTIPB3.js} +8 -10
- package/dist/chunk-PO3XB56Z.js +79 -0
- package/dist/{chunk-SIZQQD6T.js → chunk-RJ5ZGNI3.js} +42 -5
- package/dist/{chunk-KCVJWJST.cjs → chunk-RJUONLUQ.cjs} +47 -10
- package/dist/{chunk-BPKCU575.js → chunk-SOO562NM.js} +3 -1
- package/dist/{chunk-UNWKG6EI.cjs → chunk-XPIOJQS2.cjs} +51 -6
- package/dist/chunk-XXFYLL7R.js +63 -0
- package/dist/{chunk-YK57NMIF.cjs → chunk-YWL7YZWS.cjs} +47 -3
- package/dist/completion/CompletionService.cjs +23 -19
- package/dist/completion/CompletionService.d.cts +1 -0
- package/dist/completion/CompletionService.d.ts +1 -0
- package/dist/completion/CompletionService.js +22 -18
- package/dist/completion.cjs +23 -19
- package/dist/completion.d.cts +1 -0
- package/dist/completion.d.ts +1 -0
- package/dist/completion.js +22 -18
- package/dist/index.cjs +26 -22
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +26 -22
- 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/routeResolver.d.cts +3 -2
- package/dist/outbound-api/routeResolver.d.ts +3 -2
- package/dist/outbound-api/subscriptionRegistryPort.d.cts +1 -0
- package/dist/outbound-api/subscriptionRegistryPort.d.ts +1 -0
- package/dist/outbound-api/types.d.cts +2 -1
- package/dist/outbound-api/types.d.ts +2 -1
- package/dist/outbound-api.cjs +23 -19
- package/dist/outbound-api.d.cts +7 -5
- package/dist/outbound-api.d.ts +7 -5
- package/dist/outbound-api.js +22 -18
- package/dist/pipeline/AccountAllowanceScheduling.d.cts +2 -1
- package/dist/pipeline/AccountAllowanceScheduling.d.ts +2 -1
- 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/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 +4 -2
- package/dist/pipeline/SubscriptionAccountHealth.d.cts +32 -3
- package/dist/pipeline/SubscriptionAccountHealth.d.ts +32 -3
- package/dist/pipeline/SubscriptionAccountHealth.js +3 -1
- package/dist/pipeline/upstreamFetch.cjs +4 -3
- package/dist/pipeline/upstreamFetch.d.cts +35 -6
- package/dist/pipeline/upstreamFetch.d.ts +35 -6
- package/dist/pipeline/upstreamFetch.js +3 -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.d.cts +1 -1
- package/dist/ports.d.ts +1 -1
- package/dist/provider-proxy/ProviderProxy.cjs +23 -19
- package/dist/provider-proxy/ProviderProxy.d.cts +1 -0
- package/dist/provider-proxy/ProviderProxy.d.ts +1 -0
- package/dist/provider-proxy/ProviderProxy.js +22 -18
- 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 +23 -19
- package/dist/provider-proxy/ingress/providerProxyShared.d.cts +11 -1
- package/dist/provider-proxy/ingress/providerProxyShared.d.ts +11 -1
- package/dist/provider-proxy/ingress/providerProxyShared.js +22 -18
- package/dist/provider-proxy/matchText.cjs +2 -2
- package/dist/provider-proxy/matchText.d.cts +1 -3
- package/dist/provider-proxy/matchText.d.ts +1 -3
- package/dist/provider-proxy/matchText.js +1 -1
- package/dist/provider-proxy/types.d.cts +5 -0
- package/dist/provider-proxy/types.d.ts +5 -0
- package/dist/provider-proxy.cjs +23 -19
- package/dist/provider-proxy.d.cts +1 -0
- package/dist/provider-proxy.d.ts +1 -0
- package/dist/provider-proxy.js +22 -18
- package/dist/{routeResolver-CHTv_Bs5.d.ts → routeResolver-BxOfunbm.d.ts} +1 -1
- package/dist/{routeResolver-kepxnfcC.d.cts → routeResolver-D5OzD0iM.d.cts} +1 -1
- package/dist/transformer/transformers/AnthropicTransformer.cjs +3 -2
- package/dist/transformer/transformers/AnthropicTransformer.js +2 -1
- package/dist/transformer/transformers/OpenAIResponseTransformer.cjs +3 -2
- package/dist/transformer/transformers/OpenAIResponseTransformer.js +2 -1
- package/dist/transformer/transformers.cjs +7 -6
- package/dist/transformer/transformers.js +6 -5
- package/dist/transformer.cjs +9 -8
- package/dist/transformer.js +8 -7
- package/dist/{types-hsoKrVQS.d.ts → types-CqZD77rS.d.ts} +39 -0
- package/dist/{types-H3wGZSOo.d.cts → types-gjJ5lJ5n.d.cts} +39 -0
- package/dist/usage/pricing-engine.cjs +2 -2
- package/dist/usage/pricing-engine.d.cts +20 -0
- package/dist/usage/pricing-engine.d.ts +20 -0
- 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
|
@@ -1,4 +1,8 @@
|
|
|
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
|
|
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;
|
|
2
|
+
|
|
3
|
+
var _chunk5RSZYQJHcjs = require('./chunk-5RSZYQJH.cjs');
|
|
4
|
+
|
|
5
|
+
// src/transformer/transformers/AnthropicToolHandling.ts
|
|
2
6
|
function isServerSideTool(tool) {
|
|
3
7
|
const type = String(tool.type || "");
|
|
4
8
|
return type.startsWith("web_search_") || type.startsWith("code_execution_") || type.startsWith("text_editor_") || type.startsWith("memory_") || type.startsWith("web_fetch_") || type.startsWith("search_tool_");
|
|
@@ -261,11 +265,9 @@ ${formatted}`);
|
|
|
261
265
|
message,
|
|
262
266
|
finish_reason: stopReasonMapping[anthropicResponse.stop_reason] || "stop"
|
|
263
267
|
}],
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
total_tokens: (usage.input_tokens || 0) + (usage.output_tokens || 0)
|
|
268
|
-
} : void 0
|
|
268
|
+
// Preserve prompt-cache counts (cache-read → prompt_tokens_details.cached_tokens,
|
|
269
|
+
// cache-creation folded into prompt_tokens) instead of dropping them.
|
|
270
|
+
usage: _chunk5RSZYQJHcjs.anthropicUsageToChatUsage.call(void 0, usage)
|
|
269
271
|
};
|
|
270
272
|
}
|
|
271
273
|
function convertOpenAIResponseToAnthropic(openaiResponse) {
|
|
@@ -619,11 +621,7 @@ ${formatted}` },
|
|
|
619
621
|
}]
|
|
620
622
|
};
|
|
621
623
|
if (event.usage) {
|
|
622
|
-
chunk.usage =
|
|
623
|
-
prompt_tokens: event.usage.input_tokens || 0,
|
|
624
|
-
completion_tokens: event.usage.output_tokens || 0,
|
|
625
|
-
total_tokens: (event.usage.input_tokens || 0) + (event.usage.output_tokens || 0)
|
|
626
|
-
};
|
|
624
|
+
chunk.usage = _chunk5RSZYQJHcjs.anthropicUsageToChatUsage.call(void 0, event.usage);
|
|
627
625
|
}
|
|
628
626
|
safeEnqueue(`data: ${JSON.stringify(chunk)}
|
|
629
627
|
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
import {
|
|
2
|
+
anthropicUsageToChatUsage
|
|
3
|
+
} from "./chunk-FU7EAR73.js";
|
|
4
|
+
|
|
1
5
|
// src/transformer/transformers/AnthropicToolHandling.ts
|
|
2
6
|
function isServerSideTool(tool) {
|
|
3
7
|
const type = String(tool.type || "");
|
|
@@ -261,11 +265,9 @@ ${formatted}`);
|
|
|
261
265
|
message,
|
|
262
266
|
finish_reason: stopReasonMapping[anthropicResponse.stop_reason] || "stop"
|
|
263
267
|
}],
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
total_tokens: (usage.input_tokens || 0) + (usage.output_tokens || 0)
|
|
268
|
-
} : void 0
|
|
268
|
+
// Preserve prompt-cache counts (cache-read → prompt_tokens_details.cached_tokens,
|
|
269
|
+
// cache-creation folded into prompt_tokens) instead of dropping them.
|
|
270
|
+
usage: anthropicUsageToChatUsage(usage)
|
|
269
271
|
};
|
|
270
272
|
}
|
|
271
273
|
function convertOpenAIResponseToAnthropic(openaiResponse) {
|
|
@@ -619,11 +621,7 @@ ${formatted}` },
|
|
|
619
621
|
}]
|
|
620
622
|
};
|
|
621
623
|
if (event.usage) {
|
|
622
|
-
chunk.usage =
|
|
623
|
-
prompt_tokens: event.usage.input_tokens || 0,
|
|
624
|
-
completion_tokens: event.usage.output_tokens || 0,
|
|
625
|
-
total_tokens: (event.usage.input_tokens || 0) + (event.usage.output_tokens || 0)
|
|
626
|
-
};
|
|
624
|
+
chunk.usage = anthropicUsageToChatUsage(event.usage);
|
|
627
625
|
}
|
|
628
626
|
safeEnqueue(`data: ${JSON.stringify(chunk)}
|
|
629
627
|
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
// src/pipeline/ServerOverloadCounter.ts
|
|
2
|
+
var OVERLOAD_RECENT_LIMIT = 64;
|
|
3
|
+
var OVERLOAD_ENTRY_TTL_MS = 24 * 60 * 6e4;
|
|
4
|
+
function entryKey(providerId, accountId, endpoint) {
|
|
5
|
+
return `${providerId}\0${accountId}\0${endpoint}`;
|
|
6
|
+
}
|
|
7
|
+
var ServerOverloadCounterStore = class {
|
|
8
|
+
entries = /* @__PURE__ */ new Map();
|
|
9
|
+
/**
|
|
10
|
+
* Record one overload event. Creates the entry on first sight, then bumps
|
|
11
|
+
* `count`, `lastTs`, and prepends the event to the bounded `recent` ring.
|
|
12
|
+
*/
|
|
13
|
+
recordOverload(input, now = Date.now()) {
|
|
14
|
+
const key = entryKey(input.providerId, input.accountId, input.endpoint);
|
|
15
|
+
const existing = this.entries.get(key);
|
|
16
|
+
if (existing) {
|
|
17
|
+
existing.count += 1;
|
|
18
|
+
existing.lastTs = now;
|
|
19
|
+
existing.recent.unshift(now);
|
|
20
|
+
if (existing.recent.length > OVERLOAD_RECENT_LIMIT) {
|
|
21
|
+
existing.recent.length = OVERLOAD_RECENT_LIMIT;
|
|
22
|
+
}
|
|
23
|
+
return { ...existing, recent: [...existing.recent] };
|
|
24
|
+
}
|
|
25
|
+
const entry = {
|
|
26
|
+
providerId: input.providerId,
|
|
27
|
+
accountId: input.accountId,
|
|
28
|
+
endpoint: input.endpoint,
|
|
29
|
+
count: 1,
|
|
30
|
+
firstTs: now,
|
|
31
|
+
lastTs: now,
|
|
32
|
+
recent: [now]
|
|
33
|
+
};
|
|
34
|
+
this.entries.set(key, entry);
|
|
35
|
+
return { ...entry, recent: [...entry.recent] };
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Snapshot all (optionally filtered) entries, pruning stale ones first. Returns
|
|
39
|
+
* copies — callers (admin API → JSON) never see the live mutable entries.
|
|
40
|
+
*/
|
|
41
|
+
list(query = {}, now = Date.now()) {
|
|
42
|
+
const providerId = query.providerId?.trim();
|
|
43
|
+
const accountId = query.accountId?.trim();
|
|
44
|
+
const out = [];
|
|
45
|
+
for (const [key, entry] of this.entries) {
|
|
46
|
+
if (now - entry.lastTs > OVERLOAD_ENTRY_TTL_MS) {
|
|
47
|
+
this.entries.delete(key);
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
50
|
+
if (providerId && entry.providerId !== providerId) continue;
|
|
51
|
+
if (accountId && entry.accountId !== accountId) continue;
|
|
52
|
+
out.push({ ...entry, recent: [...entry.recent] });
|
|
53
|
+
}
|
|
54
|
+
return out;
|
|
55
|
+
}
|
|
56
|
+
clear() {
|
|
57
|
+
this.entries.clear();
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
var sharedStore = null;
|
|
61
|
+
function getSharedOverloadCounter() {
|
|
62
|
+
if (!sharedStore) sharedStore = new ServerOverloadCounterStore();
|
|
63
|
+
return sharedStore;
|
|
64
|
+
}
|
|
65
|
+
function setSharedOverloadCounter(instance) {
|
|
66
|
+
sharedStore = instance;
|
|
67
|
+
}
|
|
68
|
+
function __resetSharedOverloadCounterForTests() {
|
|
69
|
+
sharedStore = null;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export {
|
|
73
|
+
OVERLOAD_RECENT_LIMIT,
|
|
74
|
+
OVERLOAD_ENTRY_TTL_MS,
|
|
75
|
+
ServerOverloadCounterStore,
|
|
76
|
+
getSharedOverloadCounter,
|
|
77
|
+
setSharedOverloadCounter,
|
|
78
|
+
__resetSharedOverloadCounterForTests
|
|
79
|
+
};
|
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
import {
|
|
2
|
+
REDACTED_BODY,
|
|
2
3
|
getUpstreamTracePath,
|
|
3
4
|
redactHeaders,
|
|
4
5
|
writeUpstreamTrace
|
|
5
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-3WD4HTR2.js";
|
|
6
7
|
import {
|
|
7
8
|
getSharedAccountAllowanceStore
|
|
8
9
|
} from "./chunk-MKF46GNZ.js";
|
|
10
|
+
import {
|
|
11
|
+
getSharedAccountRouteActivity
|
|
12
|
+
} from "./chunk-GL6XM527.js";
|
|
9
13
|
|
|
10
14
|
// src/pipeline/upstreamFetch.ts
|
|
11
15
|
import { Agent, buildConnector, ProxyAgent } from "undici";
|
|
@@ -114,17 +118,48 @@ function fetchUpstream(url, init, ctx) {
|
|
|
114
118
|
}
|
|
115
119
|
return response;
|
|
116
120
|
});
|
|
121
|
+
const activity = ctx?.routeActivity;
|
|
122
|
+
const activityStartedAt = activity && ctx?.providerId && ctx.accountId ? Date.now() : 0;
|
|
123
|
+
const recordActivity = (status) => {
|
|
124
|
+
if (!activity || !ctx?.providerId || !ctx.accountId) return;
|
|
125
|
+
const record = getSharedAccountRouteActivity().record({
|
|
126
|
+
providerId: ctx.providerId,
|
|
127
|
+
accountId: ctx.accountId,
|
|
128
|
+
endpoint: activity.endpoint,
|
|
129
|
+
sessionKey: activity.sessionKey,
|
|
130
|
+
sessionSource: activity.sessionSource,
|
|
131
|
+
model: activity.model,
|
|
132
|
+
status,
|
|
133
|
+
durationMs: Math.max(0, Date.now() - activityStartedAt),
|
|
134
|
+
ts: activityStartedAt
|
|
135
|
+
});
|
|
136
|
+
try {
|
|
137
|
+
activity.onRecorded?.(record);
|
|
138
|
+
} catch {
|
|
139
|
+
}
|
|
140
|
+
};
|
|
141
|
+
const doFetchWithActivity = () => doFetchWithAllowanceTap().then(
|
|
142
|
+
(response) => {
|
|
143
|
+
recordActivity(response.status);
|
|
144
|
+
return response;
|
|
145
|
+
},
|
|
146
|
+
(error) => {
|
|
147
|
+
recordActivity(0);
|
|
148
|
+
throw error;
|
|
149
|
+
}
|
|
150
|
+
);
|
|
117
151
|
const tracePath = getUpstreamTracePath();
|
|
118
|
-
if (!tracePath || !ctx?.providerId) return
|
|
152
|
+
if (!tracePath || !ctx?.providerId) return doFetchWithActivity();
|
|
119
153
|
const startedAt = Date.now();
|
|
120
154
|
const method = typeof init.method === "string" ? init.method : "GET";
|
|
121
155
|
const requestHeaders = redactHeaders(
|
|
122
156
|
init.headers
|
|
123
157
|
);
|
|
124
|
-
const
|
|
158
|
+
const redactBodies = ctx.redactBodies === true;
|
|
159
|
+
const requestBody = redactBodies ? REDACTED_BODY : typeof init.body === "string" ? init.body : null;
|
|
125
160
|
const providerId = ctx.providerId;
|
|
126
161
|
const accountId = ctx.accountId;
|
|
127
|
-
return
|
|
162
|
+
return doFetchWithActivity().then((res) => {
|
|
128
163
|
const clone = res.clone();
|
|
129
164
|
const status = res.status;
|
|
130
165
|
const statusText = res.statusText;
|
|
@@ -142,7 +177,9 @@ function fetchUpstream(url, init, ctx) {
|
|
|
142
177
|
status,
|
|
143
178
|
statusText,
|
|
144
179
|
responseHeaders,
|
|
145
|
-
|
|
180
|
+
// The byte count stays REAL even when redacted — it is a useful
|
|
181
|
+
// diagnostic and reveals nothing about the token itself.
|
|
182
|
+
responseBody: redactBodies ? REDACTED_BODY : body,
|
|
146
183
|
responseBytes: Buffer.byteLength(body, "utf8")
|
|
147
184
|
});
|
|
148
185
|
}).catch(() => {
|
|
@@ -2,11 +2,15 @@
|
|
|
2
2
|
|
|
3
3
|
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
|
|
6
|
+
var _chunk235MXAGXcjs = require('./chunk-235MXAGX.cjs');
|
|
6
7
|
|
|
7
8
|
|
|
8
9
|
var _chunkHVBBDBS3cjs = require('./chunk-HVBBDBS3.cjs');
|
|
9
10
|
|
|
11
|
+
|
|
12
|
+
var _chunkNKVZ6Z3Ycjs = require('./chunk-NKVZ6Z3Y.cjs');
|
|
13
|
+
|
|
10
14
|
// src/pipeline/upstreamFetch.ts
|
|
11
15
|
var _undici = require('undici');
|
|
12
16
|
var _socks = require('socks');
|
|
@@ -114,23 +118,54 @@ function fetchUpstream(url, init, ctx) {
|
|
|
114
118
|
}
|
|
115
119
|
return response;
|
|
116
120
|
});
|
|
117
|
-
const
|
|
118
|
-
|
|
121
|
+
const activity = _optionalChain([ctx, 'optionalAccess', _4 => _4.routeActivity]);
|
|
122
|
+
const activityStartedAt = activity && _optionalChain([ctx, 'optionalAccess', _5 => _5.providerId]) && ctx.accountId ? Date.now() : 0;
|
|
123
|
+
const recordActivity = (status) => {
|
|
124
|
+
if (!activity || !_optionalChain([ctx, 'optionalAccess', _6 => _6.providerId]) || !ctx.accountId) return;
|
|
125
|
+
const record = _chunkNKVZ6Z3Ycjs.getSharedAccountRouteActivity.call(void 0, ).record({
|
|
126
|
+
providerId: ctx.providerId,
|
|
127
|
+
accountId: ctx.accountId,
|
|
128
|
+
endpoint: activity.endpoint,
|
|
129
|
+
sessionKey: activity.sessionKey,
|
|
130
|
+
sessionSource: activity.sessionSource,
|
|
131
|
+
model: activity.model,
|
|
132
|
+
status,
|
|
133
|
+
durationMs: Math.max(0, Date.now() - activityStartedAt),
|
|
134
|
+
ts: activityStartedAt
|
|
135
|
+
});
|
|
136
|
+
try {
|
|
137
|
+
_optionalChain([activity, 'access', _7 => _7.onRecorded, 'optionalCall', _8 => _8(record)]);
|
|
138
|
+
} catch (e5) {
|
|
139
|
+
}
|
|
140
|
+
};
|
|
141
|
+
const doFetchWithActivity = () => doFetchWithAllowanceTap().then(
|
|
142
|
+
(response) => {
|
|
143
|
+
recordActivity(response.status);
|
|
144
|
+
return response;
|
|
145
|
+
},
|
|
146
|
+
(error) => {
|
|
147
|
+
recordActivity(0);
|
|
148
|
+
throw error;
|
|
149
|
+
}
|
|
150
|
+
);
|
|
151
|
+
const tracePath = _chunk235MXAGXcjs.getUpstreamTracePath.call(void 0, );
|
|
152
|
+
if (!tracePath || !_optionalChain([ctx, 'optionalAccess', _9 => _9.providerId])) return doFetchWithActivity();
|
|
119
153
|
const startedAt = Date.now();
|
|
120
154
|
const method = typeof init.method === "string" ? init.method : "GET";
|
|
121
|
-
const requestHeaders =
|
|
155
|
+
const requestHeaders = _chunk235MXAGXcjs.redactHeaders.call(void 0,
|
|
122
156
|
init.headers
|
|
123
157
|
);
|
|
124
|
-
const
|
|
158
|
+
const redactBodies = ctx.redactBodies === true;
|
|
159
|
+
const requestBody = redactBodies ? _chunk235MXAGXcjs.REDACTED_BODY : typeof init.body === "string" ? init.body : null;
|
|
125
160
|
const providerId = ctx.providerId;
|
|
126
161
|
const accountId = ctx.accountId;
|
|
127
|
-
return
|
|
162
|
+
return doFetchWithActivity().then((res) => {
|
|
128
163
|
const clone = res.clone();
|
|
129
164
|
const status = res.status;
|
|
130
165
|
const statusText = res.statusText;
|
|
131
|
-
const responseHeaders =
|
|
166
|
+
const responseHeaders = _chunk235MXAGXcjs.redactHeaders.call(void 0, res.headers);
|
|
132
167
|
void clone.text().then((body) => {
|
|
133
|
-
|
|
168
|
+
_chunk235MXAGXcjs.writeUpstreamTrace.call(void 0, {
|
|
134
169
|
ts: startedAt,
|
|
135
170
|
durationMs: Date.now() - startedAt,
|
|
136
171
|
providerId,
|
|
@@ -142,7 +177,9 @@ function fetchUpstream(url, init, ctx) {
|
|
|
142
177
|
status,
|
|
143
178
|
statusText,
|
|
144
179
|
responseHeaders,
|
|
145
|
-
|
|
180
|
+
// The byte count stays REAL even when redacted — it is a useful
|
|
181
|
+
// diagnostic and reveals nothing about the token itself.
|
|
182
|
+
responseBody: redactBodies ? _chunk235MXAGXcjs.REDACTED_BODY : body,
|
|
146
183
|
responseBytes: Buffer.byteLength(body, "utf8")
|
|
147
184
|
});
|
|
148
185
|
}).catch(() => {
|
|
@@ -150,7 +187,7 @@ function fetchUpstream(url, init, ctx) {
|
|
|
150
187
|
return res;
|
|
151
188
|
}).catch((err) => {
|
|
152
189
|
const msg = err instanceof Error ? err.message : String(err);
|
|
153
|
-
|
|
190
|
+
_chunk235MXAGXcjs.writeUpstreamTrace.call(void 0, {
|
|
154
191
|
ts: startedAt,
|
|
155
192
|
durationMs: Date.now() - startedAt,
|
|
156
193
|
providerId,
|
|
@@ -78,7 +78,9 @@ var UsageRecorder = class {
|
|
|
78
78
|
costSavedByCacheUsd,
|
|
79
79
|
rawUsage: input.rawUsage != null ? safeStringify(input.rawUsage) : null,
|
|
80
80
|
runId: input.runId ?? null,
|
|
81
|
-
eventId: input.eventId ?? null
|
|
81
|
+
eventId: input.eventId ?? null,
|
|
82
|
+
...input.cacheKeySource !== void 0 ? { cacheKeySource: input.cacheKeySource } : {},
|
|
83
|
+
...input.cacheKeyInjected !== void 0 ? { cacheKeyInjected: input.cacheKeyInjected } : {}
|
|
82
84
|
};
|
|
83
85
|
try {
|
|
84
86
|
return await this.store.insert(row);
|
|
@@ -11,6 +11,29 @@ var _chunkXSVNC2UDcjs = require('./chunk-XSVNC2UD.cjs');
|
|
|
11
11
|
|
|
12
12
|
// src/outbound-api/auditCapture.ts
|
|
13
13
|
var _crypto = require('crypto');
|
|
14
|
+
function completeUtf8PrefixLength(buf) {
|
|
15
|
+
if (buf.length === 0) return 0;
|
|
16
|
+
let leadIndex = buf.length - 1;
|
|
17
|
+
while (leadIndex >= 0 && (buf[leadIndex] & 192) === 128) leadIndex -= 1;
|
|
18
|
+
if (leadIndex < 0) return 0;
|
|
19
|
+
const lead = buf[leadIndex];
|
|
20
|
+
let expectedLength = 1;
|
|
21
|
+
if ((lead & 224) === 192) expectedLength = 2;
|
|
22
|
+
else if ((lead & 240) === 224) expectedLength = 3;
|
|
23
|
+
else if ((lead & 248) === 240) expectedLength = 4;
|
|
24
|
+
return buf.length - leadIndex < expectedLength ? leadIndex : buf.length;
|
|
25
|
+
}
|
|
26
|
+
function truncateToBytes(text, maxBytes) {
|
|
27
|
+
if (maxBytes < 0) return text;
|
|
28
|
+
const buf = Buffer.from(text, "utf8");
|
|
29
|
+
if (buf.length <= maxBytes) return text;
|
|
30
|
+
const head = buf.subarray(0, maxBytes);
|
|
31
|
+
return head.subarray(0, completeUtf8PrefixLength(head)).toString("utf8");
|
|
32
|
+
}
|
|
33
|
+
function decodeCapturedBody(body, truncated) {
|
|
34
|
+
if (!truncated) return body.toString("utf8");
|
|
35
|
+
return body.subarray(0, completeUtf8PrefixLength(body)).toString("utf8");
|
|
36
|
+
}
|
|
14
37
|
function resolveClientIp(req, trustForwardedFor) {
|
|
15
38
|
if (trustForwardedFor) {
|
|
16
39
|
const xff = req.headers["x-forwarded-for"];
|
|
@@ -25,18 +48,39 @@ function resolveClientIp(req, trustForwardedFor) {
|
|
|
25
48
|
function beginAuditCapture(req, res, now) {
|
|
26
49
|
const config = _chunkAEOZIDEBcjs.getAuditCaptureConfig.call(void 0, );
|
|
27
50
|
if (!config) return null;
|
|
28
|
-
let
|
|
51
|
+
let requestBody;
|
|
29
52
|
const responseChunks = [];
|
|
53
|
+
let responseBytes = 0;
|
|
54
|
+
let responseTruncated = false;
|
|
30
55
|
let finished = false;
|
|
31
56
|
const ctx = {
|
|
32
57
|
setRequestBody(raw) {
|
|
33
|
-
if (config.captureBodies)
|
|
58
|
+
if (config.captureBodies) {
|
|
59
|
+
requestBody = truncateToBytes(_chunkFCR77GYMcjs.redactAuditText.call(void 0, raw), config.maxBodyBytes);
|
|
60
|
+
}
|
|
34
61
|
}
|
|
35
62
|
};
|
|
36
63
|
if (config.captureBodies) {
|
|
37
64
|
installResponseCapture(res, {
|
|
38
65
|
push(chunk) {
|
|
66
|
+
if (config.maxBodyBytes < 0) {
|
|
67
|
+
responseChunks.push(chunk);
|
|
68
|
+
responseBytes += chunk.length;
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
const remaining = config.maxBodyBytes - responseBytes;
|
|
72
|
+
if (remaining <= 0) {
|
|
73
|
+
responseTruncated = true;
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
if (chunk.length > remaining) {
|
|
77
|
+
responseChunks.push(chunk.subarray(0, remaining));
|
|
78
|
+
responseBytes += remaining;
|
|
79
|
+
responseTruncated = true;
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
39
82
|
responseChunks.push(chunk);
|
|
83
|
+
responseBytes += chunk.length;
|
|
40
84
|
}
|
|
41
85
|
});
|
|
42
86
|
}
|
|
@@ -69,12 +113,13 @@ function beginAuditCapture(req, res, now) {
|
|
|
69
113
|
}
|
|
70
114
|
if (ctx.error) record.error = _chunkFCR77GYMcjs.redactAuditText.call(void 0, ctx.error);
|
|
71
115
|
if (config.captureBodies) {
|
|
72
|
-
if (
|
|
73
|
-
record.requestBody =
|
|
116
|
+
if (requestBody != null && requestBody.length > 0) {
|
|
117
|
+
record.requestBody = requestBody;
|
|
74
118
|
}
|
|
75
119
|
if (responseChunks.length > 0) {
|
|
76
|
-
const
|
|
77
|
-
|
|
120
|
+
const captured = Buffer.concat(responseChunks, responseBytes);
|
|
121
|
+
const body = decodeCapturedBody(captured, responseTruncated);
|
|
122
|
+
record.responseBody = truncateToBytes(_chunkFCR77GYMcjs.redactAuditText.call(void 0, body), config.maxBodyBytes);
|
|
78
123
|
}
|
|
79
124
|
}
|
|
80
125
|
_chunkAEOZIDEBcjs.recordAudit.call(void 0, record);
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
// src/provider-proxy/identity/headerMerge.ts
|
|
2
|
+
function fillMissingHeaders(headers, source) {
|
|
3
|
+
const present = new Set(Object.keys(headers).map((k) => k.toLowerCase()));
|
|
4
|
+
for (const [key, value] of Object.entries(source)) {
|
|
5
|
+
const lower = key.toLowerCase();
|
|
6
|
+
if (present.has(lower)) continue;
|
|
7
|
+
headers[lower] = value;
|
|
8
|
+
present.add(lower);
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
function flattenHeaderValue(raw) {
|
|
12
|
+
if (raw === void 0) return void 0;
|
|
13
|
+
const value = Array.isArray(raw) ? raw.filter((v) => typeof v === "string").join(", ") : raw;
|
|
14
|
+
return typeof value === "string" && value.length > 0 ? value : void 0;
|
|
15
|
+
}
|
|
16
|
+
var NEVER_FORWARD_HEADERS = /* @__PURE__ */ new Set([
|
|
17
|
+
"authorization",
|
|
18
|
+
"x-api-key",
|
|
19
|
+
"cookie",
|
|
20
|
+
"proxy-authorization",
|
|
21
|
+
"host",
|
|
22
|
+
"connection",
|
|
23
|
+
"content-length",
|
|
24
|
+
"content-type",
|
|
25
|
+
"accept-encoding"
|
|
26
|
+
]);
|
|
27
|
+
|
|
28
|
+
// src/provider-proxy/identity/codexCliHeaders.ts
|
|
29
|
+
var DEFAULT_CODEX_CLI_HEADERS = Object.freeze({
|
|
30
|
+
originator: "codex_cli_rs",
|
|
31
|
+
"user-agent": "codex_cli_rs/0.144.5",
|
|
32
|
+
version: "0.144.5"
|
|
33
|
+
});
|
|
34
|
+
var CODEX_FORWARD_ALLOWLIST = /* @__PURE__ */ new Set([
|
|
35
|
+
"version",
|
|
36
|
+
"openai-beta",
|
|
37
|
+
"session_id",
|
|
38
|
+
"originator",
|
|
39
|
+
"user-agent"
|
|
40
|
+
]);
|
|
41
|
+
function extractCodexClientHeaders(reqHeaders) {
|
|
42
|
+
const out = {};
|
|
43
|
+
for (const [rawKey, rawVal] of Object.entries(reqHeaders)) {
|
|
44
|
+
const key = rawKey.toLowerCase();
|
|
45
|
+
if (NEVER_FORWARD_HEADERS.has(key)) continue;
|
|
46
|
+
if (!CODEX_FORWARD_ALLOWLIST.has(key)) continue;
|
|
47
|
+
const value = flattenHeaderValue(rawVal);
|
|
48
|
+
if (value !== void 0) out[key] = value;
|
|
49
|
+
}
|
|
50
|
+
return out;
|
|
51
|
+
}
|
|
52
|
+
function codexAcceptHeader(isStream) {
|
|
53
|
+
return isStream ? "text/event-stream" : "application/json";
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export {
|
|
57
|
+
fillMissingHeaders,
|
|
58
|
+
flattenHeaderValue,
|
|
59
|
+
NEVER_FORWARD_HEADERS,
|
|
60
|
+
DEFAULT_CODEX_CLI_HEADERS,
|
|
61
|
+
extractCodexClientHeaders,
|
|
62
|
+
codexAcceptHeader
|
|
63
|
+
};
|
|
@@ -3,6 +3,7 @@ var OVERLOAD_TTL_MS = 10 * 6e4;
|
|
|
3
3
|
var OVERLOAD_ENABLED_DEFAULT = true;
|
|
4
4
|
var AUTH_ERROR_TTL_MS = 30 * 6e4;
|
|
5
5
|
var SERVER_ERROR_TTL_MS = 5 * 6e4;
|
|
6
|
+
var MAX_QUOTA_COOLDOWN_MS = 7 * 24 * 60 * 6e4;
|
|
6
7
|
var BAN_BODY_MARKERS = [
|
|
7
8
|
"this organization has been disabled",
|
|
8
9
|
"oauth authentication is currently not allowed"
|
|
@@ -38,7 +39,7 @@ function isBanBody(bodyText) {
|
|
|
38
39
|
return BAN_BODY_MARKERS.some((marker) => lower.includes(marker));
|
|
39
40
|
}
|
|
40
41
|
function isRecordEmpty(record) {
|
|
41
|
-
return record.rateLimitEndAt === void 0 && record.overloadUntil === void 0 && record.tempUnavailableUntil === void 0 && !record.blocked;
|
|
42
|
+
return record.rateLimitEndAt === void 0 && record.overloadUntil === void 0 && record.tempUnavailableUntil === void 0 && record.quotaExhaustedUntil === void 0 && !record.blocked;
|
|
42
43
|
}
|
|
43
44
|
var KEY_SEP = "\0";
|
|
44
45
|
var SubscriptionAccountHealth = (_class = class {
|
|
@@ -159,12 +160,47 @@ var SubscriptionAccountHealth = (_class = class {
|
|
|
159
160
|
this.emitAnomaly(anomaly);
|
|
160
161
|
}
|
|
161
162
|
}
|
|
163
|
+
/**
|
|
164
|
+
* Mark an account quota/usage-exhausted until `untilEpochMs` (the Codex weekly
|
|
165
|
+
* usage-limit wall). Unlike the status-driven timers set by
|
|
166
|
+
* {@link recordUpstreamOutcome}, this mark is NOT cleared by a 2xx: in-flight
|
|
167
|
+
* sessions on the same account keep succeeding after the window is exhausted,
|
|
168
|
+
* so a traffic-driven clear would re-strand every NEW session onto this
|
|
169
|
+
* account. It excludes the account from NEW-session selection until the
|
|
170
|
+
* deadline elapses (existing sessions are unaffected — they already hold their
|
|
171
|
+
* token). Self-heals lazily on read and via {@link sweepRecoveries}.
|
|
172
|
+
* `untilEpochMs` is clamped to {@link MAX_QUOTA_COOLDOWN_MS}; an already-elapsed
|
|
173
|
+
* deadline is a no-op. Emits a `quota_exhausted` anomaly on the healthy→
|
|
174
|
+
* unhealthy edge.
|
|
175
|
+
*/
|
|
176
|
+
markQuotaExhausted(providerId, accountId, untilEpochMs, now = this.now()) {
|
|
177
|
+
if (!Number.isFinite(untilEpochMs)) return;
|
|
178
|
+
const clamped = Math.min(untilEpochMs, now + MAX_QUOTA_COOLDOWN_MS);
|
|
179
|
+
if (clamped <= now) return;
|
|
180
|
+
const key = this.key(providerId, accountId);
|
|
181
|
+
const preExisting = this.records.get(key);
|
|
182
|
+
const record = _nullishCoalesce(preExisting, () => ( {}));
|
|
183
|
+
const wasUnhealthyBefore = preExisting ? this.isUnhealthyAt(preExisting, now) : false;
|
|
184
|
+
record.quotaExhaustedUntil = clamped;
|
|
185
|
+
this.records.set(key, record);
|
|
186
|
+
if (!wasUnhealthyBefore) {
|
|
187
|
+
const anomaly = {
|
|
188
|
+
providerId,
|
|
189
|
+
accountId,
|
|
190
|
+
at: now,
|
|
191
|
+
state: "quota_exhausted"
|
|
192
|
+
};
|
|
193
|
+
this.recordDiagnostic({ kind: "health-anomaly", ...anomaly });
|
|
194
|
+
this.emitAnomaly(anomaly);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
162
197
|
/** Whether a record is unhealthy at `now`: blocked, or any timer still future. */
|
|
163
198
|
isUnhealthyAt(record, now) {
|
|
164
199
|
if (record.blocked) return true;
|
|
165
200
|
if (record.rateLimitEndAt !== void 0 && now < record.rateLimitEndAt) return true;
|
|
166
201
|
if (record.overloadUntil !== void 0 && now < record.overloadUntil) return true;
|
|
167
202
|
if (record.tempUnavailableUntil !== void 0 && now < record.tempUnavailableUntil) return true;
|
|
203
|
+
if (record.quotaExhaustedUntil !== void 0 && now < record.quotaExhaustedUntil) return true;
|
|
168
204
|
return false;
|
|
169
205
|
}
|
|
170
206
|
/**
|
|
@@ -201,7 +237,7 @@ var SubscriptionAccountHealth = (_class = class {
|
|
|
201
237
|
const recovered = [];
|
|
202
238
|
for (const [key, record] of this.records) {
|
|
203
239
|
if (record.blocked) continue;
|
|
204
|
-
const hadTimer = record.rateLimitEndAt !== void 0 || record.overloadUntil !== void 0 || record.tempUnavailableUntil !== void 0;
|
|
240
|
+
const hadTimer = record.rateLimitEndAt !== void 0 || record.overloadUntil !== void 0 || record.tempUnavailableUntil !== void 0 || record.quotaExhaustedUntil !== void 0;
|
|
205
241
|
const active = this.clearExpired(record, now);
|
|
206
242
|
if (hadTimer && !active && isRecordEmpty(record)) {
|
|
207
243
|
const [pid, aid] = this.parseKey(key);
|
|
@@ -225,6 +261,9 @@ var SubscriptionAccountHealth = (_class = class {
|
|
|
225
261
|
const record = this.records.get(this.key(providerId, accountId));
|
|
226
262
|
if (!record) return { state: "healthy" };
|
|
227
263
|
if (record.blocked) return { state: "blocked" };
|
|
264
|
+
if (record.quotaExhaustedUntil !== void 0 && now < record.quotaExhaustedUntil) {
|
|
265
|
+
return { state: "quota_exhausted", cooldownUntil: record.quotaExhaustedUntil };
|
|
266
|
+
}
|
|
228
267
|
if (record.rateLimitEndAt !== void 0 && now < record.rateLimitEndAt) {
|
|
229
268
|
return { state: "rate_limited", cooldownUntil: record.rateLimitEndAt };
|
|
230
269
|
}
|
|
@@ -311,6 +350,10 @@ var SubscriptionAccountHealth = (_class = class {
|
|
|
311
350
|
if (now >= record.tempUnavailableUntil) delete record.tempUnavailableUntil;
|
|
312
351
|
else active = true;
|
|
313
352
|
}
|
|
353
|
+
if (record.quotaExhaustedUntil !== void 0) {
|
|
354
|
+
if (now >= record.quotaExhaustedUntil) delete record.quotaExhaustedUntil;
|
|
355
|
+
else active = true;
|
|
356
|
+
}
|
|
314
357
|
return active;
|
|
315
358
|
}
|
|
316
359
|
key(providerId, accountId) {
|
|
@@ -344,4 +387,5 @@ function __resetSharedAccountHealthForTests() {
|
|
|
344
387
|
|
|
345
388
|
|
|
346
389
|
|
|
347
|
-
|
|
390
|
+
|
|
391
|
+
exports.OVERLOAD_TTL_MS = OVERLOAD_TTL_MS; exports.OVERLOAD_ENABLED_DEFAULT = OVERLOAD_ENABLED_DEFAULT; exports.AUTH_ERROR_TTL_MS = AUTH_ERROR_TTL_MS; exports.SERVER_ERROR_TTL_MS = SERVER_ERROR_TTL_MS; exports.MAX_QUOTA_COOLDOWN_MS = MAX_QUOTA_COOLDOWN_MS; exports.ACCOUNT_HEALTH_DIAGNOSTIC_LIMIT = ACCOUNT_HEALTH_DIAGNOSTIC_LIMIT; exports.resolveResetSeconds = resolveResetSeconds; exports.SubscriptionAccountHealth = SubscriptionAccountHealth; exports.getSharedAccountHealth = getSharedAccountHealth; exports.setSharedAccountHealth = setSharedAccountHealth; exports.__resetSharedAccountHealthForTests = __resetSharedAccountHealthForTests;
|