@omnicross/core 0.1.2 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (131) hide show
  1. package/dist/auth/GeminiCodeAssistProjectResolver.cjs +6 -1
  2. package/dist/auth/GeminiCodeAssistProjectResolver.js +6 -1
  3. package/dist/{chunk-SN3YWBX7.cjs → chunk-2FMI2B6V.cjs} +2329 -533
  4. package/dist/{chunk-XBSYYZIY.cjs → chunk-3QOSDDNI.cjs} +39 -3
  5. package/dist/{chunk-2FEVTJWG.js → chunk-4DECIFU7.js} +2162 -366
  6. package/dist/chunk-4IH4EL7M.cjs +9 -0
  7. package/dist/chunk-5ENKBSWO.js +311 -0
  8. package/dist/chunk-6RPZADX3.cjs +92 -0
  9. package/dist/chunk-AEOZIDEB.cjs +32 -0
  10. package/dist/chunk-BO4RFWBR.js +89 -0
  11. package/dist/{chunk-MNYKI4CI.js → chunk-CWM2ZDU5.js} +36 -0
  12. package/dist/chunk-CZHZGRU7.js +383 -0
  13. package/dist/{chunk-4NBS6KPV.cjs → chunk-DQ5VAYZ6.cjs} +7 -8
  14. package/dist/chunk-HUZZZ3JL.js +32 -0
  15. package/dist/{chunk-QOCNX236.js → chunk-IAXWICZU.js} +24 -1
  16. package/dist/{chunk-V5KPWNYX.cjs → chunk-JMJBSACD.cjs} +3 -3
  17. package/dist/chunk-L74VDN4A.cjs +32 -0
  18. package/dist/{chunk-74TMJA7Z.js → chunk-N5QFKSDO.js} +7 -4
  19. package/dist/{chunk-LKZJEL6E.cjs → chunk-Q27JY5RG.cjs} +6 -4
  20. package/dist/{chunk-SPVWWUHX.cjs → chunk-QWBWGODS.cjs} +24 -1
  21. package/dist/chunk-RPII3E6Z.cjs +145 -0
  22. package/dist/chunk-S6JGLF3G.cjs +89 -0
  23. package/dist/chunk-SVXC36MU.cjs +383 -0
  24. package/dist/chunk-TKJMZBAH.js +32 -0
  25. package/dist/{chunk-ZSVQT3PW.js → chunk-UBWEBKRC.js} +5 -6
  26. package/dist/chunk-UNEFIWXI.cjs +32 -0
  27. package/dist/chunk-VQY5W4YW.cjs +311 -0
  28. package/dist/chunk-WNY4WMRF.js +32 -0
  29. package/dist/chunk-XEKD23J5.js +9 -0
  30. package/dist/chunk-XTEI64OU.js +145 -0
  31. package/dist/chunk-XX6NQJMA.js +92 -0
  32. package/dist/{chunk-N3V2J5ZO.cjs → chunk-Y6OM7EV7.cjs} +7 -4
  33. package/dist/{chunk-745DV5FL.js → chunk-Y7FO65VT.js} +3 -3
  34. package/dist/{chunk-PXUJF5HS.js → chunk-ZY6KU6P3.js} +4 -2
  35. package/dist/completion/CompletionService.cjs +22 -15
  36. package/dist/completion/CompletionService.js +21 -14
  37. package/dist/completion/NativeSearchInjector.cjs +3 -3
  38. package/dist/completion/NativeSearchInjector.js +2 -2
  39. package/dist/completion/openrouter-headers.cjs +3 -6
  40. package/dist/completion/openrouter-headers.d.cts +9 -12
  41. package/dist/completion/openrouter-headers.d.ts +9 -12
  42. package/dist/completion/openrouter-headers.js +2 -5
  43. package/dist/completion/openrouter-models.cjs +4 -3
  44. package/dist/completion/openrouter-models.js +2 -1
  45. package/dist/completion.cjs +22 -15
  46. package/dist/completion.js +21 -14
  47. package/dist/index.cjs +139 -17
  48. package/dist/index.d.cts +40 -10
  49. package/dist/index.d.ts +40 -10
  50. package/dist/index.js +146 -24
  51. package/dist/outbound-api/routeResolver.cjs +5 -2
  52. package/dist/outbound-api/routeResolver.d.cts +8 -2
  53. package/dist/outbound-api/routeResolver.d.ts +8 -2
  54. package/dist/outbound-api/routeResolver.js +4 -1
  55. package/dist/outbound-api/types.cjs +6 -1
  56. package/dist/outbound-api/types.d.cts +11 -144
  57. package/dist/outbound-api/types.d.ts +11 -144
  58. package/dist/outbound-api/types.js +6 -0
  59. package/dist/outbound-api.cjs +133 -15
  60. package/dist/outbound-api.d.cts +786 -25
  61. package/dist/outbound-api.d.ts +786 -25
  62. package/dist/outbound-api.js +137 -19
  63. package/dist/pipeline/AuthSource.d.cts +23 -1
  64. package/dist/pipeline/AuthSource.d.ts +23 -1
  65. package/dist/pipeline/LlmConfigProviderAuth.cjs +3 -3
  66. package/dist/pipeline/LlmConfigProviderAuth.js +2 -2
  67. package/dist/pipeline/SubscriptionAccountHealth.cjs +22 -0
  68. package/dist/pipeline/SubscriptionAccountHealth.d.cts +235 -0
  69. package/dist/pipeline/SubscriptionAccountHealth.d.ts +235 -0
  70. package/dist/pipeline/SubscriptionAccountHealth.js +22 -0
  71. package/dist/pipeline/SubscriptionAuthSource.cjs +2 -2
  72. package/dist/pipeline/SubscriptionAuthSource.d.cts +3 -2
  73. package/dist/pipeline/SubscriptionAuthSource.d.ts +3 -2
  74. package/dist/pipeline/SubscriptionAuthSource.js +1 -1
  75. package/dist/pipeline/SubscriptionAuthStrategy.d.cts +24 -1
  76. package/dist/pipeline/SubscriptionAuthStrategy.d.ts +24 -1
  77. package/dist/pipeline/auditSink.cjs +14 -0
  78. package/dist/pipeline/auditSink.d.cts +48 -0
  79. package/dist/pipeline/auditSink.d.ts +48 -0
  80. package/dist/pipeline/auditSink.js +14 -0
  81. package/dist/pipeline/billingEmit.cjs +14 -0
  82. package/dist/pipeline/billingEmit.d.cts +49 -0
  83. package/dist/pipeline/billingEmit.d.ts +49 -0
  84. package/dist/pipeline/billingEmit.js +14 -0
  85. package/dist/ports/usage-event-store.d.cts +26 -1
  86. package/dist/ports/usage-event-store.d.ts +26 -1
  87. package/dist/ports.d.cts +7 -1
  88. package/dist/ports.d.ts +7 -1
  89. package/dist/provider-proxy/ProviderProxy.cjs +22 -15
  90. package/dist/provider-proxy/ProviderProxy.js +21 -14
  91. package/dist/provider-proxy/identity/SubscriptionIdentityStore.cjs +15 -0
  92. package/dist/provider-proxy/identity/SubscriptionIdentityStore.d.cts +121 -0
  93. package/dist/provider-proxy/identity/SubscriptionIdentityStore.d.ts +121 -0
  94. package/dist/provider-proxy/identity/SubscriptionIdentityStore.js +15 -0
  95. package/dist/provider-proxy/identity/fingerprintHeaders.cjs +20 -0
  96. package/dist/provider-proxy/identity/fingerprintHeaders.d.cts +89 -0
  97. package/dist/provider-proxy/identity/fingerprintHeaders.d.ts +89 -0
  98. package/dist/provider-proxy/identity/fingerprintHeaders.js +20 -0
  99. package/dist/provider-proxy/ingress/providerProxyShared.cjs +22 -15
  100. package/dist/provider-proxy/ingress/providerProxyShared.d.cts +11 -2
  101. package/dist/provider-proxy/ingress/providerProxyShared.d.ts +11 -2
  102. package/dist/provider-proxy/ingress/providerProxyShared.js +21 -14
  103. package/dist/provider-proxy/matchText.cjs +4 -2
  104. package/dist/provider-proxy/matchText.d.cts +14 -1
  105. package/dist/provider-proxy/matchText.d.ts +14 -1
  106. package/dist/provider-proxy/matchText.js +3 -1
  107. package/dist/provider-proxy/types.d.cts +23 -0
  108. package/dist/provider-proxy/types.d.ts +23 -0
  109. package/dist/provider-proxy.cjs +22 -15
  110. package/dist/provider-proxy.js +21 -14
  111. package/dist/{routeResolver-HE-ZO0fO.d.ts → routeResolver-B1NglTfe.d.ts} +36 -10
  112. package/dist/{routeResolver-BrbK6ja9.d.cts → routeResolver-CbG5uBgm.d.cts} +36 -10
  113. package/dist/transformer/transformers.cjs +7 -7
  114. package/dist/transformer/transformers.js +7 -7
  115. package/dist/transformer.cjs +5 -5
  116. package/dist/transformer.js +4 -4
  117. package/dist/types-6OUY_xfA.d.ts +830 -0
  118. package/dist/types-aBFFXoBz.d.cts +830 -0
  119. package/dist/usage/usage-recorder.cjs +2 -2
  120. package/dist/usage/usage-recorder.d.cts +19 -1
  121. package/dist/usage/usage-recorder.d.ts +19 -1
  122. package/dist/usage/usage-recorder.js +1 -1
  123. package/dist/usage.cjs +2 -2
  124. package/dist/usage.js +1 -1
  125. package/package.json +4 -2
  126. package/dist/chunk-3MEACFK3.js +0 -193
  127. package/dist/chunk-6VIXXLMX.cjs +0 -14
  128. package/dist/chunk-E3WHL7CO.js +0 -14
  129. package/dist/chunk-G2FUJNA2.cjs +0 -193
  130. package/dist/{chunk-UYPEN5XE.cjs → chunk-FFALUUZZ.cjs} +5 -5
  131. package/dist/{chunk-O466Y272.js → chunk-MQNDWYPN.js} +6 -6
