@ai-orchestration/core 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/.eslintrc.json +27 -0
- package/README.md +516 -0
- package/dist/core/errors.d.ts +21 -0
- package/dist/core/errors.d.ts.map +1 -0
- package/dist/core/errors.js +38 -0
- package/dist/core/errors.js.map +1 -0
- package/dist/core/interfaces.d.ts +87 -0
- package/dist/core/interfaces.d.ts.map +1 -0
- package/dist/core/interfaces.js +5 -0
- package/dist/core/interfaces.js.map +1 -0
- package/dist/core/orchestrator.d.ts +55 -0
- package/dist/core/orchestrator.d.ts.map +1 -0
- package/dist/core/orchestrator.js +147 -0
- package/dist/core/orchestrator.js.map +1 -0
- package/dist/core/types.d.ts +72 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +5 -0
- package/dist/core/types.js.map +1 -0
- package/dist/factory/index.d.ts +14 -0
- package/dist/factory/index.d.ts.map +1 -0
- package/dist/factory/index.js +184 -0
- package/dist/factory/index.js.map +1 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +15 -0
- package/dist/index.js.map +1 -0
- package/dist/providers/base.d.ts +30 -0
- package/dist/providers/base.d.ts.map +1 -0
- package/dist/providers/base.js +31 -0
- package/dist/providers/base.js.map +1 -0
- package/dist/providers/cerebras.d.ts +26 -0
- package/dist/providers/cerebras.d.ts.map +1 -0
- package/dist/providers/cerebras.js +190 -0
- package/dist/providers/cerebras.js.map +1 -0
- package/dist/providers/gemini.d.ts +26 -0
- package/dist/providers/gemini.d.ts.map +1 -0
- package/dist/providers/gemini.js +181 -0
- package/dist/providers/gemini.js.map +1 -0
- package/dist/providers/groq.d.ts +26 -0
- package/dist/providers/groq.d.ts.map +1 -0
- package/dist/providers/groq.js +225 -0
- package/dist/providers/groq.js.map +1 -0
- package/dist/providers/index.d.ts +15 -0
- package/dist/providers/index.d.ts.map +1 -0
- package/dist/providers/index.js +10 -0
- package/dist/providers/index.js.map +1 -0
- package/dist/providers/local.d.ts +27 -0
- package/dist/providers/local.d.ts.map +1 -0
- package/dist/providers/local.js +198 -0
- package/dist/providers/local.js.map +1 -0
- package/dist/providers/openrouter.d.ts +26 -0
- package/dist/providers/openrouter.d.ts.map +1 -0
- package/dist/providers/openrouter.js +172 -0
- package/dist/providers/openrouter.js.map +1 -0
- package/dist/strategies/base.d.ts +16 -0
- package/dist/strategies/base.d.ts.map +1 -0
- package/dist/strategies/base.js +21 -0
- package/dist/strategies/base.js.map +1 -0
- package/dist/strategies/fallback.d.ts +14 -0
- package/dist/strategies/fallback.d.ts.map +1 -0
- package/dist/strategies/fallback.js +29 -0
- package/dist/strategies/fallback.js.map +1 -0
- package/dist/strategies/health-aware.d.ts +20 -0
- package/dist/strategies/health-aware.d.ts.map +1 -0
- package/dist/strategies/health-aware.js +106 -0
- package/dist/strategies/health-aware.js.map +1 -0
- package/dist/strategies/index.d.ts +14 -0
- package/dist/strategies/index.d.ts.map +1 -0
- package/dist/strategies/index.js +10 -0
- package/dist/strategies/index.js.map +1 -0
- package/dist/strategies/priority.d.ts +18 -0
- package/dist/strategies/priority.d.ts.map +1 -0
- package/dist/strategies/priority.js +35 -0
- package/dist/strategies/priority.js.map +1 -0
- package/dist/strategies/round-robin.d.ts +10 -0
- package/dist/strategies/round-robin.d.ts.map +1 -0
- package/dist/strategies/round-robin.js +21 -0
- package/dist/strategies/round-robin.js.map +1 -0
- package/dist/strategies/weighted.d.ts +20 -0
- package/dist/strategies/weighted.d.ts.map +1 -0
- package/dist/strategies/weighted.js +58 -0
- package/dist/strategies/weighted.js.map +1 -0
- package/docs/ARCHITECTURE.md +126 -0
- package/docs/CHANGELOG.md +30 -0
- package/docs/CONTRIBUTING.md +198 -0
- package/examples/basic.ts +58 -0
- package/examples/chat-app/README.md +146 -0
- package/examples/chat-app/config.json +34 -0
- package/examples/chat-app/index.ts +330 -0
- package/examples/chat-app/package-lock.json +570 -0
- package/examples/chat-app/package.json +20 -0
- package/examples/config.example.json +42 -0
- package/examples/strategies.ts +112 -0
- package/examples/test-local.ts +150 -0
- package/examples/test-mock.ts +172 -0
- package/package/.eslintrc.json +27 -0
- package/package/CHANGELOG.md +31 -0
- package/package/CONTRIBUTING.md +156 -0
- package/package/PUBLISHING.md +213 -0
- package/package/README.md +515 -0
- package/package/dist/core/errors.d.ts +21 -0
- package/package/dist/core/errors.d.ts.map +1 -0
- package/package/dist/core/errors.js +38 -0
- package/package/dist/core/errors.js.map +1 -0
- package/package/dist/core/interfaces.d.ts +87 -0
- package/package/dist/core/interfaces.d.ts.map +1 -0
- package/package/dist/core/interfaces.js +5 -0
- package/package/dist/core/interfaces.js.map +1 -0
- package/package/dist/core/orchestrator.d.ts +55 -0
- package/package/dist/core/orchestrator.d.ts.map +1 -0
- package/package/dist/core/orchestrator.js +147 -0
- package/package/dist/core/orchestrator.js.map +1 -0
- package/package/dist/core/types.d.ts +72 -0
- package/package/dist/core/types.d.ts.map +1 -0
- package/package/dist/core/types.js +5 -0
- package/package/dist/core/types.js.map +1 -0
- package/package/dist/factory/index.d.ts +14 -0
- package/package/dist/factory/index.d.ts.map +1 -0
- package/package/dist/factory/index.js +184 -0
- package/package/dist/factory/index.js.map +1 -0
- package/package/dist/index.d.ts +14 -0
- package/package/dist/index.d.ts.map +1 -0
- package/package/dist/index.js +15 -0
- package/package/dist/index.js.map +1 -0
- package/package/dist/providers/base.d.ts +30 -0
- package/package/dist/providers/base.d.ts.map +1 -0
- package/package/dist/providers/base.js +31 -0
- package/package/dist/providers/base.js.map +1 -0
- package/package/dist/providers/cerebras.d.ts +26 -0
- package/package/dist/providers/cerebras.d.ts.map +1 -0
- package/package/dist/providers/cerebras.js +190 -0
- package/package/dist/providers/cerebras.js.map +1 -0
- package/package/dist/providers/gemini.d.ts +26 -0
- package/package/dist/providers/gemini.d.ts.map +1 -0
- package/package/dist/providers/gemini.js +181 -0
- package/package/dist/providers/gemini.js.map +1 -0
- package/package/dist/providers/groq.d.ts +26 -0
- package/package/dist/providers/groq.d.ts.map +1 -0
- package/package/dist/providers/groq.js +225 -0
- package/package/dist/providers/groq.js.map +1 -0
- package/package/dist/providers/index.d.ts +15 -0
- package/package/dist/providers/index.d.ts.map +1 -0
- package/package/dist/providers/index.js +10 -0
- package/package/dist/providers/index.js.map +1 -0
- package/package/dist/providers/local.d.ts +27 -0
- package/package/dist/providers/local.d.ts.map +1 -0
- package/package/dist/providers/local.js +198 -0
- package/package/dist/providers/local.js.map +1 -0
- package/package/dist/providers/openrouter.d.ts +26 -0
- package/package/dist/providers/openrouter.d.ts.map +1 -0
- package/package/dist/providers/openrouter.js +172 -0
- package/package/dist/providers/openrouter.js.map +1 -0
- package/package/dist/strategies/base.d.ts +16 -0
- package/package/dist/strategies/base.d.ts.map +1 -0
- package/package/dist/strategies/base.js +21 -0
- package/package/dist/strategies/base.js.map +1 -0
- package/package/dist/strategies/fallback.d.ts +14 -0
- package/package/dist/strategies/fallback.d.ts.map +1 -0
- package/package/dist/strategies/fallback.js +29 -0
- package/package/dist/strategies/fallback.js.map +1 -0
- package/package/dist/strategies/health-aware.d.ts +20 -0
- package/package/dist/strategies/health-aware.d.ts.map +1 -0
- package/package/dist/strategies/health-aware.js +106 -0
- package/package/dist/strategies/health-aware.js.map +1 -0
- package/package/dist/strategies/index.d.ts +14 -0
- package/package/dist/strategies/index.d.ts.map +1 -0
- package/package/dist/strategies/index.js +10 -0
- package/package/dist/strategies/index.js.map +1 -0
- package/package/dist/strategies/priority.d.ts +18 -0
- package/package/dist/strategies/priority.d.ts.map +1 -0
- package/package/dist/strategies/priority.js +35 -0
- package/package/dist/strategies/priority.js.map +1 -0
- package/package/dist/strategies/round-robin.d.ts +10 -0
- package/package/dist/strategies/round-robin.d.ts.map +1 -0
- package/package/dist/strategies/round-robin.js +21 -0
- package/package/dist/strategies/round-robin.js.map +1 -0
- package/package/dist/strategies/weighted.d.ts +20 -0
- package/package/dist/strategies/weighted.d.ts.map +1 -0
- package/package/dist/strategies/weighted.js +58 -0
- package/package/dist/strategies/weighted.js.map +1 -0
- package/package/docs/ARCHITECTURE.md +127 -0
- package/package/examples/basic.ts +58 -0
- package/package/examples/chat-app/README.md +146 -0
- package/package/examples/chat-app/config.json +34 -0
- package/package/examples/chat-app/index.ts +330 -0
- package/package/examples/chat-app/package-lock.json +570 -0
- package/package/examples/chat-app/package.json +20 -0
- package/package/examples/config.example.json +42 -0
- package/package/examples/strategies.ts +112 -0
- package/package/examples/test-local.ts +150 -0
- package/package/examples/test-mock.ts +172 -0
- package/package/package.json +62 -0
- package/package/scripts/check-types.ts +15 -0
- package/package/scripts/link.sh +30 -0
- package/package/scripts/pack.sh +36 -0
- package/package.json +62 -0
- package/scripts/check-types.ts +15 -0
- package/scripts/link.sh +30 -0
- package/scripts/pack.sh +36 -0
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Weighted strategy: selects providers based on weights (for load balancing or cost-aware selection)
|
|
3
|
+
*/
|
|
4
|
+
import { BaseStrategy } from './base.js';
|
|
5
|
+
export class WeightedStrategy extends BaseStrategy {
|
|
6
|
+
weights = new Map();
|
|
7
|
+
costAware;
|
|
8
|
+
constructor(config) {
|
|
9
|
+
super();
|
|
10
|
+
this.costAware = config?.costAware ?? false;
|
|
11
|
+
if (config?.weights) {
|
|
12
|
+
Object.entries(config.weights).forEach(([id, weight]) => {
|
|
13
|
+
this.weights.set(id, weight);
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
async select(providers, context) {
|
|
18
|
+
const available = this.filterAttempted(providers, context);
|
|
19
|
+
if (available.length === 0) {
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
// Calculate effective weights
|
|
23
|
+
const weightedProviders = available.map((provider) => {
|
|
24
|
+
let weight = this.weights.get(provider.id) ?? 1.0;
|
|
25
|
+
// Adjust weight based on cost if cost-aware
|
|
26
|
+
if (this.costAware && provider.metadata.costPerToken) {
|
|
27
|
+
const avgCost = (provider.metadata.costPerToken.prompt +
|
|
28
|
+
provider.metadata.costPerToken.completion) /
|
|
29
|
+
2;
|
|
30
|
+
// Lower cost = higher weight (inverse relationship)
|
|
31
|
+
weight = weight / (avgCost + 0.0001); // Add small epsilon to avoid division by zero
|
|
32
|
+
}
|
|
33
|
+
return { provider, weight };
|
|
34
|
+
});
|
|
35
|
+
// Calculate total weight
|
|
36
|
+
const totalWeight = weightedProviders.reduce((sum, wp) => sum + wp.weight, 0);
|
|
37
|
+
if (totalWeight === 0) {
|
|
38
|
+
return available[0]; // Fallback to first available
|
|
39
|
+
}
|
|
40
|
+
// Select using weighted random
|
|
41
|
+
let random = Math.random() * totalWeight;
|
|
42
|
+
for (const { provider, weight } of weightedProviders) {
|
|
43
|
+
random -= weight;
|
|
44
|
+
if (random <= 0) {
|
|
45
|
+
return provider;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
// Fallback (shouldn't reach here)
|
|
49
|
+
return available[0];
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Set weight for a provider
|
|
53
|
+
*/
|
|
54
|
+
setWeight(providerId, weight) {
|
|
55
|
+
this.weights.set(providerId, weight);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=weighted.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"weighted.js","sourceRoot":"","sources":["../../src/strategies/weighted.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAQzC,MAAM,OAAO,gBAAiB,SAAQ,YAAY;IACxC,OAAO,GAAwB,IAAI,GAAG,EAAE,CAAC;IACzC,SAAS,CAAU;IAE3B,YAAY,MAA+B;QACzC,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,SAAS,GAAG,MAAM,EAAE,SAAS,IAAI,KAAK,CAAC;QAE5C,IAAI,MAAM,EAAE,OAAO,EAAE,CAAC;YACpB,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE;gBACtD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;YAC/B,CAAC,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,KAAK,CAAC,MAAM,CACV,SAAsB,EACtB,OAA0B;QAE1B,MAAM,SAAS,GAAG,IAAI,CAAC,eAAe,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QAC3D,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC3B,OAAO,IAAI,CAAC;QACd,CAAC;QAED,8BAA8B;QAC9B,MAAM,iBAAiB,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE;YACnD,IAAI,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,GAAG,CAAC;YAElD,4CAA4C;YAC5C,IAAI,IAAI,CAAC,SAAS,IAAI,QAAQ,CAAC,QAAQ,CAAC,YAAY,EAAE,CAAC;gBACrD,MAAM,OAAO,GACX,CAAC,QAAQ,CAAC,QAAQ,CAAC,YAAY,CAAC,MAAM;oBACpC,QAAQ,CAAC,QAAQ,CAAC,YAAY,CAAC,UAAU,CAAC;oBAC5C,CAAC,CAAC;gBACJ,oDAAoD;gBACpD,MAAM,GAAG,MAAM,GAAG,CAAC,OAAO,GAAG,MAAM,CAAC,CAAC,CAAC,8CAA8C;YACtF,CAAC;YAED,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;QAC9B,CAAC,CAAC,CAAC;QAEH,yBAAyB;QACzB,MAAM,WAAW,GAAG,iBAAiB,CAAC,MAAM,CAC1C,CAAC,GAAG,EAAE,EAAE,EAAE,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,MAAM,EAC5B,CAAC,CACF,CAAC;QAEF,IAAI,WAAW,KAAK,CAAC,EAAE,CAAC;YACtB,OAAO,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,8BAA8B;QACrD,CAAC;QAED,+BAA+B;QAC/B,IAAI,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE,GAAG,WAAW,CAAC;QACzC,KAAK,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,iBAAiB,EAAE,CAAC;YACrD,MAAM,IAAI,MAAM,CAAC;YACjB,IAAI,MAAM,IAAI,CAAC,EAAE,CAAC;gBAChB,OAAO,QAAQ,CAAC;YAClB,CAAC;QACH,CAAC;QAED,kCAAkC;QAClC,OAAO,SAAS,CAAC,CAAC,CAAC,CAAC;IACtB,CAAC;IAED;;OAEG;IACH,SAAS,CAAC,UAAkB,EAAE,MAAc;QAC1C,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;IACvC,CAAC;CACF"}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
# Arquitectura del Framework
|
|
2
|
+
|
|
3
|
+
## Visión General
|
|
4
|
+
|
|
5
|
+
El framework está diseñado siguiendo principios SOLID y arquitectura basada en plugins, permitiendo extensibilidad sin modificar el código core.
|
|
6
|
+
|
|
7
|
+
## Componentes Principales
|
|
8
|
+
|
|
9
|
+
### Core (`src/core/`)
|
|
10
|
+
|
|
11
|
+
#### `interfaces.ts`
|
|
12
|
+
Define las interfaces fundamentales:
|
|
13
|
+
- `AIService`: Contrato que todos los proveedores deben implementar
|
|
14
|
+
- `SelectionStrategy`: Contrato para estrategias de selección
|
|
15
|
+
- `OrchestratorConfig`: Configuración del orchestrator
|
|
16
|
+
- Tipos de configuración para proveedores y estrategias
|
|
17
|
+
|
|
18
|
+
#### `types.ts`
|
|
19
|
+
Tipos compartidos:
|
|
20
|
+
- `ChatMessage`: Mensaje en una conversación
|
|
21
|
+
- `ChatOptions`: Opciones para completado de chat
|
|
22
|
+
- `ChatResponse`: Respuesta no-streaming
|
|
23
|
+
- `ChatChunk`: Chunk de streaming
|
|
24
|
+
- `ProviderHealth`: Estado de salud de un proveedor
|
|
25
|
+
- `ProviderMetadata`: Metadatos del proveedor
|
|
26
|
+
|
|
27
|
+
#### `orchestrator.ts`
|
|
28
|
+
Núcleo del framework:
|
|
29
|
+
- `Orchestrator`: Clase principal que gestiona proveedores y estrategias
|
|
30
|
+
- Registro y gestión de proveedores
|
|
31
|
+
- Selección automática de proveedores
|
|
32
|
+
- Fallback automático en caso de error
|
|
33
|
+
- Health checks periódicos
|
|
34
|
+
|
|
35
|
+
### Providers (`src/providers/`)
|
|
36
|
+
|
|
37
|
+
Cada proveedor extiende `BaseProvider` e implementa:
|
|
38
|
+
- `checkHealth()`: Verificación de salud
|
|
39
|
+
- `chat()`: Completado de chat (no-streaming)
|
|
40
|
+
- `chatStream()`: Completado de chat (streaming)
|
|
41
|
+
- `formatMessages()`: Conversión de formato estándar a formato del proveedor
|
|
42
|
+
- `parseResponse()`: Conversión de respuesta del proveedor a formato estándar
|
|
43
|
+
- `parseStream()`: Conversión de stream del proveedor a formato estándar
|
|
44
|
+
|
|
45
|
+
**Proveedores implementados:**
|
|
46
|
+
- `GroqProvider`: Integración con Groq API
|
|
47
|
+
- `OpenRouterProvider`: Integración con OpenRouter
|
|
48
|
+
- `GeminiProvider`: Integración con Google Gemini
|
|
49
|
+
- `LocalProvider`: Para modelos locales (API compatible con OpenAI)
|
|
50
|
+
|
|
51
|
+
### Strategies (`src/strategies/`)
|
|
52
|
+
|
|
53
|
+
Cada estrategia extiende `BaseStrategy` e implementa:
|
|
54
|
+
- `select()`: Lógica de selección de proveedor
|
|
55
|
+
- `update()` (opcional): Actualización de estado interno
|
|
56
|
+
|
|
57
|
+
**Estrategias implementadas:**
|
|
58
|
+
- `RoundRobinStrategy`: Cicla entre proveedores
|
|
59
|
+
- `PriorityStrategy`: Selecciona por prioridad
|
|
60
|
+
- `FallbackStrategy`: Intenta en orden hasta éxito
|
|
61
|
+
- `WeightedStrategy`: Selección basada en pesos (load balancing)
|
|
62
|
+
- `HealthAwareStrategy`: Selección basada en métricas de salud
|
|
63
|
+
|
|
64
|
+
### Factory (`src/factory/`)
|
|
65
|
+
|
|
66
|
+
- `createOrchestrator()`: Crea un orchestrator desde configuración declarativa
|
|
67
|
+
- `createProvider()`: Crea instancias de proveedores desde configuración
|
|
68
|
+
- `createStrategy()`: Crea instancias de estrategias desde configuración
|
|
69
|
+
- `isValidOrchestratorConfig()`: Valida configuración
|
|
70
|
+
|
|
71
|
+
## Flujo de Datos
|
|
72
|
+
|
|
73
|
+
```
|
|
74
|
+
Usuario
|
|
75
|
+
↓
|
|
76
|
+
Orchestrator.chat() / chatStream()
|
|
77
|
+
↓
|
|
78
|
+
Strategy.select() → Selecciona proveedor
|
|
79
|
+
↓
|
|
80
|
+
Provider.chat() / chatStream()
|
|
81
|
+
↓
|
|
82
|
+
Provider formatea mensajes → formatMessages()
|
|
83
|
+
↓
|
|
84
|
+
Llamada a API del proveedor
|
|
85
|
+
↓
|
|
86
|
+
Provider parsea respuesta → parseResponse() / parseStream()
|
|
87
|
+
↓
|
|
88
|
+
Respuesta estándar al usuario
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## Extensibilidad
|
|
92
|
+
|
|
93
|
+
### Agregar un Nuevo Proveedor
|
|
94
|
+
|
|
95
|
+
1. Crear clase que extienda `BaseProvider`
|
|
96
|
+
2. Implementar métodos requeridos
|
|
97
|
+
3. Registrar en `factory/index.ts` (método `createProvider`)
|
|
98
|
+
|
|
99
|
+
### Agregar una Nueva Estrategia
|
|
100
|
+
|
|
101
|
+
1. Crear clase que extienda `BaseStrategy`
|
|
102
|
+
2. Implementar método `select()`
|
|
103
|
+
3. Opcionalmente implementar `update()`
|
|
104
|
+
4. Registrar en `factory/index.ts` (método `createStrategy`)
|
|
105
|
+
|
|
106
|
+
## Principios de Diseño Aplicados
|
|
107
|
+
|
|
108
|
+
1. **Single Responsibility**: Cada clase tiene una responsabilidad única
|
|
109
|
+
2. **Open/Closed**: Abierto para extensión, cerrado para modificación
|
|
110
|
+
3. **Liskov Substitution**: Proveedores y estrategias son intercambiables
|
|
111
|
+
4. **Interface Segregation**: Interfaces especÃficas y cohesivas
|
|
112
|
+
5. **Dependency Inversion**: Dependencias de abstracciones, no implementaciones
|
|
113
|
+
|
|
114
|
+
## Compatibilidad
|
|
115
|
+
|
|
116
|
+
- **Node.js**: >= 18.0.0 (usa ReadableStream nativo)
|
|
117
|
+
- **Bun**: Compatible (usa APIs estándar)
|
|
118
|
+
- **TypeScript**: 5.3+
|
|
119
|
+
- **ES Modules**: Requerido
|
|
120
|
+
|
|
121
|
+
## Consideraciones de Rendimiento
|
|
122
|
+
|
|
123
|
+
- Health checks pueden ejecutarse en paralelo
|
|
124
|
+
- Fallback automático evita esperas innecesarias
|
|
125
|
+
- Streaming nativo para respuestas largas
|
|
126
|
+
- Estrategias pueden cachear métricas para mejor rendimiento
|
|
127
|
+
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Basic usage example
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { createOrchestrator } from '../src/index.js';
|
|
6
|
+
|
|
7
|
+
async function main() {
|
|
8
|
+
// Create orchestrator with declarative config
|
|
9
|
+
const orchestrator = createOrchestrator({
|
|
10
|
+
providers: [
|
|
11
|
+
{
|
|
12
|
+
id: 'groq-1',
|
|
13
|
+
type: 'groq',
|
|
14
|
+
apiKey: process.env.GROQ_API_KEY || '',
|
|
15
|
+
model: 'llama-3.3-70b-versatile', // Updated: llama-3.1-70b-versatile was decommissioned
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
id: 'openrouter-1',
|
|
19
|
+
type: 'openrouter',
|
|
20
|
+
apiKey: process.env.OPENROUTER_API_KEY || '',
|
|
21
|
+
model: 'openai/gpt-3.5-turbo',
|
|
22
|
+
},
|
|
23
|
+
],
|
|
24
|
+
strategy: {
|
|
25
|
+
type: 'round-robin',
|
|
26
|
+
},
|
|
27
|
+
enableHealthChecks: true,
|
|
28
|
+
healthCheckInterval: 60000, // 60 seconds
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
// Simple chat
|
|
32
|
+
console.log('=== Simple Chat ===');
|
|
33
|
+
const response = await orchestrator.chat([
|
|
34
|
+
{ role: 'user', content: 'Say hello in one sentence' },
|
|
35
|
+
]);
|
|
36
|
+
console.log('Response:', response.content);
|
|
37
|
+
console.log('Usage:', response.usage);
|
|
38
|
+
|
|
39
|
+
// Streaming chat
|
|
40
|
+
console.log('\n=== Streaming Chat ===');
|
|
41
|
+
const stream = await orchestrator.chatStream([
|
|
42
|
+
{ role: 'user', content: 'Count from 1 to 5' },
|
|
43
|
+
]);
|
|
44
|
+
|
|
45
|
+
const reader = stream.getReader();
|
|
46
|
+
while (true) {
|
|
47
|
+
const { done, value } = await reader.read();
|
|
48
|
+
if (done) break;
|
|
49
|
+
process.stdout.write(value.content);
|
|
50
|
+
}
|
|
51
|
+
console.log('\n');
|
|
52
|
+
|
|
53
|
+
// Cleanup
|
|
54
|
+
orchestrator.dispose();
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
main().catch(console.error);
|
|
58
|
+
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
# Chat App Example
|
|
2
|
+
|
|
3
|
+
A simple chat application to test `@ai-orchestration/core` using npm link.
|
|
4
|
+
|
|
5
|
+
## Quick Setup
|
|
6
|
+
|
|
7
|
+
### 1. Link the Package
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
# In the ia-orchestration directory (from project root)
|
|
11
|
+
cd /path/to/ia-orchestration
|
|
12
|
+
npm run link
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
### 2. Setup This Project
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
# In this directory
|
|
19
|
+
cd examples/chat-app
|
|
20
|
+
npm install
|
|
21
|
+
npm link @ai-orchestration/core
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
### 3. Configure Environment Variables
|
|
25
|
+
|
|
26
|
+
Create a `.env` file from the example:
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
# Copy the example file
|
|
30
|
+
cp .env.example .env
|
|
31
|
+
|
|
32
|
+
# Edit .env with your real API keys
|
|
33
|
+
# GROQ_API_KEY=your-real-key-here
|
|
34
|
+
# OPENROUTER_API_KEY=your-real-key-here
|
|
35
|
+
# GEMINI_API_KEY=your-real-key-here
|
|
36
|
+
# CEREBRAS_API_KEY=your-real-key-here
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
**Important**: The `.env` file is in `.gitignore` and will not be committed to the repository.
|
|
40
|
+
|
|
41
|
+
**Note**: You only need to configure at least ONE API key for it to work.
|
|
42
|
+
|
|
43
|
+
### 4. (Optional) Customize Configuration
|
|
44
|
+
|
|
45
|
+
You can edit `config.json` to:
|
|
46
|
+
- Change default models
|
|
47
|
+
- Change initial strategy
|
|
48
|
+
- Adjust chat options (temperature, maxTokens)
|
|
49
|
+
- Add or remove providers
|
|
50
|
+
|
|
51
|
+
### 5. Run
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
npm start
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Usage
|
|
58
|
+
|
|
59
|
+
The application allows you to:
|
|
60
|
+
- Chat with multiple AI providers
|
|
61
|
+
- Change strategy at runtime
|
|
62
|
+
- See which provider is being used
|
|
63
|
+
- View usage statistics
|
|
64
|
+
|
|
65
|
+
## Available Commands
|
|
66
|
+
|
|
67
|
+
- `/help` - Show help
|
|
68
|
+
- `/strategy <type>` - Change strategy (round-robin, priority, fallback)
|
|
69
|
+
- `/providers` - List available providers
|
|
70
|
+
- `/health` - Check provider health
|
|
71
|
+
- `/clear` - Clear conversation history
|
|
72
|
+
- `/exit` or `/quit` - Exit the application
|
|
73
|
+
|
|
74
|
+
## Example Session
|
|
75
|
+
|
|
76
|
+
```
|
|
77
|
+
🚀 Chat App - Example with @ai-orchestration/core
|
|
78
|
+
|
|
79
|
+
💡 Type /help to see available commands
|
|
80
|
+
|
|
81
|
+
🔧 Creating orchestrator...
|
|
82
|
+
✅ Orchestrator created with 2 provider(s)
|
|
83
|
+
|
|
84
|
+
💬 You: Hello!
|
|
85
|
+
🤔 Thinking...
|
|
86
|
+
✅ Response (1234ms):
|
|
87
|
+
|
|
88
|
+
Hello! How can I help you today?
|
|
89
|
+
|
|
90
|
+
💬 You: /providers
|
|
91
|
+
📋 Available providers:
|
|
92
|
+
1. groq-1 (Groq)
|
|
93
|
+
2. openrouter-1 (OpenRouter)
|
|
94
|
+
|
|
95
|
+
💬 You: /exit
|
|
96
|
+
👋 Goodbye!
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
## Verification
|
|
100
|
+
|
|
101
|
+
To verify everything is configured correctly:
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
# Verify that the link works
|
|
105
|
+
npm list @ai-orchestration/core
|
|
106
|
+
|
|
107
|
+
# Should show:
|
|
108
|
+
# chat-app-example@1.0.0
|
|
109
|
+
# └── @ai-orchestration/core@0.1.0 -> /path/to/ia-orchestration
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
## Troubleshooting
|
|
113
|
+
|
|
114
|
+
### Error: "Cannot find module '@ai-orchestration/core'"
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
# Verify link exists
|
|
118
|
+
npm list @ai-orchestration/core
|
|
119
|
+
|
|
120
|
+
# If it doesn't exist, re-link
|
|
121
|
+
npm link @ai-orchestration/core
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### Error: "No providers configured"
|
|
125
|
+
|
|
126
|
+
- Verify that `.env` exists in `examples/chat-app/`
|
|
127
|
+
- Verify it has at least one API key configured
|
|
128
|
+
- Verify there are no spaces around `=` in `.env`
|
|
129
|
+
- Verify values are not the example ones (`your-*-api-key-here`)
|
|
130
|
+
|
|
131
|
+
### Error: "Module not found" or TypeScript errors
|
|
132
|
+
|
|
133
|
+
```bash
|
|
134
|
+
# Reinstall dependencies
|
|
135
|
+
rm -rf node_modules package-lock.json
|
|
136
|
+
npm install
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
### Changes in package not reflected
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
# In the ia-orchestration directory (root)
|
|
143
|
+
npm run build
|
|
144
|
+
|
|
145
|
+
# Changes should be reflected automatically
|
|
146
|
+
```
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{
|
|
2
|
+
"providers": [
|
|
3
|
+
{
|
|
4
|
+
"id": "groq-1",
|
|
5
|
+
"type": "groq",
|
|
6
|
+
"envKey": "GROQ_API_KEY",
|
|
7
|
+
"model": "llama-3.3-70b-versatile"
|
|
8
|
+
},
|
|
9
|
+
{
|
|
10
|
+
"id": "openrouter-1",
|
|
11
|
+
"type": "openrouter",
|
|
12
|
+
"envKey": "OPENROUTER_API_KEY",
|
|
13
|
+
"model": "openai/gpt-3.5-turbo"
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
"id": "gemini-1",
|
|
17
|
+
"type": "gemini",
|
|
18
|
+
"envKey": "GEMINI_API_KEY",
|
|
19
|
+
"model": "gemini-pro"
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
"id": "cerebras-1",
|
|
23
|
+
"type": "cerebras",
|
|
24
|
+
"envKey": "CEREBRAS_API_KEY",
|
|
25
|
+
"model": "llama-3.3-70b"
|
|
26
|
+
}
|
|
27
|
+
],
|
|
28
|
+
"defaultStrategy": "round-robin",
|
|
29
|
+
"chatOptions": {
|
|
30
|
+
"temperature": 0.7,
|
|
31
|
+
"maxTokens": 1000
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|