@ax-llm/ax 10.0.50 → 11.0.1

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/index.cjs CHANGED
@@ -54,6 +54,7 @@ __export(index_exports, {
54
54
  AxAIMistralModel: () => AxAIMistralModel,
55
55
  AxAIOllama: () => AxAIOllama,
56
56
  AxAIOpenAI: () => AxAIOpenAI,
57
+ AxAIOpenAIBase: () => AxAIOpenAIBase,
57
58
  AxAIOpenAIEmbedModel: () => AxAIOpenAIEmbedModel,
58
59
  AxAIOpenAIModel: () => AxAIOpenAIModel,
59
60
  AxAIReka: () => AxAIReka,
@@ -114,9 +115,9 @@ var import_api2 = require("@opentelemetry/api");
114
115
  function getModelInfo({
115
116
  model,
116
117
  modelInfo,
117
- modelMap = {}
118
+ models
118
119
  }) {
119
- const mappedModel = modelMap?.[model] ?? model;
120
+ const mappedModel = models?.find((v) => v.key === model)?.model ?? model;
120
121
  const exactMatch = modelInfo.find((v) => v.name === model);
121
122
  if (exactMatch) return exactMatch;
122
123
  const normalizedName = mappedModel.replace(/^(anthropic\.|openai\.)/, "").replace(/-latest$/, "").replace(/-\d{8}$/, "").replace(/-v\d+:\d+$/, "").replace(/@\d{8}$/, "").replace(/-\d{2,}(-[a-zA-Z0-9-]+)?$/, "").replace(/-v\d+@\d{8}$/, "").replace(/-v\d+$/, "");
@@ -737,10 +738,10 @@ var AxBaseAI = class {
737
738
  apiURL,
738
739
  headers,
739
740
  modelInfo,
740
- models,
741
+ defaults,
741
742
  options = {},
742
743
  supportFor,
743
- modelMap
744
+ models
744
745
  }) {
745
746
  this.aiImpl = aiImpl;
746
747
  this.name = name;
@@ -749,12 +750,12 @@ var AxBaseAI = class {
749
750
  this.supportFor = supportFor;
750
751
  this.tracer = options.tracer;
751
752
  this.modelInfo = modelInfo;
752
- this.modelMap = modelMap;
753
- this.models = {
754
- model: modelMap?.[models.model] ?? models.model,
755
- embedModel: modelMap?.[models.embedModel ?? ""] ?? models.embedModel
756
- };
757
- if (!models.model || typeof models.model !== "string" || models.model === "") {
753
+ this.models = models;
754
+ this.id = crypto.randomUUID();
755
+ const model = this.models?.find((v) => v.key === defaults.model)?.model ?? defaults.model;
756
+ const embedModel = defaults.embedModel;
757
+ this.defaults = { model, embedModel };
758
+ if (!defaults.model || typeof defaults.model !== "string" || defaults.model === "") {
758
759
  throw new Error("No model defined");
759
760
  }
760
761
  this.setOptions(options);
@@ -763,13 +764,14 @@ var AxBaseAI = class {
763
764
  rt;
764
765
  fetch;
765
766
  tracer;
766
- modelMap;
767
+ models;
767
768
  modelInfo;
768
769
  modelUsage;
769
770
  embedModelUsage;
770
- models;
771
+ defaults;
771
772
  apiURL;
772
773
  name;
774
+ id;
773
775
  headers;
774
776
  supportFor;
775
777
  // Add private metrics tracking properties
@@ -804,6 +806,9 @@ var AxBaseAI = class {
804
806
  setName(name) {
805
807
  this.name = name;
806
808
  }
809
+ getId() {
810
+ return this.id;
811
+ }
807
812
  setAPIURL(apiURL) {
808
813
  this.apiURL = apiURL;
809
814
  }
@@ -834,9 +839,9 @@ var AxBaseAI = class {
834
839
  }
835
840
  getModelInfo() {
836
841
  const mi = getModelInfo({
837
- model: this.models.model,
842
+ model: this.defaults.model,
838
843
  modelInfo: this.modelInfo,
839
- modelMap: this.modelMap
844
+ models: this.models
840
845
  });
841
846
  return {
842
847
  ...mi,
@@ -844,27 +849,26 @@ var AxBaseAI = class {
844
849
  };
845
850
  }
846
851
  getEmbedModelInfo() {
847
- if (!this.models.embedModel) {
852
+ if (!this.defaults.embedModel) {
848
853
  return;
849
854
  }
850
855
  const mi = getModelInfo({
851
- model: this.models.embedModel,
852
- modelInfo: this.modelInfo,
853
- modelMap: this.modelMap
856
+ model: this.defaults.embedModel,
857
+ modelInfo: this.modelInfo
854
858
  });
855
859
  return {
856
860
  ...mi,
857
861
  provider: this.name
858
862
  };
859
863
  }
860
- getModelMap() {
861
- return this.modelMap;
864
+ getModelList() {
865
+ return this.models;
862
866
  }
863
867
  getName() {
864
868
  return this.name;
865
869
  }
866
870
  getFeatures(model) {
867
- return typeof this.supportFor === "function" ? this.supportFor(model ?? this.models.model) : this.supportFor;
871
+ return typeof this.supportFor === "function" ? this.supportFor(model ?? this.defaults.model) : this.supportFor;
868
872
  }
869
873
  // Method to calculate percentiles
870
874
  calculatePercentile(samples, percentile) {
@@ -912,7 +916,7 @@ var AxBaseAI = class {
912
916
  }
913
917
  }
914
918
  async _chat1(req, options) {
915
- const model = req.model ? this.modelMap?.[req.model] ?? req.model : this.modelMap?.[this.models.model] ?? this.models.model;
919
+ const model = req.model ? this.models?.find((v) => v.key === req.model)?.model ?? req.model : this.defaults.model;
916
920
  const modelConfig = {
917
921
  ...this.aiImpl.getModelConfig(),
918
922
  ...req.modelConfig
@@ -1056,7 +1060,7 @@ var AxBaseAI = class {
1056
1060
  }
1057
1061
  }
1058
1062
  async _embed1(req, options) {
1059
- const embedModel = req.embedModel ? this.modelMap?.[req.embedModel] ?? req.embedModel : this.modelMap?.[this.models.embedModel ?? ""] ?? this.models.embedModel;
1063
+ const embedModel = req.embedModel ?? this.defaults.embedModel;
1060
1064
  if (!embedModel) {
1061
1065
  throw new Error("No embed model defined");
1062
1066
  }
@@ -1067,7 +1071,7 @@ var AxBaseAI = class {
1067
1071
  kind: import_api2.SpanKind.SERVER,
1068
1072
  attributes: {
1069
1073
  [axSpanAttributes.LLM_SYSTEM]: this.name,
1070
- [axSpanAttributes.LLM_REQUEST_MODEL]: req.embedModel ?? this.models.embedModel
1074
+ [axSpanAttributes.LLM_REQUEST_MODEL]: embedModel
1071
1075
  }
1072
1076
  },
1073
1077
  async (span) => {
@@ -1246,13 +1250,13 @@ var AxAIAnthropicModel = /* @__PURE__ */ ((AxAIAnthropicModel2) => {
1246
1250
  AxAIAnthropicModel2["ClaudeInstant12"] = "claude-instant-1.2";
1247
1251
  return AxAIAnthropicModel2;
1248
1252
  })(AxAIAnthropicModel || {});
1249
- var AxAIAnthropicVertexModel = /* @__PURE__ */ ((AxAIAnthropicVertexModel2) => {
1250
- AxAIAnthropicVertexModel2["Claude35Haiku"] = "claude-3-5-haiku";
1251
- AxAIAnthropicVertexModel2["Claude35Sonnet"] = "claude-3-5-sonnet";
1252
- AxAIAnthropicVertexModel2["Claude35SonnetV2"] = "claude-3-5-sonnet-v2";
1253
- AxAIAnthropicVertexModel2["Claude3Haiku"] = "claude-3-haiku";
1254
- AxAIAnthropicVertexModel2["Claude3Opus"] = "claude-3-opus";
1255
- return AxAIAnthropicVertexModel2;
1253
+ var AxAIAnthropicVertexModel = /* @__PURE__ */ ((AxAIAnthropicVertexModel3) => {
1254
+ AxAIAnthropicVertexModel3["Claude35Haiku"] = "claude-3-5-haiku";
1255
+ AxAIAnthropicVertexModel3["Claude35Sonnet"] = "claude-3-5-sonnet";
1256
+ AxAIAnthropicVertexModel3["Claude35SonnetV2"] = "claude-3-5-sonnet-v2";
1257
+ AxAIAnthropicVertexModel3["Claude3Haiku"] = "claude-3-haiku";
1258
+ AxAIAnthropicVertexModel3["Claude3Opus"] = "claude-3-opus";
1259
+ return AxAIAnthropicVertexModel3;
1256
1260
  })(AxAIAnthropicVertexModel || {});
1257
1261
 
1258
1262
  // ai/anthropic/info.ts
@@ -1540,7 +1544,7 @@ var AxAIAnthropic = class extends AxBaseAI {
1540
1544
  region,
1541
1545
  config,
1542
1546
  options,
1543
- modelMap
1547
+ models
1544
1548
  }) {
1545
1549
  const isVertex = projectId !== void 0 && region !== void 0;
1546
1550
  let apiURL;
@@ -1576,10 +1580,10 @@ var AxAIAnthropic = class extends AxBaseAI {
1576
1580
  apiURL,
1577
1581
  headers,
1578
1582
  modelInfo: axModelInfoAnthropic,
1579
- models: { model: _config.model },
1583
+ defaults: { model: _config.model },
1580
1584
  options,
1581
- supportFor: { functions: true, streaming: true },
1582
- modelMap
1585
+ supportFor: { functions: true, streaming: true, functionCot: true },
1586
+ models
1583
1587
  });
1584
1588
  }
1585
1589
  };
@@ -2056,51 +2060,70 @@ function createMessages2(req) {
2056
2060
  }
2057
2061
  });
2058
2062
  }
2059
- var AxAIOpenAI = class extends AxBaseAI {
2063
+ var AxAIOpenAIBase = class extends AxBaseAI {
2060
2064
  constructor({
2061
2065
  apiKey,
2062
2066
  config,
2063
2067
  options,
2064
2068
  apiURL,
2065
- modelInfo = axModelInfoOpenAI,
2066
- modelMap
2069
+ modelInfo,
2070
+ models
2067
2071
  }) {
2068
2072
  if (!apiKey || apiKey === "") {
2069
2073
  throw new Error("OpenAI API key not set");
2070
2074
  }
2071
- const _config = {
2072
- ...axAIOpenAIDefaultConfig(),
2073
- ...config
2074
- };
2075
2075
  const aiImpl = new AxAIOpenAIImpl(
2076
- _config,
2076
+ config,
2077
2077
  options?.streamingUsage ?? true,
2078
- config?.dimensions
2078
+ config.dimensions
2079
2079
  );
2080
2080
  super(aiImpl, {
2081
2081
  name: "OpenAI",
2082
2082
  apiURL: apiURL ? apiURL : "https://api.openai.com/v1",
2083
2083
  headers: async () => ({ Authorization: `Bearer ${apiKey}` }),
2084
2084
  modelInfo,
2085
- models: {
2086
- model: _config.model,
2087
- embedModel: _config.embedModel
2085
+ defaults: {
2086
+ model: config.model,
2087
+ embedModel: config.embedModel
2088
2088
  },
2089
2089
  options,
2090
2090
  supportFor: () => {
2091
2091
  return { functions: true, streaming: true };
2092
2092
  },
2093
- modelMap
2093
+ models
2094
2094
  });
2095
2095
  }
2096
2096
  };
2097
2097
  var isReasoningModel = (model) => ["o1-mini" /* O1Mini */, "o1" /* O1 */, "o3-mini" /* O3Mini */].includes(
2098
2098
  model
2099
2099
  );
2100
+ var AxAIOpenAI = class extends AxAIOpenAIBase {
2101
+ constructor({
2102
+ apiKey,
2103
+ config,
2104
+ options,
2105
+ models
2106
+ }) {
2107
+ if (!apiKey || apiKey === "") {
2108
+ throw new Error("OpenAI API key not set");
2109
+ }
2110
+ super({
2111
+ apiKey,
2112
+ config: {
2113
+ ...axAIOpenAIDefaultConfig(),
2114
+ ...config
2115
+ },
2116
+ options,
2117
+ modelInfo: axModelInfoOpenAI,
2118
+ models
2119
+ });
2120
+ super.setName("OpenAI");
2121
+ }
2122
+ };
2100
2123
 
2101
2124
  // ai/azure-openai/api.ts
2102
2125
  var axAIAzureOpenAIDefaultConfig = axAIOpenAIDefaultConfig;
2103
- var AxAIAzureOpenAI = class extends AxAIOpenAI {
2126
+ var AxAIAzureOpenAI = class extends AxAIOpenAIBase {
2104
2127
  constructor({
2105
2128
  apiKey,
2106
2129
  resourceName,
@@ -2108,7 +2131,7 @@ var AxAIAzureOpenAI = class extends AxAIOpenAI {
2108
2131
  version = "api-version=2024-02-15-preview",
2109
2132
  config,
2110
2133
  options,
2111
- modelMap
2134
+ models
2112
2135
  }) {
2113
2136
  if (!apiKey || apiKey === "") {
2114
2137
  throw new Error("Azure OpenAPI API key not set");
@@ -2123,7 +2146,13 @@ var AxAIAzureOpenAI = class extends AxAIOpenAI {
2123
2146
  ...axAIAzureOpenAIDefaultConfig(),
2124
2147
  ...config
2125
2148
  };
2126
- super({ apiKey, config: _config, options, modelMap });
2149
+ super({
2150
+ apiKey,
2151
+ config: _config,
2152
+ options,
2153
+ models,
2154
+ modelInfo: axModelInfoOpenAI
2155
+ });
2127
2156
  const host = resourceName.includes("://") ? resourceName : `https://${resourceName}.openai.azure.com/`;
2128
2157
  super.setName("Azure OpenAI");
2129
2158
  super.setAPIURL(
@@ -2379,7 +2408,7 @@ var AxAICohere = class extends AxBaseAI {
2379
2408
  apiKey,
2380
2409
  config,
2381
2410
  options,
2382
- modelMap
2411
+ models
2383
2412
  }) {
2384
2413
  if (!apiKey || apiKey === "") {
2385
2414
  throw new Error("Cohere API key not set");
@@ -2394,10 +2423,10 @@ var AxAICohere = class extends AxBaseAI {
2394
2423
  apiURL: "https://api.cohere.ai/v1",
2395
2424
  headers: async () => ({ Authorization: `Bearer ${apiKey}` }),
2396
2425
  modelInfo: axModelInfoCohere,
2397
- models: { model: _config.model },
2426
+ defaults: { model: _config.model },
2398
2427
  supportFor: { functions: true, streaming: true },
2399
2428
  options,
2400
- modelMap
2429
+ models
2401
2430
  });
2402
2431
  }
2403
2432
  };
@@ -2486,12 +2515,12 @@ var axAIDeepSeekDefaultConfig = () => structuredClone({
2486
2515
  model: "deepseek-chat" /* DeepSeekChat */,
2487
2516
  ...axBaseAIDefaultConfig()
2488
2517
  });
2489
- var AxAIDeepSeek = class extends AxAIOpenAI {
2518
+ var AxAIDeepSeek = class extends AxAIOpenAIBase {
2490
2519
  constructor({
2491
2520
  apiKey,
2492
2521
  config,
2493
2522
  options,
2494
- modelMap
2523
+ models
2495
2524
  }) {
2496
2525
  if (!apiKey || apiKey === "") {
2497
2526
  throw new Error("DeepSeek API key not set");
@@ -2506,7 +2535,7 @@ var AxAIDeepSeek = class extends AxAIOpenAI {
2506
2535
  options,
2507
2536
  apiURL: "https://api.deepseek.com",
2508
2537
  modelInfo: axModelInfoDeepSeek,
2509
- modelMap
2538
+ models
2510
2539
  });
2511
2540
  super.setName("DeepSeek");
2512
2541
  }
@@ -2514,6 +2543,10 @@ var AxAIDeepSeek = class extends AxAIOpenAI {
2514
2543
 
2515
2544
  // ai/google-gemini/types.ts
2516
2545
  var AxAIGoogleGeminiModel = /* @__PURE__ */ ((AxAIGoogleGeminiModel2) => {
2546
+ AxAIGoogleGeminiModel2["Gemini20Pro"] = "gemini-2.0-pro-exp-02-05";
2547
+ AxAIGoogleGeminiModel2["Gemini20Flash"] = "gemini-2.0-flash";
2548
+ AxAIGoogleGeminiModel2["Gemini20FlashLite"] = "gemini-2.0-flash-lite-preview-02-05";
2549
+ AxAIGoogleGeminiModel2["Gemini20FlashThinking"] = "gemini-2.0-flash-thinking-exp-01-21";
2517
2550
  AxAIGoogleGeminiModel2["Gemini1Pro"] = "gemini-1.0-pro";
2518
2551
  AxAIGoogleGeminiModel2["Gemini15Flash"] = "gemini-1.5-flash";
2519
2552
  AxAIGoogleGeminiModel2["Gemini15Flash8B"] = "gemini-1.5-flash-8b";
@@ -2545,31 +2578,59 @@ var AxAIGoogleGeminiSafetyThreshold = /* @__PURE__ */ ((AxAIGoogleGeminiSafetyTh
2545
2578
 
2546
2579
  // ai/google-gemini/info.ts
2547
2580
  var axModelInfoGoogleGemini = [
2581
+ {
2582
+ name: "gemini-2.0-pro-exp-02-05" /* Gemini20Pro */,
2583
+ currency: "usd",
2584
+ characterIsToken: false,
2585
+ promptTokenCostPer1M: 0,
2586
+ completionTokenCostPer1M: 0
2587
+ },
2588
+ {
2589
+ name: "gemini-2.0-flash" /* Gemini20Flash */,
2590
+ currency: "usd",
2591
+ characterIsToken: false,
2592
+ promptTokenCostPer1M: 0.01,
2593
+ completionTokenCostPer1M: 0.4
2594
+ },
2595
+ {
2596
+ name: "gemini-2.0-flash-lite-preview-02-05" /* Gemini20FlashLite */,
2597
+ currency: "usd",
2598
+ characterIsToken: false,
2599
+ promptTokenCostPer1M: 0,
2600
+ completionTokenCostPer1M: 0
2601
+ },
2602
+ {
2603
+ name: "gemini-2.0-flash-thinking-exp-01-21" /* Gemini20FlashThinking */,
2604
+ currency: "usd",
2605
+ characterIsToken: false,
2606
+ promptTokenCostPer1M: 0,
2607
+ completionTokenCostPer1M: 0
2608
+ },
2548
2609
  {
2549
2610
  name: "gemini-1.5-flash" /* Gemini15Flash */,
2550
2611
  currency: "usd",
2551
- characterIsToken: true,
2612
+ characterIsToken: false,
2552
2613
  promptTokenCostPer1M: 0.075,
2553
2614
  completionTokenCostPer1M: 0.3
2554
2615
  },
2555
2616
  {
2556
2617
  name: "gemini-1.5-flash-8b" /* Gemini15Flash8B */,
2557
2618
  currency: "usd",
2558
- characterIsToken: true,
2619
+ characterIsToken: false,
2559
2620
  promptTokenCostPer1M: 0.0375,
2560
2621
  completionTokenCostPer1M: 0.15
2561
2622
  },
2562
2623
  {
2563
2624
  name: "gemini-1.5-pro" /* Gemini15Pro */,
2564
2625
  currency: "usd",
2565
- characterIsToken: true,
2626
+ characterIsToken: false,
2566
2627
  promptTokenCostPer1M: 1.25,
2567
2628
  completionTokenCostPer1M: 5
2568
2629
  },
2569
2630
  {
2570
2631
  name: "gemini-1.0-pro" /* Gemini1Pro */,
2571
2632
  currency: "usd",
2572
- characterIsToken: true,
2633
+ characterIsToken: false,
2573
2634
  promptTokenCostPer1M: 0.5,
2574
2635
  completionTokenCostPer1M: 1.5
2575
2636
  }
@@ -2883,7 +2944,7 @@ var AxAIGoogleGemini = class extends AxBaseAI {
2883
2944
  region,
2884
2945
  config,
2885
2946
  options,
2886
- modelMap
2947
+ models
2887
2948
  }) {
2888
2949
  const isVertex = projectId !== void 0 && region !== void 0;
2889
2950
  let apiURL;
@@ -2915,13 +2976,13 @@ var AxAIGoogleGemini = class extends AxBaseAI {
2915
2976
  apiURL,
2916
2977
  headers,
2917
2978
  modelInfo: axModelInfoGoogleGemini,
2918
- models: {
2979
+ defaults: {
2919
2980
  model: _config.model,
2920
2981
  embedModel: _config.embedModel
2921
2982
  },
2922
2983
  options,
2923
2984
  supportFor: { functions: true, streaming: true },
2924
- modelMap
2985
+ models
2925
2986
  });
2926
2987
  }
2927
2988
  };
@@ -3018,12 +3079,12 @@ var axAIGroqDefaultConfig = () => structuredClone({
3018
3079
  model: "llama-3.3-70b-versatile" /* Llama33_70B */,
3019
3080
  ...axBaseAIDefaultConfig()
3020
3081
  });
3021
- var AxAIGroq = class extends AxAIOpenAI {
3082
+ var AxAIGroq = class extends AxAIOpenAIBase {
3022
3083
  constructor({
3023
3084
  apiKey,
3024
3085
  config,
3025
3086
  options,
3026
- modelMap
3087
+ models
3027
3088
  }) {
3028
3089
  if (!apiKey || apiKey === "") {
3029
3090
  throw new Error("Groq API key not set");
@@ -3042,7 +3103,7 @@ var AxAIGroq = class extends AxAIOpenAI {
3042
3103
  options: _options,
3043
3104
  modelInfo: axModelInfoGroq,
3044
3105
  apiURL: "https://api.groq.com/openai/v1",
3045
- modelMap
3106
+ models
3046
3107
  });
3047
3108
  super.setName("Groq");
3048
3109
  this.setOptions(_options);
@@ -3166,7 +3227,7 @@ var AxAIHuggingFace = class extends AxBaseAI {
3166
3227
  apiKey,
3167
3228
  config,
3168
3229
  options,
3169
- modelMap
3230
+ models
3170
3231
  }) {
3171
3232
  if (!apiKey || apiKey === "") {
3172
3233
  throw new Error("HuggingFace API key not set");
@@ -3181,10 +3242,10 @@ var AxAIHuggingFace = class extends AxBaseAI {
3181
3242
  apiURL: "https://api-inference.huggingface.co",
3182
3243
  headers: async () => ({ Authorization: `Bearer ${apiKey}` }),
3183
3244
  modelInfo: axModelInfoHuggingFace,
3184
- models: { model: _config.model },
3245
+ defaults: { model: _config.model },
3185
3246
  options,
3186
3247
  supportFor: { functions: false, streaming: false },
3187
- modelMap
3248
+ models
3188
3249
  });
3189
3250
  }
3190
3251
  };
@@ -3263,12 +3324,12 @@ var axAIMistralDefaultConfig = () => structuredClone({
3263
3324
  model: "mistral-small-latest" /* MistralSmall */,
3264
3325
  ...axBaseAIDefaultConfig()
3265
3326
  });
3266
- var AxAIMistral = class extends AxAIOpenAI {
3327
+ var AxAIMistral = class extends AxAIOpenAIBase {
3267
3328
  constructor({
3268
3329
  apiKey,
3269
3330
  config,
3270
3331
  options,
3271
- modelMap
3332
+ models
3272
3333
  }) {
3273
3334
  if (!apiKey || apiKey === "") {
3274
3335
  throw new Error("Mistral API key not set");
@@ -3283,7 +3344,7 @@ var AxAIMistral = class extends AxAIOpenAI {
3283
3344
  options,
3284
3345
  apiURL: "https://api.mistral.ai/v1",
3285
3346
  modelInfo: axModelInfoMistral,
3286
- modelMap
3347
+ models
3287
3348
  });
3288
3349
  super.setName("Mistral");
3289
3350
  }
@@ -3295,13 +3356,13 @@ var axAIOllamaDefaultConfig = () => structuredClone({
3295
3356
  model: "nous-hermes2",
3296
3357
  embedModel: "all-minilm"
3297
3358
  });
3298
- var AxAIOllama = class extends AxAIOpenAI {
3359
+ var AxAIOllama = class extends AxAIOpenAIBase {
3299
3360
  constructor({
3300
3361
  apiKey = "not-set",
3301
3362
  url = "http://localhost:11434/v1",
3302
3363
  config,
3303
3364
  options,
3304
- modelMap
3365
+ models
3305
3366
  }) {
3306
3367
  const _config = {
3307
3368
  ...axAIOllamaDefaultConfig(),
@@ -3312,7 +3373,8 @@ var AxAIOllama = class extends AxAIOpenAI {
3312
3373
  options,
3313
3374
  config: _config,
3314
3375
  apiURL: url,
3315
- modelMap
3376
+ models,
3377
+ modelInfo: []
3316
3378
  });
3317
3379
  super.setName("Ollama");
3318
3380
  }
@@ -3515,7 +3577,7 @@ var AxAIReka = class extends AxBaseAI {
3515
3577
  options,
3516
3578
  apiURL,
3517
3579
  modelInfo = axModelInfoReka,
3518
- modelMap
3580
+ models
3519
3581
  }) {
3520
3582
  if (!apiKey || apiKey === "") {
3521
3583
  throw new Error("Reka API key not set");
@@ -3530,12 +3592,12 @@ var AxAIReka = class extends AxBaseAI {
3530
3592
  apiURL: apiURL ? apiURL : "https://api.reka.ai/v1/chat",
3531
3593
  headers: async () => ({ "X-Api-Key": apiKey }),
3532
3594
  modelInfo,
3533
- models: {
3595
+ defaults: {
3534
3596
  model: _config.model
3535
3597
  },
3536
3598
  options,
3537
3599
  supportFor: { functions: true, streaming: true },
3538
- modelMap
3600
+ models
3539
3601
  });
3540
3602
  }
3541
3603
  };
@@ -3549,12 +3611,12 @@ var axAITogetherDefaultConfig = () => structuredClone({
3549
3611
  model: "mistralai/Mixtral-8x7B-Instruct-v0.1",
3550
3612
  ...axBaseAIDefaultConfig()
3551
3613
  });
3552
- var AxAITogether = class extends AxAIOpenAI {
3614
+ var AxAITogether = class extends AxAIOpenAIBase {
3553
3615
  constructor({
3554
3616
  apiKey,
3555
3617
  config,
3556
3618
  options,
3557
- modelMap
3619
+ models
3558
3620
  }) {
3559
3621
  if (!apiKey || apiKey === "") {
3560
3622
  throw new Error("Together API key not set");
@@ -3569,7 +3631,7 @@ var AxAITogether = class extends AxAIOpenAI {
3569
3631
  options,
3570
3632
  apiURL: "https://api.together.xyz/v1",
3571
3633
  modelInfo: axModelInfoTogether,
3572
- modelMap
3634
+ models
3573
3635
  });
3574
3636
  super.setName("Together");
3575
3637
  }
@@ -3623,6 +3685,9 @@ var AxAI = class {
3623
3685
  getName() {
3624
3686
  return this.ai.getName();
3625
3687
  }
3688
+ getId() {
3689
+ return this.ai.getId();
3690
+ }
3626
3691
  getModelInfo() {
3627
3692
  return this.ai.getModelInfo();
3628
3693
  }
@@ -3632,8 +3697,8 @@ var AxAI = class {
3632
3697
  getFeatures(model) {
3633
3698
  return this.ai.getFeatures(model);
3634
3699
  }
3635
- getModelMap() {
3636
- return this.ai.getModelMap();
3700
+ getModelList() {
3701
+ return this.ai.getModelList();
3637
3702
  }
3638
3703
  getMetrics() {
3639
3704
  return this.ai.getMetrics();
@@ -5766,7 +5831,7 @@ var AxGen = class extends AxProgramWithSignature {
5766
5831
  traceId,
5767
5832
  functions
5768
5833
  }) {
5769
- const streamingValidation = !functions || functions.length == 0;
5834
+ const streamingValidation = ai.getFeatures().functionCot !== true;
5770
5835
  const functionCalls = [];
5771
5836
  const values = {};
5772
5837
  const xstate = {
@@ -6027,6 +6092,7 @@ var AxAgent = class {
6027
6092
  ai;
6028
6093
  signature;
6029
6094
  program;
6095
+ functions;
6030
6096
  agents;
6031
6097
  name;
6032
6098
  description;
@@ -6042,14 +6108,9 @@ var AxAgent = class {
6042
6108
  }, options) {
6043
6109
  this.ai = ai;
6044
6110
  this.agents = agents;
6111
+ this.functions = functions;
6045
6112
  this.signature = new AxSignature(signature);
6046
6113
  this.signature.setDescription(description);
6047
- const funcs = [
6048
- ...functions ?? [],
6049
- ...agents?.map((a) => a.getFunction()) ?? []
6050
- ];
6051
- const opt = { ...options, functions: funcs };
6052
- this.program = new AxGen(this.signature, opt);
6053
6114
  if (!name || name.length < 5) {
6054
6115
  throw new Error(
6055
6116
  `Agent name must be at least 10 characters (more descriptive): ${name}`
@@ -6060,6 +6121,10 @@ var AxAgent = class {
6060
6121
  `Agent description must be at least 20 characters (explain in detail what the agent does): ${description}`
6061
6122
  );
6062
6123
  }
6124
+ this.program = new AxGen(this.signature, options);
6125
+ for (const agent of agents ?? []) {
6126
+ this.program.register(agent);
6127
+ }
6063
6128
  this.name = name;
6064
6129
  this.description = description;
6065
6130
  this.subAgentList = agents?.map((a) => a.getFunction().name).join(", ");
@@ -6069,8 +6134,9 @@ var AxAgent = class {
6069
6134
  parameters: this.signature.toJSONSchema(),
6070
6135
  func: () => this.forward
6071
6136
  };
6072
- for (const agent of agents ?? []) {
6073
- this.program.register(agent);
6137
+ const mm = ai?.getModelList();
6138
+ if (mm) {
6139
+ this.func.parameters = addModelParameter(this.func.parameters, mm);
6074
6140
  }
6075
6141
  }
6076
6142
  setExamples(examples) {
@@ -6096,38 +6162,41 @@ var AxAgent = class {
6096
6162
  }
6097
6163
  getFunction() {
6098
6164
  const boundFunc = this.forward.bind(this);
6099
- const wrappedFunc = (values, options) => {
6165
+ const wrappedFunc = (valuesAndModel, options) => {
6166
+ const { model, ...values } = valuesAndModel;
6100
6167
  const ai = this.ai ?? options?.ai;
6101
6168
  if (!ai) {
6102
6169
  throw new Error("AI service is required to run the agent");
6103
6170
  }
6104
- return boundFunc(ai, values, options);
6171
+ return boundFunc(ai, values, { ...options, model });
6105
6172
  };
6106
6173
  return {
6107
6174
  ...this.func,
6108
6175
  func: wrappedFunc
6109
6176
  };
6110
6177
  }
6111
- init(ai, options) {
6112
- const _ai = this.ai ?? ai;
6113
- const funcs = [
6114
- ...options?.functions ?? [],
6115
- ...this.agents?.map((a) => a.getFunction()) ?? []
6178
+ init(parentAi, options) {
6179
+ const ai = this.ai ?? parentAi;
6180
+ const mm = ai?.getModelList();
6181
+ const agentFuncs = this.agents?.map((a) => a.getFunction())?.map(
6182
+ (f) => mm ? { ...f, parameters: addModelParameter(f.parameters, mm) } : f
6183
+ );
6184
+ const functions = [
6185
+ ...options?.functions ?? this.functions ?? [],
6186
+ ...agentFuncs ?? []
6116
6187
  ];
6117
- const opt = options;
6118
- if (funcs.length > 0) {
6119
- const opt2 = { ...options, functions: funcs };
6120
- this.program = new AxGen(this.signature, opt2);
6121
- }
6122
- return { _ai, opt };
6188
+ return { ai, functions };
6123
6189
  }
6124
- async forward(ai, values, options) {
6125
- const { _ai, opt } = this.init(ai, options);
6126
- return await this.program.forward(_ai, values, opt);
6190
+ async forward(parentAi, values, options) {
6191
+ const { ai, functions } = this.init(parentAi, options);
6192
+ return await this.program.forward(ai, values, { ...options, functions });
6127
6193
  }
6128
- async *streamingForward(ai, values, options) {
6129
- const { _ai, opt } = this.init(ai, options);
6130
- return yield* this.program.streamingForward(_ai, values, opt);
6194
+ async *streamingForward(parentAi, values, options) {
6195
+ const { ai, functions } = this.init(parentAi, options);
6196
+ return yield* this.program.streamingForward(ai, values, {
6197
+ ...options,
6198
+ functions
6199
+ });
6131
6200
  }
6132
6201
  };
6133
6202
  function toCamelCase(inputString) {
@@ -6141,6 +6210,31 @@ function toCamelCase(inputString) {
6141
6210
  }).join("");
6142
6211
  return camelCaseString;
6143
6212
  }
6213
+ function addModelParameter(parameters, models) {
6214
+ const baseSchema = parameters ? structuredClone(parameters) : {
6215
+ type: "object",
6216
+ properties: {},
6217
+ required: []
6218
+ };
6219
+ if (baseSchema.properties?.model) {
6220
+ return baseSchema;
6221
+ }
6222
+ const modelProperty = {
6223
+ type: "string",
6224
+ enum: models.map((m) => m.key),
6225
+ description: `The AI model to use for this function call. Available options: ${models.map((m) => `${m.key}: ${m.description}`).join(" | ")}`
6226
+ };
6227
+ const newProperties = {
6228
+ ...baseSchema.properties ?? {},
6229
+ model: modelProperty
6230
+ };
6231
+ const newRequired = [...baseSchema.required ?? [], "model"];
6232
+ return {
6233
+ ...baseSchema,
6234
+ properties: newProperties,
6235
+ required: newRequired
6236
+ };
6237
+ }
6144
6238
 
6145
6239
  // docs/tika.ts
6146
6240
  var import_node_fs = require("fs");
@@ -6195,6 +6289,10 @@ var AxBalancer = class _AxBalancer {
6195
6289
  currentServiceIndex = 0;
6196
6290
  currentService;
6197
6291
  debug;
6292
+ initialBackoffMs;
6293
+ maxBackoffMs;
6294
+ maxRetries;
6295
+ serviceFailures = /* @__PURE__ */ new Map();
6198
6296
  constructor(services, options) {
6199
6297
  if (services.length === 0) {
6200
6298
  throw new Error("No AI services provided.");
@@ -6208,6 +6306,9 @@ var AxBalancer = class _AxBalancer {
6208
6306
  }
6209
6307
  this.currentService = cs;
6210
6308
  this.debug = options?.debug ?? true;
6309
+ this.initialBackoffMs = options?.initialBackoffMs ?? 1e3;
6310
+ this.maxBackoffMs = options?.maxBackoffMs ?? 32e3;
6311
+ this.maxRetries = options?.maxRetries ?? 3;
6211
6312
  }
6212
6313
  /**
6213
6314
  * Service comparator that respects the input order of services.
@@ -6223,8 +6324,8 @@ var AxBalancer = class _AxBalancer {
6223
6324
  const bTotalCost = (bInfo.promptTokenCostPer1M || Infinity) + (bInfo.completionTokenCostPer1M || Infinity);
6224
6325
  return aTotalCost - bTotalCost;
6225
6326
  };
6226
- getModelMap() {
6227
- throw new Error("Method not implemented.");
6327
+ getModelList() {
6328
+ return this.currentService.getModelList();
6228
6329
  }
6229
6330
  getNextService() {
6230
6331
  const cs = this.services[++this.currentServiceIndex];
@@ -6245,6 +6346,9 @@ var AxBalancer = class _AxBalancer {
6245
6346
  getName() {
6246
6347
  return this.currentService.getName();
6247
6348
  }
6349
+ getId() {
6350
+ return this.currentService.getId();
6351
+ }
6248
6352
  getModelInfo() {
6249
6353
  return this.currentService.getModelInfo();
6250
6354
  }
@@ -6257,11 +6361,56 @@ var AxBalancer = class _AxBalancer {
6257
6361
  getMetrics() {
6258
6362
  return this.currentService.getMetrics();
6259
6363
  }
6364
+ canRetryService() {
6365
+ const failure = this.serviceFailures.get(this.currentService.getId());
6366
+ if (!failure) return true;
6367
+ const { retries, lastFailureTime } = failure;
6368
+ const timeSinceLastFailure = Date.now() - lastFailureTime;
6369
+ const backoffMs = Math.min(
6370
+ this.initialBackoffMs * Math.pow(2, retries),
6371
+ this.maxBackoffMs
6372
+ );
6373
+ return timeSinceLastFailure >= backoffMs;
6374
+ }
6375
+ handleFailure() {
6376
+ const failure = this.serviceFailures.get(this.currentService.getId());
6377
+ const retries = (failure?.retries ?? 0) + 1;
6378
+ this.serviceFailures.set(this.currentService.getId(), {
6379
+ retries,
6380
+ lastFailureTime: Date.now()
6381
+ });
6382
+ if (this.debug) {
6383
+ console.warn(
6384
+ `AxBalancer: Service ${this.currentService.getName()} failed (retry ${retries}/${this.maxRetries})`
6385
+ );
6386
+ }
6387
+ if (retries >= this.maxRetries) {
6388
+ const gotNextService = this.getNextService();
6389
+ if (this.debug) {
6390
+ console.warn(
6391
+ `AxBalancer: Switching to service ${this.currentService.getName()}`
6392
+ );
6393
+ }
6394
+ return gotNextService;
6395
+ }
6396
+ return true;
6397
+ }
6398
+ handleSuccess() {
6399
+ this.serviceFailures.delete(this.currentService.getId());
6400
+ }
6260
6401
  async chat(req, options) {
6261
6402
  this.reset();
6262
6403
  while (true) {
6404
+ if (!this.canRetryService()) {
6405
+ if (!this.getNextService()) {
6406
+ throw new Error("All services exhausted");
6407
+ }
6408
+ continue;
6409
+ }
6263
6410
  try {
6264
- return await this.currentService.chat(req, options);
6411
+ const response = await this.currentService.chat(req, options);
6412
+ this.handleSuccess();
6413
+ return response;
6265
6414
  } catch (e) {
6266
6415
  if (!(e instanceof AxAIServiceError)) {
6267
6416
  throw e;
@@ -6282,38 +6431,29 @@ var AxBalancer = class _AxBalancer {
6282
6431
  default:
6283
6432
  throw e;
6284
6433
  }
6285
- if (this.debug) {
6286
- console.warn(
6287
- `AxBalancer: Service ${this.currentService.getName()} failed`,
6288
- e
6289
- );
6290
- }
6291
- if (!this.getNextService()) {
6434
+ if (!this.handleFailure()) {
6292
6435
  throw e;
6293
6436
  }
6294
- if (this.debug) {
6295
- console.warn(
6296
- `AxBalancer: Switching to service ${this.currentService.getName()}`
6297
- );
6298
- }
6299
6437
  }
6300
6438
  }
6301
6439
  }
6302
6440
  async embed(req, options) {
6303
6441
  this.reset();
6304
6442
  while (true) {
6443
+ if (!this.canRetryService()) {
6444
+ if (!this.getNextService()) {
6445
+ throw new Error("All services exhausted");
6446
+ }
6447
+ continue;
6448
+ }
6305
6449
  try {
6306
- return await this.currentService.embed(req, options);
6450
+ const response = await this.currentService.embed(req, options);
6451
+ this.handleSuccess();
6452
+ return response;
6307
6453
  } catch (e) {
6308
- if (this.debug) {
6309
- console.warn(`Service ${this.currentService.getName()} failed`);
6310
- }
6311
- if (!this.getNextService()) {
6454
+ if (!this.handleFailure()) {
6312
6455
  throw e;
6313
6456
  }
6314
- if (this.debug) {
6315
- console.warn(`Switching to service ${this.currentService.getName()}`);
6316
- }
6317
6457
  }
6318
6458
  }
6319
6459
  }
@@ -7806,6 +7946,7 @@ var AxEmbeddingAdapter = class {
7806
7946
  var AxMockAIService = class {
7807
7947
  constructor(config = {}) {
7808
7948
  this.config = config;
7949
+ this.config.id = this.config.id ?? crypto.randomUUID();
7809
7950
  }
7810
7951
  options = {};
7811
7952
  metrics = {
@@ -7821,6 +7962,9 @@ var AxMockAIService = class {
7821
7962
  getName() {
7822
7963
  return this.config.name ?? "mock-ai-service";
7823
7964
  }
7965
+ getId() {
7966
+ return this.config.id ?? "mock-ai-service-id";
7967
+ }
7824
7968
  getModelInfo() {
7825
7969
  return {
7826
7970
  name: "mock-model",
@@ -7840,8 +7984,8 @@ var AxMockAIService = class {
7840
7984
  streaming: this.config.features?.streaming ?? false
7841
7985
  };
7842
7986
  }
7843
- getModelMap() {
7844
- return this.config.modelMap;
7987
+ getModelList() {
7988
+ return this.config.models;
7845
7989
  }
7846
7990
  getMetrics() {
7847
7991
  return this.metrics;
@@ -7977,6 +8121,7 @@ var AxRAG = class extends AxChainOfThought {
7977
8121
  AxAIMistralModel,
7978
8122
  AxAIOllama,
7979
8123
  AxAIOpenAI,
8124
+ AxAIOpenAIBase,
7980
8125
  AxAIOpenAIEmbedModel,
7981
8126
  AxAIOpenAIModel,
7982
8127
  AxAIReka,