@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,213 @@
|
|
|
1
|
+
# Guía de Publicación
|
|
2
|
+
|
|
3
|
+
Esta guía explica cómo publicar `@ai-orchestration/core` en npm para que otros proyectos puedan utilizarlo.
|
|
4
|
+
|
|
5
|
+
## Pre-requisitos
|
|
6
|
+
|
|
7
|
+
1. **Cuenta de npm**: Tu usuario es `kndl` en [npmjs.com](https://www.npmjs.com/)
|
|
8
|
+
2. **Autenticación**: Debes estar autenticado en npm desde tu terminal:
|
|
9
|
+
```bash
|
|
10
|
+
npm login
|
|
11
|
+
# Usuario: kndl
|
|
12
|
+
```
|
|
13
|
+
3. **Scoped package**: Este paquete usa el scope `@ai-orchestration` (tu organización en npm), así que puedes publicarlo directamente con tu cuenta `kndl` que tiene acceso a esa organización.
|
|
14
|
+
|
|
15
|
+
## Pasos para Publicar
|
|
16
|
+
|
|
17
|
+
### 1. Verificar que todo esté listo
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
# Verificar que el build funciona
|
|
21
|
+
npm run build
|
|
22
|
+
|
|
23
|
+
# Verificar que no hay errores de TypeScript
|
|
24
|
+
npm run typecheck
|
|
25
|
+
|
|
26
|
+
# Verificar que los tests pasan (si los tienes)
|
|
27
|
+
npm test
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### 2. Verificar package.json
|
|
31
|
+
|
|
32
|
+
Asegúrate de que `package.json` tenga:
|
|
33
|
+
- ✅ `name`: `@ai-orchestration/core`
|
|
34
|
+
- ✅ `version`: Versión semántica (ej: `0.1.0`)
|
|
35
|
+
- ✅ `description`: Descripción clara
|
|
36
|
+
- ✅ `main`: Punto de entrada (`./dist/index.js`)
|
|
37
|
+
- ✅ `types`: Tipos TypeScript (`./dist/index.d.ts`)
|
|
38
|
+
- ✅ `exports`: Configuración de exports
|
|
39
|
+
- ✅ `license`: MIT (o la que prefieras)
|
|
40
|
+
- ✅ `keywords`: Palabras clave para búsqueda
|
|
41
|
+
|
|
42
|
+
### 3. Autenticarse en npm
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
# Si no estás autenticado (usuario: kndl)
|
|
46
|
+
npm login
|
|
47
|
+
|
|
48
|
+
# Verificar que estás autenticado
|
|
49
|
+
npm whoami
|
|
50
|
+
# Debería mostrar: kndl
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### 4. Verificar el paquete antes de publicar
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
# Crear un tarball local para verificar
|
|
57
|
+
npm run pack:local
|
|
58
|
+
|
|
59
|
+
# Esto crea un archivo .tgz que puedes inspeccionar
|
|
60
|
+
# Verifica que contiene:
|
|
61
|
+
# - dist/ (archivos compilados)
|
|
62
|
+
# - package.json
|
|
63
|
+
# - README.md
|
|
64
|
+
# - LICENSE (si lo tienes)
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### 5. Publicar
|
|
68
|
+
|
|
69
|
+
Como `@ai-orchestration/core` es un scoped package de tu organización `@ai-orchestration`, puedes publicarlo así:
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
# Primera vez (requiere --access public para scoped packages)
|
|
73
|
+
npm publish --access public
|
|
74
|
+
|
|
75
|
+
# Versiones subsecuentes
|
|
76
|
+
npm publish
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
#### Para versiones subsecuentes
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
# Primero actualiza la versión:
|
|
83
|
+
npm version patch # 0.1.0 -> 0.1.1
|
|
84
|
+
npm version minor # 0.1.0 -> 0.2.0
|
|
85
|
+
npm version major # 0.1.0 -> 1.0.0
|
|
86
|
+
|
|
87
|
+
# Luego publica
|
|
88
|
+
npm publish
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### 6. Verificar la publicación
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
# Verificar que el paquete está disponible
|
|
95
|
+
npm view @ai-orchestration/core
|
|
96
|
+
|
|
97
|
+
# Instalar en otro proyecto para probar
|
|
98
|
+
cd /ruta/a/otro/proyecto
|
|
99
|
+
npm install @ai-orchestration/core
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
## Workflow Recomendado
|
|
103
|
+
|
|
104
|
+
### Para desarrollo local
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
# En el proyecto del framework
|
|
108
|
+
npm run build
|
|
109
|
+
npm link
|
|
110
|
+
|
|
111
|
+
# En el proyecto que usa el framework
|
|
112
|
+
npm link @ai-orchestration/core
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
Esto crea un symlink local, así puedes probar cambios sin publicar.
|
|
116
|
+
|
|
117
|
+
### Para publicar una nueva versión
|
|
118
|
+
|
|
119
|
+
1. **Actualiza la versión**:
|
|
120
|
+
```bash
|
|
121
|
+
npm version patch # o minor, major según el cambio
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
2. **Actualiza CHANGELOG.md** (si lo tienes):
|
|
125
|
+
- Documenta los cambios de esta versión
|
|
126
|
+
|
|
127
|
+
3. **Verifica todo**:
|
|
128
|
+
```bash
|
|
129
|
+
npm run prepublishOnly # Ejecuta build + typecheck
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
4. **Publica**:
|
|
133
|
+
```bash
|
|
134
|
+
npm publish
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
5. **Crea un tag en Git** (opcional pero recomendado):
|
|
138
|
+
```bash
|
|
139
|
+
git tag v0.1.0
|
|
140
|
+
git push origin v0.1.0
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
## Uso en Otros Proyectos
|
|
144
|
+
|
|
145
|
+
Una vez publicado, otros proyectos pueden instalarlo así:
|
|
146
|
+
|
|
147
|
+
```bash
|
|
148
|
+
npm install @ai-orchestration/core
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
Y usarlo:
|
|
152
|
+
|
|
153
|
+
```typescript
|
|
154
|
+
import { createOrchestrator } from '@ai-orchestration/core';
|
|
155
|
+
|
|
156
|
+
// Las API keys deben configurarse en el proyecto consumidor
|
|
157
|
+
const orchestrator = createOrchestrator({
|
|
158
|
+
providers: [
|
|
159
|
+
{
|
|
160
|
+
id: 'groq-1',
|
|
161
|
+
type: 'groq',
|
|
162
|
+
apiKey: process.env.GROQ_API_KEY!, // Variable de entorno del proyecto consumidor
|
|
163
|
+
model: 'llama-3.3-70b-versatile',
|
|
164
|
+
},
|
|
165
|
+
],
|
|
166
|
+
strategy: { type: 'round-robin' },
|
|
167
|
+
});
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
## Notas Importantes
|
|
171
|
+
|
|
172
|
+
1. **API Keys**: Las API keys NO deben estar en el paquete publicado. Cada proyecto consumidor debe configurar sus propias keys usando variables de entorno o archivos `.env`.
|
|
173
|
+
|
|
174
|
+
2. **Scoped Packages**: Los paquetes con scope (`@ai-orchestration/core`) requieren `--access public` la primera vez que los publicas.
|
|
175
|
+
|
|
176
|
+
3. **Versionado Semántico**: Usa [Semantic Versioning](https://semver.org/):
|
|
177
|
+
- `MAJOR.MINOR.PATCH`
|
|
178
|
+
- `MAJOR`: Cambios incompatibles
|
|
179
|
+
- `MINOR`: Nuevas funcionalidades compatibles
|
|
180
|
+
- `PATCH`: Correcciones de bugs compatibles
|
|
181
|
+
|
|
182
|
+
4. **Archivos Publicados**: Solo se publican los archivos NO ignorados por `.npmignore`:
|
|
183
|
+
- ✅ `dist/` (archivos compilados)
|
|
184
|
+
- ✅ `package.json`
|
|
185
|
+
- ✅ `README.md`
|
|
186
|
+
- ✅ `LICENSE` (si existe)
|
|
187
|
+
- ❌ `src/` (código fuente)
|
|
188
|
+
- ❌ `node_modules/`
|
|
189
|
+
- ❌ `.env*`
|
|
190
|
+
|
|
191
|
+
## Troubleshooting
|
|
192
|
+
|
|
193
|
+
### Error: "You do not have permission"
|
|
194
|
+
|
|
195
|
+
- Verifica que estés autenticado: `npm whoami` (debería mostrar `kndl`)
|
|
196
|
+
- Verifica que tengas acceso a la organización `@ai-orchestration` en npm
|
|
197
|
+
- La primera vez que publicas un scoped package necesitas `--access public`
|
|
198
|
+
|
|
199
|
+
### Error: "Package name already exists"
|
|
200
|
+
|
|
201
|
+
- El nombre ya está tomado, necesitas usar otro nombre o crear una organización
|
|
202
|
+
|
|
203
|
+
### Error: "Invalid package name"
|
|
204
|
+
|
|
205
|
+
- Verifica que el nombre en `package.json` coincida exactamente con el que intentas publicar
|
|
206
|
+
- `@ai-orchestration/core` es un scoped package, así que el nombre debe ser exactamente `@ai-orchestration/core`
|
|
207
|
+
|
|
208
|
+
## Recursos
|
|
209
|
+
|
|
210
|
+
- [npm Publishing Guide](https://docs.npmjs.com/packages-and-modules/contributing-packages-to-the-registry)
|
|
211
|
+
- [Semantic Versioning](https://semver.org/)
|
|
212
|
+
- [Scoped Packages](https://docs.npmjs.com/using-npm/scope)
|
|
213
|
+
|
|
@@ -0,0 +1,515 @@
|
|
|
1
|
+
# AI Orchestration Framework
|
|
2
|
+
|
|
3
|
+
A modular and extensible framework for orchestrating multiple AI/LLM providers consistently and configurable.
|
|
4
|
+
|
|
5
|
+
**📦 This is an npm package**: API keys must be configured in the project that uses this package (using environment variables or `.env` files in that project), not in the package itself.
|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
- 🔌 **Plugin-based architecture**: Add new providers or strategies without modifying the core
|
|
10
|
+
- 🎯 **Multiple selection strategies**: Round-robin, priority, fallback, weighted, health-aware
|
|
11
|
+
- 🌊 **Native streaming**: Full support for streaming responses using ReadableStream
|
|
12
|
+
- 🔄 **Automatic fallback**: Automatically tries multiple providers if one fails
|
|
13
|
+
- 💚 **Health checks**: Provider health monitoring with latency metrics
|
|
14
|
+
- 📦 **Runtime agnostic**: Compatible with Node.js and Bun
|
|
15
|
+
- 🎨 **Declarative API**: Simple configuration via JSON/JS objects
|
|
16
|
+
- 🔒 **Type-safe**: Fully typed with TypeScript
|
|
17
|
+
|
|
18
|
+
## Installation
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
npm install @ai-orchestration/core
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Quick Start
|
|
25
|
+
|
|
26
|
+
### Basic Usage
|
|
27
|
+
|
|
28
|
+
```typescript
|
|
29
|
+
import { createOrchestrator } from '@ai-orchestration/core';
|
|
30
|
+
|
|
31
|
+
// API keys should come from environment variables configured in YOUR project
|
|
32
|
+
// Example: export GROQ_API_KEY="your-key" or using dotenv in your project
|
|
33
|
+
const orchestrator = createOrchestrator({
|
|
34
|
+
providers: [
|
|
35
|
+
{
|
|
36
|
+
id: 'groq-1',
|
|
37
|
+
type: 'groq',
|
|
38
|
+
apiKey: process.env.GROQ_API_KEY!, // Configure this variable in your project
|
|
39
|
+
model: 'llama-3.3-70b-versatile',
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
id: 'openrouter-1',
|
|
43
|
+
type: 'openrouter',
|
|
44
|
+
apiKey: process.env.OPENROUTER_API_KEY!,
|
|
45
|
+
model: 'openai/gpt-3.5-turbo',
|
|
46
|
+
},
|
|
47
|
+
],
|
|
48
|
+
strategy: {
|
|
49
|
+
type: 'round-robin',
|
|
50
|
+
},
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
// Simple chat
|
|
54
|
+
const response = await orchestrator.chat([
|
|
55
|
+
{ role: 'user', content: 'Hello, world!' },
|
|
56
|
+
]);
|
|
57
|
+
|
|
58
|
+
console.log(response.content);
|
|
59
|
+
|
|
60
|
+
// Streaming chat
|
|
61
|
+
const stream = await orchestrator.chatStream([
|
|
62
|
+
{ role: 'user', content: 'Tell me a story' },
|
|
63
|
+
]);
|
|
64
|
+
|
|
65
|
+
const reader = stream.getReader();
|
|
66
|
+
while (true) {
|
|
67
|
+
const { done, value } = await reader.read();
|
|
68
|
+
if (done) break;
|
|
69
|
+
process.stdout.write(value.content);
|
|
70
|
+
}
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### Programmatic Usage
|
|
74
|
+
|
|
75
|
+
```typescript
|
|
76
|
+
import {
|
|
77
|
+
Orchestrator,
|
|
78
|
+
RoundRobinStrategy,
|
|
79
|
+
GroqProvider,
|
|
80
|
+
OpenRouterProvider,
|
|
81
|
+
} from '@ai-orchestration/core';
|
|
82
|
+
|
|
83
|
+
// Create strategy
|
|
84
|
+
const strategy = new RoundRobinStrategy();
|
|
85
|
+
|
|
86
|
+
// Create orchestrator
|
|
87
|
+
const orchestrator = new Orchestrator(strategy);
|
|
88
|
+
|
|
89
|
+
// Register providers
|
|
90
|
+
// API keys should come from environment variables configured in YOUR project
|
|
91
|
+
orchestrator.registerProvider(
|
|
92
|
+
new GroqProvider({
|
|
93
|
+
id: 'groq-1',
|
|
94
|
+
apiKey: process.env.GROQ_API_KEY!,
|
|
95
|
+
})
|
|
96
|
+
);
|
|
97
|
+
|
|
98
|
+
orchestrator.registerProvider(
|
|
99
|
+
new OpenRouterProvider({
|
|
100
|
+
id: 'openrouter-1',
|
|
101
|
+
apiKey: process.env.OPENROUTER_API_KEY!,
|
|
102
|
+
})
|
|
103
|
+
);
|
|
104
|
+
|
|
105
|
+
// Use
|
|
106
|
+
const response = await orchestrator.chat([
|
|
107
|
+
{ role: 'user', content: 'Hello!' },
|
|
108
|
+
]);
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
## Selection Strategies
|
|
112
|
+
|
|
113
|
+
### Round-Robin
|
|
114
|
+
|
|
115
|
+
Cycles through providers in order:
|
|
116
|
+
|
|
117
|
+
```typescript
|
|
118
|
+
{
|
|
119
|
+
strategy: {
|
|
120
|
+
type: 'round-robin',
|
|
121
|
+
},
|
|
122
|
+
}
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### Priority
|
|
126
|
+
|
|
127
|
+
Selects providers based on priority (lower number = higher priority):
|
|
128
|
+
|
|
129
|
+
```typescript
|
|
130
|
+
{
|
|
131
|
+
strategy: {
|
|
132
|
+
type: 'priority',
|
|
133
|
+
priorities: {
|
|
134
|
+
'groq-1': 1,
|
|
135
|
+
'openrouter-1': 2,
|
|
136
|
+
'gemini-1': 3,
|
|
137
|
+
},
|
|
138
|
+
},
|
|
139
|
+
}
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
### Fallback
|
|
143
|
+
|
|
144
|
+
Tries providers in order until one works:
|
|
145
|
+
|
|
146
|
+
```typescript
|
|
147
|
+
{
|
|
148
|
+
strategy: {
|
|
149
|
+
type: 'fallback',
|
|
150
|
+
order: ['groq-1', 'openrouter-1', 'gemini-1'],
|
|
151
|
+
},
|
|
152
|
+
}
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### Weighted
|
|
156
|
+
|
|
157
|
+
Selection based on weights (useful for load balancing):
|
|
158
|
+
|
|
159
|
+
```typescript
|
|
160
|
+
{
|
|
161
|
+
strategy: {
|
|
162
|
+
type: 'weighted',
|
|
163
|
+
weights: {
|
|
164
|
+
'groq-1': 0.7,
|
|
165
|
+
'openrouter-1': 0.3,
|
|
166
|
+
},
|
|
167
|
+
},
|
|
168
|
+
}
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
### Weighted Cost-Aware
|
|
172
|
+
|
|
173
|
+
Considers cost per token:
|
|
174
|
+
|
|
175
|
+
```typescript
|
|
176
|
+
{
|
|
177
|
+
strategy: {
|
|
178
|
+
type: 'weighted',
|
|
179
|
+
costAware: true,
|
|
180
|
+
weights: {
|
|
181
|
+
'groq-1': 1.0,
|
|
182
|
+
'openrouter-1': 1.0,
|
|
183
|
+
},
|
|
184
|
+
},
|
|
185
|
+
}
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
### Health-Aware
|
|
189
|
+
|
|
190
|
+
Selects based on health metrics (latency, success rate):
|
|
191
|
+
|
|
192
|
+
```typescript
|
|
193
|
+
{
|
|
194
|
+
strategy: {
|
|
195
|
+
type: 'health-aware',
|
|
196
|
+
preferLowLatency: true,
|
|
197
|
+
minHealthScore: 0.5,
|
|
198
|
+
},
|
|
199
|
+
}
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
## Supported Providers
|
|
203
|
+
|
|
204
|
+
### Groq
|
|
205
|
+
|
|
206
|
+
```typescript
|
|
207
|
+
{
|
|
208
|
+
id: 'groq-1',
|
|
209
|
+
type: 'groq',
|
|
210
|
+
apiKey: 'your-api-key',
|
|
211
|
+
model: 'llama-3.3-70b-versatile', // optional, default
|
|
212
|
+
baseURL: 'https://api.groq.com/openai/v1', // optional
|
|
213
|
+
}
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
### OpenRouter
|
|
217
|
+
|
|
218
|
+
```typescript
|
|
219
|
+
{
|
|
220
|
+
id: 'openrouter-1',
|
|
221
|
+
type: 'openrouter',
|
|
222
|
+
apiKey: 'your-api-key',
|
|
223
|
+
model: 'openai/gpt-3.5-turbo', // optional
|
|
224
|
+
baseURL: 'https://openrouter.ai/api/v1', // optional
|
|
225
|
+
}
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
### Google Gemini
|
|
229
|
+
|
|
230
|
+
```typescript
|
|
231
|
+
{
|
|
232
|
+
id: 'gemini-1',
|
|
233
|
+
type: 'gemini',
|
|
234
|
+
apiKey: 'your-api-key',
|
|
235
|
+
model: 'gemini-pro', // optional
|
|
236
|
+
baseURL: 'https://generativelanguage.googleapis.com/v1beta', // optional
|
|
237
|
+
}
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
### Cerebras
|
|
241
|
+
|
|
242
|
+
Cerebras Inference API - OpenAI compatible. Documentation: [inference-docs.cerebras.ai](https://inference-docs.cerebras.ai/quickstart)
|
|
243
|
+
|
|
244
|
+
```typescript
|
|
245
|
+
{
|
|
246
|
+
id: 'cerebras-1',
|
|
247
|
+
type: 'cerebras',
|
|
248
|
+
apiKey: 'your-api-key', // Get at: https://inference-docs.cerebras.ai
|
|
249
|
+
model: 'llama-3.3-70b', // optional, default
|
|
250
|
+
baseURL: 'https://api.cerebras.ai/v1', // optional
|
|
251
|
+
}
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
**Note**: Cerebras API requires the `User-Agent` header to avoid CloudFront blocking. This is included automatically.
|
|
255
|
+
|
|
256
|
+
### Local (Local Models)
|
|
257
|
+
|
|
258
|
+
For local models that expose an OpenAI-compatible API:
|
|
259
|
+
|
|
260
|
+
```typescript
|
|
261
|
+
{
|
|
262
|
+
id: 'local-1',
|
|
263
|
+
type: 'local',
|
|
264
|
+
baseURL: 'http://localhost:8000',
|
|
265
|
+
model: 'local-model', // optional
|
|
266
|
+
apiKey: 'optional-key', // optional
|
|
267
|
+
}
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
## Health Checks
|
|
271
|
+
|
|
272
|
+
Enable periodic health monitoring:
|
|
273
|
+
|
|
274
|
+
```typescript
|
|
275
|
+
const orchestrator = createOrchestrator({
|
|
276
|
+
providers: [...],
|
|
277
|
+
strategy: {...},
|
|
278
|
+
enableHealthChecks: true,
|
|
279
|
+
healthCheckInterval: 60000, // every 60 seconds
|
|
280
|
+
});
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
Or manually:
|
|
284
|
+
|
|
285
|
+
```typescript
|
|
286
|
+
const health = await provider.checkHealth();
|
|
287
|
+
console.log(health.healthy, health.latency);
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
## Chat Options
|
|
291
|
+
|
|
292
|
+
```typescript
|
|
293
|
+
const response = await orchestrator.chat(messages, {
|
|
294
|
+
temperature: 0.7,
|
|
295
|
+
maxTokens: 1000,
|
|
296
|
+
topP: 0.9,
|
|
297
|
+
topK: 40,
|
|
298
|
+
stopSequences: ['\n\n'],
|
|
299
|
+
});
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
## Extensibility
|
|
303
|
+
|
|
304
|
+
### Adding a New Provider
|
|
305
|
+
|
|
306
|
+
```typescript
|
|
307
|
+
import { BaseProvider } from '@ai-orchestration/core';
|
|
308
|
+
import type {
|
|
309
|
+
ChatMessage,
|
|
310
|
+
ChatOptions,
|
|
311
|
+
ChatResponse,
|
|
312
|
+
ChatChunk,
|
|
313
|
+
ProviderHealth,
|
|
314
|
+
ProviderMetadata,
|
|
315
|
+
} from '@ai-orchestration/core';
|
|
316
|
+
|
|
317
|
+
export class CustomProvider extends BaseProvider {
|
|
318
|
+
readonly id: string;
|
|
319
|
+
readonly metadata: ProviderMetadata;
|
|
320
|
+
|
|
321
|
+
constructor(config: CustomConfig) {
|
|
322
|
+
super();
|
|
323
|
+
this.id = config.id;
|
|
324
|
+
this.metadata = {
|
|
325
|
+
id: this.id,
|
|
326
|
+
name: 'Custom Provider',
|
|
327
|
+
};
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
async checkHealth(): Promise<ProviderHealth> {
|
|
331
|
+
// Implement health check
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
async chat(messages: ChatMessage[], options?: ChatOptions): Promise<ChatResponse> {
|
|
335
|
+
// Implement chat
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
async chatStream(messages: ChatMessage[], options?: ChatOptions): Promise<ReadableStream<ChatChunk>> {
|
|
339
|
+
// Implement streaming
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
protected formatMessages(messages: ChatMessage[]): unknown {
|
|
343
|
+
// Convert standard format to provider format
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
protected parseResponse(response: unknown): ChatResponse {
|
|
347
|
+
// Convert provider response to standard format
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
protected parseStream(stream: ReadableStream<unknown>): ReadableStream<ChatChunk> {
|
|
351
|
+
// Convert provider stream to standard format
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
### Adding a New Strategy
|
|
357
|
+
|
|
358
|
+
```typescript
|
|
359
|
+
import { BaseStrategy } from '@ai-orchestration/core';
|
|
360
|
+
import type { AIService, SelectionContext } from '@ai-orchestration/core';
|
|
361
|
+
|
|
362
|
+
export class CustomStrategy extends BaseStrategy {
|
|
363
|
+
async select(
|
|
364
|
+
providers: AIService[],
|
|
365
|
+
context?: SelectionContext
|
|
366
|
+
): Promise<AIService | null> {
|
|
367
|
+
// Implement selection logic
|
|
368
|
+
return providers[0];
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
update?(provider: AIService, success: boolean, metadata?: unknown): void {
|
|
372
|
+
// Optional: update internal state
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
## Architecture
|
|
378
|
+
|
|
379
|
+
```
|
|
380
|
+
src/
|
|
381
|
+
├── core/
|
|
382
|
+
│ ├── interfaces.ts # Main interfaces
|
|
383
|
+
│ ├── types.ts # Shared types
|
|
384
|
+
│ ├── orchestrator.ts # Orchestrator core
|
|
385
|
+
│ └── errors.ts # Custom error classes
|
|
386
|
+
├── providers/
|
|
387
|
+
│ ├── base.ts # Base class for providers
|
|
388
|
+
│ ├── groq.ts
|
|
389
|
+
│ ├── openrouter.ts
|
|
390
|
+
│ ├── gemini.ts
|
|
391
|
+
│ ├── cerebras.ts
|
|
392
|
+
│ └── local.ts
|
|
393
|
+
├── strategies/
|
|
394
|
+
│ ├── base.ts # Base class for strategies
|
|
395
|
+
│ ├── round-robin.ts
|
|
396
|
+
│ ├── priority.ts
|
|
397
|
+
│ ├── fallback.ts
|
|
398
|
+
│ ├── weighted.ts
|
|
399
|
+
│ └── health-aware.ts
|
|
400
|
+
├── factory/
|
|
401
|
+
│ └── index.ts # Factory for declarative creation
|
|
402
|
+
└── index.ts # Main entry point
|
|
403
|
+
```
|
|
404
|
+
|
|
405
|
+
## Design Principles
|
|
406
|
+
|
|
407
|
+
- **Single Responsibility**: Each class has a single responsibility
|
|
408
|
+
- **Open/Closed Principle**: Extensible without modifying the core
|
|
409
|
+
- **Plugin-based Architecture**: Providers and strategies are plugins
|
|
410
|
+
- **Composition over Inheritance**: Preference for composition
|
|
411
|
+
- **Configuration over Hard-coding**: Declarative configuration
|
|
412
|
+
- **Declarative APIs**: Simple and expressive APIs
|
|
413
|
+
|
|
414
|
+
## Development
|
|
415
|
+
|
|
416
|
+
### Setup
|
|
417
|
+
|
|
418
|
+
```bash
|
|
419
|
+
# Install dependencies
|
|
420
|
+
npm install
|
|
421
|
+
|
|
422
|
+
# Build
|
|
423
|
+
npm run build
|
|
424
|
+
|
|
425
|
+
# Development with watch
|
|
426
|
+
npm run dev
|
|
427
|
+
|
|
428
|
+
# Type checking
|
|
429
|
+
npm run typecheck
|
|
430
|
+
|
|
431
|
+
# Tests
|
|
432
|
+
npm test
|
|
433
|
+
```
|
|
434
|
+
|
|
435
|
+
### Testing
|
|
436
|
+
|
|
437
|
+
#### Quick Test (No API Keys Required)
|
|
438
|
+
|
|
439
|
+
Test the framework with mock providers without needing API keys:
|
|
440
|
+
|
|
441
|
+
```bash
|
|
442
|
+
npm run test:mock
|
|
443
|
+
```
|
|
444
|
+
|
|
445
|
+
#### Test with Real Providers
|
|
446
|
+
|
|
447
|
+
**Note**: The `@ai-orchestration/core` package does not include `.env` files. Environment variables must be configured in your project or in the examples.
|
|
448
|
+
|
|
449
|
+
1. **Set environment variables:**
|
|
450
|
+
|
|
451
|
+
```bash
|
|
452
|
+
export GROQ_API_KEY="your-key"
|
|
453
|
+
export OPENROUTER_API_KEY="your-key"
|
|
454
|
+
export GEMINI_API_KEY="your-key"
|
|
455
|
+
export CEREBRAS_API_KEY="your-key"
|
|
456
|
+
```
|
|
457
|
+
|
|
458
|
+
2. **Run tests:**
|
|
459
|
+
|
|
460
|
+
```bash
|
|
461
|
+
npm run test:local
|
|
462
|
+
```
|
|
463
|
+
|
|
464
|
+
### Local Development in Other Projects
|
|
465
|
+
|
|
466
|
+
#### Method 1: npm link (Recommended)
|
|
467
|
+
|
|
468
|
+
```bash
|
|
469
|
+
# In this directory (ai-orchestration)
|
|
470
|
+
npm run link
|
|
471
|
+
|
|
472
|
+
# In your other project
|
|
473
|
+
npm link @ai-orchestration/core
|
|
474
|
+
```
|
|
475
|
+
|
|
476
|
+
Now you can import normally:
|
|
477
|
+
```typescript
|
|
478
|
+
import { createOrchestrator } from '@ai-orchestration/core';
|
|
479
|
+
```
|
|
480
|
+
|
|
481
|
+
#### Method 2: npm pack
|
|
482
|
+
|
|
483
|
+
```bash
|
|
484
|
+
# In this directory
|
|
485
|
+
npm run pack:local
|
|
486
|
+
|
|
487
|
+
# In your other project
|
|
488
|
+
npm install ./@ai-orchestration-core-0.1.0.tgz
|
|
489
|
+
```
|
|
490
|
+
|
|
491
|
+
## Requirements
|
|
492
|
+
|
|
493
|
+
- **Node.js**: >= 18.0.0 (for native ReadableStream and test runner)
|
|
494
|
+
- **TypeScript**: 5.3+ (already included in devDependencies)
|
|
495
|
+
|
|
496
|
+
## Examples
|
|
497
|
+
|
|
498
|
+
See the `examples/` directory for more code examples:
|
|
499
|
+
- `basic.ts` - Basic usage example
|
|
500
|
+
- `strategies.ts` - Strategy examples
|
|
501
|
+
- `test-local.ts` - Testing with real providers
|
|
502
|
+
- `test-mock.ts` - Testing with mock providers
|
|
503
|
+
- `chat-app/` - Full chat application example
|
|
504
|
+
|
|
505
|
+
## License
|
|
506
|
+
|
|
507
|
+
MIT
|
|
508
|
+
|
|
509
|
+
## Contributing
|
|
510
|
+
|
|
511
|
+
See [CONTRIBUTING.md](./CONTRIBUTING.md) for guidelines on contributing to this project.
|
|
512
|
+
|
|
513
|
+
## Related Documentation
|
|
514
|
+
|
|
515
|
+
- [ARCHITECTURE.md](./ARCHITECTURE.md) - Detailed architecture documentation
|