@ai-orchestration/core 0.2.0 → 0.3.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 (173) hide show
  1. package/README.md +16 -0
  2. package/dist/cjs/core/errors.d.ts +21 -0
  3. package/dist/cjs/core/errors.d.ts.map +1 -0
  4. package/dist/cjs/core/errors.js +40 -0
  5. package/dist/cjs/core/errors.js.map +1 -0
  6. package/dist/cjs/core/interfaces.d.ts +166 -0
  7. package/dist/cjs/core/interfaces.d.ts.map +1 -0
  8. package/dist/cjs/core/interfaces.js +6 -0
  9. package/dist/cjs/core/interfaces.js.map +1 -0
  10. package/dist/cjs/core/metrics.d.ts +161 -0
  11. package/dist/cjs/core/metrics.d.ts.map +1 -0
  12. package/dist/cjs/core/metrics.js +282 -0
  13. package/dist/cjs/core/metrics.js.map +1 -0
  14. package/dist/cjs/core/orchestrator.d.ts +97 -0
  15. package/dist/cjs/core/orchestrator.d.ts.map +1 -0
  16. package/dist/cjs/core/orchestrator.js +402 -0
  17. package/dist/cjs/core/orchestrator.js.map +1 -0
  18. package/dist/cjs/core/types.d.ts +111 -0
  19. package/dist/cjs/core/types.d.ts.map +1 -0
  20. package/dist/cjs/core/types.js +6 -0
  21. package/dist/cjs/core/types.js.map +1 -0
  22. package/dist/cjs/factory/index.d.ts +14 -0
  23. package/dist/cjs/factory/index.d.ts.map +1 -0
  24. package/dist/cjs/factory/index.js +208 -0
  25. package/dist/cjs/factory/index.js.map +1 -0
  26. package/dist/cjs/index.d.ts +16 -0
  27. package/dist/cjs/index.d.ts.map +1 -0
  28. package/dist/cjs/index.js +37 -0
  29. package/dist/cjs/index.js.map +1 -0
  30. package/dist/cjs/providers/base.d.ts +30 -0
  31. package/dist/cjs/providers/base.d.ts.map +1 -0
  32. package/dist/cjs/providers/base.js +35 -0
  33. package/dist/cjs/providers/base.js.map +1 -0
  34. package/dist/cjs/providers/cerebras.d.ts +26 -0
  35. package/dist/cjs/providers/cerebras.d.ts.map +1 -0
  36. package/dist/cjs/providers/cerebras.js +207 -0
  37. package/dist/cjs/providers/cerebras.js.map +1 -0
  38. package/dist/cjs/providers/gemini.d.ts +26 -0
  39. package/dist/cjs/providers/gemini.d.ts.map +1 -0
  40. package/dist/cjs/providers/gemini.js +180 -0
  41. package/dist/cjs/providers/gemini.js.map +1 -0
  42. package/dist/cjs/providers/groq.d.ts +26 -0
  43. package/dist/cjs/providers/groq.d.ts.map +1 -0
  44. package/dist/cjs/providers/groq.js +242 -0
  45. package/dist/cjs/providers/groq.js.map +1 -0
  46. package/dist/cjs/providers/index.d.ts +15 -0
  47. package/dist/cjs/providers/index.d.ts.map +1 -0
  48. package/dist/cjs/providers/index.js +19 -0
  49. package/dist/cjs/providers/index.js.map +1 -0
  50. package/dist/cjs/providers/local.d.ts +27 -0
  51. package/dist/cjs/providers/local.d.ts.map +1 -0
  52. package/dist/cjs/providers/local.js +205 -0
  53. package/dist/cjs/providers/local.js.map +1 -0
  54. package/dist/cjs/providers/openrouter.d.ts +26 -0
  55. package/dist/cjs/providers/openrouter.d.ts.map +1 -0
  56. package/dist/cjs/providers/openrouter.js +187 -0
  57. package/dist/cjs/providers/openrouter.js.map +1 -0
  58. package/dist/cjs/strategies/base.d.ts +16 -0
  59. package/dist/cjs/strategies/base.d.ts.map +1 -0
  60. package/dist/cjs/strategies/base.js +25 -0
  61. package/dist/cjs/strategies/base.js.map +1 -0
  62. package/dist/cjs/strategies/fallback.d.ts +14 -0
  63. package/dist/cjs/strategies/fallback.d.ts.map +1 -0
  64. package/dist/cjs/strategies/fallback.js +32 -0
  65. package/dist/cjs/strategies/fallback.js.map +1 -0
  66. package/dist/cjs/strategies/health-aware.d.ts +20 -0
  67. package/dist/cjs/strategies/health-aware.d.ts.map +1 -0
  68. package/dist/cjs/strategies/health-aware.js +108 -0
  69. package/dist/cjs/strategies/health-aware.js.map +1 -0
  70. package/dist/cjs/strategies/index.d.ts +14 -0
  71. package/dist/cjs/strategies/index.d.ts.map +1 -0
  72. package/dist/cjs/strategies/index.js +19 -0
  73. package/dist/cjs/strategies/index.js.map +1 -0
  74. package/dist/cjs/strategies/priority.d.ts +18 -0
  75. package/dist/cjs/strategies/priority.d.ts.map +1 -0
  76. package/dist/cjs/strategies/priority.js +39 -0
  77. package/dist/cjs/strategies/priority.js.map +1 -0
  78. package/dist/cjs/strategies/round-robin.d.ts +10 -0
  79. package/dist/cjs/strategies/round-robin.d.ts.map +1 -0
  80. package/dist/cjs/strategies/round-robin.js +28 -0
  81. package/dist/cjs/strategies/round-robin.js.map +1 -0
  82. package/dist/cjs/strategies/weighted.d.ts +20 -0
  83. package/dist/cjs/strategies/weighted.d.ts.map +1 -0
  84. package/dist/cjs/strategies/weighted.js +61 -0
  85. package/dist/cjs/strategies/weighted.js.map +1 -0
  86. package/dist/esm/core/errors.d.ts +21 -0
  87. package/dist/esm/core/errors.d.ts.map +1 -0
  88. package/dist/esm/core/errors.js +33 -0
  89. package/dist/esm/core/errors.js.map +1 -0
  90. package/dist/esm/core/interfaces.d.ts +166 -0
  91. package/dist/esm/core/interfaces.d.ts.map +1 -0
  92. package/dist/esm/core/interfaces.js +5 -0
  93. package/dist/esm/core/interfaces.js.map +1 -0
  94. package/dist/esm/core/metrics.d.ts +161 -0
  95. package/dist/esm/core/metrics.d.ts.map +1 -0
  96. package/dist/esm/core/metrics.js +278 -0
  97. package/dist/esm/core/metrics.js.map +1 -0
  98. package/dist/esm/core/orchestrator.d.ts +97 -0
  99. package/dist/esm/core/orchestrator.d.ts.map +1 -0
  100. package/dist/esm/core/orchestrator.js +398 -0
  101. package/dist/esm/core/orchestrator.js.map +1 -0
  102. package/dist/esm/core/types.d.ts +111 -0
  103. package/dist/esm/core/types.d.ts.map +1 -0
  104. package/dist/esm/core/types.js +5 -0
  105. package/dist/esm/core/types.js.map +1 -0
  106. package/dist/esm/factory/index.d.ts +14 -0
  107. package/dist/esm/factory/index.d.ts.map +1 -0
  108. package/dist/esm/factory/index.js +204 -0
  109. package/dist/esm/factory/index.js.map +1 -0
  110. package/dist/esm/index.d.ts +16 -0
  111. package/dist/esm/index.d.ts.map +1 -0
  112. package/dist/esm/index.js +16 -0
  113. package/dist/esm/index.js.map +1 -0
  114. package/dist/esm/providers/base.d.ts +30 -0
  115. package/dist/esm/providers/base.d.ts.map +1 -0
  116. package/dist/esm/providers/base.js +31 -0
  117. package/dist/esm/providers/base.js.map +1 -0
  118. package/dist/esm/providers/cerebras.d.ts +26 -0
  119. package/dist/esm/providers/cerebras.d.ts.map +1 -0
  120. package/dist/esm/providers/cerebras.js +203 -0
  121. package/dist/esm/providers/cerebras.js.map +1 -0
  122. package/dist/esm/providers/gemini.d.ts +26 -0
  123. package/dist/esm/providers/gemini.d.ts.map +1 -0
  124. package/dist/esm/providers/gemini.js +176 -0
  125. package/dist/esm/providers/gemini.js.map +1 -0
  126. package/dist/esm/providers/groq.d.ts +26 -0
  127. package/dist/esm/providers/groq.d.ts.map +1 -0
  128. package/dist/esm/providers/groq.js +238 -0
  129. package/dist/esm/providers/groq.js.map +1 -0
  130. package/dist/esm/providers/index.d.ts +15 -0
  131. package/dist/esm/providers/index.d.ts.map +1 -0
  132. package/dist/esm/providers/index.js +10 -0
  133. package/dist/esm/providers/index.js.map +1 -0
  134. package/dist/esm/providers/local.d.ts +27 -0
  135. package/dist/esm/providers/local.d.ts.map +1 -0
  136. package/dist/esm/providers/local.js +201 -0
  137. package/dist/esm/providers/local.js.map +1 -0
  138. package/dist/esm/providers/openrouter.d.ts +26 -0
  139. package/dist/esm/providers/openrouter.d.ts.map +1 -0
  140. package/dist/esm/providers/openrouter.js +183 -0
  141. package/dist/esm/providers/openrouter.js.map +1 -0
  142. package/dist/esm/strategies/base.d.ts +16 -0
  143. package/dist/esm/strategies/base.d.ts.map +1 -0
  144. package/dist/esm/strategies/base.js +21 -0
  145. package/dist/esm/strategies/base.js.map +1 -0
  146. package/dist/esm/strategies/fallback.d.ts +14 -0
  147. package/dist/esm/strategies/fallback.d.ts.map +1 -0
  148. package/dist/esm/strategies/fallback.js +28 -0
  149. package/dist/esm/strategies/fallback.js.map +1 -0
  150. package/dist/esm/strategies/health-aware.d.ts +20 -0
  151. package/dist/esm/strategies/health-aware.d.ts.map +1 -0
  152. package/dist/esm/strategies/health-aware.js +104 -0
  153. package/dist/esm/strategies/health-aware.js.map +1 -0
  154. package/dist/esm/strategies/index.d.ts +14 -0
  155. package/dist/esm/strategies/index.d.ts.map +1 -0
  156. package/dist/esm/strategies/index.js +10 -0
  157. package/dist/esm/strategies/index.js.map +1 -0
  158. package/dist/esm/strategies/priority.d.ts +18 -0
  159. package/dist/esm/strategies/priority.d.ts.map +1 -0
  160. package/dist/esm/strategies/priority.js +35 -0
  161. package/dist/esm/strategies/priority.js.map +1 -0
  162. package/dist/esm/strategies/round-robin.d.ts +10 -0
  163. package/dist/esm/strategies/round-robin.d.ts.map +1 -0
  164. package/dist/esm/strategies/round-robin.js +24 -0
  165. package/dist/esm/strategies/round-robin.js.map +1 -0
  166. package/dist/esm/strategies/weighted.d.ts +20 -0
  167. package/dist/esm/strategies/weighted.d.ts.map +1 -0
  168. package/dist/esm/strategies/weighted.js +57 -0
  169. package/dist/esm/strategies/weighted.js.map +1 -0
  170. package/examples/metrics.ts +1 -0
  171. package/package.json +15 -6
  172. package/tsconfig.cjs.json +9 -0
  173. package/tsconfig.esm.json +9 -0
