@omnicross/core 0.1.9 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -21
- package/NOTICE +57 -57
- package/README.md +22 -15
- package/dist/{CompletionService-kNA17cfI.d.cts → CompletionService-BiJqftc-.d.cts} +1 -1
- package/dist/{CompletionService-C3BX0Ovy.d.ts → CompletionService-NXN_Av5W.d.ts} +1 -1
- package/dist/{ProviderProxy-QdwNV6l1.d.cts → ProviderProxy-CgIcCVwk.d.cts} +1 -1
- package/dist/{ProviderProxy--ROec6VI.d.ts → ProviderProxy-DYoY5XoT.d.ts} +1 -1
- package/dist/auth/GeminiCodeAssistProjectResolver.cjs +6 -6
- package/dist/auth/GeminiCodeAssistProjectResolver.js +4 -4
- package/dist/chunk-32SRZFFP.cjs +153 -0
- package/dist/chunk-4JOU54M5.js +200 -0
- package/dist/{chunk-2UTGX6FM.js → chunk-4VVCXVB7.js} +1 -1
- package/dist/{chunk-EPN67EGP.cjs → chunk-5UK3KLE2.cjs} +9 -1
- package/dist/chunk-6DDYNS2B.cjs +384 -0
- package/dist/{chunk-HKB656B4.js → chunk-6OC3ORW6.js} +55 -287
- package/dist/chunk-6OKXH2TW.js +320 -0
- package/dist/{chunk-XELFM7KL.cjs → chunk-7B56AJBB.cjs} +6275 -2421
- package/dist/{chunk-YWL7YZWS.cjs → chunk-7LRTPNFL.cjs} +5 -0
- package/dist/{chunk-CCVRRJOX.js → chunk-7PIUVCKK.js} +9 -2
- package/dist/{chunk-IIRPUVPH.cjs → chunk-7ZHBN75N.cjs} +3 -1
- package/dist/{chunk-UAPBLNN2.js → chunk-AQDON6MB.js} +8 -0
- package/dist/{chunk-RJ5ZGNI3.js → chunk-CFSGYFOZ.js} +1 -1
- package/dist/chunk-CTKM773J.cjs +3919 -0
- package/dist/chunk-DEIUR2TH.js +3919 -0
- package/dist/{chunk-WNKWAEUR.js → chunk-EYGBM2VC.js} +3 -1
- package/dist/{chunk-NGYOO5TO.js → chunk-FJNKXOWE.js} +9 -9
- package/dist/chunk-FX325I5Q.cjs +320 -0
- package/dist/chunk-G4CZIUIB.cjs +200 -0
- package/dist/chunk-HCOQQAZE.cjs +123 -0
- package/dist/{chunk-55FMGZ3L.js → chunk-HN74IGEO.js} +1 -1
- package/dist/{chunk-ZY6KU6P3.js → chunk-HOMUGKHR.js} +8 -5
- package/dist/{chunk-AOFWNWLT.cjs → chunk-IUL4VWNU.cjs} +22 -1
- package/dist/{chunk-5LNYGCIW.cjs → chunk-KIQ2HA2A.cjs} +5 -5
- package/dist/{chunk-MUHWHQVM.cjs → chunk-KQBLZMP6.cjs} +4 -3
- package/dist/chunk-LFEH7CEO.js +384 -0
- package/dist/chunk-N76KU6F5.js +123 -0
- package/dist/{chunk-CMVXX7ON.cjs → chunk-NOITAVHA.cjs} +114 -58
- package/dist/{chunk-Q27JY5RG.cjs → chunk-OIKREZVQ.cjs} +7 -4
- package/dist/{chunk-RJUONLUQ.cjs → chunk-OST5RJOJ.cjs} +1 -1
- package/dist/chunk-QIIAMBTM.js +153 -0
- package/dist/{chunk-56QD3YW6.cjs → chunk-QWNUOR7F.cjs} +11 -4
- package/dist/{chunk-S3DYFEBE.js → chunk-R4VCO2CB.js} +10 -1
- package/dist/{chunk-ZQQUD66M.cjs → chunk-SQMAEDNE.cjs} +63 -295
- package/dist/{chunk-4VZX5F4T.cjs → chunk-T6NWPIYZ.cjs} +5 -2
- package/dist/{chunk-P7EM6BND.cjs → chunk-TVYA5JSQ.cjs} +10 -10
- package/dist/{chunk-EBLFCNPY.js → chunk-U47LQXPB.js} +5 -2
- package/dist/{chunk-N7OOJI5V.js → chunk-V2UKUTJ3.js} +5 -0
- package/dist/{chunk-45FHEOKW.js → chunk-V53ZEFXC.js} +92 -36
- package/dist/{chunk-OC6DOOFX.cjs → chunk-VXRTQZF2.cjs} +5 -5
- package/dist/{chunk-CQIJCPMF.js → chunk-WSJE42SG.js} +5149 -1295
- package/dist/{chunk-RICPANBY.cjs → chunk-WX2E2G7H.cjs} +13 -4
- package/dist/{chunk-DE2SRBFZ.js → chunk-X335TJNS.js} +4 -3
- package/dist/{chunk-N2EIM2XJ.js → chunk-ZLNHPUFA.js} +22 -1
- package/dist/completion/CompletionService.cjs +30 -27
- package/dist/completion/CompletionService.d.cts +3 -2
- package/dist/completion/CompletionService.d.ts +3 -2
- package/dist/completion/CompletionService.js +29 -26
- package/dist/completion.cjs +38 -35
- package/dist/completion.d.cts +3 -2
- package/dist/completion.d.ts +3 -2
- package/dist/completion.js +37 -34
- package/dist/image-generation.cjs +52 -0
- package/dist/image-generation.d.cts +93 -0
- package/dist/image-generation.d.ts +93 -0
- package/dist/image-generation.js +52 -0
- package/dist/index.cjs +126 -31
- package/dist/index.d.cts +11 -7
- package/dist/index.d.ts +11 -7
- package/dist/index.js +143 -48
- package/dist/openai-operation.cjs +18 -0
- package/dist/openai-operation.d.cts +19 -0
- package/dist/openai-operation.d.ts +19 -0
- package/dist/openai-operation.js +18 -0
- package/dist/outbound-api/auditCapture.cjs +3 -3
- package/dist/outbound-api/auditCapture.d.cts +19 -2
- package/dist/outbound-api/auditCapture.d.ts +19 -2
- package/dist/outbound-api/auditCapture.js +2 -2
- package/dist/outbound-api/auditRedact.cjs +2 -2
- package/dist/outbound-api/auditRedact.js +1 -1
- package/dist/outbound-api/routeResolver.cjs +2 -2
- package/dist/outbound-api/routeResolver.d.cts +7 -4
- package/dist/outbound-api/routeResolver.d.ts +7 -4
- package/dist/outbound-api/routeResolver.js +1 -1
- package/dist/outbound-api/subscriptionRegistryPort.d.cts +2 -1
- package/dist/outbound-api/subscriptionRegistryPort.d.ts +2 -1
- package/dist/outbound-api/types.d.cts +6 -3
- package/dist/outbound-api/types.d.ts +6 -3
- package/dist/outbound-api.cjs +49 -32
- package/dist/outbound-api.d.cts +97 -10
- package/dist/outbound-api.d.ts +97 -10
- package/dist/outbound-api.js +48 -31
- package/dist/pipeline/AccountAllowanceScheduling.d.cts +18 -15
- package/dist/pipeline/AccountAllowanceScheduling.d.ts +18 -15
- package/dist/pipeline/LlmConfigProviderAuth.cjs +3 -3
- package/dist/pipeline/LlmConfigProviderAuth.js +2 -2
- package/dist/pipeline/SubscriptionAccountHealth.cjs +2 -2
- package/dist/pipeline/SubscriptionAccountHealth.d.cts +7 -0
- package/dist/pipeline/SubscriptionAccountHealth.d.ts +7 -0
- package/dist/pipeline/SubscriptionAccountHealth.js +1 -1
- package/dist/pipeline/executeProviderCall.cjs +2 -2
- package/dist/pipeline/executeProviderCall.d.cts +11 -6
- package/dist/pipeline/executeProviderCall.d.ts +11 -6
- package/dist/pipeline/executeProviderCall.js +1 -1
- package/dist/pipeline/upstreamFetch.cjs +2 -2
- package/dist/pipeline/upstreamFetch.d.cts +5 -0
- package/dist/pipeline/upstreamFetch.d.ts +5 -0
- package/dist/pipeline/upstreamFetch.js +1 -1
- package/dist/ports.d.cts +6 -3
- package/dist/ports.d.ts +6 -3
- package/dist/provider-proxy/ProviderProxy.cjs +30 -27
- package/dist/provider-proxy/ProviderProxy.d.cts +3 -2
- package/dist/provider-proxy/ProviderProxy.d.ts +3 -2
- package/dist/provider-proxy/ProviderProxy.js +29 -26
- package/dist/provider-proxy/identity/codexCliHeaders.cjs +4 -2
- package/dist/provider-proxy/identity/codexCliHeaders.d.cts +26 -6
- package/dist/provider-proxy/identity/codexCliHeaders.d.ts +26 -6
- package/dist/provider-proxy/identity/codexCliHeaders.js +5 -3
- package/dist/provider-proxy/ingress/providerProxyShared.cjs +32 -27
- package/dist/provider-proxy/ingress/providerProxyShared.d.cts +21 -8
- package/dist/provider-proxy/ingress/providerProxyShared.d.ts +21 -8
- package/dist/provider-proxy/ingress/providerProxyShared.js +31 -26
- package/dist/provider-proxy/types.d.cts +14 -483
- package/dist/provider-proxy/types.d.ts +14 -483
- package/dist/provider-proxy.cjs +44 -27
- package/dist/provider-proxy.d.cts +30 -8
- package/dist/provider-proxy.d.ts +30 -8
- package/dist/provider-proxy.js +43 -26
- package/dist/{routeResolver-C0mkkZaM.d.ts → routeResolver-CTCcSHWu.d.ts} +4 -2
- package/dist/{routeResolver-CVFE8KKe.d.cts → routeResolver-rpKQLyDO.d.cts} +4 -2
- package/dist/transformer/TransformerChainExecutor.cjs +2 -2
- package/dist/transformer/TransformerChainExecutor.d.cts +2 -2
- package/dist/transformer/TransformerChainExecutor.d.ts +2 -2
- package/dist/transformer/TransformerChainExecutor.js +1 -1
- package/dist/transformer/transformers/AnthropicOpenAIToAnthropicStream.cjs +16 -0
- package/dist/transformer/transformers/AnthropicOpenAIToAnthropicStream.d.cts +53 -0
- package/dist/transformer/transformers/AnthropicOpenAIToAnthropicStream.d.ts +53 -0
- package/dist/transformer/transformers/AnthropicOpenAIToAnthropicStream.js +16 -0
- package/dist/transformer/transformers/AnthropicTransformer.cjs +4 -3
- package/dist/transformer/transformers/AnthropicTransformer.js +3 -2
- package/dist/transformer/transformers/GeminiCodeAssistTransformer.cjs +4 -4
- package/dist/transformer/transformers/GeminiCodeAssistTransformer.js +3 -3
- package/dist/transformer/transformers/GeminiTransformer.cjs +4 -4
- package/dist/transformer/transformers/GeminiTransformer.js +3 -3
- package/dist/transformer/transformers/OpenAIResponseTransformer.cjs +3 -3
- package/dist/transformer/transformers/OpenAIResponseTransformer.js +2 -2
- package/dist/transformer/transformers/OpenAITransformer.cjs +3 -3
- package/dist/transformer/transformers/OpenAITransformer.js +2 -2
- package/dist/transformer/transformers.cjs +10 -9
- package/dist/transformer/transformers.js +13 -12
- package/dist/transformer/types.d.cts +39 -4
- package/dist/transformer/types.d.ts +39 -4
- package/dist/transformer.cjs +14 -13
- package/dist/transformer.js +14 -13
- package/dist/{types-BB8pxk_3.d.ts → types-5T223WYQ.d.ts} +183 -23
- package/dist/types-Bd72H4SB.d.ts +196 -0
- package/dist/types-CVRge76p.d.ts +1115 -0
- package/dist/types-CbglB73l.d.cts +196 -0
- package/dist/types-DsHBBk3h.d.cts +1115 -0
- package/dist/{types-C2MwkLah.d.cts → types-jjU24eYG.d.cts} +183 -23
- package/dist/usage/usage-recorder.cjs +2 -2
- package/dist/usage/usage-recorder.d.cts +12 -2
- package/dist/usage/usage-recorder.d.ts +12 -2
- package/dist/usage/usage-recorder.js +1 -1
- package/dist/usage.cjs +20 -3
- package/dist/usage.d.cts +154 -0
- package/dist/usage.d.ts +154 -0
- package/dist/usage.js +20 -3
- package/package.json +69 -64
- package/dist/chunk-7C7DET6S.js +0 -154
- package/dist/chunk-7VU7V2E4.js +0 -0
- package/dist/chunk-EYZYXJTJ.cjs +0 -1
- package/dist/chunk-FCR77GYM.cjs +0 -33
- package/dist/chunk-K5NM7VAH.js +0 -33
- package/dist/chunk-XPIOJQS2.cjs +0 -154
- /package/dist/{chunk-XXFYLL7R.js → chunk-ECZ3ZE2C.js} +0 -0
- /package/dist/{chunk-3SCOLIPT.cjs → chunk-MXI2PWIC.cjs} +0 -0
package/dist/usage.d.ts
CHANGED
|
@@ -6,3 +6,157 @@ import './logger-4GvQNzhE.js';
|
|
|
6
6
|
import './ports/pricing-store.js';
|
|
7
7
|
import '@omnicross/contracts/usage-stats-types';
|
|
8
8
|
import './ports/usage-event-store.js';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* throughputTracker — a bounded, in-memory sliding window of recently recorded
|
|
12
|
+
* usage events, answering "how fast is the gateway serving RIGHT NOW".
|
|
13
|
+
*
|
|
14
|
+
* WHY a dedicated in-memory store (not a `UsageEventStore` range query): the
|
|
15
|
+
* daemon's `JsonlUsageEventStore.getTotals()` reads and parses the ENTIRE
|
|
16
|
+
* `usage-events.jsonl` synchronously on every call (a deliberate simplification
|
|
17
|
+
* documented there). That is fine for an on-demand stats page, but a live rate
|
|
18
|
+
* widget polls every few seconds, and a periodic synchronous full-file scan
|
|
19
|
+
* would stall the same event loop that is relaying gateway requests. This
|
|
20
|
+
* tracker is fed O(1) per recorded request from `UsageRecorder`'s `onEvent`
|
|
21
|
+
* hook and read in O(samples-in-window) — it never touches disk.
|
|
22
|
+
*
|
|
23
|
+
* Shaped like `pipeline/ServerOverloadCounter`: process-local, cleared on
|
|
24
|
+
* restart, an injectable `now` clock, no external deps. It carries ONLY token
|
|
25
|
+
* counts, costs, and epoch timestamps — never a prompt, header, model secret,
|
|
26
|
+
* or key id — so no snapshot of it can leak one.
|
|
27
|
+
*
|
|
28
|
+
* TWO MEASUREMENT DECISIONS worth stating explicitly, because both are easy to
|
|
29
|
+
* get subtly wrong:
|
|
30
|
+
*
|
|
31
|
+
* 1. `totalTokens` deliberately EXCLUDES `reasoningTokens`. Providers report
|
|
32
|
+
* reasoning tokens as a SUBSET of the completion/output tokens, so adding
|
|
33
|
+
* them would double-count. They are still reported separately.
|
|
34
|
+
*
|
|
35
|
+
* 2. Rates always divide by the FULL requested window, never by "how long this
|
|
36
|
+
* process has been up". A daemon that was down served no traffic, so the
|
|
37
|
+
* honest rate over that wall-clock window really is lower; after a restart
|
|
38
|
+
* the number climbs back from zero on its own. `startedAt` is reported so a
|
|
39
|
+
* reader can say "this process started less than a window ago" without the
|
|
40
|
+
* rate itself being fudged.
|
|
41
|
+
*
|
|
42
|
+
* @module usage/throughputTracker
|
|
43
|
+
*/
|
|
44
|
+
/** Longest window a snapshot can answer; also the sample-retention horizon. */
|
|
45
|
+
declare const THROUGHPUT_RETENTION_MS: number;
|
|
46
|
+
/**
|
|
47
|
+
* Hard memory ceiling on retained samples (~20k x a few dozen bytes). Reaching
|
|
48
|
+
* it means sustained >22 req/s for a full 15 minutes; past that the OLDEST
|
|
49
|
+
* samples are evicted and the affected windows report `complete: false` rather
|
|
50
|
+
* than quietly under-reporting.
|
|
51
|
+
*/
|
|
52
|
+
declare const THROUGHPUT_SAMPLE_LIMIT = 20000;
|
|
53
|
+
/** Windows every snapshot reports, shortest first. The last must be <= retention. */
|
|
54
|
+
declare const THROUGHPUT_WINDOWS_MS: readonly [60000, 300000, 900000];
|
|
55
|
+
/** Trend-series resolution: 30 buckets across the retention horizon (30s each). */
|
|
56
|
+
declare const THROUGHPUT_BUCKET_COUNT = 30;
|
|
57
|
+
/**
|
|
58
|
+
* One recorded request's contribution. Structurally satisfied by the recorder's
|
|
59
|
+
* `UsageEventInput` row, so the daemon can forward it verbatim.
|
|
60
|
+
*/
|
|
61
|
+
interface UsageThroughputInput {
|
|
62
|
+
inputTokens: number;
|
|
63
|
+
outputTokens: number;
|
|
64
|
+
cacheReadTokens: number;
|
|
65
|
+
cacheCreationTokens: number;
|
|
66
|
+
reasoningTokens: number;
|
|
67
|
+
costUsd: number;
|
|
68
|
+
/** Epoch-ms of the event. Omit to use the `now` argument. */
|
|
69
|
+
ts?: number;
|
|
70
|
+
}
|
|
71
|
+
/** Aggregates + rates for one trailing window. */
|
|
72
|
+
interface UsageThroughputWindow {
|
|
73
|
+
/** Trailing window this row covers, in ms. */
|
|
74
|
+
windowMs: number;
|
|
75
|
+
requests: number;
|
|
76
|
+
inputTokens: number;
|
|
77
|
+
outputTokens: number;
|
|
78
|
+
cacheReadTokens: number;
|
|
79
|
+
cacheCreationTokens: number;
|
|
80
|
+
reasoningTokens: number;
|
|
81
|
+
/** input + output + cacheRead + cacheCreation (reasoning is a subset of output). */
|
|
82
|
+
totalTokens: number;
|
|
83
|
+
costUsd: number;
|
|
84
|
+
requestsPerMinute: number;
|
|
85
|
+
/** `totalTokens` per minute over `windowMs`. */
|
|
86
|
+
tokensPerMinute: number;
|
|
87
|
+
inputTokensPerMinute: number;
|
|
88
|
+
outputTokensPerMinute: number;
|
|
89
|
+
/** cacheRead + cacheCreation per minute over `windowMs`. */
|
|
90
|
+
cacheTokensPerMinute: number;
|
|
91
|
+
costUsdPerMinute: number;
|
|
92
|
+
/**
|
|
93
|
+
* False when the sample cap evicted events that fall inside this window, so
|
|
94
|
+
* every figure above is a LOWER BOUND rather than an exact count.
|
|
95
|
+
*/
|
|
96
|
+
complete: boolean;
|
|
97
|
+
}
|
|
98
|
+
/** One fixed-width bucket of the trend series. */
|
|
99
|
+
interface UsageThroughputBucket {
|
|
100
|
+
/** Epoch-ms of the bucket's (grid-aligned) start. */
|
|
101
|
+
startTs: number;
|
|
102
|
+
requests: number;
|
|
103
|
+
/** input + output + cacheRead + cacheCreation (same basis as `totalTokens`). */
|
|
104
|
+
tokens: number;
|
|
105
|
+
/** Output tokens alone, so a card headlining output can trend in step. */
|
|
106
|
+
outputTokens: number;
|
|
107
|
+
}
|
|
108
|
+
/** The `GET /admin/api/usage/throughput` payload. */
|
|
109
|
+
interface UsageThroughputSnapshot {
|
|
110
|
+
/** Always true here; the UI's fallback shape uses `false` for older daemons. */
|
|
111
|
+
available: true;
|
|
112
|
+
collectedAt: number;
|
|
113
|
+
/** Epoch-ms this tracker began observing (effectively the daemon's start). */
|
|
114
|
+
startedAt: number;
|
|
115
|
+
retentionMs: number;
|
|
116
|
+
/** Width of one `buckets` entry, in ms. */
|
|
117
|
+
bucketMs: number;
|
|
118
|
+
/** One row per {@link THROUGHPUT_WINDOWS_MS} entry, shortest window first. */
|
|
119
|
+
windows: UsageThroughputWindow[];
|
|
120
|
+
/**
|
|
121
|
+
* Oldest to newest, exactly {@link THROUGHPUT_BUCKET_COUNT} entries covering
|
|
122
|
+
* `retentionMs` on a `bucketMs` grid. Empty buckets are present and zeroed;
|
|
123
|
+
* the final bucket is still in progress. Grid alignment (rather than
|
|
124
|
+
* "now minus retention") keeps boundaries stable between polls so a sparkline
|
|
125
|
+
* does not shimmer.
|
|
126
|
+
*/
|
|
127
|
+
buckets: UsageThroughputBucket[];
|
|
128
|
+
}
|
|
129
|
+
declare class UsageThroughputTracker {
|
|
130
|
+
private samples;
|
|
131
|
+
/** Index of the oldest live sample; slots before it are consumed. */
|
|
132
|
+
private head;
|
|
133
|
+
private readonly startedAt;
|
|
134
|
+
/** Newest ts dropped by the sample CAP (not by retention). Null when none. */
|
|
135
|
+
private evictedThroughTs;
|
|
136
|
+
constructor(now?: number);
|
|
137
|
+
/** Record one served request. O(1) amortised; never touches disk. */
|
|
138
|
+
record(input: UsageThroughputInput, now?: number): void;
|
|
139
|
+
/** Aggregate every reported window plus the shared trend series. */
|
|
140
|
+
snapshot(now?: number): UsageThroughputSnapshot;
|
|
141
|
+
/** Drop all samples (tests / teardown). `startedAt` is unchanged. */
|
|
142
|
+
clear(): void;
|
|
143
|
+
/**
|
|
144
|
+
* Drop samples past the retention horizon, then enforce the sample cap.
|
|
145
|
+
*
|
|
146
|
+
* Retention pruning uses the CALLER's `now`, which is never later than a
|
|
147
|
+
* subsequent snapshot's `now`, so it can only ever keep MORE than the widest
|
|
148
|
+
* window needs — it can never shave data off the 15-minute window.
|
|
149
|
+
*/
|
|
150
|
+
private prune;
|
|
151
|
+
private window;
|
|
152
|
+
private buckets;
|
|
153
|
+
}
|
|
154
|
+
declare function getSharedUsageThroughputTracker(): UsageThroughputTracker;
|
|
155
|
+
/**
|
|
156
|
+
* TEST SEAM — swap the singleton (e.g. with a fixed-clock instance). Mirrors the
|
|
157
|
+
* `setShared…`/`__reset…ForTests` discipline of the sibling in-memory stores.
|
|
158
|
+
*/
|
|
159
|
+
declare function setSharedUsageThroughputTracker(instance: UsageThroughputTracker): void;
|
|
160
|
+
declare function __resetSharedUsageThroughputTrackerForTests(): void;
|
|
161
|
+
|
|
162
|
+
export { THROUGHPUT_BUCKET_COUNT, THROUGHPUT_RETENTION_MS, THROUGHPUT_SAMPLE_LIMIT, THROUGHPUT_WINDOWS_MS, type UsageThroughputBucket, type UsageThroughputInput, type UsageThroughputSnapshot, UsageThroughputTracker, type UsageThroughputWindow, __resetSharedUsageThroughputTrackerForTests, getSharedUsageThroughputTracker, setSharedUsageThroughputTracker };
|
package/dist/usage.js
CHANGED
|
@@ -1,12 +1,29 @@
|
|
|
1
|
-
import
|
|
1
|
+
import {
|
|
2
|
+
THROUGHPUT_BUCKET_COUNT,
|
|
3
|
+
THROUGHPUT_RETENTION_MS,
|
|
4
|
+
THROUGHPUT_SAMPLE_LIMIT,
|
|
5
|
+
THROUGHPUT_WINDOWS_MS,
|
|
6
|
+
UsageThroughputTracker,
|
|
7
|
+
__resetSharedUsageThroughputTrackerForTests,
|
|
8
|
+
getSharedUsageThroughputTracker,
|
|
9
|
+
setSharedUsageThroughputTracker
|
|
10
|
+
} from "./chunk-QIIAMBTM.js";
|
|
2
11
|
import {
|
|
3
12
|
PricingEngine
|
|
4
13
|
} from "./chunk-FXR6N3SR.js";
|
|
5
14
|
import {
|
|
6
15
|
UsageRecorder
|
|
7
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-AQDON6MB.js";
|
|
8
17
|
import "./chunk-OZFM4X3S.js";
|
|
9
18
|
export {
|
|
10
19
|
PricingEngine,
|
|
11
|
-
|
|
20
|
+
THROUGHPUT_BUCKET_COUNT,
|
|
21
|
+
THROUGHPUT_RETENTION_MS,
|
|
22
|
+
THROUGHPUT_SAMPLE_LIMIT,
|
|
23
|
+
THROUGHPUT_WINDOWS_MS,
|
|
24
|
+
UsageRecorder,
|
|
25
|
+
UsageThroughputTracker,
|
|
26
|
+
__resetSharedUsageThroughputTrackerForTests,
|
|
27
|
+
getSharedUsageThroughputTracker,
|
|
28
|
+
setSharedUsageThroughputTracker
|
|
12
29
|
};
|
package/package.json
CHANGED
|
@@ -1,64 +1,69 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@omnicross/core",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Omnicross LLM serving core
|
|
5
|
-
"license": "MIT",
|
|
6
|
-
"author": "Sayo (https://github.com/Dumoedss)",
|
|
7
|
-
"homepage": "https://github.com/Dumoedss/omnicross#readme",
|
|
8
|
-
"keywords": [
|
|
9
|
-
"omnicross",
|
|
10
|
-
"llm",
|
|
11
|
-
"openai",
|
|
12
|
-
"anthropic",
|
|
13
|
-
"gemini",
|
|
14
|
-
"proxy",
|
|
15
|
-
"router",
|
|
16
|
-
"completion",
|
|
17
|
-
"transformer"
|
|
18
|
-
],
|
|
19
|
-
"repository": {
|
|
20
|
-
"type": "git",
|
|
21
|
-
"url": "
|
|
22
|
-
"directory": "packages/core"
|
|
23
|
-
},
|
|
24
|
-
"publishConfig": {
|
|
25
|
-
"access": "public"
|
|
26
|
-
},
|
|
27
|
-
"engines": {
|
|
28
|
-
"node": ">=20"
|
|
29
|
-
},
|
|
30
|
-
"type": "module",
|
|
31
|
-
"main": "dist/index.cjs",
|
|
32
|
-
"module": "dist/index.js",
|
|
33
|
-
"types": "dist/index.d.ts",
|
|
34
|
-
"exports": {
|
|
35
|
-
".": {
|
|
36
|
-
"types": "./dist/index.d.ts",
|
|
37
|
-
"import": "./dist/index.js",
|
|
38
|
-
"require": "./dist/index.cjs"
|
|
39
|
-
},
|
|
40
|
-
"./*": {
|
|
41
|
-
"types": "./dist/*.d.ts",
|
|
42
|
-
"import": "./dist/*.js",
|
|
43
|
-
"require": "./dist/*.cjs"
|
|
44
|
-
}
|
|
45
|
-
},
|
|
46
|
-
"files": [
|
|
47
|
-
"dist",
|
|
48
|
-
"LICENSE",
|
|
49
|
-
"NOTICE",
|
|
50
|
-
"README.md"
|
|
51
|
-
],
|
|
52
|
-
"scripts": {
|
|
53
|
-
"build": "tsup",
|
|
54
|
-
"typecheck": "tsc -p tsconfig.typecheck.json --noEmit"
|
|
55
|
-
},
|
|
56
|
-
"dependencies": {
|
|
57
|
-
"@mozilla/readability": "^0.6.0",
|
|
58
|
-
"@omnicross/contracts": "^0.
|
|
59
|
-
"
|
|
60
|
-
"
|
|
61
|
-
"
|
|
62
|
-
"
|
|
63
|
-
|
|
64
|
-
|
|
1
|
+
{
|
|
2
|
+
"name": "@omnicross/core",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "Omnicross LLM serving core — provider dispatch, completion pipeline, transformers, and the provider proxy.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"author": "Sayo (https://github.com/Dumoedss)",
|
|
7
|
+
"homepage": "https://github.com/Dumoedss/omnicross#readme",
|
|
8
|
+
"keywords": [
|
|
9
|
+
"omnicross",
|
|
10
|
+
"llm",
|
|
11
|
+
"openai",
|
|
12
|
+
"anthropic",
|
|
13
|
+
"gemini",
|
|
14
|
+
"proxy",
|
|
15
|
+
"router",
|
|
16
|
+
"completion",
|
|
17
|
+
"transformer"
|
|
18
|
+
],
|
|
19
|
+
"repository": {
|
|
20
|
+
"type": "git",
|
|
21
|
+
"url": "https://github.com/DumoeDss/omnicross",
|
|
22
|
+
"directory": "packages/core"
|
|
23
|
+
},
|
|
24
|
+
"publishConfig": {
|
|
25
|
+
"access": "public"
|
|
26
|
+
},
|
|
27
|
+
"engines": {
|
|
28
|
+
"node": ">=20.9"
|
|
29
|
+
},
|
|
30
|
+
"type": "module",
|
|
31
|
+
"main": "dist/index.cjs",
|
|
32
|
+
"module": "dist/index.js",
|
|
33
|
+
"types": "dist/index.d.ts",
|
|
34
|
+
"exports": {
|
|
35
|
+
".": {
|
|
36
|
+
"types": "./dist/index.d.ts",
|
|
37
|
+
"import": "./dist/index.js",
|
|
38
|
+
"require": "./dist/index.cjs"
|
|
39
|
+
},
|
|
40
|
+
"./*": {
|
|
41
|
+
"types": "./dist/*.d.ts",
|
|
42
|
+
"import": "./dist/*.js",
|
|
43
|
+
"require": "./dist/*.cjs"
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
"files": [
|
|
47
|
+
"dist",
|
|
48
|
+
"LICENSE",
|
|
49
|
+
"NOTICE",
|
|
50
|
+
"README.md"
|
|
51
|
+
],
|
|
52
|
+
"scripts": {
|
|
53
|
+
"build": "tsup",
|
|
54
|
+
"typecheck": "tsc -p tsconfig.typecheck.json --noEmit"
|
|
55
|
+
},
|
|
56
|
+
"dependencies": {
|
|
57
|
+
"@mozilla/readability": "^0.6.0",
|
|
58
|
+
"@omnicross/contracts": "^0.2.0",
|
|
59
|
+
"busboy": "^1.6.0",
|
|
60
|
+
"jsdom": "^24.1.3",
|
|
61
|
+
"sharp": "^0.35.4",
|
|
62
|
+
"socks": "^2.8.3",
|
|
63
|
+
"turndown": "^7.2.2",
|
|
64
|
+
"undici": "^6.28.0"
|
|
65
|
+
},
|
|
66
|
+
"devDependencies": {
|
|
67
|
+
"@types/busboy": "^1.5.4"
|
|
68
|
+
}
|
|
69
|
+
}
|
package/dist/chunk-7C7DET6S.js
DELETED
|
@@ -1,154 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
redactAuditText
|
|
3
|
-
} from "./chunk-K5NM7VAH.js";
|
|
4
|
-
import {
|
|
5
|
-
getAuditCaptureConfig,
|
|
6
|
-
recordAudit
|
|
7
|
-
} from "./chunk-WNY4WMRF.js";
|
|
8
|
-
import {
|
|
9
|
-
readAuditUsage
|
|
10
|
-
} from "./chunk-OZFM4X3S.js";
|
|
11
|
-
|
|
12
|
-
// src/outbound-api/auditCapture.ts
|
|
13
|
-
import { randomUUID } from "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
|
-
}
|
|
37
|
-
function resolveClientIp(req, trustForwardedFor) {
|
|
38
|
-
if (trustForwardedFor) {
|
|
39
|
-
const xff = req.headers["x-forwarded-for"];
|
|
40
|
-
const raw = Array.isArray(xff) ? xff[0] : xff;
|
|
41
|
-
if (typeof raw === "string" && raw.trim()) {
|
|
42
|
-
const first = raw.split(",")[0]?.trim();
|
|
43
|
-
if (first) return first;
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
return req.socket?.remoteAddress ?? void 0;
|
|
47
|
-
}
|
|
48
|
-
function beginAuditCapture(req, res, now) {
|
|
49
|
-
const config = getAuditCaptureConfig();
|
|
50
|
-
if (!config) return null;
|
|
51
|
-
let requestBody;
|
|
52
|
-
const responseChunks = [];
|
|
53
|
-
let responseBytes = 0;
|
|
54
|
-
let responseTruncated = false;
|
|
55
|
-
let finished = false;
|
|
56
|
-
const ctx = {
|
|
57
|
-
setRequestBody(raw) {
|
|
58
|
-
if (config.captureBodies) {
|
|
59
|
-
requestBody = truncateToBytes(redactAuditText(raw), config.maxBodyBytes);
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
};
|
|
63
|
-
if (config.captureBodies) {
|
|
64
|
-
installResponseCapture(res, {
|
|
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
|
-
}
|
|
82
|
-
responseChunks.push(chunk);
|
|
83
|
-
responseBytes += chunk.length;
|
|
84
|
-
}
|
|
85
|
-
});
|
|
86
|
-
}
|
|
87
|
-
const finalize = () => {
|
|
88
|
-
if (finished) return;
|
|
89
|
-
finished = true;
|
|
90
|
-
try {
|
|
91
|
-
const record = {
|
|
92
|
-
id: randomUUID(),
|
|
93
|
-
ts: now,
|
|
94
|
-
method: req.method ?? "",
|
|
95
|
-
path: (req.url ?? "").split("?")[0] ?? "",
|
|
96
|
-
status: res.statusCode,
|
|
97
|
-
latencyMs: Math.max(0, Date.now() - now)
|
|
98
|
-
};
|
|
99
|
-
if (ctx.keyId != null) record.keyId = ctx.keyId;
|
|
100
|
-
const ip = resolveClientIp(req, config.trustForwardedFor);
|
|
101
|
-
if (ip) record.ip = ip;
|
|
102
|
-
const ua = req.headers["user-agent"];
|
|
103
|
-
if (typeof ua === "string" && ua) record.ua = ua;
|
|
104
|
-
if (ctx.model) record.model = ctx.model;
|
|
105
|
-
if (ctx.provider) record.provider = ctx.provider;
|
|
106
|
-
const usage = readAuditUsage(res);
|
|
107
|
-
if (usage) {
|
|
108
|
-
if (typeof usage.inputTokens === "number") record.inputTokens = usage.inputTokens;
|
|
109
|
-
if (typeof usage.outputTokens === "number") record.outputTokens = usage.outputTokens;
|
|
110
|
-
if (typeof usage.costUsd === "number") record.costUsd = usage.costUsd;
|
|
111
|
-
if (!record.model && usage.model) record.model = usage.model;
|
|
112
|
-
if (!record.provider && usage.provider) record.provider = usage.provider;
|
|
113
|
-
}
|
|
114
|
-
if (ctx.error) record.error = redactAuditText(ctx.error);
|
|
115
|
-
if (config.captureBodies) {
|
|
116
|
-
if (requestBody != null && requestBody.length > 0) {
|
|
117
|
-
record.requestBody = requestBody;
|
|
118
|
-
}
|
|
119
|
-
if (responseChunks.length > 0) {
|
|
120
|
-
const captured = Buffer.concat(responseChunks, responseBytes);
|
|
121
|
-
const body = decodeCapturedBody(captured, responseTruncated);
|
|
122
|
-
record.responseBody = truncateToBytes(redactAuditText(body), config.maxBodyBytes);
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
recordAudit(record);
|
|
126
|
-
} catch {
|
|
127
|
-
}
|
|
128
|
-
};
|
|
129
|
-
res.once("close", finalize);
|
|
130
|
-
return ctx;
|
|
131
|
-
}
|
|
132
|
-
function installResponseCapture(res, sink) {
|
|
133
|
-
const capture = (chunk) => {
|
|
134
|
-
let buf = null;
|
|
135
|
-
if (Buffer.isBuffer(chunk)) buf = chunk;
|
|
136
|
-
else if (typeof chunk === "string") buf = Buffer.from(chunk, "utf8");
|
|
137
|
-
if (!buf || buf.length === 0) return;
|
|
138
|
-
sink.push(buf);
|
|
139
|
-
};
|
|
140
|
-
const originalWrite = res.write.bind(res);
|
|
141
|
-
const originalEnd = res.end.bind(res);
|
|
142
|
-
res.write = ((chunk, ...args) => {
|
|
143
|
-
if (chunk != null) capture(chunk);
|
|
144
|
-
return originalWrite(chunk, ...args);
|
|
145
|
-
});
|
|
146
|
-
res.end = ((chunk, ...args) => {
|
|
147
|
-
if (chunk != null && typeof chunk !== "function") capture(chunk);
|
|
148
|
-
return originalEnd(chunk, ...args);
|
|
149
|
-
});
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
export {
|
|
153
|
-
beginAuditCapture
|
|
154
|
-
};
|
package/dist/chunk-7VU7V2E4.js
DELETED
|
File without changes
|
package/dist/chunk-EYZYXJTJ.cjs
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";
|
package/dist/chunk-FCR77GYM.cjs
DELETED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } }// src/outbound-api/auditRedact.ts
|
|
2
|
-
var AUDIT_REDACTED = "***REDACTED***";
|
|
3
|
-
var RULES = [
|
|
4
|
-
// `sk-…` family (Anthropic sk-ant-, omnicross sk-omnicross-, OpenAI sk-proj-/sk-).
|
|
5
|
-
{ re: /\bsk-[A-Za-z0-9_-]{6,}/g, replace: AUDIT_REDACTED },
|
|
6
|
-
// Google API keys.
|
|
7
|
-
{ re: /\bAIza[A-Za-z0-9_-]{10,}/g, replace: AUDIT_REDACTED },
|
|
8
|
-
// `Bearer <token>` (auth headers echoed into a body / SSE error).
|
|
9
|
-
{ re: /\bBearer\s+[A-Za-z0-9._~+/=-]{6,}/gi, replace: `Bearer ${AUDIT_REDACTED}` },
|
|
10
|
-
// Inline `x-api-key` / `api-key` / `authorization` label followed by a value.
|
|
11
|
-
{
|
|
12
|
-
re: /\b(x-api-key|api[_-]?key|authorization)(["']?\s*[:=]\s*["']?)[A-Za-z0-9._~+/=-]{6,}/gi,
|
|
13
|
-
replace: `$1$2${AUDIT_REDACTED}`
|
|
14
|
-
},
|
|
15
|
-
// `x-goog-api-key` header echoed inline.
|
|
16
|
-
{
|
|
17
|
-
re: /\b(x-goog-api-key)(["']?\s*[:=]\s*["']?)[A-Za-z0-9._~+/=-]{6,}/gi,
|
|
18
|
-
replace: `$1$2${AUDIT_REDACTED}`
|
|
19
|
-
}
|
|
20
|
-
];
|
|
21
|
-
function redactAuditText(text) {
|
|
22
|
-
if (typeof text !== "string" || text.length === 0) return _nullishCoalesce(text, () => ( ""));
|
|
23
|
-
let out = text;
|
|
24
|
-
for (const { re, replace } of RULES) {
|
|
25
|
-
out = out.replace(re, replace);
|
|
26
|
-
}
|
|
27
|
-
return out;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
exports.AUDIT_REDACTED = AUDIT_REDACTED; exports.redactAuditText = redactAuditText;
|
package/dist/chunk-K5NM7VAH.js
DELETED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
// src/outbound-api/auditRedact.ts
|
|
2
|
-
var AUDIT_REDACTED = "***REDACTED***";
|
|
3
|
-
var RULES = [
|
|
4
|
-
// `sk-…` family (Anthropic sk-ant-, omnicross sk-omnicross-, OpenAI sk-proj-/sk-).
|
|
5
|
-
{ re: /\bsk-[A-Za-z0-9_-]{6,}/g, replace: AUDIT_REDACTED },
|
|
6
|
-
// Google API keys.
|
|
7
|
-
{ re: /\bAIza[A-Za-z0-9_-]{10,}/g, replace: AUDIT_REDACTED },
|
|
8
|
-
// `Bearer <token>` (auth headers echoed into a body / SSE error).
|
|
9
|
-
{ re: /\bBearer\s+[A-Za-z0-9._~+/=-]{6,}/gi, replace: `Bearer ${AUDIT_REDACTED}` },
|
|
10
|
-
// Inline `x-api-key` / `api-key` / `authorization` label followed by a value.
|
|
11
|
-
{
|
|
12
|
-
re: /\b(x-api-key|api[_-]?key|authorization)(["']?\s*[:=]\s*["']?)[A-Za-z0-9._~+/=-]{6,}/gi,
|
|
13
|
-
replace: `$1$2${AUDIT_REDACTED}`
|
|
14
|
-
},
|
|
15
|
-
// `x-goog-api-key` header echoed inline.
|
|
16
|
-
{
|
|
17
|
-
re: /\b(x-goog-api-key)(["']?\s*[:=]\s*["']?)[A-Za-z0-9._~+/=-]{6,}/gi,
|
|
18
|
-
replace: `$1$2${AUDIT_REDACTED}`
|
|
19
|
-
}
|
|
20
|
-
];
|
|
21
|
-
function redactAuditText(text) {
|
|
22
|
-
if (typeof text !== "string" || text.length === 0) return text ?? "";
|
|
23
|
-
let out = text;
|
|
24
|
-
for (const { re, replace } of RULES) {
|
|
25
|
-
out = out.replace(re, replace);
|
|
26
|
-
}
|
|
27
|
-
return out;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
export {
|
|
31
|
-
AUDIT_REDACTED,
|
|
32
|
-
redactAuditText
|
|
33
|
-
};
|