@@ -0,0 +1,145 @@
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
+
4
+ var _chunk6RPZADX3cjs = require('./chunk-6RPZADX3.cjs');
5
+
6
+ // src/provider-proxy/identity/SubscriptionIdentityStore.ts
7
+ var CC_HEADER_TTL_MS = 7 * 24 * 60 * 60 * 1e3;
8
+ var KEY_SEP = "\0";
9
+ function normalizeUa(ua) {
10
+ if (typeof ua !== "string") return void 0;
11
+ const trimmed = ua.trim();
12
+ return trimmed.length > 0 ? trimmed : void 0;
13
+ }
14
+ var SubscriptionIdentityStore = (_class = class {
15
+ __init() {this.identities = /* @__PURE__ */ new Map()}
16
+
17
+
18
+
19
+
20
+ __init2() {this.persistence = null}
21
+ constructor(opts = {}) {;_class.prototype.__init.call(this);_class.prototype.__init2.call(this);
22
+ this.now = _nullishCoalesce(opts.now, () => ( Date.now));
23
+ this.enabled = _nullishCoalesce(opts.enabled, () => ( false));
24
+ this.ua = normalizeUa(opts.ua);
25
+ this.ccHeaderTtlMs = _nullishCoalesce(opts.ccHeaderTtlMs, () => ( CC_HEADER_TTL_MS));
26
+ }
27
+ /** Whether capture/replay is engaged (config flag). */
28
+ isEnabled() {
29
+ return this.enabled;
30
+ }
31
+ /** The operator UA baseline (piece 4), or undefined when unset. */
32
+ uaBaseline() {
33
+ return this.ua;
34
+ }
35
+ /**
36
+ * Re-apply config to the LIVE shared instance (bootstrap, mirroring the health
37
+ * tracker's `configure`). Only defined fields override; `ua: null` clears the
38
+ * baseline.
39
+ */
40
+ configure(opts) {
41
+ if (opts.enabled !== void 0) this.enabled = opts.enabled;
42
+ if (opts.ua !== void 0) this.ua = normalizeUa(_nullishCoalesce(opts.ua, () => ( void 0)));
43
+ }
44
+ /** Install (or clear) the write-through persistence port (P2). */
45
+ setPersistence(port) {
46
+ this.persistence = port;
47
+ }
48
+ /**
49
+ * Boot seed (P2, D5): install a PERSISTED identity for an account, but NEVER
50
+ * over a live in-memory capture (a re-captured identity from this session wins).
51
+ * A no-op for an empty/absent identity. Does NOT write back through the port.
52
+ */
53
+ seed(providerId, accountId, identity) {
54
+ if (!accountId || !identity) return;
55
+ const headers = _chunk6RPZADX3cjs.sanitizeFrozenHeaders.call(void 0, _nullishCoalesce(identity.headers, () => ( {})));
56
+ if (Object.keys(headers).length === 0) return;
57
+ const key = this.key(providerId, accountId);
58
+ if (this.identities.has(key)) return;
59
+ this.identities.set(key, {
60
+ headers,
61
+ capturedAt: typeof identity.capturedAt === "number" ? identity.capturedAt : this.now()
62
+ });
63
+ }
64
+ /**
65
+ * Capture a real client's fingerprint headers for an account. First-seen ⇒
66
+ * FREEZE the whole (sanitized) bag. Already-frozen ⇒ within the TTL, no change
67
+ * (stable identity); past the TTL, refresh the NON-stainless headers from the
68
+ * new observation while keeping stainless frozen-stable (P2). An empty/absent
69
+ * account id or an empty sanitized bag is a no-op (so an account with no
70
+ * fingerprint headers never freezes an empty identity → the caller falls back
71
+ * to the UA baseline). Fires the persistence port on a freeze/refresh.
72
+ */
73
+ capture(providerId, accountId, incoming, now = this.now()) {
74
+ if (!accountId) return;
75
+ const clean = _chunk6RPZADX3cjs.sanitizeFrozenHeaders.call(void 0, incoming);
76
+ if (Object.keys(clean).length === 0) return;
77
+ const key = this.key(providerId, accountId);
78
+ const existing = this.identities.get(key);
79
+ if (!existing) {
80
+ const frozen = { headers: clean, capturedAt: now };
81
+ this.identities.set(key, frozen);
82
+ this.emitPersist(providerId, accountId, frozen);
83
+ return;
84
+ }
85
+ if (now - existing.capturedAt < this.ccHeaderTtlMs) return;
86
+ const refreshed = {
87
+ headers: _chunk6RPZADX3cjs.refreshNonStainless.call(void 0, existing.headers, clean),
88
+ capturedAt: now
89
+ };
90
+ this.identities.set(key, refreshed);
91
+ this.emitPersist(providerId, accountId, refreshed);
92
+ }
93
+ /**
94
+ * The frozen identity headers for an account, or `undefined` when none is
95
+ * frozen (or the frozen set is empty). Returns a COPY (the caller merges it into
96
+ * a mutable outbound header bag).
97
+ */
98
+ replay(providerId, accountId) {
99
+ if (!accountId) return void 0;
100
+ const frozen = this.identities.get(this.key(providerId, accountId));
101
+ if (!frozen || Object.keys(frozen.headers).length === 0) return void 0;
102
+ return { ...frozen.headers };
103
+ }
104
+ /** Whether an identity is frozen for an account (admin coarse status — D7). */
105
+ hasIdentity(providerId, accountId) {
106
+ const frozen = this.identities.get(this.key(providerId, accountId));
107
+ return !!frozen && Object.keys(frozen.headers).length > 0;
108
+ }
109
+ /** The freeze/refresh time for an account's identity (admin coarse status). */
110
+ capturedAt(providerId, accountId) {
111
+ return _optionalChain([this, 'access', _ => _.identities, 'access', _2 => _2.get, 'call', _3 => _3(this.key(providerId, accountId)), 'optionalAccess', _4 => _4.capturedAt]);
112
+ }
113
+ emitPersist(providerId, accountId, identity) {
114
+ if (!this.persistence) return;
115
+ try {
116
+ this.persistence.persist(providerId, accountId, {
117
+ headers: { ...identity.headers },
118
+ capturedAt: identity.capturedAt
119
+ });
120
+ } catch (e) {
121
+ }
122
+ }
123
+ key(providerId, accountId) {
124
+ return `${providerId}${KEY_SEP}${accountId}`;
125
+ }
126
+ }, _class);
127
+ var _shared = null;
128
+ function getSharedIdentityStore() {
129
+ if (!_shared) _shared = new SubscriptionIdentityStore();
130
+ return _shared;
131
+ }
132
+ function setSharedIdentityStore(instance) {
133
+ _shared = instance;
134
+ }
135
+ function __resetSharedIdentityStoreForTests() {
136
+ _shared = null;
137
+ }
138
+
139
+
140
+
141
+
142
+
143
+
144
+
145
+ exports.CC_HEADER_TTL_MS = CC_HEADER_TTL_MS; exports.SubscriptionIdentityStore = SubscriptionIdentityStore; exports.getSharedIdentityStore = getSharedIdentityStore; exports.setSharedIdentityStore = setSharedIdentityStore; exports.__resetSharedIdentityStoreForTests = __resetSharedIdentityStoreForTests;
@@ -0,0 +1,89 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } }// src/pipeline/upstreamFetch.ts
2
+ var _undici = require('undici');
3
+ var _socks = require('socks');
4
+ var resolver = null;
5
+ var generation = 0;
6
+ var cache = /* @__PURE__ */ new Map();
7
+ function normalizeProxy(cfg) {
8
+ if ("url" in cfg) {
9
+ let u;
10
+ try {
11
+ u = new URL(cfg.url);
12
+ } catch (e) {
13
+ return void 0;
14
+ }
15
+ const proto = u.protocol.replace(/:$/, "").toLowerCase();
16
+ const kind2 = proto === "socks5" || proto === "socks" ? "socks5" : proto === "https" ? "https" : "http";
17
+ const port = u.port ? Number(u.port) : kind2 === "https" ? 443 : kind2 === "socks5" ? 1080 : 80;
18
+ if (!u.hostname || !Number.isFinite(port)) return void 0;
19
+ return {
20
+ kind: kind2,
21
+ host: u.hostname,
22
+ port,
23
+ username: u.username ? decodeURIComponent(u.username) : void 0,
24
+ password: u.password ? decodeURIComponent(u.password) : void 0
25
+ };
26
+ }
27
+ const kind = cfg.type === "socks5" ? "socks5" : cfg.type === "https" ? "https" : "http";
28
+ if (!cfg.host || !Number.isFinite(cfg.port)) return void 0;
29
+ return {
30
+ kind,
31
+ host: cfg.host,
32
+ port: cfg.port,
33
+ username: cfg.username || void 0,
34
+ password: cfg.password || void 0
35
+ };
36
+ }
37
+ function proxyKey(p) {
38
+ return `${p.kind}://${_nullishCoalesce(p.username, () => ( ""))}:${_nullishCoalesce(p.password, () => ( ""))}@${p.host}:${p.port}`;
39
+ }
40
+ function socksConnector(p) {
41
+ const base = _undici.buildConnector.call(void 0, {});
42
+ return ((options, callback) => {
43
+ const destPort = Number(options.port) || (options.protocol === "https:" ? 443 : 80);
44
+ _socks.SocksClient.createConnection({
45
+ proxy: { host: p.host, port: p.port, type: 5, userId: p.username, password: p.password },
46
+ command: "connect",
47
+ destination: { host: options.hostname, port: destPort }
48
+ }).then(({ socket }) => {
49
+ base({ ...options, httpSocket: socket }, callback);
50
+ }).catch((err) => callback(err, null));
51
+ });
52
+ }
53
+ function buildDispatcher(p) {
54
+ if (p.kind === "socks5") {
55
+ return new (0, _undici.Agent)({ connect: socksConnector(p) });
56
+ }
57
+ const auth = p.username != null ? `${encodeURIComponent(p.username)}:${encodeURIComponent(_nullishCoalesce(p.password, () => ( "")))}@` : "";
58
+ const uri = `${p.kind}://${auth}${p.host}:${p.port}`;
59
+ return new (0, _undici.ProxyAgent)({ uri });
60
+ }
61
+ function resolveUpstreamDispatcher(ctx) {
62
+ const active = resolver;
63
+ if (!active) return void 0;
64
+ let cfg;
65
+ try {
66
+ cfg = active(ctx);
67
+ } catch (e2) {
68
+ return void 0;
69
+ }
70
+ if (!cfg) return void 0;
71
+ const norm = normalizeProxy(cfg);
72
+ if (!norm) return void 0;
73
+ const key = `${generation}\0${proxyKey(norm)}`;
74
+ let dispatcher = cache.get(key);
75
+ if (!dispatcher) {
76
+ dispatcher = buildDispatcher(norm);
77
+ cache.set(key, dispatcher);
78
+ }
79
+ return dispatcher;
80
+ }
81
+ function fetchUpstream(url, init, ctx) {
82
+ const dispatcher = resolveUpstreamDispatcher({ ..._nullishCoalesce(ctx, () => ( {})), url });
83
+ if (!dispatcher) return fetch(url, init);
84
+ return fetch(url, { ...init, dispatcher });
85
+ }
86
+
87
+
88
+
89
+ exports.fetchUpstream = fetchUpstream;
@@ -0,0 +1,383 @@
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; }
2
+
3
+ var _chunkQBZJ7P2Tcjs = require('./chunk-QBZJ7P2T.cjs');
4
+
5
+
6
+ var _chunk4IH4EL7Mcjs = require('./chunk-4IH4EL7M.cjs');
7
+
8
+ // src/outbound-api/kindDetection.ts
9
+ var _canonicalmodels = require('@omnicross/contracts/canonical-models');
10
+
11
+ // src/outbound-api/roleDetection.ts
12
+
13
+ var BACKGROUND_TIER_TOKENS = /* @__PURE__ */ new Set([
14
+ "haiku",
15
+ "mini",
16
+ "flash",
17
+ "small",
18
+ "lite",
19
+ "nano",
20
+ "8b"
21
+ ]);
22
+ function modelTokens(normalizedId) {
23
+ return normalizedId.split(/[-._:/\s]+/).filter(Boolean);
24
+ }
25
+ function isBackgroundTierModel(rawModelId) {
26
+ if (!rawModelId) return false;
27
+ const tokens = modelTokens(_canonicalmodels.normalizeModelId.call(void 0, rawModelId));
28
+ return tokens.some((tok) => BACKGROUND_TIER_TOKENS.has(tok));
29
+ }
30
+ function extractRequestedModel(ingressFormat, body) {
31
+ const model = body["model"];
32
+ return typeof model === "string" && model ? model : void 0;
33
+ }
34
+ function detectRequestRole(ingressFormat, body, options) {
35
+ const requestedModel = extractRequestedModel(ingressFormat, body);
36
+ if (requestedModel) {
37
+ const overrides = _optionalChain([options, 'optionalAccess', _ => _.backgroundModelIds]);
38
+ if (overrides && overrides.length > 0) {
39
+ const reqNorm = _canonicalmodels.normalizeModelId.call(void 0, requestedModel);
40
+ const inOverride = overrides.some((id) => {
41
+ if (!id) return false;
42
+ const candidate = id.includes(",") ? id.slice(id.indexOf(",") + 1) : id;
43
+ return _canonicalmodels.normalizeModelId.call(void 0, candidate) === reqNorm || candidate === requestedModel;
44
+ });
45
+ if (inOverride) return "background";
46
+ }
47
+ if (isBackgroundTierModel(requestedModel)) return "background";
48
+ }
49
+ return "default";
50
+ }
51
+ function endpointToIngressFormat(endpoint) {
52
+ switch (endpoint) {
53
+ case "chat":
54
+ return "openai-chat";
55
+ case "responses":
56
+ return "openai-responses";
57
+ case "messages":
58
+ return "anthropic-messages";
59
+ case "gemini":
60
+ return "gemini-generatecontent";
61
+ }
62
+ }
63
+
64
+ // src/outbound-api/kindDetection.ts
65
+ function isNonBlankRef(ref) {
66
+ return typeof ref === "string" && ref.trim() !== "";
67
+ }
68
+ function isKindMappedEndpoint(endpoint) {
69
+ return Object.prototype.hasOwnProperty.call(_chunk4IH4EL7Mcjs.ENDPOINT_MODEL_KINDS, endpoint);
70
+ }
71
+ function modelKindsForEndpoint(endpoint) {
72
+ return _chunk4IH4EL7Mcjs.ENDPOINT_MODEL_KINDS[endpoint];
73
+ }
74
+ function detectModelKind(endpoint, requestedModelId) {
75
+ if (!requestedModelId || requestedModelId.trim() === "") return void 0;
76
+ if (endpoint === "messages") {
77
+ const declared = _chunk4IH4EL7Mcjs.ENDPOINT_MODEL_KINDS.messages;
78
+ for (const tok of modelTokens(_canonicalmodels.normalizeModelId.call(void 0, requestedModelId))) {
79
+ if (declared.includes(tok)) return tok;
80
+ }
81
+ return void 0;
82
+ }
83
+ return isBackgroundTierModel(requestedModelId) ? "mini" : "codex";
84
+ }
85
+ function validateEndpointModelConfig(config) {
86
+ if (!isKindMappedEndpoint(config.endpoint)) return [];
87
+ const map = _nullishCoalesce(config.modelMap, () => ( {}));
88
+ return modelKindsForEndpoint(config.endpoint).filter(
89
+ (kind) => !isNonBlankRef(map[kind])
90
+ );
91
+ }
92
+ function validateServerModelConfig(config) {
93
+ const errors = [];
94
+ for (const endpoint of Object.keys(_chunk4IH4EL7Mcjs.ENDPOINT_MODEL_KINDS)) {
95
+ const ep = config.endpoints.find((e) => e.endpoint === endpoint);
96
+ const declared = modelKindsForEndpoint(endpoint);
97
+ const missingKinds = ep ? validateEndpointModelConfig(ep) : [...declared];
98
+ if (missingKinds.length > 0 && missingKinds.length < declared.length) {
99
+ errors.push({ endpoint, missingKinds });
100
+ }
101
+ }
102
+ return errors;
103
+ }
104
+
105
+ // src/outbound-api/modelPrefixDispatch.ts
106
+ function classifyModelPrefix(model) {
107
+ if (!model) return null;
108
+ const id = model.trim().toLowerCase();
109
+ if (!id) return null;
110
+ if (matchesPrefix(id, "claude")) return "claude";
111
+ if (matchesPrefix(id, "gemini")) return "gemini";
112
+ if (matchesPrefix(id, "gpt") || matchesOSeries(id)) return "gpt";
113
+ return null;
114
+ }
115
+ function matchesPrefix(id, prefix) {
116
+ return id === prefix || id.startsWith(`${prefix}-`);
117
+ }
118
+ function matchesOSeries(id) {
119
+ return /^o\d/.test(id);
120
+ }
121
+ function resolvePrefixTarget(targets, model) {
122
+ const kind = classifyModelPrefix(model);
123
+ if (!kind) return null;
124
+ const ref = _optionalChain([targets, 'optionalAccess', _2 => _2[kind]]);
125
+ if (!ref || !ref.trim()) return null;
126
+ return { kind, ref };
127
+ }
128
+
129
+ // src/outbound-api/subscriptionSupport.ts
130
+ var SUBSCRIPTION_PROVIDER_IDS = [
131
+ "claude",
132
+ "codex",
133
+ "gemini",
134
+ "opencodego"
135
+ ];
136
+ var SUBSCRIPTION_ID_SET = new Set(SUBSCRIPTION_PROVIDER_IDS);
137
+ function isSubscriptionProviderId(providerId) {
138
+ if (SUBSCRIPTION_ID_SET.has(providerId)) return true;
139
+ const registry = _chunkQBZJ7P2Tcjs.getSubscriptionRegistryForOutbound.call(void 0, );
140
+ return _optionalChain([registry, 'optionalAccess', _3 => _3.getProfile, 'call', _4 => _4(providerId)]) != null;
141
+ }
142
+ var SUBSCRIPTION_SUPPORTED_ENDPOINTS = /* @__PURE__ */ new Set([
143
+ "messages",
144
+ "responses",
145
+ "chat"
146
+ ]);
147
+ function endpointSupportsSubscription(endpoint) {
148
+ return SUBSCRIPTION_SUPPORTED_ENDPOINTS.has(endpoint);
149
+ }
150
+
151
+ // src/outbound-api/routeResolver.ts
152
+ function parseModelRef(ref) {
153
+ if (!ref) return null;
154
+ const idx = ref.indexOf(",");
155
+ if (idx <= 0) return null;
156
+ const providerId = ref.slice(0, idx).trim();
157
+ const modelId = ref.slice(idx + 1).trim();
158
+ if (!providerId || !modelId) return null;
159
+ return { providerId, modelId };
160
+ }
161
+ var MESSAGES_FALLBACK_ORDER = ["sonnet", "opus", "haiku", "fable"];
162
+ function isNonBlankRef2(ref) {
163
+ return typeof ref === "string" && ref.trim() !== "";
164
+ }
165
+ function pickModelRefFromList(models, requestedModel) {
166
+ if (!requestedModel || !models || models.length === 0) return void 0;
167
+ const wanted = requestedModel.trim();
168
+ let ciHit;
169
+ for (const ref of models) {
170
+ const parsed = parseModelRef(ref);
171
+ if (!parsed) continue;
172
+ if (parsed.modelId === wanted) return ref;
173
+ if (!ciHit && parsed.modelId.toLowerCase() === wanted.toLowerCase()) ciHit = ref;
174
+ }
175
+ return ciHit;
176
+ }
177
+ function pickModelRefForRole(config, role) {
178
+ if (role === "background") {
179
+ return { ref: config.backgroundModel, effectiveRole: "background" };
180
+ }
181
+ return { ref: config.defaultModel, effectiveRole: "default" };
182
+ }
183
+ function pickModelRefForKind(config, endpoint, requestedModel) {
184
+ const map = _nullishCoalesce(config.modelMap, () => ( {}));
185
+ const detected = detectModelKind(endpoint, requestedModel);
186
+ const kind = _nullishCoalesce(detected, () => ( "unmapped"));
187
+ if (detected && isNonBlankRef2(map[detected])) {
188
+ return { ref: map[detected], kind: detected };
189
+ }
190
+ if (endpoint === "messages") {
191
+ for (const k of MESSAGES_FALLBACK_ORDER) {
192
+ if (isNonBlankRef2(map[k])) return { ref: map[k], kind };
193
+ }
194
+ return { ref: void 0, kind };
195
+ }
196
+ if (isNonBlankRef2(map["codex"])) return { ref: map["codex"], kind };
197
+ return { ref: void 0, kind };
198
+ }
199
+ async function resolveRoute(args) {
200
+ const { config, ingressFormat, llmConfig } = args;
201
+ const sessionId = _nullishCoalesce(args.sessionId, () => ( null));
202
+ const endpoint = config.endpoint;
203
+ const kindMapped = isKindMappedEndpoint(endpoint);
204
+ const requestedModel = kindMapped ? args.requestedModel : void 0;
205
+ let ref;
206
+ let effectiveRole = "default";
207
+ let noModelStatus = 503;
208
+ let noModelMessage;
209
+ let malformedMessage;
210
+ if (kindMapped) {
211
+ const picked = pickModelRefForKind(config, endpoint, args.requestedModel);
212
+ ref = picked.ref;
213
+ noModelMessage = `endpoint '${config.endpoint}' has no model configured for kind '${picked.kind}'`;
214
+ malformedMessage = (r) => `endpoint '${config.endpoint}' model ref for kind '${picked.kind}' is malformed: '${r}'`;
215
+ } else if (endpoint === "chat" && config.dispatchMode === "prefix") {
216
+ ref = _optionalChain([resolvePrefixTarget, 'call', _5 => _5(config.prefixTargets, args.requestedModel), 'optionalAccess', _6 => _6.ref]);
217
+ noModelStatus = 404;
218
+ noModelMessage = args.requestedModel ? `model '${args.requestedModel}' has no matching prefix target (claude-* / gpt-* / gemini-*) on the 'chat' endpoint` : `request has no 'model'; a prefix-dispatch 'chat' endpoint routes claude-* / gpt-* / gemini-*`;
219
+ malformedMessage = (r) => `endpoint 'chat' prefix target ref is malformed: '${r}'`;
220
+ } else if (endpoint === "chat") {
221
+ ref = pickModelRefFromList(config.models, args.requestedModel);
222
+ noModelStatus = 404;
223
+ noModelMessage = args.requestedModel ? `model '${args.requestedModel}' is not in the endpoint's model list (see GET /v1/models)` : `request has no 'model'; pick one from GET /v1/models`;
224
+ malformedMessage = (r) => `endpoint 'chat' model ref is malformed: '${r}'`;
225
+ } else {
226
+ const picked = pickModelRefForRole(config, _nullishCoalesce(args.role, () => ( "default")));
227
+ ref = picked.ref;
228
+ effectiveRole = picked.effectiveRole;
229
+ noModelMessage = `endpoint '${config.endpoint}' has no ${effectiveRole} model configured`;
230
+ malformedMessage = (r) => `endpoint '${config.endpoint}' ${effectiveRole} model ref is malformed: '${r}'`;
231
+ }
232
+ if (!ref || !ref.trim()) {
233
+ return { ok: false, error: { status: noModelStatus, message: noModelMessage } };
234
+ }
235
+ const parsed = parseModelRef(ref);
236
+ if (!parsed) {
237
+ return { ok: false, error: { status: 503, message: malformedMessage(ref) } };
238
+ }
239
+ const { providerId, modelId } = parsed;
240
+ const provider = await llmConfig.getProvider(providerId);
241
+ if (!provider) {
242
+ if (isSubscriptionProviderId(providerId)) {
243
+ return await resolveSubscriptionRoute({
244
+ config,
245
+ providerId,
246
+ modelId,
247
+ ingressFormat,
248
+ sessionId,
249
+ effectiveRole,
250
+ requestedModel,
251
+ apiKeyId: args.apiKeyId
252
+ });
253
+ }
254
+ return {
255
+ ok: false,
256
+ error: {
257
+ status: 503,
258
+ message: `provider '${providerId}' not found for endpoint '${config.endpoint}'`
259
+ }
260
+ };
261
+ }
262
+ const isOfficialProvider = provider.isOfficial === true || provider.id === "anthropic";
263
+ const targetProviderFormat = isOfficialProvider ? "anthropic" : "transform";
264
+ let anthropicSdkHints = null;
265
+ if (ingressFormat === "anthropic-messages") {
266
+ anthropicSdkHints = {
267
+ apiKey: resolveApiKey(provider.api_key),
268
+ isOfficialProvider,
269
+ passThrough: false,
270
+ attribution: { sessionId, apiKeyId: _nullishCoalesce(args.apiKeyId, () => ( null)) }
271
+ };
272
+ }
273
+ const route = {
274
+ sessionId,
275
+ targetProviderFormat,
276
+ model: modelId,
277
+ ingressFormat,
278
+ authMode: "byo",
279
+ providerId,
280
+ // Passthrough gate: the client's ORIGINAL requested id (kind-mapped only).
281
+ requestedModel,
282
+ // Usage attribution: the verified named-key id (undefined for internal traffic).
283
+ apiKeyId: args.apiKeyId,
284
+ anthropicSdkHints
285
+ };
286
+ return { ok: true, route, usedRole: effectiveRole };
287
+ }
288
+ async function resolveSubscriptionRoute(args) {
289
+ const { config, providerId, modelId, ingressFormat, sessionId, effectiveRole } = args;
290
+ const { requestedModel, apiKeyId } = args;
291
+ if (!config.useSubscription) {
292
+ return {
293
+ ok: false,
294
+ error: {
295
+ status: 503,
296
+ message: `subscription routing disabled for endpoint '${config.endpoint}'`
297
+ }
298
+ };
299
+ }
300
+ if (!endpointSupportsSubscription(config.endpoint)) {
301
+ return {
302
+ ok: false,
303
+ error: {
304
+ status: 503,
305
+ message: `subscription routing is not supported on the '${config.endpoint}' endpoint; use a BYO API-key provider, or the /v1/messages or /v1/responses endpoint`
306
+ }
307
+ };
308
+ }
309
+ const registry = _chunkQBZJ7P2Tcjs.getSubscriptionRegistryForOutbound.call(void 0, );
310
+ const profile = _nullishCoalesce(_optionalChain([registry, 'optionalAccess', _7 => _7.getProfile, 'call', _8 => _8(providerId)]), () => ( null));
311
+ if (!profile) {
312
+ return {
313
+ ok: false,
314
+ error: {
315
+ status: 503,
316
+ message: `subscription provider '${providerId}' is not available`
317
+ }
318
+ };
319
+ }
320
+ const hints = {
321
+ apiKey: "",
322
+ isOfficialProvider: false,
323
+ passThrough: false,
324
+ subscriptionProfile: profile,
325
+ attribution: { sessionId, apiKeyId: _nullishCoalesce(apiKeyId, () => ( null)) }
326
+ };
327
+ const subscriptionConfig = providerId === "opencodego" ? await _optionalChain([registry, 'optionalAccess', _9 => _9.getOpenCodeGoConfig, 'optionalCall', _10 => _10()]) : void 0;
328
+ const route = {
329
+ sessionId,
330
+ targetProviderFormat: "transform",
331
+ model: modelId,
332
+ ingressFormat,
333
+ authMode: "subscription",
334
+ providerId,
335
+ // Passthrough gate: the client's ORIGINAL requested id (kind-mapped only).
336
+ requestedModel,
337
+ // Usage attribution: the verified named-key id (undefined for internal traffic).
338
+ apiKeyId,
339
+ // Anthropic delegation carries the dispatch profile inside
340
+ // `anthropicSdkHints.subscriptionProfile`. The Responses ingress reads the
341
+ // TOP-LEVEL `route.subscriptionProfile`, and so does the built-in
342
+ // (factory-absent) `/v1/messages` subscription path (RT2.1) — the registry's
343
+ // `SubscriptionDispatchProfile` structurally satisfies `SubscriptionAuthProfile`
344
+ // ({ authStrategy, resolveUpstreamUrl, providerTransformerNames }), so set it
345
+ // for BOTH. This is INERT when an Anthropic ingress factory is present: that
346
+ // delegation reads the hint-bundle field above (and uses a different
347
+ // route-minting path), never the top-level field. (chat/gemini never reach
348
+ // here — Gate 2 rejected them.)
349
+ subscriptionProfile: ingressFormat === "openai-responses" || ingressFormat === "anthropic-messages" || ingressFormat === "openai-chat" ? profile : void 0,
350
+ // Opaque per-account config (opencodego-only; `undefined` otherwise). Read by
351
+ // the built-in `/v1/messages` plan builder; INERT for the factory-present
352
+ // delegation path + non-opencodego.
353
+ subscriptionConfig,
354
+ anthropicSdkHints: hints
355
+ };
356
+ return { ok: true, route, usedRole: effectiveRole };
357
+ }
358
+ function resolveApiKey(apiKey) {
359
+ if (!apiKey) return "";
360
+ if (apiKey.startsWith("$")) {
361
+ return process.env[apiKey.slice(1)] || "";
362
+ }
363
+ return apiKey;
364
+ }
365
+
366
+
367
+
368
+
369
+
370
+
371
+
372
+
373
+
374
+
375
+
376
+
377
+
378
+
379
+
380
+
381
+
382
+
383
+ exports.extractRequestedModel = extractRequestedModel; exports.detectRequestRole = detectRequestRole; exports.endpointToIngressFormat = endpointToIngressFormat; exports.isKindMappedEndpoint = isKindMappedEndpoint; exports.modelKindsForEndpoint = modelKindsForEndpoint; exports.detectModelKind = detectModelKind; exports.validateEndpointModelConfig = validateEndpointModelConfig; exports.validateServerModelConfig = validateServerModelConfig; exports.classifyModelPrefix = classifyModelPrefix; exports.resolvePrefixTarget = resolvePrefixTarget; exports.SUBSCRIPTION_PROVIDER_IDS = SUBSCRIPTION_PROVIDER_IDS; exports.isSubscriptionProviderId = isSubscriptionProviderId; exports.endpointSupportsSubscription = endpointSupportsSubscription; exports.parseModelRef = parseModelRef; exports.pickModelRefFromList = pickModelRefFromList; exports.resolveRoute = resolveRoute;
@@ -0,0 +1,32 @@
1
+ // src/pipeline/billingEmit.ts
2
+ var sink = null;
3
+ var captureConfig = null;
4
+ function setBillingSink(fn) {
5
+ sink = fn;
6
+ }
7
+ function setBillingCaptureConfig(config) {
8
+ captureConfig = config && config.enabled ? config : null;
9
+ }
10
+ function getBillingCaptureConfig() {
11
+ return captureConfig;
12
+ }
13
+ function publishBillingEvent(event) {
14
+ const active = sink;
15
+ if (!active) return;
16
+ try {
17
+ active(event);
18
+ } catch {
19
+ }
20
+ }
21
+ function __resetBillingSinkForTests() {
22
+ sink = null;
23
+ captureConfig = null;
24
+ }
25
+
26
+ export {
27
+ setBillingSink,
28
+ setBillingCaptureConfig,
29
+ getBillingCaptureConfig,
30
+ publishBillingEvent,
31
+ __resetBillingSinkForTests
32
+ };
@@ -1,7 +1,9 @@
1
+ import {
2
+ OPENROUTER_APP_HEADERS
3
+ } from "./chunk-HUZZZ3JL.js";
4
+
1
5
  // src/completion/openrouter-headers.ts
