@elsium-ai/gateway 0.8.0 → 0.9.1
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/README.md +95 -1
- package/dist/gateway.d.ts +7 -0
- package/dist/gateway.d.ts.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +57 -17
- package/dist/router.d.ts.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -65,6 +65,7 @@ interface Gateway {
|
|
|
65
65
|
data: T
|
|
66
66
|
response: LLMResponse
|
|
67
67
|
}>
|
|
68
|
+
extract<T>(schema: z.ZodType<T>, input: string, options?: ExtractOptions): Promise<T>
|
|
68
69
|
readonly provider: LLMProvider
|
|
69
70
|
lastCall(): XRayData | null
|
|
70
71
|
callHistory(limit?: number): XRayData[]
|
|
@@ -76,6 +77,7 @@ interface Gateway {
|
|
|
76
77
|
| `complete(request)` | Send a completion request and return the full response. |
|
|
77
78
|
| `stream(request)` | Stream a completion request, returning an async-iterable `ElsiumStream`. |
|
|
78
79
|
| `generate<T>(request)` | Structured output -- sends a Zod schema, parses and validates the LLM's JSON response. |
|
|
80
|
+
| `extract<T>(schema, input, options?)` | Structured extraction -- takes a Zod schema and text input, returns typed data with auto-retry on validation failure. |
|
|
79
81
|
| `provider` | Read-only reference to the underlying `LLMProvider` instance. |
|
|
80
82
|
| `lastCall()` | Returns the most recent `XRayData` entry, or `null` if X-Ray is disabled. |
|
|
81
83
|
| `callHistory(limit?)` | Returns up to `limit` (default 10) recent `XRayData` entries. |
|
|
@@ -141,6 +143,58 @@ const { data } = await llm.generate({
|
|
|
141
143
|
console.log(data.name) // "Mars"
|
|
142
144
|
```
|
|
143
145
|
|
|
146
|
+
#### Structured Extraction
|
|
147
|
+
|
|
148
|
+
`extract()` provides a simpler API for pulling typed data out of text. It takes a Zod schema and input text, returns the parsed object directly, and auto-retries on validation failure.
|
|
149
|
+
|
|
150
|
+
```ts
|
|
151
|
+
interface Gateway {
|
|
152
|
+
extract<T>(
|
|
153
|
+
schema: z.ZodType<T>,
|
|
154
|
+
input: string,
|
|
155
|
+
options?: ExtractOptions,
|
|
156
|
+
): Promise<T>
|
|
157
|
+
}
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
**`ExtractOptions`**
|
|
161
|
+
|
|
162
|
+
```ts
|
|
163
|
+
interface ExtractOptions {
|
|
164
|
+
maxRetries?: number // Default: 3
|
|
165
|
+
temperature?: number
|
|
166
|
+
system?: string
|
|
167
|
+
model?: string
|
|
168
|
+
}
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
On validation failure, `extract()` feeds the Zod error back to the LLM and retries (up to `maxRetries`). The return type is inferred from the schema.
|
|
172
|
+
|
|
173
|
+
```ts
|
|
174
|
+
import { gateway } from '@elsium-ai/gateway'
|
|
175
|
+
import { z } from 'zod'
|
|
176
|
+
|
|
177
|
+
const llm = gateway({
|
|
178
|
+
provider: 'anthropic',
|
|
179
|
+
apiKey: process.env.ANTHROPIC_API_KEY!,
|
|
180
|
+
})
|
|
181
|
+
|
|
182
|
+
const ContactInfo = z.object({
|
|
183
|
+
name: z.string(),
|
|
184
|
+
email: z.string().email(),
|
|
185
|
+
role: z.string(),
|
|
186
|
+
})
|
|
187
|
+
|
|
188
|
+
const contact = await llm.extract(
|
|
189
|
+
ContactInfo,
|
|
190
|
+
'Reach out to Jane Smith (jane@acme.com), she is the VP of Engineering.',
|
|
191
|
+
)
|
|
192
|
+
|
|
193
|
+
console.log(contact.name) // "Jane Smith"
|
|
194
|
+
console.log(contact.email) // "jane@acme.com"
|
|
195
|
+
console.log(contact.role) // "VP of Engineering"
|
|
196
|
+
```
|
|
197
|
+
|
|
144
198
|
#### X-Ray Mode
|
|
145
199
|
|
|
146
200
|
```ts
|
|
@@ -295,6 +349,46 @@ const response = await provider.complete({
|
|
|
295
349
|
})
|
|
296
350
|
```
|
|
297
351
|
|
|
352
|
+
### `createOpenAICompatibleProvider(config)`
|
|
353
|
+
|
|
354
|
+
Creates an LLM provider for any API that follows the OpenAI chat completions format (e.g. Groq, Together, Ollama, LMStudio, Azure OpenAI).
|
|
355
|
+
|
|
356
|
+
```ts
|
|
357
|
+
function createOpenAICompatibleProvider(config: {
|
|
358
|
+
baseUrl: string
|
|
359
|
+
apiKey: string
|
|
360
|
+
name?: string
|
|
361
|
+
defaultModel?: string
|
|
362
|
+
capabilities?: string[]
|
|
363
|
+
}): LLMProvider
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
| Parameter | Type | Default | Description |
|
|
367
|
+
|---|---|---|---|
|
|
368
|
+
| `config.baseUrl` | `string` | **(required)** | Base URL of the OpenAI-compatible API. |
|
|
369
|
+
| `config.apiKey` | `string` | **(required)** | API key for the provider. |
|
|
370
|
+
| `config.name` | `string` | `'openai-compatible'` | Provider name used in logging and routing. |
|
|
371
|
+
| `config.defaultModel` | `string` | `'default'` | Default model when none is specified per-request. |
|
|
372
|
+
| `config.capabilities` | `string[]` | `['streaming']` | Capabilities to advertise (used by `capability-aware` routing). |
|
|
373
|
+
|
|
374
|
+
**Returns:** An `LLMProvider` that sends requests to the given base URL using the OpenAI request/response format.
|
|
375
|
+
|
|
376
|
+
```ts
|
|
377
|
+
import { createOpenAICompatibleProvider } from '@elsium-ai/gateway'
|
|
378
|
+
|
|
379
|
+
const provider = createOpenAICompatibleProvider({
|
|
380
|
+
baseUrl: 'https://api.groq.com/openai',
|
|
381
|
+
apiKey: process.env.GROQ_API_KEY!,
|
|
382
|
+
name: 'groq',
|
|
383
|
+
defaultModel: 'llama-3.3-70b-versatile',
|
|
384
|
+
capabilities: ['tools', 'streaming'],
|
|
385
|
+
})
|
|
386
|
+
|
|
387
|
+
const response = await provider.complete({
|
|
388
|
+
messages: [{ role: 'user', content: 'Hello!' }],
|
|
389
|
+
})
|
|
390
|
+
```
|
|
391
|
+
|
|
298
392
|
### `createGoogleProvider(config)`
|
|
299
393
|
|
|
300
394
|
Creates an LLM provider for the Google Gemini API.
|
|
@@ -962,7 +1056,7 @@ interface ProviderMesh {
|
|
|
962
1056
|
| Member | Description |
|
|
963
1057
|
|---|---|
|
|
964
1058
|
| `complete(request)` | Routes a completion request according to the configured strategy. |
|
|
965
|
-
| `stream(request)` | Streams from the first available provider (respects circuit breaker state). |
|
|
1059
|
+
| `stream(request)` | Streams from the first available provider with automatic failover across all four routing strategies (respects circuit breaker state). |
|
|
966
1060
|
| `providers` | List of provider names in the mesh. |
|
|
967
1061
|
| `strategy` | The active routing strategy. |
|
|
968
1062
|
|
package/dist/gateway.d.ts
CHANGED
|
@@ -17,6 +17,12 @@ export interface GatewayConfig {
|
|
|
17
17
|
maxMessages?: number;
|
|
18
18
|
maxInputTokens?: number;
|
|
19
19
|
}
|
|
20
|
+
export interface ExtractOptions {
|
|
21
|
+
model?: string;
|
|
22
|
+
system?: string;
|
|
23
|
+
maxRetries?: number;
|
|
24
|
+
temperature?: number;
|
|
25
|
+
}
|
|
20
26
|
export interface Gateway {
|
|
21
27
|
complete(request: CompletionRequest): Promise<LLMResponse>;
|
|
22
28
|
stream(request: CompletionRequest): ElsiumStream;
|
|
@@ -26,6 +32,7 @@ export interface Gateway {
|
|
|
26
32
|
data: T;
|
|
27
33
|
response: LLMResponse;
|
|
28
34
|
}>;
|
|
35
|
+
extract<T>(schema: z.ZodType<T>, input: string, options?: ExtractOptions): Promise<T>;
|
|
29
36
|
readonly provider: LLMProvider;
|
|
30
37
|
lastCall(): XRayData | null;
|
|
31
38
|
callHistory(limit?: number): XRayData[];
|
package/dist/gateway.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gateway.d.ts","sourceRoot":"","sources":["../src/gateway.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACX,iBAAiB,EACjB,WAAW,EACX,UAAU,EAEV,cAAc,EAEd,gBAAgB,EAChB,QAAQ,EACR,MAAM,iBAAiB,CAAA;AACxB,OAAO,EAEN,KAAK,YAAY,EAIjB,MAAM,iBAAiB,CAAA;AACxB,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAI5B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAY7C,MAAM,WAAW,aAAa;IAC7B,QAAQ,EAAE,MAAM,CAAA;IAChB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,UAAU,CAAC,EAAE,UAAU,EAAE,CAAA;IACzB,gBAAgB,CAAC,EAAE,gBAAgB,EAAE,CAAA;IACrC,IAAI,CAAC,EAAE,OAAO,GAAG;QAAE,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;IACxC,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,cAAc,CAAC,EAAE,MAAM,CAAA;CACvB;AAED,MAAM,WAAW,OAAO;IACvB,QAAQ,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,WAAW,CAAC,CAAA;IAC1D,MAAM,CAAC,OAAO,EAAE,iBAAiB,GAAG,YAAY,CAAA;IAChD,QAAQ,CAAC,CAAC,EAAE,OAAO,EAAE,iBAAiB,GAAG;QAAE,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAA;KAAE,GAAG,OAAO,CAAC;QAC3E,IAAI,EAAE,CAAC,CAAA;QACP,QAAQ,EAAE,WAAW,CAAA;KACrB,CAAC,CAAA;IACF,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAA;IAC9B,QAAQ,IAAI,QAAQ,GAAG,IAAI,CAAA;IAC3B,WAAW,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,QAAQ,EAAE,CAAA;CACvC;AA4BD,wBAAgB,uBAAuB,CACtC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,CAAC,MAAM,EAAE,cAAc,KAAK,WAAW,GAC9C,IAAI,CAGN;AAwJD,wBAAgB,OAAO,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,
|
|
1
|
+
{"version":3,"file":"gateway.d.ts","sourceRoot":"","sources":["../src/gateway.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACX,iBAAiB,EACjB,WAAW,EACX,UAAU,EAEV,cAAc,EAEd,gBAAgB,EAChB,QAAQ,EACR,MAAM,iBAAiB,CAAA;AACxB,OAAO,EAEN,KAAK,YAAY,EAIjB,MAAM,iBAAiB,CAAA;AACxB,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAI5B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAY7C,MAAM,WAAW,aAAa;IAC7B,QAAQ,EAAE,MAAM,CAAA;IAChB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,UAAU,CAAC,EAAE,UAAU,EAAE,CAAA;IACzB,gBAAgB,CAAC,EAAE,gBAAgB,EAAE,CAAA;IACrC,IAAI,CAAC,EAAE,OAAO,GAAG;QAAE,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;IACxC,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,cAAc,CAAC,EAAE,MAAM,CAAA;CACvB;AAED,MAAM,WAAW,cAAc;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,WAAW,CAAC,EAAE,MAAM,CAAA;CACpB;AAED,MAAM,WAAW,OAAO;IACvB,QAAQ,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,WAAW,CAAC,CAAA;IAC1D,MAAM,CAAC,OAAO,EAAE,iBAAiB,GAAG,YAAY,CAAA;IAChD,QAAQ,CAAC,CAAC,EAAE,OAAO,EAAE,iBAAiB,GAAG;QAAE,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAA;KAAE,GAAG,OAAO,CAAC;QAC3E,IAAI,EAAE,CAAC,CAAA;QACP,QAAQ,EAAE,WAAW,CAAA;KACrB,CAAC,CAAA;IACF,OAAO,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,CAAC,CAAC,CAAA;IACrF,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAA;IAC9B,QAAQ,IAAI,QAAQ,GAAG,IAAI,CAAA;IAC3B,WAAW,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,QAAQ,EAAE,CAAA;CACvC;AA4BD,wBAAgB,uBAAuB,CACtC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,CAAC,MAAM,EAAE,cAAc,KAAK,WAAW,GAC9C,IAAI,CAGN;AAwJD,wBAAgB,OAAO,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAsKtD"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { gateway, registerProviderFactory } from './gateway';
|
|
2
|
-
export type { GatewayConfig, Gateway } from './gateway';
|
|
2
|
+
export type { GatewayConfig, Gateway, ExtractOptions } from './gateway';
|
|
3
3
|
export type { LLMProvider, ProviderFactory, ProviderMetadata, ModelPricing, ModelTier, } from './provider';
|
|
4
4
|
export { registerProvider, getProviderFactory, listProviders, registerProviderMetadata, getProviderMetadata, } from './provider';
|
|
5
5
|
export { createAnthropicProvider } from './providers/anthropic';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,uBAAuB,EAAE,MAAM,WAAW,CAAA;AAC5D,YAAY,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,uBAAuB,EAAE,MAAM,WAAW,CAAA;AAC5D,YAAY,EAAE,aAAa,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAA;AAGvE,YAAY,EACX,WAAW,EACX,eAAe,EACf,gBAAgB,EAChB,YAAY,EACZ,SAAS,GACT,MAAM,YAAY,CAAA;AACnB,OAAO,EACN,gBAAgB,EAChB,kBAAkB,EAClB,aAAa,EACb,wBAAwB,EACxB,mBAAmB,GACnB,MAAM,YAAY,CAAA;AAGnB,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAA;AAC/D,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAA;AACzD,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAA;AACzD,OAAO,EAAE,8BAA8B,EAAE,MAAM,+BAA+B,CAAA;AAC9E,YAAY,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAA;AAG3E,OAAO,EACN,iBAAiB,EACjB,uBAAuB,EACvB,iBAAiB,EACjB,sBAAsB,EACtB,cAAc,GACd,MAAM,cAAc,CAAA;AACrB,YAAY,EAAE,SAAS,EAAE,MAAM,cAAc,CAAA;AAG7C,OAAO,EACN,kBAAkB,EAClB,qBAAqB,EACrB,eAAe,EACf,aAAa,EACb,oBAAoB,EACpB,eAAe,GACf,MAAM,YAAY,CAAA;AACnB,YAAY,EACX,wBAAwB,EACxB,iBAAiB,EACjB,cAAc,EACd,kBAAkB,EAClB,oBAAoB,GACpB,MAAM,YAAY,CAAA;AAGnB,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAA;AAC/D,YAAY,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAG1D,OAAO,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAA;AAC9D,YAAY,EAAE,YAAY,EAAE,UAAU,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAA;AAG9E,OAAO,EAAE,yBAAyB,EAAE,MAAM,qBAAqB,CAAA;AAC/D,YAAY,EACX,qBAAqB,EACrB,mBAAmB,EACnB,eAAe,GACf,MAAM,qBAAqB,CAAA;AAG5B,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,WAAW,CAAA;AAGxE,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAA;AACrC,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AAGxE,OAAO,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAA;AAC7C,YAAY,EACX,kBAAkB,EAClB,aAAa,EACb,eAAe,EACf,YAAY,EACZ,eAAe,GACf,MAAM,UAAU,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -2251,6 +2251,38 @@ function gateway(config) {
|
|
|
2251
2251
|
});
|
|
2252
2252
|
}
|
|
2253
2253
|
return { data: result.data, response };
|
|
2254
|
+
},
|
|
2255
|
+
async extract(schema, input, options) {
|
|
2256
|
+
const maxRetries = options?.maxRetries ?? 3;
|
|
2257
|
+
const messages = [{ role: "user", content: input }];
|
|
2258
|
+
let lastError;
|
|
2259
|
+
for (let attempt = 0;attempt <= maxRetries; attempt++) {
|
|
2260
|
+
try {
|
|
2261
|
+
const result = await this.generate({
|
|
2262
|
+
messages: [...messages],
|
|
2263
|
+
schema,
|
|
2264
|
+
model: options?.model,
|
|
2265
|
+
system: options?.system,
|
|
2266
|
+
temperature: options?.temperature
|
|
2267
|
+
});
|
|
2268
|
+
return result.data;
|
|
2269
|
+
} catch (e) {
|
|
2270
|
+
if (e instanceof ElsiumError && e.code === "VALIDATION_ERROR") {
|
|
2271
|
+
lastError = e;
|
|
2272
|
+
messages.push({
|
|
2273
|
+
role: "assistant",
|
|
2274
|
+
content: "Invalid output"
|
|
2275
|
+
});
|
|
2276
|
+
messages.push({
|
|
2277
|
+
role: "user",
|
|
2278
|
+
content: `The previous response failed validation: ${e.message}. Please try again and return valid JSON matching the schema.`
|
|
2279
|
+
});
|
|
2280
|
+
continue;
|
|
2281
|
+
}
|
|
2282
|
+
throw e;
|
|
2283
|
+
}
|
|
2284
|
+
}
|
|
2285
|
+
throw lastError;
|
|
2254
2286
|
}
|
|
2255
2287
|
};
|
|
2256
2288
|
}
|
|
@@ -3199,10 +3231,10 @@ function createProviderMesh(config) {
|
|
|
3199
3231
|
};
|
|
3200
3232
|
}());
|
|
3201
3233
|
}
|
|
3202
|
-
function logStreamFailover(provider, error) {
|
|
3234
|
+
function logStreamFailover(provider, toProvider, error) {
|
|
3203
3235
|
audit?.log("provider_failover", {
|
|
3204
3236
|
fromProvider: provider,
|
|
3205
|
-
toProvider
|
|
3237
|
+
toProvider,
|
|
3206
3238
|
strategy: config.strategy,
|
|
3207
3239
|
reason: error?.message
|
|
3208
3240
|
});
|
|
@@ -3225,25 +3257,33 @@ function createProviderMesh(config) {
|
|
|
3225
3257
|
}
|
|
3226
3258
|
return { success: true };
|
|
3227
3259
|
}
|
|
3260
|
+
async function attemptStreamProvider(entry, nextProvider, request, emit) {
|
|
3261
|
+
try {
|
|
3262
|
+
const result = await tryStreamProvider(entry, request, emit);
|
|
3263
|
+
if (result.success)
|
|
3264
|
+
return { success: true };
|
|
3265
|
+
logStreamFailover(entry.name, nextProvider, result.error);
|
|
3266
|
+
return { success: false, error: result.error };
|
|
3267
|
+
} catch (err2) {
|
|
3268
|
+
const error = toError2(err2);
|
|
3269
|
+
logStreamFailover(entry.name, nextProvider, error);
|
|
3270
|
+
return { success: false, error };
|
|
3271
|
+
}
|
|
3272
|
+
}
|
|
3228
3273
|
async function runStreamFallbackLoop(available, request, emit) {
|
|
3229
3274
|
let lastError = null;
|
|
3230
3275
|
let failedProvider = null;
|
|
3231
|
-
for (
|
|
3232
|
-
|
|
3233
|
-
|
|
3234
|
-
|
|
3235
|
-
|
|
3236
|
-
|
|
3237
|
-
|
|
3238
|
-
|
|
3239
|
-
lastError = result.error ?? null;
|
|
3240
|
-
failedProvider = entry.name;
|
|
3241
|
-
logStreamFailover(entry.name, result.error);
|
|
3242
|
-
} catch (err2) {
|
|
3243
|
-
failedProvider = entry.name;
|
|
3244
|
-
lastError = toError2(err2);
|
|
3245
|
-
logStreamFailover(entry.name, lastError);
|
|
3276
|
+
for (let i = 0;i < available.length; i++) {
|
|
3277
|
+
const entry = available[i];
|
|
3278
|
+
const nextProvider = i + 1 < available.length ? available[i + 1].name : "none";
|
|
3279
|
+
const attempt = await attemptStreamProvider(entry, nextProvider, request, emit);
|
|
3280
|
+
if (attempt.success) {
|
|
3281
|
+
if (failedProvider)
|
|
3282
|
+
logFailover(failedProvider, entry.name, lastError?.message);
|
|
3283
|
+
return;
|
|
3246
3284
|
}
|
|
3285
|
+
lastError = attempt.error ?? null;
|
|
3286
|
+
failedProvider = entry.name;
|
|
3247
3287
|
}
|
|
3248
3288
|
emit({
|
|
3249
3289
|
type: "error",
|
package/dist/router.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../src/router.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAA;AACrE,OAAO,EAEN,KAAK,oBAAoB,EAEzB,YAAY,EAGZ,MAAM,iBAAiB,CAAA;AAKxB,MAAM,MAAM,eAAe,GACxB,UAAU,GACV,gBAAgB,GAChB,mBAAmB,GACnB,kBAAkB,CAAA;AAErB,MAAM,WAAW,aAAa;IAC7B,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;IAC5C,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,YAAY,CAAC,EAAE,MAAM,EAAE,CAAA;CACvB;AAED,MAAM,WAAW,mBAAmB;IACnC,WAAW,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAA;IAChD,YAAY,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAA;IACjD,mBAAmB,CAAC,EAAE,MAAM,CAAA;CAC5B;AAED,MAAM,WAAW,eAAe;IAC/B,GAAG,CACF,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,GAC5C,IAAI,CAAA;CACP;AAED,MAAM,WAAW,kBAAkB;IAClC,SAAS,EAAE,aAAa,EAAE,CAAA;IAC1B,QAAQ,EAAE,eAAe,CAAA;IACzB,aAAa,CAAC,EAAE,mBAAmB,CAAA;IACnC,cAAc,CAAC,EAAE,oBAAoB,GAAG,OAAO,CAAA;IAC/C,KAAK,CAAC,EAAE,eAAe,CAAA;CACvB;AAED,MAAM,WAAW,YAAY;IAC5B,QAAQ,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,WAAW,CAAC,CAAA;IAC1D,MAAM,CAAC,OAAO,EAAE,iBAAiB,GAAG,YAAY,CAAA;IAChD,QAAQ,CAAC,SAAS,EAAE,MAAM,EAAE,CAAA;IAC5B,QAAQ,CAAC,QAAQ,EAAE,eAAe,CAAA;CAClC;AAoDD,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,kBAAkB,GAAG,YAAY,
|
|
1
|
+
{"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../src/router.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAA;AACrE,OAAO,EAEN,KAAK,oBAAoB,EAEzB,YAAY,EAGZ,MAAM,iBAAiB,CAAA;AAKxB,MAAM,MAAM,eAAe,GACxB,UAAU,GACV,gBAAgB,GAChB,mBAAmB,GACnB,kBAAkB,CAAA;AAErB,MAAM,WAAW,aAAa;IAC7B,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;IAC5C,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,YAAY,CAAC,EAAE,MAAM,EAAE,CAAA;CACvB;AAED,MAAM,WAAW,mBAAmB;IACnC,WAAW,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAA;IAChD,YAAY,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAA;IACjD,mBAAmB,CAAC,EAAE,MAAM,CAAA;CAC5B;AAED,MAAM,WAAW,eAAe;IAC/B,GAAG,CACF,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,GAC5C,IAAI,CAAA;CACP;AAED,MAAM,WAAW,kBAAkB;IAClC,SAAS,EAAE,aAAa,EAAE,CAAA;IAC1B,QAAQ,EAAE,eAAe,CAAA;IACzB,aAAa,CAAC,EAAE,mBAAmB,CAAA;IACnC,cAAc,CAAC,EAAE,oBAAoB,GAAG,OAAO,CAAA;IAC/C,KAAK,CAAC,EAAE,eAAe,CAAA;CACvB;AAED,MAAM,WAAW,YAAY;IAC5B,QAAQ,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,WAAW,CAAC,CAAA;IAC1D,MAAM,CAAC,OAAO,EAAE,iBAAiB,GAAG,YAAY,CAAA;IAChD,QAAQ,CAAC,SAAS,EAAE,MAAM,EAAE,CAAA;IAC5B,QAAQ,CAAC,QAAQ,EAAE,eAAe,CAAA;CAClC;AAoDD,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,kBAAkB,GAAG,YAAY,CAkc3E"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@elsium-ai/gateway",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.1",
|
|
4
4
|
"description": "Multi-provider LLM gateway for ElsiumAI",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Eric Utrera <ebutrera9103@gmail.com>",
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"dev": "bun --watch src/index.ts"
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@elsium-ai/core": "^0.
|
|
29
|
+
"@elsium-ai/core": "^0.9.1",
|
|
30
30
|
"zod": "^3.24.0"
|
|
31
31
|
},
|
|
32
32
|
"devDependencies": {
|