@elsium-ai/app 0.7.0 → 0.8.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/app.d.ts +2 -1
- package/dist/app.d.ts.map +1 -1
- package/dist/index.js +605 -13
- package/dist/routes.d.ts +2 -1
- package/dist/routes.d.ts.map +1 -1
- package/dist/sse.d.ts +1 -1
- package/dist/sse.d.ts.map +1 -1
- package/dist/types.d.ts +2 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +8 -8
package/dist/app.d.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import { type Gateway } from '@elsium-ai/gateway';
|
|
1
|
+
import { type Gateway, type ProviderMesh } from '@elsium-ai/gateway';
|
|
2
2
|
import { type Tracer } from '@elsium-ai/observe';
|
|
3
3
|
import { Hono } from 'hono';
|
|
4
4
|
import type { AppConfig } from './types';
|
|
5
5
|
export interface ElsiumApp {
|
|
6
6
|
readonly hono: Hono;
|
|
7
7
|
readonly gateway: Gateway;
|
|
8
|
+
readonly mesh: ProviderMesh | undefined;
|
|
8
9
|
readonly tracer: Tracer;
|
|
9
10
|
listen(port?: number): {
|
|
10
11
|
port: number;
|
package/dist/app.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,KAAK,OAAO,
|
|
1
|
+
{"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,KAAK,OAAO,EAAE,KAAK,YAAY,EAA+B,MAAM,oBAAoB,CAAA;AACjG,OAAO,EAAE,KAAK,MAAM,EAAW,MAAM,oBAAoB,CAAA;AAIzD,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAS3B,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAA;AAExC,MAAM,WAAW,SAAS;IACzB,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAA;IACnB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;IACzB,QAAQ,CAAC,IAAI,EAAE,YAAY,GAAG,SAAS,CAAA;IACvC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,MAAM,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;KAAE,CAAA;CAClE;AAED,wBAAgB,SAAS,CAAC,MAAM,EAAE,SAAS,GAAG,SAAS,CA8JtD"}
|
package/dist/index.js
CHANGED
|
@@ -477,6 +477,134 @@ function zodToJsonSchema(schema) {
|
|
|
477
477
|
// ../core/src/registry.ts
|
|
478
478
|
var log2 = createLogger();
|
|
479
479
|
var BLOCKED_KEYS = new Set(["__proto__", "constructor", "prototype"]);
|
|
480
|
+
// ../core/src/circuit-breaker.ts
|
|
481
|
+
function defaultShouldCount(error) {
|
|
482
|
+
if (error && typeof error === "object" && "retryable" in error) {
|
|
483
|
+
return error.retryable === true;
|
|
484
|
+
}
|
|
485
|
+
return true;
|
|
486
|
+
}
|
|
487
|
+
function createCircuitBreaker(config) {
|
|
488
|
+
const failureThreshold = config?.failureThreshold ?? 5;
|
|
489
|
+
const resetTimeoutMs = config?.resetTimeoutMs ?? 30000;
|
|
490
|
+
const halfOpenMaxAttempts = config?.halfOpenMaxAttempts ?? 3;
|
|
491
|
+
const windowMs = config?.windowMs ?? 60000;
|
|
492
|
+
if (failureThreshold < 1 || !Number.isFinite(failureThreshold)) {
|
|
493
|
+
throw new ElsiumError({
|
|
494
|
+
code: "CONFIG_ERROR",
|
|
495
|
+
message: "failureThreshold must be >= 1",
|
|
496
|
+
retryable: false
|
|
497
|
+
});
|
|
498
|
+
}
|
|
499
|
+
if (resetTimeoutMs < 0 || !Number.isFinite(resetTimeoutMs)) {
|
|
500
|
+
throw new ElsiumError({
|
|
501
|
+
code: "CONFIG_ERROR",
|
|
502
|
+
message: "resetTimeoutMs must be >= 0 and finite",
|
|
503
|
+
retryable: false
|
|
504
|
+
});
|
|
505
|
+
}
|
|
506
|
+
if (halfOpenMaxAttempts < 1 || !Number.isFinite(halfOpenMaxAttempts)) {
|
|
507
|
+
throw new ElsiumError({
|
|
508
|
+
code: "CONFIG_ERROR",
|
|
509
|
+
message: "halfOpenMaxAttempts must be >= 1",
|
|
510
|
+
retryable: false
|
|
511
|
+
});
|
|
512
|
+
}
|
|
513
|
+
if (windowMs < 0 || !Number.isFinite(windowMs)) {
|
|
514
|
+
throw new ElsiumError({
|
|
515
|
+
code: "CONFIG_ERROR",
|
|
516
|
+
message: "windowMs must be >= 0 and finite",
|
|
517
|
+
retryable: false
|
|
518
|
+
});
|
|
519
|
+
}
|
|
520
|
+
const onStateChange = config?.onStateChange;
|
|
521
|
+
const shouldCount = config?.shouldCount ?? defaultShouldCount;
|
|
522
|
+
let currentState = "closed";
|
|
523
|
+
let failureTimestamps = [];
|
|
524
|
+
let lastOpenedAt = 0;
|
|
525
|
+
let halfOpenAttempts = 0;
|
|
526
|
+
let halfOpenInFlight = 0;
|
|
527
|
+
function transition(to) {
|
|
528
|
+
if (currentState === to)
|
|
529
|
+
return;
|
|
530
|
+
const from = currentState;
|
|
531
|
+
currentState = to;
|
|
532
|
+
onStateChange?.(from, to);
|
|
533
|
+
}
|
|
534
|
+
function recordFailure() {
|
|
535
|
+
const now = Date.now();
|
|
536
|
+
failureTimestamps.push(now);
|
|
537
|
+
failureTimestamps = failureTimestamps.filter((t) => now - t < windowMs);
|
|
538
|
+
if (failureTimestamps.length >= failureThreshold) {
|
|
539
|
+
lastOpenedAt = now;
|
|
540
|
+
halfOpenAttempts = 0;
|
|
541
|
+
transition("open");
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
function recordSuccess() {
|
|
545
|
+
if (currentState === "half-open") {
|
|
546
|
+
failureTimestamps = [];
|
|
547
|
+
halfOpenAttempts = 0;
|
|
548
|
+
halfOpenInFlight = 0;
|
|
549
|
+
transition("closed");
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
return {
|
|
553
|
+
get state() {
|
|
554
|
+
if (currentState === "open" && Date.now() - lastOpenedAt >= resetTimeoutMs) {
|
|
555
|
+
transition("half-open");
|
|
556
|
+
}
|
|
557
|
+
return currentState;
|
|
558
|
+
},
|
|
559
|
+
get failureCount() {
|
|
560
|
+
const now = Date.now();
|
|
561
|
+
return failureTimestamps.filter((t) => now - t < windowMs).length;
|
|
562
|
+
},
|
|
563
|
+
async execute(fn) {
|
|
564
|
+
const state = this.state;
|
|
565
|
+
if (state === "open") {
|
|
566
|
+
throw new ElsiumError({
|
|
567
|
+
code: "PROVIDER_ERROR",
|
|
568
|
+
message: "Circuit breaker is open",
|
|
569
|
+
retryable: true
|
|
570
|
+
});
|
|
571
|
+
}
|
|
572
|
+
if (state === "half-open" && halfOpenInFlight >= halfOpenMaxAttempts) {
|
|
573
|
+
lastOpenedAt = Date.now();
|
|
574
|
+
transition("open");
|
|
575
|
+
throw new ElsiumError({
|
|
576
|
+
code: "PROVIDER_ERROR",
|
|
577
|
+
message: "Circuit breaker is open",
|
|
578
|
+
retryable: true
|
|
579
|
+
});
|
|
580
|
+
}
|
|
581
|
+
if (state === "half-open") {
|
|
582
|
+
halfOpenAttempts++;
|
|
583
|
+
halfOpenInFlight++;
|
|
584
|
+
}
|
|
585
|
+
try {
|
|
586
|
+
const result = await fn();
|
|
587
|
+
recordSuccess();
|
|
588
|
+
return result;
|
|
589
|
+
} catch (error) {
|
|
590
|
+
if (shouldCount(error)) {
|
|
591
|
+
recordFailure();
|
|
592
|
+
}
|
|
593
|
+
throw error;
|
|
594
|
+
} finally {
|
|
595
|
+
if (state === "half-open") {
|
|
596
|
+
halfOpenInFlight = Math.max(0, halfOpenInFlight - 1);
|
|
597
|
+
}
|
|
598
|
+
}
|
|
599
|
+
},
|
|
600
|
+
reset() {
|
|
601
|
+
failureTimestamps = [];
|
|
602
|
+
halfOpenAttempts = 0;
|
|
603
|
+
halfOpenInFlight = 0;
|
|
604
|
+
transition("closed");
|
|
605
|
+
}
|
|
606
|
+
};
|
|
607
|
+
}
|
|
480
608
|
// ../core/src/shutdown.ts
|
|
481
609
|
function createShutdownManager(config) {
|
|
482
610
|
const drainTimeoutMs = config?.drainTimeoutMs ?? 30000;
|
|
@@ -1900,11 +2028,44 @@ async function processOpenAISSEStream(body, emit) {
|
|
|
1900
2028
|
}
|
|
1901
2029
|
}
|
|
1902
2030
|
|
|
2031
|
+
// ../gateway/src/providers/openai-compatible.ts
|
|
2032
|
+
function createOpenAICompatibleProvider(config) {
|
|
2033
|
+
const providerName = config.name ?? "openai-compatible";
|
|
2034
|
+
const model = config.defaultModel ?? "default";
|
|
2035
|
+
const inner = createOpenAIProvider({
|
|
2036
|
+
apiKey: config.apiKey,
|
|
2037
|
+
baseUrl: config.baseUrl,
|
|
2038
|
+
timeout: config.timeout,
|
|
2039
|
+
maxRetries: config.maxRetries
|
|
2040
|
+
});
|
|
2041
|
+
const metadata = {
|
|
2042
|
+
baseUrl: `${config.baseUrl}/v1/chat/completions`,
|
|
2043
|
+
capabilities: config.capabilities ?? ["tools", "streaming", "system"],
|
|
2044
|
+
authStyle: "bearer"
|
|
2045
|
+
};
|
|
2046
|
+
return {
|
|
2047
|
+
name: providerName,
|
|
2048
|
+
defaultModel: model,
|
|
2049
|
+
metadata,
|
|
2050
|
+
async complete(request) {
|
|
2051
|
+
const response = await inner.complete(request);
|
|
2052
|
+
return { ...response, provider: providerName };
|
|
2053
|
+
},
|
|
2054
|
+
stream(request) {
|
|
2055
|
+
return inner.stream(request);
|
|
2056
|
+
},
|
|
2057
|
+
async listModels() {
|
|
2058
|
+
return inner.listModels();
|
|
2059
|
+
}
|
|
2060
|
+
};
|
|
2061
|
+
}
|
|
2062
|
+
|
|
1903
2063
|
// ../gateway/src/gateway.ts
|
|
1904
2064
|
var PROVIDER_FACTORIES = {
|
|
1905
2065
|
anthropic: createAnthropicProvider,
|
|
1906
2066
|
openai: createOpenAIProvider,
|
|
1907
|
-
google: createGoogleProvider
|
|
2067
|
+
google: createGoogleProvider,
|
|
2068
|
+
"openai-compatible": (cfg) => createOpenAICompatibleProvider({ ...cfg, baseUrl: cfg.baseUrl ?? "" })
|
|
1908
2069
|
};
|
|
1909
2070
|
registerProviderMetadata("anthropic", {
|
|
1910
2071
|
baseUrl: "https://api.anthropic.com/v1/messages",
|
|
@@ -2132,6 +2293,408 @@ var log4 = createLogger();
|
|
|
2132
2293
|
var log5 = createLogger();
|
|
2133
2294
|
// ../gateway/src/batch.ts
|
|
2134
2295
|
var log6 = createLogger();
|
|
2296
|
+
// ../gateway/src/router.ts
|
|
2297
|
+
var REASONING_KEYWORDS = /\b(prove|explain why|analyze|compare|contrast|evaluate|critique|debate|reason|deduce|infer|justify|argue|synthesize|hypothesize|derive)\b/i;
|
|
2298
|
+
var CODE_KEYWORDS = /\b(implement|refactor|debug|optimize|architect|design pattern|algorithm|data structure|write code|code review|fix the bug|type system)\b/i;
|
|
2299
|
+
var CREATIVE_KEYWORDS = /\b(write a (story|essay|poem|article|report|paper)|compose|draft|create a (plan|proposal|strategy))\b/i;
|
|
2300
|
+
var MATH_KEYWORDS = /\b(calculate|compute|solve|equation|integral|derivative|matrix|probability|statistical|proof|theorem|formula)\b/i;
|
|
2301
|
+
function extractTextContent(request) {
|
|
2302
|
+
const parts = [];
|
|
2303
|
+
for (const m of request.messages) {
|
|
2304
|
+
if (typeof m.content === "string") {
|
|
2305
|
+
parts.push(m.content);
|
|
2306
|
+
} else if (Array.isArray(m.content)) {
|
|
2307
|
+
for (const p of m.content) {
|
|
2308
|
+
if (p.type === "text")
|
|
2309
|
+
parts.push(p.text);
|
|
2310
|
+
}
|
|
2311
|
+
}
|
|
2312
|
+
}
|
|
2313
|
+
if (request.system)
|
|
2314
|
+
parts.push(request.system);
|
|
2315
|
+
return parts.join(" ");
|
|
2316
|
+
}
|
|
2317
|
+
function estimateComplexity(request) {
|
|
2318
|
+
let score = 0;
|
|
2319
|
+
const totalChars = request.messages.reduce((sum, m) => {
|
|
2320
|
+
const len = typeof m.content === "string" ? m.content.length : JSON.stringify(m.content).length;
|
|
2321
|
+
return sum + len;
|
|
2322
|
+
}, 0);
|
|
2323
|
+
if (totalChars > 2000)
|
|
2324
|
+
score += 0.3;
|
|
2325
|
+
if (totalChars > 5000)
|
|
2326
|
+
score += 0.2;
|
|
2327
|
+
if (request.tools?.length)
|
|
2328
|
+
score += 0.2;
|
|
2329
|
+
if ((request.tools?.length ?? 0) > 3)
|
|
2330
|
+
score += 0.1;
|
|
2331
|
+
if (request.system && request.system.length > 500)
|
|
2332
|
+
score += 0.1;
|
|
2333
|
+
if (request.messages.length > 10)
|
|
2334
|
+
score += 0.1;
|
|
2335
|
+
const text = extractTextContent(request);
|
|
2336
|
+
if (REASONING_KEYWORDS.test(text))
|
|
2337
|
+
score += 0.5;
|
|
2338
|
+
if (CODE_KEYWORDS.test(text))
|
|
2339
|
+
score += 0.5;
|
|
2340
|
+
if (CREATIVE_KEYWORDS.test(text))
|
|
2341
|
+
score += 0.2;
|
|
2342
|
+
if (MATH_KEYWORDS.test(text))
|
|
2343
|
+
score += 0.5;
|
|
2344
|
+
return Math.min(score, 1);
|
|
2345
|
+
}
|
|
2346
|
+
function createProviderMesh(config) {
|
|
2347
|
+
if (config.providers.length === 0) {
|
|
2348
|
+
throw new ElsiumError({
|
|
2349
|
+
code: "CONFIG_ERROR",
|
|
2350
|
+
message: "Provider mesh requires at least one provider",
|
|
2351
|
+
retryable: false
|
|
2352
|
+
});
|
|
2353
|
+
}
|
|
2354
|
+
const sortedProviders = [...config.providers];
|
|
2355
|
+
const gateways = new Map;
|
|
2356
|
+
const circuitBreakers = new Map;
|
|
2357
|
+
const audit = config.audit;
|
|
2358
|
+
for (const entry of sortedProviders) {
|
|
2359
|
+
const gw = gateway({
|
|
2360
|
+
provider: entry.name,
|
|
2361
|
+
apiKey: entry.config.apiKey,
|
|
2362
|
+
baseUrl: entry.config.baseUrl,
|
|
2363
|
+
model: entry.model
|
|
2364
|
+
});
|
|
2365
|
+
gateways.set(entry.name, gw);
|
|
2366
|
+
if (config.circuitBreaker) {
|
|
2367
|
+
const cbConfig = typeof config.circuitBreaker === "boolean" ? {} : config.circuitBreaker;
|
|
2368
|
+
const providerName = entry.name;
|
|
2369
|
+
const wrappedConfig = {
|
|
2370
|
+
...cbConfig,
|
|
2371
|
+
onStateChange(from, to) {
|
|
2372
|
+
cbConfig.onStateChange?.(from, to);
|
|
2373
|
+
audit?.log("circuit_breaker_state_change", {
|
|
2374
|
+
provider: providerName,
|
|
2375
|
+
fromState: from,
|
|
2376
|
+
toState: to
|
|
2377
|
+
});
|
|
2378
|
+
}
|
|
2379
|
+
};
|
|
2380
|
+
circuitBreakers.set(entry.name, createCircuitBreaker(wrappedConfig));
|
|
2381
|
+
}
|
|
2382
|
+
}
|
|
2383
|
+
function callWithCircuitBreaker(providerName, fn) {
|
|
2384
|
+
const cb = circuitBreakers.get(providerName);
|
|
2385
|
+
return cb ? cb.execute(fn) : fn();
|
|
2386
|
+
}
|
|
2387
|
+
function isProviderAvailable(providerName) {
|
|
2388
|
+
const cb = circuitBreakers.get(providerName);
|
|
2389
|
+
return !cb || cb.state !== "open";
|
|
2390
|
+
}
|
|
2391
|
+
function getGateway(providerName) {
|
|
2392
|
+
const gw = gateways.get(providerName);
|
|
2393
|
+
if (!gw) {
|
|
2394
|
+
throw new ElsiumError({
|
|
2395
|
+
code: "CONFIG_ERROR",
|
|
2396
|
+
message: `Provider "${providerName}" not found in mesh`,
|
|
2397
|
+
retryable: false
|
|
2398
|
+
});
|
|
2399
|
+
}
|
|
2400
|
+
return gw;
|
|
2401
|
+
}
|
|
2402
|
+
function attemptProvider(entry, request) {
|
|
2403
|
+
const gw = getGateway(entry.name);
|
|
2404
|
+
return callWithCircuitBreaker(entry.name, () => gw.complete({ ...request, model: request.model ?? entry.model }));
|
|
2405
|
+
}
|
|
2406
|
+
function logFailover(fromProvider, toProvider, reason) {
|
|
2407
|
+
audit?.log("provider_failover", {
|
|
2408
|
+
fromProvider,
|
|
2409
|
+
toProvider,
|
|
2410
|
+
strategy: config.strategy,
|
|
2411
|
+
reason
|
|
2412
|
+
});
|
|
2413
|
+
}
|
|
2414
|
+
function toError2(err2) {
|
|
2415
|
+
return err2 instanceof Error ? err2 : new Error(String(err2));
|
|
2416
|
+
}
|
|
2417
|
+
async function tryProvidersWithAudit(providers, request, errorMessage) {
|
|
2418
|
+
let lastError = null;
|
|
2419
|
+
let failedProvider = null;
|
|
2420
|
+
for (const entry of providers) {
|
|
2421
|
+
if (!isProviderAvailable(entry.name))
|
|
2422
|
+
continue;
|
|
2423
|
+
try {
|
|
2424
|
+
const response = await attemptProvider(entry, request);
|
|
2425
|
+
if (failedProvider)
|
|
2426
|
+
logFailover(failedProvider, entry.name, lastError?.message);
|
|
2427
|
+
return response;
|
|
2428
|
+
} catch (err2) {
|
|
2429
|
+
failedProvider = entry.name;
|
|
2430
|
+
lastError = toError2(err2);
|
|
2431
|
+
}
|
|
2432
|
+
}
|
|
2433
|
+
throw lastError ?? new ElsiumError({ code: "PROVIDER_ERROR", message: errorMessage, retryable: false });
|
|
2434
|
+
}
|
|
2435
|
+
async function fallbackComplete(request) {
|
|
2436
|
+
return tryProvidersWithAudit(sortedProviders, request, "All providers failed");
|
|
2437
|
+
}
|
|
2438
|
+
async function costOptimizedComplete(request) {
|
|
2439
|
+
const optimizer = config.costOptimizer;
|
|
2440
|
+
if (!optimizer) {
|
|
2441
|
+
return fallbackComplete(request);
|
|
2442
|
+
}
|
|
2443
|
+
const complexity = estimateComplexity(request);
|
|
2444
|
+
const threshold = optimizer.complexityThreshold ?? 0.5;
|
|
2445
|
+
const target = complexity < threshold ? optimizer.simpleModel : optimizer.complexModel;
|
|
2446
|
+
const gw = getGateway(target.provider);
|
|
2447
|
+
try {
|
|
2448
|
+
return await gw.complete({ ...request, model: target.model });
|
|
2449
|
+
} catch (err2) {
|
|
2450
|
+
audit?.log("provider_failover", {
|
|
2451
|
+
fromProvider: target.provider,
|
|
2452
|
+
toProvider: "fallback-chain",
|
|
2453
|
+
strategy: "cost-optimized",
|
|
2454
|
+
reason: err2 instanceof Error ? err2.message : String(err2)
|
|
2455
|
+
});
|
|
2456
|
+
return fallbackComplete(request);
|
|
2457
|
+
}
|
|
2458
|
+
}
|
|
2459
|
+
async function latencyOptimizedComplete(request) {
|
|
2460
|
+
const controller = new AbortController;
|
|
2461
|
+
const availableProviders = sortedProviders.filter((e) => isProviderAvailable(e.name));
|
|
2462
|
+
const promises = availableProviders.map(async (entry) => {
|
|
2463
|
+
const gw = getGateway(entry.name);
|
|
2464
|
+
return callWithCircuitBreaker(entry.name, () => gw.complete({
|
|
2465
|
+
...request,
|
|
2466
|
+
model: request.model ?? entry.model,
|
|
2467
|
+
signal: controller.signal
|
|
2468
|
+
}));
|
|
2469
|
+
});
|
|
2470
|
+
try {
|
|
2471
|
+
const result = await Promise.any(promises);
|
|
2472
|
+
controller.abort();
|
|
2473
|
+
return result;
|
|
2474
|
+
} catch {
|
|
2475
|
+
throw new ElsiumError({
|
|
2476
|
+
code: "PROVIDER_ERROR",
|
|
2477
|
+
message: "All providers failed",
|
|
2478
|
+
retryable: false
|
|
2479
|
+
});
|
|
2480
|
+
}
|
|
2481
|
+
}
|
|
2482
|
+
function detectRequiredCapabilities(request) {
|
|
2483
|
+
const capabilities = [];
|
|
2484
|
+
if ((request.tools?.length ?? 0) > 0)
|
|
2485
|
+
capabilities.push("tools");
|
|
2486
|
+
const needsVision = request.messages.some((m) => Array.isArray(m.content) && m.content.some((p) => p.type === "image"));
|
|
2487
|
+
if (needsVision)
|
|
2488
|
+
capabilities.push("vision");
|
|
2489
|
+
return capabilities;
|
|
2490
|
+
}
|
|
2491
|
+
function filterCapableProviders(capabilities) {
|
|
2492
|
+
return sortedProviders.filter((entry) => {
|
|
2493
|
+
if (capabilities.length === 0)
|
|
2494
|
+
return true;
|
|
2495
|
+
const providerCaps = entry.capabilities ?? defaultCapabilities(entry.name);
|
|
2496
|
+
return capabilities.every((c) => providerCaps.includes(c));
|
|
2497
|
+
});
|
|
2498
|
+
}
|
|
2499
|
+
async function capabilityAwareComplete(request) {
|
|
2500
|
+
const capabilities = detectRequiredCapabilities(request);
|
|
2501
|
+
const capable = filterCapableProviders(capabilities);
|
|
2502
|
+
if (capable.length === 0) {
|
|
2503
|
+
return fallbackComplete(request);
|
|
2504
|
+
}
|
|
2505
|
+
return tryProvidersWithAudit(capable, request, "No capable provider succeeded");
|
|
2506
|
+
}
|
|
2507
|
+
function defaultCapabilities(provider) {
|
|
2508
|
+
const meta = getProviderMetadata(provider);
|
|
2509
|
+
if (meta?.capabilities)
|
|
2510
|
+
return meta.capabilities;
|
|
2511
|
+
switch (provider) {
|
|
2512
|
+
case "anthropic":
|
|
2513
|
+
return ["tools", "vision", "streaming", "system"];
|
|
2514
|
+
case "openai":
|
|
2515
|
+
return ["tools", "vision", "streaming", "system", "json_mode"];
|
|
2516
|
+
case "google":
|
|
2517
|
+
return ["tools", "vision", "streaming", "system"];
|
|
2518
|
+
default:
|
|
2519
|
+
return ["streaming"];
|
|
2520
|
+
}
|
|
2521
|
+
}
|
|
2522
|
+
function errorStream(message) {
|
|
2523
|
+
return new ElsiumStream(async function* () {
|
|
2524
|
+
yield {
|
|
2525
|
+
type: "error",
|
|
2526
|
+
error: new ElsiumError({
|
|
2527
|
+
code: "PROVIDER_ERROR",
|
|
2528
|
+
message,
|
|
2529
|
+
retryable: false
|
|
2530
|
+
})
|
|
2531
|
+
};
|
|
2532
|
+
}());
|
|
2533
|
+
}
|
|
2534
|
+
function logStreamFailover(provider, error) {
|
|
2535
|
+
audit?.log("provider_failover", {
|
|
2536
|
+
fromProvider: provider,
|
|
2537
|
+
toProvider: "next",
|
|
2538
|
+
strategy: config.strategy,
|
|
2539
|
+
reason: error?.message
|
|
2540
|
+
});
|
|
2541
|
+
}
|
|
2542
|
+
async function tryStreamProvider(entry, request, emit) {
|
|
2543
|
+
const gw = getGateway(entry.name);
|
|
2544
|
+
const providerStream = await callWithCircuitBreaker(entry.name, async () => gw.stream({ ...request, model: request.model ?? entry.model }));
|
|
2545
|
+
let hasEmittedContent = false;
|
|
2546
|
+
for await (const event of providerStream) {
|
|
2547
|
+
if (event.type === "error") {
|
|
2548
|
+
const err2 = event.error instanceof Error ? event.error : new Error(String(event.error));
|
|
2549
|
+
if (hasEmittedContent) {
|
|
2550
|
+
emit(event);
|
|
2551
|
+
return { success: true };
|
|
2552
|
+
}
|
|
2553
|
+
return { success: false, error: err2 };
|
|
2554
|
+
}
|
|
2555
|
+
hasEmittedContent = true;
|
|
2556
|
+
emit(event);
|
|
2557
|
+
}
|
|
2558
|
+
return { success: true };
|
|
2559
|
+
}
|
|
2560
|
+
async function runStreamFallbackLoop(available, request, emit) {
|
|
2561
|
+
let lastError = null;
|
|
2562
|
+
let failedProvider = null;
|
|
2563
|
+
for (const entry of available) {
|
|
2564
|
+
try {
|
|
2565
|
+
const result = await tryStreamProvider(entry, request, emit);
|
|
2566
|
+
if (result.success) {
|
|
2567
|
+
if (failedProvider)
|
|
2568
|
+
logFailover(failedProvider, entry.name, lastError?.message);
|
|
2569
|
+
return;
|
|
2570
|
+
}
|
|
2571
|
+
lastError = result.error ?? null;
|
|
2572
|
+
failedProvider = entry.name;
|
|
2573
|
+
logStreamFailover(entry.name, result.error);
|
|
2574
|
+
} catch (err2) {
|
|
2575
|
+
failedProvider = entry.name;
|
|
2576
|
+
lastError = toError2(err2);
|
|
2577
|
+
logStreamFailover(entry.name, lastError);
|
|
2578
|
+
}
|
|
2579
|
+
}
|
|
2580
|
+
emit({
|
|
2581
|
+
type: "error",
|
|
2582
|
+
error: lastError ?? new ElsiumError({
|
|
2583
|
+
code: "PROVIDER_ERROR",
|
|
2584
|
+
message: "All providers failed during streaming",
|
|
2585
|
+
retryable: false
|
|
2586
|
+
})
|
|
2587
|
+
});
|
|
2588
|
+
}
|
|
2589
|
+
function streamWithFallback(providers, request) {
|
|
2590
|
+
const available = providers.filter((e) => isProviderAvailable(e.name));
|
|
2591
|
+
if (available.length === 0) {
|
|
2592
|
+
return errorStream("All providers unavailable");
|
|
2593
|
+
}
|
|
2594
|
+
return createStream(async (emit) => {
|
|
2595
|
+
await runStreamFallbackLoop(available, request, emit);
|
|
2596
|
+
});
|
|
2597
|
+
}
|
|
2598
|
+
function streamCostOptimized(request) {
|
|
2599
|
+
const optimizer = config.costOptimizer;
|
|
2600
|
+
if (!optimizer) {
|
|
2601
|
+
return streamWithFallback(sortedProviders, request);
|
|
2602
|
+
}
|
|
2603
|
+
const complexity = estimateComplexity(request);
|
|
2604
|
+
const threshold = optimizer.complexityThreshold ?? 0.5;
|
|
2605
|
+
const target = complexity < threshold ? optimizer.simpleModel : optimizer.complexModel;
|
|
2606
|
+
return createStream(async (emit) => {
|
|
2607
|
+
try {
|
|
2608
|
+
const gw = getGateway(target.provider);
|
|
2609
|
+
const providerStream = gw.stream({ ...request, model: target.model });
|
|
2610
|
+
for await (const event of providerStream) {
|
|
2611
|
+
emit(event);
|
|
2612
|
+
}
|
|
2613
|
+
} catch {
|
|
2614
|
+
const fallbackStream = streamWithFallback(sortedProviders, request);
|
|
2615
|
+
for await (const event of fallbackStream) {
|
|
2616
|
+
emit(event);
|
|
2617
|
+
}
|
|
2618
|
+
}
|
|
2619
|
+
});
|
|
2620
|
+
}
|
|
2621
|
+
function streamLatencyOptimized(request) {
|
|
2622
|
+
const available = sortedProviders.filter((e) => isProviderAvailable(e.name));
|
|
2623
|
+
if (available.length === 0) {
|
|
2624
|
+
return errorStream("All providers unavailable");
|
|
2625
|
+
}
|
|
2626
|
+
return createStream(async (emit) => {
|
|
2627
|
+
const controller = new AbortController;
|
|
2628
|
+
const racePromises = available.map(async (entry) => {
|
|
2629
|
+
const gw = getGateway(entry.name);
|
|
2630
|
+
return callWithCircuitBreaker(entry.name, async () => ({
|
|
2631
|
+
entry,
|
|
2632
|
+
stream: gw.stream({
|
|
2633
|
+
...request,
|
|
2634
|
+
model: request.model ?? entry.model,
|
|
2635
|
+
signal: controller.signal
|
|
2636
|
+
})
|
|
2637
|
+
}));
|
|
2638
|
+
});
|
|
2639
|
+
try {
|
|
2640
|
+
const winner = await Promise.any(racePromises);
|
|
2641
|
+
controller.abort();
|
|
2642
|
+
for await (const event of winner.stream) {
|
|
2643
|
+
emit(event);
|
|
2644
|
+
}
|
|
2645
|
+
} catch {
|
|
2646
|
+
emit({
|
|
2647
|
+
type: "error",
|
|
2648
|
+
error: new ElsiumError({
|
|
2649
|
+
code: "PROVIDER_ERROR",
|
|
2650
|
+
message: "All providers failed during streaming",
|
|
2651
|
+
retryable: false
|
|
2652
|
+
})
|
|
2653
|
+
});
|
|
2654
|
+
}
|
|
2655
|
+
});
|
|
2656
|
+
}
|
|
2657
|
+
function streamCapabilityAware(request) {
|
|
2658
|
+
const capabilities = detectRequiredCapabilities(request);
|
|
2659
|
+
const capable = filterCapableProviders(capabilities);
|
|
2660
|
+
if (capable.length === 0) {
|
|
2661
|
+
return streamWithFallback(sortedProviders, request);
|
|
2662
|
+
}
|
|
2663
|
+
return streamWithFallback(capable, request);
|
|
2664
|
+
}
|
|
2665
|
+
return {
|
|
2666
|
+
providers: sortedProviders.map((p) => p.name),
|
|
2667
|
+
strategy: config.strategy,
|
|
2668
|
+
async complete(request) {
|
|
2669
|
+
switch (config.strategy) {
|
|
2670
|
+
case "fallback":
|
|
2671
|
+
return fallbackComplete(request);
|
|
2672
|
+
case "cost-optimized":
|
|
2673
|
+
return costOptimizedComplete(request);
|
|
2674
|
+
case "latency-optimized":
|
|
2675
|
+
return latencyOptimizedComplete(request);
|
|
2676
|
+
case "capability-aware":
|
|
2677
|
+
return capabilityAwareComplete(request);
|
|
2678
|
+
default:
|
|
2679
|
+
return fallbackComplete(request);
|
|
2680
|
+
}
|
|
2681
|
+
},
|
|
2682
|
+
stream(request) {
|
|
2683
|
+
switch (config.strategy) {
|
|
2684
|
+
case "fallback":
|
|
2685
|
+
return streamWithFallback(sortedProviders, request);
|
|
2686
|
+
case "cost-optimized":
|
|
2687
|
+
return streamCostOptimized(request);
|
|
2688
|
+
case "latency-optimized":
|
|
2689
|
+
return streamLatencyOptimized(request);
|
|
2690
|
+
case "capability-aware":
|
|
2691
|
+
return streamCapabilityAware(request);
|
|
2692
|
+
default:
|
|
2693
|
+
return streamWithFallback(sortedProviders, request);
|
|
2694
|
+
}
|
|
2695
|
+
}
|
|
2696
|
+
};
|
|
2697
|
+
}
|
|
2135
2698
|
// ../observe/src/span.ts
|
|
2136
2699
|
function createSpan(name, options = {}) {
|
|
2137
2700
|
const id = generateId("spn");
|
|
@@ -4762,12 +5325,13 @@ function createRoutes(deps) {
|
|
|
4762
5325
|
return c.json({ error: resolved.error }, 404);
|
|
4763
5326
|
}
|
|
4764
5327
|
if (body.stream) {
|
|
4765
|
-
const
|
|
5328
|
+
const streamSource = deps.mesh ?? deps.gateway;
|
|
5329
|
+
const agentStream = streamSource.stream({
|
|
4766
5330
|
messages: [{ role: "user", content: body.message }],
|
|
4767
5331
|
system: resolved.agent.config.system,
|
|
4768
5332
|
model: resolved.agent.config.model
|
|
4769
5333
|
});
|
|
4770
|
-
return streamResponse(c,
|
|
5334
|
+
return streamResponse(c, agentStream);
|
|
4771
5335
|
}
|
|
4772
5336
|
let result;
|
|
4773
5337
|
try {
|
|
@@ -4798,8 +5362,9 @@ function createRoutes(deps) {
|
|
|
4798
5362
|
role: m.role,
|
|
4799
5363
|
content: m.content
|
|
4800
5364
|
}));
|
|
5365
|
+
const completeSource = deps.mesh ?? deps.gateway;
|
|
4801
5366
|
if (body.stream) {
|
|
4802
|
-
const stream2 =
|
|
5367
|
+
const stream2 = completeSource.stream({
|
|
4803
5368
|
messages,
|
|
4804
5369
|
model: body.model,
|
|
4805
5370
|
system: body.system,
|
|
@@ -4810,7 +5375,7 @@ function createRoutes(deps) {
|
|
|
4810
5375
|
}
|
|
4811
5376
|
let response;
|
|
4812
5377
|
try {
|
|
4813
|
-
response = await
|
|
5378
|
+
response = await completeSource.complete({
|
|
4814
5379
|
messages,
|
|
4815
5380
|
model: body.model,
|
|
4816
5381
|
system: body.system,
|
|
@@ -4861,14 +5426,39 @@ function createApp(config) {
|
|
|
4861
5426
|
return c.json({ error: "Not found" }, 404);
|
|
4862
5427
|
});
|
|
4863
5428
|
const providerNames = Object.keys(config.gateway.providers);
|
|
4864
|
-
|
|
4865
|
-
|
|
4866
|
-
|
|
4867
|
-
|
|
4868
|
-
|
|
4869
|
-
|
|
4870
|
-
|
|
4871
|
-
|
|
5429
|
+
let gw;
|
|
5430
|
+
let mesh;
|
|
5431
|
+
if (providerNames.length > 1) {
|
|
5432
|
+
const entries = providerNames.map((name) => ({
|
|
5433
|
+
name,
|
|
5434
|
+
config: {
|
|
5435
|
+
apiKey: config.gateway.providers[name].apiKey,
|
|
5436
|
+
baseUrl: config.gateway.providers[name].baseUrl
|
|
5437
|
+
},
|
|
5438
|
+
model: config.gateway.providers[name].model
|
|
5439
|
+
}));
|
|
5440
|
+
mesh = createProviderMesh({
|
|
5441
|
+
providers: entries,
|
|
5442
|
+
strategy: config.gateway.strategy ?? "fallback"
|
|
5443
|
+
});
|
|
5444
|
+
const primaryProvider = providerNames[0];
|
|
5445
|
+
const primaryConfig = config.gateway.providers[primaryProvider];
|
|
5446
|
+
gw = gateway({
|
|
5447
|
+
provider: primaryProvider,
|
|
5448
|
+
model: config.gateway.defaultModel,
|
|
5449
|
+
apiKey: primaryConfig.apiKey,
|
|
5450
|
+
baseUrl: primaryConfig.baseUrl
|
|
5451
|
+
});
|
|
5452
|
+
} else {
|
|
5453
|
+
const primaryProvider = providerNames[0];
|
|
5454
|
+
const primaryConfig = config.gateway.providers[primaryProvider];
|
|
5455
|
+
gw = gateway({
|
|
5456
|
+
provider: primaryProvider,
|
|
5457
|
+
model: config.gateway.defaultModel,
|
|
5458
|
+
apiKey: primaryConfig.apiKey,
|
|
5459
|
+
baseUrl: primaryConfig.baseUrl
|
|
5460
|
+
});
|
|
5461
|
+
}
|
|
4872
5462
|
const tracer = observe({
|
|
4873
5463
|
output: config.observe?.tracing ? ["console"] : [],
|
|
4874
5464
|
costTracking: config.observe?.costTracking ?? true
|
|
@@ -4894,6 +5484,7 @@ function createApp(config) {
|
|
|
4894
5484
|
const defaultAgent = config.agents?.[0];
|
|
4895
5485
|
const routes = createRoutes({
|
|
4896
5486
|
gateway: gw,
|
|
5487
|
+
mesh,
|
|
4897
5488
|
agents: agentMap,
|
|
4898
5489
|
defaultAgent,
|
|
4899
5490
|
tracer,
|
|
@@ -4905,6 +5496,7 @@ function createApp(config) {
|
|
|
4905
5496
|
return {
|
|
4906
5497
|
hono: app,
|
|
4907
5498
|
gateway: gw,
|
|
5499
|
+
mesh,
|
|
4908
5500
|
tracer,
|
|
4909
5501
|
listen(port) {
|
|
4910
5502
|
const listenPort = port ?? serverConfig.port ?? 3000;
|
package/dist/routes.d.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import type { Agent } from '@elsium-ai/agents';
|
|
2
|
-
import type { Gateway } from '@elsium-ai/gateway';
|
|
2
|
+
import type { Gateway, ProviderMesh } from '@elsium-ai/gateway';
|
|
3
3
|
import type { Tracer } from '@elsium-ai/observe';
|
|
4
4
|
import { Hono } from 'hono';
|
|
5
5
|
export interface RoutesDeps {
|
|
6
6
|
gateway: Gateway;
|
|
7
|
+
mesh?: ProviderMesh;
|
|
7
8
|
agents: Map<string, Agent>;
|
|
8
9
|
defaultAgent?: Agent;
|
|
9
10
|
tracer?: Tracer;
|
package/dist/routes.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../src/routes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAA;AAE9C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAA;
|
|
1
|
+
{"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../src/routes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAA;AAE9C,OAAO,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAC/D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAA;AAEhD,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAqE3B,MAAM,WAAW,UAAU;IAC1B,OAAO,EAAE,OAAO,CAAA;IAChB,IAAI,CAAC,EAAE,YAAY,CAAA;IACnB,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,CAAA;IAC1B,YAAY,CAAC,EAAE,KAAK,CAAA;IACpB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,SAAS,EAAE,MAAM,CAAA;IACjB,OAAO,EAAE,MAAM,CAAA;IACf,SAAS,EAAE,MAAM,EAAE,CAAA;CACnB;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,UAAU,GAAG,IAAI,CAqKnD"}
|
package/dist/sse.d.ts
CHANGED
|
@@ -2,5 +2,5 @@ import type { ElsiumStream } from '@elsium-ai/core';
|
|
|
2
2
|
import type { Context } from 'hono';
|
|
3
3
|
export declare function sseHeaders(): Record<string, string>;
|
|
4
4
|
export declare function formatSSE(event: string, data: unknown): string;
|
|
5
|
-
export declare function streamResponse(c: Context, source: ElsiumStream): Response;
|
|
5
|
+
export declare function streamResponse(c: Context, source: ElsiumStream | AsyncIterable<unknown>): Response;
|
|
6
6
|
//# sourceMappingURL=sse.d.ts.map
|
package/dist/sse.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sse.d.ts","sourceRoot":"","sources":["../src/sse.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAe,MAAM,iBAAiB,CAAA;AAChE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAA;AAGnC,wBAAgB,UAAU,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAOnD;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,MAAM,CAM9D;AAED,wBAAgB,cAAc,
|
|
1
|
+
{"version":3,"file":"sse.d.ts","sourceRoot":"","sources":["../src/sse.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAe,MAAM,iBAAiB,CAAA;AAChE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAA;AAGnC,wBAAgB,UAAU,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAOnD;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,MAAM,CAM9D;AAED,wBAAgB,cAAc,CAC7B,CAAC,EAAE,OAAO,EACV,MAAM,EAAE,YAAY,GAAG,aAAa,CAAC,OAAO,CAAC,GAC3C,QAAQ,CAwBV"}
|
package/dist/types.d.ts
CHANGED
|
@@ -5,8 +5,10 @@ export interface AppConfig {
|
|
|
5
5
|
providers: Record<string, {
|
|
6
6
|
apiKey: string;
|
|
7
7
|
baseUrl?: string;
|
|
8
|
+
model?: string;
|
|
8
9
|
}>;
|
|
9
10
|
defaultModel?: string;
|
|
11
|
+
strategy?: 'fallback' | 'cost-optimized' | 'latency-optimized' | 'capability-aware';
|
|
10
12
|
};
|
|
11
13
|
agents?: Agent[];
|
|
12
14
|
rag?: RAGPipeline;
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAA;AAC9C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AAEjD,MAAM,WAAW,SAAS;IACzB,OAAO,EAAE;QACR,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE;YAAE,MAAM,EAAE,MAAM,CAAC;YAAC,OAAO,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC,CAAA;QAC/
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@elsium-ai/app",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0",
|
|
4
4
|
"description": "App bootstrap, HTTP server, and API routes for ElsiumAI",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Eric Utrera <ebutrera9103@gmail.com>",
|
|
@@ -26,13 +26,13 @@
|
|
|
26
26
|
"dev": "bun --watch src/index.ts"
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@elsium-ai/core": "^0.
|
|
30
|
-
"@elsium-ai/gateway": "^0.
|
|
31
|
-
"@elsium-ai/agents": "^0.
|
|
32
|
-
"@elsium-ai/tools": "^0.
|
|
33
|
-
"@elsium-ai/observe": "^0.
|
|
34
|
-
"@elsium-ai/rag": "^0.
|
|
35
|
-
"@elsium-ai/workflows": "^0.
|
|
29
|
+
"@elsium-ai/core": "^0.8.0",
|
|
30
|
+
"@elsium-ai/gateway": "^0.8.0",
|
|
31
|
+
"@elsium-ai/agents": "^0.8.0",
|
|
32
|
+
"@elsium-ai/tools": "^0.8.0",
|
|
33
|
+
"@elsium-ai/observe": "^0.8.0",
|
|
34
|
+
"@elsium-ai/rag": "^0.8.0",
|
|
35
|
+
"@elsium-ai/workflows": "^0.8.0",
|
|
36
36
|
"@hono/node-server": "^1.19.10",
|
|
37
37
|
"hono": "^4.12.4",
|
|
38
38
|
"zod": "^3.24.0"
|