2
6
  var OPENROUTER_DEFAULT_BASE_URL = "https://openrouter.ai/api/v1";
3
- var OPENROUTER_HTTP_REFERER = "https://omnicross.dev";
4
- var OPENROUTER_X_TITLE = "Omnicross";
5
7
  function buildOpenRouterHeaders(credentials, options = {}) {
6
8
  const apiKey = credentials.apiKey?.trim();
7
9
  if (!apiKey) {
@@ -9,8 +11,7 @@ function buildOpenRouterHeaders(credentials, options = {}) {
9
11
  }
10
12
  const headers = {
11
13
  Authorization: `Bearer ${apiKey}`,
12
- "HTTP-Referer": OPENROUTER_HTTP_REFERER,
13
- "X-Title": OPENROUTER_X_TITLE
14
+ ...OPENROUTER_APP_HEADERS
14
15
  };
15
16
  if (options.contentType !== false) {
16
17
  headers["Content-Type"] = options.contentType ?? "application/json";
@@ -35,8 +36,6 @@ function buildOpenRouterUrl(endpoint, path) {
35
36
 
36
37
  export {
37
38
  OPENROUTER_DEFAULT_BASE_URL,
38
- OPENROUTER_HTTP_REFERER,
39
- OPENROUTER_X_TITLE,
40
39
  buildOpenRouterHeaders,
41
40
  resolveOpenRouterBaseUrl,
42
41
  buildOpenRouterUrl