@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.
Files changed (199) hide show
  1. package/.eslintrc.json +27 -0
  2. package/README.md +516 -0
  3. package/dist/core/errors.d.ts +21 -0
  4. package/dist/core/errors.d.ts.map +1 -0
  5. package/dist/core/errors.js +38 -0
  6. package/dist/core/errors.js.map +1 -0
  7. package/dist/core/interfaces.d.ts +87 -0
  8. package/dist/core/interfaces.d.ts.map +1 -0
  9. package/dist/core/interfaces.js +5 -0
  10. package/dist/core/interfaces.js.map +1 -0
  11. package/dist/core/orchestrator.d.ts +55 -0
  12. package/dist/core/orchestrator.d.ts.map +1 -0
  13. package/dist/core/orchestrator.js +147 -0
  14. package/dist/core/orchestrator.js.map +1 -0
  15. package/dist/core/types.d.ts +72 -0
  16. package/dist/core/types.d.ts.map +1 -0
  17. package/dist/core/types.js +5 -0
  18. package/dist/core/types.js.map +1 -0
  19. package/dist/factory/index.d.ts +14 -0
  20. package/dist/factory/index.d.ts.map +1 -0
  21. package/dist/factory/index.js +184 -0
  22. package/dist/factory/index.js.map +1 -0
  23. package/dist/index.d.ts +14 -0
  24. package/dist/index.d.ts.map +1 -0
  25. package/dist/index.js +15 -0
  26. package/dist/index.js.map +1 -0
  27. package/dist/providers/base.d.ts +30 -0
  28. package/dist/providers/base.d.ts.map +1 -0
  29. package/dist/providers/base.js +31 -0
  30. package/dist/providers/base.js.map +1 -0
  31. package/dist/providers/cerebras.d.ts +26 -0
  32. package/dist/providers/cerebras.d.ts.map +1 -0
  33. package/dist/providers/cerebras.js +190 -0
  34. package/dist/providers/cerebras.js.map +1 -0
  35. package/dist/providers/gemini.d.ts +26 -0
  36. package/dist/providers/gemini.d.ts.map +1 -0
  37. package/dist/providers/gemini.js +181 -0
  38. package/dist/providers/gemini.js.map +1 -0
  39. package/dist/providers/groq.d.ts +26 -0
  40. package/dist/providers/groq.d.ts.map +1 -0
  41. package/dist/providers/groq.js +225 -0
  42. package/dist/providers/groq.js.map +1 -0
  43. package/dist/providers/index.d.ts +15 -0
  44. package/dist/providers/index.d.ts.map +1 -0
  45. package/dist/providers/index.js +10 -0
  46. package/dist/providers/index.js.map +1 -0
  47. package/dist/providers/local.d.ts +27 -0
  48. package/dist/providers/local.d.ts.map +1 -0
  49. package/dist/providers/local.js +198 -0
  50. package/dist/providers/local.js.map +1 -0
  51. package/dist/providers/openrouter.d.ts +26 -0
  52. package/dist/providers/openrouter.d.ts.map +1 -0
  53. package/dist/providers/openrouter.js +172 -0
  54. package/dist/providers/openrouter.js.map +1 -0
  55. package/dist/strategies/base.d.ts +16 -0
  56. package/dist/strategies/base.d.ts.map +1 -0
  57. package/dist/strategies/base.js +21 -0
  58. package/dist/strategies/base.js.map +1 -0
  59. package/dist/strategies/fallback.d.ts +14 -0
  60. package/dist/strategies/fallback.d.ts.map +1 -0
  61. package/dist/strategies/fallback.js +29 -0
  62. package/dist/strategies/fallback.js.map +1 -0
  63. package/dist/strategies/health-aware.d.ts +20 -0
  64. package/dist/strategies/health-aware.d.ts.map +1 -0
  65. package/dist/strategies/health-aware.js +106 -0
  66. package/dist/strategies/health-aware.js.map +1 -0
  67. package/dist/strategies/index.d.ts +14 -0
  68. package/dist/strategies/index.d.ts.map +1 -0
  69. package/dist/strategies/index.js +10 -0
  70. package/dist/strategies/index.js.map +1 -0
  71. package/dist/strategies/priority.d.ts +18 -0
  72. package/dist/strategies/priority.d.ts.map +1 -0
  73. package/dist/strategies/priority.js +35 -0
  74. package/dist/strategies/priority.js.map +1 -0
  75. package/dist/strategies/round-robin.d.ts +10 -0
  76. package/dist/strategies/round-robin.d.ts.map +1 -0
  77. package/dist/strategies/round-robin.js +21 -0
  78. package/dist/strategies/round-robin.js.map +1 -0
  79. package/dist/strategies/weighted.d.ts +20 -0
  80. package/dist/strategies/weighted.d.ts.map +1 -0
  81. package/dist/strategies/weighted.js +58 -0
  82. package/dist/strategies/weighted.js.map +1 -0
  83. package/docs/ARCHITECTURE.md +126 -0
  84. package/docs/CHANGELOG.md +30 -0
  85. package/docs/CONTRIBUTING.md +198 -0
  86. package/examples/basic.ts +58 -0
  87. package/examples/chat-app/README.md +146 -0
  88. package/examples/chat-app/config.json +34 -0
  89. package/examples/chat-app/index.ts +330 -0
  90. package/examples/chat-app/package-lock.json +570 -0
  91. package/examples/chat-app/package.json +20 -0
  92. package/examples/config.example.json +42 -0
  93. package/examples/strategies.ts +112 -0
  94. package/examples/test-local.ts +150 -0
  95. package/examples/test-mock.ts +172 -0
  96. package/package/.eslintrc.json +27 -0
  97. package/package/CHANGELOG.md +31 -0
  98. package/package/CONTRIBUTING.md +156 -0
  99. package/package/PUBLISHING.md +213 -0
  100. package/package/README.md +515 -0
  101. package/package/dist/core/errors.d.ts +21 -0
  102. package/package/dist/core/errors.d.ts.map +1 -0
  103. package/package/dist/core/errors.js +38 -0
  104. package/package/dist/core/errors.js.map +1 -0
  105. package/package/dist/core/interfaces.d.ts +87 -0
  106. package/package/dist/core/interfaces.d.ts.map +1 -0
  107. package/package/dist/core/interfaces.js +5 -0
  108. package/package/dist/core/interfaces.js.map +1 -0
  109. package/package/dist/core/orchestrator.d.ts +55 -0
  110. package/package/dist/core/orchestrator.d.ts.map +1 -0
  111. package/package/dist/core/orchestrator.js +147 -0
  112. package/package/dist/core/orchestrator.js.map +1 -0
  113. package/package/dist/core/types.d.ts +72 -0
  114. package/package/dist/core/types.d.ts.map +1 -0
  115. package/package/dist/core/types.js +5 -0
  116. package/package/dist/core/types.js.map +1 -0
  117. package/package/dist/factory/index.d.ts +14 -0
  118. package/package/dist/factory/index.d.ts.map +1 -0
  119. package/package/dist/factory/index.js +184 -0
  120. package/package/dist/factory/index.js.map +1 -0
  121. package/package/dist/index.d.ts +14 -0
  122. package/package/dist/index.d.ts.map +1 -0
  123. package/package/dist/index.js +15 -0
  124. package/package/dist/index.js.map +1 -0
  125. package/package/dist/providers/base.d.ts +30 -0
  126. package/package/dist/providers/base.d.ts.map +1 -0
  127. package/package/dist/providers/base.js +31 -0
  128. package/package/dist/providers/base.js.map +1 -0
  129. package/package/dist/providers/cerebras.d.ts +26 -0
  130. package/package/dist/providers/cerebras.d.ts.map +1 -0
  131. package/package/dist/providers/cerebras.js +190 -0
  132. package/package/dist/providers/cerebras.js.map +1 -0
  133. package/package/dist/providers/gemini.d.ts +26 -0
  134. package/package/dist/providers/gemini.d.ts.map +1 -0
  135. package/package/dist/providers/gemini.js +181 -0
  136. package/package/dist/providers/gemini.js.map +1 -0
  137. package/package/dist/providers/groq.d.ts +26 -0
  138. package/package/dist/providers/groq.d.ts.map +1 -0
  139. package/package/dist/providers/groq.js +225 -0
  140. package/package/dist/providers/groq.js.map +1 -0
  141. package/package/dist/providers/index.d.ts +15 -0
  142. package/package/dist/providers/index.d.ts.map +1 -0
  143. package/package/dist/providers/index.js +10 -0
  144. package/package/dist/providers/index.js.map +1 -0
  145. package/package/dist/providers/local.d.ts +27 -0
  146. package/package/dist/providers/local.d.ts.map +1 -0
  147. package/package/dist/providers/local.js +198 -0
  148. package/package/dist/providers/local.js.map +1 -0
  149. package/package/dist/providers/openrouter.d.ts +26 -0
  150. package/package/dist/providers/openrouter.d.ts.map +1 -0
  151. package/package/dist/providers/openrouter.js +172 -0
  152. package/package/dist/providers/openrouter.js.map +1 -0
  153. package/package/dist/strategies/base.d.ts +16 -0
  154. package/package/dist/strategies/base.d.ts.map +1 -0
  155. package/package/dist/strategies/base.js +21 -0
  156. package/package/dist/strategies/base.js.map +1 -0
  157. package/package/dist/strategies/fallback.d.ts +14 -0
  158. package/package/dist/strategies/fallback.d.ts.map +1 -0
  159. package/package/dist/strategies/fallback.js +29 -0
  160. package/package/dist/strategies/fallback.js.map +1 -0
  161. package/package/dist/strategies/health-aware.d.ts +20 -0
  162. package/package/dist/strategies/health-aware.d.ts.map +1 -0
  163. package/package/dist/strategies/health-aware.js +106 -0
  164. package/package/dist/strategies/health-aware.js.map +1 -0
  165. package/package/dist/strategies/index.d.ts +14 -0
  166. package/package/dist/strategies/index.d.ts.map +1 -0
  167. package/package/dist/strategies/index.js +10 -0
  168. package/package/dist/strategies/index.js.map +1 -0
  169. package/package/dist/strategies/priority.d.ts +18 -0
  170. package/package/dist/strategies/priority.d.ts.map +1 -0
  171. package/package/dist/strategies/priority.js +35 -0
  172. package/package/dist/strategies/priority.js.map +1 -0
  173. package/package/dist/strategies/round-robin.d.ts +10 -0
  174. package/package/dist/strategies/round-robin.d.ts.map +1 -0
  175. package/package/dist/strategies/round-robin.js +21 -0
  176. package/package/dist/strategies/round-robin.js.map +1 -0
  177. package/package/dist/strategies/weighted.d.ts +20 -0
  178. package/package/dist/strategies/weighted.d.ts.map +1 -0
  179. package/package/dist/strategies/weighted.js +58 -0
  180. package/package/dist/strategies/weighted.js.map +1 -0
  181. package/package/docs/ARCHITECTURE.md +127 -0
  182. package/package/examples/basic.ts +58 -0
  183. package/package/examples/chat-app/README.md +146 -0
  184. package/package/examples/chat-app/config.json +34 -0
  185. package/package/examples/chat-app/index.ts +330 -0
  186. package/package/examples/chat-app/package-lock.json +570 -0
  187. package/package/examples/chat-app/package.json +20 -0
  188. package/package/examples/config.example.json +42 -0
  189. package/package/examples/strategies.ts +112 -0
  190. package/package/examples/test-local.ts +150 -0
  191. package/package/examples/test-mock.ts +172 -0
  192. package/package/package.json +62 -0
  193. package/package/scripts/check-types.ts +15 -0
  194. package/package/scripts/link.sh +30 -0
  195. package/package/scripts/pack.sh +36 -0
  196. package/package.json +62 -0
  197. package/scripts/check-types.ts +15 -0
  198. package/scripts/link.sh +30 -0
  199. 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