@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.js CHANGED
@@ -5,9 +5,9 @@ import { SpanKind } from "@opentelemetry/api";
5
5
  function getModelInfo({
6
6
  model,
7
7
  modelInfo,
8
- modelMap = {}
8
+ models
9
9
  }) {
10
- const mappedModel = modelMap?.[model] ?? model;
10
+ const mappedModel = models?.find((v) => v.key === model)?.model ?? model;
11
11
  const exactMatch = modelInfo.find((v) => v.name === model);
12
12
  if (exactMatch) return exactMatch;
13
13
  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+$/, "");
@@ -636,10 +636,10 @@ var AxBaseAI = class {
636
636
  apiURL,
637
637
  headers,
638
638
  modelInfo,
639
- models,
639
+ defaults,
640
640
  options = {},
641
641
  supportFor,
642
- modelMap
642
+ models
643
643
  }) {
644
644
  this.aiImpl = aiImpl;
645
645
  this.name = name;
@@ -648,12 +648,12 @@ var AxBaseAI = class {
648
648
  this.supportFor = supportFor;
649
649
  this.tracer = options.tracer;
650
650
  this.modelInfo = modelInfo;
651
- this.modelMap = modelMap;
652
- this.models = {
653
- model: modelMap?.[models.model] ?? models.model,
654
- embedModel: modelMap?.[models.embedModel ?? ""] ?? models.embedModel
655
- };
656
- if (!models.model || typeof models.model !== "string" || models.model === "") {
651
+ this.models = models;
652
+ this.id = crypto.randomUUID();
653
+ const model = this.models?.find((v) => v.key === defaults.model)?.model ?? defaults.model;
654
+ const embedModel = defaults.embedModel;
655
+ this.defaults = { model, embedModel };
656
+ if (!defaults.model || typeof defaults.model !== "string" || defaults.model === "") {
657
657
  throw new Error("No model defined");
658
658
  }
659
659
  this.setOptions(options);
@@ -662,13 +662,14 @@ var AxBaseAI = class {
662
662
  rt;
663
663
  fetch;
664
664
  tracer;
665
- modelMap;
665
+ models;
666
666
  modelInfo;
667
667
  modelUsage;
668
668
  embedModelUsage;
669
- models;
669
+ defaults;
670
670
  apiURL;
671
671
  name;
672
+ id;
672
673
  headers;
673
674
  supportFor;
674
675
  // Add private metrics tracking properties
@@ -703,6 +704,9 @@ var AxBaseAI = class {
703
704
  setName(name) {
704
705
  this.name = name;
705
706
  }
707
+ getId() {
708
+ return this.id;
709
+ }
706
710
  setAPIURL(apiURL) {
707
711
  this.apiURL = apiURL;
708
712
  }
@@ -733,9 +737,9 @@ var AxBaseAI = class {
733
737
  }
734
738
  getModelInfo() {
735
739
  const mi = getModelInfo({
736
- model: this.models.model,
740
+ model: this.defaults.model,
737
741
  modelInfo: this.modelInfo,
738
- modelMap: this.modelMap
742
+ models: this.models
739
743
  });
740
744
  return {
741
745
  ...mi,
@@ -743,27 +747,26 @@ var AxBaseAI = class {
743
747
  };
744
748
  }
745
749
  getEmbedModelInfo() {
746
- if (!this.models.embedModel) {
750
+ if (!this.defaults.embedModel) {
747
751
  return;
748
752
  }
749
753
  const mi = getModelInfo({
750
- model: this.models.embedModel,
751
- modelInfo: this.modelInfo,
752
- modelMap: this.modelMap
754
+ model: this.defaults.embedModel,
755
+ modelInfo: this.modelInfo
753
756
  });
754
757
  return {
755
758
  ...mi,
756
759
  provider: this.name
757
760
  };
758
761
  }
759
- getModelMap() {
760
- return this.modelMap;
762
+ getModelList() {
763
+ return this.models;
761
764
  }
762
765
  getName() {
763
766
  return this.name;
764
767
  }
765
768
  getFeatures(model) {
766
- return typeof this.supportFor === "function" ? this.supportFor(model ?? this.models.model) : this.supportFor;
769
+ return typeof this.supportFor === "function" ? this.supportFor(model ?? this.defaults.model) : this.supportFor;
767
770
  }
768
771
  // Method to calculate percentiles
769
772
  calculatePercentile(samples, percentile) {
@@ -811,7 +814,7 @@ var AxBaseAI = class {
811
814
  }
812
815
  }
813
816
  async _chat1(req, options) {
814
- const model = req.model ? this.modelMap?.[req.model] ?? req.model : this.modelMap?.[this.models.model] ?? this.models.model;
817
+ const model = req.model ? this.models?.find((v) => v.key === req.model)?.model ?? req.model : this.defaults.model;
815
818
  const modelConfig = {
816
819
  ...this.aiImpl.getModelConfig(),
817
820
  ...req.modelConfig
@@ -955,7 +958,7 @@ var AxBaseAI = class {
955
958
  }
956
959
  }
957
960
  async _embed1(req, options) {
958
- const embedModel = req.embedModel ? this.modelMap?.[req.embedModel] ?? req.embedModel : this.modelMap?.[this.models.embedModel ?? ""] ?? this.models.embedModel;
961
+ const embedModel = req.embedModel ?? this.defaults.embedModel;
959
962
  if (!embedModel) {
960
963
  throw new Error("No embed model defined");
961
964
  }
@@ -966,7 +969,7 @@ var AxBaseAI = class {
966
969
  kind: SpanKind.SERVER,
967
970
  attributes: {
968
971
  [axSpanAttributes.LLM_SYSTEM]: this.name,
969
- [axSpanAttributes.LLM_REQUEST_MODEL]: req.embedModel ?? this.models.embedModel
972
+ [axSpanAttributes.LLM_REQUEST_MODEL]: embedModel
970
973
  }
971
974
  },
972
975
  async (span) => {
@@ -1145,13 +1148,13 @@ var AxAIAnthropicModel = /* @__PURE__ */ ((AxAIAnthropicModel2) => {
1145
1148
  AxAIAnthropicModel2["ClaudeInstant12"] = "claude-instant-1.2";
1146
1149
  return AxAIAnthropicModel2;
1147
1150
  })(AxAIAnthropicModel || {});
1148
- var AxAIAnthropicVertexModel = /* @__PURE__ */ ((AxAIAnthropicVertexModel2) => {
1149
- AxAIAnthropicVertexModel2["Claude35Haiku"] = "claude-3-5-haiku";
1150
- AxAIAnthropicVertexModel2["Claude35Sonnet"] = "claude-3-5-sonnet";
1151
- AxAIAnthropicVertexModel2["Claude35SonnetV2"] = "claude-3-5-sonnet-v2";
1152
- AxAIAnthropicVertexModel2["Claude3Haiku"] = "claude-3-haiku";
1153
- AxAIAnthropicVertexModel2["Claude3Opus"] = "claude-3-opus";
1154
- return AxAIAnthropicVertexModel2;
1151
+ var AxAIAnthropicVertexModel = /* @__PURE__ */ ((AxAIAnthropicVertexModel3) => {
1152
+ AxAIAnthropicVertexModel3["Claude35Haiku"] = "claude-3-5-haiku";
1153
+ AxAIAnthropicVertexModel3["Claude35Sonnet"] = "claude-3-5-sonnet";
1154
+ AxAIAnthropicVertexModel3["Claude35SonnetV2"] = "claude-3-5-sonnet-v2";
1155
+ AxAIAnthropicVertexModel3["Claude3Haiku"] = "claude-3-haiku";
1156
+ AxAIAnthropicVertexModel3["Claude3Opus"] = "claude-3-opus";
1157
+ return AxAIAnthropicVertexModel3;
1155
1158
  })(AxAIAnthropicVertexModel || {});
1156
1159
 
1157
1160
  // ai/anthropic/info.ts
@@ -1439,7 +1442,7 @@ var AxAIAnthropic = class extends AxBaseAI {
1439
1442
  region,
1440
1443
  config,
1441
1444
  options,
1442
- modelMap
1445
+ models
1443
1446
  }) {
1444
1447
  const isVertex = projectId !== void 0 && region !== void 0;
1445
1448
  let apiURL;
@@ -1475,10 +1478,10 @@ var AxAIAnthropic = class extends AxBaseAI {
1475
1478
  apiURL,
1476
1479
  headers,
1477
1480
  modelInfo: axModelInfoAnthropic,
1478
- models: { model: _config.model },
1481
+ defaults: { model: _config.model },
1479
1482
  options,
1480
- supportFor: { functions: true, streaming: true },
1481
- modelMap
1483
+ supportFor: { functions: true, streaming: true, functionCot: true },
1484
+ models
1482
1485
  });
1483
1486
  }
1484
1487
  };
@@ -1955,51 +1958,70 @@ function createMessages2(req) {
1955
1958
  }
1956
1959
  });
1957
1960
  }
1958
- var AxAIOpenAI = class extends AxBaseAI {
1961
+ var AxAIOpenAIBase = class extends AxBaseAI {
1959
1962
  constructor({
1960
1963
  apiKey,
1961
1964
  config,
1962
1965
  options,
1963
1966
  apiURL,
1964
- modelInfo = axModelInfoOpenAI,
1965
- modelMap
1967
+ modelInfo,
1968
+ models
1966
1969
  }) {
1967
1970
  if (!apiKey || apiKey === "") {
1968
1971
  throw new Error("OpenAI API key not set");
1969
1972
  }
1970
- const _config = {
1971
- ...axAIOpenAIDefaultConfig(),
1972
- ...config
1973
- };
1974
1973
  const aiImpl = new AxAIOpenAIImpl(
1975
- _config,
1974
+ config,
1976
1975
  options?.streamingUsage ?? true,
1977
- config?.dimensions
1976
+ config.dimensions
1978
1977
  );
1979
1978
  super(aiImpl, {
1980
1979
  name: "OpenAI",
1981
1980
  apiURL: apiURL ? apiURL : "https://api.openai.com/v1",
1982
1981
  headers: async () => ({ Authorization: `Bearer ${apiKey}` }),
1983
1982
  modelInfo,
1984
- models: {
1985
- model: _config.model,
1986
- embedModel: _config.embedModel
1983
+ defaults: {
1984
+ model: config.model,
1985
+ embedModel: config.embedModel
1987
1986
  },
1988
1987
  options,
1989
1988
  supportFor: () => {
1990
1989
  return { functions: true, streaming: true };
1991
1990
  },
1992
- modelMap
1991
+ models
1993
1992
  });
1994
1993
  }
1995
1994
  };
1996
1995
  var isReasoningModel = (model) => ["o1-mini" /* O1Mini */, "o1" /* O1 */, "o3-mini" /* O3Mini */].includes(
1997
1996
  model
1998
1997
  );
1998
+ var AxAIOpenAI = class extends AxAIOpenAIBase {
1999
+ constructor({
2000
+ apiKey,
2001
+ config,
2002
+ options,
2003
+ models
2004
+ }) {
2005
+ if (!apiKey || apiKey === "") {
2006
+ throw new Error("OpenAI API key not set");
2007
+ }
2008
+ super({
2009
+ apiKey,
2010
+ config: {
2011
+ ...axAIOpenAIDefaultConfig(),
2012
+ ...config
2013
+ },
2014
+ options,
2015
+ modelInfo: axModelInfoOpenAI,
2016
+ models
2017
+ });
2018
+ super.setName("OpenAI");
2019
+ }
2020
+ };
1999
2021
 
2000
2022
  // ai/azure-openai/api.ts
2001
2023
  var axAIAzureOpenAIDefaultConfig = axAIOpenAIDefaultConfig;
2002
- var AxAIAzureOpenAI = class extends AxAIOpenAI {
2024
+ var AxAIAzureOpenAI = class extends AxAIOpenAIBase {
2003
2025
  constructor({
2004
2026
  apiKey,
2005
2027
  resourceName,
@@ -2007,7 +2029,7 @@ var AxAIAzureOpenAI = class extends AxAIOpenAI {
2007
2029
  version = "api-version=2024-02-15-preview",
2008
2030
  config,
2009
2031
  options,
2010
- modelMap
2032
+ models
2011
2033
  }) {
2012
2034
  if (!apiKey || apiKey === "") {
2013
2035
  throw new Error("Azure OpenAPI API key not set");
@@ -2022,7 +2044,13 @@ var AxAIAzureOpenAI = class extends AxAIOpenAI {
2022
2044
  ...axAIAzureOpenAIDefaultConfig(),
2023
2045
  ...config
2024
2046
  };
2025
- super({ apiKey, config: _config, options, modelMap });
2047
+ super({
2048
+ apiKey,
2049
+ config: _config,
2050
+ options,
2051
+ models,
2052
+ modelInfo: axModelInfoOpenAI
2053
+ });
2026
2054
  const host = resourceName.includes("://") ? resourceName : `https://${resourceName}.openai.azure.com/`;
2027
2055
  super.setName("Azure OpenAI");
2028
2056
  super.setAPIURL(
@@ -2278,7 +2306,7 @@ var AxAICohere = class extends AxBaseAI {
2278
2306
  apiKey,
2279
2307
  config,
2280
2308
  options,
2281
- modelMap
2309
+ models
2282
2310
  }) {
2283
2311
  if (!apiKey || apiKey === "") {
2284
2312
  throw new Error("Cohere API key not set");
@@ -2293,10 +2321,10 @@ var AxAICohere = class extends AxBaseAI {
2293
2321
  apiURL: "https://api.cohere.ai/v1",
2294
2322
  headers: async () => ({ Authorization: `Bearer ${apiKey}` }),
2295
2323
  modelInfo: axModelInfoCohere,
2296
- models: { model: _config.model },
2324
+ defaults: { model: _config.model },
2297
2325
  supportFor: { functions: true, streaming: true },
2298
2326
  options,
2299
- modelMap
2327
+ models
2300
2328
  });
2301
2329
  }
2302
2330
  };
@@ -2385,12 +2413,12 @@ var axAIDeepSeekDefaultConfig = () => structuredClone({
2385
2413
  model: "deepseek-chat" /* DeepSeekChat */,
2386
2414
  ...axBaseAIDefaultConfig()
2387
2415
  });
2388
- var AxAIDeepSeek = class extends AxAIOpenAI {
2416
+ var AxAIDeepSeek = class extends AxAIOpenAIBase {
2389
2417
  constructor({
2390
2418
  apiKey,
2391
2419
  config,
2392
2420
  options,
2393
- modelMap
2421
+ models
2394
2422
  }) {
2395
2423
  if (!apiKey || apiKey === "") {
2396
2424
  throw new Error("DeepSeek API key not set");
@@ -2405,7 +2433,7 @@ var AxAIDeepSeek = class extends AxAIOpenAI {
2405
2433
  options,
2406
2434
  apiURL: "https://api.deepseek.com",
2407
2435
  modelInfo: axModelInfoDeepSeek,
2408
- modelMap
2436
+ models
2409
2437
  });
2410
2438
  super.setName("DeepSeek");
2411
2439
  }
@@ -2413,6 +2441,10 @@ var AxAIDeepSeek = class extends AxAIOpenAI {
2413
2441
 
2414
2442
  // ai/google-gemini/types.ts
2415
2443
  var AxAIGoogleGeminiModel = /* @__PURE__ */ ((AxAIGoogleGeminiModel2) => {
2444
+ AxAIGoogleGeminiModel2["Gemini20Pro"] = "gemini-2.0-pro-exp-02-05";
2445
+ AxAIGoogleGeminiModel2["Gemini20Flash"] = "gemini-2.0-flash";
2446
+ AxAIGoogleGeminiModel2["Gemini20FlashLite"] = "gemini-2.0-flash-lite-preview-02-05";
2447
+ AxAIGoogleGeminiModel2["Gemini20FlashThinking"] = "gemini-2.0-flash-thinking-exp-01-21";
2416
2448
  AxAIGoogleGeminiModel2["Gemini1Pro"] = "gemini-1.0-pro";
2417
2449
  AxAIGoogleGeminiModel2["Gemini15Flash"] = "gemini-1.5-flash";
2418
2450
  AxAIGoogleGeminiModel2["Gemini15Flash8B"] = "gemini-1.5-flash-8b";
@@ -2444,31 +2476,59 @@ var AxAIGoogleGeminiSafetyThreshold = /* @__PURE__ */ ((AxAIGoogleGeminiSafetyTh
2444
2476
 
2445
2477
  // ai/google-gemini/info.ts
2446
2478
  var axModelInfoGoogleGemini = [
2479
+ {
2480
+ name: "gemini-2.0-pro-exp-02-05" /* Gemini20Pro */,
2481
+ currency: "usd",
2482
+ characterIsToken: false,
2483
+ promptTokenCostPer1M: 0,
2484
+ completionTokenCostPer1M: 0
2485
+ },
2486
+ {
2487
+ name: "gemini-2.0-flash" /* Gemini20Flash */,
2488
+ currency: "usd",
2489
+ characterIsToken: false,
2490
+ promptTokenCostPer1M: 0.01,
2491
+ completionTokenCostPer1M: 0.4
2492
+ },
2493
+ {
2494
+ name: "gemini-2.0-flash-lite-preview-02-05" /* Gemini20FlashLite */,
2495
+ currency: "usd",
2496
+ characterIsToken: false,
2497
+ promptTokenCostPer1M: 0,
2498
+ completionTokenCostPer1M: 0
2499
+ },
2500
+ {
2501
+ name: "gemini-2.0-flash-thinking-exp-01-21" /* Gemini20FlashThinking */,
2502
+ currency: "usd",
2503
+ characterIsToken: false,
2504
+ promptTokenCostPer1M: 0,
2505
+ completionTokenCostPer1M: 0
2506
+ },
2447
2507
  {
2448
2508
  name: "gemini-1.5-flash" /* Gemini15Flash */,
2449
2509
  currency: "usd",
2450
- characterIsToken: true,
2510
+ characterIsToken: false,
2451
2511
  promptTokenCostPer1M: 0.075,
2452
2512
  completionTokenCostPer1M: 0.3
2453
2513
  },
2454
2514
  {
2455
2515
  name: "gemini-1.5-flash-8b" /* Gemini15Flash8B */,
2456
2516
  currency: "usd",
2457
- characterIsToken: true,
2517
+ characterIsToken: false,
2458
2518
  promptTokenCostPer1M: 0.0375,
2459
2519
  completionTokenCostPer1M: 0.15
2460
2520
  },
2461
2521
  {
2462
2522
  name: "gemini-1.5-pro" /* Gemini15Pro */,
2463
2523
  currency: "usd",
2464
- characterIsToken: true,
2524
+ characterIsToken: false,
2465
2525
  promptTokenCostPer1M: 1.25,
2466
2526
  completionTokenCostPer1M: 5
2467
2527
  },
2468
2528
  {
2469
2529
  name: "gemini-1.0-pro" /* Gemini1Pro */,
2470
2530
  currency: "usd",
2471
- characterIsToken: true,
2531
+ characterIsToken: false,
2472
2532
  promptTokenCostPer1M: 0.5,
2473
2533
  completionTokenCostPer1M: 1.5
2474
2534
  }
@@ -2782,7 +2842,7 @@ var AxAIGoogleGemini = class extends AxBaseAI {
2782
2842
  region,
2783
2843
  config,
2784
2844
  options,
2785
- modelMap
2845
+ models
2786
2846
  }) {
2787
2847
  const isVertex = projectId !== void 0 && region !== void 0;
2788
2848
  let apiURL;
@@ -2814,13 +2874,13 @@ var AxAIGoogleGemini = class extends AxBaseAI {
2814
2874
  apiURL,
2815
2875
  headers,
2816
2876
  modelInfo: axModelInfoGoogleGemini,
2817
- models: {
2877
+ defaults: {
2818
2878
  model: _config.model,
2819
2879
  embedModel: _config.embedModel
2820
2880
  },
2821
2881
  options,
2822
2882
  supportFor: { functions: true, streaming: true },
2823
- modelMap
2883
+ models
2824
2884
  });
2825
2885
  }
2826
2886
  };
@@ -2917,12 +2977,12 @@ var axAIGroqDefaultConfig = () => structuredClone({
2917
2977
  model: "llama-3.3-70b-versatile" /* Llama33_70B */,
2918
2978
  ...axBaseAIDefaultConfig()
2919
2979
  });
2920
- var AxAIGroq = class extends AxAIOpenAI {
2980
+ var AxAIGroq = class extends AxAIOpenAIBase {
2921
2981
  constructor({
2922
2982
  apiKey,
2923
2983
  config,
2924
2984
  options,
2925
- modelMap
2985
+ models
2926
2986
  }) {
2927
2987
  if (!apiKey || apiKey === "") {
2928
2988
  throw new Error("Groq API key not set");
@@ -2941,7 +3001,7 @@ var AxAIGroq = class extends AxAIOpenAI {
2941
3001
  options: _options,
2942
3002
  modelInfo: axModelInfoGroq,
2943
3003
  apiURL: "https://api.groq.com/openai/v1",
2944
- modelMap
3004
+ models
2945
3005
  });
2946
3006
  super.setName("Groq");
2947
3007
  this.setOptions(_options);
@@ -3065,7 +3125,7 @@ var AxAIHuggingFace = class extends AxBaseAI {
3065
3125
  apiKey,
3066
3126
  config,
3067
3127
  options,
3068
- modelMap
3128
+ models
3069
3129
  }) {
3070
3130
  if (!apiKey || apiKey === "") {
3071
3131
  throw new Error("HuggingFace API key not set");
@@ -3080,10 +3140,10 @@ var AxAIHuggingFace = class extends AxBaseAI {
3080
3140
  apiURL: "https://api-inference.huggingface.co",
3081
3141
  headers: async () => ({ Authorization: `Bearer ${apiKey}` }),
3082
3142
  modelInfo: axModelInfoHuggingFace,
3083
- models: { model: _config.model },
3143
+ defaults: { model: _config.model },
3084
3144
  options,
3085
3145
  supportFor: { functions: false, streaming: false },
3086
- modelMap
3146
+ models
3087
3147
  });
3088
3148
  }
3089
3149
  };
@@ -3162,12 +3222,12 @@ var axAIMistralDefaultConfig = () => structuredClone({
3162
3222
  model: "mistral-small-latest" /* MistralSmall */,
3163
3223
  ...axBaseAIDefaultConfig()
3164
3224
  });
3165
- var AxAIMistral = class extends AxAIOpenAI {
3225
+ var AxAIMistral = class extends AxAIOpenAIBase {
3166
3226
  constructor({
3167
3227
  apiKey,
3168
3228
  config,
3169
3229
  options,
3170
- modelMap
3230
+ models
3171
3231
  }) {
3172
3232
  if (!apiKey || apiKey === "") {
3173
3233
  throw new Error("Mistral API key not set");
@@ -3182,7 +3242,7 @@ var AxAIMistral = class extends AxAIOpenAI {
3182
3242
  options,
3183
3243
  apiURL: "https://api.mistral.ai/v1",
3184
3244
  modelInfo: axModelInfoMistral,
3185
- modelMap
3245
+ models
3186
3246
  });
3187
3247
  super.setName("Mistral");
3188
3248
  }
@@ -3194,13 +3254,13 @@ var axAIOllamaDefaultConfig = () => structuredClone({
3194
3254
  model: "nous-hermes2",
3195
3255
  embedModel: "all-minilm"
3196
3256
  });
3197
- var AxAIOllama = class extends AxAIOpenAI {
3257
+ var AxAIOllama = class extends AxAIOpenAIBase {
3198
3258
  constructor({
3199
3259
  apiKey = "not-set",
3200
3260
  url = "http://localhost:11434/v1",
3201
3261
  config,
3202
3262
  options,
3203
- modelMap
3263
+ models
3204
3264
  }) {
3205
3265
  const _config = {
3206
3266
  ...axAIOllamaDefaultConfig(),
@@ -3211,7 +3271,8 @@ var AxAIOllama = class extends AxAIOpenAI {
3211
3271
  options,
3212
3272
  config: _config,
3213
3273
  apiURL: url,
3214
- modelMap
3274
+ models,
3275
+ modelInfo: []
3215
3276
  });
3216
3277
  super.setName("Ollama");
3217
3278
  }
@@ -3414,7 +3475,7 @@ var AxAIReka = class extends AxBaseAI {
3414
3475
  options,
3415
3476
  apiURL,
3416
3477
  modelInfo = axModelInfoReka,
3417
- modelMap
3478
+ models
3418
3479
  }) {
3419
3480
  if (!apiKey || apiKey === "") {
3420
3481
  throw new Error("Reka API key not set");
@@ -3429,12 +3490,12 @@ var AxAIReka = class extends AxBaseAI {
3429
3490
  apiURL: apiURL ? apiURL : "https://api.reka.ai/v1/chat",
3430
3491
  headers: async () => ({ "X-Api-Key": apiKey }),
3431
3492
  modelInfo,
3432
- models: {
3493
+ defaults: {
3433
3494
  model: _config.model
3434
3495
  },
3435
3496
  options,
3436
3497
  supportFor: { functions: true, streaming: true },
3437
- modelMap
3498
+ models
3438
3499
  });
3439
3500
  }
3440
3501
  };
@@ -3448,12 +3509,12 @@ var axAITogetherDefaultConfig = () => structuredClone({
3448
3509
  model: "mistralai/Mixtral-8x7B-Instruct-v0.1",
3449
3510
  ...axBaseAIDefaultConfig()
3450
3511
  });
3451
- var AxAITogether = class extends AxAIOpenAI {
3512
+ var AxAITogether = class extends AxAIOpenAIBase {
3452
3513
  constructor({
3453
3514
  apiKey,
3454
3515
  config,
3455
3516
  options,
3456
- modelMap
3517
+ models
3457
3518
  }) {
3458
3519
  if (!apiKey || apiKey === "") {
3459
3520
  throw new Error("Together API key not set");
@@ -3468,7 +3529,7 @@ var AxAITogether = class extends AxAIOpenAI {
3468
3529
  options,
3469
3530
  apiURL: "https://api.together.xyz/v1",
3470
3531
  modelInfo: axModelInfoTogether,
3471
- modelMap
3532
+ models
3472
3533
  });
3473
3534
  super.setName("Together");
3474
3535
  }
@@ -3522,6 +3583,9 @@ var AxAI = class {
3522
3583
  getName() {
3523
3584
  return this.ai.getName();
3524
3585
  }
3586
+ getId() {
3587
+ return this.ai.getId();
3588
+ }
3525
3589
  getModelInfo() {
3526
3590
  return this.ai.getModelInfo();
3527
3591
  }
@@ -3531,8 +3595,8 @@ var AxAI = class {
3531
3595
  getFeatures(model) {
3532
3596
  return this.ai.getFeatures(model);
3533
3597
  }
3534
- getModelMap() {
3535
- return this.ai.getModelMap();
3598
+ getModelList() {
3599
+ return this.ai.getModelList();
3536
3600
  }
3537
3601
  getMetrics() {
3538
3602
  return this.ai.getMetrics();
@@ -5665,7 +5729,7 @@ var AxGen = class extends AxProgramWithSignature {
5665
5729
  traceId,
5666
5730
  functions
5667
5731
  }) {
5668
- const streamingValidation = !functions || functions.length == 0;
5732
+ const streamingValidation = ai.getFeatures().functionCot !== true;
5669
5733
  const functionCalls = [];
5670
5734
  const values = {};
5671
5735
  const xstate = {
@@ -5926,6 +5990,7 @@ var AxAgent = class {
5926
5990
  ai;
5927
5991
  signature;
5928
5992
  program;
5993
+ functions;
5929
5994
  agents;
5930
5995
  name;
5931
5996
  description;
@@ -5941,14 +6006,9 @@ var AxAgent = class {
5941
6006
  }, options) {
5942
6007
  this.ai = ai;
5943
6008
  this.agents = agents;
6009
+ this.functions = functions;
5944
6010
  this.signature = new AxSignature(signature);
5945
6011
  this.signature.setDescription(description);
5946
- const funcs = [
5947
- ...functions ?? [],
5948
- ...agents?.map((a) => a.getFunction()) ?? []
5949
- ];
5950
- const opt = { ...options, functions: funcs };
5951
- this.program = new AxGen(this.signature, opt);
5952
6012
  if (!name || name.length < 5) {
5953
6013
  throw new Error(
5954
6014
  `Agent name must be at least 10 characters (more descriptive): ${name}`
@@ -5959,6 +6019,10 @@ var AxAgent = class {
5959
6019
  `Agent description must be at least 20 characters (explain in detail what the agent does): ${description}`
5960
6020
  );
5961
6021
  }
6022
+ this.program = new AxGen(this.signature, options);
6023
+ for (const agent of agents ?? []) {
6024
+ this.program.register(agent);
6025
+ }
5962
6026
  this.name = name;
5963
6027
  this.description = description;
5964
6028
  this.subAgentList = agents?.map((a) => a.getFunction().name).join(", ");
@@ -5968,8 +6032,9 @@ var AxAgent = class {
5968
6032
  parameters: this.signature.toJSONSchema(),
5969
6033
  func: () => this.forward
5970
6034
  };
5971
- for (const agent of agents ?? []) {
5972
- this.program.register(agent);
6035
+ const mm = ai?.getModelList();
6036
+ if (mm) {
6037
+ this.func.parameters = addModelParameter(this.func.parameters, mm);
5973
6038
  }
5974
6039
  }
5975
6040
  setExamples(examples) {
@@ -5995,38 +6060,41 @@ var AxAgent = class {
5995
6060
  }
5996
6061
  getFunction() {
5997
6062
  const boundFunc = this.forward.bind(this);
5998
- const wrappedFunc = (values, options) => {
6063
+ const wrappedFunc = (valuesAndModel, options) => {
6064
+ const { model, ...values } = valuesAndModel;
5999
6065
  const ai = this.ai ?? options?.ai;
6000
6066
  if (!ai) {
6001
6067
  throw new Error("AI service is required to run the agent");
6002
6068
  }
6003
- return boundFunc(ai, values, options);
6069
+ return boundFunc(ai, values, { ...options, model });
6004
6070
  };
6005
6071
  return {
6006
6072
  ...this.func,
6007
6073
  func: wrappedFunc
6008
6074
  };
6009
6075
  }
6010
- init(ai, options) {
6011
- const _ai = this.ai ?? ai;
6012
- const funcs = [
6013
- ...options?.functions ?? [],
6014
- ...this.agents?.map((a) => a.getFunction()) ?? []
6076
+ init(parentAi, options) {
6077
+ const ai = this.ai ?? parentAi;
6078
+ const mm = ai?.getModelList();
6079
+ const agentFuncs = this.agents?.map((a) => a.getFunction())?.map(
6080
+ (f) => mm ? { ...f, parameters: addModelParameter(f.parameters, mm) } : f
6081
+ );
6082
+ const functions = [
6083
+ ...options?.functions ?? this.functions ?? [],
6084
+ ...agentFuncs ?? []
6015
6085
  ];
6016
- const opt = options;
6017
- if (funcs.length > 0) {
6018
- const opt2 = { ...options, functions: funcs };
6019
- this.program = new AxGen(this.signature, opt2);
6020
- }
6021
- return { _ai, opt };
6086
+ return { ai, functions };
6022
6087
  }
6023
- async forward(ai, values, options) {
6024
- const { _ai, opt } = this.init(ai, options);
6025
- return await this.program.forward(_ai, values, opt);
6088
+ async forward(parentAi, values, options) {
6089
+ const { ai, functions } = this.init(parentAi, options);
6090
+ return await this.program.forward(ai, values, { ...options, functions });
6026
6091
  }
6027
- async *streamingForward(ai, values, options) {
6028
- const { _ai, opt } = this.init(ai, options);
6029
- return yield* this.program.streamingForward(_ai, values, opt);
6092
+ async *streamingForward(parentAi, values, options) {
6093
+ const { ai, functions } = this.init(parentAi, options);
6094
+ return yield* this.program.streamingForward(ai, values, {
6095
+ ...options,
6096
+ functions
6097
+ });
6030
6098
  }
6031
6099
  };
6032
6100
  function toCamelCase(inputString) {
@@ -6040,6 +6108,31 @@ function toCamelCase(inputString) {
6040
6108
  }).join("");
6041
6109
  return camelCaseString;
6042
6110
  }
6111
+ function addModelParameter(parameters, models) {
6112
+ const baseSchema = parameters ? structuredClone(parameters) : {
6113
+ type: "object",
6114
+ properties: {},
6115
+ required: []
6116
+ };
6117
+ if (baseSchema.properties?.model) {
6118
+ return baseSchema;
6119
+ }
6120
+ const modelProperty = {
6121
+ type: "string",
6122
+ enum: models.map((m) => m.key),
6123
+ description: `The AI model to use for this function call. Available options: ${models.map((m) => `${m.key}: ${m.description}`).join(" | ")}`
6124
+ };
6125
+ const newProperties = {
6126
+ ...baseSchema.properties ?? {},
6127
+ model: modelProperty
6128
+ };
6129
+ const newRequired = [...baseSchema.required ?? [], "model"];
6130
+ return {
6131
+ ...baseSchema,
6132
+ properties: newProperties,
6133
+ required: newRequired
6134
+ };
6135
+ }
6043
6136
 
6044
6137
  // docs/tika.ts
6045
6138
  import { createReadStream } from "node:fs";
@@ -6094,6 +6187,10 @@ var AxBalancer = class _AxBalancer {
6094
6187
  currentServiceIndex = 0;
6095
6188
  currentService;
6096
6189
  debug;
6190
+ initialBackoffMs;
6191
+ maxBackoffMs;
6192
+ maxRetries;
6193
+ serviceFailures = /* @__PURE__ */ new Map();
6097
6194
  constructor(services, options) {
6098
6195
  if (services.length === 0) {
6099
6196
  throw new Error("No AI services provided.");
@@ -6107,6 +6204,9 @@ var AxBalancer = class _AxBalancer {
6107
6204
  }
6108
6205
  this.currentService = cs;
6109
6206
  this.debug = options?.debug ?? true;
6207
+ this.initialBackoffMs = options?.initialBackoffMs ?? 1e3;
6208
+ this.maxBackoffMs = options?.maxBackoffMs ?? 32e3;
6209
+ this.maxRetries = options?.maxRetries ?? 3;
6110
6210
  }
6111
6211
  /**
6112
6212
  * Service comparator that respects the input order of services.
@@ -6122,8 +6222,8 @@ var AxBalancer = class _AxBalancer {
6122
6222
  const bTotalCost = (bInfo.promptTokenCostPer1M || Infinity) + (bInfo.completionTokenCostPer1M || Infinity);
6123
6223
  return aTotalCost - bTotalCost;
6124
6224
  };
6125
- getModelMap() {
6126
- throw new Error("Method not implemented.");
6225
+ getModelList() {
6226
+ return this.currentService.getModelList();
6127
6227
  }
6128
6228
  getNextService() {
6129
6229
  const cs = this.services[++this.currentServiceIndex];
@@ -6144,6 +6244,9 @@ var AxBalancer = class _AxBalancer {
6144
6244
  getName() {
6145
6245
  return this.currentService.getName();
6146
6246
  }
6247
+ getId() {
6248
+ return this.currentService.getId();
6249
+ }
6147
6250
  getModelInfo() {
6148
6251
  return this.currentService.getModelInfo();
6149
6252
  }
@@ -6156,11 +6259,56 @@ var AxBalancer = class _AxBalancer {
6156
6259
  getMetrics() {
6157
6260
  return this.currentService.getMetrics();
6158
6261
  }
6262
+ canRetryService() {
6263
+ const failure = this.serviceFailures.get(this.currentService.getId());
6264
+ if (!failure) return true;
6265
+ const { retries, lastFailureTime } = failure;
6266
+ const timeSinceLastFailure = Date.now() - lastFailureTime;
6267
+ const backoffMs = Math.min(
6268
+ this.initialBackoffMs * Math.pow(2, retries),
6269
+ this.maxBackoffMs
6270
+ );
6271
+ return timeSinceLastFailure >= backoffMs;
6272
+ }
6273
+ handleFailure() {
6274
+ const failure = this.serviceFailures.get(this.currentService.getId());
6275
+ const retries = (failure?.retries ?? 0) + 1;
6276
+ this.serviceFailures.set(this.currentService.getId(), {
6277
+ retries,
6278
+ lastFailureTime: Date.now()
6279
+ });
6280
+ if (this.debug) {
6281
+ console.warn(
6282
+ `AxBalancer: Service ${this.currentService.getName()} failed (retry ${retries}/${this.maxRetries})`
6283
+ );
6284
+ }
6285
+ if (retries >= this.maxRetries) {
6286
+ const gotNextService = this.getNextService();
6287
+ if (this.debug) {
6288
+ console.warn(
6289
+ `AxBalancer: Switching to service ${this.currentService.getName()}`
6290
+ );
6291
+ }
6292
+ return gotNextService;
6293
+ }
6294
+ return true;
6295
+ }
6296
+ handleSuccess() {
6297
+ this.serviceFailures.delete(this.currentService.getId());
6298
+ }
6159
6299
  async chat(req, options) {
6160
6300
  this.reset();
6161
6301
  while (true) {
6302
+ if (!this.canRetryService()) {
6303
+ if (!this.getNextService()) {
6304
+ throw new Error("All services exhausted");
6305
+ }
6306
+ continue;
6307
+ }
6162
6308
  try {
6163
- return await this.currentService.chat(req, options);
6309
+ const response = await this.currentService.chat(req, options);
6310
+ this.handleSuccess();
6311
+ return response;
6164
6312
  } catch (e) {
6165
6313
  if (!(e instanceof AxAIServiceError)) {
6166
6314
  throw e;
@@ -6181,38 +6329,29 @@ var AxBalancer = class _AxBalancer {
6181
6329
  default:
6182
6330
  throw e;
6183
6331
  }
6184
- if (this.debug) {
6185
- console.warn(
6186
- `AxBalancer: Service ${this.currentService.getName()} failed`,
6187
- e
6188
- );
6189
- }
6190
- if (!this.getNextService()) {
6332
+ if (!this.handleFailure()) {
6191
6333
  throw e;
6192
6334
  }
6193
- if (this.debug) {
6194
- console.warn(
6195
- `AxBalancer: Switching to service ${this.currentService.getName()}`
6196
- );
6197
- }
6198
6335
  }
6199
6336
  }
6200
6337
  }
6201
6338
  async embed(req, options) {
6202
6339
  this.reset();
6203
6340
  while (true) {
6341
+ if (!this.canRetryService()) {
6342
+ if (!this.getNextService()) {
6343
+ throw new Error("All services exhausted");
6344
+ }
6345
+ continue;
6346
+ }
6204
6347
  try {
6205
- return await this.currentService.embed(req, options);
6348
+ const response = await this.currentService.embed(req, options);
6349
+ this.handleSuccess();
6350
+ return response;
6206
6351
  } catch (e) {
6207
- if (this.debug) {
6208
- console.warn(`Service ${this.currentService.getName()} failed`);
6209
- }
6210
- if (!this.getNextService()) {
6352
+ if (!this.handleFailure()) {
6211
6353
  throw e;
6212
6354
  }
6213
- if (this.debug) {
6214
- console.warn(`Switching to service ${this.currentService.getName()}`);
6215
- }
6216
6355
  }
6217
6356
  }
6218
6357
  }
@@ -7705,6 +7844,7 @@ var AxEmbeddingAdapter = class {
7705
7844
  var AxMockAIService = class {
7706
7845
  constructor(config = {}) {
7707
7846
  this.config = config;
7847
+ this.config.id = this.config.id ?? crypto.randomUUID();
7708
7848
  }
7709
7849
  options = {};
7710
7850
  metrics = {
@@ -7720,6 +7860,9 @@ var AxMockAIService = class {
7720
7860
  getName() {
7721
7861
  return this.config.name ?? "mock-ai-service";
7722
7862
  }
7863
+ getId() {
7864
+ return this.config.id ?? "mock-ai-service-id";
7865
+ }
7723
7866
  getModelInfo() {
7724
7867
  return {
7725
7868
  name: "mock-model",
@@ -7739,8 +7882,8 @@ var AxMockAIService = class {
7739
7882
  streaming: this.config.features?.streaming ?? false
7740
7883
  };
7741
7884
  }
7742
- getModelMap() {
7743
- return this.config.modelMap;
7885
+ getModelList() {
7886
+ return this.config.models;
7744
7887
  }
7745
7888
  getMetrics() {
7746
7889
  return this.metrics;
@@ -7875,6 +8018,7 @@ export {
7875
8018
  AxAIMistralModel,
7876
8019
  AxAIOllama,
7877
8020
  AxAIOpenAI,
8021
+ AxAIOpenAIBase,
7878
8022
  AxAIOpenAIEmbedModel,
7879
8023
  AxAIOpenAIModel,
7880
8024
  AxAIReka,