@omnicross/subscriptions 0.1.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 -0
- package/NOTICE +45 -0
- package/README.md +15 -0
- package/dist/index.cjs +1679 -0
- package/dist/index.d.cts +868 -0
- package/dist/index.d.ts +868 -0
- package/dist/index.js +1639 -0
- package/dist/oauth.cjs +396 -0
- package/dist/oauth.d.cts +131 -0
- package/dist/oauth.d.ts +131 -0
- package/dist/oauth.js +363 -0
- package/package.json +58 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,868 @@
|
|
|
1
|
+
import { AccountTokensConfig } from '@omnicross/contracts/account-tokens-types';
|
|
2
|
+
import { SubscriptionProviderId, SubscriptionStatusEntry, SubscriptionListEntry, OpenCodeGoTokenConfig, OpenCodeGoScenario, OpenCodeGoModelEntry } from '@omnicross/contracts/subscription-types';
|
|
3
|
+
import http from 'node:http';
|
|
4
|
+
export { FetchLike, claudeOAuth, codexOAuth, geminiOAuth } from './oauth.js';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* SubscriptionCredentialStore — the credential port the subscription block
|
|
8
|
+
* depends on instead of the host's concrete token store.
|
|
9
|
+
*
|
|
10
|
+
* The subscription auth strategies + account service + provider registry only
|
|
11
|
+
* ever consume a narrow six-method surface of the host's encrypted OAuth/static
|
|
12
|
+
* credential store. Declaring it here (in `@omnicross/subscriptions`) keeps the
|
|
13
|
+
* package host-clean: the host injects its concrete token store (which
|
|
14
|
+
* structurally satisfies this interface) at bootstrap.
|
|
15
|
+
*
|
|
16
|
+
* The serving core (`@omnicross/core`) does NOT consume credentials — it sees
|
|
17
|
+
* the subscription registry only through the `subscriptionRegistryPort` slot —
|
|
18
|
+
* so this port lives in THIS package, not in core (Phase-0b port pattern at the
|
|
19
|
+
* subscriptions layer).
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
/** The six methods the subscription block consumes from the host credential store. */
|
|
23
|
+
interface SubscriptionCredentialStore {
|
|
24
|
+
/** Full decrypted account-tokens config (all subscription providers). */
|
|
25
|
+
getFullConfig(): Promise<AccountTokensConfig>;
|
|
26
|
+
/** Current valid Claude OAuth access token, refreshing if near expiry; `null` if none. */
|
|
27
|
+
getValidClaudeAccessToken(): Promise<string | null>;
|
|
28
|
+
/** Force a Claude OAuth token refresh; `true` on success. */
|
|
29
|
+
refreshClaudeToken(): Promise<boolean>;
|
|
30
|
+
/** Force a Codex (ChatGPT) OAuth token refresh; `true` on success. */
|
|
31
|
+
refreshCodexToken(): Promise<boolean>;
|
|
32
|
+
/** Force a Gemini (Google) OAuth token refresh; `true` on success. */
|
|
33
|
+
refreshGeminiToken(): Promise<boolean>;
|
|
34
|
+
/** Current valid OpenCodeGo static API key; `null` if none. */
|
|
35
|
+
getValidOpenCodeGoApiKey(): Promise<string | null>;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* SubscriptionAuthStrategy — the pluggable subscription-auth contract, defined
|
|
40
|
+
* in the serving core (`pipeline/`).
|
|
41
|
+
*
|
|
42
|
+
* Each subscription provider in the `SubscriptionProviderRegistry` (the
|
|
43
|
+
* subscriptions package) carries an `AuthStrategy` instance. The proxy calls
|
|
44
|
+
* `applyHeaders` before issuing the upstream request and `onUnauthorized`
|
|
45
|
+
* after a 401 to ask whether to retry.
|
|
46
|
+
*
|
|
47
|
+
* It is a PURE contract (no upstream semantics), defined down here so
|
|
48
|
+
* `pipeline/SubscriptionAuthSource.ts` consumes it WITHOUT importing upward
|
|
49
|
+
* (correct dependency direction). The subscriptions package's
|
|
50
|
+
* `auth/AuthStrategy.ts` RE-EXPORTS this type, and its three concrete
|
|
51
|
+
* strategies implement THIS interface — so they remain assignable and no
|
|
52
|
+
* downstream consumer's import path changes.
|
|
53
|
+
*
|
|
54
|
+
* NOTE: this `AuthApplyHints` (OPTIONAL fields) is the SUBSCRIPTION-side hint
|
|
55
|
+
* shape and is intentionally distinct from `pipeline/AuthSource.ts`'s
|
|
56
|
+
* `AuthApplyHints` (REQUIRED fields). They are not interchangeable; the
|
|
57
|
+
* `SubscriptionAuthSource` adapter maps between them at the boundary.
|
|
58
|
+
*
|
|
59
|
+
* @module pipeline/SubscriptionAuthStrategy
|
|
60
|
+
*/
|
|
61
|
+
|
|
62
|
+
/** Hints the strategy may need to vary header formatting per request. */
|
|
63
|
+
interface AuthApplyHints {
|
|
64
|
+
/** Resolved upstream URL — used by some strategies (e.g. OpenCodeGo) to
|
|
65
|
+
* choose between Anthropic-shape and OpenAI-shape headers. */
|
|
66
|
+
upstreamUrl?: string;
|
|
67
|
+
/** Resolved model id — same purpose as `upstreamUrl`. */
|
|
68
|
+
resolvedModel?: string;
|
|
69
|
+
}
|
|
70
|
+
interface AuthStrategy {
|
|
71
|
+
/** Discriminator — also surfaced through `subscription:list` to renderers. */
|
|
72
|
+
readonly kind: 'pass-through' | 'oauth-bearer' | 'static-bearer';
|
|
73
|
+
/** Stable id of the bound subscription provider. */
|
|
74
|
+
readonly providerId: SubscriptionProviderId;
|
|
75
|
+
/**
|
|
76
|
+
* Inject any required authentication headers into the outbound request.
|
|
77
|
+
* Implementations MAY refresh expiring tokens here (transparent refresh).
|
|
78
|
+
*
|
|
79
|
+
* Pass-through implementations are a no-op; the proxy's pass-through
|
|
80
|
+
* code path preserves the SDK's own Authorization header instead.
|
|
81
|
+
*/
|
|
82
|
+
applyHeaders(headers: Record<string, string>, hints?: AuthApplyHints): Promise<void>;
|
|
83
|
+
/**
|
|
84
|
+
* Called when the upstream returns 401. Return `true` to ask the proxy to
|
|
85
|
+
* retry the request once with freshly-applied headers; return `false` to
|
|
86
|
+
* surface the 401 immediately.
|
|
87
|
+
*
|
|
88
|
+
* Implementations SHOULD use a shared `RefreshMutex` to dedupe concurrent
|
|
89
|
+
* refreshes so N parallel 401s collapse into one upstream refresh call.
|
|
90
|
+
*/
|
|
91
|
+
onUnauthorized(): Promise<boolean>;
|
|
92
|
+
/** Diagnostic surface for the `subscription:status` IPC. */
|
|
93
|
+
describeStatus(): Promise<SubscriptionStatusEntry>;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* SubscriptionAccountService — the single resolver between the credential store and
|
|
98
|
+
* the dispatch proxy for subscription-mode dispatch.
|
|
99
|
+
*
|
|
100
|
+
* Responsibilities:
|
|
101
|
+
* - Hold long-lived `AuthStrategy` instances for each subscription provider.
|
|
102
|
+
* - Share a single `RefreshMutex` across all strategies so concurrent 401s
|
|
103
|
+
* for the same provider collapse into one upstream refresh call.
|
|
104
|
+
* - Expose `listAll()` / `getStatus()` for the `subscription:status` and
|
|
105
|
+
* `subscription:list` IPC channels.
|
|
106
|
+
*/
|
|
107
|
+
|
|
108
|
+
declare class SubscriptionAccountService {
|
|
109
|
+
private readonly mutex;
|
|
110
|
+
private readonly strategies;
|
|
111
|
+
constructor(tokens: SubscriptionCredentialStore);
|
|
112
|
+
/** Returns the strategy bound to a subscription provider, or `null` for unknown ids. */
|
|
113
|
+
getStrategy(providerId: SubscriptionProviderId): AuthStrategy | null;
|
|
114
|
+
/** Diagnostic for the `subscription:status` IPC. */
|
|
115
|
+
getStatus(providerId: SubscriptionProviderId): Promise<SubscriptionStatusEntry>;
|
|
116
|
+
/** Catalog entry list for the `subscription:list` IPC. */
|
|
117
|
+
listAll(): Promise<SubscriptionListEntry[]>;
|
|
118
|
+
}
|
|
119
|
+
/** Set once at host bootstrap; consumed by the host's router + engine wiring. */
|
|
120
|
+
declare function setSubscriptionAccountService(svc: SubscriptionAccountService): void;
|
|
121
|
+
/** Returns the singleton if it has been set, else `null` (don't throw — callers
|
|
122
|
+
* may run before main wiring on early-boot diagnostics). */
|
|
123
|
+
declare function getSubscriptionAccountService(): SubscriptionAccountService | null;
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* TransformerService Types
|
|
127
|
+
*
|
|
128
|
+
* Type definitions for the Transformer system, providing unified
|
|
129
|
+
* request/response formats and transformer chain configuration.
|
|
130
|
+
*
|
|
131
|
+
* @module transformer/types
|
|
132
|
+
*/
|
|
133
|
+
/**
|
|
134
|
+
* Thinking effort level for reasoning models
|
|
135
|
+
*/
|
|
136
|
+
type ThinkLevel = 'none' | 'low' | 'medium' | 'high';
|
|
137
|
+
/**
|
|
138
|
+
* Thinking content with optional signature for extended context
|
|
139
|
+
*/
|
|
140
|
+
interface ThinkingContent {
|
|
141
|
+
content: string;
|
|
142
|
+
signature?: string;
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Reasoning configuration for request
|
|
146
|
+
*/
|
|
147
|
+
interface ReasoningConfig {
|
|
148
|
+
/** OpenAI-style effort level */
|
|
149
|
+
effort?: ThinkLevel;
|
|
150
|
+
/** Anthropic-style max tokens for thinking */
|
|
151
|
+
max_tokens?: number;
|
|
152
|
+
/** Whether reasoning is enabled */
|
|
153
|
+
enabled?: boolean;
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Text content block
|
|
157
|
+
*/
|
|
158
|
+
interface TextContent {
|
|
159
|
+
type: 'text';
|
|
160
|
+
text: string;
|
|
161
|
+
cache_control?: {
|
|
162
|
+
type?: string;
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Image content block
|
|
167
|
+
*/
|
|
168
|
+
interface ImageContent {
|
|
169
|
+
type: 'image_url';
|
|
170
|
+
image_url: {
|
|
171
|
+
url: string;
|
|
172
|
+
};
|
|
173
|
+
media_type?: string;
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Union of all content types
|
|
177
|
+
*/
|
|
178
|
+
type MessageContent = TextContent | ImageContent;
|
|
179
|
+
/**
|
|
180
|
+
* Tool call definition
|
|
181
|
+
*/
|
|
182
|
+
interface ToolCall {
|
|
183
|
+
id: string;
|
|
184
|
+
type: 'function';
|
|
185
|
+
function: {
|
|
186
|
+
name: string;
|
|
187
|
+
arguments: string;
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Unified message format that works across all providers
|
|
192
|
+
*/
|
|
193
|
+
interface UnifiedMessage {
|
|
194
|
+
role: 'user' | 'assistant' | 'system' | 'tool';
|
|
195
|
+
content: string | null | MessageContent[];
|
|
196
|
+
tool_calls?: ToolCall[];
|
|
197
|
+
tool_call_id?: string;
|
|
198
|
+
cache_control?: {
|
|
199
|
+
type?: string;
|
|
200
|
+
};
|
|
201
|
+
thinking?: ThinkingContent;
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Tool parameter schema
|
|
205
|
+
*/
|
|
206
|
+
interface ToolParameterSchema {
|
|
207
|
+
type: 'object';
|
|
208
|
+
properties: Record<string, unknown>;
|
|
209
|
+
required?: string[];
|
|
210
|
+
additionalProperties?: boolean;
|
|
211
|
+
$schema?: string;
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Unified tool definition
|
|
215
|
+
*/
|
|
216
|
+
interface UnifiedTool {
|
|
217
|
+
type: 'function';
|
|
218
|
+
function: {
|
|
219
|
+
name: string;
|
|
220
|
+
description: string;
|
|
221
|
+
parameters: ToolParameterSchema;
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* Tool choice configuration
|
|
226
|
+
*/
|
|
227
|
+
type ToolChoice = 'auto' | 'none' | 'required' | string | {
|
|
228
|
+
type: 'function';
|
|
229
|
+
function: {
|
|
230
|
+
name: string;
|
|
231
|
+
};
|
|
232
|
+
};
|
|
233
|
+
/**
|
|
234
|
+
* Unified chat request format
|
|
235
|
+
*/
|
|
236
|
+
interface UnifiedChatRequest {
|
|
237
|
+
messages: UnifiedMessage[];
|
|
238
|
+
model: string;
|
|
239
|
+
max_tokens?: number;
|
|
240
|
+
temperature?: number;
|
|
241
|
+
stream?: boolean;
|
|
242
|
+
tools?: UnifiedTool[];
|
|
243
|
+
tool_choice?: ToolChoice;
|
|
244
|
+
reasoning?: ReasoningConfig;
|
|
245
|
+
/**
|
|
246
|
+
* Internal-only routing metadata. Populated by callers (CompletionService /
|
|
247
|
+
* the host's engine adapters and proxy servers) so the usage-capture hook can attribute
|
|
248
|
+
* the recorded event to a chat message, session, engine origin, and api key.
|
|
249
|
+
*
|
|
250
|
+
* **Must not be serialised into the outbound HTTP body.** The transformer chain
|
|
251
|
+
* passes this object alongside the request internally; transformers that build
|
|
252
|
+
* provider request payloads must drop `meta` from their output.
|
|
253
|
+
*/
|
|
254
|
+
meta?: UnifiedChatRequestMeta;
|
|
255
|
+
}
|
|
256
|
+
/**
|
|
257
|
+
* Routing metadata threaded through the transformer chain so the usage-capture
|
|
258
|
+
* hook can identify which chat message / session / api key produced the call.
|
|
259
|
+
* See `UnifiedChatRequest.meta`.
|
|
260
|
+
*/
|
|
261
|
+
interface UnifiedChatRequestMeta {
|
|
262
|
+
/** Host message id of the assistant message being produced, when known. */
|
|
263
|
+
messageId?: string | null;
|
|
264
|
+
/** Parent assistant message id (for subagent dispatches that have a parent). */
|
|
265
|
+
parentMessageId?: string | null;
|
|
266
|
+
/** Host session id, when applicable. */
|
|
267
|
+
sessionId?: string | null;
|
|
268
|
+
/** Which engine path is making the call. See `UsageEngineOrigin`. */
|
|
269
|
+
engineOrigin?: 'completion' | 'claude-sdk' | 'claude-sdk-direct' | 'codex-ingress' | (string & {});
|
|
270
|
+
/** The api-key-pool entry id selected for this request. */
|
|
271
|
+
apiKeyId?: string | null;
|
|
272
|
+
}
|
|
273
|
+
/**
|
|
274
|
+
* LLM Provider configuration (runtime format)
|
|
275
|
+
*/
|
|
276
|
+
interface LLMProvider {
|
|
277
|
+
name: string;
|
|
278
|
+
baseUrl: string;
|
|
279
|
+
apiKey: string;
|
|
280
|
+
models: string[];
|
|
281
|
+
transformer?: TransformerChainConfig;
|
|
282
|
+
/**
|
|
283
|
+
* Resolved Google **Code Assist** project id, threaded onto the transformer
|
|
284
|
+
* provider object by the subscription dispatch seam (SubscriptionDispatcher /
|
|
285
|
+
* openaiResponsesIngress) so `GeminiCodeAssistTransformer.transformRequestIn`
|
|
286
|
+
* can embed it in the top-level envelope. `undefined` is the valid fresh
|
|
287
|
+
* free-tier value (sending a project on free/legacy-tier → Precondition
|
|
288
|
+
* Failed). Only ever set for the gemini subscription profile; inert otherwise.
|
|
289
|
+
*/
|
|
290
|
+
geminiProject?: string;
|
|
291
|
+
}
|
|
292
|
+
/**
|
|
293
|
+
* Transformer options passed during instantiation
|
|
294
|
+
*/
|
|
295
|
+
interface TransformerOptions {
|
|
296
|
+
[key: string]: unknown;
|
|
297
|
+
}
|
|
298
|
+
/**
|
|
299
|
+
* Context passed through transformer chain
|
|
300
|
+
*/
|
|
301
|
+
interface TransformerContext {
|
|
302
|
+
/** Original request object */
|
|
303
|
+
req?: unknown;
|
|
304
|
+
/** Logger instance */
|
|
305
|
+
logger?: TransformerLogger;
|
|
306
|
+
/** Provider name */
|
|
307
|
+
providerName?: string;
|
|
308
|
+
/** Additional context data */
|
|
309
|
+
[key: string]: unknown;
|
|
310
|
+
}
|
|
311
|
+
/**
|
|
312
|
+
* Logger interface for transformers
|
|
313
|
+
*/
|
|
314
|
+
interface TransformerLogger {
|
|
315
|
+
debug(message: string, ...args: unknown[]): void;
|
|
316
|
+
info(message: string, ...args: unknown[]): void;
|
|
317
|
+
warn(message: string, ...args: unknown[]): void;
|
|
318
|
+
error(message: string, ...args: unknown[]): void;
|
|
319
|
+
}
|
|
320
|
+
/**
|
|
321
|
+
* Transformer interface - defines the contract for all transformers
|
|
322
|
+
*/
|
|
323
|
+
interface Transformer {
|
|
324
|
+
/** Unique name for the transformer */
|
|
325
|
+
name?: string;
|
|
326
|
+
/** API endpoint path (e.g., '/v1/chat/completions') */
|
|
327
|
+
endPoint?: string;
|
|
328
|
+
/** Logger instance */
|
|
329
|
+
logger?: TransformerLogger;
|
|
330
|
+
/**
|
|
331
|
+
* Transform incoming request (provider-specific → unified format)
|
|
332
|
+
* Called when request enters the transformer chain
|
|
333
|
+
*/
|
|
334
|
+
transformRequestIn?: (request: UnifiedChatRequest, provider: LLMProvider, context: TransformerContext) => Promise<Record<string, unknown>>;
|
|
335
|
+
/**
|
|
336
|
+
* Transform outgoing request (unified → provider-specific format)
|
|
337
|
+
* Called before sending to LLM provider
|
|
338
|
+
*/
|
|
339
|
+
transformRequestOut?: (request: unknown, context: TransformerContext) => Promise<UnifiedChatRequest>;
|
|
340
|
+
/**
|
|
341
|
+
* Transform incoming response (provider-specific → unified format)
|
|
342
|
+
* Called after receiving response from provider
|
|
343
|
+
*/
|
|
344
|
+
transformResponseIn?: (response: Response, context?: TransformerContext) => Promise<Response>;
|
|
345
|
+
/**
|
|
346
|
+
* Transform outgoing response (unified → client format)
|
|
347
|
+
* Called before returning response to client
|
|
348
|
+
*/
|
|
349
|
+
transformResponseOut?: (response: Response, context: TransformerContext) => Promise<Response>;
|
|
350
|
+
/**
|
|
351
|
+
* Handle authentication for the request
|
|
352
|
+
*/
|
|
353
|
+
auth?: (request: unknown, provider: LLMProvider, context: TransformerContext) => Promise<unknown>;
|
|
354
|
+
}
|
|
355
|
+
/**
|
|
356
|
+
* Transformer constructor interface
|
|
357
|
+
*/
|
|
358
|
+
interface TransformerConstructor {
|
|
359
|
+
new (options?: TransformerOptions): Transformer;
|
|
360
|
+
TransformerName?: string;
|
|
361
|
+
}
|
|
362
|
+
/**
|
|
363
|
+
* Individual transformer reference in chain
|
|
364
|
+
* Can be a string name or [name, options] tuple
|
|
365
|
+
*/
|
|
366
|
+
type TransformerReference = string | [string, TransformerOptions];
|
|
367
|
+
/**
|
|
368
|
+
* Model-specific transformer configuration
|
|
369
|
+
*/
|
|
370
|
+
interface ModelTransformerConfig {
|
|
371
|
+
use?: TransformerReference[];
|
|
372
|
+
}
|
|
373
|
+
/**
|
|
374
|
+
* Transformer chain configuration for a provider
|
|
375
|
+
*/
|
|
376
|
+
interface TransformerChainConfig {
|
|
377
|
+
/** Provider-level transformers applied to all models */
|
|
378
|
+
use?: TransformerReference[];
|
|
379
|
+
/** Model-specific transformer overrides */
|
|
380
|
+
[modelName: string]: ModelTransformerConfig | TransformerReference[] | undefined;
|
|
381
|
+
}
|
|
382
|
+
/**
|
|
383
|
+
* Resolved transformer chain (instances ready to execute)
|
|
384
|
+
*/
|
|
385
|
+
interface ResolvedTransformerChain {
|
|
386
|
+
/** Provider-level transformer instances */
|
|
387
|
+
providerTransformers: Transformer[];
|
|
388
|
+
/** Model-specific transformer instances */
|
|
389
|
+
modelTransformers: Transformer[];
|
|
390
|
+
}
|
|
391
|
+
/**
|
|
392
|
+
* Result of request transformation
|
|
393
|
+
*/
|
|
394
|
+
interface TransformRequestResult {
|
|
395
|
+
/** Transformed request body */
|
|
396
|
+
requestBody: unknown;
|
|
397
|
+
/** Additional request configuration */
|
|
398
|
+
config: RequestConfig;
|
|
399
|
+
/** Whether to bypass further transformations */
|
|
400
|
+
bypass: boolean;
|
|
401
|
+
}
|
|
402
|
+
/**
|
|
403
|
+
* Request configuration for HTTP call
|
|
404
|
+
*/
|
|
405
|
+
interface RequestConfig {
|
|
406
|
+
/** Request URL */
|
|
407
|
+
url?: URL | string;
|
|
408
|
+
/** Request headers */
|
|
409
|
+
headers?: Record<string, string>;
|
|
410
|
+
/** Additional fetch options */
|
|
411
|
+
[key: string]: unknown;
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
/**
|
|
415
|
+
* TransformerChainExecutor - Executes transformer chains for requests and responses
|
|
416
|
+
*
|
|
417
|
+
* Implements the transformer pipeline:
|
|
418
|
+
* Request: transformRequestOut 鈫?Provider transformers 鈫?Model transformers 鈫?HTTP
|
|
419
|
+
* Response: Model transformers (reverse) 鈫?Provider transformers (reverse) 鈫?transformResponseIn
|
|
420
|
+
*
|
|
421
|
+
* @module transformer/TransformerChainExecutor
|
|
422
|
+
*/
|
|
423
|
+
|
|
424
|
+
/**
|
|
425
|
+
* Options for chain execution
|
|
426
|
+
*/
|
|
427
|
+
interface ChainExecutionOptions {
|
|
428
|
+
/** The primary/endpoint transformer */
|
|
429
|
+
endpointTransformer?: Transformer;
|
|
430
|
+
/** Request headers */
|
|
431
|
+
headers?: Record<string, string> | Headers;
|
|
432
|
+
/** Logger instance */
|
|
433
|
+
logger?: TransformerLogger;
|
|
434
|
+
/**
|
|
435
|
+
* 1M-context opt-in. When `enabled` is true and the post-chain request body
|
|
436
|
+
* looks Anthropic-shaped (has a `messages` array), the executor injects
|
|
437
|
+
* `'context-1m-2025-08-07'` into `body.anthropic_beta`. Capability gating
|
|
438
|
+
* (model id allowlist) lives inside `injectExtendedContextBeta` itself.
|
|
439
|
+
*/
|
|
440
|
+
extendedContext?: {
|
|
441
|
+
enabled: boolean;
|
|
442
|
+
model: string;
|
|
443
|
+
};
|
|
444
|
+
}
|
|
445
|
+
/**
|
|
446
|
+
* TransformerChainExecutor handles the execution of transformer chains.
|
|
447
|
+
*
|
|
448
|
+
* The execution flow follows the llms project pattern:
|
|
449
|
+
*
|
|
450
|
+
* Request Phase:
|
|
451
|
+
* 1. transformRequestOut (endpoint transformer) - Convert to unified format
|
|
452
|
+
* 2. Provider transformers [].transformRequestIn (forward order)
|
|
453
|
+
* 3. Model transformers [].transformRequestIn (forward order)
|
|
454
|
+
*
|
|
455
|
+
* Response Phase:
|
|
456
|
+
* 4. Model transformers [].transformResponseOut (reverse order)
|
|
457
|
+
* 5. Provider transformers [].transformResponseOut (reverse order)
|
|
458
|
+
* 6. transformResponseIn (endpoint transformer) - Convert to client format
|
|
459
|
+
*/
|
|
460
|
+
declare class TransformerChainExecutor {
|
|
461
|
+
private logger;
|
|
462
|
+
constructor(logger?: TransformerLogger);
|
|
463
|
+
/**
|
|
464
|
+
* Execute the request transformation chain
|
|
465
|
+
*
|
|
466
|
+
* @param request - Original request body
|
|
467
|
+
* @param provider - LLM provider configuration
|
|
468
|
+
* @param chain - Resolved transformer chain
|
|
469
|
+
* @param options - Execution options
|
|
470
|
+
* @returns Transformed request result
|
|
471
|
+
*/
|
|
472
|
+
executeRequestChain(request: unknown, provider: LLMProvider, chain: ResolvedTransformerChain, options?: ChainExecutionOptions): Promise<TransformRequestResult>;
|
|
473
|
+
/**
|
|
474
|
+
* Execute the response transformation chain
|
|
475
|
+
*
|
|
476
|
+
* @param request - Original request (for context)
|
|
477
|
+
* @param response - Response from provider
|
|
478
|
+
* @param provider - LLM provider configuration
|
|
479
|
+
* @param chain - Resolved transformer chain
|
|
480
|
+
* @param options - Execution options
|
|
481
|
+
* @returns Transformed response
|
|
482
|
+
*/
|
|
483
|
+
executeResponseChain(request: UnifiedChatRequest, response: Response, provider: LLMProvider, chain: ResolvedTransformerChain, options?: ChainExecutionOptions): Promise<Response>;
|
|
484
|
+
/**
|
|
485
|
+
* Execute authentication handler if available
|
|
486
|
+
*
|
|
487
|
+
* @param request - Request body
|
|
488
|
+
* @param provider - LLM provider
|
|
489
|
+
* @param endpointTransformer - Endpoint transformer with auth handler
|
|
490
|
+
* @param context - Transformer context
|
|
491
|
+
* @returns Auth result with potentially modified request and config
|
|
492
|
+
*/
|
|
493
|
+
executeAuth(request: unknown, provider: LLMProvider, endpointTransformer: Transformer | undefined, context: TransformerContext): Promise<{
|
|
494
|
+
requestBody: unknown;
|
|
495
|
+
config: RequestConfig;
|
|
496
|
+
}>;
|
|
497
|
+
/**
|
|
498
|
+
* Check if transformers should be bypassed (optimization)
|
|
499
|
+
*
|
|
500
|
+
* Bypass is enabled when:
|
|
501
|
+
* - Provider has only one transformer that matches the endpoint transformer
|
|
502
|
+
* - Model has no specific transformers or only the same endpoint transformer
|
|
503
|
+
*/
|
|
504
|
+
private shouldBypassTransformers;
|
|
505
|
+
/**
|
|
506
|
+
* Clean headers for pass-through
|
|
507
|
+
*/
|
|
508
|
+
private cleanHeaders;
|
|
509
|
+
/**
|
|
510
|
+
* Get error message from unknown error
|
|
511
|
+
*/
|
|
512
|
+
private getErrorMessage;
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
/**
|
|
516
|
+
* TransformerService - Core service for managing transformer lifecycle
|
|
517
|
+
*
|
|
518
|
+
* Handles transformer registration, retrieval, and initialization.
|
|
519
|
+
*
|
|
520
|
+
* Adapted from the `musistudio/llms` project (MIT, © 2025 musistudio) — the
|
|
521
|
+
* transformer IR upstream — for the Electron environment. See the package
|
|
522
|
+
* `NOTICE` for full third-party attribution.
|
|
523
|
+
*
|
|
524
|
+
* @module transformer/TransformerService
|
|
525
|
+
*/
|
|
526
|
+
|
|
527
|
+
/**
|
|
528
|
+
* TransformerService manages the lifecycle of all transformers.
|
|
529
|
+
*
|
|
530
|
+
* Features:
|
|
531
|
+
* - Register transformers by name
|
|
532
|
+
* - Get transformer by name
|
|
533
|
+
* - Initialize default transformers
|
|
534
|
+
* - Resolve transformer chains from configuration
|
|
535
|
+
*/
|
|
536
|
+
declare class TransformerService {
|
|
537
|
+
private transformers;
|
|
538
|
+
private logger;
|
|
539
|
+
private instanceCache;
|
|
540
|
+
private endpointTransformersCache;
|
|
541
|
+
private noEndpointTransformersCache;
|
|
542
|
+
constructor(logger?: TransformerLogger);
|
|
543
|
+
/**
|
|
544
|
+
* Clear instance caches
|
|
545
|
+
*/
|
|
546
|
+
clearInstanceCache(): void;
|
|
547
|
+
/**
|
|
548
|
+
* Get cache statistics for diagnostics
|
|
549
|
+
*/
|
|
550
|
+
getCacheStats(): {
|
|
551
|
+
instanceCacheSize: number;
|
|
552
|
+
hasEndpointCache: boolean;
|
|
553
|
+
};
|
|
554
|
+
/**
|
|
555
|
+
* Register a transformer by name
|
|
556
|
+
* @param name - Unique transformer name
|
|
557
|
+
* @param transformer - Transformer instance or constructor
|
|
558
|
+
*/
|
|
559
|
+
registerTransformer(name: string, transformer: Transformer | TransformerConstructor): void;
|
|
560
|
+
/**
|
|
561
|
+
* Get a transformer by name
|
|
562
|
+
* @param name - Transformer name
|
|
563
|
+
* @returns Transformer instance/constructor or undefined
|
|
564
|
+
*/
|
|
565
|
+
getTransformer(name: string): Transformer | TransformerConstructor | undefined;
|
|
566
|
+
/**
|
|
567
|
+
* Get all registered transformers
|
|
568
|
+
* @returns Map of all transformers
|
|
569
|
+
*/
|
|
570
|
+
getAllTransformers(): Map<string, Transformer | TransformerConstructor>;
|
|
571
|
+
/**
|
|
572
|
+
* Get transformers that have an endpoint defined
|
|
573
|
+
* Uses cache to avoid redundant traversal
|
|
574
|
+
* @returns Array of transformers with endpoints
|
|
575
|
+
*/
|
|
576
|
+
getTransformersWithEndpoint(): {
|
|
577
|
+
name: string;
|
|
578
|
+
transformer: Transformer;
|
|
579
|
+
}[];
|
|
580
|
+
/**
|
|
581
|
+
* Get transformers without endpoints
|
|
582
|
+
* Uses cache to avoid redundant traversal
|
|
583
|
+
* @returns Array of transformers without endpoints
|
|
584
|
+
*/
|
|
585
|
+
getTransformersWithoutEndpoint(): {
|
|
586
|
+
name: string;
|
|
587
|
+
transformer: Transformer;
|
|
588
|
+
}[];
|
|
589
|
+
/**
|
|
590
|
+
* Remove a transformer by name
|
|
591
|
+
* @param name - Transformer name
|
|
592
|
+
* @returns true if removed, false if not found
|
|
593
|
+
*/
|
|
594
|
+
removeTransformer(name: string): boolean;
|
|
595
|
+
/**
|
|
596
|
+
* Check if a transformer is registered
|
|
597
|
+
* @param name - Transformer name
|
|
598
|
+
* @returns true if registered
|
|
599
|
+
*/
|
|
600
|
+
hasTransformer(name: string): boolean;
|
|
601
|
+
/**
|
|
602
|
+
* Initialize the service with default transformers
|
|
603
|
+
* @param defaultTransformers - Map or object of default transformers
|
|
604
|
+
*/
|
|
605
|
+
initialize(defaultTransformers?: Record<string, Transformer | TransformerConstructor>): Promise<void>;
|
|
606
|
+
/**
|
|
607
|
+
* Register default transformers from a map
|
|
608
|
+
* @param transformers - Map of transformer name to transformer
|
|
609
|
+
*/
|
|
610
|
+
private registerDefaultTransformers;
|
|
611
|
+
/**
|
|
612
|
+
* Resolve a transformer chain configuration to actual transformer instances
|
|
613
|
+
* @param chainConfig - Transformer chain configuration
|
|
614
|
+
* @param modelName - Model name for model-specific transformers
|
|
615
|
+
* @returns Resolved transformer chain with instances
|
|
616
|
+
*/
|
|
617
|
+
resolveTransformerChain(chainConfig: TransformerChainConfig | undefined, modelName?: string): ResolvedTransformerChain;
|
|
618
|
+
/**
|
|
619
|
+
* Resolve an array of transformer references to instances
|
|
620
|
+
* @param refs - Array of transformer references
|
|
621
|
+
* @returns Array of transformer instances
|
|
622
|
+
*/
|
|
623
|
+
resolveTransformerReferences(refs: TransformerReference[]): Transformer[];
|
|
624
|
+
/**
|
|
625
|
+
* Instantiate a transformer if it's a constructor
|
|
626
|
+
* Uses instance cache to avoid redundant instantiation
|
|
627
|
+
*
|
|
628
|
+
* @param transformer - Transformer instance or constructor
|
|
629
|
+
* @param options - Options to pass to constructor
|
|
630
|
+
* @returns Transformer instance
|
|
631
|
+
*/
|
|
632
|
+
private instantiateIfNeeded;
|
|
633
|
+
/**
|
|
634
|
+
* Check if a value is a transformer constructor
|
|
635
|
+
* @param value - Value to check
|
|
636
|
+
* @returns true if it's a constructor
|
|
637
|
+
*/
|
|
638
|
+
private isTransformerConstructor;
|
|
639
|
+
/**
|
|
640
|
+
* Get list of all registered transformer names
|
|
641
|
+
* @returns Array of transformer names
|
|
642
|
+
*/
|
|
643
|
+
getTransformerNames(): string[];
|
|
644
|
+
/**
|
|
645
|
+
* Clear all registered transformers
|
|
646
|
+
*/
|
|
647
|
+
clear(): void;
|
|
648
|
+
}
|
|
649
|
+
|
|
650
|
+
/**
|
|
651
|
+
* Shared contract types for the resident `ProviderProxy`.
|
|
652
|
+
*
|
|
653
|
+
* The `ProviderProxy` (OpenSpec `engine-provider-decouple`, design D0/D3/D7/D9)
|
|
654
|
+
* is the single resident `127.0.0.1` listener that subsumes both of the
|
|
655
|
+
* host's per-session proxies (Anthropic Messages ingress and OpenAI Responses
|
|
656
|
+
* ingress). Per-run state lives in a `Map<token, RouteContext>`
|
|
657
|
+
* minted at run start and reaped at run end / on idle TTL.
|
|
658
|
+
*
|
|
659
|
+
* These types are kept in their own module so the server, route map, router,
|
|
660
|
+
* and the two ingress parsers can share shapes without importing one another
|
|
661
|
+
* for type-only purposes.
|
|
662
|
+
*
|
|
663
|
+
* @module provider-proxy/types
|
|
664
|
+
*/
|
|
665
|
+
|
|
666
|
+
/** Lightweight summary derived from the inbound Anthropic request body —
|
|
667
|
+
* consumed by `modelMapper` (scenario routing) without full body access. */
|
|
668
|
+
interface SubscriptionRequestSummary {
|
|
669
|
+
messageCount: number;
|
|
670
|
+
/** cl100k_base-estimated token count of system + messages (no tools). */
|
|
671
|
+
estimatedInputTokens: number;
|
|
672
|
+
/**
|
|
673
|
+
* OPTIONAL bounded per-message text slice (system prompt + the most recent
|
|
674
|
+
* user/system messages, each per-message-capped) consumed ONLY by the
|
|
675
|
+
* OpenCodeGo keyword matcher in `@omnicross/subscriptions`
|
|
676
|
+
* (`resolveOpenCodeGoScenario`). Core only WRITES this `string[]`; it never
|
|
677
|
+
* reads it and never names the matcher — keeping the cross-layer litmus at 0
|
|
678
|
+
* (no `@omnicross/core` → `@omnicross/subscriptions` edge). Optional so callers
|
|
679
|
+
* that omit it (legacy/tests) compile and degrade to the token-threshold +
|
|
680
|
+
* `default` routing.
|
|
681
|
+
*/
|
|
682
|
+
matchText?: string[];
|
|
683
|
+
}
|
|
684
|
+
interface SubscriptionDispatchProfile {
|
|
685
|
+
readonly providerId: SubscriptionProviderId;
|
|
686
|
+
readonly displayName: string;
|
|
687
|
+
readonly authStrategy: AuthStrategy;
|
|
688
|
+
/** Pass-through providers (Claude) skip the transformer chain entirely.
|
|
689
|
+
* Transformer providers use the chain below + the proxy's existing
|
|
690
|
+
* `AnthropicTransformer` endpoint reverse-decoder. */
|
|
691
|
+
readonly mode: 'pass-through' | 'transformer';
|
|
692
|
+
/** Resolve the upstream URL for a given resolved model id. Required for
|
|
693
|
+
* `mode === 'transformer'`; unused for pass-through (proxy hard-codes
|
|
694
|
+
* `api.anthropic.com`). The OPTIONAL 2nd `config` arg lets the opencodego
|
|
695
|
+
* profile honor a per-account `baseUrl` override (D1) — additive, so existing
|
|
696
|
+
* one-arg callers compile unchanged. */
|
|
697
|
+
readonly resolveUpstreamUrl?: (resolvedModel: string, config?: OpenCodeGoTokenConfig) => string;
|
|
698
|
+
/** Names of transformers (registered in `TransformerService`) to run on the
|
|
699
|
+
* provider chain. The proxy adds `AnthropicTransformer` as the endpoint
|
|
700
|
+
* reverse-decoder. */
|
|
701
|
+
readonly providerTransformerNames?: readonly string[];
|
|
702
|
+
readonly modelTransformerNames?: readonly string[];
|
|
703
|
+
/**
|
|
704
|
+
* OPTIONAL shape-aware provider transformer-name resolver (opencodego zen).
|
|
705
|
+
* Parallel to `resolveUpstreamUrl(model, config)`: lets a profile vary its
|
|
706
|
+
* provider chain by the RESOLVED model's wire shape (e.g. zen `responses` ⇒
|
|
707
|
+
* `['openai-response']`, `gemini` ⇒ `['gemini']`). `config` is `unknown` on the
|
|
708
|
+
* core side (opaque-config discipline — core never names
|
|
709
|
+
* `OpenCodeGoTokenConfig` from `@omnicross/subscriptions`); the subscriptions
|
|
710
|
+
* implementation narrows it. When ABSENT, both ingress paths fall back to the
|
|
711
|
+
* static `providerTransformerNames` — BYTE-IDENTICAL for claude / codex / gemini
|
|
712
|
+
* (which leave this unset). Purely additive (optional).
|
|
713
|
+
*/
|
|
714
|
+
readonly resolveProviderTransformerNames?: (model: string, config?: unknown) => readonly string[];
|
|
715
|
+
/** Optional model placeholder rewriter — only set for OpenCodeGo. */
|
|
716
|
+
readonly modelMapper?: (sdkModel: string, summary: SubscriptionRequestSummary, config: OpenCodeGoTokenConfig | undefined) => {
|
|
717
|
+
resolvedModel: string;
|
|
718
|
+
scenario: OpenCodeGoScenario;
|
|
719
|
+
};
|
|
720
|
+
/** Optional fallback resolver — for OpenCodeGo, picks the next model after
|
|
721
|
+
* an unrecoverable error. Returns `null` when exhausted. Cap = 3. The
|
|
722
|
+
* opencodego implementation ALSO consults the circuit breaker (D5): it skips
|
|
723
|
+
* models whose circuit is open. */
|
|
724
|
+
readonly nextFallback?: (scenario: OpenCodeGoScenario, attempted: readonly string[], config: OpenCodeGoTokenConfig | undefined) => OpenCodeGoModelEntry | null;
|
|
725
|
+
/** Optional circuit-breaker admission gate for the PRIMARY (mapped) model
|
|
726
|
+
* (D5 primary-gating). Only set for OpenCodeGo. Returns whether `modelId`'s
|
|
727
|
+
* circuit currently admits a request (side-effecting: flips an `open` model
|
|
728
|
+
* to `half-open` once its window elapses, exactly like `nextFallback`'s
|
|
729
|
+
* internal consult). `nextFallback` covers the FALLBACKS; this covers the
|
|
730
|
+
* primary the loop already holds. Absent/undefined ⇒ the loop treats the
|
|
731
|
+
* primary as always admitted (claude / codex / gemini have no breaker). */
|
|
732
|
+
readonly allowModel?: (modelId: string) => boolean;
|
|
733
|
+
/** Optional record-outcome callback (D5 record seam). Only set for OpenCodeGo.
|
|
734
|
+
* Both fallback loops invoke it after each attempt: `ok: true` on a `2xx`,
|
|
735
|
+
* `ok: false` on a thrown/network error / `5xx` / `429`; a non-429 `4xx` is
|
|
736
|
+
* NEUTRAL and the loops MUST NOT call it. Drives the per-model breaker.
|
|
737
|
+
* Absent/undefined for claude / codex / gemini ⇒ a no-op (no breaker). */
|
|
738
|
+
readonly recordModelOutcome?: (modelId: string, ok: boolean) => void;
|
|
739
|
+
}
|
|
740
|
+
|
|
741
|
+
/**
|
|
742
|
+
* SubscriptionProviderRegistry — fixed catalog of subscription dispatch profiles.
|
|
743
|
+
*
|
|
744
|
+
* Each entry maps a `SubscriptionProviderId` to a `SubscriptionDispatchProfile`
|
|
745
|
+
* that tells the dispatch proxy:
|
|
746
|
+
* - how to authenticate (via the bound `AuthStrategy`),
|
|
747
|
+
* - which transformer chain to run (resolved by name from `TransformerService`),
|
|
748
|
+
* - which upstream URL to hit (static OR computed per model id),
|
|
749
|
+
* - how to map the SDK-supplied model placeholder to a provider model
|
|
750
|
+
* (OpenCodeGo scenario routing),
|
|
751
|
+
* - which fallback model entries to try when the primary fails.
|
|
752
|
+
*
|
|
753
|
+
* The registry is intentionally a static in-memory map — subscription
|
|
754
|
+
* providers are a built-in catalog, NOT user-configurable LLM provider rows.
|
|
755
|
+
*/
|
|
756
|
+
|
|
757
|
+
declare class SubscriptionProviderRegistry {
|
|
758
|
+
private readonly accounts;
|
|
759
|
+
private readonly tokens;
|
|
760
|
+
private readonly profiles;
|
|
761
|
+
/**
|
|
762
|
+
* Per-model circuit breaker for opencodego routing (D5). ONE registry-owned
|
|
763
|
+
* process singleton, built here and captured by the opencodego profile's
|
|
764
|
+
* `nextFallback` (consult) + `recordModelOutcome` (record) closures. Because
|
|
765
|
+
* the `SubscriptionProviderRegistry` is itself a process singleton (via
|
|
766
|
+
* `setSubscriptionProviderRegistry`), breaker state persists across requests —
|
|
767
|
+
* exactly the reference's long-lived `FallbackHandler`. Constructed with the
|
|
768
|
+
* default reference thresholds (3 / 30s / 3) and the default `Date.now` clock.
|
|
769
|
+
*/
|
|
770
|
+
private readonly breaker;
|
|
771
|
+
constructor(accounts: SubscriptionAccountService, tokens: SubscriptionCredentialStore);
|
|
772
|
+
/** Returns the dispatch profile for a known subscription provider, or
|
|
773
|
+
* `null` for unknown ids (callers must treat null as "fall back to the
|
|
774
|
+
* legacy LLM provider DB lookup"). */
|
|
775
|
+
getProfile(providerId: string): SubscriptionDispatchProfile | null;
|
|
776
|
+
/** Read the currently-stored OpenCodeGo config so the proxy can pick up
|
|
777
|
+
* user overrides (modelMap / fallbacks / baseUrl). Wraps the injected
|
|
778
|
+
* `SubscriptionCredentialStore` so the proxy doesn't need to know about
|
|
779
|
+
* that surface. */
|
|
780
|
+
getOpenCodeGoConfig(): Promise<OpenCodeGoTokenConfig | undefined>;
|
|
781
|
+
}
|
|
782
|
+
declare function setSubscriptionProviderRegistry(svc: SubscriptionProviderRegistry): void;
|
|
783
|
+
declare function getSubscriptionProviderRegistry(): SubscriptionProviderRegistry | null;
|
|
784
|
+
|
|
785
|
+
/**
|
|
786
|
+
* SubscriptionDispatcher — handles the dispatch proxy's subscription-mode flow.
|
|
787
|
+
*
|
|
788
|
+
* Extracted from the host proxy server to keep that file focused on the legacy
|
|
789
|
+
* LLM-provider pipeline. The dispatcher mirrors the proxy's inner
|
|
790
|
+
* transformer-pipeline shape but sources upstream URL,
|
|
791
|
+
* transformer chain, auth, and model mapping from a
|
|
792
|
+
* `SubscriptionDispatchProfile` instead of the host's config service.
|
|
793
|
+
*
|
|
794
|
+
* The proxy delegates here from `handleRequest` whenever a profile is bound.
|
|
795
|
+
*/
|
|
796
|
+
|
|
797
|
+
/** Hooks the dispatcher needs from the host proxy server's private surface. */
|
|
798
|
+
interface DispatcherHooks {
|
|
799
|
+
/** Anthropic endpoint transformer instance, reused across requests. */
|
|
800
|
+
readonly endpointTransformer: Transformer;
|
|
801
|
+
/** Shared transformer chain executor. */
|
|
802
|
+
readonly executor: TransformerChainExecutor;
|
|
803
|
+
/** Shared transformer service registry — looks up transformer-by-name. */
|
|
804
|
+
readonly transformerService: TransformerService;
|
|
805
|
+
/** Fetch + retry helper from the proxy (semaphore, 429/5xx loop). */
|
|
806
|
+
fetchWithRetry(url: string, headers: Record<string, string>, body: unknown, model: string): Promise<Response>;
|
|
807
|
+
/** Forward the upstream response to the SDK + tap usage. */
|
|
808
|
+
writeProxyResponse(res: http.ServerResponse, providerResponse: Response, isStream: boolean, reqId?: number): Promise<void>;
|
|
809
|
+
}
|
|
810
|
+
interface DispatchRequest {
|
|
811
|
+
reqId: number;
|
|
812
|
+
res: http.ServerResponse;
|
|
813
|
+
rawBody: string;
|
|
814
|
+
anthropicBody: Record<string, unknown>;
|
|
815
|
+
isStream: boolean;
|
|
816
|
+
sdkModel: string;
|
|
817
|
+
fallbackModel: string;
|
|
818
|
+
}
|
|
819
|
+
declare class SubscriptionDispatcher {
|
|
820
|
+
private readonly profile;
|
|
821
|
+
private readonly hooks;
|
|
822
|
+
private readonly getOpenCodeGoConfig;
|
|
823
|
+
constructor(profile: SubscriptionDispatchProfile, hooks: DispatcherHooks, getOpenCodeGoConfig: () => Promise<OpenCodeGoTokenConfig | undefined>);
|
|
824
|
+
/**
|
|
825
|
+
* Entry point — called by the host proxy's request handler after model
|
|
826
|
+
* resolution and probe-detection.
|
|
827
|
+
*/
|
|
828
|
+
dispatch(req: DispatchRequest): Promise<void>;
|
|
829
|
+
/** Bypass path for OpenCodeGo MiniMax models — forwards Anthropic body verbatim. */
|
|
830
|
+
private dispatchAnthropicShapeBypass;
|
|
831
|
+
/** Standard subscription transformer chain — Codex/Gemini/OpenCodeGo OpenAI-shape. */
|
|
832
|
+
private dispatchTransformerChain;
|
|
833
|
+
/**
|
|
834
|
+
* D2 PRIMARY-GATING (opencodego, D5): pick the first-attempt model for a
|
|
835
|
+
* fallback loop. Consults the breaker for the mapped primary; when the primary's
|
|
836
|
+
* circuit is open, advance to the first admitting `nextFallback` candidate
|
|
837
|
+
* WITHOUT an upstream round-trip on the open primary. When EVERY candidate is
|
|
838
|
+
* open (all-open) the breaker FAILS OPEN — it attempts the original primary
|
|
839
|
+
* anyway. Returns the resolved first-attempt model plus the `attempted` list
|
|
840
|
+
* seeded for the loop (the SKIPPED primary is recorded at chain index 0 so the
|
|
841
|
+
* loop's `nextFallback` excludes it; on fail-open the list is left empty so the
|
|
842
|
+
* primary is the first real attempt). When the profile has no `allowModel`
|
|
843
|
+
* (claude / codex / gemini, or breaker unset) this is byte-identical to the
|
|
844
|
+
* prior behavior: the primary is the first attempt, `attempted` empty.
|
|
845
|
+
*/
|
|
846
|
+
private gatePrimaryModel;
|
|
847
|
+
/**
|
|
848
|
+
* On a 401 error from the upstream, ask the AuthStrategy whether to retry.
|
|
849
|
+
* Returns `{ retryOnce: true, headers }` when the strategy refreshed
|
|
850
|
+
* successfully (caller should retry once); otherwise re-throws.
|
|
851
|
+
*/
|
|
852
|
+
private maybeRetryAfterError;
|
|
853
|
+
private applyHeadersWithRetry;
|
|
854
|
+
/**
|
|
855
|
+
* Resolve the Code Assist project for the gemini subscription profile. Pulls
|
|
856
|
+
* the Bearer the bound `AuthStrategy` would inject (so the strategy stays the
|
|
857
|
+
* single source of the token), then runs the cached handshake. Returns
|
|
858
|
+
* `undefined` for a fresh free-tier account (valid — the envelope omits the
|
|
859
|
+
* project). A handshake hard failure (403/429) propagates to the dispatch
|
|
860
|
+
* error handler.
|
|
861
|
+
*/
|
|
862
|
+
private resolveGeminiProject;
|
|
863
|
+
private resolveTransformers;
|
|
864
|
+
/** Build a lightweight request summary for OpenCodeGo scenario routing. */
|
|
865
|
+
private buildRequestSummary;
|
|
866
|
+
}
|
|
867
|
+
|
|
868
|
+
export { type AuthApplyHints, type AuthStrategy, type DispatchRequest, type DispatcherHooks, SubscriptionAccountService, type SubscriptionCredentialStore, type SubscriptionDispatchProfile, SubscriptionDispatcher, SubscriptionProviderRegistry, type SubscriptionRequestSummary, getSubscriptionAccountService, getSubscriptionProviderRegistry, setSubscriptionAccountService, setSubscriptionProviderRegistry };
|