@@ -0,0 +1,104 @@
1
+ /**
2
+ * Health-aware strategy: selects providers based on health metrics (latency, success rate)
3
+ */
4
+ import { BaseStrategy } from './base.js';
5
+ export class HealthAwareStrategy extends BaseStrategy {
6
+ constructor(config) {
7
+ super();
8
+ this.stats = new Map();
9
+ this.preferLowLatency = config?.preferLowLatency ?? true;
10
+ this.minHealthScore = config?.minHealthScore ?? 0;
11
+ }
12
+ async select(providers, context) {
13
+ const available = this.filterAttempted(providers, context);
14
+ if (available.length === 0) {
15
+ return null;
16
+ }
17
+ // Fetch health for all providers
18
+ const healthChecks = await Promise.allSettled(available.map(async (p) => {
19
+ const health = await p.checkHealth();
20
+ return { provider: p, health };
21
+ }));
22
+ // Build stats with health information
23
+ const candidates = [];
24
+ for (const result of healthChecks) {
25
+ if (result.status === 'fulfilled') {
26
+ const { provider, health } = result.value;
27
+ if (!health.healthy)
28
+ continue;
29
+ const stats = this.getOrCreateStats(provider);
30
+ stats.health = health;
31
+ const healthScore = this.calculateHealthScore(stats);
32
+ if (healthScore >= this.minHealthScore) {
33
+ candidates.push(stats);
34
+ }
35
+ }
36
+ }
37
+ if (candidates.length === 0) {
38
+ return null;
39
+ }
40
+ // Sort by health score (and latency if preferred)
41
+ candidates.sort((a, b) => {
42
+ const scoreA = this.calculateHealthScore(a);
43
+ const scoreB = this.calculateHealthScore(b);
44
+ if (scoreA !== scoreB) {
45
+ return scoreB - scoreA; // Higher score first
46
+ }
47
+ // If scores are equal and prefer low latency, sort by latency
48
+ if (this.preferLowLatency) {
49
+ const latencyA = a.health.latency ?? Infinity;
50
+ const latencyB = b.health.latency ?? Infinity;
51
+ return latencyA - latencyB;
52
+ }
53
+ return 0;
54
+ });
55
+ return candidates[0].provider;
56
+ }
57
+ update(provider, success, metadata) {
58
+ const stats = this.getOrCreateStats(provider);
59
+ if (success) {
60
+ stats.successCount++;
61
+ // Update latency if available
62
+ if (metadata && typeof metadata === 'object' && 'latency' in metadata) {
63
+ const latency = Number(metadata.latency);
64
+ if (!isNaN(latency)) {
65
+ stats.avgLatency =
66
+ stats.avgLatency === undefined
67
+ ? latency
68
+ : (stats.avgLatency + latency) / 2;
69
+ }
70
+ }
71
+ }
72
+ else {
73
+ stats.failureCount++;
74
+ }
75
+ }
76
+ getOrCreateStats(provider) {
77
+ let stats = this.stats.get(provider.id);
78
+ if (!stats) {
79
+ stats = {
80
+ provider,
81
+ health: { healthy: true },
82
+ successCount: 0,
83
+ failureCount: 0,
84
+ };
85
+ this.stats.set(provider.id, stats);
86
+ }
87
+ return stats;
88
+ }
89
+ calculateHealthScore(stats) {
90
+ const total = stats.successCount + stats.failureCount;
91
+ if (total === 0) {
92
+ return 1.0; // No data, assume healthy
93
+ }
94
+ const successRate = stats.successCount / total;
95
+ // Factor in latency if available
96
+ let latencyFactor = 1.0;
97
+ if (stats.avgLatency !== undefined) {
98
+ // Normalize latency (assume < 1000ms is good, > 5000ms is bad)
99
+ latencyFactor = Math.max(0, 1 - (stats.avgLatency - 1000) / 4000);
100
+ }
101
+ return successRate * latencyFactor;
102
+ }
103
+ }
104
+ //# sourceMappingURL=health-aware.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"health-aware.js","sourceRoot":"","sources":["../../../src/strategies/health-aware.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Export all strategies
3
+ */
4
+ export { BaseStrategy } from './base.js';
5
+ export { RoundRobinStrategy } from './round-robin.js';
6
+ export { PriorityStrategy } from './priority.js';
7
+ export type { PriorityStrategyConfig } from './priority.js';
8
+ export { FallbackStrategy } from './fallback.js';
9
+ export type { FallbackStrategyConfig } from './fallback.js';
10
+ export { WeightedStrategy } from './weighted.js';
11
+ export type { WeightedStrategyConfig } from './weighted.js';
12
+ export { HealthAwareStrategy } from './health-aware.js';
13
+ export type { HealthAwareStrategyConfig } from './health-aware.js';
14
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/strategies/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACjD,YAAY,EAAE,sBAAsB,EAAE,MAAM,eAAe,CAAC;AAC5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACjD,YAAY,EAAE,sBAAsB,EAAE,MAAM,eAAe,CAAC;AAC5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACjD,YAAY,EAAE,sBAAsB,EAAE,MAAM,eAAe,CAAC;AAC5D,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,YAAY,EAAE,yBAAyB,EAAE,MAAM,mBAAmB,CAAC"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Export all strategies
3
+ */
4
+ export { BaseStrategy } from './base.js';
5
+ export { RoundRobinStrategy } from './round-robin.js';
6
+ export { PriorityStrategy } from './priority.js';
7
+ export { FallbackStrategy } from './fallback.js';
8
+ export { WeightedStrategy } from './weighted.js';
9
+ export { HealthAwareStrategy } from './health-aware.js';
10
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/strategies/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAEjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAEjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAEjD,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Priority strategy: selects providers based on priority order
3
+ */
4
+ import { BaseStrategy } from './base.js';
5
+ import type { AIService, SelectionContext } from '../core/interfaces.js';
6
+ export interface PriorityStrategyConfig {
7
+ priorities?: Record<string, number>;
8
+ }
9
+ export declare class PriorityStrategy extends BaseStrategy {
10
+ private priorities;
11
+ constructor(config?: PriorityStrategyConfig);
12
+ select(providers: AIService[], context?: SelectionContext): Promise<AIService | null>;
13
+ /**
14
+ * Set priority for a provider
15
+ */
16
+ setPriority(providerId: string, priority: number): void;
17
+ }
18
+ //# sourceMappingURL=priority.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"priority.d.ts","sourceRoot":"","sources":["../../../src/strategies/priority.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,KAAK,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAEzE,MAAM,WAAW,sBAAsB;IACrC,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACrC;AAED,qBAAa,gBAAiB,SAAQ,YAAY;IAChD,OAAO,CAAC,UAAU,CAAkC;gBAExC,MAAM,CAAC,EAAE,sBAAsB;IASrC,MAAM,CACV,SAAS,EAAE,SAAS,EAAE,EACtB,OAAO,CAAC,EAAE,gBAAgB,GACzB,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC;IAgB5B;;OAEG;IACH,WAAW,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI;CAGxD"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Priority strategy: selects providers based on priority order
3
+ */
4
+ import { BaseStrategy } from './base.js';
5
+ export class PriorityStrategy extends BaseStrategy {
6
+ constructor(config) {
7
+ super();
8
+ this.priorities = new Map();
9
+ if (config?.priorities) {
10
+ Object.entries(config.priorities).forEach(([id, priority]) => {
11
+ this.priorities.set(id, priority);
12
+ });
13
+ }
14
+ }
15
+ async select(providers, context) {
16
+ const available = this.filterAttempted(providers, context);
17
+ if (available.length === 0) {
18
+ return null;
19
+ }
20
+ // Sort by priority (lower number = higher priority)
21
+ const sorted = [...available].sort((a, b) => {
22
+ const priorityA = this.priorities.get(a.id) ?? 999;
23
+ const priorityB = this.priorities.get(b.id) ?? 999;
24
+ return priorityA - priorityB;
25
+ });
26
+ return sorted[0];
27
+ }
28
+ /**
29
+ * Set priority for a provider
30
+ */
31
+ setPriority(providerId, priority) {
32
+ this.priorities.set(providerId, priority);
33
+ }
34
+ }
35
+ //# sourceMappingURL=priority.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"priority.js","sourceRoot":"","sources":["../../../src/strategies/priority.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAOzC,MAAM,OAAO,gBAAiB,SAAQ,YAAY;IAGhD,YAAY,MAA+B;QACzC,KAAK,EAAE,CAAC;QAHF,eAAU,GAAwB,IAAI,GAAG,EAAE,CAAC;QAIlD,IAAI,MAAM,EAAE,UAAU,EAAE,CAAC;YACvB,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,QAAQ,CAAC,EAAE,EAAE;gBAC3D,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC;YACpC,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,oDAAoD;QACpD,MAAM,MAAM,GAAG,CAAC,GAAG,SAAS,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;YAC1C,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,GAAG,CAAC;YACnD,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,GAAG,CAAC;YACnD,OAAO,SAAS,GAAG,SAAS,CAAC;QAC/B,CAAC,CAAC,CAAC;QAEH,OAAO,MAAM,CAAC,CAAC,CAAC,CAAC;IACnB,CAAC;IAED;;OAEG;IACH,WAAW,CAAC,UAAkB,EAAE,QAAgB;QAC9C,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;IAC5C,CAAC;CACF"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Round-robin strategy: cycles through providers in order
3
+ */
4
+ import { BaseStrategy } from './base.js';
5
+ import type { AIService, SelectionContext } from '../core/interfaces.js';
6
+ export declare class RoundRobinStrategy extends BaseStrategy {
7
+ private currentIndex;
8
+ select(providers: AIService[], context?: SelectionContext): Promise<AIService | null>;
9
+ }
10
+ //# sourceMappingURL=round-robin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"round-robin.d.ts","sourceRoot":"","sources":["../../../src/strategies/round-robin.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,KAAK,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAEzE,qBAAa,kBAAmB,SAAQ,YAAY;IAClD,OAAO,CAAC,YAAY,CAAK;IAEnB,MAAM,CACV,SAAS,EAAE,SAAS,EAAE,EACtB,OAAO,CAAC,EAAE,gBAAgB,GACzB,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC;CAgB7B"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Round-robin strategy: cycles through providers in order
3
+ */
4
+ import { BaseStrategy } from './base.js';
5
+ export class RoundRobinStrategy extends BaseStrategy {
6
+ constructor() {
7
+ super(...arguments);
8
+ this.currentIndex = 0;
9
+ }
10
+ async select(providers, context) {
11
+ const available = this.filterAttempted(providers, context);
12
+ if (available.length === 0) {
13
+ return null;
14
+ }
15
+ // Reset index if it's out of bounds
16
+ if (this.currentIndex >= available.length) {
17
+ this.currentIndex = 0;
18
+ }
19
+ const selected = available[this.currentIndex];
20
+ this.currentIndex = (this.currentIndex + 1) % available.length;
21
+ return selected;
22
+ }
23
+ }
24
+ //# sourceMappingURL=round-robin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"round-robin.js","sourceRoot":"","sources":["../../../src/strategies/round-robin.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAGzC,MAAM,OAAO,kBAAmB,SAAQ,YAAY;IAApD;;QACU,iBAAY,GAAG,CAAC,CAAC;IAqB3B,CAAC;IAnBC,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,oCAAoC;QACpC,IAAI,IAAI,CAAC,YAAY,IAAI,SAAS,CAAC,MAAM,EAAE,CAAC;YAC1C,IAAI,CAAC,YAAY,GAAG,CAAC,CAAC;QACxB,CAAC;QAED,MAAM,QAAQ,GAAG,SAAS,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAC9C,IAAI,CAAC,YAAY,GAAG,CAAC,IAAI,CAAC,YAAY,GAAG,CAAC,CAAC,GAAG,SAAS,CAAC,MAAM,CAAC;QAE/D,OAAO,QAAQ,CAAC;IAClB,CAAC;CACF"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Weighted strategy: selects providers based on weights (for load balancing or cost-aware selection)
3
+ */
4
+ import { BaseStrategy } from './base.js';
5
+ import type { AIService, SelectionContext } from '../core/interfaces.js';
6
+ export interface WeightedStrategyConfig {
7
+ weights?: Record<string, number>;
8
+ costAware?: boolean;
9
+ }
10
+ export declare class WeightedStrategy extends BaseStrategy {
11
+ private weights;
12
+ private costAware;
13
+ constructor(config?: WeightedStrategyConfig);
14
+ select(providers: AIService[], context?: SelectionContext): Promise<AIService | null>;
15
+ /**
16
+ * Set weight for a provider
17
+ */
18
+ setWeight(providerId: string, weight: number): void;
19
+ }
20
+ //# sourceMappingURL=weighted.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"weighted.d.ts","sourceRoot":"","sources":["../../../src/strategies/weighted.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,KAAK,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAEzE,MAAM,WAAW,sBAAsB;IACrC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,qBAAa,gBAAiB,SAAQ,YAAY;IAChD,OAAO,CAAC,OAAO,CAAkC;IACjD,OAAO,CAAC,SAAS,CAAU;gBAEf,MAAM,CAAC,EAAE,sBAAsB;IAWrC,MAAM,CACV,SAAS,EAAE,SAAS,EAAE,EACtB,OAAO,CAAC,EAAE,gBAAgB,GACzB,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC;IA8C5B;;OAEG;IACH,SAAS,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;CAGpD"}
@@ -0,0 +1,57 @@
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
+ constructor(config) {
7
+ super();
8
+ this.weights = new Map();
9
+ this.costAware = config?.costAware ?? false;
10
+ if (config?.weights) {
11
+ Object.entries(config.weights).forEach(([id, weight]) => {
12
+ this.weights.set(id, weight);
13
+ });
14
+ }
15
+ }
16
+ async select(providers, context) {
17
+ const available = this.filterAttempted(providers, context);
18
+ if (available.length === 0) {
19
+ return null;
20
+ }
21
+ // Calculate effective weights
22
+ const weightedProviders = available.map((provider) => {
23
+ let weight = this.weights.get(provider.id) ?? 1.0;
24
+ // Adjust weight based on cost if cost-aware
25
+ if (this.costAware && provider.metadata.costPerToken) {
26
+ const avgCost = (provider.metadata.costPerToken.prompt +
27
+ provider.metadata.costPerToken.completion) /
28
+ 2;
29
+ // Lower cost = higher weight (inverse relationship)
30
+ weight = weight / (avgCost + 0.0001); // Add small epsilon to avoid division by zero
31
+ }
32
+ return { provider, weight };
33
+ });
34
+ // Calculate total weight
35
+ const totalWeight = weightedProviders.reduce((sum, wp) => sum + wp.weight, 0);
36
+ if (totalWeight === 0) {
37
+ return available[0]; // Fallback to first available
38
+ }
39
+ // Select using weighted random
40
+ let random = Math.random() * totalWeight;
41
+ for (const { provider, weight } of weightedProviders) {
42
+ random -= weight;
43
+ if (random <= 0) {
44
+ return provider;
45
+ }
46
+ }
47
+ // Fallback (shouldn't reach here)
48
+ return available[0];
49
+ }
50
+ /**
51
+ * Set weight for a provider
52
+ */
53
+ setWeight(providerId, weight) {
54
+ this.weights.set(providerId, weight);
55
+ }
56
+ }
57
+ //# 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;IAIhD,YAAY,MAA+B;QACzC,KAAK,EAAE,CAAC;QAJF,YAAO,GAAwB,IAAI,GAAG,EAAE,CAAC;QAK/C,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"}
@@ -148,3 +148,4 @@ async function main() {
148
148
 
149
149
  main().catch(console.error);
150
150
 
151
+
package/package.json CHANGED
@@ -1,18 +1,27 @@
1
1
  {
2
2
  "name": "@ai-orchestration/core",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "Modular AI orchestration framework for multiple LLM providers",
5
5
  "type": "module",
6
- "main": "./dist/index.js",
7
- "types": "./dist/index.d.ts",
6
+ "main": "./dist/cjs/index.js",
7
+ "module": "./dist/esm/index.js",
8
+ "types": "./dist/esm/index.d.ts",
8
9
  "exports": {
9
10
  ".": {
10
- "import": "./dist/index.js",
11
- "types": "./dist/index.d.ts"
11
+ "import": {
12
+ "types": "./dist/esm/index.d.ts",
13
+ "default": "./dist/esm/index.js"
14
+ },
15
+ "require": {
16
+ "types": "./dist/cjs/index.d.ts",
17
+ "default": "./dist/cjs/index.js"
18
+ }
12
19
  }
13
20
  },
14
21
  "scripts": {
15
- "build": "tsc",
22
+ "build": "npm run build:esm && npm run build:cjs",
23
+ "build:esm": "tsc -p tsconfig.esm.json",
24
+ "build:cjs": "tsc -p tsconfig.cjs.json",
16
25
  "dev": "tsc --watch",
17
26
  "test": "node --test --loader tsx tests/**/*.test.ts",
18
27
  "test:local": "npx tsx examples/test-local.ts",
@@ -0,0 +1,9 @@
1
+ {
2
+ "extends": "./tsconfig.json",
3
+ "compilerOptions": {
4
+ "module": "CommonJS",
5
+ "moduleResolution": "node",
6
+ "outDir": "./dist/cjs"
7
+ }
8
+ }
9
+
@@ -0,0 +1,9 @@
1
+ {
2
+ "extends": "./tsconfig.json",
3
+ "compilerOptions": {
4
+ "module": "ESNext",
5
+ "moduleResolution": "bundler",
6
+ "outDir": "./dist/esm"
7
+ }
8
+ }
9
+