@wopr-network/platform-core 1.51.0 → 1.53.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/dist/gateway/proxy.d.ts +3 -0
- package/dist/gateway/proxy.js +11 -2
- package/dist/gateway/types.d.ts +5 -0
- package/package.json +1 -1
- package/src/gateway/proxy.ts +14 -2
- package/src/gateway/types.ts +5 -0
package/dist/gateway/proxy.d.ts
CHANGED
|
@@ -24,6 +24,9 @@ export interface ProxyDeps {
|
|
|
24
24
|
topUpUrl: string;
|
|
25
25
|
graceBufferCents?: number;
|
|
26
26
|
providers: ProviderConfig;
|
|
27
|
+
defaultModel?: string;
|
|
28
|
+
/** Dynamic model resolver — called per-request, overrides defaultModel. Return null to use defaultModel fallback. */
|
|
29
|
+
resolveDefaultModel?: () => string | null;
|
|
27
30
|
defaultMargin: number;
|
|
28
31
|
fetchFn: FetchFn;
|
|
29
32
|
arbitrageRouter?: import("../monetization/arbitrage/router.js").ArbitrageRouter;
|
package/dist/gateway/proxy.js
CHANGED
|
@@ -52,6 +52,8 @@ export function buildProxyDeps(config) {
|
|
|
52
52
|
topUpUrl: config.topUpUrl ?? "/dashboard/credits",
|
|
53
53
|
graceBufferCents: config.graceBufferCents,
|
|
54
54
|
providers: config.providers,
|
|
55
|
+
defaultModel: config.defaultModel,
|
|
56
|
+
resolveDefaultModel: config.resolveDefaultModel,
|
|
55
57
|
defaultMargin: config.defaultMargin ?? DEFAULT_MARGIN,
|
|
56
58
|
fetchFn: config.fetchFn ?? fetch,
|
|
57
59
|
arbitrageRouter: config.arbitrageRouter,
|
|
@@ -108,18 +110,25 @@ export function chatCompletions(deps) {
|
|
|
108
110
|
return c.json({ error: creditErr }, 402);
|
|
109
111
|
}
|
|
110
112
|
// Parse body once — needed for both arbitrage routing and direct proxy.
|
|
111
|
-
const
|
|
113
|
+
const rawBody = await c.req.text();
|
|
112
114
|
let isStreaming = false;
|
|
113
115
|
let requestModel;
|
|
114
116
|
let parsedBody;
|
|
117
|
+
// Resolve the enforced model once — dynamic DB resolver takes priority over static env var.
|
|
118
|
+
const enforcedModel = deps.resolveDefaultModel?.() ?? deps.defaultModel ?? null;
|
|
115
119
|
try {
|
|
116
|
-
parsedBody = JSON.parse(
|
|
120
|
+
parsedBody = JSON.parse(rawBody);
|
|
117
121
|
isStreaming = parsedBody?.stream === true;
|
|
122
|
+
if (enforcedModel && parsedBody) {
|
|
123
|
+
parsedBody.model = enforcedModel;
|
|
124
|
+
}
|
|
118
125
|
requestModel = parsedBody?.model;
|
|
119
126
|
}
|
|
120
127
|
catch {
|
|
121
128
|
// Not valid JSON, assume non-streaming
|
|
122
129
|
}
|
|
130
|
+
// Re-serialize if model was overridden, otherwise forward raw body.
|
|
131
|
+
const body = enforcedModel && parsedBody ? JSON.stringify(parsedBody) : rawBody;
|
|
123
132
|
deps.metrics?.recordGatewayRequest("chat-completions");
|
|
124
133
|
// WOP-746: Arbitrage routing for non-streaming chat completions.
|
|
125
134
|
// Mirrors the TTS arbitrage pattern. When arbitrageRouter is present and
|
package/dist/gateway/types.d.ts
CHANGED
|
@@ -102,6 +102,11 @@ export interface ProviderConfig {
|
|
|
102
102
|
}
|
|
103
103
|
/** Full gateway configuration. */
|
|
104
104
|
export interface GatewayConfig {
|
|
105
|
+
/** Static model override — rewrites body.model before forwarding to upstream. */
|
|
106
|
+
defaultModel?: string;
|
|
107
|
+
/** Dynamic model resolver — called per-request, takes priority over defaultModel.
|
|
108
|
+
* Return null to fall back to defaultModel / client-specified. */
|
|
109
|
+
resolveDefaultModel?: () => string | null;
|
|
105
110
|
/** MeterEmitter instance for usage tracking */
|
|
106
111
|
meter: MeterEmitter;
|
|
107
112
|
/** BudgetChecker instance for pre-call budget validation */
|
package/package.json
CHANGED
package/src/gateway/proxy.ts
CHANGED
|
@@ -67,6 +67,9 @@ export interface ProxyDeps {
|
|
|
67
67
|
topUpUrl: string;
|
|
68
68
|
graceBufferCents?: number;
|
|
69
69
|
providers: ProviderConfig;
|
|
70
|
+
defaultModel?: string;
|
|
71
|
+
/** Dynamic model resolver — called per-request, overrides defaultModel. Return null to use defaultModel fallback. */
|
|
72
|
+
resolveDefaultModel?: () => string | null;
|
|
70
73
|
defaultMargin: number;
|
|
71
74
|
fetchFn: FetchFn;
|
|
72
75
|
arbitrageRouter?: import("../monetization/arbitrage/router.js").ArbitrageRouter;
|
|
@@ -91,6 +94,8 @@ export function buildProxyDeps(config: GatewayConfig): ProxyDeps {
|
|
|
91
94
|
topUpUrl: config.topUpUrl ?? "/dashboard/credits",
|
|
92
95
|
graceBufferCents: config.graceBufferCents,
|
|
93
96
|
providers: config.providers,
|
|
97
|
+
defaultModel: config.defaultModel,
|
|
98
|
+
resolveDefaultModel: config.resolveDefaultModel,
|
|
94
99
|
defaultMargin: config.defaultMargin ?? DEFAULT_MARGIN,
|
|
95
100
|
fetchFn: config.fetchFn ?? fetch,
|
|
96
101
|
arbitrageRouter: config.arbitrageRouter,
|
|
@@ -166,7 +171,7 @@ export function chatCompletions(deps: ProxyDeps) {
|
|
|
166
171
|
}
|
|
167
172
|
|
|
168
173
|
// Parse body once — needed for both arbitrage routing and direct proxy.
|
|
169
|
-
const
|
|
174
|
+
const rawBody = await c.req.text();
|
|
170
175
|
let isStreaming = false;
|
|
171
176
|
let requestModel: string | undefined;
|
|
172
177
|
let parsedBody:
|
|
@@ -178,13 +183,20 @@ export function chatCompletions(deps: ProxyDeps) {
|
|
|
178
183
|
temperature?: number;
|
|
179
184
|
}
|
|
180
185
|
| undefined;
|
|
186
|
+
// Resolve the enforced model once — dynamic DB resolver takes priority over static env var.
|
|
187
|
+
const enforcedModel = deps.resolveDefaultModel?.() ?? deps.defaultModel ?? null;
|
|
181
188
|
try {
|
|
182
|
-
parsedBody = JSON.parse(
|
|
189
|
+
parsedBody = JSON.parse(rawBody) as typeof parsedBody;
|
|
183
190
|
isStreaming = parsedBody?.stream === true;
|
|
191
|
+
if (enforcedModel && parsedBody) {
|
|
192
|
+
parsedBody.model = enforcedModel;
|
|
193
|
+
}
|
|
184
194
|
requestModel = parsedBody?.model;
|
|
185
195
|
} catch {
|
|
186
196
|
// Not valid JSON, assume non-streaming
|
|
187
197
|
}
|
|
198
|
+
// Re-serialize if model was overridden, otherwise forward raw body.
|
|
199
|
+
const body = enforcedModel && parsedBody ? JSON.stringify(parsedBody) : rawBody;
|
|
188
200
|
|
|
189
201
|
deps.metrics?.recordGatewayRequest("chat-completions");
|
|
190
202
|
|
package/src/gateway/types.ts
CHANGED
|
@@ -98,6 +98,11 @@ export interface ProviderConfig {
|
|
|
98
98
|
|
|
99
99
|
/** Full gateway configuration. */
|
|
100
100
|
export interface GatewayConfig {
|
|
101
|
+
/** Static model override — rewrites body.model before forwarding to upstream. */
|
|
102
|
+
defaultModel?: string;
|
|
103
|
+
/** Dynamic model resolver — called per-request, takes priority over defaultModel.
|
|
104
|
+
* Return null to fall back to defaultModel / client-specified. */
|
|
105
|
+
resolveDefaultModel?: () => string | null;
|
|
101
106
|
/** MeterEmitter instance for usage tracking */
|
|
102
107
|
meter: MeterEmitter;
|
|
103
108
|
/** BudgetChecker instance for pre-call budget validation */
|