@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 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,EAAW,MAAM,oBAAoB,CAAA;AAC1D,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,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,CAgItD"}
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 stream2 = deps.gateway.stream({
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, stream2);
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 = deps.gateway.stream({
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 deps.gateway.complete({
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
- const primaryProvider = providerNames[0];
4865
- const primaryConfig = config.gateway.providers[primaryProvider];
4866
- const gw = gateway({
4867
- provider: primaryProvider,
4868
- model: config.gateway.defaultModel,
4869
- apiKey: primaryConfig.apiKey,
4870
- baseUrl: primaryConfig.baseUrl
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;
@@ -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;AACjD,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,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,CAkKnD"}
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,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,YAAY,GAAG,QAAQ,CAwBzE"}
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;
@@ -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/D,YAAY,CAAC,EAAE,MAAM,CAAA;KACrB,CAAA;IACD,MAAM,CAAC,EAAE,KAAK,EAAE,CAAA;IAChB,GAAG,CAAC,EAAE,WAAW,CAAA;IACjB,OAAO,CAAC,EAAE;QACT,OAAO,CAAC,EAAE,OAAO,CAAA;QACjB,YAAY,CAAC,EAAE,OAAO,CAAA;QACtB,MAAM,CAAC,EAAE,MAAM,CAAA;KACf,CAAA;IACD,MAAM,CAAC,EAAE,YAAY,CAAA;IACrB,OAAO,CAAC,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,WAAW,YAAY;IAC5B,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,IAAI,CAAC,EAAE,OAAO,GAAG,UAAU,CAAA;IAC3B,IAAI,CAAC,EAAE,UAAU,CAAA;IACjB,SAAS,CAAC,EAAE,eAAe,CAAA;IAC3B,gBAAgB,CAAC,EAAE,OAAO,GAAG;QAAE,cAAc,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;CACxD;AAED,MAAM,WAAW,UAAU;IAC1B,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;IAC1B,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;IAClB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;IAClB,WAAW,CAAC,EAAE,OAAO,CAAA;CACrB;AAED,MAAM,WAAW,UAAU;IAC1B,IAAI,EAAE,QAAQ,CAAA;IACd,KAAK,EAAE,MAAM,CAAA;CACb;AAED,MAAM,WAAW,eAAe;IAC/B,QAAQ,EAAE,MAAM,CAAA;IAChB,WAAW,EAAE,MAAM,CAAA;CACnB;AAID,MAAM,WAAW,WAAW;IAC3B,OAAO,EAAE,MAAM,CAAA;IACf,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,OAAO,CAAA;CAChB;AAED,MAAM,WAAW,YAAY;IAC5B,OAAO,EAAE,MAAM,CAAA;IACf,KAAK,EAAE;QACN,WAAW,EAAE,MAAM,CAAA;QACnB,YAAY,EAAE,MAAM,CAAA;QACpB,WAAW,EAAE,MAAM,CAAA;QACnB,IAAI,EAAE,MAAM,CAAA;KACZ,CAAA;IACD,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,MAAM,CAAA;CACf;AAED,MAAM,WAAW,eAAe;IAC/B,QAAQ,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IAClD,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,MAAM,CAAC,EAAE,OAAO,CAAA;CAChB;AAED,MAAM,WAAW,cAAc;IAC9B,MAAM,EAAE,IAAI,GAAG,UAAU,CAAA;IACzB,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,MAAM,EAAE,CAAA;CACnB;AAED,MAAM,WAAW,eAAe;IAC/B,MAAM,EAAE,MAAM,CAAA;IACd,aAAa,EAAE,MAAM,CAAA;IACrB,WAAW,EAAE,MAAM,CAAA;IACnB,SAAS,EAAE,MAAM,CAAA;IACjB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAC3E;AAID,MAAM,WAAW,eAAe;IAC/B,IAAI,EAAE,YAAY,GAAG,aAAa,GAAG,OAAO,CAAA;IAC5C,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,CAAA;IAC1E,KAAK,CAAC,EAAE,MAAM,CAAA;CACd;AAED,MAAM,WAAW,mBAAmB;IACnC,IAAI,EAAE,YAAY,GAAG,iBAAiB,GAAG,iBAAiB,GAAG,aAAa,GAAG,OAAO,CAAA;IACpF,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,QAAQ,CAAC,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAA;IACvC,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,KAAK,CAAC,EAAE;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,CAAA;IAC1E,KAAK,CAAC,EAAE,MAAM,CAAA;CACd"}
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,CAAC;YAAC,KAAK,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC,CAAA;QAC/E,YAAY,CAAC,EAAE,MAAM,CAAA;QACrB,QAAQ,CAAC,EAAE,UAAU,GAAG,gBAAgB,GAAG,mBAAmB,GAAG,kBAAkB,CAAA;KACnF,CAAA;IACD,MAAM,CAAC,EAAE,KAAK,EAAE,CAAA;IAChB,GAAG,CAAC,EAAE,WAAW,CAAA;IACjB,OAAO,CAAC,EAAE;QACT,OAAO,CAAC,EAAE,OAAO,CAAA;QACjB,YAAY,CAAC,EAAE,OAAO,CAAA;QACtB,MAAM,CAAC,EAAE,MAAM,CAAA;KACf,CAAA;IACD,MAAM,CAAC,EAAE,YAAY,CAAA;IACrB,OAAO,CAAC,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,WAAW,YAAY;IAC5B,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,IAAI,CAAC,EAAE,OAAO,GAAG,UAAU,CAAA;IAC3B,IAAI,CAAC,EAAE,UAAU,CAAA;IACjB,SAAS,CAAC,EAAE,eAAe,CAAA;IAC3B,gBAAgB,CAAC,EAAE,OAAO,GAAG;QAAE,cAAc,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;CACxD;AAED,MAAM,WAAW,UAAU;IAC1B,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;IAC1B,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;IAClB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;IAClB,WAAW,CAAC,EAAE,OAAO,CAAA;CACrB;AAED,MAAM,WAAW,UAAU;IAC1B,IAAI,EAAE,QAAQ,CAAA;IACd,KAAK,EAAE,MAAM,CAAA;CACb;AAED,MAAM,WAAW,eAAe;IAC/B,QAAQ,EAAE,MAAM,CAAA;IAChB,WAAW,EAAE,MAAM,CAAA;CACnB;AAID,MAAM,WAAW,WAAW;IAC3B,OAAO,EAAE,MAAM,CAAA;IACf,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,OAAO,CAAA;CAChB;AAED,MAAM,WAAW,YAAY;IAC5B,OAAO,EAAE,MAAM,CAAA;IACf,KAAK,EAAE;QACN,WAAW,EAAE,MAAM,CAAA;QACnB,YAAY,EAAE,MAAM,CAAA;QACpB,WAAW,EAAE,MAAM,CAAA;QACnB,IAAI,EAAE,MAAM,CAAA;KACZ,CAAA;IACD,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,MAAM,CAAA;CACf;AAED,MAAM,WAAW,eAAe;IAC/B,QAAQ,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IAClD,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,MAAM,CAAC,EAAE,OAAO,CAAA;CAChB;AAED,MAAM,WAAW,cAAc;IAC9B,MAAM,EAAE,IAAI,GAAG,UAAU,CAAA;IACzB,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,MAAM,EAAE,CAAA;CACnB;AAED,MAAM,WAAW,eAAe;IAC/B,MAAM,EAAE,MAAM,CAAA;IACd,aAAa,EAAE,MAAM,CAAA;IACrB,WAAW,EAAE,MAAM,CAAA;IACnB,SAAS,EAAE,MAAM,CAAA;IACjB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAC3E;AAID,MAAM,WAAW,eAAe;IAC/B,IAAI,EAAE,YAAY,GAAG,aAAa,GAAG,OAAO,CAAA;IAC5C,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,CAAA;IAC1E,KAAK,CAAC,EAAE,MAAM,CAAA;CACd;AAED,MAAM,WAAW,mBAAmB;IACnC,IAAI,EAAE,YAAY,GAAG,iBAAiB,GAAG,iBAAiB,GAAG,aAAa,GAAG,OAAO,CAAA;IACpF,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,QAAQ,CAAC,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAA;IACvC,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,KAAK,CAAC,EAAE;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,CAAA;IAC1E,KAAK,CAAC,EAAE,MAAM,CAAA;CACd"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@elsium-ai/app",
3
- "version": "0.7.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.7.0",
30
- "@elsium-ai/gateway": "^0.7.0",
31
- "@elsium-ai/agents": "^0.7.0",
32
- "@elsium-ai/tools": "^0.7.0",
33
- "@elsium-ai/observe": "^0.7.0",
34
- "@elsium-ai/rag": "^0.7.0",
35
- "@elsium-ai/workflows": "^0.7.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"